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{}