]> Sergey Matveev's repositories - btrtrc.git/blob - worst_conns.go
1f41c561d8eff0115b50c6b46d4982c7540c1473
[btrtrc.git] / worst_conns.go
1 package torrent
2
3 import (
4         "time"
5 )
6
7 // Implements heap functions such that [0] is the worst connection.
8 type worstConns struct {
9         c  []*connection
10         t  *Torrent
11         cl *Client
12 }
13
14 func (wc *worstConns) Len() int      { return len(wc.c) }
15 func (wc *worstConns) Swap(i, j int) { wc.c[i], wc.c[j] = wc.c[j], wc.c[i] }
16
17 func (wc *worstConns) Pop() (ret interface{}) {
18         old := wc.c
19         n := len(old)
20         ret = old[n-1]
21         wc.c = old[:n-1]
22         return
23 }
24
25 func (wc *worstConns) Push(x interface{}) {
26         wc.c = append(wc.c, x.(*connection))
27 }
28
29 type worstConnsSortKey struct {
30         useful      bool
31         lastHelpful time.Time
32         connected   time.Time
33 }
34
35 func (wc worstConnsSortKey) Less(other worstConnsSortKey) bool {
36         if wc.useful != other.useful {
37                 return !wc.useful
38         }
39         if !wc.lastHelpful.Equal(other.lastHelpful) {
40                 return wc.lastHelpful.Before(other.lastHelpful)
41         }
42         return wc.connected.Before(other.connected)
43 }
44
45 func (wc *worstConns) key(i int) (key worstConnsSortKey) {
46         c := wc.c[i]
47         key.useful = wc.cl.usefulConn(wc.t, c)
48         if wc.cl.seeding(wc.t) {
49                 key.lastHelpful = c.lastChunkSent
50         }
51         // Intentionally consider the last time a chunk was received when seeding,
52         // because we might go from seeding back to leeching.
53         if c.lastUsefulChunkReceived.After(key.lastHelpful) {
54                 key.lastHelpful = c.lastUsefulChunkReceived
55         }
56         key.connected = c.completedHandshake
57         return
58 }
59
60 func (wc worstConns) Less(i, j int) bool {
61         return wc.key(i).Less(wc.key(j))
62 }