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  }