Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

add OptimisticTransactionDB #205

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
add OptimisticTransactionDB
  • Loading branch information
flier committed Mar 18, 2021
commit 9c0f4ca12817f5c3532a8d51d1c2c095eb091517
48 changes: 29 additions & 19 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand All @@ -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
}

Expand All @@ -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
}

Expand All @@ -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
}

Expand Down Expand Up @@ -133,9 +141,10 @@ func OpenDbColumnFamilies(
}

return &DB{
name: name,
c: db,
opts: opts,
c: db,
closer: dbClose,
name: name,
opts: opts,
}, cfHandles, nil
}

Expand Down Expand Up @@ -195,9 +204,10 @@ func OpenDbForReadOnlyColumnFamilies(
}

return &DB{
name: name,
c: db,
opts: opts,
c: db,
closer: dbClose,
name: name,
opts: opts,
}, cfHandles, nil
}

Expand Down Expand Up @@ -904,7 +914,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
Expand Down
28 changes: 28 additions & 0 deletions options_transaction.go
Original file line number Diff line number Diff line change
Expand Up @@ -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))
}
65 changes: 65 additions & 0 deletions transactiondb.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
101 changes: 101 additions & 0 deletions transactiondb_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
}