]> Sergey Matveev's repositories - btrtrc.git/blob - request-strategy-impls.go
Implement decoding hash request, reject and 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                         torrents:                   cl.torrents,
63                         capFunc:                    primaryTorrent.storage.Capacity,
64                 }
65         }
66 }
67
68 func (t *Torrent) getRequestStrategyInput() request_strategy.Input {
69         return t.cl.getRequestStrategyInput(t)
70 }
71
72 type requestStrategyTorrent struct {
73         t *Torrent
74 }
75
76 func (r requestStrategyTorrent) Piece(i int) request_strategy.Piece {
77         return (*requestStrategyPiece)(r.t.piece(i))
78 }
79
80 func (r requestStrategyTorrent) PieceLength() int64 {
81         return r.t.info.PieceLength
82 }
83
84 var _ request_strategy.Torrent = requestStrategyTorrent{}
85
86 type requestStrategyPiece Piece
87
88 func (r *requestStrategyPiece) Request() bool {
89         return !r.t.ignorePieceForRequests(r.index)
90 }
91
92 func (r *requestStrategyPiece) NumPendingChunks() int {
93         return int(r.t.pieceNumPendingChunks(r.index))
94 }
95
96 var _ request_strategy.Piece = (*requestStrategyPiece)(nil)