Avoid allocation putting undirtiedChunksIter into interface

This commit is contained in:
Matt Joiner 2021-10-13 15:17:48 +11:00
parent 529aaa9b1f
commit de87fd3eb1
4 changed files with 11 additions and 26 deletions

View File

@ -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()

View File

@ -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)
}

View File

@ -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) {

View File

@ -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(),
}
}
}