12 g "github.com/anacrolix/generics"
13 "github.com/anacrolix/squirrel"
15 "github.com/anacrolix/torrent/metainfo"
16 "github.com/anacrolix/torrent/storage"
19 // A convenience function that creates a connection pool, resource provider, and a pieces storage
20 // ClientImpl and returns them all with a Close attached.
21 func NewDirectStorage(opts NewDirectStorageOpts) (_ storage.ClientImplCloser, err error) {
22 cache, err := squirrel.NewCache(opts)
31 // Creates a storage.ClientImpl from a provided squirrel.Cache. The caller is responsible for
32 // closing the squirrel.Cache.
33 func NewWrappingClient(cache *squirrel.Cache) storage.ClientImpl {
42 capacityFetched time.Time
47 func (c *client) Close() error {
48 return c.cache.Close()
51 func (c *client) capacity() (cap int64, capped bool) {
53 defer c.capacityMu.Unlock()
54 if !c.capacityFetched.IsZero() && time.Since(c.capacityFetched) < time.Second {
55 cap, capped = c.capacityCap, c.capacityCapped
58 c.capacityCap, c.capacityCapped = c.cache.GetCapacity()
59 // Should this go before or after the capacityCap and capacityCapped assignments?
60 c.capacityFetched = time.Now()
61 cap, capped = c.capacityCap, c.capacityCapped
65 func (c *client) OpenTorrent(*metainfo.Info, metainfo.Hash) (storage.TorrentImpl, error) {
68 return storage.TorrentImpl{PieceWithHash: t.Piece, Close: t.Close, Capacity: &capFunc}, nil
75 func (t torrent) Piece(p metainfo.Piece, pieceHash g.Option[[]byte]) storage.PieceImpl {
77 sb: t.c.OpenWithLength(hex.EncodeToString(pieceHash.Unwrap()), p.Length()),
79 ret.ReaderAt = &ret.sb
80 ret.WriterAt = &ret.sb
84 func (t torrent) Close() error {
94 func (p piece) MarkComplete() error {
95 return p.sb.SetTag("verified", true)
98 func (p piece) MarkNotComplete() error {
99 return p.sb.SetTag("verified", false)
102 func (p piece) Completion() (ret storage.Completion) {
103 err := p.sb.GetTag("verified", func(stmt squirrel.SqliteStmt) {
104 ret.Complete = stmt.ColumnInt(0) != 0