diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1de0967c7..ed9b7cbf7 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,8 +23,428 @@ jobs: - uses: actions/checkout@v3 - name: test & coverage report creation run: | - CGO_ENABLED=1 go test ./... -mod=readonly -timeout 8m -race -coverprofile=coverage.txt -covermode=atomic -tags=memdb,goleveldb,cleveldb,boltdb,rocksdb,badgerdb -v + CGO_ENABLED=1 go test ./... -mod=readonly -timeout 8m -race -coverprofile=coverage.txt -covermode=atomic -tags=memdb,goleveldb,cleveldb,rocksdb,pebbledb -v - uses: codecov/codecov-action@v3 with: file: ./coverage.txt - fail_ci_if_error: true + fail_ci_if_error: true + + Pebble: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble2: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble3: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble4: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble5: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble6: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble7: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble8: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble9: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble10: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble11: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble12: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble13: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble14: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble15: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble16: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble17: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble18: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble19: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble20: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble21: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble22: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble23: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble24: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble25: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble26: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble27: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble28: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble29: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble30: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble31: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble32: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble33: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble34: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ + + Pebble35: + # The custom image here contains pre-built libraries for leveldb and + # rocksdb, which are needed to build and test those modules. + # To update the container image, see docker.yml. + runs-on: ubuntu-latest + container: tendermintdev/docker-tm-db-testing + steps: + - uses: actions/checkout@v3 + - name: test & coverage report creation + run: | + go test -count 5000 -tags pebbledb -test.run ^TestDBIterator/pebbledb$ diff --git a/.gitpod.yml b/.gitpod.yml new file mode 100644 index 000000000..4b56b6b70 --- /dev/null +++ b/.gitpod.yml @@ -0,0 +1,7 @@ +# This configuration file was automatically generated by Gitpod. +# Please adjust to your needs (see https://www.gitpod.io/docs/config-gitpod-file) +# and commit this file to your remote git repository to share the goodness with others. + +image: tendermintdev/docker-tm-db-testing + +# this means that there's a one-click known good environment available to developers. diff --git a/.golangci.yml b/.golangci.yml index abf03e7ac..e4405da38 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -40,6 +40,12 @@ linters: # - gocognit - nolintlint +run: + build-tags: + - cleveldb + - rocksdb + - boltdb + issues: exclude-rules: - path: _test\.go diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 000000000..202e6a60d --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,7 @@ +{ + "makefile.extensionOutputFolder": "./.vscode", + "go.buildTags": "pebbledb goleveldb cleveldb rocksdb", + "go.lintTool": "golangci-lint", + "go.lintOnSave": "workspace", + "go.inferGopath": false +} \ No newline at end of file diff --git a/CHANGELOG.md b/CHANGELOG.md index 607f0bafb..9654735be 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## Unreleased + +- remove mutex from prefixdb + ## 0.6.7 **2022-2-21** diff --git a/README.md b/README.md index 2aa6efb53..7792e37d9 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# Tendermint DB +# Tendermint DB [![version](https://img.shields.io/github/tag/tendermint/tm-db.svg)](https://github.com/tendermint/tm-db/releases/latest) [![license](https://img.shields.io/github/license/tendermint/tm-db.svg)](https://github.com/tendermint/tm-db/blob/master/LICENSE) @@ -22,12 +22,8 @@ Go 1.13+ - **[LevelDB](https://github.com/google/leveldb) [experimental]:** A [Go wrapper](https://github.com/jmhodges/levigo) around [LevelDB](https://github.com/google/leveldb). Uses LSM-trees for on-disk storage, which have good performance for write-heavy workloads, particularly on spinning disks, but requires periodic compaction to maintain decent read performance and reclaim disk space. Does not support transactions. -- **[BoltDB](https://github.com/etcd-io/bbolt) [experimental]:** A [fork](https://github.com/etcd-io/bbolt) of [BoltDB](https://github.com/boltdb/bolt). Uses B+trees for on-disk storage, which have good performance for read-heavy workloads and range scans. Supports serializable ACID transactions. - - **[RocksDB](https://github.com/cosmos/gorocksdb) [experimental]:** A [Go wrapper](https://github.com/cosmos/gorocksdb) around [RocksDB](https://rocksdb.org). Similarly to LevelDB (above) it uses LSM-trees for on-disk storage, but is optimized for fast storage media such as SSDs and memory. Supports atomic transactions, but not full ACID transactions. -- **[BadgerDB](https://github.com/dgraph-io/badger) [experimental]:** A key-value database written as a pure-Go alternative to e.g. LevelDB and RocksDB, with LSM-tree storage. Makes use of multiple goroutines for performance, and includes advanced features such as serializable ACID transactions, write batches, compression, and more. - ## Meta-databases - **PrefixDB [stable]:** A database which wraps another database and uses a static prefix for all keys. This allows multiple logical databases to be stored in a common underlying databases by using different namespaces. Used by the Cosmos SDK to give different modules their own namespaced database in a single application database. diff --git a/backend_test.go b/backend_test.go index 63630beca..aecae4bf5 100644 --- a/backend_test.go +++ b/backend_test.go @@ -315,7 +315,6 @@ func testDBIterator(t *testing.T, backend BackendType) { ritr, err = db2.ReverseIterator(nil, nil) require.NoError(t, err) verifyIterator(t, ritr, nil, "reverse iterator with empty db") - } func verifyIterator(t *testing.T, itr Iterator, expected []int64, msg string) { diff --git a/badger_db.go b/badger_db.go deleted file mode 100644 index 193372abf..000000000 --- a/badger_db.go +++ /dev/null @@ -1,295 +0,0 @@ -//go:build badgerdb -// +build badgerdb - -package db - -import ( - "bytes" - "fmt" - "os" - "path/filepath" - - "github.com/dgraph-io/badger/v3" -) - -func init() { registerDBCreator(BadgerDBBackend, badgerDBCreator, true) } - -func badgerDBCreator(dbName, dir string) (DB, error) { - return NewBadgerDB(dbName, dir) -} - -// NewBadgerDB creates a Badger key-value store backed to the -// directory dir supplied. If dir does not exist, it will be created. -func NewBadgerDB(dbName, dir string) (*BadgerDB, error) { - // Since Badger doesn't support database names, we join both to obtain - // the final directory to use for the database. - path := filepath.Join(dir, dbName) - - if err := os.MkdirAll(path, 0755); err != nil { - return nil, err - } - opts := badger.DefaultOptions(path) - opts.SyncWrites = false // note that we have Sync methods - opts.Logger = nil // badger is too chatty by default - return NewBadgerDBWithOptions(opts) -} - -// NewBadgerDBWithOptions creates a BadgerDB key value store -// gives the flexibility of initializing a database with the -// respective options. -func NewBadgerDBWithOptions(opts badger.Options) (*BadgerDB, error) { - db, err := badger.Open(opts) - if err != nil { - return nil, err - } - return &BadgerDB{db: db}, nil -} - -type BadgerDB struct { - db *badger.DB -} - -var _ DB = (*BadgerDB)(nil) - -func (b *BadgerDB) Get(key []byte) ([]byte, error) { - if len(key) == 0 { - return nil, errKeyEmpty - } - var val []byte - err := b.db.View(func(txn *badger.Txn) error { - item, err := txn.Get(key) - if err == badger.ErrKeyNotFound { - return nil - } else if err != nil { - return err - } - val, err = item.ValueCopy(nil) - if err == nil && val == nil { - val = []byte{} - } - return err - }) - return val, err -} - -func (b *BadgerDB) Has(key []byte) (bool, error) { - if len(key) == 0 { - return false, errKeyEmpty - } - var found bool - err := b.db.View(func(txn *badger.Txn) error { - _, err := txn.Get(key) - if err != nil && err != badger.ErrKeyNotFound { - return err - } - found = (err != badger.ErrKeyNotFound) - return nil - }) - return found, err -} - -func (b *BadgerDB) Set(key, value []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - if value == nil { - return errValueNil - } - return b.db.Update(func(txn *badger.Txn) error { - return txn.Set(key, value) - }) -} - -func withSync(db *badger.DB, err error) error { - if err != nil { - return err - } - return db.Sync() -} - -func (b *BadgerDB) SetSync(key, value []byte) error { - return withSync(b.db, b.Set(key, value)) -} - -func (b *BadgerDB) Delete(key []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - return b.db.Update(func(txn *badger.Txn) error { - return txn.Delete(key) - }) -} - -func (b *BadgerDB) DeleteSync(key []byte) error { - return withSync(b.db, b.Delete(key)) -} - -func (b *BadgerDB) Close() error { - return b.db.Close() -} - -func (b *BadgerDB) Print() error { - return nil -} - -func (b *BadgerDB) iteratorOpts(start, end []byte, opts badger.IteratorOptions) (*badgerDBIterator, error) { - if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { - return nil, errKeyEmpty - } - txn := b.db.NewTransaction(false) - iter := txn.NewIterator(opts) - iter.Rewind() - iter.Seek(start) - if opts.Reverse && iter.Valid() && bytes.Equal(iter.Item().Key(), start) { - // If we're going in reverse, our starting point was "end", - // which is exclusive. - iter.Next() - } - return &badgerDBIterator{ - reverse: opts.Reverse, - start: start, - end: end, - - txn: txn, - iter: iter, - }, nil -} - -func (b *BadgerDB) Iterator(start, end []byte) (Iterator, error) { - opts := badger.DefaultIteratorOptions - return b.iteratorOpts(start, end, opts) -} - -func (b *BadgerDB) ReverseIterator(start, end []byte) (Iterator, error) { - opts := badger.DefaultIteratorOptions - opts.Reverse = true - return b.iteratorOpts(end, start, opts) -} - -func (b *BadgerDB) Stats() map[string]string { - return nil -} - -func (b *BadgerDB) NewBatch() Batch { - wb := &badgerDBBatch{ - db: b.db, - wb: b.db.NewWriteBatch(), - firstFlush: make(chan struct{}, 1), - } - wb.firstFlush <- struct{}{} - return wb -} - -var _ Batch = (*badgerDBBatch)(nil) - -type badgerDBBatch struct { - db *badger.DB - wb *badger.WriteBatch - - // Calling db.Flush twice panics, so we must keep track of whether we've - // flushed already on our own. If Write can receive from the firstFlush - // channel, then it's the first and only Flush call we should do. - // - // Upstream bug report: - // https://github.com/dgraph-io/badger/issues/1394 - firstFlush chan struct{} -} - -func (b *badgerDBBatch) Set(key, value []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - if value == nil { - return errValueNil - } - return b.wb.Set(key, value) -} - -func (b *badgerDBBatch) Delete(key []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - return b.wb.Delete(key) -} - -func (b *badgerDBBatch) Write() error { - select { - case <-b.firstFlush: - return b.wb.Flush() - default: - return fmt.Errorf("batch already flushed") - } -} - -func (b *badgerDBBatch) WriteSync() error { - return withSync(b.db, b.Write()) -} - -func (b *badgerDBBatch) Close() error { - select { - case <-b.firstFlush: // a Flush after Cancel panics too - default: - } - b.wb.Cancel() - return nil -} - -type badgerDBIterator struct { - reverse bool - start, end []byte - - txn *badger.Txn - iter *badger.Iterator - - lastErr error -} - -func (i *badgerDBIterator) Close() error { - i.iter.Close() - i.txn.Discard() - return nil -} - -func (i *badgerDBIterator) Domain() (start, end []byte) { return i.start, i.end } -func (i *badgerDBIterator) Error() error { return i.lastErr } - -func (i *badgerDBIterator) Next() { - if !i.Valid() { - panic("iterator is invalid") - } - i.iter.Next() -} - -func (i *badgerDBIterator) Valid() bool { - if !i.iter.Valid() { - return false - } - if len(i.end) > 0 { - key := i.iter.Item().Key() - if c := bytes.Compare(key, i.end); (!i.reverse && c >= 0) || (i.reverse && c < 0) { - // We're at the end key, or past the end. - return false - } - } - return true -} - -func (i *badgerDBIterator) Key() []byte { - if !i.Valid() { - panic("iterator is invalid") - } - // Note that we don't use KeyCopy, so this is only valid until the next - // call to Next. - return i.iter.Item().KeyCopy(nil) -} - -func (i *badgerDBIterator) Value() []byte { - if !i.Valid() { - panic("iterator is invalid") - } - val, err := i.iter.Item().ValueCopy(nil) - if err != nil { - i.lastErr = err - } - return val -} diff --git a/boltdb.go b/boltdb.go deleted file mode 100644 index 398c401a4..000000000 --- a/boltdb.go +++ /dev/null @@ -1,206 +0,0 @@ -// +build boltdb - -package db - -import ( - "errors" - "fmt" - "os" - "path/filepath" - - "go.etcd.io/bbolt" -) - -var ( - bucket = []byte("tm") -) - -func init() { - registerDBCreator(BoltDBBackend, func(name, dir string) (DB, error) { - return NewBoltDB(name, dir) - }, false) -} - -// BoltDB is a wrapper around etcd's fork of bolt (https://github.com/etcd-io/bbolt). -// -// NOTE: All operations (including Set, Delete) are synchronous by default. One -// can globally turn it off by using NoSync config option (not recommended). -// -// A single bucket ([]byte("tm")) is used per a database instance. This could -// lead to performance issues when/if there will be lots of keys. -type BoltDB struct { - db *bbolt.DB -} - -var _ DB = (*BoltDB)(nil) - -// NewBoltDB returns a BoltDB with default options. -func NewBoltDB(name, dir string) (DB, error) { - return NewBoltDBWithOpts(name, dir, bbolt.DefaultOptions) -} - -// NewBoltDBWithOpts allows you to supply *bbolt.Options. ReadOnly: true is not -// supported because NewBoltDBWithOpts creates a global bucket. -func NewBoltDBWithOpts(name string, dir string, opts *bbolt.Options) (DB, error) { - if opts.ReadOnly { - return nil, errors.New("ReadOnly: true is not supported") - } - - dbPath := filepath.Join(dir, name+".db") - db, err := bbolt.Open(dbPath, os.ModePerm, opts) - if err != nil { - return nil, err - } - - // create a global bucket - err = db.Update(func(tx *bbolt.Tx) error { - _, err := tx.CreateBucketIfNotExists(bucket) - return err - }) - if err != nil { - return nil, err - } - - return &BoltDB{db: db}, nil -} - -// Get implements DB. -func (bdb *BoltDB) Get(key []byte) (value []byte, err error) { - if len(key) == 0 { - return nil, errKeyEmpty - } - err = bdb.db.View(func(tx *bbolt.Tx) error { - b := tx.Bucket(bucket) - if v := b.Get(key); v != nil { - value = append([]byte{}, v...) - } - return nil - }) - if err != nil { - return nil, err - } - return -} - -// Has implements DB. -func (bdb *BoltDB) Has(key []byte) (bool, error) { - bytes, err := bdb.Get(key) - if err != nil { - return false, err - } - return bytes != nil, nil -} - -// Set implements DB. -func (bdb *BoltDB) Set(key, value []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - if value == nil { - return errValueNil - } - err := bdb.db.Update(func(tx *bbolt.Tx) error { - b := tx.Bucket(bucket) - return b.Put(key, value) - }) - if err != nil { - return err - } - return nil -} - -// SetSync implements DB. -func (bdb *BoltDB) SetSync(key, value []byte) error { - return bdb.Set(key, value) -} - -// Delete implements DB. -func (bdb *BoltDB) Delete(key []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - err := bdb.db.Update(func(tx *bbolt.Tx) error { - return tx.Bucket(bucket).Delete(key) - }) - if err != nil { - return err - } - return nil -} - -// DeleteSync implements DB. -func (bdb *BoltDB) DeleteSync(key []byte) error { - return bdb.Delete(key) -} - -// Close implements DB. -func (bdb *BoltDB) Close() error { - return bdb.db.Close() -} - -// Print implements DB. -func (bdb *BoltDB) Print() error { - stats := bdb.db.Stats() - fmt.Printf("%v\n", stats) - - err := bdb.db.View(func(tx *bbolt.Tx) error { - tx.Bucket(bucket).ForEach(func(k, v []byte) error { - fmt.Printf("[%X]:\t[%X]\n", k, v) - return nil - }) - return nil - }) - if err != nil { - return err - } - return nil -} - -// Stats implements DB. -func (bdb *BoltDB) Stats() map[string]string { - stats := bdb.db.Stats() - m := make(map[string]string) - - // Freelist stats - m["FreePageN"] = fmt.Sprintf("%v", stats.FreePageN) - m["PendingPageN"] = fmt.Sprintf("%v", stats.PendingPageN) - m["FreeAlloc"] = fmt.Sprintf("%v", stats.FreeAlloc) - m["FreelistInuse"] = fmt.Sprintf("%v", stats.FreelistInuse) - - // Transaction stats - m["TxN"] = fmt.Sprintf("%v", stats.TxN) - m["OpenTxN"] = fmt.Sprintf("%v", stats.OpenTxN) - - return m -} - -// NewBatch implements DB. -func (bdb *BoltDB) NewBatch() Batch { - return newBoltDBBatch(bdb) -} - -// WARNING: Any concurrent writes or reads will block until the iterator is -// closed. -func (bdb *BoltDB) Iterator(start, end []byte) (Iterator, error) { - if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { - return nil, errKeyEmpty - } - tx, err := bdb.db.Begin(false) - if err != nil { - return nil, err - } - return newBoltDBIterator(tx, start, end, false), nil -} - -// WARNING: Any concurrent writes or reads will block until the iterator is -// closed. -func (bdb *BoltDB) ReverseIterator(start, end []byte) (Iterator, error) { - if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { - return nil, errKeyEmpty - } - tx, err := bdb.db.Begin(false) - if err != nil { - return nil, err - } - return newBoltDBIterator(tx, start, end, true), nil -} diff --git a/boltdb_batch.go b/boltdb_batch.go deleted file mode 100644 index 390bc309b..000000000 --- a/boltdb_batch.go +++ /dev/null @@ -1,86 +0,0 @@ -// +build boltdb - -package db - -import "go.etcd.io/bbolt" - -// boltDBBatch stores operations internally and dumps them to BoltDB on Write(). -type boltDBBatch struct { - db *BoltDB - ops []operation -} - -var _ Batch = (*boltDBBatch)(nil) - -func newBoltDBBatch(db *BoltDB) *boltDBBatch { - return &boltDBBatch{ - db: db, - ops: []operation{}, - } -} - -// Set implements Batch. -func (b *boltDBBatch) Set(key, value []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - if value == nil { - return errValueNil - } - if b.ops == nil { - return errBatchClosed - } - b.ops = append(b.ops, operation{opTypeSet, key, value}) - return nil -} - -// Delete implements Batch. -func (b *boltDBBatch) Delete(key []byte) error { - if len(key) == 0 { - return errKeyEmpty - } - if b.ops == nil { - return errBatchClosed - } - b.ops = append(b.ops, operation{opTypeDelete, key, nil}) - return nil -} - -// Write implements Batch. -func (b *boltDBBatch) Write() error { - if b.ops == nil { - return errBatchClosed - } - err := b.db.db.Batch(func(tx *bbolt.Tx) error { - bkt := tx.Bucket(bucket) - for _, op := range b.ops { - switch op.opType { - case opTypeSet: - if err := bkt.Put(op.key, op.value); err != nil { - return err - } - case opTypeDelete: - if err := bkt.Delete(op.key); err != nil { - return err - } - } - } - return nil - }) - 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 *boltDBBatch) WriteSync() error { - return b.Write() -} - -// Close implements Batch. -func (b *boltDBBatch) Close() error { - b.ops = nil - return nil -} diff --git a/boltdb_iterator.go b/boltdb_iterator.go deleted file mode 100644 index 74212c5ca..000000000 --- a/boltdb_iterator.go +++ /dev/null @@ -1,141 +0,0 @@ -// +build boltdb - -package db - -import ( - "bytes" - - "go.etcd.io/bbolt" -) - -// boltDBIterator allows you to iterate on range of keys/values given some -// start / end keys (nil & nil will result in doing full scan). -type boltDBIterator struct { - tx *bbolt.Tx - - itr *bbolt.Cursor - start []byte - end []byte - - currentKey []byte - currentValue []byte - - isInvalid bool - isReverse bool -} - -var _ Iterator = (*boltDBIterator)(nil) - -// newBoltDBIterator creates a new boltDBIterator. -func newBoltDBIterator(tx *bbolt.Tx, start, end []byte, isReverse bool) *boltDBIterator { - itr := tx.Bucket(bucket).Cursor() - - var ck, cv []byte - if isReverse { - switch { - case end == nil: - ck, cv = itr.Last() - default: - _, _ = itr.Seek(end) // after key - ck, cv = itr.Prev() // return to end key - } - } else { - switch { - case start == nil: - ck, cv = itr.First() - default: - ck, cv = itr.Seek(start) - } - } - - return &boltDBIterator{ - tx: tx, - itr: itr, - start: start, - end: end, - currentKey: ck, - currentValue: cv, - isReverse: isReverse, - isInvalid: false, - } -} - -// Domain implements Iterator. -func (itr *boltDBIterator) Domain() ([]byte, []byte) { - return itr.start, itr.end -} - -// Valid implements Iterator. -func (itr *boltDBIterator) Valid() bool { - if itr.isInvalid { - return false - } - - if itr.Error() != nil { - itr.isInvalid = true - return false - } - - // iterated to the end of the cursor - if itr.currentKey == nil { - itr.isInvalid = true - return false - } - - if itr.isReverse { - if itr.start != nil && bytes.Compare(itr.currentKey, itr.start) < 0 { - itr.isInvalid = true - return false - } - } else { - if itr.end != nil && bytes.Compare(itr.end, itr.currentKey) <= 0 { - itr.isInvalid = true - return false - } - } - - // Valid - return true -} - -// Next implements Iterator. -func (itr *boltDBIterator) Next() { - itr.assertIsValid() - if itr.isReverse { - itr.currentKey, itr.currentValue = itr.itr.Prev() - } else { - itr.currentKey, itr.currentValue = itr.itr.Next() - } -} - -// Key implements Iterator. -func (itr *boltDBIterator) Key() []byte { - itr.assertIsValid() - return append([]byte{}, itr.currentKey...) -} - -// Value implements Iterator. -func (itr *boltDBIterator) Value() []byte { - itr.assertIsValid() - var value []byte - if itr.currentValue != nil { - value = append([]byte{}, itr.currentValue...) - } - return value -} - -// Error implements Iterator. -func (itr *boltDBIterator) Error() error { - return nil -} - -// Close implements Iterator. -func (itr *boltDBIterator) Close() error { - return itr.tx.Rollback() -} - -func (itr *boltDBIterator) assertIsValid() { - if !itr.Valid() { - panic("iterator is invalid") - } -} diff --git a/boltdb_test.go b/boltdb_test.go deleted file mode 100644 index 0fd12bbe2..000000000 --- a/boltdb_test.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build boltdb - -package db - -import ( - "fmt" - "os" - "testing" - - "github.com/stretchr/testify/require" -) - -func TestBoltDBNewBoltDB(t *testing.T) { - name := fmt.Sprintf("test_%x", randStr(12)) - dir := os.TempDir() - defer cleanupDBDir(dir, name) - - db, err := NewBoltDB(name, dir) - require.NoError(t, err) - db.Close() -} - -func BenchmarkBoltDBRandomReadsWrites(b *testing.B) { - name := fmt.Sprintf("test_%x", randStr(12)) - db, err := NewBoltDB(name, "") - if err != nil { - b.Fatal(err) - } - defer func() { - db.Close() - cleanupDBDir("", name) - }() - - benchmarkRandomReadsWrites(b, db) -} diff --git a/cleveldb.go b/cleveldb.go index 377956deb..789673011 100644 --- a/cleveldb.go +++ b/cleveldb.go @@ -1,3 +1,4 @@ +//go:build cleveldb // +build cleveldb package db diff --git a/cleveldb_batch.go b/cleveldb_batch.go index 132a521cb..b77bd523d 100644 --- a/cleveldb_batch.go +++ b/cleveldb_batch.go @@ -1,3 +1,4 @@ +//go:build cleveldb // +build cleveldb package db diff --git a/cleveldb_iterator.go b/cleveldb_iterator.go index 04375d565..5a7f1e6ad 100644 --- a/cleveldb_iterator.go +++ b/cleveldb_iterator.go @@ -1,3 +1,4 @@ +//go:build cleveldb // +build cleveldb package db @@ -20,7 +21,7 @@ var _ Iterator = (*cLevelDBIterator)(nil) func newCLevelDBIterator(source *levigo.Iterator, start, end []byte, isReverse bool) *cLevelDBIterator { if isReverse { - if end == nil || len(end) == 0 { + if len(end) == 0 { source.SeekToLast() } else { source.Seek(end) @@ -34,7 +35,7 @@ func newCLevelDBIterator(source *levigo.Iterator, start, end []byte, isReverse b } } } else { - if start == nil || len(start) == 0 { + if len(start) == 0 { source.SeekToFirst() } else { source.Seek(start) @@ -56,7 +57,6 @@ func (itr cLevelDBIterator) Domain() ([]byte, []byte) { // Valid implements Iterator. func (itr cLevelDBIterator) Valid() bool { - // Once invalid, forever invalid. if itr.isInvalid { return false @@ -64,28 +64,24 @@ func (itr cLevelDBIterator) Valid() bool { // If source errors, invalid. if itr.source.GetError() != nil { - itr.isInvalid = true return false } // If source is invalid, invalid. if !itr.source.Valid() { - itr.isInvalid = true return false } // If key is end or past it, invalid. - var start = itr.start - var end = itr.end - var key = itr.source.Key() + start := itr.start + end := itr.end + key := itr.source.Key() if itr.isReverse { if start != nil && bytes.Compare(key, start) < 0 { - itr.isInvalid = true return false } } else { if end != nil && bytes.Compare(end, key) <= 0 { - itr.isInvalid = true return false } } diff --git a/cleveldb_test.go b/cleveldb_test.go index 61e2fb6ef..55fca6b9f 100644 --- a/cleveldb_test.go +++ b/cleveldb_test.go @@ -1,3 +1,4 @@ +//go:build cleveldb // +build cleveldb package db @@ -7,12 +8,24 @@ import ( "fmt" "math/rand" "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) +func TestWithClevelDB(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "cleveldb") + + db, err := NewCLevelDB(path, "") + require.NoError(t, err) + + t.Run("ClevelDB", func(t *testing.T) { Run(t, db) }) +} + +//nolint: errcheck func BenchmarkRandomReadsWrites2(b *testing.B) { b.StopTimer() @@ -36,9 +49,8 @@ func BenchmarkRandomReadsWrites2(b *testing.B) { idx := (int64(rand.Int()) % numItems) internal[idx]++ val := internal[idx] - idxBytes := int642Bytes(int64(idx)) - valBytes := int642Bytes(int64(val)) - //fmt.Printf("Set %X -> %X\n", idxBytes, valBytes) + idxBytes := int642Bytes(idx) + valBytes := int642Bytes(val) db.Set( idxBytes, valBytes, @@ -48,12 +60,12 @@ func BenchmarkRandomReadsWrites2(b *testing.B) { { idx := (int64(rand.Int()) % numItems) val := internal[idx] - idxBytes := int642Bytes(int64(idx)) + idxBytes := int642Bytes(idx) valBytes, err := db.Get(idxBytes) if err != nil { b.Error(err) } - //fmt.Printf("Get %X -> %X\n", idxBytes, valBytes) + // fmt.Printf("Get %X -> %X\n", idxBytes, valBytes) if val == 0 { if !bytes.Equal(valBytes, nil) { b.Errorf("Expected %v for %v, got %X", diff --git a/db.go b/db.go index ef573f17e..63f7580d5 100644 --- a/db.go +++ b/db.go @@ -22,19 +22,10 @@ const ( // MemDBBackend represents in-memory key value store, which is mostly used // for testing. MemDBBackend BackendType = "memdb" - // BoltDBBackend represents bolt (uses etcd's fork of bolt - - // github.com/etcd-io/bbolt) - // - EXPERIMENTAL - // - may be faster is some use-cases (random reads - indexer) - // - use boltdb build tag (go build -tags boltdb) - BoltDBBackend BackendType = "boltdb" - // RocksDBBackend represents rocksdb (uses github.com/cosmos/gorocksdb) - // - EXPERIMENTAL - // - requires gcc - // - use rocksdb build tag (go build -tags rocksdb) + RocksDBBackend BackendType = "rocksdb" - BadgerDBBackend BackendType = "badgerdb" + PebbleDBBackend BackendType = "pebbledb" ) type dbCreator func(name string, dir string) (DB, error) diff --git a/go.mod b/go.mod index 1f0dd8ab9..50d0541ed 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,9 @@ module github.com/tendermint/tm-db -go 1.17 +go 1.18 require ( + github.com/cockroachdb/pebble v0.0.0-20220726134658-7b78c71e4055 github.com/cosmos/gorocksdb v1.2.0 github.com/gogo/protobuf v1.3.2 github.com/golang/protobuf v1.5.2 // indirect @@ -10,26 +11,25 @@ require ( github.com/jmhodges/levigo v1.0.0 github.com/stretchr/testify v1.8.0 github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca - go.etcd.io/bbolt v1.3.6 google.golang.org/grpc v1.48.0 ) -require github.com/dgraph-io/badger/v3 v3.2103.2 - require ( - github.com/cespare/xxhash v1.1.0 // indirect + github.com/DataDog/zstd v1.4.5 // indirect + github.com/HdrHistogram/hdrhistogram-go v1.1.2 // indirect github.com/cespare/xxhash/v2 v2.1.1 // 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.1.0 // indirect - github.com/dustin/go-humanize v1.0.0 // indirect - github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect - github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect github.com/golang/snappy v0.0.3 // indirect - github.com/google/flatbuffers v1.12.1 // indirect github.com/klauspost/compress v1.12.3 // indirect + github.com/kr/pretty v0.1.0 // indirect + github.com/kr/text v0.2.0 // indirect github.com/pkg/errors v0.9.1 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect - go.opencensus.io v0.22.5 // indirect + golang.org/x/exp v0.0.0-20200513190911-00229845015e // indirect golang.org/x/net v0.0.0-20201021035429-f5854403a974 // indirect golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 // indirect golang.org/x/text v0.3.3 // indirect diff --git a/go.sum b/go.sum index 0d1afaab2..6080a5698 100644 --- a/go.sum +++ b/go.sum @@ -1,13 +1,24 @@ cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= +dmitri.shuralyov.com/gpu/mtl v0.0.0-20190408044501-666a987793e9/go.mod h1:H6x//7gZCb22OMCxBHrMx7a5I7Hp++hsVxbQ4BYO7hU= +github.com/AndreasBriese/bbloom v0.0.0-20190306092124-e2d15f34fcf9/go.mod h1:bOvUY6CB00SOBii9/FifXqc0awNKxLFCL/+pkDPuyl8= github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= -github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= +github.com/CloudyKit/fastprinter v0.0.0-20170127035650-74b38d55f37a/go.mod h1:EFZQ978U7x8IRnstaskI3IysnWY5Ao3QgZUKOXlsAdw= +github.com/CloudyKit/jet v2.1.3-0.20180809161101-62edd43e4f88+incompatible/go.mod h1:HPYO+50pSWkPoj9Q/eq0aRGByCL6ScRlUmiEX5Zgm+w= +github.com/DataDog/zstd v1.4.5 h1:EndNeuB0l9syBZhut0wns3gV1hL8zX8LIu6ZiVHWLIQ= +github.com/DataDog/zstd v1.4.5/go.mod h1:1jcaCB/ufaK+sKp1NBhlGmpz41jOoPQ35bpF36t7BBo= +github.com/HdrHistogram/hdrhistogram-go v1.1.2 h1:5IcZpTvzydCQeHzK4Ef/D5rrSqwxob0t8PQPMybUNFM= +github.com/HdrHistogram/hdrhistogram-go v1.1.2/go.mod h1:yDgFjdqOqDEKOvasDdhWNXYg9BVp4O+o5f6V/ehm6Oo= +github.com/Joker/hpp v1.0.0/go.mod h1:8x5n+M1Hp5hC0g8okX3sR3vFQwynaX/UgSOM9MeBKzY= +github.com/Joker/jade v1.0.1-0.20190614124447-d475f43051e7/go.mod h1:6E6s8o2AE4KhCrqr6GRJjdC/gNfTdxkIXvuGZZda2VM= +github.com/Shopify/goreferrer v0.0.0-20181106222321-ec9c9a553398/go.mod h1:a1uqRtAwp2Xwc6WNPJEufxJ7fx3npB4UV/JOLmbu5I0= +github.com/ajg/form v1.5.1/go.mod h1:uL1WgH+h2mgNtvBq0339dVnzXdBETtL2LeUXaIv25UY= +github.com/ajstarks/svgo v0.0.0-20180226025133-644b8db467af/go.mod h1:K08gAheRH3/J6wwsYMMT4xOr94bZjxIelGM0+d/wbFw= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= github.com/armon/consul-api v0.0.0-20180202201655-eb2c6b5be1b6/go.mod h1:grANhF5doyWs3UAsr3K4I6qtAmlQcZDesFNEHPZAzj8= +github.com/aymerick/raymond v2.0.3-0.20180322193309-b565731e1464+incompatible/go.mod h1:osfaiScAUVup+UC9Nfq76eWqDhXlp+4UYaA8uhTBO6g= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= -github.com/cespare/xxhash v1.1.0 h1:a6HrQnmkObjyL+Gs60czilIUGqrzKutQD6XZog3p+ko= -github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw= @@ -17,45 +28,73 @@ github.com/cncf/udpa/go v0.0.0-20210930031921-04548b0d99d4/go.mod h1:6pvJx4me5XP github.com/cncf/xds/go v0.0.0-20210922020428-25de7278fc84/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211001041855-01bcc9b48dfe/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= github.com/cncf/xds/go v0.0.0-20211011173535-cb28da3451f1/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v1.0.0/go.mod h1:5Ib8Meh+jk1RlHIXej6Pzevx/NLlNvQB9pmSBZErGA4= +github.com/cockroachdb/errors v1.6.1/go.mod h1:tm6FTP5G81vwJ5lC0SizQo374JNCOPrHyXGitRJoDqM= +github.com/cockroachdb/errors v1.8.1 h1:A5+txlVZfOqFBDa4mGz2bUWSp0aHElvHX2bKkdbQu+Y= +github.com/cockroachdb/errors v1.8.1/go.mod h1:qGwQn6JmZ+oMjuLwjWzUNqblqk0xl4CVV3SQbGwK7Ac= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f h1:o/kfcElHqOiXqcou5a3rIlMc7oJbMQkeLk0VQJ7zgqY= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/cockroachdb/pebble v0.0.0-20220726134658-7b78c71e4055 h1:lKgbA+hhzIse5eXx1aZwpHAnPKTp1mtQnJRZJbLwJtU= +github.com/cockroachdb/pebble v0.0.0-20220726134658-7b78c71e4055/go.mod h1:890yq1fUb9b6dGNwssgeUO5vQV9qfXnCPxAJhBQfXw0= +github.com/cockroachdb/redact v1.0.8 h1:8QG/764wK+vmEYoOlfobpe12EQcS81ukx/a4hdVMxNw= +github.com/cockroachdb/redact v1.0.8/go.mod h1:BVNblN9mBWFyMyqK1k3AAiSxhvhfK2oOZZ2lK+dpvRg= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2 h1:IKgmqgMQlVJIZj19CdocBeSfSaiCbEBZGKODaixqtHM= +github.com/cockroachdb/sentry-go v0.6.1-cockroachdb.2/go.mod h1:8BT+cPK6xvFOcRlk0R8eg+OTkcqI6baNH4xAkpiYVvQ= +github.com/codegangsta/inject v0.0.0-20150114235600-33e0aa1cb7c0/go.mod h1:4Zcjuz89kmFXt9morQgcfYZAYZ5n8WHjt81YYWIwtTM= github.com/coreos/etcd v3.3.10+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= github.com/coreos/go-etcd v2.0.0+incompatible/go.mod h1:Jez6KQU2B/sWsbdaef3ED8NzMklzPG4d5KIOhIy30Tk= github.com/coreos/go-semver v0.2.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= github.com/cosmos/gorocksdb v1.2.0 h1:d0l3jJG8M4hBouIZq0mDUHZ+zjOx044J3nGRskwTb4Y= github.com/cosmos/gorocksdb v1.2.0/go.mod h1:aaKvKItm514hKfNJpUJXnnOWeBnk2GL4+Qw9NHizILw= github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= +github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= -github.com/dgraph-io/badger/v3 v3.2103.2 h1:dpyM5eCJAtQCBcMCZcT4UBZchuTJgCywerHHgmxfxM8= -github.com/dgraph-io/badger/v3 v3.2103.2/go.mod h1:RHo4/GmYcKKh5Lxu63wLEMHJ70Pac2JqZRYGhlyAo2M= -github.com/dgraph-io/ristretto v0.1.0 h1:Jv3CGQHp9OjuMBSne1485aDpUkTKEcUqF+jm/LuerPI= -github.com/dgraph-io/ristretto v0.1.0/go.mod h1:fux0lOrBhrVCJd3lcTHsIJhq1T2rokOu6v9Vcb3Q9ug= -github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2 h1:tdlZCpZ/P9DhczCTSixgIKmwPv6+wP5DGjqLYw5SUiA= +github.com/dgraph-io/badger v1.6.0/go.mod h1:zwt7syl517jmP8s94KqSxTlM6IMsdhYy6psNgSztDR4= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw= -github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo= github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= +github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= github.com/envoyproxy/go-control-plane v0.9.9-0.20201210154907-fd9021fe5dad/go.mod h1:cXg6YxExXjJnVBQHBLXeUAgxn2UodCpnH306RInaBQk= github.com/envoyproxy/go-control-plane v0.10.2-0.20220325020618-49ff273808a1/go.mod h1:KJwIaB5Mv44NWtYuAOFCVOjcI94vtpEz2JU/D2v6IjE= github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= +github.com/etcd-io/bbolt v1.3.3/go.mod h1:ZF2nL25h33cCyBtcyWeZ2/I3HQOfTP+0PIEvHjkjCrw= github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c h1:8ISkoahWXwZR41ois5lSJBSVw4D0OV19Ht/JSTzvSv0= -github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= -github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 h1:7HZCaLC5+BZpmbhCOZJ293Lz68O7PYrF2EzeiFMwCLk= -github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= +github.com/fasthttp-contrib/websocket v0.0.0-20160511215533-1f3b11f56072/go.mod h1:duJ4Jxv5lDcvg4QuQr0oowTf7dz4/CR8NtyCooz9HL8= +github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= +github.com/flosch/pongo2 v0.0.0-20190707114632-bbf5a6c351f4/go.mod h1:T9YF2M40nIgbVgp3rreNmTged+9HrbNTIQf1PsaIiTA= +github.com/fogleman/gg v1.2.1-0.20190220221249-0403632d5b90/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo= github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4= github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ= +github.com/gavv/httpexpect v2.0.0+incompatible/go.mod h1:x+9tiU1YnrOvnB725RkpoLv1M62hOWzwo5OXotisrKc= +github.com/ghemawat/stream v0.0.0-20171120220530-696b145b53b9/go.mod h1:106OIgooyS7OzLDOpUGgm9fA3bQENb/cFSyyBmMoJDs= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= +github.com/gin-contrib/sse v0.0.0-20190301062529-5545eab6dad3/go.mod h1:VJ0WA2NBN22VlZ2dKZQPAPnyWw5XTlK1KymzLKsr59s= +github.com/gin-gonic/gin v1.4.0/go.mod h1:OW2EZn3DO8Ln9oIKOvM++LBO+5UPHJJDH72/q/3rZdM= +github.com/go-check/check v0.0.0-20180628173108-788fd7840127/go.mod h1:9ES+weclKsC9YodN5RgxqK/VD9HM9JsCSh7rNhMZE98= +github.com/go-errors/errors v1.0.1 h1:LUHzmkK3GUKUrL/1gfBUxAHzcev3apQlezX/+O7ma6w= +github.com/go-errors/errors v1.0.1/go.mod h1:f4zRHt4oKfwPJE5k8C9vpYG+aDHdBFUsgrm6/TyX73Q= +github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= +github.com/go-gl/glfw/v3.3/glfw v0.0.0-20200222043503-6f7a984d4dc4/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= +github.com/go-martini/martini v0.0.0-20170121215854-22fa46961aab/go.mod h1:/P9AEU963A2AYjv4d1V5eVL1CQbEJq6aCNHDDjibzu8= +github.com/gobwas/httphead v0.0.0-20180130184737-2c6c146eadee/go.mod h1:L0fX3K22YWvt/FAX9NnzrNzcI4wNYi9Yku4O0LKYflo= +github.com/gobwas/pool v0.2.0/go.mod h1:q8bcK0KcYlCgd9e7WYLm9LpyS+YeLd8JVDW6WezmKEw= +github.com/gobwas/ws v1.0.2/go.mod h1:szmBTxLgaFppYjEmNtny/v3w89xOydFnnZMcgRRu/EM= +github.com/gogo/googleapis v0.0.0-20180223154316-0cd9801be74a/go.mod h1:gf4bu3Q80BeJ6H1S1vYPm8/ELATdvryBaNFGgqEef3s= +github.com/gogo/protobuf v1.2.0/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= -github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58= +github.com/gogo/status v1.1.0/go.mod h1:BFv9nrluPLmrS0EmGVvLaPNmRosr9KapBYd5/hpY1WM= +github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I= -github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A= github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= @@ -75,10 +114,9 @@ github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiu github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA= github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q= +github.com/gomodule/redigo v1.7.1-0.20190724094224-574c33c3df38/go.mod h1:B4C85qUVwatsJoIUNIfCRsp7qO0iAmpGFZ4EELWSbC4= github.com/google/btree v1.1.2 h1:xf4v41cLI2Z6FxbKm+8Bu+m8ifhj15JuZ9sa0jZCMUU= github.com/google/btree v1.1.2/go.mod h1:qOPhT0dTNdNzV6Z/lhRX0YXUafgPLFUh+gZMl761Gm4= -github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6ImGw= -github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -88,35 +126,85 @@ github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/ github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= +github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= github.com/google/uuid v1.1.2/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= +github.com/hashicorp/go-version v1.2.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= +github.com/hashicorp/go-version v1.6.0/go.mod h1:fltr4n8CU8Ke44wwGCBoEymUuxUHl09ZGVZPK5anwXA= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= +github.com/hydrogen18/memlistener v0.0.0-20141126152155-54553eb933fb/go.mod h1:qEIFzExnS6016fRpRfxrExeVn2gbClQA99gQhnIcdhE= +github.com/imkira/go-interpol v1.1.0/go.mod h1:z0h2/2T3XF8kyEPpRgJ3kmNv+C43p+I/CoI+jC3w2iA= github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8= +github.com/iris-contrib/blackfriday v2.0.0+incompatible/go.mod h1:UzZ2bDEoaSGPbkg6SAB4att1aAwTmVIx/5gCVqeyUdI= +github.com/iris-contrib/go.uuid v2.0.0+incompatible/go.mod h1:iz2lgM/1UnEf1kP0L/+fafWORmlnuysV2EMP8MW+qe0= +github.com/iris-contrib/i18n v0.0.0-20171121225848-987a633949d0/go.mod h1:pMCz62A0xJL6I+umB2YTlFRwWXaDFA0jy+5HzGiJjqI= +github.com/iris-contrib/schema v0.0.1/go.mod h1:urYA3uvUNG1TIIjOSCzHr9/LmbQo8LrOcOqfqxa4hXw= github.com/jmhodges/levigo v1.0.0 h1:q5EC36kV79HWeTBWsod3mG11EgStG3qArTKcvlksN1U= github.com/jmhodges/levigo v1.0.0/go.mod h1:Q6Qx+uH3RAqyK4rFQroq9RL7mdkABMcfhEI+nNuzMJQ= +github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= +github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= +github.com/juju/errors v0.0.0-20181118221551-089d3ea4e4d5/go.mod h1:W54LbzXuIE0boCoNJfwqpmkKJ1O4TCTZMetAt6jGk7Q= +github.com/juju/loggo v0.0.0-20180524022052-584905176618/go.mod h1:vgyd7OREkbtVEN/8IXZe5Ooef3LQePvuBm9UWj6ZL8U= +github.com/juju/testing v0.0.0-20180920084828-472a3e8b2073/go.mod h1:63prj8cnj0tU0S9OHjGJn+b1h0ZghCndfnbQolrYTwA= +github.com/jung-kurt/gofpdf v1.0.3-0.20190309125859-24315acbbda5/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes= +github.com/k0kubun/colorstring v0.0.0-20150214042306-9440f1994b88/go.mod h1:3w7q1U84EfirKl04SVQ/s7nPm1ZPhiXd34z40TNz36k= +github.com/kataras/golog v0.0.9/go.mod h1:12HJgwBIZFNGL0EJnMRhmvGA0PQGx8VFwrZtM4CqbAk= +github.com/kataras/iris/v12 v12.0.1/go.mod h1:udK4vLQKkdDqMGJJVd/msuMtN6hpYJhg/lSzuxjhO+U= +github.com/kataras/neffos v0.0.10/go.mod h1:ZYmJC07hQPW67eKuzlfY7SO3bC0mw83A3j6im82hfqw= +github.com/kataras/pio v0.0.0-20190103105442-ea782b38602d/go.mod h1:NV88laa9UiiDuX9AhMbDPkGYSPugBOV6yTZB1l2K9Z0= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= +github.com/klauspost/compress v1.8.2/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.9.0/go.mod h1:RyIbtBH6LamlWaDj8nUwkbUhJ87Yi3uG0guNDohfE1A= +github.com/klauspost/compress v1.11.7/go.mod h1:aoV0uJVorq1K+umq18yTdKaF57EivdYsUV+/s2qKfXs= github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU= github.com/klauspost/compress v1.12.3/go.mod h1:8dP1Hq4DHOhN9w426knH3Rhby4rFm6D8eO+e+Dq5Gzg= +github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= -github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= +github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= +github.com/labstack/echo/v4 v4.1.11/go.mod h1:i541M3Fj6f76NZtHSj7TXnyM8n2gaodfvfxNnFqi74g= +github.com/labstack/gommon v0.3.0/go.mod h1:MULnywXg0yavhxWKc+lOruYdAhDwPK9wf0OL7NoOu+k= github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= +github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= +github.com/mattn/go-isatty v0.0.7/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= +github.com/mattn/go-isatty v0.0.9/go.mod h1:YNRxwqDuOph6SZLI9vUUz6OYw3QyUt7WiY2yME+cCiQ= +github.com/mattn/goveralls v0.0.2/go.mod h1:8d1ZMHsd7fW6IRPKQh46F2WRpyib5/X4FOpevwGNQEw= +github.com/mediocregopher/mediocre-go-lib v0.0.0-20181029021733-cb65787f37ed/go.mod h1:dSsfyI2zABAdhcbvkXqgxOxrCsbYeHCPgrZkku60dSg= +github.com/mediocregopher/radix/v3 v3.3.0/go.mod h1:EmfVyvspXz1uZEyPBMyGK+kjWiKQGvsUt6O3Pj+LDCQ= +github.com/microcosm-cc/bluemonday v1.0.2/go.mod h1:iVP4YcDBq+n/5fb23BhYFvIMq/leAFZyRl6bYmGDlGc= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= +github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= +github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= +github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= +github.com/nats-io/nats.go v1.8.1/go.mod h1:BrFz9vVn0fU3AcH9Vn4Kd7W0NpJ651tD5omQ3M8LwxM= +github.com/nats-io/nkeys v0.0.2/go.mod h1:dab7URMsZm6Z/jp9Z5UGa87Uutgc2mVpXLC4B7TDb/4= +github.com/nats-io/nuid v1.0.1/go.mod h1:19wcPz3Ph3q0Jbyiqsd0kePYG7A95tJPxeL+1OSON2c= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= +github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLANZcx1PVRCS0qkT7pwLkGfwJo4zjcN/Tysno= github.com/nxadm/tail v1.4.4 h1:DQuhQpB1tVlglWS2hLQ5OV6B5r8aGxSrPc5Qo6uTN78= github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= +github.com/onsi/ginkgo v1.13.0/go.mod h1:+REjRxOmWfHCjfv9TTWB1jD1Frx4XydAD3zm1lskyM0= github.com/onsi/ginkgo v1.14.0 h1:2mOpI4JVVPBN+WQRa0WKH2eXR+Ey+uK4n7Zj0aYpIQA= github.com/onsi/ginkgo v1.14.0/go.mod h1:iSB4RoI2tjJc9BBv4NKIKWKya62Rps+oPG/Lv9klQyY= github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY= github.com/onsi/gomega v1.10.1 h1:o0+MgICZLuZ7xjH7Vx6zS/zcu93/BEp1VwkIW1mEXCE= github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= +github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= +github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4= github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= @@ -124,9 +212,12 @@ github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZN github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/russross/blackfriday v1.5.2/go.mod h1:JO/DiYxRf+HjHt06OyowR9PTA263kcR/rfWxYHBV53g= -github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= -github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= -github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFouqFdy9/2g9QGwK3SQygK0Ts= +github.com/sclevine/agouti v3.0.0+incompatible/go.mod h1:b4WX9W9L1sfQKXeJf1mUTLZKJ48R1S7H23Ji7oFO5Bw= +github.com/sergi/go-diff v1.1.0/go.mod h1:STckp+ISIX8hZLjrqAeVduY0gWCT9IjLuqbuNXdaHfM= +github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeVRXNmyL/1OwPU0+IJeTBvfc= +github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU= @@ -136,6 +227,7 @@ github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DM github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= +github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= @@ -144,33 +236,62 @@ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PK github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca h1:Ld/zXl5t4+D69SiV4JoN7kkfvJdOWlPpfxrzxpLMoUk= github.com/syndtr/goleveldb v1.0.1-0.20200815110645-5c35d600f0ca/go.mod h1:u2MKkTVTVJWe5D1rCvame8WqhBd88EuIwODJZ1VHCPM= +github.com/ugorji/go v1.1.4/go.mod h1:uQMGLiO92mf5W77hV/PUCpI3pbzQx3CRekS0kk+RGrc= github.com/ugorji/go/codec v0.0.0-20181204163529-d75b2dcb6bc8/go.mod h1:VFNgLljTbGfSG7qAOspJ7OScBnGdDN/yBr0sguwnwf0= +github.com/urfave/negroni v1.0.0/go.mod h1:Meg73S6kFm/4PpbYdq35yYWoCZ9mS/YSx+lKnmiohz4= +github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc= +github.com/valyala/fasthttp v1.6.0/go.mod h1:FstJa9V+Pj9vQ7OJie2qMHdwemEDaDiSdBnvPM1Su9w= +github.com/valyala/fasttemplate v1.0.1/go.mod h1:UQGH1tvbgY+Nz5t2n7tXsz52dQxojPUpymEIMZ47gx8= +github.com/valyala/tcplisten v0.0.0-20161114210144-ceec8f93295a/go.mod h1:v3UYOV9WzVtRmSR+PDvWpU/qWl4Wa5LApYYX4ZtKbio= +github.com/xeipuuv/gojsonpointer v0.0.0-20180127040702-4e3ac2762d5f/go.mod h1:N2zxlSyiKSe5eX1tZViRH5QA0qijqEDrYZiPEAiq3wU= +github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415/go.mod h1:GwrjFmJcFw6At/Gs6z4yjiIwzuJ1/+UwLxMQDVQXShQ= +github.com/xeipuuv/gojsonschema v1.2.0/go.mod h1:anYRn/JVcOK2ZgGU+IjEV4nwlhoK5sQluxsYJ78Id3Y= github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q= +github.com/yalp/jsonpath v0.0.0-20180802001716-5cc68e5049a0/go.mod h1:/LWChgwKmvncFJFHJ7Gvn9wZArjbV5/FppcK2fKk/tI= +github.com/yudai/gojsondiff v1.0.0/go.mod h1:AY32+k2cwILAkW1fbgxQ5mUmMiZFgLIV+FBNExI05xg= +github.com/yudai/golcs v0.0.0-20170316035057-ecda9a501e82/go.mod h1:lgjkn3NuSvDfVJdfcVVdX+jpBxNmX4rDAzaS45IcYoM= +github.com/yudai/pp v2.0.1+incompatible/go.mod h1:PuxR/8QJ7cyCkFp/aUDS+JY727OFEZkTdatxwunjIkc= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= -go.etcd.io/bbolt v1.3.6 h1:/ecaJf0sk1l4l6V4awd65v2C3ILy7MSj+s/x1ADCIMU= -go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= -go.opencensus.io v0.22.5 h1:dntmOdLpSpHlVqbW5Eay97DelsZHe+55D+xC6i0dDS0= -go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= golang.org/x/crypto v0.0.0-20181203042331-505ab145d0a9/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20190701094942-4def268fd1a4/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20180321215751-8460e604b9de/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20180807140117-3d87b88a115f/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190125153040-c74c464bbbf2/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= +golang.org/x/exp v0.0.0-20191030013958-a1ab85dbe136/go.mod h1:JXzH8nQsPlswgeRAPE3MuO9GYsAcnJvJ4vnMwN/5qkY= +golang.org/x/exp v0.0.0-20200513190911-00229845015e h1:rMqLP+9XLy+LdbCXHjJHAmTfXCr93W7oruWA6Hq1Alc= +golang.org/x/exp v0.0.0-20200513190911-00229845015e/go.mod h1:4M0jN8W1tt0AVLNr8HDosyJCDCDuyL9N9+3m7wDWgKw= +golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHlgUYUwCkIfeOF89ocIRzGO/8vkc= +golang.org/x/mobile v0.0.0-20190719004257-d2bd2a29d028/go.mod h1:E/iHnbuqvinMTCcRqshq8CkpyQDoeVncDDYHnLhea+o= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= +golang.org/x/mod v0.1.1-0.20191107180719-034126e5016b/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180826012351-8a410e7b638d/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190327091125-710a502c58a2/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190503192946-f4e77d36d62c/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20190827160401-ba9fcec4b297/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200520004742-59133d7f0dd7/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200813134508-3edf25e44fcc/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -185,35 +306,47 @@ golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20190227155943-e225da77a7e6/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20190502145724-3ef323f4f1fd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190626221950-04f50cda93cb/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20190904154756-749cb33beabd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20191001151750-bb3f8db39f24/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191005200804-aed5e4c7ecf9/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191120155948-bd437916bb0e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200519105757-fe76b779f299/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200814200057-3d37ad5750ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210119212857-b64e53b001e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210909193231-528a39cd75f3/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9 h1:nhht2DYV/Sn3qOayu8lM+cU1ii9sTLUeBQwQQfUHtrs= golang.org/x/sys v0.0.0-20220227234510-4e6760a101f9/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/tools v0.0.0-20180525024113-a5b4c53f6e8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181221001348-537d06c36207/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190206041539-40960b6deb8e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190327201419-c70d86f8b7cf/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= +golang.org/x/tools v0.0.0-20191012152004-8de300cfc20a/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200207183749-b753a1ba74fa/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= @@ -221,19 +354,25 @@ golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8T golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gonum.org/v1/gonum v0.0.0-20180816165407-929014505bf4/go.mod h1:Y+Yx5eoAFn32cQvJDxZx5Dpnq+c3wtXuadVZAcxbbBo= +gonum.org/v1/gonum v0.8.2 h1:CCXrcPKiGGotvnN6jfUsKk4rRqm7q09/YbKb5xCEvtM= +gonum.org/v1/gonum v0.8.2/go.mod h1:oe/vMfY3deqTw+1EZJhuvEW2iwGF1bW9wwu7XCu0+v0= +gonum.org/v1/netlib v0.0.0-20190313105609-8cb42192e0e0/go.mod h1:wa6Ws7BG/ESfp6dHfk7C6KdzKA7wR7u/rKwOGE66zvw= +gonum.org/v1/plot v0.0.0-20190515093506-e2840ee46a6b/go.mod h1:Wt8AAjI+ypCyYX3nZBvf6cAIx93T+c/OS2HFAYskSZc= google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM= google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= +google.golang.org/genproto v0.0.0-20180518175338-11a468237815/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= -google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE= google.golang.org/genproto v0.0.0-20190819201941-24fa4b261c55/go.mod h1:DMBHOl98Agz4BDEuKkezgsaosCRResVns1a3J2ZsMNc= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013 h1:+kGHl1aib/qcwaRi1CbqBZ1rk19r85MNUf8HaBghugY= google.golang.org/genproto v0.0.0-20200526211855-cb27e3aa2013/go.mod h1:NbSheEEYHJ7i3ixzK3sjbqSGDJWnxyFXZblF3eUsNvo= +google.golang.org/grpc v1.12.0/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c= -google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38= google.golang.org/grpc v1.23.0/go.mod h1:Y5yQAOtifL1yxbo5wqy6BxZv8vAUGQwXBOALyacEbxg= google.golang.org/grpc v1.25.1/go.mod h1:c3i+UQWmh7LiEpx4sFZnkU36qjEYZ0imhYfXVyQciAY= google.golang.org/grpc v1.27.0/go.mod h1:qbnxyOmOxrQa7FizSgH+ReBfzJrCY1pSN7KXBS8abTk= +google.golang.org/grpc v1.29.1/go.mod h1:itym6AZVZYACWQqET3MqgPpjcuV5QH3BxFS3IjizoKk= google.golang.org/grpc v1.33.1/go.mod h1:fr5YgcSWrqhRRxogOsw7RzIpsmvOZ6IcH4kBYTpR3n0= google.golang.org/grpc v1.36.0/go.mod h1:qjiiYl8FncCW8feJPdyg3v6XW24KsRHe+dy9BAGRRjU= google.golang.org/grpc v1.48.0 h1:rQOsyJ/8+ufEDJd/Gdsz7HG220Mh9HAhFHRGnIjda0w= @@ -252,9 +391,13 @@ google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQ google.golang.org/protobuf v1.27.1 h1:SnqbnDw1V7RiZcXPx5MEeqPv2s79L9i7BJUlG/+RurQ= google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= -gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= +gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= +gopkg.in/go-playground/assert.v1 v1.2.1/go.mod h1:9RXL0bg/zibRAgZUYszZSwO/z8Y/a8bDuhia5mkpMnE= +gopkg.in/go-playground/validator.v8 v8.18.2/go.mod h1:RX2a/7Ha8BgOhfk7j780h4/u/RRjR0eouCJSH80/M2Y= +gopkg.in/mgo.v2 v2.0.0-20180705113604-9856a29383ce/go.mod h1:yeKp02qBN3iKW1OzL3MGk2IdtZzaj7SFntXj72NppTA= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -267,3 +410,4 @@ gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA= gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4= +rsc.io/pdf v0.1.1/go.mod h1:n8OzWcQ6Sp37PL01nO98y4iUCRdTGarVfzxY20ICaU4= diff --git a/goleveldb_iterator.go b/goleveldb_iterator.go index 9cf9a5e15..5341d1ac2 100644 --- a/goleveldb_iterator.go +++ b/goleveldb_iterator.go @@ -54,7 +54,6 @@ func (itr *goLevelDBIterator) Domain() ([]byte, []byte) { // Valid implements Iterator. func (itr *goLevelDBIterator) Valid() bool { - // Once invalid, forever invalid. if itr.isInvalid { return false @@ -73,9 +72,9 @@ func (itr *goLevelDBIterator) Valid() bool { } // If key is end or past it, invalid. - var start = itr.start - var end = itr.end - var key = itr.source.Key() + start := itr.start + end := itr.end + key := itr.source.Key() if itr.isReverse { if start != nil && bytes.Compare(key, start) < 0 { diff --git a/makefile b/makefile index bedebc457..f5453e26c 100644 --- a/makefile +++ b/makefile @@ -24,13 +24,13 @@ test-boltdb: @echo "--> Running go test" @go test $(PACKAGES) -tags boltdb -v -test-badgerdb: +test-pebble: @echo "--> Running go test" - @go test $(PACKAGES) -tags badgerdb -v + @go test $(PACKAGES) -tags pebbledb -v test-all: @echo "--> Running go test" - @go test $(PACKAGES) -tags cleveldb,boltdb,rocksdb,badgerdb -v + @go test $(PACKAGES) -tags cleveldb,rocksdb,pebble -v lint: @echo "--> Running linter" diff --git a/pebble.go b/pebble.go new file mode 100644 index 000000000..6c50527ef --- /dev/null +++ b/pebble.go @@ -0,0 +1,218 @@ +//go:build pebbledb + +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 (db *PebbleDB) DB() *pebble.DB { + return db.db +} + +// NB: A lot of the code in this file is sourced from here: https://github.com/cockroachdb/pebble/blob/master/cmd/pebble/db.go +// NB: This was my best working commit from today July 27 2022: https://github.com/notional-labs/tm-db/tree/6a41b774b9c362cac7d22156fa1021780d801f8a + +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 +} + +// 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 +} + +// The stats section was contributed by ValNodes. Toss e'm some stake! +// Stats implements DB. +func (db *PebbleDB) Stats() map[string]string { + stats := make(map[string]string, 1) + stats["Metrics"] = fmt.Sprint(db.db.Metrics()) + return stats +} + +// NewBatch implements DB. +func (db *PebbleDB) NewBatch() Batch { + return newPebbleDBBatch(db) +} + +// NB For the reverse iterator and the iterator, this seems to make some sense: https://github.com/cockroachdb/pebble/blob/7b78c71e40558c8d6cc1c673b5075376609ff4ea/cmd/pebble/db.go#L120 + +// 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 +} diff --git a/pebble_batch.go b/pebble_batch.go new file mode 100644 index 000000000..9883ce477 --- /dev/null +++ b/pebble_batch.go @@ -0,0 +1,91 @@ +//go:build pebbledb + +package db + +import "github.com/cockroachdb/pebble" + +type pebbleDBBatch struct { + db *PebbleDB + batch *pebble.Batch +} + +var _ Batch = (*pebbleDBBatch)(nil) + +// new PebbleDBBatch returns a new PebbleDBBatch. +func newPebbleDBBatch(db *PebbleDB) *pebbleDBBatch { + return &pebbleDBBatch{ + batch: db.db.NewBatch(), + } +} + +// Set implements Batch. +// 1) we make sure that the key is not empty, and if it is we return errKeyEmpty. +// 2) Then we check if the value is nil, If the value is nil, we return an error. +// 3) Then we check if the batch is nil value, and return errBatchClosed if it is. +// 4) We set a new value in the batch. +// 5) We return nil. +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 +} diff --git a/pebble_batch_test.go b/pebble_batch_test.go new file mode 100644 index 000000000..b06a07564 --- /dev/null +++ b/pebble_batch_test.go @@ -0,0 +1,5 @@ +//go:build pebbledb + +package db + +// Stub file for the tests for the pebble batch only diff --git a/pebble_iterator.go b/pebble_iterator.go new file mode 100644 index 000000000..040f04d46 --- /dev/null +++ b/pebble_iterator.go @@ -0,0 +1,127 @@ +//go:build pebbledb + +package db + +import ( + "bytes" + + "github.com/cockroachdb/pebble" +) + +type pebbleDBIterator struct { + source *pebble.Iterator + start, end []byte + isReverse bool + isInvalid bool +} + +var _ Iterator = (*pebbleDBIterator)(nil) + +func newPebbleDBIterator(source *pebble.Iterator, start, end []byte, isReverse bool) *pebbleDBIterator { + if isReverse { + if end == nil { + source.Last() + } + } else { + if start == nil { + source.First() + } + } + return &pebbleDBIterator{ + source: source, + start: start, + end: end, + isReverse: isReverse, + isInvalid: false, + } +} + +// Domain implements Iterator. +func (itr *pebbleDBIterator) Domain() ([]byte, []byte) { + return itr.start, itr.end +} + +// Valid implements Iterator. +func (itr *pebbleDBIterator) Valid() bool { + // Once invalid, forever invalid. + if itr.isInvalid { + return false + } + + // If source has error, invalid. + if err := itr.source.Error(); err != nil { + itr.isInvalid = true + + return false + } + + // If source is invalid, invalid. + if !itr.source.Valid() { + itr.isInvalid = true + + return false + } + + // If key is end or past it, invalid. + start := itr.start + end := itr.end + key := itr.source.Key() + if itr.isReverse { + if start != nil && bytes.Compare(key, start) < 0 { + itr.isInvalid = true + + return false + } + } else { + if end != nil && bytes.Compare(end, key) <= 0 { + itr.isInvalid = true + + return false + } + } + + // It's valid. + return true +} + +// Key implements Iterator. +func (itr *pebbleDBIterator) Key() []byte { + itr.assertIsValid() + return itr.source.Key() +} + +// Value implements Iterator. +func (itr *pebbleDBIterator) Value() []byte { + itr.assertIsValid() + return itr.source.Value() +} + +// Next implements Iterator. +func (itr pebbleDBIterator) Next() { + itr.assertIsValid() + if itr.isReverse { + itr.source.Prev() + } else { + itr.source.Next() + } +} + +// Error implements Iterator. +func (itr *pebbleDBIterator) Error() error { + return itr.source.Error() +} + +// Close implements Iterator. +func (itr *pebbleDBIterator) Close() error { + err := itr.source.Close() + if err != nil { + return err + } + return nil +} + +func (itr *pebbleDBIterator) assertIsValid() { + if !itr.Valid() { + panic("iterator is invalid") + } +} diff --git a/pebble_iterator_test.go b/pebble_iterator_test.go new file mode 100644 index 000000000..cf33484fb --- /dev/null +++ b/pebble_iterator_test.go @@ -0,0 +1,3 @@ +package db + +// this file contains tests related to the pebble iterator only diff --git a/pebble_test.go b/pebble_test.go new file mode 100644 index 000000000..ae414209a --- /dev/null +++ b/pebble_test.go @@ -0,0 +1,61 @@ +//go:build pebbledb + +package db + +import ( + "fmt" + "os" + "path/filepath" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestPebbleDBBackend(t *testing.T) { + name := fmt.Sprintf("test_%x", randStr(12)) + dir := os.TempDir() + db, err := NewDB(name, PebbleDBBackend, dir) + require.NoError(t, err) + defer cleanupDBDir(dir, name) + + _, ok := db.(*PebbleDB) + assert.True(t, ok) +} + +func TestWithPebbleDB(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "pebbledb") + + db, err := NewPebbleDB(path, "") + require.NoError(t, err) + + t.Run("PebbleDB", func(t *testing.T) { Run(t, db) }) +} + +func TestPebbleDBStats(t *testing.T) { + name := fmt.Sprintf("test_%x", randStr(12)) + dir := os.TempDir() + db, err := NewDB(name, PebbleDBBackend, dir) + require.NoError(t, err) + defer cleanupDBDir(dir, name) + + assert.NotEmpty(t, db.Stats()) +} + +func BenchmarkPebbleDBRandomReadsWrites(b *testing.B) { + name := fmt.Sprintf("test_%x", randStr(12)) + dir := os.TempDir() + db, err := NewDB(name, PebbleDBBackend, dir) + if err != nil { + b.Fatal(err) + } + defer func() { + db.Close() + cleanupDBDir("", name) + }() + + benchmarkRandomReadsWrites(b, db) +} + +// TODO: Add tests for pebble diff --git a/prefixdb.go b/prefixdb.go index 0b2d2a1cf..447ce2e9b 100644 --- a/prefixdb.go +++ b/prefixdb.go @@ -27,8 +27,6 @@ func (pdb *PrefixDB) Get(key []byte) ([]byte, error) { if len(key) == 0 { return nil, errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() pkey := pdb.prefixed(key) value, err := pdb.db.Get(pkey) @@ -43,8 +41,6 @@ func (pdb *PrefixDB) Has(key []byte) (bool, error) { if len(key) == 0 { return false, errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() ok, err := pdb.db.Has(pdb.prefixed(key)) if err != nil { @@ -62,8 +58,6 @@ func (pdb *PrefixDB) Set(key []byte, value []byte) error { if value == nil { return errValueNil } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() pkey := pdb.prefixed(key) if err := pdb.db.Set(pkey, value); err != nil { @@ -80,8 +74,6 @@ func (pdb *PrefixDB) SetSync(key []byte, value []byte) error { if value == nil { return errValueNil } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() return pdb.db.SetSync(pdb.prefixed(key), value) } @@ -91,8 +83,6 @@ func (pdb *PrefixDB) Delete(key []byte) error { if len(key) == 0 { return errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() return pdb.db.Delete(pdb.prefixed(key)) } @@ -102,8 +92,6 @@ func (pdb *PrefixDB) DeleteSync(key []byte) error { if len(key) == 0 { return errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() return pdb.db.DeleteSync(pdb.prefixed(key)) } @@ -113,8 +101,6 @@ func (pdb *PrefixDB) Iterator(start, end []byte) (Iterator, error) { if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { return nil, errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() var pstart, pend []byte pstart = append(cp(pdb.prefix), start...) @@ -136,8 +122,6 @@ func (pdb *PrefixDB) ReverseIterator(start, end []byte) (Iterator, error) { if (start != nil && len(start) == 0) || (end != nil && len(end) == 0) { return nil, errKeyEmpty } - pdb.mtx.Lock() - defer pdb.mtx.Unlock() var pstart, pend []byte pstart = append(cp(pdb.prefix), start...) @@ -156,9 +140,6 @@ func (pdb *PrefixDB) ReverseIterator(start, end []byte) (Iterator, error) { // NewBatch implements DB. func (pdb *PrefixDB) NewBatch() Batch { - pdb.mtx.Lock() - defer pdb.mtx.Unlock() - return newPrefixBatch(pdb.prefix, pdb.db.NewBatch()) } diff --git a/prefixdb_iterator.go b/prefixdb_iterator.go index 79e1ef7fa..8f2f93262 100644 --- a/prefixdb_iterator.go +++ b/prefixdb_iterator.go @@ -91,7 +91,6 @@ func (itr *prefixDBIterator) Next() { if !itr.source.Valid() || !bytes.HasPrefix(itr.source.Key(), itr.prefix) { itr.valid = false - } else if bytes.Equal(itr.source.Key(), itr.prefix) { // Empty keys are not allowed, so if a key exists in the database that exactly matches the // prefix we need to skip it. diff --git a/prefixdb_test.go b/prefixdb_test.go index 3fc53ee92..931c2c929 100644 --- a/prefixdb_test.go +++ b/prefixdb_test.go @@ -1,6 +1,12 @@ package db import ( + "bytes" + "encoding/binary" + "fmt" + "math/rand" + "path/filepath" + "sync" "testing" "github.com/stretchr/testify/require" @@ -20,6 +26,97 @@ func mockDBWithStuff(t *testing.T) DB { return db } +func taskKey(i, k int) []byte { + return []byte(fmt.Sprintf("task-%d-key-%d", i, k)) +} + +func randomValue() []byte { + b := make([]byte, 16) + rand.Read(b) + return b +} + +func TestGolevelDB(t *testing.T) { + path := filepath.Join(t.TempDir(), "goleveldb") + + db, err := NewGoLevelDB(path, "") + require.NoError(t, err) + + Run(t, db) +} + +func TestWithMemDB(t *testing.T) { + db := NewMemDB() + + t.Run("MemDB", func(t *testing.T) { Run(t, db) }) +} + +// Run generates concurrent reads and writes to db so the race detector can +// verify concurrent operations are properly synchronized. +// The contents of db are garbage after Run returns. +func Run(t *testing.T, db DB) { + t.Helper() + + const numWorkers = 10 + const numKeys = 64 + + var wg sync.WaitGroup + for i := 0; i < numWorkers; i++ { + wg.Add(1) + i := i + go func() { + defer wg.Done() + + // Insert a bunch of keys with random data. + for k := 1; k <= numKeys; k++ { + key := taskKey(i, k) // say, "task--key-" + value := randomValue() + if err := db.Set(key, value); err != nil { + t.Errorf("Task %d: db.Set(%q=%q) failed: %v", + i, string(key), string(value), err) + } + } + + // Iterate over the database to make sure our keys are there. + it, err := db.Iterator(nil, nil) + if err != nil { + t.Errorf("Iterator[%d]: %v", i, err) + return + } + found := make(map[string][]byte) + mine := []byte(fmt.Sprintf("task-%d-", i)) + for { + if key := it.Key(); bytes.HasPrefix(key, mine) { + found[string(key)] = it.Value() + } + it.Next() + if !it.Valid() { + break + } + } + if err := it.Error(); err != nil { + t.Errorf("Iterator[%d] reported error: %v", i, err) + } + if err := it.Close(); err != nil { + t.Errorf("Close iterator[%d]: %v", i, err) + } + if len(found) != numKeys { + t.Errorf("Task %d: found %d keys, wanted %d", i, len(found), numKeys) + } + + // Delete all the keys we inserted. + for key := range mine { + bs := make([]byte, 4) + binary.LittleEndian.PutUint32(bs, uint32(key)) + if err := db.Delete(bs); err != nil { + t.Errorf("Delete %q: %v", key, err) + } + } + }() + } + wg.Wait() +} + func TestPrefixDBSimple(t *testing.T) { db := mockDBWithStuff(t) pdb := NewPrefixDB(db, bz("key")) diff --git a/remotedb/test.crt b/remotedb/test.crt index 8ce516466..b3b203e37 100644 --- a/remotedb/test.crt +++ b/remotedb/test.crt @@ -1,25 +1,25 @@ -----BEGIN CERTIFICATE----- -MIIEOjCCAiKgAwIBAgIQfxecvKrUOJEOok/qZ2WLnjANBgkqhkiG9w0BAQsFADAZ -MRcwFQYDVQQDEw50ZW5kZXJtaW50LmNvbTAeFw0yMTAxMjAwOTE2NTBaFw0yMjA3 -MjAwOTE2NDZaMBMxETAPBgNVBAMTCHJlbW90ZWRiMIIBIjANBgkqhkiG9w0BAQEF -AAOCAQ8AMIIBCgKCAQEAqNCbMG9fwkcloAZIHOhpE5Lzg7FIpykiXOt/zUShiSKc -9eDGF5+IBRY9RtZVLBZ9nTAWzK+fAGx9YiYoV0XY0I9iFWl9nInkfuFy0jqkbRov -/VBRHZ0mmyQlqJOsVzBi/erKpRhINXl6Z1MHqTIV+ae2lfEar02UEByyy8lwRY1D -y5U+mY9/5oy/hB6yI77gkZq3hqC65LLg54+Dq4YG6UlkUKmejBslwD0r6S0LCnX2 -0RXEEjONnrSpY7yckmPg4IgvUkEKZRiPIvgHIYqEQRrJi2E1r+djI+zObZDUCZV8 -qucS5rf3BkSrbt0Pe8af14gKQ4tkxgPtNNhZbtLGSwIDAQABo4GDMIGAMA4GA1Ud +MIIEOjCCAiKgAwIBAgIQELi28YSz7wnGMCFY/LkGTDANBgkqhkiG9w0BAQsFADAZ +MRcwFQYDVQQDEw50ZW5kZXJtaW50LmNvbTAeFw0yMjA3MjYxMTQ1NTVaFw0yNDAx +MjYxMTQ1NTVaMBMxETAPBgNVBAMTCHJlbW90ZWRiMIIBIjANBgkqhkiG9w0BAQEF +AAOCAQ8AMIIBCgKCAQEA93GhF6GfEyh7VRBsLGlKMsG7rbE5Z6HjoMzWvURXjV2C +jsSfCmmVhv6UeaTQc8Wci7Sdabwm9eTiv1ikeY0ZYt+oZdcvhjXP4+so4yhPiBMk +II/Ds4VcojZ+aGXdbvhcdemFy0ZpvQ1nqJGdKgMt7CSExe8/Q06Xgy3JzlhlVMlb +KRC1OywwjxTxCjdA1MzmUG+P/4wYls0ejvco87UfSmaIm6GJwi3H9QlrtPAaI7JH +sZS1puR4JkA1xusBY1A5LeWLDaCmiSYh2x2NC7CiF23Fj5K4YQegQ1TsZxgS7pG1 +OZiAsa65V/pNXI3MAGk7k0Yb6Ai+IhzaczHAvhf4VQIDAQABo4GDMIGAMA4GA1Ud DwEB/wQEAwIDuDAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUHAwIwHQYDVR0O -BBYEFGNRxW37g6FMPcR7GmZejA+9BZfmMB8GA1UdIwQYMBaAFBoC/uE2wTQRb1Z+ -esvMU5ae/TdrMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQELBQADggIBAChw -YIz+UVWKKnPE7VqTZutKypUBrDfnngXWfMXzTm6jrgD2JOC2Dj50itG+FPytjs8O -0zdQ4rL8buq5fLU3BmLMW4M16rtv/3jWzo2CP5i49cHIur8loZe/jxzbTX+d5qah -zThR5VvZKr4cF/p6TODjwwpe3y00gIJryJ7IOIppM3EGMDy2PVJ0pEF1xslpIyZY -k5WBmmFZadsf1DY9j0R+f45754kGdH3IEUGbsbWxn7E6YNDTUeHE+8ZW0sMBmPWl -XnE2q1Z2eTfiPVmfOhHNBiLt5qoWHJnAuI3KpNPhGbcPIUbHNZtnLN4jH+pblHAE -eIy1f1otJcexjH1/axxw2tIwy5s6o6tlbWotRa54kguhaPL7rqVeePBCphh0Ak8O -0KkM8ai5E9+aMfm7VP7L5gidzXnZJltveh7szD+wGeXq/RbT9ZYortYP320SJnn/ -E12CFIyHmBorNgmPFlUnrHiUKJ1Wfii5Vbwqc4bv5qOZ6UECVHI9oo0Juhf1KJVY -i7zIJ6x3zZ/pRGU0Sks2H7ZFx3wBARR413q9flS7leYFR9cmo2lDmjUfbfmbCEjW -/dt/PFrTMbAhEHSlGcICjnCxNz1uVEnEtPD/XmioxLsSwiGW1f1TOZboVC0Z7Qdk -VyaP7W3ChntBIJhM2x95BYsId5CsHAZ30d1ztxa6 +BBYEFKaGp/Pd8Iy9l+V5oeFAbv0MylOTMB8GA1UdIwQYMBaAFNSp7CXUG885Al3n +oJjlAZ0I+/yfMA8GA1UdEQQIMAaHBH8AAAEwDQYJKoZIhvcNAQELBQADggIBAHfM +odmek2HhUKzmqBSaLMHstyiGlxUDuUALfkJY8TNAtC02J9TIrAcT5dqT7zdKq3d5 +AldjBMcj3R9WlUPZv4prEvaLJSCpUilgGETVo4Q6EjTwplUiC558XspORF5WAZuB +73gxrz6rc8zUXDKcf0ey/kV/WOFS4ICjVhJMVa8hesd9JiQIqYnf0N1XrXk/YAqf +10lH+AWza5EsVH4sg45DVdwM45OxRIK1fQbSpBYczpT+UocGQWe1J2ehthFlh5Ab +V9OQ4TdJEdIs/p9WSZ9tmRlXJVvo2A9wWD3NOOSWiAXhKBBr5QsqNqaMjqQpajbT +STaQS3zeVAEYKdOUGy16ymfBm4nwcneDbwFOAGMahu3l/V4vlXA+Eb5tdSX1kwcf +l3ImQglBwwXTXPf1yyLXOVHFxqXTZI9fVOFB1qd4l76aGN0fBvnleqbhmXNohcVe +B/x/liaiGhL/udhDM7Y+dspw8LmNTGsqYGgYKmD3prFfWrkYcaRc32bPs9fk8hOz +e7vCQwSAbTEfXZ9/q7MwNcBG35iz37GJa9tV5Mg5UbJeZzj85PpnfIcCu6bmHlA9 +ROlJ8XF0TDqtvQrxz3WGaSm22DgkUP/Z+anCy+7E78dX1Ef+d1lg045PiHGijFIC +5NMT9dYCR7J3c6S6fDkSl0/iR0v5URCFJ7t2xjIC -----END CERTIFICATE----- diff --git a/remotedb/test.key b/remotedb/test.key index 8a125c208..15ada098c 100644 --- a/remotedb/test.key +++ b/remotedb/test.key @@ -1,27 +1,27 @@ -----BEGIN RSA PRIVATE KEY----- -MIIEpAIBAAKCAQEAqNCbMG9fwkcloAZIHOhpE5Lzg7FIpykiXOt/zUShiSKc9eDG -F5+IBRY9RtZVLBZ9nTAWzK+fAGx9YiYoV0XY0I9iFWl9nInkfuFy0jqkbRov/VBR -HZ0mmyQlqJOsVzBi/erKpRhINXl6Z1MHqTIV+ae2lfEar02UEByyy8lwRY1Dy5U+ -mY9/5oy/hB6yI77gkZq3hqC65LLg54+Dq4YG6UlkUKmejBslwD0r6S0LCnX20RXE -EjONnrSpY7yckmPg4IgvUkEKZRiPIvgHIYqEQRrJi2E1r+djI+zObZDUCZV8qucS -5rf3BkSrbt0Pe8af14gKQ4tkxgPtNNhZbtLGSwIDAQABAoIBAHXANE9fkErCN7Nc -Tlajog9+NA9KzKOUpJxtw9JZKdeu5g73fxUhOM5bidhsTjKXaX0H+w9A/MZd5kNc -3EyrsqUfLkpDL9PNtyztcprDPse/OXQW3s2qPTB/0Si6AL88SABXEox/2HY8Sq3h -k3loLz3ZxxjleTiIA1wNuIU+9+n6kiHvGlV8kow7pDLdnm0v6GMtGQb7a9MI4od7 -1U+iqiySzsqrBNdq2m9Zvs1OYQumP/xZnuL8w6xel/sM6k8AgV2ZXX6d7nWmQfYI -jcwdltm70KK9iMILh9M+Y/CCjwCQIwvDLyFp85zmlrlA3px0CHvnI+2RPMjOXLrb -8gJrQVkCgYEA0t3M+O1LWI/ODqDkjfeQdPwfawpwgXBJV5TkarwFjqWuuEz4/ryT -bSegciPBnRN4OVH45hXXCpPbol1pzg9kS5Frao/NLParPQSjB1EST3D5T1IhS0M3 -5BULFAgMf3DxGVJ50vC3nsvb5OuoPxmZMDkGwEgooAbyyb4yaiKpdx8CgYEAzPKi -5ptgbb1Q+dI7TfNqkA6pJWghtyuM2+rmp/6bCEsO34cQqgL/UDJlqgA29a85N0eg -7FGb4ppLV2wskojURQH+fl2ej2U//VvEup1zMFHjZzmLp7IH2cmcuNFfh2lR7Y1h -bEQbNVzGvKsXyJYWW61nT5Ek8NpbDr9LlSIHp1UCgYEAny4iqpNvenZsZeydPHJz -UWx2RzbFQWFDbGMQn2Y6h7mZELXCjYJLhG4Sl7dYVDw7WIIB86bvA6QkfAgqdAx4 -ePdY8EOH7nZzRAe5Di/sM54kBfYI/ijLC1m7WC7PSHE5ABWbs1pWMwDPiZtAEgo/ -8wBJkWOnj05Pf24d3rM13J8CgYEAoXbHQEdJQSvVj/xBHLiZS8VBHWdcqKJ25wu5 -jMDaAz6fCRuv1UFnRBdwYO6qXgUeXp7f+U6SMYS9trJSq1+BXJylk4jOUsrCDykt -ZJiHF5psPfboP8XSyZI9Fp5dVKF1GmI4TsOZbAEb0ag5pJ4aH0AOFHGVWOuusX+k -XGni/cECgYBod/Xv/dtB/+FdtkhYeqxXeTcOogg+5POXNcCDcfL6qw03Vt2mVXBd -CbFFnkYR5D0f3myIPPcDIO1hB18OV79kjDHcSRAYzN0zi2mPWyRIr+/ETVaYBPiZ -iYh1pgL97ufp+2tDPXSxaN222GmoCUuMZQe9gEBERswgMFzTrXBouw== +MIIEpQIBAAKCAQEA93GhF6GfEyh7VRBsLGlKMsG7rbE5Z6HjoMzWvURXjV2CjsSf +CmmVhv6UeaTQc8Wci7Sdabwm9eTiv1ikeY0ZYt+oZdcvhjXP4+so4yhPiBMkII/D +s4VcojZ+aGXdbvhcdemFy0ZpvQ1nqJGdKgMt7CSExe8/Q06Xgy3JzlhlVMlbKRC1 +OywwjxTxCjdA1MzmUG+P/4wYls0ejvco87UfSmaIm6GJwi3H9QlrtPAaI7JHsZS1 +puR4JkA1xusBY1A5LeWLDaCmiSYh2x2NC7CiF23Fj5K4YQegQ1TsZxgS7pG1OZiA +sa65V/pNXI3MAGk7k0Yb6Ai+IhzaczHAvhf4VQIDAQABAoIBAQC2tuA2O/Djy6uu +d275KFJSwn2cV1ZFMOSN01Pp9DIWP+ttEsFBhg+U3B206T/HjS74dkkaT4YRYo8Q +rhrdapRJT0/gy5HbL5cv/HB3tEdt+nxd0uq2gA6T9VtIKZfmHlzf8K0MGhVwNRrK +/aMo56ocSicEpZJ4V+tHQSNYTCue+5CzAsBzebh96/F0xx7Tb9AkjE3P0IPtgBgq +z0xT8rZxlxwDXgS1kw0EGGCFAFInJTziOqgS7rI6A6mznxNYAgWitziBiQrljXQj +3zssbt+nQ5iZLlICRBMgZXzOmI5nH5EXqYY+ZPANHpzb52MCMrA/3VNfxQj0OHth +ELH1BoptAoGBAPtRKv7hd+B6DXyuNZNpx33ELrS1dFC/1mtAN+6hBXDbTyYrNpcb +83BDP7l8W8RIZyh/6iG2lc8VQQxYHUPqHVfUSn4MLxFvF1vrxuROaCleSy2TXcwS +FFtBaBF8Mz2Gpnojhpu7jZ5FcG0gJ+oScRTSzCwY/Ko/Q1VaiZfOWAVjAoGBAPwN +/ELfkp2VNZY46NUQVhFMMbGI34XJ1W7oe63GwnrkRIbAqs7/Kj3tD3vy3PNgB1HK +ZERAgq/a4rwaOl2YvcAhTKgkYEbHpdz0ktv9qu3ShqJOpD1wOAGKmE8XXXuu/unw +/ScXqWwFH/bqs+/wktmzJHWWbmOOy1LX8DhwETTnAoGANFI1rVKrbmR6olZyePow +uhI51w1f5d/KeBGqk1ealmBSHhQpDVSYXeriPW+Se07Hizr2N4aXscEvBa7iiN0Y +tsxPpeZLdkm2h0CS670XGmWzKQ3hHTc2XblEPT+qO0jpJ8x1nb5yQV0bhtyG8shc +GoW4VAXvtFHvZrmuo5gl4xkCgYEA+YwLJlZdvWC9xjYf5tqeq8+JH6FI1BfJFV5d +HOa9I5iec9+K/RfKRbdP7kK8GMUJWiQMczp/aQZIFz3MbWBM9UzCrXIeU9VUVNdc +Eywpr/4QR9+eYimZeYUzWJLkfhD61rk+mhamKYlFZVxnu/WuHpVrUnQWZME6cpHS +hr4Fex8CgYEA1ma2f7DppXXZYEReqedsf+sN5/7KmnEH4H/f/7SAPLBLTJhV9zua +Mv3ur8wZH1NOb36o0jzFGdwXqjF1ubbJihKcJHz658q6lVbnaREa1NenZiVrm7H6 +SOHxWjPSvyUoj91ci4/5xeVWWtX2YyGHSMfJs5h4PNBVQPfON+uIhwQ= -----END RSA PRIVATE KEY----- diff --git a/rocksdb.go b/rocksdb.go index dd9be2a36..06d056dd8 100644 --- a/rocksdb.go +++ b/rocksdb.go @@ -1,3 +1,4 @@ +//go:build rocksdb // +build rocksdb package db diff --git a/rocksdb_batch.go b/rocksdb_batch.go index af7e65c60..b2557ac45 100644 --- a/rocksdb_batch.go +++ b/rocksdb_batch.go @@ -1,3 +1,4 @@ +//go:build rocksdb // +build rocksdb package db diff --git a/rocksdb_iterator.go b/rocksdb_iterator.go index 9970c169e..e79a76cd6 100644 --- a/rocksdb_iterator.go +++ b/rocksdb_iterator.go @@ -1,3 +1,4 @@ +//go:build rocksdb // +build rocksdb package db @@ -55,7 +56,6 @@ func (itr *rocksDBIterator) Domain() ([]byte, []byte) { // Valid implements Iterator. func (itr *rocksDBIterator) Valid() bool { - // Once invalid, forever invalid. if itr.isInvalid { return false @@ -74,9 +74,9 @@ func (itr *rocksDBIterator) Valid() bool { } // If key is end or past it, invalid. - var start = itr.start - var end = itr.end - var key = moveSliceToBytes(itr.source.Key()) + start := itr.start + end := itr.end + key := moveSliceToBytes(itr.source.Key()) if itr.isReverse { if start != nil && bytes.Compare(key, start) < 0 { itr.isInvalid = true diff --git a/rocksdb_test.go b/rocksdb_test.go index 6bbe51133..bd6793420 100644 --- a/rocksdb_test.go +++ b/rocksdb_test.go @@ -1,3 +1,4 @@ +//go:build rocksdb // +build rocksdb package db @@ -5,6 +6,7 @@ package db import ( "fmt" "os" + "path/filepath" "testing" "github.com/stretchr/testify/assert" @@ -22,6 +24,16 @@ func TestRocksDBBackend(t *testing.T) { assert.True(t, ok) } +func TestWithRocksDB(t *testing.T) { + dir := t.TempDir() + path := filepath.Join(dir, "rocksdb") + + db, err := NewRocksDB(path, "") + require.NoError(t, err) + + t.Run("RocksDB", func(t *testing.T) { Run(t, db) }) +} + func TestRocksDBStats(t *testing.T) { name := fmt.Sprintf("test_%x", randStr(12)) dir := os.TempDir() diff --git a/util_test.go b/util_test.go index 411abe1ee..68e6b8e40 100644 --- a/util_test.go +++ b/util_test.go @@ -25,11 +25,6 @@ func TestPrefixIteratorNoMatchNil(t *testing.T) { // Empty iterator for db populated after iterator created. func TestPrefixIteratorNoMatch1(t *testing.T) { for backend := range backends { - if backend == BoltDBBackend { - t.Log("bolt does not support concurrent writes while iterating") - continue - } - t.Run(fmt.Sprintf("Prefix w/ backend %s", backend), func(t *testing.T) { db, dir := newTempDB(t, backend) defer os.RemoveAll(dir)