Rework requesting of shuffled pending pieces

This commit is contained in:
Matt Joiner 2016-02-07 21:58:48 +11:00
parent 54b538d322
commit 623d9e0e06
2 changed files with 18 additions and 30 deletions

View File

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

View File

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