Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

added support for explicit compaction #111

Merged
merged 25 commits into from
Feb 7, 2024
Merged
Show file tree
Hide file tree
Changes from 15 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6b1bd33
Added compaction to bolt and badger
jmalicevic Jan 3, 2024
568d51c
Merge branch 'main' into jasmina/add-compaction-to-db
jmalicevic Jan 29, 2024
62c963c
Merge branch 'main' into jasmina/add-compaction-to-db
jmalicevic Jan 29, 2024
fc38cdf
Added compaction to pebble and removed stats from goleveldb
jmalicevic Jan 29, 2024
89480b4
Fixed lint
jmalicevic Jan 29, 2024
170fc4b
Added compact function to clevelDB
jmalicevic Jan 29, 2024
9adfbd1
Added compact function to batch DBs
jmalicevic Jan 29, 2024
b549715
Removed unused identifiers
jmalicevic Jan 29, 2024
ebd7873
Added call to compact from tests and expanded the batch interface
jmalicevic Jan 29, 2024
b2f411e
Merge branch 'main' into jasmina/add-compaction-to-db
jmalicevic Jan 30, 2024
a8118ce
Added compacton to test
jmalicevic Jan 30, 2024
7292b78
Added compacton to test-fix
jmalicevic Jan 30, 2024
e01569d
Fixed tests for pebbleDB
jmalicevic Jan 30, 2024
ee3ebc3
Fixed lint
jmalicevic Jan 30, 2024
3ae37a7
Added changelog
jmalicevic Jan 30, 2024
0876df8
Fixed typo
jmalicevic Jan 30, 2024
ef1cc29
Use go 1.20
jmalicevic Feb 5, 2024
86a630a
Merge branch 'jasmina/add-compaction-to-db' of github.com:cometbft/co…
jmalicevic Feb 6, 2024
0720335
Added comment on sleep in test
jmalicevic Feb 6, 2024
b17cefb
Removed compact from batch
jmalicevic Feb 6, 2024
ea11e09
Close iterator in defer
jmalicevic Feb 6, 2024
699b171
Merge branch 'main' into jasmina/add-compaction-to-db
jmalicevic Feb 6, 2024
0d786db
Reverted downgrading go version
jmalicevic Feb 7, 2024
cf6f5e8
Merge branch 'main' into jasmina/add-compaction-to-db
jmalicevic Feb 7, 2024
6c8b95e
Fixed compilation error
jmalicevic Feb 7, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Expanded db interface to support compaction ([\#111](https://github.com/cometbft/cometbft-db/pull/111))
1 change: 1 addition & 0 deletions .changelog/unreleased/features/111-compaction-support.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Add compaction support to the databases ([\#111](https://github.com/cometbft/cometbft-db/pull/111))
jmalicevic marked this conversation as resolved.
Show resolved Hide resolved
31 changes: 29 additions & 2 deletions backend_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@ import (
"fmt"
"os"
"path/filepath"
"strings"
"testing"
"time"

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
Expand Down Expand Up @@ -37,9 +39,10 @@ func testBackendGetSetDelete(t *testing.T, backend BackendType) {
// Default
dirname, err := os.MkdirTemp("", fmt.Sprintf("test_backend_%s_", backend))
require.Nil(t, err)
db, err := NewDB("testdb", backend, dirname)
name := fmt.Sprintf("testdb_%x", randStr(12))
db, err := NewDB(name, backend, dirname)
require.NoError(t, err)
defer cleanupDBDir(dirname, "testdb")
defer cleanupDBDir(dirname, name)

// A nonexistent key should return nil.
value, err := db.Get([]byte("a"))
Expand Down Expand Up @@ -133,6 +136,23 @@ func testBackendGetSetDelete(t *testing.T, backend BackendType) {
value, err = db.Get([]byte("x"))
require.NoError(t, err)
require.Equal(t, []byte{}, value)

err = db.Compact(nil, nil)
if strings.Contains(string(backend), "pebbledb") {
// In pebble the start and end will be the same so
// we expect an error
require.Error(t, err)
}

err = db.Set([]byte("y"), []byte{})
require.NoError(t, err)

err = db.Compact(nil, nil)
require.NoError(t, err)

if strings.Contains(string(backend), "pebbledb") {
jmalicevic marked this conversation as resolved.
Show resolved Hide resolved
time.Sleep(time.Second * 5)
}
}

func TestBackendsGetSetDelete(t *testing.T) {
Expand Down Expand Up @@ -306,6 +326,7 @@ func testDBIterator(t *testing.T, backend BackendType) {
// Ensure that the iterators don't panic with an empty database.
dir2, err := os.MkdirTemp("", "tm-db-test")
require.NoError(t, err)
name = fmt.Sprintf("test_%x", randStr(12))
db2, err := NewDB(name, backend, dir2)
require.NoError(t, err)
defer cleanupDBDir(dir2, name)
Expand Down Expand Up @@ -415,6 +436,12 @@ func testDBBatch(t *testing.T, backend BackendType) {
require.Error(t, batch.Delete([]byte("a")))
require.Error(t, batch.Write())
require.Error(t, batch.WriteSync())

require.NoError(t, batch.Compact(nil, nil))

if strings.Contains(string(backend), "pebbledb") {
time.Sleep(5 * time.Second)
jmalicevic marked this conversation as resolved.
Show resolved Hide resolved
}
}

func assertKeyValues(t *testing.T, db DB, expect map[string][]byte) {
Expand Down
9 changes: 9 additions & 0 deletions badger_db.go
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,11 @@ func (b *BadgerDB) Stats() map[string]string {
return nil
}

func (b *BadgerDB) Compact(start, end []byte) error {
// Explicit compaction is not currently supported in badger
return nil
}

func (b *BadgerDB) NewBatch() Batch {
wb := &badgerDBBatch{
db: b.db,
Expand Down Expand Up @@ -225,6 +230,10 @@ func (b *badgerDBBatch) WriteSync() error {
return withSync(b.db, b.Write())
}

func (*badgerDBBatch) Compact(start, end []byte) error {
return nil
}

func (b *badgerDBBatch) Close() error {
select {
case <-b.firstFlush: // a Flush after Cancel panics too
Expand Down
6 changes: 6 additions & 0 deletions boltdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -203,3 +203,9 @@ func (bdb *BoltDB) ReverseIterator(start, end []byte) (Iterator, error) {
}
return newBoltDBIterator(tx, start, end, true), nil
}

func (bdb *BoltDB) Compact(start, end []byte) error {
// There is no explicit CompactRange support in BoltDB, only a function that copies the
// entire DB from one place to another while doing deletions. Hence we do not support it.
return nil
}
4 changes: 4 additions & 0 deletions boltdb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,3 +85,7 @@ func (b *boltDBBatch) Close() error {
b.ops = nil
return nil
}

func (*boltDBBatch) Compact(start, end []byte) error {
return nil
}
7 changes: 7 additions & 0 deletions cleveldb.go
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,13 @@ func (db *CLevelDB) DeleteSync(key []byte) error {
return nil
}

// CompactRange implements DB and compacts the given range of the DB
jmalicevic marked this conversation as resolved.
Show resolved Hide resolved
func (db *CLevelDB) Compact(start, end []byte) error {
// CompactRange of clevelDB does not return anything
db.db.CompactRange(levigo.Range{Start: start, Limit: end})
return nil
}

// FIXME This should not be exposed
func (db *CLevelDB) DB() *levigo.DB {
return db.db
Expand Down
5 changes: 5 additions & 0 deletions cleveldb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,8 @@ func (b *cLevelDBBatch) Close() error {
}
return nil
}

// Compact compacts given range of DB
func (b *cLevelDBBatch) Compact(start, end []byte) error {
return b.db.Compact(start, end)
}
2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ require (
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.4 // indirect
github.com/google/go-cmp v0.6.0 // 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
Expand All @@ -40,7 +41,6 @@ require (
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
github.com/google/go-cmp v0.6.0 // indirect
golang.org/x/net v0.18.0 // indirect
golang.org/x/sys v0.14.0 // indirect
google.golang.org/protobuf v1.31.0 // indirect
Expand Down
17 changes: 14 additions & 3 deletions goleveldb.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@ func NewGoLevelDBWithOpts(name string, dir string, o *opt.Options) (*GoLevelDB,
if err != nil {
return nil, err
}

database := &GoLevelDB{
db: db,
}
Expand Down Expand Up @@ -71,7 +72,8 @@ func (db *GoLevelDB) Set(key []byte, value []byte) error {
if value == nil {
return errValueNil
}
if err := db.db.Put(key, value, nil); err != nil {
err := db.db.Put(key, value, nil)
if err != nil {
return err
}
return nil
Expand All @@ -85,7 +87,9 @@ func (db *GoLevelDB) SetSync(key []byte, value []byte) error {
if value == nil {
return errValueNil
}
if err := db.db.Put(key, value, &opt.WriteOptions{Sync: true}); err != nil {

err := db.db.Put(key, value, &opt.WriteOptions{Sync: true})
if err != nil {
return err
}
return nil
Expand All @@ -96,7 +100,9 @@ func (db *GoLevelDB) Delete(key []byte) error {
if len(key) == 0 {
return errKeyEmpty
}
if err := db.db.Delete(key, nil); err != nil {

err := db.db.Delete(key, nil)
if err != nil {
return err
}
return nil
Expand Down Expand Up @@ -188,3 +194,8 @@ func (db *GoLevelDB) ReverseIterator(start, end []byte) (Iterator, error) {
itr := db.db.NewIterator(&util.Range{Start: start, Limit: end}, nil)
return newGoLevelDBIterator(itr, start, end, true), nil
}

// Compact range
func (db *GoLevelDB) Compact(start, end []byte) error {
return db.db.CompactRange(util.Range{Start: start, Limit: end})
}
6 changes: 6 additions & 0 deletions goleveldb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package db
import (
"github.com/syndtr/goleveldb/leveldb"
"github.com/syndtr/goleveldb/leveldb/opt"
"github.com/syndtr/goleveldb/leveldb/util"
)

type goLevelDBBatch struct {
Expand Down Expand Up @@ -60,6 +61,7 @@ func (b *goLevelDBBatch) write(sync bool) error {
if b.batch == nil {
return errBatchClosed
}

err := b.db.db.Write(b.batch, &opt.WriteOptions{Sync: sync})
if err != nil {
return err
Expand All @@ -76,3 +78,7 @@ func (b *goLevelDBBatch) Close() error {
}
return nil
}

func (b *goLevelDBBatch) Compact(start, end []byte) error {
jmalicevic marked this conversation as resolved.
Show resolved Hide resolved
return b.db.db.CompactRange(util.Range{Start: start, Limit: end})
}
5 changes: 5 additions & 0 deletions memdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,8 @@ func (db *MemDB) ReverseIteratorNoMtx(start, end []byte) (Iterator, error) {
}
return newMemDBIteratorMtxChoice(db, start, end, true, false), nil
}

func (*MemDB) Compact(start, end []byte) error {
// No Compaction is supported for memDB and there is no point in supporting compaction for a memory DB
adizere marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
4 changes: 4 additions & 0 deletions memdb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -92,3 +92,7 @@ func (b *memDBBatch) Close() error {
b.ops = nil
return nil
}

func (*memDBBatch) Compact(start, end []byte) error {
return nil
}
29 changes: 29 additions & 0 deletions pebble.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,29 @@
return db.db
}

func (db *PebbleDB) Compact(start, end []byte) error {
// Currently nil,nil is an invalid range in Pebble.
// This was taken from https://github.com/cockroachdb/pebble/issues/1474
// In case the start and end keys are the same
// pebbleDB will throw an error that it cannot compact.
if start != nil && end != nil {
return db.db.Compact(start, end, true)
}

Check warning on line 146 in pebble.go

View check run for this annotation

Codecov / codecov/patch

pebble.go#L145-L146

Added lines #L145 - L146 were not covered by tests

iter := db.db.NewIter(nil)

if start == nil && iter.First() {
start = append(start, iter.Key()...)
}
if end == nil && iter.Last() {
end = append(end, iter.Key()...)
}
if err := iter.Close(); err != nil {
sergio-mena marked this conversation as resolved.
Show resolved Hide resolved
return err
}

Check warning on line 158 in pebble.go

View check run for this annotation

Codecov / codecov/patch

pebble.go#L157-L158

Added lines #L157 - L158 were not covered by tests
adizere marked this conversation as resolved.
Show resolved Hide resolved
return db.db.Compact(start, end, true)
}

// Close implements DB.
func (db PebbleDB) Close() error {
db.db.Close()
Expand Down Expand Up @@ -285,6 +308,12 @@
return nil
}

// Compact specified range
// nil, nil will run compaction over the entire database
func (b *pebbleDBBatch) Compact(start, end []byte) error {
return b.db.Compact(start, end)
}

type pebbleDBIterator struct {
source *pebble.Iterator
start, end []byte
Expand Down
4 changes: 4 additions & 0 deletions prefixdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,7 @@ func (pdb *PrefixDB) Stats() map[string]string {
func (pdb *PrefixDB) prefixed(key []byte) []byte {
return append(cp(pdb.prefix), key...)
}

func (pdb *PrefixDB) Compact(start, end []byte) error {
return pdb.db.Compact(start, end)
}
5 changes: 5 additions & 0 deletions prefixdb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -49,3 +49,8 @@ func (pb prefixDBBatch) WriteSync() error {
func (pb prefixDBBatch) Close() error {
return pb.source.Close()
}

func (prefixDBBatch) Compact(start, end []byte) error {
// Not implemented
adizere marked this conversation as resolved.
Show resolved Hide resolved
return nil
}
5 changes: 5 additions & 0 deletions rocksdb.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,3 +202,8 @@ func (db *RocksDB) ReverseIterator(start, end []byte) (Iterator, error) {
itr := db.db.NewIterator(db.ro)
return newRocksDBIterator(itr, start, end, true), nil
}

func (db *RocksDB) Compact(start, end []byte) error {
db.db.CompactRange(grocksdb.Range{Start: start, Limit: end})
return nil
}
5 changes: 5 additions & 0 deletions rocksdb_batch.go
Original file line number Diff line number Diff line change
Expand Up @@ -81,3 +81,8 @@ func (b *rocksDBBatch) Close() error {
}
return nil
}

// Compact compacts a given range of keys in the DB
func (b *rocksDBBatch) Compact(start, end []byte) error {
return b.db.Compact(start, end)
}
6 changes: 6 additions & 0 deletions types.go
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,9 @@ type DB interface {

// Stats returns a map of property values for all keys and the size of the cache.
Stats() map[string]string

// Compact explicitly
Compact(start, end []byte) error
}

// Batch represents a group of writes. They may or may not be written atomically depending on the
Expand All @@ -94,6 +97,9 @@ type Batch interface {

// Close closes the batch. It is idempotent, but calls to other methods afterwards will error.
Close() error

// Compact explicitly
Compact(start, end []byte) error
}

// Iterator represents an iterator over a domain of keys. Callers must call Close when done.
Expand Down
Loading