]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Rework requesting of shuffled pending pieces
authorMatt Joiner <anacrolix@gmail.com>
Sun, 7 Feb 2016 10:58:48 +0000 (21:58 +1100)
committerMatt Joiner <anacrolix@gmail.com>
Sun, 7 Feb 2016 10:58:48 +0000 (21:58 +1100)
piece.go
torrent.go

index 9f22d718b9f918ec309ffc835f500aefa25112bf..bcc09546c11f4f34f3cee0ae03e9f1fb04695694 100644 (file)
--- a/piece.go
+++ b/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
 }
 
index d1764875bc12188dbf6a2af314d6b10292024ff3..5f7807c8c3f4d6226f11b53a3d871c06f2f41085 100644 (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
 }