From 623d9e0e0627c3ac2d8ef0f750746a5714d4d28a Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Sun, 7 Feb 2016 21:58:48 +1100 Subject: [PATCH] Rework requesting of shuffled pending pieces --- piece.go | 34 ++++++++++------------------------ torrent.go | 14 ++++++++------ 2 files changed, 18 insertions(+), 30 deletions(-) diff --git a/piece.go b/piece.go index 9f22d718..bcc09546 100644 --- a/piece.go +++ b/piece.go @@ -1,11 +1,9 @@ package torrent import ( - "math/rand" "sync" "github.com/anacrolix/missinggo/bitmap" - "github.com/bradfitz/iter" pp "github.com/anacrolix/torrent/peer_protocol" ) @@ -30,7 +28,9 @@ const ( type piece struct { // The completed piece SHA1 hash, from the metainfo "pieces" field. - Hash pieceSum + Hash pieceSum + t *torrent + index int // Chunks we've written to since the last check. The chunk offset and // length can be determined by the request chunkSize in use. DirtyChunks bitmap.Bitmap @@ -77,27 +77,13 @@ func chunkIndexSpec(index int, pieceLength, chunkSize pp.Integer) chunkSpec { return ret } -func (p *piece) shuffledPendingChunkSpecs(t *torrent, piece int) (css []chunkSpec) { - // defer func() { - // log.Println(piece, css) - // }() - numPending := t.pieceNumPendingChunks(piece) - if numPending == 0 { - return - } - css = make([]chunkSpec, 0, numPending) - for ci := range iter.N(t.pieceNumChunks(piece)) { - if !p.DirtyChunks.Contains(ci) { - css = append(css, t.chunkIndexSpec(ci, piece)) - } - } - if len(css) <= 1 { - return - } - for i := range css { - j := rand.Intn(i + 1) - css[i], css[j] = css[j], css[i] - } +func (p *piece) numChunks() int { + return p.t.pieceNumChunks(p.index) +} + +func (p *piece) undirtiedChunkIndices() (ret bitmap.Bitmap) { + ret = p.DirtyChunks.Copy() + ret.FlipRange(0, p.numChunks()) return } diff --git a/torrent.go b/torrent.go index d1764875..5f7807c8 100644 --- a/torrent.go +++ b/torrent.go @@ -14,6 +14,7 @@ import ( "github.com/anacrolix/missinggo" "github.com/anacrolix/missinggo/bitmap" + "github.com/anacrolix/missinggo/itertools" "github.com/anacrolix/missinggo/perf" "github.com/anacrolix/missinggo/pubsub" "github.com/bradfitz/iter" @@ -252,6 +253,8 @@ func (t *torrent) setMetadata(md *metainfo.Info, infoBytes []byte) (err error) { t.Pieces = make([]piece, len(hashes)) for i, hash := range hashes { piece := &t.Pieces[i] + piece.t = t + piece.index = i piece.noPendingWrites.L = &piece.pendingWritesMutex missinggo.CopyExact(piece.Hash[:], hash) } @@ -997,12 +1000,11 @@ func (t *torrent) connRequestPiecePendingChunks(c *connection, piece int) (more if !c.PeerHasPiece(piece) { return true } - for _, cs := range t.Pieces[piece].shuffledPendingChunkSpecs(t, piece) { - req := request{pp.Integer(piece), cs} - if !c.Request(req) { - return false - } - } + chunkIndices := t.Pieces[piece].undirtiedChunkIndices().ToSortedSlice() + return itertools.ForPerm(len(chunkIndices), func(i int) bool { + req := request{pp.Integer(piece), t.chunkIndexSpec(chunkIndices[i], piece)} + return c.Request(req) + }) return true } -- 2.48.1