7 "github.com/anacrolix/missinggo/x"
8 bolt "github.com/etcd-io/bbolt"
10 "github.com/anacrolix/torrent/metainfo"
13 type boltDBPiece struct {
21 _ PieceImpl = (*boltDBPiece)(nil)
22 dataBucketKey = []byte("data")
25 func (me *boltDBPiece) pc() PieceCompletionGetSetter {
26 return boltPieceCompletion{me.db}
29 func (me *boltDBPiece) pk() metainfo.PieceKey {
30 return metainfo.PieceKey{me.ih, me.p.Index()}
33 func (me *boltDBPiece) Completion() Completion {
34 c, err := me.pc().Get(me.pk())
39 func (me *boltDBPiece) MarkComplete() error {
40 return me.pc().Set(me.pk(), true)
43 func (me *boltDBPiece) MarkNotComplete() error {
44 return me.pc().Set(me.pk(), false)
46 func (me *boltDBPiece) ReadAt(b []byte, off int64) (n int, err error) {
47 err = me.db.View(func(tx *bolt.Tx) error {
48 db := tx.Bucket(dataBucketKey)
55 ck := me.chunkKey(int(ci))
57 // If the chunk is the wrong size, assume it's missing as we can't rely on the data.
58 if len(_b) != chunkSize {
61 n1 := copy(b, _b[off:])
72 func (me *boltDBPiece) chunkKey(index int) (ret [26]byte) {
73 copy(ret[:], me.key[:])
74 binary.BigEndian.PutUint16(ret[24:], uint16(index))
78 func (me *boltDBPiece) WriteAt(b []byte, off int64) (n int, err error) {
79 err = me.db.Update(func(tx *bolt.Tx) error {
80 db, err := tx.CreateBucketIfNotExists(dataBucketKey)
87 _b := make([]byte, chunkSize)
88 ck := me.chunkKey(int(ci))
89 copy(_b, db.Get(ck[:]))
90 n1 := copy(_b[off:], b)