]> Sergey Matveev's repositories - btrtrc.git/commitdiff
Allocate Torrent file segments index just once
authorMatt Joiner <anacrolix@gmail.com>
Fri, 18 Jul 2025 13:08:15 +0000 (23:08 +1000)
committerMatt Joiner <anacrolix@gmail.com>
Fri, 18 Jul 2025 13:08:15 +0000 (23:08 +1000)
piece.go
torrent.go
webseed-peer.go
webseed/client.go

index 597cd190520307d1c2c4bc9eac2dc80318ad5274..fc17714b1b05c5a9e7e606ed6b32a8807d4eba48 100644 (file)
--- a/piece.go
+++ b/piece.go
@@ -451,7 +451,7 @@ func (p *Piece) publishStateChange() {
 }
 
 func (p *Piece) fileExtents(offsetIntoPiece int64) iter.Seq2[int, segments.Extent] {
-       return p.t.info.FileSegmentsIndex().LocateIter(segments.Extent{
+       return p.t.fileSegmentsIndex.Unwrap().LocateIter(segments.Extent{
                p.torrentBeginOffset() + offsetIntoPiece,
                int64(p.length()) - offsetIntoPiece,
        })
index aab918a8c3696fb82937325335b5d4e04bde2988..104733f9b824635511a96741b661210e21556645 100644 (file)
@@ -35,6 +35,7 @@ import (
        "github.com/anacrolix/missinggo/v2/pubsub"
        "github.com/anacrolix/multiless"
        "github.com/anacrolix/sync"
+       "github.com/anacrolix/torrent/segments"
        "github.com/pion/webrtc/v4"
        "golang.org/x/sync/errgroup"
        "golang.org/x/time/rate"
@@ -115,8 +116,9 @@ type Torrent struct {
        // routines. Cancelled when the Torrent is Closed too.
        getInfoCtx context.Context
        // Put a nice reason in :)
-       getInfoCtxCancel context.CancelCauseFunc
-       files            *[]*File
+       getInfoCtxCancel  context.CancelCauseFunc
+       files             *[]*File
+       fileSegmentsIndex g.Option[segments.Index]
 
        _chunksPerRegularPiece chunkIndexType
 
@@ -380,7 +382,8 @@ func (t *Torrent) invalidateMetadata() {
                t.metadataCompletedChunks[i] = false
        }
        t.nameMu.Lock()
-       t.info = nil
+       // Why the fuck would info be set?
+       panicif.NotNil(t.info)
        t.nameMu.Unlock()
 }
 
@@ -538,6 +541,7 @@ func (t *Torrent) setInfo(info *metainfo.Info) error {
        }
        t.nameMu.Lock()
        t.info = info
+       panicif.True(t.fileSegmentsIndex.Set(info.FileSegmentsIndex()).Ok)
        t.getInfoCtxCancel(errors.New("got info"))
        t.nameMu.Unlock()
        t._chunksPerRegularPiece = chunkIndexType(intCeilDiv(pp.Integer(t.usualPieceSize()), t.chunkSize))
index 1a131f1271e0c31521119bb3d8e128d7bf65fecc..b7c7a54ff1cd74ba6a8ef7ff4f797bab494974f2 100644 (file)
@@ -90,7 +90,7 @@ func (ws *webseedPeer) String() string {
 }
 
 func (ws *webseedPeer) onGotInfo(info *metainfo.Info) {
-       ws.client.SetInfo(info)
+       ws.client.SetInfo(info, ws.peer.t.fileSegmentsIndex.UnwrapPtr())
        // There should be probably be a callback in Client instead, so it can remove pieces at its whim
        // too.
        ws.client.Pieces.Iterate(func(x uint32) bool {
index f6e03da509e3ede9817ff3fb801460ce8e35a632..a4d432747d38cb6e0a05e417b38d0f38b5018892 100644 (file)
@@ -67,8 +67,7 @@ type Client struct {
        // Max concurrent requests to a WebSeed for a given torrent.
        MaxRequests int
 
-       // TODO: Share this with Torrent.
-       fileIndex segments.Index
+       fileIndex *segments.Index
        info      *metainfo.Info
        // The pieces we can request with the Url. We're more likely to ban/block at the file-level
        // given that's how requests are mapped to webseeds, but the torrent.Client works at the piece
@@ -84,13 +83,13 @@ type Client struct {
 
 type ResponseBodyWrapper func(io.Reader) io.Reader
 
-func (me *Client) SetInfo(info *metainfo.Info) {
+func (me *Client) SetInfo(info *metainfo.Info, fileIndex *segments.Index) {
        if !strings.HasSuffix(me.Url, "/") && info.IsDir() {
                // In my experience, this is a non-conforming webseed. For example the
                // http://ia600500.us.archive.org/1/items URLs in archive.org torrents.
                return
        }
-       me.fileIndex = info.FileSegmentsIndex()
+       me.fileIndex = fileIndex
        me.info = info
        me.Pieces.AddRange(0, uint64(info.NumPieces()))
 }