New worst conns algorithm that takes into account connection useful chunk hit rate
This commit is contained in:
parent
c0d7b2fbf2
commit
ced8a7b78f
11
torrent.go
11
torrent.go
@ -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)
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
@ -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)
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user