Skip to content

Commit

Permalink
add support for pebbledb
Browse files Browse the repository at this point in the history
  • Loading branch information
web-flow committed Mar 15, 2023
1 parent 25056d0 commit d05701f
Show file tree
Hide file tree
Showing 8 changed files with 1,031 additions and 10 deletions.
7 changes: 6 additions & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,14 @@ test-badgerdb:
@go test $(PACKAGES) -tags badgerdb -v
.PHONY: test-badgerdb

test-pebbledb:
@echo "--> Running go test"
@go test $(PACKAGES) -tags pebbledb -v
PHONY: test-pebbledb

test-all:
@echo "--> Running go test"
@go test $(PACKAGES) -tags cleveldb,boltdb,rocksdb,badgerdb -v
@go test $(PACKAGES) -tags cleveldb,boltdb,rocksdb,badgerdb,pebbledb -v
.PHONY: test-all

test-all-with-coverage:
Expand Down
5 changes: 5 additions & 0 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,11 @@ const (
RocksDBBackend BackendType = "rocksdb"

BadgerDBBackend BackendType = "badgerdb"

// PebbleDBDBBackend represents pebble (uses github.com/cockroachdb/pebble)
// - EXPERIMENTAL
// - use pebble build tag (go build -tags pebbledb)
PebbleDBBackend BackendType = "pebbledb"
)

type dbCreator func(name string, dir string) (DB, error)
Expand Down
22 changes: 19 additions & 3 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ module github.com/cometbft/cometbft-db
go 1.18

require (
github.com/cockroachdb/pebble v0.0.0-20230315005856-dcb60b9212f9
github.com/dgraph-io/badger/v2 v2.2007.4
github.com/gogo/protobuf v1.3.2
github.com/google/btree v1.1.2
Expand All @@ -15,16 +16,31 @@ require (
)

require (
github.com/DataDog/zstd v1.4.5 // indirect
github.com/beorn7/perks v1.0.1 // indirect
github.com/cespare/xxhash v1.1.0 // indirect
github.com/cespare/xxhash/v2 v2.2.0 // indirect
github.com/cockroachdb/errors v1.8.1 // indirect
github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f // indirect
github.com/cockroachdb/redact v1.0.8 // indirect
github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/dgraph-io/ristretto v0.0.3-0.20200630154024-f66de99634de // indirect
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/klauspost/compress v1.12.3 // indirect
github.com/pkg/errors v0.8.1 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/klauspost/compress v1.15.15 // indirect
github.com/kr/pretty v0.2.1 // indirect
github.com/kr/text v0.2.0 // indirect
github.com/matttproud/golang_protobuf_extensions v1.0.2-0.20181231171920-c182affec369 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/prometheus/client_golang v1.12.0 // indirect
github.com/prometheus/client_model v0.2.1-0.20210607210712-147c58e9608a // indirect
github.com/prometheus/common v0.32.1 // indirect
github.com/prometheus/procfs v0.7.3 // indirect
golang.org/x/exp v0.0.0-20200513190911-00229845015e // indirect
golang.org/x/net v0.4.0 // indirect
golang.org/x/sys v0.3.0 // indirect
golang.org/x/text v0.5.0 // indirect
Expand Down
538 changes: 532 additions & 6 deletions go.sum

Large diffs are not rendered by default.

215 changes: 215 additions & 0 deletions pebble.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,215 @@
package db

import (
"fmt"
"path/filepath"

"github.com/cockroachdb/pebble"
)

func init() {
dbCreator := func(name string, dir string) (DB, error) {
return NewPebbleDB(name, dir)
}
registerDBCreator(PebbleDBBackend, dbCreator, false)
}

// PebbleDB is a PebbleDB backend.
type PebbleDB struct {
db *pebble.DB
}

var _ DB = (*PebbleDB)(nil)

func NewPebbleDB(name string, dir string) (DB, error) {
dbPath := filepath.Join(dir, name+".db")
// cache := pebble.NewCache(1024 * 1024 * 32)
// defer cache.Unref()
opts := &pebble.Options{
// Cache: cache,
// FormatMajorVersion: pebble.FormatNewest,
// L0CompactionThreshold: 2,
// L0StopWritesThreshold: 1000,
// LBaseMaxBytes: 64 << 20, // 64 MB
// Levels: make([]pebble.LevelOptions, 7),
// MaxConcurrentCompactions: 3,
// MaxOpenFiles: 1024,
// MemTableSize: 64 << 20,
// MemTableStopWritesThreshold: 4,
}
/*
for i := 0; i < len(opts.Levels); i++ {
l := &opts.Levels[i]
l.BlockSize = 32 << 10 // 32 KB
l.IndexBlockSize = 256 << 10 // 256 KB
l.FilterPolicy = bloom.FilterPolicy(10)
l.FilterType = pebble.TableFilter
if i > 0 {
l.TargetFileSize = opts.Levels[i-1].TargetFileSize * 2
}
l.EnsureDefaults()
}
*/
// opts.Levels[6].FilterPolicy = nil
// opts.FlushSplitBytes = opts.Levels[0].TargetFileSize

opts.EnsureDefaults()

p, err := pebble.Open(dbPath, opts)
if err != nil {
return nil, err
}
return &PebbleDB{
db: p,
}, err
}

// Get implements DB.
func (db *PebbleDB) Get(key []byte) ([]byte, error) {
if len(key) == 0 {
return nil, errKeyEmpty
}
res, closer, err := db.db.Get(key)
if err != nil {
return res, nil
}
closer.Close()
return res, nil
}

// Has implements DB.
func (db *PebbleDB) Has(key []byte) (bool, error) {
if len(key) == 0 {
return false, errKeyEmpty
}
bytes, err := db.Get(key)
if err != nil {
return false, err
}
return bytes != nil, nil
}

// Set implements DB.
func (db *PebbleDB) Set(key []byte, value []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
if value == nil {
return errValueNil
}
err := db.db.Set(key, value, pebble.NoSync)
if err != nil {
return err
}
return nil
}

// SetSync implements DB.
func (db *PebbleDB) SetSync(key []byte, value []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
if value == nil {
return errValueNil
}
err := db.db.Set(key, value, pebble.Sync)
if err != nil {
return err
}
return nil
}

// Delete implements DB.
func (db *PebbleDB) Delete(key []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
err := db.db.Delete(key, pebble.NoSync)
if err != nil {
return err
}
return nil
}

// DeleteSync implements DB.
func (db PebbleDB) DeleteSync(key []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
err := db.db.Delete(key, pebble.Sync)
if err != nil {
return nil
}
return nil
}

func (db *PebbleDB) DB() *pebble.DB {
return db.db
}

// Close implements DB.
func (db PebbleDB) Close() error {
db.db.Close()
return nil
}

// Print implements DB.
func (db *PebbleDB) Print() error {
itr, err := db.Iterator(nil, nil)
if err != nil {
return err
}
defer itr.Close()
for ; itr.Valid(); itr.Next() {
key := itr.Key()
value := itr.Value()
fmt.Printf("[%X]:\t[%X]\n", key, value)
}
return nil
}

// Stats implements DB.
func (db *PebbleDB) Stats() map[string]string {
/*
keys := []string{"rocksdb.stats"}
stats := make(map[string]string, len(keys))
for _, key := range keys {
stats[key] = db.(key)
}
*/
return nil
}

// NewBatch implements DB.
func (db *PebbleDB) NewBatch() Batch {
return newPebbleDBBatch(db)
}

// Iterator implements DB.
func (db *PebbleDB) Iterator(start, end []byte) (Iterator, error) {
if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) {
return nil, errKeyEmpty
}
o := pebble.IterOptions{
LowerBound: start,
UpperBound: end,
}
itr := db.db.NewIter(&o)
itr.First()

return newPebbleDBIterator(itr, start, end, false), nil
}

// ReverseIterator implements DB.
func (db *PebbleDB) ReverseIterator(start, end []byte) (Iterator, error) {
if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) {
return nil, errKeyEmpty
}
o := pebble.IterOptions{
LowerBound: start,
UpperBound: end,
}
itr := db.db.NewIter(&o)
itr.Last()
return newPebbleDBIterator(itr, start, end, true), nil
}
83 changes: 83 additions & 0 deletions pebble_batch.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
package db

import "github.com/cockroachdb/pebble"

type pebbleDBBatch struct {
db *PebbleDB
batch *pebble.Batch
}

var _ Batch = (*pebbleDBBatch)(nil)

func newPebbleDBBatch(db *PebbleDB) *pebbleDBBatch {
return &pebbleDBBatch{
batch: db.db.NewBatch(),
}
}

// Set implements Batch.
func (b *pebbleDBBatch) Set(key, value []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
if value == nil {
return errValueNil
}
if b.batch == nil {
return errBatchClosed
}
b.batch.Set(key, value, nil)
return nil
}

// Delete implements Batch.
func (b *pebbleDBBatch) Delete(key []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
if b.batch == nil {
return errBatchClosed
}
b.batch.Delete(key, nil)
return nil
}

// Write implements Batch.
func (b *pebbleDBBatch) Write() error {
if b.batch == nil {
return errBatchClosed
}
err := b.batch.Commit(pebble.NoSync)
if err != nil {
return err
}
// Make sure batch cannot be used afterwards. Callers should still call Close(), for errors.

return b.Close()
}

// WriteSync implements Batch.
func (b *pebbleDBBatch) WriteSync() error {
if b.batch == nil {
return errBatchClosed
}
err := b.batch.Commit(pebble.Sync)
if err != nil {
return err
}
// Make sure batch cannot be used afterwards. Callers should still call Close(), for errors.
return b.Close()
}

// Close implements Batch.
func (b *pebbleDBBatch) Close() error {
if b.batch != nil {
err := b.batch.Close()
if err != nil {
return err
}
b.batch = nil
}

return nil
}
Loading

0 comments on commit d05701f

Please sign in to comment.