]> Sergey Matveev's repositories - btrtrc.git/commitdiff
New worst conns algorithm that takes into account connection useful chunk hit rate
authorMatt Joiner <anacrolix@gmail.com>
Thu, 11 Sep 2014 10:31:31 +0000 (20:31 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 11 Sep 2014 10:31:31 +0000 (20:31 +1000)
torrent.go
torrent_test.go
worst_conns.go

index 8274091c65083b2d33705131484bcfbd365a4ed9..5d6b66b77190a9831d522bda390d8570241abb61 100644 (file)
@@ -69,10 +69,9 @@ type torrent struct {
        metadataHave []bool
 }
 
-func (t *torrent) worstConnsHeap() (wcs *worstConnsHeap) {
-       wcs = new(worstConnsHeap)
-       *wcs = make([]*connection, 0, len(t.Conns))
-       *wcs = append(*wcs, t.Conns...)
+func (t *torrent) worstConnsHeap() (wcs *worstConns) {
+       wcs = new(worstConns)
+       *wcs = append([]*connection{}, t.Conns...)
        heap.Init(wcs)
        return
 }
@@ -293,9 +292,7 @@ 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))
-       wcs := new(worstConnsHeap)
-       *wcs = t.Conns
-       sort.Sort(wcs)
+       sort.Sort(worstConns(t.Conns))
        for _, c := range t.Conns {
                c.WriteStatus(w)
        }
index 18306ecf747ebda9cc8dea2a34efb143d3c7ab98..302a97515c0f7d4d9dd7b853b1ca86fc25b9774f 100644 (file)
@@ -58,3 +58,12 @@ func TestTorrentDoubleClose(t *testing.T) {
        }
        wg.Wait()
 }
+
+func TestAppendToCopySlice(t *testing.T) {
+       orig := []int{1, 2, 3}
+       dupe := append([]int{}, orig...)
+       dupe[0] = 4
+       if orig[0] != 1 {
+               t.FailNow()
+       }
+}
index 37037cb6fd4cc6a9fd1e3a3d8b09ee11cc948731..a1bf326bf8647c85fa14925cba471084adce8f9b 100644 (file)
@@ -4,27 +4,13 @@ import (
        "time"
 )
 
-type worstConnsHeap []*connection
+// Implements heap functions such that [0] is the worst connection.
+type worstConns []*connection
 
-func (me worstConnsHeap) Len() int      { return len(me) }
-func (me worstConnsHeap) Swap(i, j int) { me[i], me[j] = me[j], me[i] }
-func (me worstConnsHeap) last(c *connection) (ret time.Time) {
-       ret = c.lastUsefulChunkReceived
-       if !ret.IsZero() {
-               return
-       }
-       ret = c.completedHandshake
-       if time.Now().Sub(ret) >= 3*time.Minute {
-               return
-       }
-       ret = time.Now().Add(-3 * time.Minute)
-       return
-}
-func (me worstConnsHeap) Less(i, j int) bool {
-       return me.last(me[i]).Before(me.last(me[j]))
-}
+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 *worstConnsHeap) Pop() (ret interface{}) {
+func (me *worstConns) Pop() (ret interface{}) {
        old := *me
        n := len(old)
        ret = old[n-1]
@@ -32,6 +18,20 @@ func (me *worstConnsHeap) Pop() (ret interface{}) {
        return
 }
 
-func (me *worstConnsHeap) Push(x interface{}) {
+func (me *worstConns) Push(x interface{}) {
        *me = append(*me, x.(*connection))
 }
+
+func (me worstConns) key(i int) (ret time.Duration) {
+       c := me[i]
+       return time.Duration(1+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)
+}
+
+func (me worstConns) Less(i, j int) bool {
+       return me.key(i) > me.key(j)
+}