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 {
|
2015-06-16 14:57:47 +08:00
|
|
|
c []*connection
|
2016-04-03 16:40:43 +08:00
|
|
|
t *Torrent
|
2015-06-16 14:57:47 +08:00
|
|
|
cl *Client
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
2014-08-28 06:04:41 +08:00
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
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] }
|
2014-08-28 06:04:41 +08:00
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
func (wc *worstConns) Pop() (ret interface{}) {
|
|
|
|
old := wc.c
|
2014-08-28 06:04:41 +08:00
|
|
|
n := len(old)
|
|
|
|
ret = old[n-1]
|
2016-04-19 12:11:11 +08:00
|
|
|
wc.c = old[:n-1]
|
2014-08-28 06:04:41 +08:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
func (wc *worstConns) Push(x interface{}) {
|
|
|
|
wc.c = append(wc.c, x.(*connection))
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
type worstConnsSortKey struct {
|
2015-06-16 14:57:47 +08:00
|
|
|
useful bool
|
|
|
|
lastHelpful time.Time
|
2015-06-29 22:45:26 +08:00
|
|
|
connected time.Time
|
2014-08-28 06:04:41 +08:00
|
|
|
}
|
2014-09-11 18:31:31 +08:00
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
func (wc worstConnsSortKey) Less(other worstConnsSortKey) bool {
|
|
|
|
if wc.useful != other.useful {
|
|
|
|
return !wc.useful
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
2016-04-19 12:11:11 +08:00
|
|
|
if !wc.lastHelpful.Equal(other.lastHelpful) {
|
|
|
|
return wc.lastHelpful.Before(other.lastHelpful)
|
2015-06-29 22:45:26 +08:00
|
|
|
}
|
2016-04-19 12:11:11 +08:00
|
|
|
return wc.connected.Before(other.connected)
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
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) {
|
2015-06-16 14:57:47 +08:00
|
|
|
key.lastHelpful = c.lastChunkSent
|
2015-06-29 22:45:26 +08:00
|
|
|
}
|
|
|
|
// 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) {
|
2015-06-16 14:57:47 +08:00
|
|
|
key.lastHelpful = c.lastUsefulChunkReceived
|
2014-09-14 01:40:35 +08:00
|
|
|
}
|
2015-06-29 22:45:26 +08:00
|
|
|
key.connected = c.completedHandshake
|
2014-09-14 01:40:35 +08:00
|
|
|
return
|
2014-09-11 18:31:31 +08:00
|
|
|
}
|
|
|
|
|
2016-04-19 12:11:11 +08:00
|
|
|
func (wc worstConns) Less(i, j int) bool {
|
|
|
|
return wc.key(i).Less(wc.key(j))
|
2014-09-11 18:31:31 +08:00
|
|
|
}
|