go.mod | 2 +- go.sum | 2 ++ request-strategy/order.go | 12 +++++++++--- request-strategy/torrent.go | 6 +++++- storage/disabled/disabled.go | 10 ++-------- storage/interface.go | 8 ++++++-- storage/sqlite/direct.go | 2 +- diff --git a/go.mod b/go.mod index 843bee23cf5ee840c94461d3ad90a0c1e7cca69d..edad54ca15696017af2303cb3354ba26d408fb6b 100644 --- a/go.mod +++ b/go.mod @@ -16,7 +16,7 @@ github.com/anacrolix/missinggo v1.3.0 github.com/anacrolix/missinggo/perf v1.0.0 github.com/anacrolix/missinggo/v2 v2.5.2 github.com/anacrolix/multiless v0.1.1-0.20210529082330-de2f6cf29619 - github.com/anacrolix/squirrel v0.1.0 + github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a github.com/anacrolix/sync v0.4.0 github.com/anacrolix/tagflag v1.3.0 github.com/anacrolix/upnp v0.1.2-0.20200416075019-5e9378ed1425 diff --git a/go.sum b/go.sum index 507f5040eb79e3dc7a3548f11db74c609b446923..eb9323d5439858dfaf391e37e1b426b4d867956b 100644 --- a/go.sum +++ b/go.sum @@ -124,6 +124,8 @@ github.com/anacrolix/multiless v0.1.1-0.20210529082330-de2f6cf29619 h1:ZkusP2EHxvxm+IymiKJ8DBVE/E6fJkb8K/2+GXZpjAY= github.com/anacrolix/multiless v0.1.1-0.20210529082330-de2f6cf29619/go.mod h1:TrCLEZfIDbMVfLoQt5tOoiBS/uq4y8+ojuEVVvTNPX4= github.com/anacrolix/squirrel v0.1.0 h1:Zz7XUFUr2ozhsTvzwLdmrFpduoTHtBNTB/KZQ4Ivh00= github.com/anacrolix/squirrel v0.1.0/go.mod h1:YzgVvikMdFD441oTWlNG189bpKabO9Sbf3uCSVgca04= +github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a h1:8LAUQgDPqnzuF/WrGQzTY6i+bVO/FpA90Hi6jXA+2vQ= +github.com/anacrolix/squirrel v0.1.1-0.20210914065657-81bc5ecdc43a/go.mod h1:YzgVvikMdFD441oTWlNG189bpKabO9Sbf3uCSVgca04= github.com/anacrolix/stm v0.1.0/go.mod h1:ZKz7e7ERWvP0KgL7WXfRjBXHNRhlVRlbBQecqFtPq+A= github.com/anacrolix/stm v0.1.1-0.20191106051447-e749ba3531cf/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg= github.com/anacrolix/stm v0.2.0/go.mod h1:zoVQRvSiGjGoTmbM0vSLIiaKjWtNPeTvXUSdJQA4hsg= diff --git a/request-strategy/order.go b/request-strategy/order.go index e2b8e51e25480199718b14266baffd5d76dc785b..92125c14dbfb4000f8d476930209cc161164b321 100644 --- a/request-strategy/order.go +++ b/request-strategy/order.go @@ -6,6 +6,7 @@ "sort" "sync" "github.com/anacrolix/multiless" + "github.com/anacrolix/torrent/storage" pp "github.com/anacrolix/torrent/peer_protocol" "github.com/anacrolix/torrent/types" @@ -96,8 +97,8 @@ } pieces := make([]filterPiece, 0, maxPieces) ret = make([]requestablePiece, 0, maxPieces) // Storage capacity left for this run, keyed by the storage capacity pointer on the storage - // TorrentImpl. - storageLeft := make(map[*func() *int64]*int64) + // TorrentImpl. A nil value means no capacity limit. + storageLeft := make(map[storage.TorrentCapacity]*int64) for _t := range input.Torrents { // TODO: We could do metainfo requests here. t := &filterTorrent{ @@ -107,7 +108,12 @@ } key := t.Capacity if key != nil { if _, ok := storageLeft[key]; !ok { - storageLeft[key] = (*key)() + capacity, ok := (*key)() + if ok { + storageLeft[key] = &capacity + } else { + storageLeft[key] = nil + } } t.storageLeft = storageLeft[key] } diff --git a/request-strategy/torrent.go b/request-strategy/torrent.go index 2090c7a87903e239541603a389a8ccac52647fad..c7ed3c60b8a0aec70a0e6cfb494cf29f3735a2e6 100644 --- a/request-strategy/torrent.go +++ b/request-strategy/torrent.go @@ -1,8 +1,12 @@ package request_strategy +import ( + "github.com/anacrolix/torrent/storage" +) + type Torrent struct { Pieces []Piece - Capacity *func() *int64 + Capacity storage.TorrentCapacity Peers []Peer // not closed. // Some value that's unique and stable between runs. Could even use the infohash? StableId uintptr diff --git a/storage/disabled/disabled.go b/storage/disabled/disabled.go index 22d51434ee2cabd977759f0db7035c813b69c1c8..f511222ae2114dc44c68fd8059629b72083e2099 100644 --- a/storage/disabled/disabled.go +++ b/storage/disabled/disabled.go @@ -9,11 +9,9 @@ ) type Client struct{} -var capacity int64 - func (c Client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage.TorrentImpl, error) { - capFunc := func() *int64 { - return &capacity + capFunc := func() (int64, bool) { + return 0, true } return storage.TorrentImpl{ Piece: func(piece metainfo.Piece) storage.PieceImpl { @@ -24,10 +22,6 @@ return nil }, Capacity: &capFunc, }, nil -} - -func (c Client) capacity() *int64 { - return &capacity } type Piece struct{} diff --git a/storage/interface.go b/storage/interface.go index a52ee6dca1cbc05e42033c164b56ca34515b28c2..ee6e6336cdb8e7bf6ccb08f31e2aa07dd6a97210 100644 --- a/storage/interface.go +++ b/storage/interface.go @@ -16,12 +16,16 @@ type ClientImpl interface { OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (TorrentImpl, error) } +type TorrentCapacity *func() (cap int64, capped bool) + // Data storage bound to a torrent. type TorrentImpl struct { Piece func(p metainfo.Piece) PieceImpl Close func() error - // Storages that share the same value, will provide a pointer to the same function. - Capacity *func() *int64 + // Storages that share the same space, will provide equal pointers. The function is called once + // to determine the storage for torrents sharing the same function pointer, and mutated in + // place. + Capacity TorrentCapacity } // Interacts with torrent piece data. Optional interfaces to implement include: diff --git a/storage/sqlite/direct.go b/storage/sqlite/direct.go index b36867fac3ce3457a0c9be2ad46b2c80ab5849d2..4fda7d0cbef6f21bc52d82a61d09571a223aa981 100644 --- a/storage/sqlite/direct.go +++ b/storage/sqlite/direct.go @@ -35,7 +35,7 @@ } type client struct { *squirrel.Cache - capacity func() *int64 + capacity func() (int64, bool) } func (c *client) OpenTorrent(info *metainfo.Info, infoHash metainfo.Hash) (storage.TorrentImpl, error) {