]> Sergey Matveev's repositories - btrtrc.git/commitdiff
New worst conn algorithm that incorporates useful/unwanted chunk download rates
authorMatt Joiner <anacrolix@gmail.com>
Sat, 13 Sep 2014 17:40:35 +0000 (03:40 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Sat, 13 Sep 2014 17:40:35 +0000 (03:40 +1000)
torrent.go
worst_conns.go

index 5d6b66b77190a9831d522bda390d8570241abb61..771933838cf4ceb53d12bd1cb23d82236e37265e 100644 (file)
@@ -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)
        }
index a1bf326bf8647c85fa14925cba471084adce8f9b..3b26c18f65e04211459795816d947c9a60895994 100644 (file)
@@ -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))
 }