if t.PieceNumPendingBytes(index) == t.PieceLength(index) {
break
}
- for chunkSpec := range t.Pieces[index].PendingChunkSpecs {
- if !c.Request(request{index, chunkSpec}) {
+ // Request chunks in random order to reduce overlap with other
+ // connections.
+ for _, cs := range t.Pieces[index].shuffledPendingChunkSpecs() {
+ if !c.Request(request{index, cs}) {
return
}
}
"bitbucket.org/anacrolix/go.torrent/mmap_span"
"crypto"
"errors"
+ "math/rand"
"os"
"path/filepath"
"time"
const (
pieceHash = crypto.SHA1
- maxRequests = 250 // Maximum pending requests we allow peers to send us.
+ maxRequests = 250 // Maximum pending requests we allow peers to send us.
chunkSize = 0x4000 // 16KiB
BEP20 = "-GT0000-" // Peer ID client identifier prefix
dialTimeout = time.Second * 15
EverHashed bool
}
+func (p *piece) shuffledPendingChunkSpecs() (css []chunkSpec) {
+ css = make([]chunkSpec, 0, len(p.PendingChunkSpecs))
+ for cs := range p.PendingChunkSpecs {
+ css = append(css, cs)
+ }
+ for i := range css {
+ j := rand.Intn(i + 1)
+ css[i], css[j] = css[j], css[i]
+ }
+ return
+}
+
func (p *piece) Complete() bool {
return len(p.PendingChunkSpecs) == 0 && p.EverHashed
}
return
}
+func (t *torrent) UsualPieceSize() int {
+ return int(t.MetaInfo.PieceLength)
+}
+
func (t *torrent) LastPieceSize() int {
return int(t.PieceLength(pp.Integer(t.NumPieces() - 1)))
}