]> Sergey Matveev's repositories - btrtrc.git/blobdiff - prioritized_peers.go
Change default webseed path escaping to work for all S3-compatible providers
[btrtrc.git] / prioritized_peers.go
index faafe00fe23f8a1d32114479f8ff054137b30766..d0ef43edbb6d9bed2c89ea8f9bfbaa2152fc3a74 100644 (file)
@@ -1,6 +1,8 @@
 package torrent
 
 import (
+       "hash/maphash"
+
        "github.com/anacrolix/multiless"
        "github.com/google/btree"
 )
@@ -9,23 +11,33 @@ import (
 // change if our apparent IP changes, we don't currently handle that.
 type prioritizedPeersItem struct {
        prio peerPriority
-       p    Peer
+       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,
+               me.prio, other.prio).Int64(
+               me.addrHash(), other.addrHash(),
        ).Less()
 }
 
 type prioritizedPeers struct {
        om      *btree.BTree
-       getPrio func(Peer) peerPriority
+       getPrio func(PeerInfo) peerPriority
 }
 
-func (me *prioritizedPeers) Each(f func(Peer)) {
+func (me *prioritizedPeers) Each(f func(PeerInfo)) {
        me.om.Ascend(func(i btree.Item) bool {
                f(i.(prioritizedPeersItem).p)
                return true
@@ -37,10 +49,21 @@ func (me *prioritizedPeers) Len() int {
 }
 
 // Returns true if a peer is replaced.
-func (me *prioritizedPeers) Add(p Peer) bool {
+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 {
@@ -51,6 +74,6 @@ func (me *prioritizedPeers) DeleteMin() (ret prioritizedPeersItem, ok bool) {
        return
 }
 
-func (me *prioritizedPeers) PopMax() Peer {
+func (me *prioritizedPeers) PopMax() PeerInfo {
        return me.om.DeleteMax().(prioritizedPeersItem).p
 }