}
func (t *torrent) worstConnsHeap() (wcs *worstConns) {
- wcs = new(worstConns)
- *wcs = append([]*connection{}, t.Conns...)
+ wcs = &worstConns{
+ c: append([]*connection{}, t.Conns...),
+ t: t,
+ }
heap.Init(wcs)
return
}
fmt.Fprintln(w)
fmt.Fprintf(w, "Pending peers: %d\n", len(t.Peers))
fmt.Fprintf(w, "Active peers: %d\n", len(t.Conns))
- sort.Sort(worstConns(t.Conns))
+ sort.Sort(&worstConns{
+ c: t.Conns,
+ t: t,
+ })
for _, c := range t.Conns {
c.WriteStatus(w)
}
)
// Implements heap functions such that [0] is the worst connection.
-type worstConns []*connection
+type worstConns struct {
+ c []*connection
+ t *torrent
+}
-func (me worstConns) Len() int { return len(me) }
-func (me worstConns) Swap(i, j int) { me[i], me[j] = me[j], me[i] }
+func (me worstConns) Len() int { return len(me.c) }
+func (me worstConns) Swap(i, j int) { me.c[i], me.c[j] = me.c[j], me.c[i] }
func (me *worstConns) Pop() (ret interface{}) {
- old := *me
+ old := me.c
n := len(old)
ret = old[n-1]
- *me = old[:n-1]
+ me.c = old[:n-1]
return
}
func (me *worstConns) Push(x interface{}) {
- *me = append(*me, x.(*connection))
+ me.c = append(me.c, x.(*connection))
+}
+
+type worstConnsSortKey struct {
+ level int
+ age time.Duration
}
-func (me worstConns) key(i int) (ret time.Duration) {
- c := me[i]
- return time.Duration(1+c.UnwantedChunksReceived) * time.Now().Sub(func() time.Time {
+func (me worstConnsSortKey) Less(other worstConnsSortKey) bool {
+ if me.level != other.level {
+ return me.level > other.level
+ }
+ return me.age > other.age
+}
+
+func (me worstConns) key(i int) (key worstConnsSortKey) {
+ c := me.c[i]
+ if time.Now().Sub(c.completedHandshake) >= 30*time.Second && !me.t.connHasWantedPieces(c) {
+ key.level = 1
+ }
+ key.age = time.Duration(1+3*c.UnwantedChunksReceived) * time.Now().Sub(func() time.Time {
if !c.lastUsefulChunkReceived.IsZero() {
return c.lastUsefulChunkReceived
}
return c.completedHandshake.Add(-time.Minute)
}()) / time.Duration(1+c.UsefulChunksReceived)
+ return
}
func (me worstConns) Less(i, j int) bool {
- return me.key(i) > me.key(j)
+ return me.key(i).Less(me.key(j))
}