]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Restore request strategy Torrent.Piece use, without a heap allocation
authorMatt Joiner <anacrolix@gmail.com>
Thu, 8 Feb 2024 06:58:12 +0000 (17:58 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Thu, 8 Feb 2024 06:58:12 +0000 (17:58 +1100)
request-strategy-impls.go
request-strategy-impls_test.go [new file with mode: 0644]
request-strategy/order.go
request-strategy/torrent.go

index 0b05ed41b0da43bba65255c9c07316387a12161a..5d91e64aa95df2695bdc3e02eea274bcbd63f2e4 100644 (file)
@@ -44,15 +44,8 @@ type requestStrategyTorrent struct {
        t *Torrent
 }
 
-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) Piece(i int) request_strategy.Piece {
+       return (*requestStrategyPiece)(r.t.piece(i))
 }
 
 func (r requestStrategyTorrent) PieceLength() int64 {
@@ -61,17 +54,14 @@ func (r requestStrategyTorrent) PieceLength() int64 {
 
 var _ request_strategy.Torrent = requestStrategyTorrent{}
 
-type requestStrategyPiece struct {
-       t *Torrent
-       i pieceIndex
-}
+type requestStrategyPiece Piece
 
-func (r requestStrategyPiece) Request() bool {
-       return !r.t.ignorePieceForRequests(r.i)
+func (r *requestStrategyPiece) Request() bool {
+       return !r.t.ignorePieceForRequests(r.index)
 }
 
-func (r requestStrategyPiece) NumPendingChunks() int {
-       return int(r.t.pieceNumPendingChunks(r.i))
+func (r *requestStrategyPiece) NumPendingChunks() int {
+       return int(r.t.pieceNumPendingChunks(r.index))
 }
 
-var _ request_strategy.Piece = requestStrategyPiece{}
+var _ request_strategy.Piece = (*requestStrategyPiece)(nil)
diff --git a/request-strategy-impls_test.go b/request-strategy-impls_test.go
new file mode 100644 (file)
index 0000000..f0d3fa1
--- /dev/null
@@ -0,0 +1,29 @@
+package torrent
+
+import (
+       "io"
+       "runtime"
+       "testing"
+
+       "github.com/davecgh/go-spew/spew"
+       qt "github.com/frankban/quicktest"
+
+       request_strategy "github.com/anacrolix/torrent/request-strategy"
+)
+
+func makeRequestStrategyPiece(t request_strategy.Torrent) request_strategy.Piece {
+       return t.Piece(0)
+}
+
+func TestRequestStrategyPieceDoesntAlloc(t *testing.T) {
+       c := qt.New(t)
+       akshalTorrent := &Torrent{pieces: make([]Piece, 1)}
+       rst := requestStrategyTorrent{akshalTorrent}
+       var before, after runtime.MemStats
+       runtime.ReadMemStats(&before)
+       p := makeRequestStrategyPiece(rst)
+       runtime.ReadMemStats(&after)
+       c.Assert(before.HeapAlloc, qt.Equals, after.HeapAlloc)
+       // We have to use p, or it gets optimized away.
+       spew.Fdump(io.Discard, p)
+}
index df656f6db06c941d0ba4e442cee472b2ec038784..92793f58fd39ff895770b197feadbc974f999f5a 100644 (file)
@@ -66,7 +66,8 @@ func GetRequestablePieces(
                lastItem.Set(_i)
 
                ih := _i.key.InfoHash
-               t := input.Torrent(ih)
+               var t Torrent = input.Torrent(ih)
+               var piece Piece = t.Piece(_i.key.Index)
                pieceLength := t.PieceLength()
                if storageLeft != nil {
                        if *storageLeft < pieceLength {
@@ -74,7 +75,7 @@ func GetRequestablePieces(
                        }
                        *storageLeft -= pieceLength
                }
-               if t.IgnorePiece(_i.key.Index) {
+               if !piece.Request() || piece.NumPendingChunks() == 0 {
                        // TODO: Clarify exactly what is verified. Stuff that's being hashed should be
                        // considered unverified and hold up further requests.
                        return true
index 5bc438ee558b59b037c7c31afb746973585dc9b0..690f8b6dafb6d9df2eb3edf7f9c9ecddebfa2f8b 100644 (file)
@@ -1,6 +1,6 @@
 package requestStrategy
 
 type Torrent interface {
-       IgnorePiece(int) bool
+       Piece(int) Piece
        PieceLength() int64
 }