]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Optimize Torrent.worstBadConn
authorMatt Joiner <anacrolix@gmail.com>
Fri, 10 Sep 2021 11:48:44 +0000 (21:48 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Fri, 10 Sep 2021 13:07:10 +0000 (23:07 +1000)
go.mod
go.sum
torrent.go

diff --git a/go.mod b/go.mod
index 144bc7fda0680949fb007556d7cf736032a079b8..dcbe602c596174a5ab62105dce86986e346008fd 100644 (file)
--- a/go.mod
+++ b/go.mod
@@ -5,7 +5,7 @@ require (
        crawshaw.io/sqlite v0.3.3-0.20210127221821-98b1f83c5508
        github.com/RoaringBitmap/roaring v0.9.4
        github.com/alexflint/go-arg v1.4.2
-       github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9
+       github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9
        github.com/anacrolix/confluence v1.8.0 // indirect
        github.com/anacrolix/dht/v2 v2.10.5-0.20210902001729-06cc4fe90e53
        github.com/anacrolix/envpprof v1.1.1
diff --git a/go.sum b/go.sum
index af23d4b51ba58a2caa461214abf4981e4e3a2120..4dc4fcefade9aa12761d402d0361eeb84d1bdcc8 100644 (file)
--- a/go.sum
+++ b/go.sum
@@ -49,6 +49,8 @@ github.com/anacrolix/chansync v0.1.0 h1:4cIfJmEV8sYkSEMW2AXnPjX6iQT4plqELJ65pLna
 github.com/anacrolix/chansync v0.1.0/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
 github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9 h1:Jk3Mdr+XbO1uvf/+nUXjb/M1dPDNPQThxKmS5MLGE+w=
 github.com/anacrolix/chansync v0.1.1-0.20210904130811-9cd7139c8dd9/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
+github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9 h1:jfSupvl9p7Bkd9snD6DrjxDmsYjJeYxSqhQa/I9wV3I=
+github.com/anacrolix/chansync v0.2.1-0.20210910114620-14955c95ded9/go.mod h1:DZsatdsdXxD0WiwcGl0nJVwyjCKMDv+knl1q2iBjA2k=
 github.com/anacrolix/confluence v1.7.1-0.20210221224747-9cb14aa2c53a/go.mod h1:T0JHvSaf9UfoiUdCtCOUuRroHm/tauUJTbLc6/vd5YA=
 github.com/anacrolix/confluence v1.7.1-0.20210221225853-90405640e928/go.mod h1:NoLcfoRet+kYttjLXJRmh4qBVrylJsfIItik5GGj21A=
 github.com/anacrolix/confluence v1.7.1-0.20210311004351-d642adb8546c/go.mod h1:KCZ3eObqKECNeZg0ekAoJVakHMP3gAdR8i0bQ26IkzM=
index b719529f846b8ed5311da2d208a56d54a98afe6a..27ad3e1ed5f88fb4ca7a3761c3b8175b4bf6075c 100644 (file)
@@ -263,14 +263,13 @@ func (t *Torrent) addrActive(addr string) bool {
        return false
 }
 
-func (t *Torrent) unclosedConnsAsSlice() (ret []*PeerConn) {
-       ret = make([]*PeerConn, 0, len(t.conns))
+func (t *Torrent) appendUnclosedConns(ret []*PeerConn) []*PeerConn {
        for c := range t.conns {
                if !c.closed.IsSet() {
                        ret = append(ret, c)
                }
        }
-       return
+       return ret
 }
 
 func (t *Torrent) addPeer(p PeerInfo) (added bool) {
@@ -974,11 +973,25 @@ func (t *Torrent) wantPieceIndex(index pieceIndex) bool {
        })
 }
 
+// A pool of []*PeerConn, to reduce allocations in functions that need to index or sort Torrent
+// conns (which is a map).
+var peerConnSlices sync.Pool
+
 // The worst connection is one that hasn't been sent, or sent anything useful for the longest. A bad
-// connection is one that usually sends us unwanted pieces, or has been in worser half of the
-// established connections for more than a minute.
-func (t *Torrent) worstBadConn() *PeerConn {
-       wcs := worseConnSlice{t.unclosedConnsAsSlice()}
+// connection is one that usually sends us unwanted pieces, or has been in the worse half of the
+// established connections for more than a minute. This is O(n log n). If there was a way to not
+// consider the position of a conn relative to the total number, it could be reduced to O(n).
+func (t *Torrent) worstBadConn() (ret *PeerConn) {
+       var sl []*PeerConn
+       getInterface := peerConnSlices.Get()
+       if getInterface == nil {
+               sl = make([]*PeerConn, 0, len(t.conns))
+       } else {
+               sl = getInterface.([]*PeerConn)[:0]
+       }
+       sl = t.appendUnclosedConns(sl)
+       defer peerConnSlices.Put(sl)
+       wcs := worseConnSlice{sl}
        heap.Init(&wcs)
        for wcs.Len() != 0 {
                c := heap.Pop(&wcs).(*PeerConn)