From: Matt Joiner <anacrolix@gmail.com>
Date: Wed, 28 May 2014 15:32:34 +0000 (+1000)
Subject: Shuffle chunk spec request order for readahead pieces
X-Git-Tag: v1.0.0~1719
X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=26116a7df83fbc8ede9b31354d025359ddf7feba;p=btrtrc.git

Shuffle chunk spec request order for readahead pieces

Should reduce overlap in received chunks.
---

diff --git a/client.go b/client.go
index e079881a..e86a93a9 100644
--- 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 2e5f02bb..c53976fa 100644
--- 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
 }
diff --git a/torrent.go b/torrent.go
index dfe24314..cbb4cd32 100644
--- a/torrent.go
+++ b/torrent.go
@@ -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)))
 }