1 //go:build !noboltdb && !wasm
2 // +build !noboltdb,!wasm
12 "github.com/anacrolix/torrent/metainfo"
15 type boltPiece struct {
23 _ PieceImpl = (*boltPiece)(nil)
24 dataBucketKey = []byte("data")
27 func (me *boltPiece) pc() PieceCompletionGetSetter {
28 return boltPieceCompletion{me.db}
31 func (me *boltPiece) pk() metainfo.PieceKey {
32 return metainfo.PieceKey{me.ih, me.p.Index()}
35 func (me *boltPiece) Completion() Completion {
36 c, err := me.pc().Get(me.pk())
38 case bbolt.ErrDatabaseNotOpen:
47 func (me *boltPiece) MarkComplete() error {
48 return me.pc().Set(me.pk(), true)
51 func (me *boltPiece) MarkNotComplete() error {
52 return me.pc().Set(me.pk(), false)
54 func (me *boltPiece) ReadAt(b []byte, off int64) (n int, err error) {
55 err = me.db.View(func(tx *bbolt.Tx) error {
56 db := tx.Bucket(dataBucketKey)
63 ck := me.chunkKey(int(ci))
65 // If the chunk is the wrong size, assume it's missing as we can't rely on the data.
66 if len(_b) != chunkSize {
69 n1 := copy(b, _b[off:])
80 func (me *boltPiece) chunkKey(index int) (ret [26]byte) {
81 copy(ret[:], me.key[:])
82 binary.BigEndian.PutUint16(ret[24:], uint16(index))
86 func (me *boltPiece) WriteAt(b []byte, off int64) (n int, err error) {
87 err = me.db.Update(func(tx *bbolt.Tx) error {
88 db, err := tx.CreateBucketIfNotExists(dataBucketKey)
95 _b := make([]byte, chunkSize)
96 ck := me.chunkKey(int(ci))
97 copy(_b, db.Get(ck[:]))
98 n1 := copy(_b[off:], b)