github.com/lbryio/lbcd@v0.22.119/claimtrie/block/blockrepo/pebble.go (about)

     1  package blockrepo
     2  
     3  import (
     4  	"encoding/binary"
     5  
     6  	"github.com/pkg/errors"
     7  
     8  	"github.com/lbryio/lbcd/chaincfg/chainhash"
     9  
    10  	"github.com/cockroachdb/pebble"
    11  )
    12  
    13  type Pebble struct {
    14  	db *pebble.DB
    15  }
    16  
    17  func NewPebble(path string) (*Pebble, error) {
    18  
    19  	db, err := pebble.Open(path, &pebble.Options{MaxOpenFiles: 2000})
    20  	repo := &Pebble{db: db}
    21  
    22  	return repo, errors.Wrapf(err, "unable to open %s", path)
    23  }
    24  
    25  func (repo *Pebble) Load() (int32, error) {
    26  
    27  	iter := repo.db.NewIter(nil)
    28  	if !iter.Last() {
    29  		err := iter.Close()
    30  		return 0, errors.Wrap(err, "closing iterator with no last")
    31  	}
    32  
    33  	height := int32(binary.BigEndian.Uint32(iter.Key()))
    34  	err := iter.Close()
    35  	return height, errors.Wrap(err, "closing iterator")
    36  }
    37  
    38  func (repo *Pebble) Get(height int32) (*chainhash.Hash, error) {
    39  
    40  	key := make([]byte, 4)
    41  	binary.BigEndian.PutUint32(key, uint32(height))
    42  
    43  	b, closer, err := repo.db.Get(key)
    44  	if closer != nil {
    45  		defer closer.Close()
    46  	}
    47  	if err != nil {
    48  		return nil, errors.Wrap(err, "in get")
    49  	}
    50  	hash, err := chainhash.NewHash(b)
    51  	return hash, errors.Wrap(err, "creating hash")
    52  }
    53  
    54  func (repo *Pebble) Set(height int32, hash *chainhash.Hash) error {
    55  
    56  	key := make([]byte, 4)
    57  	binary.BigEndian.PutUint32(key, uint32(height))
    58  
    59  	return errors.WithStack(repo.db.Set(key, hash[:], pebble.NoSync))
    60  }
    61  
    62  func (repo *Pebble) Delete(heightMin, heightMax int32) error {
    63  	lower := make([]byte, 4)
    64  	binary.BigEndian.PutUint32(lower, uint32(heightMin))
    65  
    66  	upper := make([]byte, 4)
    67  	binary.BigEndian.PutUint32(upper, uint32(heightMax)+1)
    68  
    69  	return errors.Wrap(repo.db.DeleteRange(lower, upper, pebble.NoSync), "on range delete")
    70  }
    71  
    72  func (repo *Pebble) Close() error {
    73  
    74  	err := repo.db.Flush()
    75  	if err != nil {
    76  		// if we fail to close are we going to try again later?
    77  		return errors.Wrap(err, "on flush")
    78  	}
    79  
    80  	err = repo.db.Close()
    81  	return errors.Wrap(err, "on close")
    82  }
    83  
    84  func (repo *Pebble) Flush() error {
    85  	_, err := repo.db.AsyncFlush()
    86  	return err
    87  }