]> Sergey Matveev's repositories - btrtrc.git/blob - request-strategy-impls.go
Improve handling of v2 hashes
[btrtrc.git] / request-strategy-impls.go
1 package torrent
2
3 import (
4         g "github.com/anacrolix/generics"
5
6         "github.com/anacrolix/torrent/metainfo"
7         request_strategy "github.com/anacrolix/torrent/request-strategy"
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) request_strategy.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 type requestStrategyInputSingleTorrent struct {
34         requestStrategyInputCommon
35         t *Torrent
36 }
37
38 func (r requestStrategyInputSingleTorrent) Torrent(_ metainfo.Hash) request_strategy.Torrent {
39         return requestStrategyTorrent{r.t}
40 }
41
42 func (r requestStrategyInputSingleTorrent) Capacity() (cap int64, capped bool) {
43         return 0, false
44 }
45
46 var _ request_strategy.Input = requestStrategyInputSingleTorrent{}
47
48 func (cl *Client) getRequestStrategyInputCommon() requestStrategyInputCommon {
49         return requestStrategyInputCommon{cl.config.MaxUnverifiedBytes}
50 }
51
52 // Returns what is necessary to run request_strategy.GetRequestablePieces for primaryTorrent.
53 func (cl *Client) getRequestStrategyInput(primaryTorrent *Torrent) (input request_strategy.Input) {
54         if !primaryTorrent.hasStorageCap() {
55                 return requestStrategyInputSingleTorrent{
56                         requestStrategyInputCommon: cl.getRequestStrategyInputCommon(),
57                         t:                          primaryTorrent,
58                 }
59         } else {
60                 return requestStrategyInputMultiTorrent{
61                         requestStrategyInputCommon: cl.getRequestStrategyInputCommon(),
62                         // TODO: Check this is an appropriate key
63                         torrents: cl.torrentsByShortHash,
64                         capFunc:  primaryTorrent.storage.Capacity,
65                 }
66         }
67 }
68
69 func (t *Torrent) getRequestStrategyInput() request_strategy.Input {
70         return t.cl.getRequestStrategyInput(t)
71 }
72
73 type requestStrategyTorrent struct {
74         t *Torrent
75 }
76
77 func (r requestStrategyTorrent) Piece(i int) request_strategy.Piece {
78         return requestStrategyPiece{r.t.piece(i)}
79 }
80
81 func (r requestStrategyTorrent) PieceLength() int64 {
82         return r.t.info.PieceLength
83 }
84
85 var _ request_strategy.Torrent = requestStrategyTorrent{}
86
87 type requestStrategyPiece struct {
88         p *Piece
89 }
90
91 func (r requestStrategyPiece) Request() bool {
92         return !r.p.ignoreForRequests()
93 }
94
95 func (r requestStrategyPiece) NumPendingChunks() int {
96         return int(r.p.t.pieceNumPendingChunks(r.p.index))
97 }
98
99 var _ request_strategy.Piece = (*requestStrategyPiece)(nil)