github.com/lbryio/lbcd@v0.22.119/claimtrie/chain/chainrepo/pebble.go (about) 1 package chainrepo 2 3 import ( 4 "encoding/binary" 5 6 "github.com/pkg/errors" 7 8 "github.com/lbryio/lbcd/claimtrie/change" 9 "github.com/vmihailenco/msgpack/v5" 10 11 "github.com/cockroachdb/pebble" 12 ) 13 14 type Pebble struct { 15 db *pebble.DB 16 } 17 18 func NewPebble(path string) (*Pebble, error) { 19 20 db, err := pebble.Open(path, &pebble.Options{BytesPerSync: 64 << 20, MaxOpenFiles: 2000}) 21 repo := &Pebble{db: db} 22 23 return repo, errors.Wrapf(err, "open %s", path) 24 } 25 26 func (repo *Pebble) Save(height int32, changes []change.Change) error { 27 28 if len(changes) == 0 { 29 return nil 30 } 31 32 var key [4]byte 33 binary.BigEndian.PutUint32(key[:], uint32(height)) 34 35 value, err := msgpack.Marshal(changes) 36 if err != nil { 37 return errors.Wrap(err, "in marshaller") 38 } 39 40 err = repo.db.Set(key[:], value, pebble.NoSync) 41 return errors.Wrap(err, "in set") 42 } 43 44 func (repo *Pebble) Load(height int32) ([]change.Change, error) { 45 46 var key [4]byte 47 binary.BigEndian.PutUint32(key[:], uint32(height)) 48 49 b, closer, err := repo.db.Get(key[:]) 50 if closer != nil { 51 defer closer.Close() 52 } 53 if err != nil { 54 return nil, errors.Wrap(err, "in get") 55 } 56 57 var changes []change.Change 58 err = msgpack.Unmarshal(b, &changes) 59 return changes, errors.Wrap(err, "in unmarshaller") 60 } 61 62 func (repo *Pebble) Close() error { 63 64 err := repo.db.Flush() 65 if err != nil { 66 // if we fail to close are we going to try again later? 67 return errors.Wrap(err, "on flush") 68 } 69 70 err = repo.db.Close() 71 return errors.Wrap(err, "on close") 72 } 73 74 func (repo *Pebble) Flush() error { 75 _, err := repo.db.AsyncFlush() 76 return err 77 }