diff --git a/db/c.cc b/db/c.cc index d9e75e04f..3b52d2d70 100644 --- a/db/c.cc +++ b/db/c.cc @@ -36,6 +36,9 @@ #include "rocksdb/utilities/backupable_db.h" #include "rocksdb/utilities/write_batch_with_index.h" #include "utilities/merge_operators.h" +#include "rocksdb/utilities/transaction.h" +#include "rocksdb/utilities/transaction_db.h" +#include "rocksdb/utilities/checkpoint.h" using rocksdb::BytewiseComparator; using rocksdb::Cache; @@ -90,6 +93,11 @@ using rocksdb::CompactRangeOptions; using rocksdb::RateLimiter; using rocksdb::NewGenericRateLimiter; using rocksdb::PinnableSlice; +using rocksdb::TransactionDBOptions; +using rocksdb::TransactionDB; +using rocksdb::TransactionOptions; +using rocksdb::Transaction; +using rocksdb::Checkpoint; using std::shared_ptr; @@ -131,6 +139,21 @@ struct rocksdb_ratelimiter_t { RateLimiter* rep; }; struct rocksdb_pinnableslice_t { PinnableSlice rep; }; +struct rocksdb_transactiondb_options_t { + TransactionDBOptions rep; +}; +struct rocksdb_transactiondb_t { + TransactionDB* rep; +}; +struct rocksdb_transaction_options_t { + TransactionOptions rep; +}; +struct rocksdb_transaction_t { + Transaction* rep; +}; +struct rocksdb_checkpoint_t { + Checkpoint* rep; +}; struct rocksdb_compactionfiltercontext_t { CompactionFilter::Context rep; @@ -543,6 +566,29 @@ void rocksdb_backup_engine_close(rocksdb_backup_engine_t* be) { delete be; } +rocksdb_checkpoint_t* rocksdb_checkpoint_object_create(rocksdb_t* db, + char** errptr) { + Checkpoint* checkpoint; + if (SaveError(errptr, Checkpoint::Create(db->rep, &checkpoint))) { + return nullptr; + } + rocksdb_checkpoint_t* result = new rocksdb_checkpoint_t; + result->rep = checkpoint; + return result; +} + +void rocksdb_checkpoint_create(rocksdb_checkpoint_t* checkpoint, + const char* checkpoint_dir, + uint64_t log_size_for_flush, char** errptr) { + SaveError(errptr, checkpoint->rep->CreateCheckpoint( + std::string(checkpoint_dir), log_size_for_flush)); +} + +void rocksdb_checkpoint_object_destroy(rocksdb_checkpoint_t* checkpoint) { + delete checkpoint->rep; + delete checkpoint; +} + void rocksdb_close(rocksdb_t* db) { delete db->rep; delete db; @@ -3094,6 +3140,223 @@ void rocksdb_delete_file_in_range_cf( (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr))); } +rocksdb_transactiondb_options_t* rocksdb_transactiondb_options_create() { + return new rocksdb_transactiondb_options_t; +} + +void rocksdb_transactiondb_options_destroy(rocksdb_transactiondb_options_t* opt){ + delete opt; +} + +void rocksdb_transactiondb_options_set_max_num_locks( + rocksdb_transactiondb_options_t* opt, int64_t max_num_locks) { + opt->rep.max_num_locks = max_num_locks; +} + +void rocksdb_transactiondb_options_set_num_stripes( + rocksdb_transactiondb_options_t* opt, size_t num_stripes) { + opt->rep.num_stripes = num_stripes; +} + +void rocksdb_transactiondb_options_set_transaction_lock_timeout( + rocksdb_transactiondb_options_t* opt, int64_t txn_lock_timeout) { + opt->rep.transaction_lock_timeout = txn_lock_timeout; +} + +void rocksdb_transactiondb_options_set_default_lock_timeout( + rocksdb_transactiondb_options_t* opt, int64_t default_lock_timeout) { + opt->rep.default_lock_timeout = default_lock_timeout; +} + +rocksdb_transaction_options_t* rocksdb_transaction_options_create() { + return new rocksdb_transaction_options_t; +} + +void rocksdb_transaction_options_destroy(rocksdb_transaction_options_t* opt) { + delete opt; +} + +void rocksdb_transaction_options_set_set_snapshot( + rocksdb_transaction_options_t* opt, unsigned char v) { + opt->rep.set_snapshot = v; +} + +void rocksdb_transaction_options_set_deadlock_detect( + rocksdb_transaction_options_t* opt, unsigned char v) { + opt->rep.deadlock_detect = v; +} + +void rocksdb_transaction_options_set_lock_timeout( + rocksdb_transaction_options_t* opt, int64_t lock_timeout) { + opt->rep.lock_timeout = lock_timeout; +} + +void rocksdb_transaction_options_set_expiration( + rocksdb_transaction_options_t* opt, int64_t expiration) { + opt->rep.expiration = expiration; +} + +void rocksdb_transaction_options_set_deadlock_detect_depth( + rocksdb_transaction_options_t* opt, int64_t depth) { + opt->rep.deadlock_detect_depth = depth; +} + +void rocksdb_transaction_options_set_max_write_batch_size( + rocksdb_transaction_options_t* opt, size_t size) { + opt->rep.max_write_batch_size = size; +} + +rocksdb_transactiondb_t* rocksdb_transactiondb_open( + const rocksdb_options_t* options, + const rocksdb_transactiondb_options_t* txn_db_options, const char* name, + char** errptr) { + TransactionDB* txn_db; + if (SaveError(errptr, TransactionDB::Open(options->rep, txn_db_options->rep, + std::string(name), &txn_db))) { + return nullptr; + } + rocksdb_transactiondb_t* result = new rocksdb_transactiondb_t; + result->rep = txn_db; + return result; +} + +const rocksdb_snapshot_t* rocksdb_transactiondb_create_snapshot( + rocksdb_transactiondb_t* txn_db) { + rocksdb_snapshot_t* result = new rocksdb_snapshot_t; + result->rep = txn_db->rep->GetSnapshot(); + return result; +} + +void rocksdb_transactiondb_release_snapshot( + rocksdb_transactiondb_t* txn_db, const rocksdb_snapshot_t* snapshot) { + txn_db->rep->ReleaseSnapshot(snapshot->rep); + delete snapshot; +} + +rocksdb_transaction_t* rocksdb_transaction_begin( + rocksdb_transactiondb_t* txn_db, + const rocksdb_writeoptions_t* write_options, + const rocksdb_transaction_options_t* txn_options, + rocksdb_transaction_t* old_txn) { + if (old_txn == nullptr) { + rocksdb_transaction_t* result = new rocksdb_transaction_t; + result->rep = txn_db->rep->BeginTransaction(write_options->rep, + txn_options->rep, nullptr); + return result; + } + old_txn->rep = txn_db->rep->BeginTransaction(write_options->rep, + txn_options->rep, old_txn->rep); + return old_txn; +} + +void rocksdb_transaction_commit(rocksdb_transaction_t* txn, char** errptr) { + SaveError(errptr, txn->rep->Commit()); +} + +void rocksdb_transaction_rollback(rocksdb_transaction_t* txn, char** errptr) { + SaveError(errptr, txn->rep->Rollback()); +} + +void rocksdb_transaction_destroy(rocksdb_transaction_t* txn) { + delete txn->rep; + delete txn; +} + +//Read a key inside a transaction +char* rocksdb_transaction_get(rocksdb_transaction_t* txn, + const rocksdb_readoptions_t* options, + const char* key, size_t klen, size_t* vlen, + char** errptr) { + char* result = nullptr; + std::string tmp; + Status s = txn->rep->Get(options->rep, Slice(key, klen), &tmp); + if (s.ok()) { + *vlen = tmp.size(); + result = CopyString(tmp); + } else { + *vlen = 0; + if (!s.IsNotFound()) { + SaveError(errptr, s); + } + } + return result; +} + +// Read a key outside a transaction +char* rocksdb_transactiondb_get( + rocksdb_transactiondb_t* txn_db, + const rocksdb_readoptions_t* options, + const char* key, size_t klen, + size_t* vlen, + char** errptr){ + char* result = nullptr; + std::string tmp; + Status s = txn_db->rep->Get(options->rep, Slice(key, klen), &tmp); + if (s.ok()) { + *vlen = tmp.size(); + result = CopyString(tmp); + } else { + *vlen = 0; + if (!s.IsNotFound()) { + SaveError(errptr, s); + } + } + return result; +} + +// Put a key inside a transaction +void rocksdb_transaction_put(rocksdb_transaction_t* txn, const char* key, + size_t klen, const char* val, size_t vlen, + char** errptr) { + SaveError(errptr, txn->rep->Put(Slice(key, klen), Slice(val, vlen))); +} + +//Put a key outside a transaction +void rocksdb_transactiondb_put(rocksdb_transactiondb_t* txn_db, + const rocksdb_writeoptions_t* options, + const char* key, size_t klen, const char* val, + size_t vlen, char** errptr) { + SaveError(errptr, + txn_db->rep->Put(options->rep, Slice(key, klen), Slice(val, vlen))); +} + +// Delete a key inside a transaction +void rocksdb_transaction_delete(rocksdb_transaction_t* txn, const char* key, + size_t klen, char** errptr) { + SaveError(errptr, txn->rep->Delete(Slice(key, klen))); +} + +// Delete a key outside a transaction +void rocksdb_transactiondb_delete(rocksdb_transactiondb_t* txn_db, + const rocksdb_writeoptions_t* options, + const char* key, size_t klen, char** errptr) { + SaveError(errptr, txn_db->rep->Delete(options->rep, Slice(key, klen))); +} + +// Create an iterator inside a transaction +rocksdb_iterator_t* rocksdb_transaction_create_iterator( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options) { + rocksdb_iterator_t* result = new rocksdb_iterator_t; + result->rep = txn->rep->GetIterator(options->rep); + return result; +} + +void rocksdb_transactiondb_close(rocksdb_transactiondb_t* txn_db) { + delete txn_db->rep; + delete txn_db; +} + +rocksdb_checkpoint_t* rocksdb_transactiondb_checkpoint_object_create( + rocksdb_transactiondb_t* txn_db, char** errptr) { + Checkpoint* checkpoint; + if (SaveError(errptr, Checkpoint::Create(txn_db->rep, &checkpoint))) { + return nullptr; + } + rocksdb_checkpoint_t* result = new rocksdb_checkpoint_t; + result->rep = checkpoint; + return result; +} + void rocksdb_free(void* ptr) { free(ptr); } rocksdb_pinnableslice_t* rocksdb_get_pinned( diff --git a/db/c_test.c b/db/c_test.c index 9a45922c2..e8b44a726 100644 --- a/db/c_test.c +++ b/db/c_test.c @@ -40,6 +40,7 @@ const char* phase = ""; static char dbname[200]; static char sstfilename[200]; static char dbbackupname[200]; +static char dbcheckpointname[200]; static void StartPhase(const char* name) { fprintf(stderr, "=== Test %s\n", name); @@ -318,6 +319,34 @@ static char* MergeOperatorPartialMerge( return result; } +static void CheckTxnGet( + rocksdb_transaction_t* txn, + const rocksdb_readoptions_t* options, + const char* key, + const char* expected) { + char* err = NULL; + size_t val_len; + char* val; + val = rocksdb_transaction_get(txn, options, key, strlen(key), &val_len, &err); + CheckNoError(err); + CheckEqual(expected, val, val_len); + Free(&val); +} + +static void CheckTxnDBGet( + rocksdb_transactiondb_t* txn_db, + const rocksdb_readoptions_t* options, + const char* key, + const char* expected) { + char* err = NULL; + size_t val_len; + char* val; + val = rocksdb_transactiondb_get(txn_db, options, key, strlen(key), &val_len, &err); + CheckNoError(err); + CheckEqual(expected, val, val_len); + Free(&val); +} + int main(int argc, char** argv) { rocksdb_t* db; rocksdb_comparator_t* cmp; @@ -329,6 +358,10 @@ int main(int argc, char** argv) { rocksdb_readoptions_t* roptions; rocksdb_writeoptions_t* woptions; rocksdb_ratelimiter_t* rate_limiter; + rocksdb_transactiondb_t* txn_db; + rocksdb_transactiondb_options_t* txn_db_options; + rocksdb_transaction_t* txn; + rocksdb_transaction_options_t* txn_options; char* err = NULL; int run = -1; @@ -342,6 +375,11 @@ int main(int argc, char** argv) { GetTempDir(), ((int) geteuid())); + snprintf(dbcheckpointname, sizeof(dbcheckpointname), + "%s/rocksdb_c_test-%d-checkpoint", + GetTempDir(), + ((int) geteuid())); + snprintf(sstfilename, sizeof(sstfilename), "%s/rocksdb_c_test-%d-sst", GetTempDir(), @@ -457,6 +495,36 @@ int main(int argc, char** argv) { rocksdb_backup_engine_close(be); } + StartPhase("checkpoint"); + { + rocksdb_destroy_db(options, dbcheckpointname, &err); + CheckNoError(err); + + rocksdb_checkpoint_t* checkpoint = rocksdb_checkpoint_object_create(db, &err); + CheckNoError(err); + + rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err); + CheckNoError(err); + + // start a new database from the checkpoint + rocksdb_close(db); + rocksdb_options_set_error_if_exists(options, 0); + db = rocksdb_open(options, dbcheckpointname, &err); + CheckNoError(err); + + CheckGet(db, roptions, "foo", "hello"); + + rocksdb_checkpoint_object_destroy(checkpoint); + + rocksdb_close(db); + rocksdb_destroy_db(options, dbcheckpointname, &err); + CheckNoError(err); + + db = rocksdb_open(options, dbname, &err); + CheckNoError(err); + rocksdb_options_set_error_if_exists(options, 1); + } + StartPhase("compactall"); rocksdb_compact_range(db, NULL, 0, NULL, 0); CheckGet(db, roptions, "foo", "hello"); @@ -1266,14 +1334,98 @@ int main(int argc, char** argv) { } } - // Simple sanity check that setting memtable rep works. - StartPhase("memtable_reps"); + StartPhase("transactions"); { - // Create database with vector memtable. rocksdb_close(db); rocksdb_destroy_db(options, dbname, &err); CheckNoError(err); + // open a TransactionDB + txn_db_options = rocksdb_transactiondb_options_create(); + txn_options = rocksdb_transaction_options_create(); + rocksdb_options_set_create_if_missing(options, 1); + txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err); + CheckNoError(err); + + // put outside a transaction + rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hello", 5, &err); + CheckNoError(err); + CheckTxnDBGet(txn_db, roptions, "foo", "hello"); + + // delete from outside transaction + rocksdb_transactiondb_delete(txn_db, woptions, "foo", 3, &err); + CheckNoError(err); + CheckTxnDBGet(txn_db, roptions, "foo", NULL); + + // begin a transaction + txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL); + // put + rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err); + CheckNoError(err); + CheckTxnGet(txn, roptions, "foo", "hello"); + // delete + rocksdb_transaction_delete(txn, "foo", 3, &err); + CheckNoError(err); + CheckTxnGet(txn, roptions, "foo", NULL); + + rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err); + CheckNoError(err); + + // read from outside transaction, before commit + CheckTxnDBGet(txn_db, roptions, "foo", NULL); + + // commit + rocksdb_transaction_commit(txn, &err); + CheckNoError(err); + + // read from outside transaction, after commit + CheckTxnDBGet(txn_db, roptions, "foo", "hello"); + + // reuse old transaction + txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, txn); + + // snapshot + const rocksdb_snapshot_t* snapshot; + snapshot = rocksdb_transactiondb_create_snapshot(txn_db); + rocksdb_readoptions_set_snapshot(roptions, snapshot); + + rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err); + CheckNoError(err); + + CheckTxnDBGet(txn_db, roptions, "foo", "hello"); + rocksdb_readoptions_set_snapshot(roptions, NULL); + rocksdb_transactiondb_release_snapshot(txn_db, snapshot); + CheckTxnDBGet(txn_db, roptions, "foo", "hey"); + + // iterate + rocksdb_transaction_put(txn, "bar", 3, "hi", 2, &err); + rocksdb_iterator_t* iter = rocksdb_transaction_create_iterator(txn, roptions); + CheckCondition(!rocksdb_iter_valid(iter)); + rocksdb_iter_seek_to_first(iter); + CheckCondition(rocksdb_iter_valid(iter)); + CheckIter(iter, "bar", "hi"); + rocksdb_iter_get_error(iter, &err); + CheckNoError(err); + rocksdb_iter_destroy(iter); + + // rollback + rocksdb_transaction_rollback(txn, &err); + CheckNoError(err); + CheckTxnDBGet(txn_db, roptions, "bar", NULL); + + // close and destroy + rocksdb_transaction_destroy(txn); + rocksdb_transactiondb_close(txn_db); + rocksdb_destroy_db(options, dbname, &err); + CheckNoError(err); + rocksdb_transaction_options_destroy(txn_options); + rocksdb_transactiondb_options_destroy(txn_db_options); + } + + // Simple sanity check that setting memtable rep works. + StartPhase("memtable_reps"); + { + // Create database with vector memtable. rocksdb_options_set_memtable_vector_rep(options); db = rocksdb_open(options, dbname, &err); CheckNoError(err); diff --git a/include/rocksdb/c.h b/include/rocksdb/c.h index 975f62c94..7981ff339 100644 --- a/include/rocksdb/c.h +++ b/include/rocksdb/c.h @@ -112,6 +112,11 @@ typedef struct rocksdb_ingestexternalfileoptions_t rocksdb_ingestexternalfileopt typedef struct rocksdb_sstfilewriter_t rocksdb_sstfilewriter_t; typedef struct rocksdb_ratelimiter_t rocksdb_ratelimiter_t; typedef struct rocksdb_pinnableslice_t rocksdb_pinnableslice_t; +typedef struct rocksdb_transactiondb_options_t rocksdb_transactiondb_options_t; +typedef struct rocksdb_transactiondb_t rocksdb_transactiondb_t; +typedef struct rocksdb_transaction_options_t rocksdb_transaction_options_t; +typedef struct rocksdb_transaction_t rocksdb_transaction_t; +typedef struct rocksdb_checkpoint_t rocksdb_checkpoint_t; /* DB operations */ @@ -170,6 +175,16 @@ extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_info_destroy( extern ROCKSDB_LIBRARY_API void rocksdb_backup_engine_close( rocksdb_backup_engine_t* be); +extern ROCKSDB_LIBRARY_API rocksdb_checkpoint_t* +rocksdb_checkpoint_object_create(rocksdb_t* db, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_checkpoint_create( + rocksdb_checkpoint_t* checkpoint, const char* checkpoint_dir, + uint64_t log_size_for_flush, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_checkpoint_object_destroy( + rocksdb_checkpoint_t* checkpoint); + extern ROCKSDB_LIBRARY_API rocksdb_t* rocksdb_open_column_families( const rocksdb_options_t* options, const char* name, int num_column_families, const char** column_family_names, @@ -1219,6 +1234,116 @@ extern ROCKSDB_LIBRARY_API void rocksdb_delete_file_in_range_cf( const char* start_key, size_t start_key_len, const char* limit_key, size_t limit_key_len, char** errptr); +/* Transactions */ + +extern ROCKSDB_LIBRARY_API rocksdb_transactiondb_t* rocksdb_transactiondb_open( + const rocksdb_options_t* options, + const rocksdb_transactiondb_options_t* txn_db_options, const char* name, + char** errptr); + +extern ROCKSDB_LIBRARY_API const rocksdb_snapshot_t* +rocksdb_transactiondb_create_snapshot(rocksdb_transactiondb_t* txn_db); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_release_snapshot( + rocksdb_transactiondb_t* txn_db, const rocksdb_snapshot_t* snapshot); + +extern ROCKSDB_LIBRARY_API rocksdb_transaction_t* rocksdb_transaction_begin( + rocksdb_transactiondb_t* txn_db, + const rocksdb_writeoptions_t* write_options, + const rocksdb_transaction_options_t* txn_options, + rocksdb_transaction_t* old_txn); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_commit( + rocksdb_transaction_t* txn, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_rollback( + rocksdb_transaction_t* txn, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_destroy( + rocksdb_transaction_t* txn); + +extern ROCKSDB_LIBRARY_API char* rocksdb_transaction_get( + rocksdb_transaction_t* txn, const rocksdb_readoptions_t* options, + const char* key, size_t klen, size_t* vlen, char** errptr); + +extern ROCKSDB_LIBRARY_API char* rocksdb_transactiondb_get( + rocksdb_transactiondb_t* txn_db, const rocksdb_readoptions_t* options, + const char* key, size_t klen, size_t* vlen, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_put( + rocksdb_transaction_t* txn, const char* key, size_t klen, const char* val, + size_t vlen, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_put( + rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options, + const char* key, size_t klen, const char* val, size_t vlen, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_delete( + rocksdb_transaction_t* txn, const char* key, size_t klen, char** errptr); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_delete( + rocksdb_transactiondb_t* txn_db, const rocksdb_writeoptions_t* options, + const char* key, size_t klen, char** errptr); + +extern ROCKSDB_LIBRARY_API rocksdb_iterator_t* +rocksdb_transaction_create_iterator(rocksdb_transaction_t* txn, + const rocksdb_readoptions_t* options); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_close( + rocksdb_transactiondb_t* txn_db); + +extern ROCKSDB_LIBRARY_API rocksdb_checkpoint_t* +rocksdb_transactiondb_checkpoint_object_create(rocksdb_transactiondb_t* txn_db, + char** errptr); + +/* Transaction Options */ + +extern ROCKSDB_LIBRARY_API rocksdb_transactiondb_options_t* +rocksdb_transactiondb_options_create(); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_options_destroy( + rocksdb_transactiondb_options_t* opt); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_options_set_max_num_locks( + rocksdb_transactiondb_options_t* opt, int64_t max_num_locks); + +extern ROCKSDB_LIBRARY_API void rocksdb_transactiondb_options_set_num_stripes( + rocksdb_transactiondb_options_t* opt, size_t num_stripes); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transactiondb_options_set_transaction_lock_timeout( + rocksdb_transactiondb_options_t* opt, int64_t txn_lock_timeout); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transactiondb_options_set_default_lock_timeout( + rocksdb_transactiondb_options_t* opt, int64_t default_lock_timeout); + +extern ROCKSDB_LIBRARY_API rocksdb_transaction_options_t* +rocksdb_transaction_options_create(); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_options_destroy( + rocksdb_transaction_options_t* opt); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_options_set_set_snapshot( + rocksdb_transaction_options_t* opt, unsigned char v); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_options_set_deadlock_detect( + rocksdb_transaction_options_t* opt, unsigned char v); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_options_set_lock_timeout( + rocksdb_transaction_options_t* opt, int64_t lock_timeout); + +extern ROCKSDB_LIBRARY_API void rocksdb_transaction_options_set_expiration( + rocksdb_transaction_options_t* opt, int64_t expiration); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transaction_options_set_deadlock_detect_depth( + rocksdb_transaction_options_t* opt, int64_t depth); + +extern ROCKSDB_LIBRARY_API void +rocksdb_transaction_options_set_max_write_batch_size( + rocksdb_transaction_options_t* opt, size_t size); + // referring to convention (3), this should be used by client // to free memory that was malloc()ed extern ROCKSDB_LIBRARY_API void rocksdb_free(void* ptr);