Rework requesting of shuffled pending pieces
This commit is contained in:
parent
54b538d322
commit
623d9e0e06
34
piece.go
34
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
|
||||
}
|
||||
|
||||
|
|
14
torrent.go
14
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
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue