2
0
mirror of synced 2025-02-23 14:18:13 +00:00

New worst conns algorithm that takes into account connection useful chunk hit rate

This commit is contained in:
Matt Joiner 2014-09-11 20:31:31 +10:00
parent c0d7b2fbf2
commit ced8a7b78f
3 changed files with 33 additions and 27 deletions

View 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)
}

View 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()
}
}

View 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)
}