requesting.go | 4 +--- torrent.go | 7 ++++++- diff --git a/requesting.go b/requesting.go index f1831346e816cc2508d96e8e3b79ff055ac31cbd..b781316d0bf75b6b16d8f7b61b4172cd616b3890 100644 --- a/requesting.go +++ b/requesting.go @@ -156,9 +156,7 @@ // reader position so that reads earlier in a torrent don't starve reads later in the // torrent. This would probably require reconsideration of how readahead priority works. ml = ml.Int(leftPieceIndex, rightPieceIndex) } else { - // TODO: To prevent unnecessarily requesting from disparate pieces, and to ensure pieces are - // selected randomly when availability is even, there should be some fixed ordering of - // pieces. + ml = ml.Int(t.pieceRequestOrder[leftPieceIndex], t.pieceRequestOrder[rightPieceIndex]) } return ml.Less() } diff --git a/torrent.go b/torrent.go index dbfbea18ef2a5d8998bd283605724e5eefd325e6..55ba2230fe6eea449d9d0c62c1df55f95b41145d 100644 --- a/torrent.go +++ b/torrent.go @@ -8,6 +8,7 @@ "crypto/sha1" "errors" "fmt" "io" + "math/rand" "net/netip" "net/url" "sort" @@ -62,6 +63,9 @@ closed chansync.SetOnce infoHash metainfo.Hash pieces []Piece + + // The order pieces are requested if there's no stronger reason like availability or priority. + pieceRequestOrder []int // Values are the piece indices that changed. pieceStateChanges pubsub.PubSub[PieceStateChange] // The size of chunks to request from peers over the wire. This is @@ -459,6 +463,7 @@ } // This seems to be all the follow-up tasks after info is set, that can't fail. func (t *Torrent) onSetInfo() { + t.pieceRequestOrder = rand.Perm(t.numPieces()) t.initPieceRequestOrder() MakeSliceWithLength(&t.requestState, t.numChunks()) MakeSliceWithLength(&t.requestPieceStates, t.numPieces()) @@ -849,7 +854,7 @@ return int(t.info.PieceLength) } func (t *Torrent) numPieces() pieceIndex { - return pieceIndex(t.info.NumPieces()) + return t.info.NumPieces() } func (t *Torrent) numPiecesCompleted() (num pieceIndex) {