request-strategy-impls.go 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. package torrent
  2. import (
  3. g "github.com/anacrolix/generics"
  4. "github.com/anacrolix/torrent/metainfo"
  5. request_strategy "github.com/anacrolix/torrent/request-strategy"
  6. "github.com/anacrolix/torrent/storage"
  7. )
  8. type requestStrategyInputCommon struct {
  9. maxUnverifiedBytes int64
  10. }
  11. func (r requestStrategyInputCommon) MaxUnverifiedBytes() int64 {
  12. return r.maxUnverifiedBytes
  13. }
  14. type requestStrategyInputMultiTorrent struct {
  15. requestStrategyInputCommon
  16. torrents map[metainfo.Hash]*Torrent
  17. capFunc storage.TorrentCapacity
  18. }
  19. func (r requestStrategyInputMultiTorrent) Torrent(ih metainfo.Hash) request_strategy.Torrent {
  20. return requestStrategyTorrent{g.MapMustGet(r.torrents, ih)}
  21. }
  22. func (r requestStrategyInputMultiTorrent) Capacity() (int64, bool) {
  23. return (*r.capFunc)()
  24. }
  25. type requestStrategyInputSingleTorrent struct {
  26. requestStrategyInputCommon
  27. t *Torrent
  28. }
  29. func (r requestStrategyInputSingleTorrent) Torrent(_ metainfo.Hash) request_strategy.Torrent {
  30. return requestStrategyTorrent{r.t}
  31. }
  32. func (r requestStrategyInputSingleTorrent) Capacity() (cap int64, capped bool) {
  33. return 0, false
  34. }
  35. var _ request_strategy.Input = requestStrategyInputSingleTorrent{}
  36. func (cl *Client) getRequestStrategyInputCommon() requestStrategyInputCommon {
  37. return requestStrategyInputCommon{cl.config.MaxUnverifiedBytes}
  38. }
  39. // Returns what is necessary to run request_strategy.GetRequestablePieces for primaryTorrent.
  40. func (cl *Client) getRequestStrategyInput(primaryTorrent *Torrent) (input request_strategy.Input) {
  41. if !primaryTorrent.hasStorageCap() {
  42. return requestStrategyInputSingleTorrent{
  43. requestStrategyInputCommon: cl.getRequestStrategyInputCommon(),
  44. t: primaryTorrent,
  45. }
  46. } else {
  47. return requestStrategyInputMultiTorrent{
  48. requestStrategyInputCommon: cl.getRequestStrategyInputCommon(),
  49. // TODO: Check this is an appropriate key
  50. torrents: cl.torrentsByShortHash,
  51. capFunc: primaryTorrent.storage.Capacity,
  52. }
  53. }
  54. }
  55. func (t *Torrent) getRequestStrategyInput() request_strategy.Input {
  56. return t.cl.getRequestStrategyInput(t)
  57. }
  58. type requestStrategyTorrent struct {
  59. t *Torrent
  60. }
  61. func (r requestStrategyTorrent) Piece(i int) request_strategy.Piece {
  62. return requestStrategyPiece{r.t.piece(i)}
  63. }
  64. func (r requestStrategyTorrent) PieceLength() int64 {
  65. return r.t.info.PieceLength
  66. }
  67. var _ request_strategy.Torrent = requestStrategyTorrent{}
  68. type requestStrategyPiece struct {
  69. p *Piece
  70. }
  71. func (r requestStrategyPiece) CountUnverified() bool {
  72. return r.p.hashing || r.p.marking || r.p.queuedForHash()
  73. }
  74. func (r requestStrategyPiece) Request() bool {
  75. return !r.p.ignoreForRequests() && r.p.purePriority() != PiecePriorityNone
  76. }
  77. var _ request_strategy.Piece = requestStrategyPiece{}