From: Matt Joiner Date: Sat, 13 Sep 2014 17:40:35 +0000 (+1000) Subject: New worst conn algorithm that incorporates useful/unwanted chunk download rates X-Git-Tag: v1.0.0~1568 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=dcc3de7a70c83b0899e1b9f4d21a73525ee1e631;p=btrtrc.git New worst conn algorithm that incorporates useful/unwanted chunk download rates --- diff --git a/torrent.go b/torrent.go index 5d6b66b7..77193383 100644 --- a/torrent.go +++ b/torrent.go @@ -70,8 +70,10 @@ type torrent struct { } 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 } @@ -292,7 +294,10 @@ func (t *torrent) WriteStatus(w io.Writer) { 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) } diff --git a/worst_conns.go b/worst_conns.go index a1bf326b..3b26c18f 100644 --- a/worst_conns.go +++ b/worst_conns.go @@ -5,33 +5,52 @@ import ( ) // 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)) }