From: Matt Joiner Date: Mon, 28 Jul 2025 02:17:50 +0000 (+1000) Subject: Make peer conns minimize request overlap with webseeds X-Git-Tag: v1.59.0~2^2~89 X-Git-Url: http://www.git.stargrave.org/?a=commitdiff_plain;h=adf5c4c5c16863b0367449c13c8fd5619493f461;p=btrtrc.git Make peer conns minimize request overlap with webseeds --- diff --git a/requesting.go b/requesting.go index 5ec3391d..63becb0a 100644 --- a/requesting.go +++ b/requesting.go @@ -1,6 +1,7 @@ package torrent import ( + "cmp" "context" "encoding/gob" "fmt" @@ -153,18 +154,32 @@ func (p *desiredPeerRequests) lessByValue(leftRequest, rightRequest RequestIndex // it will be served and therefore is the best candidate to cancel. ml = ml.CmpInt64(rightLast.Sub(leftLast).Nanoseconds()) } - ml = ml.Int( - leftPiece.Availability, - rightPiece.Availability) - if priority == PiecePriorityReadahead { - // TODO: For readahead in particular, it would be even better to consider distance from the - // 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) + // Just trigger on any webseed requests present on the Torrent. That suggests that the Torrent + // or files are prioritized enough to compete with PeerConn requests. Later we could filter on + // webseeds actually requesting or supporting requests for the pieces we're comparing. + if t.hasActiveWebseedRequests() { + // Prefer the highest possible request index, since webseeds prefer the lowest. Additionally, + // this should mean remote clients serve in reverse order so we meet webseeds responses in + // the middle. + ml = ml.Cmp(-cmp.Compare(leftRequest, rightRequest)) } else { - ml = ml.Int(t.pieceRequestOrder[leftPieceIndex], t.pieceRequestOrder[rightPieceIndex]) + ml = ml.Int( + leftPiece.Availability, + rightPiece.Availability) + if priority == PiecePriorityReadahead { + // TODO: For readahead in particular, it would be even better to consider distance from the + // 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 { + ml = ml.Int(t.pieceRequestOrder[leftPieceIndex], t.pieceRequestOrder[rightPieceIndex]) + } + ml = multiless.EagerOrdered(ml, leftRequest, rightRequest) } - return ml.Less() + // Prefer request indexes in order for storage write performance. Since the heap request heap + // does not contain duplicates, if we order at the request index level we should never have any + // ambiguity. + return ml.MustLess() } type desiredRequestState struct { diff --git a/torrent.go b/torrent.go index fc4f8cd7..e1d7b9a0 100644 --- a/torrent.go +++ b/torrent.go @@ -3594,3 +3594,23 @@ func (t *Torrent) fileMightBePartial(fileIndex int) bool { return true } } + +func (t *Torrent) requestIndexIsInActiveWebseedRequest(reqIndex RequestIndex) bool { + for _, p := range t.webSeeds { + for range p.activeRequestsForIndex(reqIndex) { + return true + } + } + return false +} + +func (t *Torrent) hasActiveWebseedRequests() bool { + for _, p := range t.webSeeds { + for req := range p.activeRequests { + if !req.cancelled.Load() { + return true + } + } + } + return false +}