]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Shuffle chunk spec request order for readahead pieces
authorMatt Joiner <anacrolix@gmail.com>
Wed, 28 May 2014 15:32:34 +0000 (01:32 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Wed, 28 May 2014 15:32:34 +0000 (01:32 +1000)
Should reduce overlap in received chunks.

client.go
misc.go
torrent.go

index e079881ab2b66d06cde800fc70cd49e21715dcee..e86a93a96df412566210be74e4eecd7675ba51d8 100644 (file)
--- a/client.go
+++ b/client.go
@@ -819,8 +819,10 @@ func (me *ResponsiveDownloadStrategy) FillRequests(t *torrent, c *connection) {
                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
                        }
                }
diff --git a/misc.go b/misc.go
index 2e5f02bb8a24c0c86fb3baae343ba06ea4c8cd5e..c53976fab111780ed960fa0e54e983c2b46c78ed 100644 (file)
--- a/misc.go
+++ b/misc.go
@@ -4,6 +4,7 @@ import (
        "bitbucket.org/anacrolix/go.torrent/mmap_span"
        "crypto"
        "errors"
+       "math/rand"
        "os"
        "path/filepath"
        "time"
@@ -15,7 +16,7 @@ import (
 
 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
@@ -46,6 +47,18 @@ type piece struct {
        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
 }
index dfe2431433e109cbda4dcc2114148f37704a5e63..cbb4cd3221cf9494eb158f57dfbb9fa70e6d067c 100644 (file)
@@ -59,6 +59,10 @@ func (t *torrent) ChunkCount() (num int) {
        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)))
 }