2014-08-28 06:04:41 +08:00
|
|
|
package torrent
|
|
|
|
|
|
|
|
import (
|
|
|
|
"time"
|
|
|
|
)
|
|
|
|
|
2014-09-11 18:31:31 +08:00
|
|
|
// Implements heap functions such that [0] is the worst connection.
|
2014-09-14 01:40:35 +08:00
|
|
|
type worstConns struct {
|
|
|
|
c []*connection
|
|
|
|
t *torrent
|
|
|
|
}
|
2014-08-28 06:04:41 +08:00
|
|
|
|
2014-09-14 01:40:35 +08:00
|
|
|
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] }
|
2014-08-28 06:04:41 +08:00
|
|
|
|
2014-09-11 18:31:31 +08:00
|
|
|
func (me *worstConns) Pop() (ret interface{}) {
|
2014-09-14 01:40:35 +08:00
|
|
|
old := me.c
|
2014-08-28 06:04:41 +08:00
|
|
|
n := len(old)
|
|
|
|
ret = old[n-1]
|
2014-09-14 01:40:35 +08:00
|
|
|
me.c = old[:n-1]
|
2014-08-28 06:04:41 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2014-09-11 18:31:31 +08:00
|
|
|
func (me *worstConns) Push(x interface{}) {
|
2014-09-14 01:40:35 +08:00
|
|
|
me.c = append(me.c, x.(*connection))
|
|
|
|
}
|
|
|
|
|
|
|
|
type worstConnsSortKey struct {
|
2014-12-01 17:27:52 +08:00
|
|
|
// Peer has something we want.
|
|
|
|
useless bool
|
|
|
|
// A fabricated duration since peer was last helpful.
|
|
|
|
age time.Duration
|
2014-08-28 06:04:41 +08:00
|
|
|
}
|
2014-09-11 18:31:31 +08:00
|
|
|
|
2014-09-14 01:40:35 +08:00
|
|
|
func (me worstConnsSortKey) Less(other worstConnsSortKey) bool {
|
2014-12-01 17:27:52 +08:00
|
|
|
if me.useless != other.useless {
|
|
|
|
return me.useless
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
|
|
|
return me.age > other.age
|
|
|
|
}
|
|
|
|
|
|
|
|
func (me worstConns) key(i int) (key worstConnsSortKey) {
|
|
|
|
c := me.c[i]
|
2014-12-01 17:27:52 +08:00
|
|
|
// Peer has had time to declare what they have.
|
|
|
|
if time.Now().Sub(c.completedHandshake) >= 30*time.Second {
|
|
|
|
if !me.t.haveInfo() {
|
2014-12-03 15:07:50 +08:00
|
|
|
key.useless = !c.supportsExtension("ut_metadata")
|
2014-12-01 17:27:52 +08:00
|
|
|
} else {
|
|
|
|
if !me.t.connHasWantedPieces(c) {
|
|
|
|
key.useless = true
|
|
|
|
}
|
|
|
|
}
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
|
|
|
key.age = time.Duration(1+3*c.UnwantedChunksReceived) * time.Now().Sub(func() time.Time {
|
2014-09-11 18:31:31 +08:00
|
|
|
if !c.lastUsefulChunkReceived.IsZero() {
|
|
|
|
return c.lastUsefulChunkReceived
|
|
|
|
}
|
|
|
|
return c.completedHandshake.Add(-time.Minute)
|
|
|
|
}()) / time.Duration(1+c.UsefulChunksReceived)
|
2014-09-14 01:40:35 +08:00
|
|
|
return
|
2014-09-11 18:31:31 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
func (me worstConns) Less(i, j int) bool {
|
2014-09-14 01:40:35 +08:00
|
|
|
return me.key(i).Less(me.key(j))
|
2014-09-11 18:31:31 +08:00
|
|
|
}
|