2023-09-09 23:45:47 +00:00
|
|
|
package store
|
|
|
|
|
|
|
|
import (
|
2024-01-03 07:31:42 +00:00
|
|
|
"io"
|
|
|
|
|
2023-09-09 23:45:47 +00:00
|
|
|
"github.com/cockroachdb/pebble"
|
2024-03-23 20:26:57 +00:00
|
|
|
"github.com/pkg/errors"
|
2023-09-09 23:45:47 +00:00
|
|
|
"source.quilibrium.com/quilibrium/monorepo/node/config"
|
|
|
|
)
|
|
|
|
|
2024-01-03 07:31:42 +00:00
|
|
|
type PebbleDB struct {
|
|
|
|
db *pebble.DB
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewPebbleDB(config *config.DBConfig) *PebbleDB {
|
2023-09-09 23:45:47 +00:00
|
|
|
db, err := pebble.Open(config.Path, &pebble.Options{})
|
|
|
|
if err != nil {
|
|
|
|
panic(err)
|
|
|
|
}
|
|
|
|
|
2024-01-03 07:31:42 +00:00
|
|
|
return &PebbleDB{db}
|
2023-09-09 23:45:47 +00:00
|
|
|
}
|
|
|
|
|
2024-01-03 07:31:42 +00:00
|
|
|
func (p *PebbleDB) Get(key []byte) ([]byte, io.Closer, error) {
|
|
|
|
return p.db.Get(key)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) Set(key, value []byte) error {
|
|
|
|
return p.db.Set(key, value, &pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) Delete(key []byte) error {
|
|
|
|
return p.db.Delete(key, &pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) NewBatch() Transaction {
|
|
|
|
return &PebbleTransaction{
|
|
|
|
b: p.db.NewBatch(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) NewIter(lowerBound []byte, upperBound []byte) (
|
|
|
|
Iterator,
|
|
|
|
error,
|
|
|
|
) {
|
|
|
|
return p.db.NewIter(&pebble.IterOptions{
|
|
|
|
LowerBound: lowerBound,
|
|
|
|
UpperBound: upperBound,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) Compact(start, end []byte, parallelize bool) error {
|
|
|
|
return p.db.Compact(start, end, parallelize)
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) Close() error {
|
|
|
|
return p.db.Close()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (p *PebbleDB) DeleteRange(start, end []byte) error {
|
|
|
|
return p.db.DeleteRange(start, end, &pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
2024-03-23 20:26:57 +00:00
|
|
|
func (p *PebbleDB) CompactAll() error {
|
|
|
|
iter, err := p.db.NewIter(nil)
|
|
|
|
if err != nil {
|
|
|
|
return errors.Wrap(err, "compact all")
|
|
|
|
}
|
|
|
|
|
|
|
|
var first, last []byte
|
|
|
|
if iter.First() {
|
|
|
|
first = append(first, iter.Key()...)
|
|
|
|
}
|
|
|
|
if iter.Last() {
|
|
|
|
last = append(last, iter.Key()...)
|
|
|
|
}
|
|
|
|
if err := iter.Close(); err != nil {
|
|
|
|
return errors.Wrap(err, "compact all")
|
|
|
|
}
|
|
|
|
|
2024-03-24 08:11:00 +00:00
|
|
|
if err := p.Compact(first, last, false); err != nil {
|
2024-03-23 20:26:57 +00:00
|
|
|
return errors.Wrap(err, "compact all")
|
|
|
|
}
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
2024-01-03 07:31:42 +00:00
|
|
|
var _ KVDB = (*PebbleDB)(nil)
|
|
|
|
|
2023-09-09 23:45:47 +00:00
|
|
|
type Transaction interface {
|
2024-06-21 17:46:36 +00:00
|
|
|
Get(key []byte) ([]byte, io.Closer, error)
|
2023-09-09 23:45:47 +00:00
|
|
|
Set(key []byte, value []byte) error
|
|
|
|
Commit() error
|
|
|
|
Delete(key []byte) error
|
2023-09-27 09:05:39 +00:00
|
|
|
Abort() error
|
2024-06-21 17:46:36 +00:00
|
|
|
NewIter(lowerBound []byte, upperBound []byte) (Iterator, error)
|
2023-09-09 23:45:47 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type PebbleTransaction struct {
|
|
|
|
b *pebble.Batch
|
|
|
|
}
|
|
|
|
|
2024-06-21 17:46:36 +00:00
|
|
|
func (t *PebbleTransaction) Get(key []byte) ([]byte, io.Closer, error) {
|
|
|
|
return t.b.Get(key)
|
|
|
|
}
|
|
|
|
|
2023-09-09 23:45:47 +00:00
|
|
|
func (t *PebbleTransaction) Set(key []byte, value []byte) error {
|
|
|
|
return t.b.Set(key, value, &pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *PebbleTransaction) Commit() error {
|
|
|
|
return t.b.Commit(&pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
|
|
|
func (t *PebbleTransaction) Delete(key []byte) error {
|
|
|
|
return t.b.Delete(key, &pebble.WriteOptions{Sync: true})
|
|
|
|
}
|
|
|
|
|
2023-09-27 09:05:39 +00:00
|
|
|
func (t *PebbleTransaction) Abort() error {
|
|
|
|
return t.b.Close()
|
|
|
|
}
|
|
|
|
|
2024-06-21 17:46:36 +00:00
|
|
|
func (t *PebbleTransaction) NewIter(lowerBound []byte, upperBound []byte) (
|
|
|
|
Iterator,
|
|
|
|
error,
|
|
|
|
) {
|
|
|
|
return t.b.NewIter(&pebble.IterOptions{
|
|
|
|
LowerBound: lowerBound,
|
|
|
|
UpperBound: upperBound,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2023-09-09 23:45:47 +00:00
|
|
|
var _ Transaction = (*PebbleTransaction)(nil)
|
|
|
|
|
|
|
|
func rightAlign(data []byte, size int) []byte {
|
|
|
|
l := len(data)
|
|
|
|
|
|
|
|
if l == size {
|
|
|
|
return data
|
|
|
|
}
|
|
|
|
|
|
|
|
if l > size {
|
|
|
|
return data[l-size:]
|
|
|
|
}
|
|
|
|
|
|
|
|
pad := make([]byte, size)
|
|
|
|
copy(pad[size-l:], data)
|
|
|
|
return pad
|
|
|
|
}
|