]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Avoid heap allocation in GetRequestablePieces (#734)
authorJonathan McDowell <noodles-github@earth.li>
Mon, 11 Apr 2022 04:22:05 +0000 (05:22 +0100)
committerGitHub <noreply@github.com>
Mon, 11 Apr 2022 04:22:05 +0000 (14:22 +1000)
The calculation of whether we should ignore a piece in
GetRequestablePieces ends up doing an allocation for every piece, when
all we really need to do is query the index in the torrent. Provide an
IgnorePiece function instead, which avoids the need for a temporary
allocation.

Observed to cut out 40% of object allocations in some workloads (large
download, lots of seeds).

request-strategy-impls.go
request-strategy/order.go
request-strategy/torrent.go

index f4c126466ba4e57ec6941f3768cb08bfb5a31a08..bf3e4083129de42bc76b2bd7c8df831987d711f5 100644 (file)
@@ -44,8 +44,15 @@ type requestStrategyTorrent struct {
        t *Torrent
 }
 
-func (r requestStrategyTorrent) Piece(i int) request_strategy.Piece {
-       return requestStrategyPiece{r.t, i}
+func (r requestStrategyTorrent) IgnorePiece(i int) bool {
+       if r.t.ignorePieceForRequests(i) {
+               return true
+       }
+       if r.t.pieceNumPendingChunks(i) == 0 {
+               return true
+       }
+
+       return false
 }
 
 func (r requestStrategyTorrent) ChunksPerPiece() uint32 {
index 130c698b9f9e6e75235ef0987fa4b68a73d762dc..09f1ff0c5863c7bf1a8abdd6d472b05ebc10be69 100644 (file)
@@ -54,7 +54,6 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(ih metainf
        pro.tree.Scan(func(_i pieceRequestOrderItem) bool {
                ih := _i.key.InfoHash
                var t Torrent = input.Torrent(ih)
-               var piece Piece = t.Piece(_i.key.Index)
                pieceLength := t.PieceLength()
                if storageLeft != nil {
                        if *storageLeft < pieceLength {
@@ -62,7 +61,7 @@ func GetRequestablePieces(input Input, pro *PieceRequestOrder, f func(ih metainf
                        }
                        *storageLeft -= pieceLength
                }
-               if !piece.Request() || piece.NumPendingChunks() == 0 {
+               if t.IgnorePiece(_i.key.Index) {
                        // TODO: Clarify exactly what is verified. Stuff that's being hashed should be
                        // considered unverified and hold up further requests.
                        return true
index 51fc1a6cc3516e86fbf1772fe68c916c9294ada6..2460f2e4df1296dbf02f93ef7d0a78ad0b671f63 100644 (file)
@@ -1,7 +1,7 @@
 package request_strategy
 
 type Torrent interface {
-       Piece(int) Piece
+       IgnorePiece(int) bool
        ChunksPerPiece() uint32
        PieceLength() int64
 }