torrent/worst_conns.go

63 lines
1.4 KiB
Go

package torrent
import (
"time"
)
// Implements heap functions such that [0] is the worst connection.
type worstConns struct {
c []*connection
t *Torrent
cl *Client
}
func (wc *worstConns) Len() int { return len(wc.c) }
func (wc *worstConns) Swap(i, j int) { wc.c[i], wc.c[j] = wc.c[j], wc.c[i] }
func (wc *worstConns) Pop() (ret interface{}) {
old := wc.c
n := len(old)
ret = old[n-1]
wc.c = old[:n-1]
return
}
func (wc *worstConns) Push(x interface{}) {
wc.c = append(wc.c, x.(*connection))
}
type worstConnsSortKey struct {
useful bool
lastHelpful time.Time
connected time.Time
}
func (wc worstConnsSortKey) Less(other worstConnsSortKey) bool {
if wc.useful != other.useful {
return !wc.useful
}
if !wc.lastHelpful.Equal(other.lastHelpful) {
return wc.lastHelpful.Before(other.lastHelpful)
}
return wc.connected.Before(other.connected)
}
func (wc *worstConns) key(i int) (key worstConnsSortKey) {
c := wc.c[i]
key.useful = wc.cl.usefulConn(wc.t, c)
if wc.cl.seeding(wc.t) {
key.lastHelpful = c.lastChunkSent
}
// Intentionally consider the last time a chunk was received when seeding,
// because we might go from seeding back to leeching.
if c.lastUsefulChunkReceived.After(key.lastHelpful) {
key.lastHelpful = c.lastUsefulChunkReceived
}
key.connected = c.completedHandshake
return
}
func (wc worstConns) Less(i, j int) bool {
return wc.key(i).Less(wc.key(j))
}