#ifndef ROCKSDB_LITE // Lite does not support C API
-#include "rocksdb/c.h"
-
+#include <assert.h>
#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <sys/types.h>
+
+#include "rocksdb/c.h"
#ifndef OS_WIN
#include <unistd.h>
#endif
return result;
}
-// VS < 2015
-#if defined(_MSC_VER) && (_MSC_VER < 1900)
-#define snprintf _snprintf
-#endif
-
#endif
const char* phase = "";
}
#ifdef _MSC_VER
#pragma warning(push)
-#pragma warning (disable: 4996) // getenv security warning
+#pragma warning(disable : 4996) // getenv security warning
#endif
static const char* GetTempDir(void) {
- const char* ret = getenv("TEST_TMPDIR");
- if (ret == NULL || ret[0] == '\0')
+ const char* ret = getenv("TEST_TMPDIR");
+ if (ret == NULL || ret[0] == '\0')
#ifdef OS_WIN
- ret = getenv("TEMP");
+ ret = getenv("TEMP");
#else
- ret = "/tmp";
+ ret = "/tmp";
#endif
- return ret;
+ return ret;
}
#ifdef _MSC_VER
#pragma warning(pop)
#endif
-#define CheckNoError(err) \
- if ((err) != NULL) { \
+#define CheckNoError(err) \
+ if ((err) != NULL) { \
fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
- abort(); \
+ abort(); \
}
-#define CheckCondition(cond) \
- if (!(cond)) { \
+#define CheckCondition(cond) \
+ if (!(cond)) { \
fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \
- abort(); \
+ abort(); \
}
static void CheckEqual(const char* expected, const char* v, size_t n) {
// ok
return;
} else {
- fprintf(stderr, "%s: expected '%s', got '%s'\n",
- phase,
- (expected ? expected : "(null)"),
- (v ? v : "(null"));
+ fprintf(stderr, "%s: expected '%s', got '%s'\n", phase,
+ (expected ? expected : "(null)"), (v ? v : "(null)"));
abort();
}
}
}
}
-static void CheckValue(
- char* err,
- const char* expected,
- char** actual,
- size_t actual_length) {
+static void CheckValue(char* err, const char* expected, char** actual,
+ size_t actual_length) {
CheckNoError(err);
CheckEqual(expected, *actual, actual_length);
Free(actual);
}
-static void CheckGet(
- rocksdb_t* db,
- const rocksdb_readoptions_t* options,
- const char* key,
- const char* expected) {
+static void CheckGet(rocksdb_t* db, const rocksdb_readoptions_t* options,
+ const char* key, const char* expected) {
char* err = NULL;
size_t val_len;
char* val;
Free(&val);
}
-static void CheckGetCF(
- rocksdb_t* db,
- const rocksdb_readoptions_t* options,
- rocksdb_column_family_handle_t* handle,
- const char* key,
- const char* expected) {
+static void CheckGetCF(rocksdb_t* db, const rocksdb_readoptions_t* options,
+ rocksdb_column_family_handle_t* handle, const char* key,
+ const char* expected) {
char* err = NULL;
size_t val_len;
char* val;
rocksdb_pinnableslice_destroy(p);
}
-static void CheckIter(rocksdb_iterator_t* iter,
- const char* key, const char* val) {
+static void CheckMultiGetValues(size_t num_keys, char** values,
+ size_t* values_sizes, char** errs,
+ const char** expected) {
+ for (size_t i = 0; i < num_keys; i++) {
+ CheckNoError(errs[i]);
+ CheckEqual(expected[i], values[i], values_sizes[i]);
+ Free(&values[i]);
+ }
+}
+
+static void CheckIter(rocksdb_iterator_t* iter, const char* key,
+ const char* val) {
size_t len;
const char* str;
str = rocksdb_iter_key(iter, &len);
}
// Callback from rocksdb_writebatch_iterate()
-static void CheckPut(void* ptr,
- const char* k, size_t klen,
- const char* v, size_t vlen) {
- int* state = (int*) ptr;
+static void CheckPut(void* ptr, const char* k, size_t klen, const char* v,
+ size_t vlen) {
+ int* state = (int*)ptr;
CheckCondition(*state < 2);
switch (*state) {
case 0:
// Callback from rocksdb_writebatch_iterate()
static void CheckDel(void* ptr, const char* k, size_t klen) {
- int* state = (int*) ptr;
+ int* state = (int*)ptr;
CheckCondition(*state == 2);
CheckEqual("bar", k, klen);
(*state)++;
static void CmpDestroy(void* arg) { (void)arg; }
-static int CmpCompare(void* arg, const char* a, size_t alen,
- const char* b, size_t blen) {
+static int CmpCompare(void* arg, const char* a, size_t alen, const char* b,
+ size_t blen) {
(void)arg;
size_t n = (alen < blen) ? alen : blen;
int r = memcmp(a, b, n);
if (r == 0) {
- if (alen < blen) r = -1;
- else if (alen > blen) r = +1;
+ if (alen < blen)
+ r = -1;
+ else if (alen > blen)
+ r = +1;
}
return r;
}
return "foo";
}
-// Custom filter policy
-static unsigned char fake_filter_result = 1;
-static void FilterDestroy(void* arg) { (void)arg; }
-static const char* FilterName(void* arg) {
- (void)arg;
- return "TestFilter";
-}
-static char* FilterCreate(
- void* arg,
- const char* const* key_array, const size_t* key_length_array,
- int num_keys,
- size_t* filter_length) {
- (void)arg;
- (void)key_array;
- (void)key_length_array;
- (void)num_keys;
- *filter_length = 4;
- char* result = malloc(4);
- memcpy(result, "fake", 4);
- return result;
-}
-static unsigned char FilterKeyMatch(
- void* arg,
- const char* key, size_t length,
- const char* filter, size_t filter_length) {
- (void)arg;
- (void)key;
- (void)length;
- CheckCondition(filter_length == 4);
- CheckCondition(memcmp(filter, "fake", 4) == 0);
- return fake_filter_result;
-}
-
// Custom compaction filter
static void CFilterDestroy(void* arg) { (void)arg; }
static const char* CFilterName(void* arg) {
CFilterName);
}
+void CheckMetaData(rocksdb_column_family_metadata_t* cf_meta,
+ const char* expected_cf_name) {
+ char* cf_name = rocksdb_column_family_metadata_get_name(cf_meta);
+ assert(strcmp(cf_name, expected_cf_name) == 0);
+ rocksdb_free(cf_name);
+
+ size_t cf_size = rocksdb_column_family_metadata_get_size(cf_meta);
+ assert(cf_size > 0);
+ size_t cf_file_count = rocksdb_column_family_metadata_get_size(cf_meta);
+ assert(cf_file_count > 0);
+
+ uint64_t total_level_size = 0;
+ size_t total_file_count = 0;
+ size_t level_count = rocksdb_column_family_metadata_get_level_count(cf_meta);
+ assert(level_count > 0);
+ for (size_t l = 0; l < level_count; ++l) {
+ rocksdb_level_metadata_t* level_meta =
+ rocksdb_column_family_metadata_get_level_metadata(cf_meta, l);
+ assert(level_meta);
+ assert(rocksdb_level_metadata_get_level(level_meta) >= (int)l);
+ uint64_t level_size = rocksdb_level_metadata_get_size(level_meta);
+ uint64_t file_size_in_level = 0;
+
+ size_t file_count = rocksdb_level_metadata_get_file_count(level_meta);
+ total_file_count += file_count;
+ for (size_t f = 0; f < file_count; ++f) {
+ rocksdb_sst_file_metadata_t* file_meta =
+ rocksdb_level_metadata_get_sst_file_metadata(level_meta, f);
+ assert(file_meta);
+
+ uint64_t file_size = rocksdb_sst_file_metadata_get_size(file_meta);
+ assert(file_size > 0);
+ file_size_in_level += file_size;
+
+ char* file_name =
+ rocksdb_sst_file_metadata_get_relative_filename(file_meta);
+ assert(file_name);
+ assert(strlen(file_name) > 0);
+ rocksdb_free(file_name);
+
+ size_t smallest_key_len;
+ char* smallest_key = rocksdb_sst_file_metadata_get_smallestkey(
+ file_meta, &smallest_key_len);
+ assert(smallest_key);
+ assert(smallest_key_len > 0);
+ size_t largest_key_len;
+ char* largest_key =
+ rocksdb_sst_file_metadata_get_largestkey(file_meta, &largest_key_len);
+ assert(largest_key);
+ assert(largest_key_len > 0);
+ rocksdb_free(smallest_key);
+ rocksdb_free(largest_key);
+
+ rocksdb_sst_file_metadata_destroy(file_meta);
+ }
+ assert(level_size == file_size_in_level);
+ total_level_size += level_size;
+ rocksdb_level_metadata_destroy(level_meta);
+ }
+ assert(total_file_count > 0);
+ assert(cf_size == total_level_size);
+}
+
+void GetAndCheckMetaData(rocksdb_t* db) {
+ rocksdb_column_family_metadata_t* cf_meta =
+ rocksdb_get_column_family_metadata(db);
+
+ CheckMetaData(cf_meta, "default");
+
+ rocksdb_column_family_metadata_destroy(cf_meta);
+}
+
+void GetAndCheckMetaDataCf(rocksdb_t* db,
+ rocksdb_column_family_handle_t* handle,
+ const char* cf_name) {
+ // Compact to make sure we have at least one sst file to obtain datadata.
+ rocksdb_compact_range_cf(db, handle, NULL, 0, NULL, 0);
+
+ rocksdb_column_family_metadata_t* cf_meta =
+ rocksdb_get_column_family_metadata_cf(db, handle);
+
+ CheckMetaData(cf_meta, cf_name);
+
+ rocksdb_column_family_metadata_destroy(cf_meta);
+}
+
static rocksdb_t* CheckCompaction(rocksdb_t* db, rocksdb_options_t* options,
rocksdb_readoptions_t* roptions,
rocksdb_writeoptions_t* woptions) {
CheckNoError(err);
CheckGet(db, roptions, "baz", "bazvalue");
+ // Disable compaction
+ rocksdb_disable_manual_compaction(db);
+ rocksdb_compact_range(db, NULL, 0, NULL, 0);
+ // should not filter anything when disabled
+ CheckGet(db, roptions, "foo", "foovalue");
+ CheckGet(db, roptions, "bar", "barvalue");
+ CheckGet(db, roptions, "baz", "bazvalue");
+ // Reenable compaction
+ rocksdb_enable_manual_compaction(db);
+
// Force compaction
rocksdb_compact_range(db, NULL, 0, NULL, 0);
// should have filtered bar, but not foo
CheckGet(db, roptions, "foo", "foovalue");
CheckGet(db, roptions, "bar", NULL);
CheckGet(db, roptions, "baz", "newbazvalue");
+
+ rocksdb_suggest_compact_range(db, "bar", 3, "foo", 3, &err);
+ GetAndCheckMetaData(db);
+ CheckNoError(err);
+
return db;
}
return "TestMergeOperator";
}
static char* MergeOperatorFullMerge(
- void* arg,
- const char* key, size_t key_length,
- const char* existing_value, size_t existing_value_length,
- const char* const* operands_list, const size_t* operands_list_length,
- int num_operands,
+ void* arg, const char* key, size_t key_length, const char* existing_value,
+ size_t existing_value_length, const char* const* operands_list,
+ const size_t* operands_list_length, int num_operands,
unsigned char* success, size_t* new_value_length) {
(void)arg;
(void)key;
memcpy(result, "fake", 4);
return result;
}
-static char* MergeOperatorPartialMerge(
- void* arg,
- const char* key, size_t key_length,
- const char* const* operands_list, const size_t* operands_list_length,
- int num_operands,
- unsigned char* success, size_t* new_value_length) {
+static char* MergeOperatorPartialMerge(void* arg, const char* key,
+ size_t key_length,
+ const char* const* operands_list,
+ const size_t* operands_list_length,
+ int num_operands, unsigned char* success,
+ size_t* new_value_length) {
(void)arg;
(void)key;
(void)key_length;
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 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 CheckTxnGetCF(rocksdb_transaction_t* txn,
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);
+static void CheckTxnPinGet(rocksdb_transaction_t* txn,
+ const rocksdb_readoptions_t* options,
+ const char* key, const char* expected) {
+ rocksdb_pinnableslice_t* p = NULL;
+ const char* val = NULL;
+ char* err = NULL;
+ size_t val_len;
+ p = rocksdb_transaction_get_pinned(txn, options, key, strlen(key), &err);
+ CheckNoError(err);
+ val = rocksdb_pinnableslice_value(p, &val_len);
+ CheckEqual(expected, val, val_len);
+ rocksdb_pinnableslice_destroy(p);
+}
+
+static void CheckTxnPinGetCF(rocksdb_transaction_t* txn,
+ const rocksdb_readoptions_t* options,
+ rocksdb_column_family_handle_t* column_family,
+ const char* key, const char* expected) {
+ rocksdb_pinnableslice_t* p = NULL;
+ const char* val = NULL;
+ char* err = NULL;
+ size_t val_len;
+ p = rocksdb_transaction_get_pinned_cf(txn, options, column_family, key,
+ strlen(key), &err);
+ CheckNoError(err);
+ val = rocksdb_pinnableslice_value(p, &val_len);
+ CheckEqual(expected, val, val_len);
+ rocksdb_pinnableslice_destroy(p);
+}
+
+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);
}
static void CheckTxnDBGetCF(rocksdb_transactiondb_t* txn_db,
Free(&val);
}
+static void CheckTxnDBPinGet(rocksdb_transactiondb_t* txn_db,
+ const rocksdb_readoptions_t* options,
+ const char* key, const char* expected) {
+ rocksdb_pinnableslice_t* p = NULL;
+ const char* val = NULL;
+ char* err = NULL;
+ size_t val_len;
+ p = rocksdb_transactiondb_get_pinned(txn_db, options, key, strlen(key), &err);
+ CheckNoError(err);
+ val = rocksdb_pinnableslice_value(p, &val_len);
+ CheckEqual(expected, val, val_len);
+ rocksdb_pinnableslice_destroy(p);
+}
+
+static void CheckTxnDBPinGetCF(rocksdb_transactiondb_t* txn_db,
+ const rocksdb_readoptions_t* options,
+ rocksdb_column_family_handle_t* column_family,
+ const char* key, const char* expected) {
+ rocksdb_pinnableslice_t* p = NULL;
+ const char* val = NULL;
+ char* err = NULL;
+ size_t val_len;
+ p = rocksdb_transactiondb_get_pinned_cf(txn_db, options, column_family, key,
+ strlen(key), &err);
+ CheckNoError(err);
+ val = rocksdb_pinnableslice_value(p, &val_len);
+ CheckEqual(expected, val, val_len);
+ rocksdb_pinnableslice_destroy(p);
+}
+
+static void LoadAndCheckLatestOptions(const char* db_name, rocksdb_env_t* env,
+ bool ignore_unknown_options,
+ rocksdb_cache_t* cache,
+ rocksdb_comparator_t* cmp,
+ const size_t expected_num_column_families,
+ const char** expected_cf_names,
+ const char* expected_open_err) {
+ rocksdb_options_t* db_options;
+ size_t num_column_families;
+ char** list_column_family_names;
+ rocksdb_options_t** list_column_family_options;
+ char* err = 0;
+
+ // load the latest rocksdb option
+ rocksdb_load_latest_options(db_name, env, ignore_unknown_options, cache,
+ &db_options, &num_column_families,
+ &list_column_family_names,
+ &list_column_family_options, &err);
+ assert(num_column_families == expected_num_column_families);
+ CheckNoError(err);
+
+ // verify the loaded options by opening the db.
+ rocksdb_options_set_error_if_exists(db_options, 0);
+
+ char** list_const_cf_names =
+ (char**)malloc(num_column_families * sizeof(char*));
+ rocksdb_options_t** list_const_cf_options = (rocksdb_options_t**)malloc(
+ num_column_families * sizeof(rocksdb_options_t*));
+ for (size_t i = 0; i < num_column_families; ++i) {
+ assert(strcmp(list_column_family_names[i], expected_cf_names[i]) == 0);
+ list_const_cf_names[i] = list_column_family_names[i];
+ if (cmp) {
+ rocksdb_options_set_comparator(list_column_family_options[i], cmp);
+ }
+ list_const_cf_options[i] = list_column_family_options[i];
+ }
+ rocksdb_column_family_handle_t** handles =
+ (rocksdb_column_family_handle_t**)malloc(
+ num_column_families * sizeof(rocksdb_column_family_handle_t*));
+
+ rocksdb_t* db = rocksdb_open_column_families(
+ db_options, db_name, (int)num_column_families,
+ (const char* const*)list_const_cf_names,
+ (const rocksdb_options_t* const*)list_const_cf_options, handles, &err);
+ if (expected_open_err == NULL) {
+ CheckNoError(err);
+ for (size_t i = 0; i < num_column_families; ++i) {
+ rocksdb_column_family_handle_destroy(handles[i]);
+ }
+ free(handles);
+ rocksdb_close(db);
+ } else {
+ assert(err != NULL);
+ assert(strcmp(err, expected_open_err) == 0);
+ free(handles);
+ free(err);
+ }
+
+ free(list_const_cf_names);
+ free(list_const_cf_options);
+ rocksdb_load_latest_options_destroy(db_options, list_column_family_names,
+ list_column_family_options,
+ num_column_families);
+}
+
int main(int argc, char** argv) {
(void)argc;
(void)argv;
rocksdb_t* db;
rocksdb_comparator_t* cmp;
rocksdb_cache_t* cache;
- rocksdb_dbpath_t *dbpath;
+ rocksdb_dbpath_t* dbpath;
rocksdb_env_t* env;
rocksdb_options_t* options;
rocksdb_compactoptions_t* coptions;
char* err = NULL;
int run = -1;
- snprintf(dbname, sizeof(dbname),
- "%s/rocksdb_c_test-%d",
- GetTempDir(),
- ((int) geteuid()));
+ snprintf(dbname, sizeof(dbname), "%s/rocksdb_c_test-%d", GetTempDir(),
+ ((int)geteuid()));
- snprintf(dbbackupname, sizeof(dbbackupname),
- "%s/rocksdb_c_test-%d-backup",
- GetTempDir(),
- ((int) geteuid()));
+ snprintf(dbbackupname, sizeof(dbbackupname), "%s/rocksdb_c_test-%d-backup",
+ GetTempDir(), ((int)geteuid()));
snprintf(dbcheckpointname, sizeof(dbcheckpointname),
- "%s/rocksdb_c_test-%d-checkpoint",
- GetTempDir(),
- ((int) geteuid()));
+ "%s/rocksdb_c_test-%d-checkpoint", GetTempDir(), ((int)geteuid()));
- snprintf(sstfilename, sizeof(sstfilename),
- "%s/rocksdb_c_test-%d-sst",
- GetTempDir(),
- ((int)geteuid()));
+ snprintf(sstfilename, sizeof(sstfilename), "%s/rocksdb_c_test-%d-sst",
+ GetTempDir(), ((int)geteuid()));
- snprintf(dbpathname, sizeof(dbpathname),
- "%s/rocksdb_c_test-%d-dbpath",
- GetTempDir(),
- ((int) geteuid()));
+ snprintf(dbpathname, sizeof(dbpathname), "%s/rocksdb_c_test-%d-dbpath",
+ GetTempDir(), ((int)geteuid()));
StartPhase("create_objects");
cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
dbpath = rocksdb_dbpath_create(dbpathname, 1024 * 1024);
env = rocksdb_create_default_env();
+
+ rocksdb_create_dir_if_missing(env, GetTempDir(), &err);
+ CheckNoError(err);
+
cache = rocksdb_cache_create_lru(100000);
options = rocksdb_options_create();
rocksdb_options_set_write_buffer_size(options, 100000);
rocksdb_options_set_paranoid_checks(options, 1);
rocksdb_options_set_max_open_files(options, 10);
- rocksdb_options_set_base_background_compactions(options, 1);
table_options = rocksdb_block_based_options_create();
rocksdb_block_based_options_set_block_cache(table_options, cache);
coptions = rocksdb_compactoptions_create();
rocksdb_compactoptions_set_exclusive_manual_compaction(coptions, 1);
+ rocksdb_options_add_compact_on_deletion_collector_factory(options, 10000,
+ 10001);
+
StartPhase("destroy");
rocksdb_destroy_db(options, dbname, &err);
Free(&err);
rocksdb_destroy_db(options, dbbackupname, &err);
CheckNoError(err);
- rocksdb_backup_engine_t *be = rocksdb_backup_engine_open(options, dbbackupname, &err);
+ rocksdb_backup_engine_t* be =
+ rocksdb_backup_engine_open(options, dbbackupname, &err);
CheckNoError(err);
rocksdb_backup_engine_create_new_backup(be, db, &err);
rocksdb_backup_engine_create_new_backup(be, db, &err);
CheckNoError(err);
- const rocksdb_backup_engine_info_t* bei = rocksdb_backup_engine_get_backup_info(be);
+ const rocksdb_backup_engine_info_t* bei =
+ rocksdb_backup_engine_get_backup_info(be);
CheckCondition(rocksdb_backup_engine_info_count(bei) > 1);
rocksdb_backup_engine_info_destroy(bei);
rocksdb_destroy_db(options, dbname, &err);
CheckNoError(err);
- rocksdb_restore_options_t *restore_options = rocksdb_restore_options_create();
+ rocksdb_restore_options_t* restore_options =
+ rocksdb_restore_options_create();
rocksdb_restore_options_set_keep_log_files(restore_options, 0);
- rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname, restore_options, &err);
+ rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname,
+ restore_options, &err);
CheckNoError(err);
rocksdb_restore_options_destroy(restore_options);
rocksdb_destroy_db(options, dbcheckpointname, &err);
CheckNoError(err);
- rocksdb_checkpoint_t* checkpoint = rocksdb_checkpoint_object_create(db, &err);
+ rocksdb_checkpoint_t* checkpoint =
+ rocksdb_checkpoint_object_create(db, &err);
CheckNoError(err);
rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err);
CheckGet(db, roptions, "sstk22", "v5");
CheckGet(db, roptions, "sstk3", "v6");
+ rocksdb_sstfilewriter_open(writer, sstfilename, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_put(writer, "abc1", 4, "v7", 2, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_put(writer, "abc2", 4, "v8", 2, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_put(writer, "abc3", 4, "v9", 2, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_put(writer, "abc4", 4, "v10", 3, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_delete_range(writer, "abc1", 4, "abc4", 4, &err);
+ CheckNoError(err);
+ rocksdb_sstfilewriter_finish(writer, &err);
+ CheckNoError(err);
+
rocksdb_ingestexternalfileoptions_destroy(ing_opt);
rocksdb_sstfilewriter_destroy(writer);
rocksdb_options_destroy(io_options);
StartPhase("writebatch_vectors");
{
rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
- const char* k_list[2] = { "z", "ap" };
- const size_t k_sizes[2] = { 1, 2 };
- const char* v_list[3] = { "x", "y", "z" };
- const size_t v_sizes[3] = { 1, 1, 1 };
+ const char* k_list[2] = {"z", "ap"};
+ const size_t k_sizes[2] = {1, 2};
+ const char* v_list[3] = {"x", "y", "z"};
+ const size_t v_sizes[3] = {1, 1, 1};
rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
rocksdb_write(db, woptions, wb, &err);
CheckNoError(err);
CheckCondition(count == 3);
size_t size;
char* value;
- value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "box", 3, &size, &err);
+ value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "box", 3, &size,
+ &err);
CheckValue(err, "c", &value, size);
- value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "bar", 3, &size, &err);
+ value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "bar", 3, &size,
+ &err);
CheckValue(err, NULL, &value, size);
- value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "foo", 3, &size, &err);
+ value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions,
+ "foo", 3, &size, &err);
CheckValue(err, "hello", &value, size);
- value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "box", 3, &size, &err);
+ value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions,
+ "box", 3, &size, &err);
CheckValue(err, "c", &value, size);
rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
CheckNoError(err);
StartPhase("writebatch_wi_vectors");
{
rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
- const char* k_list[2] = { "z", "ap" };
- const size_t k_sizes[2] = { 1, 2 };
- const char* v_list[3] = { "x", "y", "z" };
- const size_t v_sizes[3] = { 1, 1, 1 };
+ const char* k_list[2] = {"z", "ap"};
+ const size_t k_sizes[2] = {1, 2};
+ const char* v_list[3] = {"x", "y", "z"};
+ const size_t v_sizes[3] = {1, 1, 1};
rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
rocksdb_write_writebatch_wi(db, woptions, wb, &err);
CheckNoError(err);
StartPhase("multiget");
{
- const char* keys[3] = { "box", "foo", "notfound" };
- const size_t keys_sizes[3] = { 3, 3, 8 };
+ const char* keys[3] = {"box", "foo", "notfound"};
+ const size_t keys_sizes[3] = {3, 3, 8};
char* vals[3];
size_t vals_sizes[3];
char* errs[3];
- rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes, errs);
-
- int i;
- for (i = 0; i < 3; i++) {
- CheckEqual(NULL, errs[i], 0);
- switch (i) {
- case 0:
- CheckEqual("c", vals[i], vals_sizes[i]);
- break;
- case 1:
- CheckEqual("hello", vals[i], vals_sizes[i]);
- break;
- case 2:
- CheckEqual(NULL, vals[i], vals_sizes[i]);
- break;
- }
- Free(&vals[i]);
- }
+ const char* expected[3] = {"c", "hello", NULL};
+ rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes,
+ errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
}
StartPhase("pin_get");
char keybuf[100];
char valbuf[100];
uint64_t sizes[2];
- const char* start[2] = { "a", "k00000000000000010000" };
- size_t start_len[2] = { 1, 21 };
- const char* limit[2] = { "k00000000000000010000", "z" };
- size_t limit_len[2] = { 21, 1 };
+ const char* start[2] = {"a", "k00000000000000010000"};
+ size_t start_len[2] = {1, 21};
+ const char* limit[2] = {"k00000000000000010000", "z"};
+ size_t limit_len[2] = {21, 1};
rocksdb_writeoptions_set_sync(woptions, 0);
for (i = 0; i < n; i++) {
snprintf(keybuf, sizeof(keybuf), "k%020d", i);
&err);
CheckNoError(err);
}
- rocksdb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes);
+ rocksdb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes,
+ &err);
+ CheckNoError(err);
CheckCondition(sizes[0] > 0);
CheckCondition(sizes[1] > 0);
}
CheckGet(db, roptions, "foo", NULL);
rocksdb_release_snapshot(db, snap);
}
-
+ StartPhase("snapshot_with_memtable_inplace_update");
+ {
+ rocksdb_close(db);
+ const rocksdb_snapshot_t* snap = NULL;
+ const char* s_key = "foo_snap";
+ const char* value1 = "hello_s1";
+ const char* value2 = "hello_s2";
+ rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
+ rocksdb_options_set_inplace_update_support(options, 1);
+ rocksdb_options_set_error_if_exists(options, 0);
+ db = rocksdb_open(options, dbname, &err);
+ CheckNoError(err);
+ rocksdb_put(db, woptions, s_key, 8, value1, 8, &err);
+ snap = rocksdb_create_snapshot(db);
+ assert(snap != NULL);
+ rocksdb_put(db, woptions, s_key, 8, value2, 8, &err);
+ CheckNoError(err);
+ rocksdb_readoptions_set_snapshot(roptions, snap);
+ CheckGet(db, roptions, "foo", NULL);
+ // snapshot syntax is invalid, because of inplace update supported is set
+ CheckGet(db, roptions, s_key, value2);
+ // restore the data and options
+ rocksdb_delete(db, woptions, s_key, 8, &err);
+ CheckGet(db, roptions, s_key, NULL);
+ rocksdb_release_snapshot(db, snap);
+ rocksdb_readoptions_set_snapshot(roptions, NULL);
+ rocksdb_options_set_inplace_update_support(options, 0);
+ rocksdb_options_set_allow_concurrent_memtable_write(options, 1);
+ rocksdb_options_set_error_if_exists(options, 1);
+ }
StartPhase("repair");
{
// If we do not compact here, then the lazy deletion of
}
StartPhase("filter");
- for (run = 0; run <= 2; run++) {
- // First run uses custom filter
- // Second run uses old block-based bloom filter
- // Third run uses full bloom filter
+ for (run = 1; run <= 4; run++) {
+ // run=0 uses custom filter (not currently supported)
+ // run=1 uses old block-based bloom filter
+ // run=2 run uses full bloom filter
+ // run=3 uses Ribbon
+ // run=4 uses Ribbon-Bloom hybrid configuration
CheckNoError(err);
rocksdb_filterpolicy_t* policy;
- if (run == 0) {
- policy = rocksdb_filterpolicy_create(NULL, FilterDestroy, FilterCreate,
- FilterKeyMatch, NULL, FilterName);
- } else if (run == 1) {
- policy = rocksdb_filterpolicy_create_bloom(8);
+ if (run == 1) {
+ policy = rocksdb_filterpolicy_create_bloom(8.0);
+ } else if (run == 2) {
+ policy = rocksdb_filterpolicy_create_bloom_full(8.0);
+ } else if (run == 3) {
+ policy = rocksdb_filterpolicy_create_ribbon(8.0);
} else {
- policy = rocksdb_filterpolicy_create_bloom_full(8);
+ policy = rocksdb_filterpolicy_create_ribbon_hybrid(8.0, 1);
}
rocksdb_block_based_options_set_filter_policy(table_options, policy);
}
rocksdb_compact_range(db, NULL, 0, NULL, 0);
- fake_filter_result = 1;
CheckGet(db, roptions, "foo", "foovalue");
CheckGet(db, roptions, "bar", "barvalue");
- if (run == 0) {
- // Must not find value when custom filter returns false
- fake_filter_result = 0;
- CheckGet(db, roptions, "foo", NULL);
- CheckGet(db, roptions, "bar", NULL);
- fake_filter_result = 1;
-
- CheckGet(db, roptions, "foo", "foovalue");
- CheckGet(db, roptions, "bar", "barvalue");
- }
{
// Query some keys not added to identify Bloom filter implementation
int i;
char keybuf[100];
for (i = 0; i < keys_to_query; i++) {
- fake_filter_result = i % 2;
snprintf(keybuf, sizeof(keybuf), "no%020d", i);
CheckGet(db, roptions, keybuf, NULL);
}
if (run == 0) {
// Due to half true, half false with fake filter result
CheckCondition(hits == keys_to_query / 2);
- } else if (run == 1) {
- // Essentially a fingerprint of the block-based Bloom schema
- CheckCondition(hits == 241);
+ } else if (run == 1 || run == 2 || run == 4) {
+ // For run == 1, block-based Bloom is no longer available in public
+ // API; attempting to enable it enables full Bloom instead.
+ //
+ // Essentially a fingerprint of full Bloom schema, format_version=5
+ CheckCondition(hits == 188);
} else {
- // Essentially a fingerprint of the full Bloom schema(s),
- // format_version < 5, which vary for three different CACHE_LINE_SIZEs
- CheckCondition(hits == 224 || hits == 180 || hits == 125);
+ // Essentially a fingerprint of Ribbon schema
+ CheckCondition(hits == 226);
}
CheckCondition(
(keys_to_query - hits) ==
factory);
db = CheckCompaction(db, options_with_filter_factory, roptions, woptions);
- rocksdb_options_set_compaction_filter_factory(
- options_with_filter_factory, NULL);
+ rocksdb_options_set_compaction_filter_factory(options_with_filter_factory,
+ NULL);
rocksdb_options_destroy(options_with_filter_factory);
}
rocksdb_merge(db, woptions, "bar", 3, "barvalue", 8, &err);
CheckNoError(err);
CheckGet(db, roptions, "bar", "fake");
-
}
StartPhase("columnfamilies");
rocksdb_options_t* db_options = rocksdb_options_create();
rocksdb_options_set_create_if_missing(db_options, 1);
db = rocksdb_open(db_options, dbname, &err);
- CheckNoError(err)
+ CheckNoError(err);
+ rocksdb_close(db);
+ {
+ const char* expected_cf_names[1] = {"default"};
+ LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
+ expected_cf_names, NULL);
+ }
+
+ rocksdb_options_set_create_if_missing(db_options, 0);
+ db = rocksdb_open(db_options, dbname, &err);
rocksdb_column_family_handle_t* cfh;
cfh = rocksdb_create_column_family(db, db_options, "cf1", &err);
rocksdb_column_family_handle_destroy(cfh);
rocksdb_close(db);
size_t cflen;
- char** column_fams = rocksdb_list_column_families(db_options, dbname, &cflen, &err);
+ char** column_fams =
+ rocksdb_list_column_families(db_options, dbname, &cflen, &err);
CheckNoError(err);
CheckEqual("default", column_fams[0], 7);
CheckEqual("cf1", column_fams[1], 3);
const char* cf_names[2] = {"default", "cf1"};
const rocksdb_options_t* cf_opts[2] = {cf_options, cf_options};
rocksdb_column_family_handle_t* handles[2];
- db = rocksdb_open_column_families(db_options, dbname, 2, cf_names, cf_opts, handles, &err);
+
+ LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 2, cf_names,
+ NULL);
+
+ db = rocksdb_open_column_families(db_options, dbname, 2, cf_names, cf_opts,
+ handles, &err);
CheckNoError(err);
rocksdb_put_cf(db, woptions, handles[1], "foo", 3, "hello", 5, &err);
CheckNoError(err);
rocksdb_put_cf(db, woptions, handles[1], "foobar4", 7, "hello4", 6, &err);
CheckNoError(err);
+ rocksdb_suggest_compact_range_cf(db, handles[1], "foo", 3, "foobar9", 7,
+ &err);
+ CheckNoError(err);
- rocksdb_flushoptions_t *flush_options = rocksdb_flushoptions_create();
+ rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
rocksdb_flushoptions_set_wait(flush_options, 1);
rocksdb_flush_cf(db, flush_options, handles[1], &err);
- CheckNoError(err)
- rocksdb_flushoptions_destroy(flush_options);
+ CheckNoError(err) rocksdb_flushoptions_destroy(flush_options);
CheckGetCF(db, roptions, handles[1], "foo", "hello");
CheckPinGetCF(db, roptions, handles[1], "foo", "hello");
rocksdb_writebatch_clear(wb);
rocksdb_writebatch_put_cf(wb, handles[1], "bar", 3, "b", 1);
rocksdb_writebatch_put_cf(wb, handles[1], "box", 3, "c", 1);
+ rocksdb_writebatch_put_cf(wb, handles[1], "buff", 4, "rocksdb", 7);
rocksdb_writebatch_delete_cf(wb, handles[1], "bar", 3);
rocksdb_write(db, woptions, wb, &err);
CheckNoError(err);
CheckGetCF(db, roptions, handles[1], "baz", NULL);
CheckGetCF(db, roptions, handles[1], "bar", NULL);
CheckGetCF(db, roptions, handles[1], "box", "c");
+ CheckGetCF(db, roptions, handles[1], "buff", "rocksdb");
CheckPinGetCF(db, roptions, handles[1], "baz", NULL);
CheckPinGetCF(db, roptions, handles[1], "bar", NULL);
CheckPinGetCF(db, roptions, handles[1], "box", "c");
+ CheckPinGetCF(db, roptions, handles[1], "buff", "rocksdb");
rocksdb_writebatch_destroy(wb);
- const char* keys[3] = { "box", "box", "barfooxx" };
- const rocksdb_column_family_handle_t* get_handles[3] = { handles[0], handles[1], handles[1] };
- const size_t keys_sizes[3] = { 3, 3, 8 };
+ rocksdb_flush_wal(db, 1, &err);
+ CheckNoError(err);
+
+ const char* keys[3] = {"box", "box", "barfooxx"};
+ const rocksdb_column_family_handle_t* get_handles[3] = {
+ handles[0], handles[1], handles[1]};
+ const size_t keys_sizes[3] = {3, 3, 8};
char* vals[3];
size_t vals_sizes[3];
char* errs[3];
- rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals, vals_sizes, errs);
+ rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals,
+ vals_sizes, errs);
int i;
for (i = 0; i < 3; i++) {
CheckEqual(NULL, errs[i], 0);
switch (i) {
- case 0:
- CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
- break;
- case 1:
- CheckEqual("c", vals[i], vals_sizes[i]); // bingo
- break;
- case 2:
- CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
- break;
+ case 0:
+ CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
+ break;
+ case 1:
+ CheckEqual("c", vals[i], vals_sizes[i]); // bingo
+ break;
+ case 2:
+ CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
+ break;
}
Free(&vals[i]);
}
+ {
+ const char* batched_keys[4] = {"box", "buff", "barfooxx", "box"};
+ const size_t batched_keys_sizes[4] = {3, 4, 8, 3};
+ const char* expected_value[4] = {"c", "rocksdb", NULL, "c"};
+ char* batched_errs[4];
+
+ rocksdb_pinnableslice_t* pvals[4];
+ rocksdb_batched_multi_get_cf(db, roptions, handles[1], 4, batched_keys,
+ batched_keys_sizes, pvals, batched_errs,
+ false);
+ const char* val;
+ size_t val_len;
+ for (i = 0; i < 4; ++i) {
+ val = rocksdb_pinnableslice_value(pvals[i], &val_len);
+ CheckNoError(batched_errs[i]);
+ CheckEqual(expected_value[i], val, val_len);
+ rocksdb_pinnableslice_destroy(pvals[i]);
+ }
+ }
+
{
unsigned char value_found = 0;
}
}
- rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]);
+ rocksdb_iterator_t* iter =
+ rocksdb_create_iterator_cf(db, roptions, handles[1]);
CheckCondition(!rocksdb_iter_valid(iter));
rocksdb_iter_seek_to_first(iter);
CheckCondition(rocksdb_iter_valid(iter));
for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
i++;
}
- CheckCondition(i == 3);
+ CheckCondition(i == 4);
rocksdb_iter_get_error(iter, &err);
CheckNoError(err);
rocksdb_iter_destroy(iter);
- rocksdb_column_family_handle_t* iters_cf_handles[2] = { handles[0], handles[1] };
+ rocksdb_column_family_handle_t* iters_cf_handles[2] = {handles[0],
+ handles[1]};
rocksdb_iterator_t* iters_handles[2];
- rocksdb_create_iterators(db, roptions, iters_cf_handles, iters_handles, 2, &err);
+ rocksdb_create_iterators(db, roptions, iters_cf_handles, iters_handles, 2,
+ &err);
CheckNoError(err);
iter = iters_handles[0];
for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
i++;
}
- CheckCondition(i == 3);
+ CheckCondition(i == 4);
rocksdb_iter_get_error(iter, &err);
CheckNoError(err);
rocksdb_iter_destroy(iter);
+ GetAndCheckMetaDataCf(db, handles[1], cf_names[1]);
+
rocksdb_drop_column_family(db, handles[1], &err);
CheckNoError(err);
for (i = 0; i < 2; i++) {
rocksdb_column_family_handle_destroy(handles[i]);
}
rocksdb_close(db);
+ {
+ // As column family has been dropped, we expect only one column family.
+ const char* expected_cf_names[1] = {"default"};
+ LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
+ expected_cf_names, NULL);
+ }
rocksdb_destroy_db(options, dbname, &err);
rocksdb_options_destroy(db_options);
rocksdb_options_destroy(cf_options);
{
// Create new database
rocksdb_options_set_allow_mmap_reads(options, 1);
- rocksdb_options_set_prefix_extractor(options, rocksdb_slicetransform_create_fixed_prefix(3));
+ rocksdb_options_set_prefix_extractor(
+ options, rocksdb_slicetransform_create_fixed_prefix(3));
rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
rocksdb_options_set_plain_table_factory(options, 4, 10, 0.75, 16);
rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
rocksdb_readoptions_set_total_order_seek(roptions, 0);
rocksdb_close(db);
+
+ {
+ const char* expected_cf_names[1] = {"default"};
+ LoadAndCheckLatestOptions(dbname, env, false, cache, NULL, 1,
+ expected_cf_names,
+ "Invalid argument: leveldb.BytewiseComparator: "
+ "does not match existing comparator foo");
+ LoadAndCheckLatestOptions(dbname, env, false, cache, cmp, 1,
+ expected_cf_names, NULL);
+ }
rocksdb_destroy_db(options, dbname, &err);
}
// amount of memory used within memtables should grow
CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_total(mu2) >=
rocksdb_approximate_memory_usage_get_mem_table_total(mu1));
- CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu2) >=
- rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu1));
+ CheckCondition(
+ rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu2) >=
+ rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu1));
rocksdb_memory_consumers_destroy(consumers);
rocksdb_approximate_memory_usage_destroy(mu1);
rocksdb_options_set_max_background_compactions(o, 3);
CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
- rocksdb_options_set_base_background_compactions(o, 4);
- CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
-
rocksdb_options_set_max_background_flushes(o, 5);
CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
rocksdb_options_set_recycle_log_file_num(o, 9);
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
- rocksdb_options_set_soft_rate_limit(o, 2.0);
- CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
-
- rocksdb_options_set_hard_rate_limit(o, 4.0);
- CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
-
rocksdb_options_set_soft_pending_compaction_bytes_limit(o, 10);
CheckCondition(10 ==
rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
CheckCondition(11 ==
rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
- rocksdb_options_set_rate_limit_delay_max_milliseconds(o, 1);
- CheckCondition(1 ==
- rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
-
rocksdb_options_set_max_manifest_file_size(o, 12);
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
rocksdb_options_set_is_fd_close_on_exec(o, 1);
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
- rocksdb_options_set_skip_log_error_on_recovery(o, 1);
- CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
-
rocksdb_options_set_stats_dump_period_sec(o, 18);
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
rocksdb_options_set_atomic_flush(o, 1);
CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
+ rocksdb_options_set_manual_wal_flush(o, 1);
+ CheckCondition(1 == rocksdb_options_get_manual_wal_flush(o));
+
+ rocksdb_options_set_wal_compression(o, 1);
+ CheckCondition(1 == rocksdb_options_get_wal_compression(o));
+
+ rocksdb_options_set_experimental_mempurge_threshold(o, 29.0);
+ CheckCondition(29.0 ==
+ rocksdb_options_get_experimental_mempurge_threshold(o));
+
+ /* Blob Options */
+ rocksdb_options_set_enable_blob_files(o, 1);
+ CheckCondition(1 == rocksdb_options_get_enable_blob_files(o));
+
+ rocksdb_options_set_min_blob_size(o, 29);
+ CheckCondition(29 == rocksdb_options_get_min_blob_size(o));
+
+ rocksdb_options_set_blob_file_size(o, 30);
+ CheckCondition(30 == rocksdb_options_get_blob_file_size(o));
+
+ rocksdb_options_set_blob_compression_type(o, 4);
+ CheckCondition(4 == rocksdb_options_get_blob_compression_type(o));
+
+ rocksdb_options_set_enable_blob_gc(o, 1);
+ CheckCondition(1 == rocksdb_options_get_enable_blob_gc(o));
+
+ rocksdb_options_set_blob_gc_age_cutoff(o, 0.5);
+ CheckCondition(0.5 == rocksdb_options_get_blob_gc_age_cutoff(o));
+
+ rocksdb_options_set_blob_gc_force_threshold(o, 0.75);
+ CheckCondition(0.75 == rocksdb_options_get_blob_gc_force_threshold(o));
+
+ rocksdb_options_set_blob_compaction_readahead_size(o, 262144);
+ CheckCondition(262144 ==
+ rocksdb_options_get_blob_compaction_readahead_size(o));
+
+ rocksdb_options_set_blob_file_starting_level(o, 5);
+ CheckCondition(5 == rocksdb_options_get_blob_file_starting_level(o));
+
+ rocksdb_options_set_prepopulate_blob_cache(o, 1 /* flush only */);
+ CheckCondition(1 == rocksdb_options_get_prepopulate_blob_cache(o));
+
// Create a copy that should be equal to the original.
rocksdb_options_t* copy;
copy = rocksdb_options_create_copy(o);
CheckCondition(123456 == rocksdb_options_get_max_subcompactions(copy));
CheckCondition(2 == rocksdb_options_get_max_background_jobs(copy));
CheckCondition(3 == rocksdb_options_get_max_background_compactions(copy));
- CheckCondition(4 == rocksdb_options_get_base_background_compactions(copy));
CheckCondition(5 == rocksdb_options_get_max_background_flushes(copy));
CheckCondition(6 == rocksdb_options_get_max_log_file_size(copy));
CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(copy));
CheckCondition(8 == rocksdb_options_get_keep_log_file_num(copy));
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(copy));
- CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(copy));
- CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(copy));
CheckCondition(
10 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
CheckCondition(
11 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
- CheckCondition(1 ==
- rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(copy));
CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(copy));
CheckCondition(14 == rocksdb_options_get_arena_block_size(copy));
CheckCondition(
1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(copy));
- CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(copy));
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(copy));
CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(copy));
CheckCondition(1 == rocksdb_options_get_advise_random_on_open(copy));
CheckCondition(4 == rocksdb_options_get_bottommost_compression(copy));
CheckCondition(2 == rocksdb_options_get_compaction_style(copy));
CheckCondition(1 == rocksdb_options_get_atomic_flush(copy));
+ CheckCondition(29.0 ==
+ rocksdb_options_get_experimental_mempurge_threshold(copy));
// Copies should be independent.
rocksdb_options_set_allow_ingest_behind(copy, 0);
CheckCondition(13 == rocksdb_options_get_max_background_compactions(copy));
CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
- rocksdb_options_set_base_background_compactions(copy, 14);
- CheckCondition(14 == rocksdb_options_get_base_background_compactions(copy));
- CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
-
rocksdb_options_set_max_background_flushes(copy, 15);
CheckCondition(15 == rocksdb_options_get_max_background_flushes(copy));
CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
CheckCondition(19 == rocksdb_options_get_recycle_log_file_num(copy));
CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
- rocksdb_options_set_soft_rate_limit(copy, 4.0);
- CheckCondition(4.0 == rocksdb_options_get_soft_rate_limit(copy));
- CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
-
- rocksdb_options_set_hard_rate_limit(copy, 2.0);
- CheckCondition(2.0 == rocksdb_options_get_hard_rate_limit(copy));
- CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
-
rocksdb_options_set_soft_pending_compaction_bytes_limit(copy, 110);
CheckCondition(
110 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
CheckCondition(11 ==
rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
- rocksdb_options_set_rate_limit_delay_max_milliseconds(copy, 0);
- CheckCondition(0 ==
- rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
- CheckCondition(1 ==
- rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
-
rocksdb_options_set_max_manifest_file_size(copy, 112);
CheckCondition(112 == rocksdb_options_get_max_manifest_file_size(copy));
CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
CheckCondition(0 == rocksdb_options_get_is_fd_close_on_exec(copy));
CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
- rocksdb_options_set_skip_log_error_on_recovery(copy, 0);
- CheckCondition(0 == rocksdb_options_get_skip_log_error_on_recovery(copy));
- CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
-
rocksdb_options_set_stats_dump_period_sec(copy, 218);
CheckCondition(218 == rocksdb_options_get_stats_dump_period_sec(copy));
CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
CheckCondition(0 == rocksdb_options_get_atomic_flush(copy));
CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
+ rocksdb_options_set_experimental_mempurge_threshold(copy, 229.0);
+ CheckCondition(229.0 ==
+ rocksdb_options_get_experimental_mempurge_threshold(copy));
+ CheckCondition(29.0 ==
+ rocksdb_options_get_experimental_mempurge_threshold(o));
+
rocksdb_options_destroy(copy);
rocksdb_options_destroy(o);
}
rocksdb_readoptions_set_ignore_range_deletions(ro, 1);
CheckCondition(1 == rocksdb_readoptions_get_ignore_range_deletions(ro));
+ rocksdb_readoptions_set_deadline(ro, 300);
+ CheckCondition(300 == rocksdb_readoptions_get_deadline(ro));
+
+ rocksdb_readoptions_set_io_timeout(ro, 400);
+ CheckCondition(400 == rocksdb_readoptions_get_io_timeout(ro));
+
rocksdb_readoptions_destroy(ro);
}
rocksdb_cache_destroy(co);
}
+ StartPhase("jemalloc_nodump_allocator");
+ {
+ rocksdb_memory_allocator_t* allocator;
+ allocator = rocksdb_jemalloc_nodump_allocator_create(&err);
+ if (err != NULL) {
+ // not supported on all platforms, allow unsupported error
+ const char* ni = "Not implemented: ";
+ size_t ni_len = strlen(ni);
+ size_t err_len = strlen(err);
+
+ CheckCondition(err_len >= ni_len);
+ CheckCondition(memcmp(ni, err, ni_len) == 0);
+ Free(&err);
+ } else {
+ rocksdb_cache_t* co;
+ rocksdb_lru_cache_options_t* copts;
+
+ copts = rocksdb_lru_cache_options_create();
+
+ rocksdb_lru_cache_options_set_capacity(copts, 100);
+ rocksdb_lru_cache_options_set_memory_allocator(copts, allocator);
+
+ co = rocksdb_cache_create_lru_opts(copts);
+ CheckCondition(100 == rocksdb_cache_get_capacity(co));
+
+ rocksdb_cache_destroy(co);
+ rocksdb_lru_cache_options_destroy(copts);
+ }
+ rocksdb_memory_allocator_destroy(allocator);
+ }
+
StartPhase("env");
{
rocksdb_env_t* e;
rocksdb_fifo_compaction_options_destroy(fco);
}
- StartPhase("backupable_db_option");
+ StartPhase("backup_engine_option");
{
- rocksdb_backupable_db_options_t* bdo;
- bdo = rocksdb_backupable_db_options_create("path");
+ rocksdb_backup_engine_options_t* bdo;
+ bdo = rocksdb_backup_engine_options_create("path");
- rocksdb_backupable_db_options_set_share_table_files(bdo, 1);
+ rocksdb_backup_engine_options_set_share_table_files(bdo, 1);
CheckCondition(1 ==
- rocksdb_backupable_db_options_get_share_table_files(bdo));
+ rocksdb_backup_engine_options_get_share_table_files(bdo));
- rocksdb_backupable_db_options_set_sync(bdo, 1);
- CheckCondition(1 == rocksdb_backupable_db_options_get_sync(bdo));
+ rocksdb_backup_engine_options_set_sync(bdo, 1);
+ CheckCondition(1 == rocksdb_backup_engine_options_get_sync(bdo));
- rocksdb_backupable_db_options_set_destroy_old_data(bdo, 1);
+ rocksdb_backup_engine_options_set_destroy_old_data(bdo, 1);
CheckCondition(1 ==
- rocksdb_backupable_db_options_get_destroy_old_data(bdo));
+ rocksdb_backup_engine_options_get_destroy_old_data(bdo));
- rocksdb_backupable_db_options_set_backup_log_files(bdo, 1);
+ rocksdb_backup_engine_options_set_backup_log_files(bdo, 1);
CheckCondition(1 ==
- rocksdb_backupable_db_options_get_backup_log_files(bdo));
+ rocksdb_backup_engine_options_get_backup_log_files(bdo));
- rocksdb_backupable_db_options_set_backup_rate_limit(bdo, 123);
+ rocksdb_backup_engine_options_set_backup_rate_limit(bdo, 123);
CheckCondition(123 ==
- rocksdb_backupable_db_options_get_backup_rate_limit(bdo));
+ rocksdb_backup_engine_options_get_backup_rate_limit(bdo));
- rocksdb_backupable_db_options_set_restore_rate_limit(bdo, 37);
+ rocksdb_backup_engine_options_set_restore_rate_limit(bdo, 37);
CheckCondition(37 ==
- rocksdb_backupable_db_options_get_restore_rate_limit(bdo));
+ rocksdb_backup_engine_options_get_restore_rate_limit(bdo));
- rocksdb_backupable_db_options_set_max_background_operations(bdo, 20);
+ rocksdb_backup_engine_options_set_max_background_operations(bdo, 20);
CheckCondition(
- 20 == rocksdb_backupable_db_options_get_max_background_operations(bdo));
+ 20 == rocksdb_backup_engine_options_get_max_background_operations(bdo));
- rocksdb_backupable_db_options_set_callback_trigger_interval_size(bdo, 9000);
+ rocksdb_backup_engine_options_set_callback_trigger_interval_size(bdo, 9000);
CheckCondition(
9000 ==
- rocksdb_backupable_db_options_get_callback_trigger_interval_size(bdo));
+ rocksdb_backup_engine_options_get_callback_trigger_interval_size(bdo));
- rocksdb_backupable_db_options_set_max_valid_backups_to_open(bdo, 40);
+ rocksdb_backup_engine_options_set_max_valid_backups_to_open(bdo, 40);
CheckCondition(
- 40 == rocksdb_backupable_db_options_get_max_valid_backups_to_open(bdo));
+ 40 == rocksdb_backup_engine_options_get_max_valid_backups_to_open(bdo));
- rocksdb_backupable_db_options_set_share_files_with_checksum_naming(bdo, 2);
+ rocksdb_backup_engine_options_set_share_files_with_checksum_naming(bdo, 2);
CheckCondition(
- 2 == rocksdb_backupable_db_options_get_share_files_with_checksum_naming(
+ 2 == rocksdb_backup_engine_options_get_share_files_with_checksum_naming(
bdo));
- rocksdb_backupable_db_options_destroy(bdo);
+ rocksdb_backup_engine_options_destroy(bdo);
+ }
+
+ StartPhase("compression_options");
+ {
+ rocksdb_options_t* co;
+ co = rocksdb_options_create();
+
+ rocksdb_options_set_compression_options_zstd_max_train_bytes(co, 100);
+ CheckCondition(
+ 100 ==
+ rocksdb_options_get_compression_options_zstd_max_train_bytes(co));
+
+ rocksdb_options_set_compression_options_parallel_threads(co, 2);
+ CheckCondition(
+ 2 == rocksdb_options_get_compression_options_parallel_threads(co));
+
+ rocksdb_options_set_compression_options_max_dict_buffer_bytes(co, 200);
+ CheckCondition(
+ 200 ==
+ rocksdb_options_get_compression_options_max_dict_buffer_bytes(co));
+
+ rocksdb_options_set_compression_options_use_zstd_dict_trainer(co, 0);
+ CheckCondition(
+ 0 == rocksdb_options_get_compression_options_use_zstd_dict_trainer(co));
+ rocksdb_options_destroy(co);
}
StartPhase("iterate_upper_bound");
db = rocksdb_open(options, dbname, &err);
CheckNoError(err);
- rocksdb_put(db, woptions, "a", 1, "0", 1, &err); CheckNoError(err);
- rocksdb_put(db, woptions, "foo", 3, "bar", 3, &err); CheckNoError(err);
- rocksdb_put(db, woptions, "foo1", 4, "bar1", 4, &err); CheckNoError(err);
- rocksdb_put(db, woptions, "g1", 2, "0", 1, &err); CheckNoError(err);
+ rocksdb_put(db, woptions, "a", 1, "0", 1, &err);
+ CheckNoError(err);
+ rocksdb_put(db, woptions, "foo", 3, "bar", 3, &err);
+ CheckNoError(err);
+ rocksdb_put(db, woptions, "foo1", 4, "bar1", 4, &err);
+ CheckNoError(err);
+ rocksdb_put(db, woptions, "g1", 2, "0", 1, &err);
+ CheckNoError(err);
// testing basic case with no iterate_upper_bound and no prefix_extractor
{
- rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
- rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
+ rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
+ rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
- rocksdb_iter_seek(iter, "foo", 3);
- CheckCondition(rocksdb_iter_valid(iter));
- CheckIter(iter, "foo", "bar");
+ rocksdb_iter_seek(iter, "foo", 3);
+ CheckCondition(rocksdb_iter_valid(iter));
+ CheckIter(iter, "foo", "bar");
- rocksdb_iter_next(iter);
- CheckCondition(rocksdb_iter_valid(iter));
- CheckIter(iter, "foo1", "bar1");
+ rocksdb_iter_next(iter);
+ CheckCondition(rocksdb_iter_valid(iter));
+ CheckIter(iter, "foo1", "bar1");
- rocksdb_iter_next(iter);
- CheckCondition(rocksdb_iter_valid(iter));
- CheckIter(iter, "g1", "0");
+ rocksdb_iter_next(iter);
+ CheckCondition(rocksdb_iter_valid(iter));
+ CheckIter(iter, "g1", "0");
- rocksdb_iter_destroy(iter);
+ rocksdb_iter_destroy(iter);
}
// testing iterate_upper_bound and forward iterator
// to make sure it stops at bound
{
- // iterate_upper_bound points beyond the last expected entry
- rocksdb_readoptions_set_iterate_upper_bound(roptions, "foo2", 4);
+ // iterate_upper_bound points beyond the last expected entry
+ rocksdb_readoptions_set_iterate_upper_bound(roptions, "foo2", 4);
- rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
+ rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
- rocksdb_iter_seek(iter, "foo", 3);
- CheckCondition(rocksdb_iter_valid(iter));
- CheckIter(iter, "foo", "bar");
+ rocksdb_iter_seek(iter, "foo", 3);
+ CheckCondition(rocksdb_iter_valid(iter));
+ CheckIter(iter, "foo", "bar");
- rocksdb_iter_next(iter);
- CheckCondition(rocksdb_iter_valid(iter));
- CheckIter(iter, "foo1", "bar1");
+ rocksdb_iter_next(iter);
+ CheckCondition(rocksdb_iter_valid(iter));
+ CheckIter(iter, "foo1", "bar1");
- rocksdb_iter_next(iter);
- // should stop here...
- CheckCondition(!rocksdb_iter_valid(iter));
+ rocksdb_iter_next(iter);
+ // should stop here...
+ CheckCondition(!rocksdb_iter_valid(iter));
- rocksdb_iter_destroy(iter);
- rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
+ rocksdb_iter_destroy(iter);
+ rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
}
}
rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hello", 5, &err);
CheckNoError(err);
CheckTxnDBGet(txn_db, roptions, "foo", "hello");
+ CheckTxnDBPinGet(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);
+ CheckTxnDBPinGet(txn_db, roptions, "foo", NULL);
// write batch into TransactionDB
rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
rocksdb_transactiondb_write(txn_db, woptions, wb, &err);
rocksdb_writebatch_destroy(wb);
CheckTxnDBGet(txn_db, roptions, "box", "c");
+ CheckTxnDBPinGet(txn_db, roptions, "box", "c");
CheckNoError(err);
+ // multi get
+ {
+ const char* keys[3] = {"box", "foo", "notfound"};
+ const size_t keys_sizes[3] = {3, 3, 8};
+ char* vals[3];
+ size_t vals_sizes[3];
+ char* errs[3];
+ const char* expected[3] = {"c", NULL, NULL};
+ rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
+ vals, vals_sizes, errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
+ }
+
// 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");
+ CheckTxnPinGet(txn, roptions, "foo", "hello");
+ {
+ const char* keys[3] = {"box", "foo", "notfound"};
+ const size_t keys_sizes[3] = {3, 3, 8};
+ char* vals[3];
+ size_t vals_sizes[3];
+ char* errs[3];
+ const char* expected[3] = {"c", "hello", NULL};
+ rocksdb_transaction_multi_get(txn, roptions, 3, keys, keys_sizes, vals,
+ vals_sizes, errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
+ }
// delete
rocksdb_transaction_delete(txn, "foo", 3, &err);
CheckNoError(err);
CheckTxnGet(txn, roptions, "foo", NULL);
+ CheckTxnPinGet(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);
+ CheckTxnDBPinGet(txn_db, roptions, "foo", NULL);
+ {
+ const char* keys[3] = {"box", "foo", "notfound"};
+ const size_t keys_sizes[3] = {3, 3, 8};
+ char* vals[3];
+ size_t vals_sizes[3];
+ char* errs[3];
+ const char* expected[3] = {"c", NULL, NULL};
+ rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
+ vals, vals_sizes, errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
+ }
// commit
rocksdb_transaction_commit(txn, &err);
// read from outside transaction, after commit
CheckTxnDBGet(txn_db, roptions, "foo", "hello");
+ CheckTxnDBPinGet(txn_db, roptions, "foo", "hello");
+ {
+ const char* keys[3] = {"box", "foo", "notfound"};
+ const size_t keys_sizes[3] = {3, 3, 8};
+ char* vals[3];
+ size_t vals_sizes[3];
+ char* errs[3];
+ const char* expected[3] = {"c", "hello", NULL};
+ rocksdb_transactiondb_multi_get(txn_db, roptions, 3, keys, keys_sizes,
+ vals, vals_sizes, errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
+ }
// reuse old transaction
txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, txn);
snapshot = rocksdb_transactiondb_create_snapshot(txn_db);
rocksdb_readoptions_set_snapshot(roptions, snapshot);
- rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
+ rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
CheckNoError(err);
CheckTxnDBGet(txn_db, roptions, "foo", "hello");
+ CheckTxnDBPinGet(txn_db, roptions, "foo", "hello");
rocksdb_readoptions_set_snapshot(roptions, NULL);
rocksdb_transactiondb_release_snapshot(txn_db, snapshot);
CheckTxnDBGet(txn_db, roptions, "foo", "hey");
+ CheckTxnDBPinGet(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);
+ 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));
rocksdb_transaction_rollback(txn, &err);
CheckNoError(err);
CheckTxnDBGet(txn_db, roptions, "bar", NULL);
+ CheckTxnDBPinGet(txn_db, roptions, "bar", NULL);
// save point
rocksdb_transaction_put(txn, "foo1", 4, "hi1", 3, &err);
rocksdb_transaction_set_savepoint(txn);
CheckTxnGet(txn, roptions, "foo1", "hi1");
+ CheckTxnPinGet(txn, roptions, "foo1", "hi1");
rocksdb_transaction_put(txn, "foo2", 4, "hi2", 3, &err);
CheckTxnGet(txn, roptions, "foo2", "hi2");
+ CheckTxnPinGet(txn, roptions, "foo2", "hi2");
// rollback to savepoint
rocksdb_transaction_rollback_to_savepoint(txn, &err);
CheckNoError(err);
CheckTxnGet(txn, roptions, "foo2", NULL);
CheckTxnGet(txn, roptions, "foo1", "hi1");
+ CheckTxnPinGet(txn, roptions, "foo2", NULL);
+ CheckTxnPinGet(txn, roptions, "foo1", "hi1");
CheckTxnDBGet(txn_db, roptions, "foo1", NULL);
CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
+ CheckTxnDBPinGet(txn_db, roptions, "foo1", NULL);
+ CheckTxnDBPinGet(txn_db, roptions, "foo2", NULL);
rocksdb_transaction_commit(txn, &err);
CheckNoError(err);
CheckTxnDBGet(txn_db, roptions, "foo1", "hi1");
CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
+ CheckTxnDBPinGet(txn_db, roptions, "foo1", "hi1");
+ CheckTxnDBPinGet(txn_db, roptions, "foo2", NULL);
// Column families.
rocksdb_column_family_handle_t* cfh;
8, &err);
CheckNoError(err);
CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
+ CheckTxnDBPinGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
+ {
+ const rocksdb_column_family_handle_t* get_handles[2] = {cfh, cfh};
+ const char* keys[2] = {"cf_foo", "notfound"};
+ const size_t keys_sizes[2] = {6, 8};
+ char* vals[2];
+ size_t vals_sizes[2];
+ char* errs[2];
+ const char* expected[2] = {"cf_hello", NULL};
+ rocksdb_transactiondb_multi_get_cf(txn_db, roptions, get_handles, 2, keys,
+ keys_sizes, vals, vals_sizes, errs);
+ CheckMultiGetValues(2, vals, vals_sizes, errs, expected);
+ }
rocksdb_transactiondb_delete_cf(txn_db, woptions, cfh, "cf_foo", 6, &err);
CheckNoError(err);
CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
+ CheckTxnDBPinGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
- rocksdb_column_family_handle_destroy(cfh);
+ // flush
+ rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
+ rocksdb_flushoptions_set_wait(flush_options, 1);
+ rocksdb_transactiondb_flush_wal(txn_db, 1, &err);
+ CheckNoError(err);
+ rocksdb_transactiondb_flush_cf(txn_db, flush_options, cfh, &err);
+ CheckNoError(err);
+ rocksdb_transactiondb_flush(txn_db, flush_options, &err);
+ CheckNoError(err);
+ rocksdb_flushoptions_destroy(flush_options);
// close and destroy
+ rocksdb_column_family_handle_destroy(cfh);
rocksdb_transaction_destroy(txn);
rocksdb_transactiondb_close(txn_db);
rocksdb_destroy_db(options, dbname, &err);
rocksdb_transactiondb_options_destroy(txn_db_options);
}
+ StartPhase("two-phase commit");
+ {
+ // 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);
+
+ rocksdb_transaction_options_set_skip_prepare(txn_options, 0);
+ txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
+ rocksdb_transaction_commit(txn, &err);
+ CheckCondition(err != NULL);
+ Free(&err);
+ err = NULL;
+ rocksdb_transaction_prepare(txn, &err);
+ CheckCondition(err != NULL);
+ Free(&err);
+ err = NULL;
+ rocksdb_transaction_set_name(txn, "txn1", 4, &err);
+ CheckNoError(err);
+ rocksdb_transaction_prepare(txn, &err);
+ CheckNoError(err);
+ rocksdb_transaction_commit(txn, &err);
+ CheckNoError(err);
+ rocksdb_transaction_destroy(txn);
+
+ // prepare 2 transactions and close db.
+ rocksdb_transaction_t* txn1 =
+ rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
+ rocksdb_transaction_put(txn1, "bar1", 4, "1", 1, &err);
+ CheckNoError(err);
+ rocksdb_transaction_set_name(txn1, "txn1", 4, &err);
+ CheckNoError(err);
+ rocksdb_transaction_prepare(txn1, &err);
+ CheckNoError(err);
+ rocksdb_transaction_t* txn2 =
+ rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
+ rocksdb_transaction_put(txn2, "bar2", 4, "2", 1, &err);
+ CheckNoError(err);
+ rocksdb_transaction_set_name(txn2, "txn2", 4, &err);
+ CheckNoError(err);
+ rocksdb_transaction_prepare(txn2, &err);
+ CheckNoError(err);
+ rocksdb_transaction_destroy(txn1);
+ rocksdb_transaction_destroy(txn2);
+ rocksdb_transactiondb_close(txn_db);
+ rocksdb_transaction_options_destroy(txn_options);
+ rocksdb_transactiondb_options_destroy(txn_db_options);
+
+ // reopen db and get all prepared.
+ txn_db_options = rocksdb_transactiondb_options_create();
+ txn_options = rocksdb_transaction_options_create();
+ rocksdb_options_set_error_if_exists(options, 0);
+ txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
+ CheckNoError(err);
+ CheckTxnDBPinGet(txn_db, roptions, "bar1", NULL);
+ CheckTxnDBPinGet(txn_db, roptions, "bar2", NULL);
+ size_t cnt;
+ rocksdb_transaction_t** txns =
+ rocksdb_transactiondb_get_prepared_transactions(txn_db, &cnt);
+ CheckCondition(cnt == 2);
+ size_t i;
+ for (i = 0; i < cnt; i++) {
+ txn = txns[i];
+ size_t name_len = 0;
+ char* name = rocksdb_transaction_get_name(txn, &name_len);
+ CheckCondition(name_len == 4);
+ if (strncmp(name, "txn1", name_len) == 0) {
+ rocksdb_transaction_commit(txn, &err);
+ } else if (strncmp(name, "txn2", name_len) == 0) {
+ rocksdb_transaction_rollback(txn, &err);
+ }
+ rocksdb_free(name);
+ CheckNoError(err);
+ rocksdb_transaction_destroy(txn);
+ }
+ rocksdb_free(txns);
+ CheckTxnDBGet(txn_db, roptions, "bar1", "1");
+ CheckTxnDBGet(txn_db, roptions, "bar2", NULL);
+ rocksdb_transactiondb_put(txn_db, woptions, "bar2", 4, "2", 1, &err);
+ CheckNoError(err);
+
+ // close and destroy
+ 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);
+ }
+
StartPhase("optimistic_transactions");
{
rocksdb_options_t* db_options = rocksdb_options_create();
rocksdb_transaction_put(txn2, "key1", 4, "value1", 6, &err);
CheckNoError(err);
CheckTxnGet(txn1, roptions, "key", "value");
+ CheckTxnPinGet(txn1, roptions, "key", "value");
rocksdb_transaction_commit(txn1, &err);
CheckNoError(err);
rocksdb_transaction_commit(txn2, &err);
txn);
CheckGetCF(db, roptions, cfh1, "key_cf1", "val_cf1");
CheckTxnGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
+ CheckTxnPinGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
+ {
+ const rocksdb_column_family_handle_t* get_handles[3] = {cfh1, cfh2, cfh2};
+ const char* keys[3] = {"key_cf1", "key_cf2", "notfound"};
+ const size_t keys_sizes[3] = {7, 7, 8};
+ char* vals[3];
+ size_t vals_sizes[3];
+ char* errs[3];
+ const char* expected[3] = {"val_cf1", "val_cf2", NULL};
+ rocksdb_transaction_multi_get_cf(txn, roptions, get_handles, 3, keys,
+ keys_sizes, vals, vals_sizes, errs);
+ CheckMultiGetValues(3, vals, vals_sizes, errs, expected);
+ }
// Check iterator with column family
rocksdb_transaction_put_cf(txn, cfh1, "key1_cf", 7, "val1_cf", 7, &err);
CheckTxnGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
CheckTxnGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
CheckTxnGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
+ CheckTxnPinGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
+ CheckTxnPinGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
+ CheckTxnPinGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
rocksdb_transaction_destroy(txn_cf);
rocksdb_options_destroy(cf_options);
rocksdb_column_family_handle_destroy(cf_handles[0]);
CheckNoError(err);
}
+ StartPhase("filter_with_prefix_seek");
+ {
+ rocksdb_close(db);
+ rocksdb_destroy_db(options, dbname, &err);
+ CheckNoError(err);
+
+ rocksdb_options_set_prefix_extractor(
+ options, rocksdb_slicetransform_create_fixed_prefix(1));
+ rocksdb_filterpolicy_t* filter_policy =
+ rocksdb_filterpolicy_create_bloom_full(8.0);
+ rocksdb_block_based_options_set_filter_policy(table_options, filter_policy);
+ rocksdb_options_set_block_based_table_factory(options, table_options);
+
+ db = rocksdb_open(options, dbname, &err);
+ CheckNoError(err);
+
+ int i;
+ for (i = 0; i < 10; ++i) {
+ char key = '0' + (char)i;
+ rocksdb_put(db, woptions, &key, 1, "", 1, &err);
+ CheckNoError(err);
+ }
+
+ // Flush to generate an L0 so that filter will be used later.
+ rocksdb_flushoptions_t* flush_options = rocksdb_flushoptions_create();
+ rocksdb_flushoptions_set_wait(flush_options, 1);
+ rocksdb_flush(db, flush_options, &err);
+ rocksdb_flushoptions_destroy(flush_options);
+ CheckNoError(err);
+
+ rocksdb_readoptions_t* ropts = rocksdb_readoptions_create();
+ rocksdb_iterator_t* iter = rocksdb_create_iterator(db, ropts);
+
+ rocksdb_iter_seek(iter, "0", 1);
+ int cnt = 0;
+ while (rocksdb_iter_valid(iter)) {
+ ++cnt;
+ rocksdb_iter_next(iter);
+ }
+ CheckCondition(10 == cnt);
+
+ rocksdb_iter_destroy(iter);
+ rocksdb_readoptions_destroy(ropts);
+ }
+
StartPhase("cancel_all_background_work");
rocksdb_cancel_all_background_work(db, 1);
#else
-int main() {
+int main(void) {
fprintf(stderr, "SKIPPED\n");
return 0;
}