From a2447a7f7dc022ee444511ce7810b408b891fd7d Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Mon, 22 Mar 2021 13:39:07 +0800 Subject: [PATCH 1/7] add go.mod --- .gitignore | 1 + go.mod | 10 ++++++++++ go.sum | 16 ++++++++++++++++ 3 files changed, 27 insertions(+) create mode 100644 go.mod create mode 100644 go.sum diff --git a/.gitignore b/.gitignore index 485dee64..3ce5adbb 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ .idea +vendor diff --git a/go.mod b/go.mod new file mode 100644 index 00000000..b0912f25 --- /dev/null +++ b/go.mod @@ -0,0 +1,10 @@ +module github.com/tecbot/gorocksdb + +go 1.13 + +require ( + github.com/facebookgo/ensure v0.0.0-20200202191622-63f1cf65ac4c + github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 // indirect + github.com/facebookgo/subset v0.0.0-20200203212716-c811ad88dec4 // indirect + github.com/stretchr/testify v1.7.0 +) diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..35ffeaf5 --- /dev/null +++ b/go.sum @@ -0,0 +1,16 @@ +github.com/davecgh/go-spew v1.1.0 h1:ZDRjVQ15GmhC3fiQ8ni8+OwkZQO4DARzQgrnXU1Liz8= +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +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/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY= +github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= From 63169b4e818b7091296d3388f844fe75f9f0dd2d Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Mon, 22 Mar 2021 11:54:43 +0800 Subject: [PATCH 2/7] Update for 6.16 --- db.go | 34 ++++++++++++++++++++++++---------- db_test.go | 18 ++++++++++++------ 2 files changed, 36 insertions(+), 16 deletions(-) diff --git a/db.go b/db.go index 64735c61..5e52d656 100755 --- a/db.go +++ b/db.go @@ -582,10 +582,11 @@ func (db *DB) DropColumnFamily(c *ColumnFamilyHandle) error { // // The keys counted will begin at Range.Start and end on the key before // Range.Limit. -func (db *DB) GetApproximateSizes(ranges []Range) []uint64 { - sizes := make([]uint64, len(ranges)) +func (db *DB) GetApproximateSizes(ranges []Range) (sizes []uint64, err error) { + var cErr *C.char + sizes = make([]uint64, len(ranges)) if len(ranges) == 0 { - return sizes + return } cStarts := make([]*C.char, len(ranges)) @@ -613,9 +614,15 @@ func (db *DB) GetApproximateSizes(ranges []Range) []uint64 { &cStartLens[0], &cLimits[0], &cLimitLens[0], - (*C.uint64_t)(&sizes[0])) + (*C.uint64_t)(&sizes[0]), + &cErr, + ) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + err = errors.New(C.GoString(cErr)) + } - return sizes + return } // GetApproximateSizesCF returns the approximate number of bytes of file system @@ -623,10 +630,11 @@ func (db *DB) GetApproximateSizes(ranges []Range) []uint64 { // // The keys counted will begin at Range.Start and end on the key before // Range.Limit. -func (db *DB) GetApproximateSizesCF(cf *ColumnFamilyHandle, ranges []Range) []uint64 { - sizes := make([]uint64, len(ranges)) +func (db *DB) GetApproximateSizesCF(cf *ColumnFamilyHandle, ranges []Range) (sizes []uint64, err error) { + var cErr *C.char + sizes = make([]uint64, len(ranges)) if len(ranges) == 0 { - return sizes + return } cStarts := make([]*C.char, len(ranges)) @@ -655,9 +663,15 @@ func (db *DB) GetApproximateSizesCF(cf *ColumnFamilyHandle, ranges []Range) []ui &cStartLens[0], &cLimits[0], &cLimitLens[0], - (*C.uint64_t)(&sizes[0])) + (*C.uint64_t)(&sizes[0]), + &cErr, + ) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + err = errors.New(C.GoString(cErr)) + } - return sizes + return } // SetOptions dynamically changes options through the SetOptions API. diff --git a/db_test.go b/db_test.go index 4ccc7aa8..d5c1600c 100755 --- a/db_test.go +++ b/db_test.go @@ -210,15 +210,18 @@ func TestDBGetApproximateSizes(t *testing.T) { defer db.Close() // no ranges - sizes := db.GetApproximateSizes(nil) + sizes, err := db.GetApproximateSizes(nil) + ensure.Nil(t, err) ensure.DeepEqual(t, len(sizes), 0) // range will nil start and limit - sizes = db.GetApproximateSizes([]Range{{Start: nil, Limit: nil}}) + sizes, err = db.GetApproximateSizes([]Range{{Start: nil, Limit: nil}}) + ensure.Nil(t, err) ensure.DeepEqual(t, sizes, []uint64{0}) // valid range - sizes = db.GetApproximateSizes([]Range{{Start: []byte{0x00}, Limit: []byte{0xFF}}}) + sizes, err = db.GetApproximateSizes([]Range{{Start: []byte{0x00}, Limit: []byte{0xFF}}}) + ensure.Nil(t, err) ensure.DeepEqual(t, sizes, []uint64{0}) } @@ -232,14 +235,17 @@ func TestDBGetApproximateSizesCF(t *testing.T) { ensure.Nil(t, err) // no ranges - sizes := db.GetApproximateSizesCF(cf, nil) + sizes, err := db.GetApproximateSizesCF(cf, nil) + ensure.Nil(t, err) ensure.DeepEqual(t, len(sizes), 0) // range will nil start and limit - sizes = db.GetApproximateSizesCF(cf, []Range{{Start: nil, Limit: nil}}) + sizes, err = db.GetApproximateSizesCF(cf, []Range{{Start: nil, Limit: nil}}) + ensure.Nil(t, err) ensure.DeepEqual(t, sizes, []uint64{0}) // valid range - sizes = db.GetApproximateSizesCF(cf, []Range{{Start: []byte{0x00}, Limit: []byte{0xFF}}}) + sizes, err = db.GetApproximateSizesCF(cf, []Range{{Start: []byte{0x00}, Limit: []byte{0xFF}}}) + ensure.Nil(t, err) ensure.DeepEqual(t, sizes, []uint64{0}) } From 295b6b017c159e297a46ecd2a60ae4cb60ae899e Mon Sep 17 00:00:00 2001 From: Flier Lu Date: Thu, 18 Mar 2021 16:27:07 +0800 Subject: [PATCH 3/7] add OptimisticTransactionDB --- db.go | 48 ++++++++++++-------- options_transaction.go | 28 ++++++++++++ transactiondb.go | 65 ++++++++++++++++++++++++++ transactiondb_test.go | 101 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 223 insertions(+), 19 deletions(-) diff --git a/db.go b/db.go index 5e52d656..d27eea3a 100755 --- a/db.go +++ b/db.go @@ -18,9 +18,14 @@ type Range struct { // DB is a reusable handle to a RocksDB database on disk, created by Open. type DB struct { - c *C.rocksdb_t - name string - opts *Options + c *C.rocksdb_t + closer func(*C.rocksdb_t) + name string + opts *Options +} + +func dbClose(c *C.rocksdb_t) { + C.rocksdb_close(c) } // OpenDb opens a database with the specified options. @@ -36,9 +41,10 @@ func OpenDb(opts *Options, name string) (*DB, error) { return nil, errors.New(C.GoString(cErr)) } return &DB{ - name: name, - c: db, - opts: opts, + c: db, + closer: dbClose, + name: name, + opts: opts, }, nil } @@ -55,9 +61,10 @@ func OpenDbWithTTL(opts *Options, name string, ttl int) (*DB, error) { return nil, errors.New(C.GoString(cErr)) } return &DB{ - name: name, - c: db, - opts: opts, + c: db, + closer: dbClose, + name: name, + opts: opts, }, nil } @@ -74,9 +81,10 @@ func OpenDbForReadOnly(opts *Options, name string, errorIfLogFileExist bool) (*D return nil, errors.New(C.GoString(cErr)) } return &DB{ - name: name, - c: db, - opts: opts, + c: db, + closer: dbClose, + name: name, + opts: opts, }, nil } @@ -133,9 +141,10 @@ func OpenDbColumnFamilies( } return &DB{ - name: name, - c: db, - opts: opts, + c: db, + closer: dbClose, + name: name, + opts: opts, }, cfHandles, nil } @@ -195,9 +204,10 @@ func OpenDbForReadOnlyColumnFamilies( } return &DB{ - name: name, - c: db, - opts: opts, + c: db, + closer: dbClose, + name: name, + opts: opts, }, cfHandles, nil } @@ -918,7 +928,7 @@ func (db *DB) NewCheckpoint() (*Checkpoint, error) { // Close closes the database. func (db *DB) Close() { - C.rocksdb_close(db.c) + db.closer(db.c) } // DestroyDb removes a database entirely, removing everything from the diff --git a/options_transaction.go b/options_transaction.go index cb72bff8..d051592e 100644 --- a/options_transaction.go +++ b/options_transaction.go @@ -64,3 +64,31 @@ func (opts *TransactionOptions) Destroy() { C.rocksdb_transaction_options_destroy(opts.c) opts.c = nil } + +// OptimisticTransactionOptions represent all of the available options for +// a optimistic transaction on the database. +type OptimisticTransactionOptions struct { + c *C.rocksdb_optimistictransaction_options_t +} + +// NewDefaultOptimisticTransactionOptions creates a default OptimisticTransactionOptions object. +func NewDefaultOptimisticTransactionOptions() *OptimisticTransactionOptions { + return NewNativeOptimisticTransactionOptions(C.rocksdb_optimistictransaction_options_create()) +} + +// NewNativeOptimisticTransactionOptions creates a OptimisticTransactionOptions object. +func NewNativeOptimisticTransactionOptions(c *C.rocksdb_optimistictransaction_options_t) *OptimisticTransactionOptions { + return &OptimisticTransactionOptions{c} +} + +// Destroy deallocates the OptimisticTransactionOptions object. +func (opts *OptimisticTransactionOptions) Destroy() { + C.rocksdb_optimistictransaction_options_destroy(opts.c) + opts.c = nil +} + +// SetSetSnapshot to true is the same as calling +// Transaction::SetSnapshot(). +func (opts *OptimisticTransactionOptions) SetSetSnapshot(value bool) { + C.rocksdb_optimistictransaction_options_set_set_snapshot(opts.c, boolToChar(value)) +} diff --git a/transactiondb.go b/transactiondb.go index cfdeac9c..8820708b 100644 --- a/transactiondb.go +++ b/transactiondb.go @@ -141,3 +141,68 @@ func (transactionDB *TransactionDB) Close() { C.rocksdb_transactiondb_close(transactionDB.c) transactionDB.c = nil } + +// OptimisticTransactionDB is a reusable handle to a RocksDB optimistic transactional database on disk, created by OpenOptimisticTransactionDb. +type OptimisticTransactionDB struct { + c *C.rocksdb_optimistictransactiondb_t + name string + opts *Options +} + +// OpenTransactionDb opens a database with the specified options. +func OpenOptimisticTransactionDb( + opts *Options, + name string, +) (*OptimisticTransactionDB, error) { + var ( + cErr *C.char + cName = C.CString(name) + ) + defer C.free(unsafe.Pointer(cName)) + db := C.rocksdb_optimistictransactiondb_open(opts.c, cName, &cErr) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + return nil, errors.New(C.GoString(cErr)) + } + return &OptimisticTransactionDB{ + name: name, + c: db, + opts: opts, + }, nil +} + +// GetBaseDB returns the base database. +func (db *OptimisticTransactionDB) GetBaseDB() *DB { + return &DB{ + c: C.rocksdb_optimistictransactiondb_get_base_db(db.c), + closer: func(c *C.rocksdb_t) { C.rocksdb_optimistictransactiondb_close_base_db(c) }, + name: db.name, + opts: db.opts, + } +} + +// TransactionBegin begins a new transaction +// with the WriteOptions and TransactionOptions given. +func (db *OptimisticTransactionDB) TransactionBegin( + opts *WriteOptions, + transactionOpts *OptimisticTransactionOptions, + oldTransaction *Transaction, +) *Transaction { + if oldTransaction != nil { + return NewNativeTransaction(C.rocksdb_optimistictransaction_begin( + db.c, + opts.c, + transactionOpts.c, + oldTransaction.c, + )) + } + + return NewNativeTransaction(C.rocksdb_optimistictransaction_begin( + db.c, opts.c, transactionOpts.c, nil)) +} + +// Close closes the database. +func (transactionDB *OptimisticTransactionDB) Close() { + C.rocksdb_optimistictransactiondb_close(transactionDB.c) + transactionDB.c = nil +} diff --git a/transactiondb_test.go b/transactiondb_test.go index 48fb382b..0a038629 100644 --- a/transactiondb_test.go +++ b/transactiondb_test.go @@ -137,3 +137,104 @@ func newTestTransactionDB(t *testing.T, name string, applyOpts func(opts *Option return db } + +func TestOpenOptimisticTransactionDb(t *testing.T) { + db := newTestOptimisticTransactionDB(t, "TestOpenOptimisticTransactionDb", nil) + defer db.Close() +} + +func TestOptimisticTransactionDBCRUD(t *testing.T) { + txdb := newTestOptimisticTransactionDB(t, "TestOptimisticTransactionDBGet", nil) + defer txdb.Close() + + db := txdb.GetBaseDB() + defer db.Close() + + var ( + givenKey = []byte("hello") + givenVal1 = []byte("world1") + givenVal2 = []byte("world2") + givenTxnKey = []byte("hello2") + givenTxnKey2 = []byte("hello3") + givenTxnVal1 = []byte("whatawonderful") + wo = NewDefaultWriteOptions() + ro = NewDefaultReadOptions() + to = NewDefaultOptimisticTransactionOptions() + ) + + // create + ensure.Nil(t, db.Put(wo, givenKey, givenVal1)) + + // retrieve + v1, err := db.Get(ro, givenKey) + defer v1.Free() + ensure.Nil(t, err) + ensure.DeepEqual(t, v1.Data(), givenVal1) + + // update + ensure.Nil(t, db.Put(wo, givenKey, givenVal2)) + v2, err := db.Get(ro, givenKey) + defer v2.Free() + ensure.Nil(t, err) + ensure.DeepEqual(t, v2.Data(), givenVal2) + + // delete + ensure.Nil(t, db.Delete(wo, givenKey)) + v3, err := db.Get(ro, givenKey) + defer v3.Free() + ensure.Nil(t, err) + ensure.True(t, v3.Data() == nil) + + // transaction + txn := txdb.TransactionBegin(wo, to, nil) + defer txn.Destroy() + // create + ensure.Nil(t, txn.Put(givenTxnKey, givenTxnVal1)) + v4, err := txn.Get(ro, givenTxnKey) + defer v4.Free() + ensure.Nil(t, err) + ensure.DeepEqual(t, v4.Data(), givenTxnVal1) + + ensure.Nil(t, txn.Commit()) + v5, err := db.Get(ro, givenTxnKey) + defer v5.Free() + ensure.Nil(t, err) + ensure.DeepEqual(t, v5.Data(), givenTxnVal1) + + // transaction + txn2 := txdb.TransactionBegin(wo, to, nil) + defer txn2.Destroy() + // create + ensure.Nil(t, txn2.Put(givenTxnKey2, givenTxnVal1)) + // rollback + ensure.Nil(t, txn2.Rollback()) + + v6, err := txn2.Get(ro, givenTxnKey2) + defer v6.Free() + ensure.Nil(t, err) + ensure.True(t, v6.Data() == nil) + // transaction + txn3 := txdb.TransactionBegin(wo, to, nil) + defer txn3.Destroy() + // delete + ensure.Nil(t, txn3.Delete(givenTxnKey)) + ensure.Nil(t, txn3.Commit()) + + v7, err := db.Get(ro, givenTxnKey) + defer v7.Free() + ensure.Nil(t, err) + ensure.True(t, v7.Data() == nil) + +} + +func newTestOptimisticTransactionDB(t *testing.T, name string, applyOpts func(opts *Options)) *OptimisticTransactionDB { + dir, err := ioutil.TempDir("", "gorockstransactiondb-"+name) + ensure.Nil(t, err) + + opts := NewDefaultOptions() + opts.SetCreateIfMissing(true) + db, err := OpenOptimisticTransactionDb(opts, dir) + ensure.Nil(t, err) + + return db +} From 1eb5b472f5c0875d14634b6c89fae9da184300b7 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 14 Jul 2021 18:58:33 +0800 Subject: [PATCH 4/7] Add OptimisticTransactionDB::NewCheckpoint --- transactiondb.go | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/transactiondb.go b/transactiondb.go index 8820708b..6bf111f5 100644 --- a/transactiondb.go +++ b/transactiondb.go @@ -206,3 +206,19 @@ func (transactionDB *OptimisticTransactionDB) Close() { C.rocksdb_optimistictransactiondb_close(transactionDB.c) transactionDB.c = nil } + +// NewCheckpoint creates a new Checkpoint for this db. +func (db *OptimisticTransactionDB) NewCheckpoint() (*Checkpoint, error) { + var ( + cErr *C.char + ) + cCheckpoint := C.rocksdb_optimistictransactiondb_checkpoint_object_create( + db.c, &cErr, + ) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + return nil, errors.New(C.GoString(cErr)) + } + + return NewNativeCheckpoint(cCheckpoint), nil +} From 0449c4f4b038856b924e75d230edf5a6007234e7 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 14 Jul 2021 19:01:01 +0800 Subject: [PATCH 5/7] Add {Optimistic}TransactionDB::Write() --- transactiondb.go | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/transactiondb.go b/transactiondb.go index 6bf111f5..b8bd9ba8 100644 --- a/transactiondb.go +++ b/transactiondb.go @@ -106,6 +106,17 @@ func (db *TransactionDB) Put(opts *WriteOptions, key, value []byte) error { return nil } +// Write writes a WriteBatch to the database +func (db *TransactionDB) Write(opts *WriteOptions, batch *WriteBatch) error { + var cErr *C.char + C.rocksdb_transactiondb_write(db.c, opts.c, batch.c, &cErr) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + return errors.New(C.GoString(cErr)) + } + return nil +} + // Delete removes the data associated with the key from the database. func (db *TransactionDB) Delete(opts *WriteOptions, key []byte) error { var ( @@ -201,6 +212,17 @@ func (db *OptimisticTransactionDB) TransactionBegin( db.c, opts.c, transactionOpts.c, nil)) } +// Write writes a WriteBatch to the database +func (db *OptimisticTransactionDB) Write(opts *WriteOptions, batch *WriteBatch) error { + var cErr *C.char + C.rocksdb_optimistictransactiondb_write(db.c, opts.c, batch.c, &cErr) + if cErr != nil { + defer C.rocksdb_free(unsafe.Pointer(cErr)) + return errors.New(C.GoString(cErr)) + } + return nil +} + // Close closes the database. func (transactionDB *OptimisticTransactionDB) Close() { C.rocksdb_optimistictransactiondb_close(transactionDB.c) From 300fe467ef4a83c3f53c16e8b3ef63d958352a88 Mon Sep 17 00:00:00 2001 From: houfazhou Date: Wed, 14 Apr 2021 19:20:40 +0800 Subject: [PATCH 6/7] add SetIterateLowerBound and testcase --- iterator_test.go | 33 +++++++++++++++++++++++++++++++++ options_read.go | 18 ++++++++++++++++-- 2 files changed, 49 insertions(+), 2 deletions(-) diff --git a/iterator_test.go b/iterator_test.go index 358400ba..2195beb6 100644 --- a/iterator_test.go +++ b/iterator_test.go @@ -29,3 +29,36 @@ func TestIterator(t *testing.T) { ensure.Nil(t, iter.Err()) ensure.DeepEqual(t, actualKeys, givenKeys) } + +func TestIteratorWithRange(t *testing.T) { + db := newTestDB(t, "TestIterator", nil) + defer db.Close() + + // insert keys + givenKeys := [][]byte{ + []byte("key1"), + []byte("key2"), + []byte("key3"), + []byte("key4"), + []byte("key5"), + } + wo := NewDefaultWriteOptions() + for _, k := range givenKeys { + ensure.Nil(t, db.Put(wo, k, []byte("val"))) + } + + ro := NewDefaultReadOptions() + ro.SetIterateLowerBound([]byte("key2")) + ro.SetIterateUpperBound([]byte("key4")) + + iter := db.NewIterator(ro) + defer iter.Close() + var actualKeys [][]byte + for iter.SeekToFirst(); iter.Valid(); iter.Next() { + key := make([]byte, 4) + copy(key, iter.Key().Data()) + actualKeys = append(actualKeys, key) + } + ensure.Nil(t, iter.Err()) + ensure.DeepEqual(t, len(actualKeys), 2) +} \ No newline at end of file diff --git a/options_read.go b/options_read.go index 6a37cc48..6d38cdda 100644 --- a/options_read.go +++ b/options_read.go @@ -100,8 +100,6 @@ func (opts *ReadOptions) SetTailing(value bool) { // not a valid entry. If iterator_extractor is not null, the Seek target // and iterator_upper_bound need to have the same prefix. // This is because ordering is not guaranteed outside of prefix domain. -// There is no lower bound on the iterator. If needed, that can be easily -// implemented. // Default: nullptr func (opts *ReadOptions) SetIterateUpperBound(key []byte) { cKey := byteToChar(key) @@ -109,6 +107,22 @@ func (opts *ReadOptions) SetIterateUpperBound(key []byte) { C.rocksdb_readoptions_set_iterate_upper_bound(opts.c, cKey, cKeyLen) } +// SetIterateLowerBound specifies "iterate_lower_bound", which defines +// the smallest key at which the backward iterator can return an entry. +// Once the bound is passed, Valid() will be false. +// `iterate_lower_bound` is inclusive ie the bound value is a valid +// entry. +// +// If prefix_extractor is not null, the Seek target and `iterate_lower_bound` +// need to have the same prefix. This is because ordering is not guaranteed +// outside of prefix domain. +// Default: nullptr +func (opts *ReadOptions) SetIterateLowerBound(key []byte) { + cKey := byteToChar(key) + cKeyLen := C.size_t(len(key)) + C.rocksdb_readoptions_set_iterate_lower_bound(opts.c, cKey, cKeyLen) +} + // SetPinData specifies the value of "pin_data". If true, it keeps the blocks // loaded by the iterator pinned in memory as long as the iterator is not deleted, // If used when reading from tables created with From c0bf0b3635e5a356bd35c302073827c700a11751 Mon Sep 17 00:00:00 2001 From: Roy Crihfield Date: Wed, 4 Aug 2021 21:37:37 +0800 Subject: [PATCH 7/7] add (Optimistic)TransactionDB::GetProperty --- transactiondb.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/transactiondb.go b/transactiondb.go index b8bd9ba8..80e14099 100644 --- a/transactiondb.go +++ b/transactiondb.go @@ -52,6 +52,15 @@ func (db *TransactionDB) ReleaseSnapshot(snapshot *Snapshot) { snapshot.c = nil } +// GetProperty returns the value of a database property. +func (db *TransactionDB) GetProperty(propName string) string { + cprop := C.CString(propName) + defer C.free(unsafe.Pointer(cprop)) + cValue := C.rocksdb_transactiondb_property_value(db.c, cprop) + defer C.rocksdb_free(unsafe.Pointer(cValue)) + return C.GoString(cValue) +} + // TransactionBegin begins a new transaction // with the WriteOptions and TransactionOptions given. func (db *TransactionDB) TransactionBegin( @@ -192,6 +201,15 @@ func (db *OptimisticTransactionDB) GetBaseDB() *DB { } } +// GetProperty returns the value of a database property. +func (db *OptimisticTransactionDB) GetProperty(propName string) string { + cprop := C.CString(propName) + defer C.free(unsafe.Pointer(cprop)) + cValue := C.rocksdb_optimistictransactiondb_property_value(db.c, cprop) + defer C.rocksdb_free(unsafe.Pointer(cValue)) + return C.GoString(cValue) +} + // TransactionBegin begins a new transaction // with the WriteOptions and TransactionOptions given. func (db *OptimisticTransactionDB) TransactionBegin(