request-strategy-impls.go | 26 ++++++++------------------ request-strategy-impls_test.go | 29 +++++++++++++++++++++++++++++ request-strategy/order.go | 5 +++-- request-strategy/torrent.go | 2 +- diff --git a/request-strategy-impls.go b/request-strategy-impls.go index 0b05ed41b0da43bba65255c9c07316387a12161a..5d91e64aa95df2695bdc3e02eea274bcbd63f2e4 100644 --- a/request-strategy-impls.go +++ b/request-strategy-impls.go @@ -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 @@ } 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 index 0000000000000000000000000000000000000000..f0d3fa183fdbf488e5052cbf3f7c19599e095665 --- /dev/null +++ b/request-strategy-impls_test.go @@ -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) +} diff --git a/request-strategy/order.go b/request-strategy/order.go index df656f6db06c941d0ba4e442cee472b2ec038784..92793f58fd39ff895770b197feadbc974f999f5a 100644 --- a/request-strategy/order.go +++ b/request-strategy/order.go @@ -66,7 +66,8 @@ } 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 @@ return false } *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 diff --git a/request-strategy/torrent.go b/request-strategy/torrent.go index 5bc438ee558b59b037c7c31afb746973585dc9b0..690f8b6dafb6d9df2eb3edf7f9c9ecddebfa2f8b 100644 --- a/request-strategy/torrent.go +++ b/request-strategy/torrent.go @@ -1,6 +1,6 @@ package requestStrategy type Torrent interface { - IgnorePiece(int) bool + Piece(int) Piece PieceLength() int64 }