diff --git a/issue97_test.go b/issue97_test.go index 2091b758..04a2c4be 100644 --- a/issue97_test.go +++ b/issue97_test.go @@ -19,6 +19,7 @@ func TestHashPieceAfterStorageClosed(t *testing.T) { tt := &Torrent{ storageOpener: storage.NewClient(storage.NewFile(td)), logger: log.Default, + chunkSize: defaultChunkSize, } mi := testutil.GreetingMetaInfo() info, err := mi.UnmarshalInfo() diff --git a/piece.go b/piece.go index 411b187c..6b70a5b5 100644 --- a/piece.go +++ b/piece.go @@ -8,7 +8,6 @@ import ( "github.com/RoaringBitmap/roaring" "github.com/anacrolix/chansync" "github.com/anacrolix/missinggo/v2/bitmap" - request_strategy "github.com/anacrolix/torrent/request-strategy" "github.com/anacrolix/torrent/metainfo" pp "github.com/anacrolix/torrent/peer_protocol" @@ -41,6 +40,8 @@ type Piece struct { // Connections that have written data to this piece since its last check. // This can include connections that have closed. dirtiers map[*Peer]struct{} + + undirtiedChunksIter undirtiedChunksIter } func (p *Piece) String() string { @@ -244,13 +245,14 @@ func init() { gob.Register(undirtiedChunksIter{}) } +// Use an iterator to jump between dirty bits. type undirtiedChunksIter struct { TorrentDirtyChunks *roaring.Bitmap StartRequestIndex RequestIndex EndRequestIndex RequestIndex } -func (me undirtiedChunksIter) Iter(f func(chunkIndexType)) { +func (me *undirtiedChunksIter) Iter(f func(chunkIndexType)) { it := me.TorrentDirtyChunks.Iterator() startIndex := me.StartRequestIndex endIndex := me.EndRequestIndex @@ -272,29 +274,6 @@ func (me undirtiedChunksIter) Iter(f func(chunkIndexType)) { return } -func (p *Piece) undirtiedChunksIter() request_strategy.ChunksIter { - // Use an iterator to jump between dirty bits. - return undirtiedChunksIter{ - TorrentDirtyChunks: &p.t.dirtyChunks, - StartRequestIndex: p.requestIndexOffset(), - EndRequestIndex: p.requestIndexOffset() + p.numChunks(), - } -} - -func (p *Piece) iterUndirtiedChunks(f func(chunkIndexType)) { - if true { - p.undirtiedChunksIter().Iter(f) - return - } - // The original implementation. - for i := chunkIndexType(0); i < p.numChunks(); i++ { - if p.chunkIndexDirty(i) { - continue - } - f(i) - } -} - func (p *Piece) requestIndexOffset() RequestIndex { return p.t.pieceRequestIndexOffset(p.index) } diff --git a/requesting.go b/requesting.go index 0ec4151b..ed20ba80 100644 --- a/requesting.go +++ b/requesting.go @@ -46,7 +46,7 @@ func (cl *Client) getRequestStrategyInput() request_strategy.Input { Availability: p.availability, Length: int64(p.length()), NumPendingChunks: int(t.pieceNumPendingChunks(i)), - IterPendingChunks: p.undirtiedChunksIter(), + IterPendingChunks: &p.undirtiedChunksIter, }) } t.iterPeers(func(p *Peer) { diff --git a/torrent.go b/torrent.go index b4898364..e9295824 100644 --- a/torrent.go +++ b/torrent.go @@ -363,6 +363,11 @@ func (t *Torrent) makePieces() { beginFile := pieceFirstFileIndex(piece.torrentBeginOffset(), files) endFile := pieceEndFileIndex(piece.torrentEndOffset(), files) piece.files = files[beginFile:endFile] + piece.undirtiedChunksIter = undirtiedChunksIter{ + TorrentDirtyChunks: &t.dirtyChunks, + StartRequestIndex: piece.requestIndexOffset(), + EndRequestIndex: piece.requestIndexOffset() + piece.numChunks(), + } } }