]> Sergey Matveev's repositories - btrtrc.git/blob - worst_conns.go
Replace pruning timer with as-required connection dropping
[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 (me *worstConns) Len() int      { return len(me.c) }
15 func (me *worstConns) Swap(i, j int) { me.c[i], me.c[j] = me.c[j], me.c[i] }
16
17 func (me *worstConns) Pop() (ret interface{}) {
18         old := me.c
19         n := len(old)
20         ret = old[n-1]
21         me.c = old[:n-1]
22         return
23 }
24
25 func (me *worstConns) Push(x interface{}) {
26         me.c = append(me.c, x.(*connection))
27 }
28
29 type worstConnsSortKey struct {
30         useful      bool
31         lastHelpful time.Time
32         connected   time.Time
33 }
34
35 func (me worstConnsSortKey) Less(other worstConnsSortKey) bool {
36         if me.useful != other.useful {
37                 return !me.useful
38         }
39         if !me.lastHelpful.Equal(other.lastHelpful) {
40                 return me.lastHelpful.Before(other.lastHelpful)
41         }
42         return me.connected.Before(other.connected)
43 }
44
45 func (me *worstConns) key(i int) (key worstConnsSortKey) {
46         c := me.c[i]
47         key.useful = me.cl.usefulConn(me.t, c)
48         if me.cl.seeding(me.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 (me worstConns) Less(i, j int) bool {
61         return me.key(i).Less(me.key(j))
62 }