github.com/anacrolix/torrent@v1.61.0/request-strategy-impls.go (about)

     1  package torrent
     2  
     3  import (
     4  	g "github.com/anacrolix/generics"
     5  
     6  	requestStrategy "github.com/anacrolix/torrent/internal/request-strategy"
     7  	"github.com/anacrolix/torrent/metainfo"
     8  	"github.com/anacrolix/torrent/storage"
     9  )
    10  
    11  type requestStrategyInputCommon struct {
    12  	maxUnverifiedBytes int64
    13  }
    14  
    15  func (r requestStrategyInputCommon) MaxUnverifiedBytes() int64 {
    16  	return r.maxUnverifiedBytes
    17  }
    18  
    19  type requestStrategyInputMultiTorrent struct {
    20  	requestStrategyInputCommon
    21  	torrents map[metainfo.Hash]*Torrent
    22  	capFunc  storage.TorrentCapacity
    23  }
    24  
    25  func (r requestStrategyInputMultiTorrent) Torrent(ih metainfo.Hash) requestStrategy.Torrent {
    26  	return requestStrategyTorrent{g.MapMustGet(r.torrents, ih)}
    27  }
    28  
    29  func (r requestStrategyInputMultiTorrent) Capacity() (int64, bool) {
    30  	return (*r.capFunc)()
    31  }
    32  
    33  // I don't think we need this for correctness purposes, but it must be faster to look up the Torrent
    34  // input because it's locked to a given Torrent. It would be easy enough to drop in the
    35  // multi-torrent version in this place and compare. TODO: With unique.Handle on infohash, this would
    36  // not be necessary anymore. I don't think it's provided any performance benefit for some time now.
    37  type requestStrategyInputSingleTorrent struct {
    38  	requestStrategyInputCommon
    39  	t *Torrent
    40  }
    41  
    42  func (r requestStrategyInputSingleTorrent) Torrent(_ metainfo.Hash) requestStrategy.Torrent {
    43  	return requestStrategyTorrent{r.t}
    44  }
    45  
    46  func (r requestStrategyInputSingleTorrent) Capacity() (cap int64, capped bool) {
    47  	return 0, false
    48  }
    49  
    50  var _ requestStrategy.Input = requestStrategyInputSingleTorrent{}
    51  
    52  // getRequestStrategyInputCommon returns request strategy Input implementation common to all inputs.
    53  func (cl *Client) getRequestStrategyInputCommon() requestStrategyInputCommon {
    54  	return requestStrategyInputCommon{cl.config.MaxUnverifiedBytes}
    55  }
    56  
    57  func (t *Torrent) getRequestStrategyInput() requestStrategy.Input {
    58  	return t.clientPieceRequestOrderKey().getRequestStrategyInput(t.cl)
    59  }
    60  
    61  // Wraps a Torrent to provide request-strategy.Torrent interface.
    62  type requestStrategyTorrent struct {
    63  	t *Torrent
    64  }
    65  
    66  func (r requestStrategyTorrent) Piece(i int) requestStrategy.Piece {
    67  	return requestStrategyPiece{r.t.piece(i)}
    68  }
    69  
    70  func (r requestStrategyTorrent) PieceLength() int64 {
    71  	return r.t.info.PieceLength
    72  }
    73  
    74  var _ requestStrategy.Torrent = requestStrategyTorrent{}
    75  
    76  type requestStrategyPiece struct {
    77  	p *Piece
    78  }
    79  
    80  func (r requestStrategyPiece) CountUnverified() bool {
    81  	return r.p.hashing || r.p.marking || r.p.queuedForHash()
    82  }
    83  
    84  func (r requestStrategyPiece) Request() bool {
    85  	return r.p.effectivePriority() > PiecePriorityNone
    86  }
    87  
    88  var _ requestStrategy.Piece = requestStrategyPiece{}