-
-
Notifications
You must be signed in to change notification settings - Fork 628
/
prioritized-peers.go
82 lines (69 loc) · 1.81 KB
/
prioritized-peers.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package torrent
import (
"hash/maphash"
"github.com/anacrolix/multiless"
"github.com/google/btree"
)
// Peers are stored with their priority at insertion. Their priority may
// change if our apparent IP changes, we don't currently handle that.
type prioritizedPeersItem struct {
prio peerPriority
p PeerInfo
}
var hashSeed = maphash.MakeSeed()
func (me prioritizedPeersItem) addrHash() int64 {
var h maphash.Hash
h.SetSeed(hashSeed)
h.WriteString(me.p.Addr.String())
return int64(h.Sum64())
}
func (me prioritizedPeersItem) Less(than btree.Item) bool {
other := than.(prioritizedPeersItem)
return multiless.New().Bool(
me.p.Trusted, other.p.Trusted).Uint32(
me.prio, other.prio).Int64(
me.addrHash(), other.addrHash(),
).Less()
}
type prioritizedPeers struct {
om *btree.BTree
getPrio func(PeerInfo) peerPriority
}
func (me *prioritizedPeers) Each(f func(PeerInfo)) {
me.om.Ascend(func(i btree.Item) bool {
f(i.(prioritizedPeersItem).p)
return true
})
}
func (me *prioritizedPeers) Len() int {
if me == nil || me.om == nil {
return 0
}
return me.om.Len()
}
// Returns true if a peer is replaced.
func (me *prioritizedPeers) Add(p PeerInfo) bool {
return me.om.ReplaceOrInsert(prioritizedPeersItem{me.getPrio(p), p}) != nil
}
// Returns true if a peer is replaced.
func (me *prioritizedPeers) AddReturningReplacedPeer(p PeerInfo) (ret PeerInfo, ok bool) {
item := me.om.ReplaceOrInsert(prioritizedPeersItem{me.getPrio(p), p})
if item == nil {
return
}
ret = item.(prioritizedPeersItem).p
ok = true
return
}
func (me *prioritizedPeers) DeleteMin() (ret prioritizedPeersItem, ok bool) {
i := me.om.DeleteMin()
if i == nil {
return
}
ret = i.(prioritizedPeersItem)
ok = true
return
}
func (me *prioritizedPeers) PopMax() PeerInfo {
return me.om.DeleteMax().(prioritizedPeersItem).p
}