1 //go:build !noboltdb && !wasm
2 // +build !noboltdb,!wasm
14 "github.com/anacrolix/torrent/metainfo"
18 boltDbCompleteValue = "c"
19 boltDbIncompleteValue = "i"
22 var completionBucketKey = []byte("completion")
24 type boltPieceCompletion struct {
28 var _ PieceCompletion = (*boltPieceCompletion)(nil)
30 func NewBoltPieceCompletion(dir string) (ret PieceCompletion, err error) {
31 os.MkdirAll(dir, 0o750)
32 p := filepath.Join(dir, ".torrent.bolt.db")
33 db, err := bbolt.Open(p, 0o660, &bbolt.Options{
40 ret = &boltPieceCompletion{db}
44 func (me boltPieceCompletion) Get(pk metainfo.PieceKey) (cn Completion, err error) {
45 err = me.db.View(func(tx *bbolt.Tx) error {
46 cb := tx.Bucket(completionBucketKey)
50 ih := cb.Bucket(pk.InfoHash[:])
55 binary.BigEndian.PutUint32(key[:], uint32(pk.Index))
57 switch string(ih.Get(key[:])) {
58 case boltDbCompleteValue:
60 case boltDbIncompleteValue:
70 func (me boltPieceCompletion) Set(pk metainfo.PieceKey, b bool) error {
71 if c, err := me.Get(pk); err == nil && c.Ok && c.Complete == b {
74 return me.db.Update(func(tx *bbolt.Tx) error {
75 c, err := tx.CreateBucketIfNotExists(completionBucketKey)
79 ih, err := c.CreateBucketIfNotExists(pk.InfoHash[:])
84 binary.BigEndian.PutUint32(key[:], uint32(pk.Index))
85 return ih.Put(key[:], []byte(func() string {
87 return boltDbCompleteValue
89 return boltDbIncompleteValue
95 func (me *boltPieceCompletion) Close() error {