From 4f793130b219ad3e24b9f0502a20f62c9ded0dad Mon Sep 17 00:00:00 2001 From: Matt Joiner Date: Mon, 21 Jul 2025 22:04:34 +1000 Subject: [PATCH] Ignore webseed request start offset in prioritization --- torrent.go | 2 +- webseed-requesting.go | 9 +++++---- webseed/client.go | 4 ++-- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/torrent.go b/torrent.go index ff6a4c93..e854c38a 100644 --- a/torrent.go +++ b/torrent.go @@ -179,7 +179,7 @@ type Torrent struct { connsWithAllPieces map[*Peer]struct{} - // Last active request for each chunks. TODO: Change to PeerConn specific? + // Last active PeerConn request for each chunk. requestState map[RequestIndex]requestState // Chunks we've written to since the corresponding piece was last checked. dirtyChunks typedRoaring.Bitmap[RequestIndex] diff --git a/webseed-requesting.go b/webseed-requesting.go index 71a1ec70..5d50f949 100644 --- a/webseed-requesting.go +++ b/webseed-requesting.go @@ -99,15 +99,16 @@ func (cl *Client) updateWebseedRequests() { aprioriHeap := heap.InterfaceForSlice( &heapSlice, func(l heapElem, r heapElem) bool { - // Prefer the highest priority, then existing requests, then longest remaining file extent. + // Prefer the highest priority, then existing requests, then largest files. return cmp.Or( -cmp.Compare(l.priority, r.priority), // Existing requests are assigned the priority of the piece they're reading next. compareBool(l.existingWebseedRequest == nil, r.existingWebseedRequest == nil), - // This won't thrash because we already preferred existing requests, so we'll finish out small extents. + // Note this isn't correct if the starting piece is split across multiple files. But + // I plan to refactor to key on starting piece to handle this case. -cmp.Compare( - l.t.Files()[l.fileIndex].length-l.startOffset, - r.t.Files()[r.fileIndex].length-r.startOffset), + l.t.Files()[l.fileIndex].length, + r.t.Files()[r.fileIndex].length), ) < 0 }, ) diff --git a/webseed/client.go b/webseed/client.go index a4d43274..babbe0f5 100644 --- a/webseed/client.go +++ b/webseed/client.go @@ -64,7 +64,7 @@ type Client struct { Logger *slog.Logger HttpClient *http.Client Url string - // Max concurrent requests to a WebSeed for a given torrent. + // Max concurrent requests to a WebSeed for a given torrent. TODO: Unused. MaxRequests int fileIndex *segments.Index @@ -73,7 +73,7 @@ type Client struct { // given that's how requests are mapped to webseeds, but the torrent.Client works at the piece // level. We can map our file-level adjustments to the pieces here. This probably need to be // private in the future, if Client ever starts removing pieces. TODO: This belongs in - // webseedPeer. + // webseedPeer. TODO: Unused. Pieces roaring.Bitmap // This wraps http.Response bodies, for example to limit the download rate. ResponseBodyWrapper ResponseBodyWrapper -- 2.51.0