1 /* Copyright (c) 2011 The LevelDB Authors. All rights reserved.
2 Use of this source code is governed by a BSD-style license that can be
3 found in the LICENSE file. See the AUTHORS file for names of contributors. */
4 // Copyright (c) Facebook, Inc. and its affiliates. All Rights Reserved.
5
6 #include <stdio.h>
7
8 #ifndef ROCKSDB_LITE // Lite does not support C API
9
10 #include "rocksdb/c.h"
11
12 #include <stddef.h>
13 #include <stdlib.h>
14 #include <string.h>
15 #include <sys/types.h>
16 #ifndef OS_WIN
17 #include <unistd.h>
18 #endif
19 #include <inttypes.h>
20
21 // Can not use port/port.h macros as this is a c file
22 #ifdef OS_WIN
23 #include <windows.h>
24
25 // Ok for uniqueness
geteuid()26 int geteuid() {
27 int result = 0;
28
29 result = ((int)GetCurrentProcessId() << 16);
30 result |= (int)GetCurrentThreadId();
31
32 return result;
33 }
34
35 // VS < 2015
36 #if defined(_MSC_VER) && (_MSC_VER < 1900)
37 #define snprintf _snprintf
38 #endif
39
40 #endif
41
42 const char* phase = "";
43 static char dbname[200];
44 static char sstfilename[200];
45 static char dbbackupname[200];
46 static char dbcheckpointname[200];
47 static char dbpathname[200];
48 static char secondary_path[200];
49
StartPhase(const char * name)50 static void StartPhase(const char* name) {
51 fprintf(stderr, "=== Test %s\n", name);
52 phase = name;
53 }
54 #ifdef _MSC_VER
55 #pragma warning(push)
56 #pragma warning (disable: 4996) // getenv security warning
57 #endif
GetTempDir(void)58 static const char* GetTempDir(void) {
59 const char* ret = getenv("TEST_TMPDIR");
60 if (ret == NULL || ret[0] == '\0')
61 #ifdef OS_WIN
62 ret = getenv("TEMP");
63 #else
64 ret = "/tmp";
65 #endif
66 return ret;
67 }
68 #ifdef _MSC_VER
69 #pragma warning(pop)
70 #endif
71
72 #define CheckNoError(err) \
73 if ((err) != NULL) { \
74 fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
75 abort(); \
76 }
77
78 #define CheckCondition(cond) \
79 if (!(cond)) { \
80 fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \
81 abort(); \
82 }
83
CheckEqual(const char * expected,const char * v,size_t n)84 static void CheckEqual(const char* expected, const char* v, size_t n) {
85 if (expected == NULL && v == NULL) {
86 // ok
87 } else if (expected != NULL && v != NULL && n == strlen(expected) &&
88 memcmp(expected, v, n) == 0) {
89 // ok
90 return;
91 } else {
92 fprintf(stderr, "%s: expected '%s', got '%s'\n",
93 phase,
94 (expected ? expected : "(null)"),
95 (v ? v : "(null"));
96 abort();
97 }
98 }
99
Free(char ** ptr)100 static void Free(char** ptr) {
101 if (*ptr) {
102 free(*ptr);
103 *ptr = NULL;
104 }
105 }
106
CheckValue(char * err,const char * expected,char ** actual,size_t actual_length)107 static void CheckValue(
108 char* err,
109 const char* expected,
110 char** actual,
111 size_t actual_length) {
112 CheckNoError(err);
113 CheckEqual(expected, *actual, actual_length);
114 Free(actual);
115 }
116
CheckGet(rocksdb_t * db,const rocksdb_readoptions_t * options,const char * key,const char * expected)117 static void CheckGet(
118 rocksdb_t* db,
119 const rocksdb_readoptions_t* options,
120 const char* key,
121 const char* expected) {
122 char* err = NULL;
123 size_t val_len;
124 char* val;
125 val = rocksdb_get(db, options, key, strlen(key), &val_len, &err);
126 CheckNoError(err);
127 CheckEqual(expected, val, val_len);
128 Free(&val);
129 }
130
CheckGetCF(rocksdb_t * db,const rocksdb_readoptions_t * options,rocksdb_column_family_handle_t * handle,const char * key,const char * expected)131 static void CheckGetCF(
132 rocksdb_t* db,
133 const rocksdb_readoptions_t* options,
134 rocksdb_column_family_handle_t* handle,
135 const char* key,
136 const char* expected) {
137 char* err = NULL;
138 size_t val_len;
139 char* val;
140 val = rocksdb_get_cf(db, options, handle, key, strlen(key), &val_len, &err);
141 CheckNoError(err);
142 CheckEqual(expected, val, val_len);
143 Free(&val);
144 }
145
CheckPinGet(rocksdb_t * db,const rocksdb_readoptions_t * options,const char * key,const char * expected)146 static void CheckPinGet(rocksdb_t* db, const rocksdb_readoptions_t* options,
147 const char* key, const char* expected) {
148 char* err = NULL;
149 size_t val_len;
150 const char* val;
151 rocksdb_pinnableslice_t* p;
152 p = rocksdb_get_pinned(db, options, key, strlen(key), &err);
153 CheckNoError(err);
154 val = rocksdb_pinnableslice_value(p, &val_len);
155 CheckEqual(expected, val, val_len);
156 rocksdb_pinnableslice_destroy(p);
157 }
158
CheckPinGetCF(rocksdb_t * db,const rocksdb_readoptions_t * options,rocksdb_column_family_handle_t * handle,const char * key,const char * expected)159 static void CheckPinGetCF(rocksdb_t* db, const rocksdb_readoptions_t* options,
160 rocksdb_column_family_handle_t* handle,
161 const char* key, const char* expected) {
162 char* err = NULL;
163 size_t val_len;
164 const char* val;
165 rocksdb_pinnableslice_t* p;
166 p = rocksdb_get_pinned_cf(db, options, handle, key, strlen(key), &err);
167 CheckNoError(err);
168 val = rocksdb_pinnableslice_value(p, &val_len);
169 CheckEqual(expected, val, val_len);
170 rocksdb_pinnableslice_destroy(p);
171 }
172
CheckIter(rocksdb_iterator_t * iter,const char * key,const char * val)173 static void CheckIter(rocksdb_iterator_t* iter,
174 const char* key, const char* val) {
175 size_t len;
176 const char* str;
177 str = rocksdb_iter_key(iter, &len);
178 CheckEqual(key, str, len);
179 str = rocksdb_iter_value(iter, &len);
180 CheckEqual(val, str, len);
181 }
182
183 // Callback from rocksdb_writebatch_iterate()
CheckPut(void * ptr,const char * k,size_t klen,const char * v,size_t vlen)184 static void CheckPut(void* ptr,
185 const char* k, size_t klen,
186 const char* v, size_t vlen) {
187 int* state = (int*) ptr;
188 CheckCondition(*state < 2);
189 switch (*state) {
190 case 0:
191 CheckEqual("bar", k, klen);
192 CheckEqual("b", v, vlen);
193 break;
194 case 1:
195 CheckEqual("box", k, klen);
196 CheckEqual("c", v, vlen);
197 break;
198 }
199 (*state)++;
200 }
201
202 // Callback from rocksdb_writebatch_iterate()
CheckDel(void * ptr,const char * k,size_t klen)203 static void CheckDel(void* ptr, const char* k, size_t klen) {
204 int* state = (int*) ptr;
205 CheckCondition(*state == 2);
206 CheckEqual("bar", k, klen);
207 (*state)++;
208 }
209
CmpDestroy(void * arg)210 static void CmpDestroy(void* arg) { (void)arg; }
211
CmpCompare(void * arg,const char * a,size_t alen,const char * b,size_t blen)212 static int CmpCompare(void* arg, const char* a, size_t alen,
213 const char* b, size_t blen) {
214 (void)arg;
215 size_t n = (alen < blen) ? alen : blen;
216 int r = memcmp(a, b, n);
217 if (r == 0) {
218 if (alen < blen) r = -1;
219 else if (alen > blen) r = +1;
220 }
221 return r;
222 }
223
CmpName(void * arg)224 static const char* CmpName(void* arg) {
225 (void)arg;
226 return "foo";
227 }
228
229 // Custom filter policy
230 static unsigned char fake_filter_result = 1;
FilterDestroy(void * arg)231 static void FilterDestroy(void* arg) { (void)arg; }
FilterName(void * arg)232 static const char* FilterName(void* arg) {
233 (void)arg;
234 return "TestFilter";
235 }
FilterCreate(void * arg,const char * const * key_array,const size_t * key_length_array,int num_keys,size_t * filter_length)236 static char* FilterCreate(
237 void* arg,
238 const char* const* key_array, const size_t* key_length_array,
239 int num_keys,
240 size_t* filter_length) {
241 (void)arg;
242 (void)key_array;
243 (void)key_length_array;
244 (void)num_keys;
245 *filter_length = 4;
246 char* result = malloc(4);
247 memcpy(result, "fake", 4);
248 return result;
249 }
FilterKeyMatch(void * arg,const char * key,size_t length,const char * filter,size_t filter_length)250 static unsigned char FilterKeyMatch(
251 void* arg,
252 const char* key, size_t length,
253 const char* filter, size_t filter_length) {
254 (void)arg;
255 (void)key;
256 (void)length;
257 CheckCondition(filter_length == 4);
258 CheckCondition(memcmp(filter, "fake", 4) == 0);
259 return fake_filter_result;
260 }
261
262 // Custom compaction filter
CFilterDestroy(void * arg)263 static void CFilterDestroy(void* arg) { (void)arg; }
CFilterName(void * arg)264 static const char* CFilterName(void* arg) {
265 (void)arg;
266 return "foo";
267 }
CFilterFilter(void * arg,int level,const char * key,size_t key_length,const char * existing_value,size_t value_length,char ** new_value,size_t * new_value_length,unsigned char * value_changed)268 static unsigned char CFilterFilter(void* arg, int level, const char* key,
269 size_t key_length,
270 const char* existing_value,
271 size_t value_length, char** new_value,
272 size_t* new_value_length,
273 unsigned char* value_changed) {
274 (void)arg;
275 (void)level;
276 (void)existing_value;
277 (void)value_length;
278 if (key_length == 3) {
279 if (memcmp(key, "bar", key_length) == 0) {
280 return 1;
281 } else if (memcmp(key, "baz", key_length) == 0) {
282 *value_changed = 1;
283 *new_value = "newbazvalue";
284 *new_value_length = 11;
285 return 0;
286 }
287 }
288 return 0;
289 }
290
CFilterFactoryDestroy(void * arg)291 static void CFilterFactoryDestroy(void* arg) { (void)arg; }
CFilterFactoryName(void * arg)292 static const char* CFilterFactoryName(void* arg) {
293 (void)arg;
294 return "foo";
295 }
CFilterCreate(void * arg,rocksdb_compactionfiltercontext_t * context)296 static rocksdb_compactionfilter_t* CFilterCreate(
297 void* arg, rocksdb_compactionfiltercontext_t* context) {
298 (void)arg;
299 (void)context;
300 return rocksdb_compactionfilter_create(NULL, CFilterDestroy, CFilterFilter,
301 CFilterName);
302 }
303
CheckCompaction(rocksdb_t * db,rocksdb_options_t * options,rocksdb_readoptions_t * roptions,rocksdb_writeoptions_t * woptions)304 static rocksdb_t* CheckCompaction(rocksdb_t* db, rocksdb_options_t* options,
305 rocksdb_readoptions_t* roptions,
306 rocksdb_writeoptions_t* woptions) {
307 char* err = NULL;
308 db = rocksdb_open(options, dbname, &err);
309 CheckNoError(err);
310 rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
311 CheckNoError(err);
312 CheckGet(db, roptions, "foo", "foovalue");
313 rocksdb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
314 CheckNoError(err);
315 CheckGet(db, roptions, "bar", "barvalue");
316 rocksdb_put(db, woptions, "baz", 3, "bazvalue", 8, &err);
317 CheckNoError(err);
318 CheckGet(db, roptions, "baz", "bazvalue");
319
320 // Force compaction
321 rocksdb_compact_range(db, NULL, 0, NULL, 0);
322 // should have filtered bar, but not foo
323 CheckGet(db, roptions, "foo", "foovalue");
324 CheckGet(db, roptions, "bar", NULL);
325 CheckGet(db, roptions, "baz", "newbazvalue");
326 return db;
327 }
328
329 // Custom merge operator
MergeOperatorDestroy(void * arg)330 static void MergeOperatorDestroy(void* arg) { (void)arg; }
MergeOperatorName(void * arg)331 static const char* MergeOperatorName(void* arg) {
332 (void)arg;
333 return "TestMergeOperator";
334 }
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,unsigned char * success,size_t * new_value_length)335 static char* MergeOperatorFullMerge(
336 void* arg,
337 const char* key, size_t key_length,
338 const char* existing_value, size_t existing_value_length,
339 const char* const* operands_list, const size_t* operands_list_length,
340 int num_operands,
341 unsigned char* success, size_t* new_value_length) {
342 (void)arg;
343 (void)key;
344 (void)key_length;
345 (void)existing_value;
346 (void)existing_value_length;
347 (void)operands_list;
348 (void)operands_list_length;
349 (void)num_operands;
350 *new_value_length = 4;
351 *success = 1;
352 char* result = malloc(4);
353 memcpy(result, "fake", 4);
354 return result;
355 }
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)356 static char* MergeOperatorPartialMerge(
357 void* arg,
358 const char* key, size_t key_length,
359 const char* const* operands_list, const size_t* operands_list_length,
360 int num_operands,
361 unsigned char* success, size_t* new_value_length) {
362 (void)arg;
363 (void)key;
364 (void)key_length;
365 (void)operands_list;
366 (void)operands_list_length;
367 (void)num_operands;
368 *new_value_length = 4;
369 *success = 1;
370 char* result = malloc(4);
371 memcpy(result, "fake", 4);
372 return result;
373 }
374
CheckTxnGet(rocksdb_transaction_t * txn,const rocksdb_readoptions_t * options,const char * key,const char * expected)375 static void CheckTxnGet(
376 rocksdb_transaction_t* txn,
377 const rocksdb_readoptions_t* options,
378 const char* key,
379 const char* expected) {
380 char* err = NULL;
381 size_t val_len;
382 char* val;
383 val = rocksdb_transaction_get(txn, options, key, strlen(key), &val_len, &err);
384 CheckNoError(err);
385 CheckEqual(expected, val, val_len);
386 Free(&val);
387 }
388
CheckTxnGetCF(rocksdb_transaction_t * txn,const rocksdb_readoptions_t * options,rocksdb_column_family_handle_t * column_family,const char * key,const char * expected)389 static void CheckTxnGetCF(rocksdb_transaction_t* txn,
390 const rocksdb_readoptions_t* options,
391 rocksdb_column_family_handle_t* column_family,
392 const char* key, const char* expected) {
393 char* err = NULL;
394 size_t val_len;
395 char* val;
396 val = rocksdb_transaction_get_cf(txn, options, column_family, key,
397 strlen(key), &val_len, &err);
398 CheckNoError(err);
399 CheckEqual(expected, val, val_len);
400 Free(&val);
401 }
402
CheckTxnDBGet(rocksdb_transactiondb_t * txn_db,const rocksdb_readoptions_t * options,const char * key,const char * expected)403 static void CheckTxnDBGet(
404 rocksdb_transactiondb_t* txn_db,
405 const rocksdb_readoptions_t* options,
406 const char* key,
407 const char* expected) {
408 char* err = NULL;
409 size_t val_len;
410 char* val;
411 val = rocksdb_transactiondb_get(txn_db, options, key, strlen(key), &val_len, &err);
412 CheckNoError(err);
413 CheckEqual(expected, val, val_len);
414 Free(&val);
415 }
416
CheckTxnDBGetCF(rocksdb_transactiondb_t * txn_db,const rocksdb_readoptions_t * options,rocksdb_column_family_handle_t * column_family,const char * key,const char * expected)417 static void CheckTxnDBGetCF(rocksdb_transactiondb_t* txn_db,
418 const rocksdb_readoptions_t* options,
419 rocksdb_column_family_handle_t* column_family,
420 const char* key, const char* expected) {
421 char* err = NULL;
422 size_t val_len;
423 char* val;
424 val = rocksdb_transactiondb_get_cf(txn_db, options, column_family, key,
425 strlen(key), &val_len, &err);
426 CheckNoError(err);
427 CheckEqual(expected, val, val_len);
428 Free(&val);
429 }
430
main(int argc,char ** argv)431 int main(int argc, char** argv) {
432 (void)argc;
433 (void)argv;
434 rocksdb_t* db;
435 rocksdb_comparator_t* cmp;
436 rocksdb_cache_t* cache;
437 rocksdb_dbpath_t *dbpath;
438 rocksdb_env_t* env;
439 rocksdb_options_t* options;
440 rocksdb_compactoptions_t* coptions;
441 rocksdb_block_based_table_options_t* table_options;
442 rocksdb_readoptions_t* roptions;
443 rocksdb_writeoptions_t* woptions;
444 rocksdb_ratelimiter_t* rate_limiter;
445 rocksdb_transactiondb_t* txn_db;
446 rocksdb_transactiondb_options_t* txn_db_options;
447 rocksdb_transaction_t* txn;
448 rocksdb_transaction_options_t* txn_options;
449 rocksdb_optimistictransactiondb_t* otxn_db;
450 rocksdb_optimistictransaction_options_t* otxn_options;
451 char* err = NULL;
452 int run = -1;
453
454 snprintf(dbname, sizeof(dbname),
455 "%s/rocksdb_c_test-%d",
456 GetTempDir(),
457 ((int) geteuid()));
458
459 snprintf(dbbackupname, sizeof(dbbackupname),
460 "%s/rocksdb_c_test-%d-backup",
461 GetTempDir(),
462 ((int) geteuid()));
463
464 snprintf(dbcheckpointname, sizeof(dbcheckpointname),
465 "%s/rocksdb_c_test-%d-checkpoint",
466 GetTempDir(),
467 ((int) geteuid()));
468
469 snprintf(sstfilename, sizeof(sstfilename),
470 "%s/rocksdb_c_test-%d-sst",
471 GetTempDir(),
472 ((int)geteuid()));
473
474 snprintf(dbpathname, sizeof(dbpathname),
475 "%s/rocksdb_c_test-%d-dbpath",
476 GetTempDir(),
477 ((int) geteuid()));
478
479 StartPhase("create_objects");
480 cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
481 dbpath = rocksdb_dbpath_create(dbpathname, 1024 * 1024);
482 env = rocksdb_create_default_env();
483 cache = rocksdb_cache_create_lru(100000);
484
485 options = rocksdb_options_create();
486 rocksdb_options_set_comparator(options, cmp);
487 rocksdb_options_set_error_if_exists(options, 1);
488 rocksdb_options_set_env(options, env);
489 rocksdb_options_set_info_log(options, NULL);
490 rocksdb_options_set_write_buffer_size(options, 100000);
491 rocksdb_options_set_paranoid_checks(options, 1);
492 rocksdb_options_set_max_open_files(options, 10);
493 rocksdb_options_set_base_background_compactions(options, 1);
494
495 table_options = rocksdb_block_based_options_create();
496 rocksdb_block_based_options_set_block_cache(table_options, cache);
497 rocksdb_block_based_options_set_data_block_index_type(table_options, 1);
498 rocksdb_block_based_options_set_data_block_hash_ratio(table_options, 0.75);
499 rocksdb_options_set_block_based_table_factory(options, table_options);
500
501 rocksdb_options_set_compression(options, rocksdb_no_compression);
502 rocksdb_options_set_compression_options(options, -14, -1, 0, 0);
503 int compression_levels[] = {rocksdb_no_compression, rocksdb_no_compression,
504 rocksdb_no_compression, rocksdb_no_compression};
505 rocksdb_options_set_compression_per_level(options, compression_levels, 4);
506 rate_limiter = rocksdb_ratelimiter_create(1000 * 1024 * 1024, 100 * 1000, 10);
507 rocksdb_options_set_ratelimiter(options, rate_limiter);
508 rocksdb_ratelimiter_destroy(rate_limiter);
509
510 roptions = rocksdb_readoptions_create();
511 rocksdb_readoptions_set_verify_checksums(roptions, 1);
512 rocksdb_readoptions_set_fill_cache(roptions, 1);
513
514 woptions = rocksdb_writeoptions_create();
515 rocksdb_writeoptions_set_sync(woptions, 1);
516
517 coptions = rocksdb_compactoptions_create();
518 rocksdb_compactoptions_set_exclusive_manual_compaction(coptions, 1);
519
520 rocksdb_options_add_compact_on_deletion_collector_factory(options, 10000,
521 10001);
522
523 StartPhase("destroy");
524 rocksdb_destroy_db(options, dbname, &err);
525 Free(&err);
526
527 StartPhase("open_error");
528 rocksdb_open(options, dbname, &err);
529 CheckCondition(err != NULL);
530 Free(&err);
531
532 StartPhase("open");
533 rocksdb_options_set_create_if_missing(options, 1);
534 db = rocksdb_open(options, dbname, &err);
535 CheckNoError(err);
536 CheckGet(db, roptions, "foo", NULL);
537
538 StartPhase("put");
539 rocksdb_put(db, woptions, "foo", 3, "hello", 5, &err);
540 CheckNoError(err);
541 CheckGet(db, roptions, "foo", "hello");
542
543 StartPhase("backup_and_restore");
544 {
545 rocksdb_destroy_db(options, dbbackupname, &err);
546 CheckNoError(err);
547
548 rocksdb_backup_engine_t *be = rocksdb_backup_engine_open(options, dbbackupname, &err);
549 CheckNoError(err);
550
551 rocksdb_backup_engine_create_new_backup(be, db, &err);
552 CheckNoError(err);
553
554 // need a change to trigger a new backup
555 rocksdb_delete(db, woptions, "does-not-exist", 14, &err);
556 CheckNoError(err);
557
558 rocksdb_backup_engine_create_new_backup(be, db, &err);
559 CheckNoError(err);
560
561 const rocksdb_backup_engine_info_t* bei = rocksdb_backup_engine_get_backup_info(be);
562 CheckCondition(rocksdb_backup_engine_info_count(bei) > 1);
563 rocksdb_backup_engine_info_destroy(bei);
564
565 rocksdb_backup_engine_purge_old_backups(be, 1, &err);
566 CheckNoError(err);
567
568 bei = rocksdb_backup_engine_get_backup_info(be);
569 CheckCondition(rocksdb_backup_engine_info_count(bei) == 1);
570 rocksdb_backup_engine_info_destroy(bei);
571
572 rocksdb_delete(db, woptions, "foo", 3, &err);
573 CheckNoError(err);
574
575 rocksdb_close(db);
576
577 rocksdb_destroy_db(options, dbname, &err);
578 CheckNoError(err);
579
580 rocksdb_restore_options_t *restore_options = rocksdb_restore_options_create();
581 rocksdb_restore_options_set_keep_log_files(restore_options, 0);
582 rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname, restore_options, &err);
583 CheckNoError(err);
584 rocksdb_restore_options_destroy(restore_options);
585
586 rocksdb_options_set_error_if_exists(options, 0);
587 db = rocksdb_open(options, dbname, &err);
588 CheckNoError(err);
589 rocksdb_options_set_error_if_exists(options, 1);
590
591 CheckGet(db, roptions, "foo", "hello");
592
593 rocksdb_backup_engine_close(be);
594 }
595
596 StartPhase("checkpoint");
597 {
598 rocksdb_destroy_db(options, dbcheckpointname, &err);
599 CheckNoError(err);
600
601 rocksdb_checkpoint_t* checkpoint = rocksdb_checkpoint_object_create(db, &err);
602 CheckNoError(err);
603
604 rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err);
605 CheckNoError(err);
606
607 // start a new database from the checkpoint
608 rocksdb_close(db);
609 rocksdb_options_set_error_if_exists(options, 0);
610 db = rocksdb_open(options, dbcheckpointname, &err);
611 CheckNoError(err);
612
613 CheckGet(db, roptions, "foo", "hello");
614
615 rocksdb_checkpoint_object_destroy(checkpoint);
616
617 rocksdb_close(db);
618 rocksdb_destroy_db(options, dbcheckpointname, &err);
619 CheckNoError(err);
620
621 db = rocksdb_open(options, dbname, &err);
622 CheckNoError(err);
623 rocksdb_options_set_error_if_exists(options, 1);
624 }
625
626 StartPhase("compactall");
627 rocksdb_compact_range(db, NULL, 0, NULL, 0);
628 CheckGet(db, roptions, "foo", "hello");
629
630 StartPhase("compactrange");
631 rocksdb_compact_range(db, "a", 1, "z", 1);
632 CheckGet(db, roptions, "foo", "hello");
633
634 StartPhase("compactallopt");
635 rocksdb_compact_range_opt(db, coptions, NULL, 0, NULL, 0);
636 CheckGet(db, roptions, "foo", "hello");
637
638 StartPhase("compactrangeopt");
639 rocksdb_compact_range_opt(db, coptions, "a", 1, "z", 1);
640 CheckGet(db, roptions, "foo", "hello");
641
642 // Simple check cache usage
643 StartPhase("cache_usage");
644 {
645 rocksdb_readoptions_set_pin_data(roptions, 1);
646 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
647 rocksdb_iter_seek(iter, "foo", 3);
648
649 size_t usage = rocksdb_cache_get_usage(cache);
650 CheckCondition(usage > 0);
651
652 size_t pin_usage = rocksdb_cache_get_pinned_usage(cache);
653 CheckCondition(pin_usage > 0);
654
655 rocksdb_iter_next(iter);
656 rocksdb_iter_destroy(iter);
657 rocksdb_readoptions_set_pin_data(roptions, 0);
658 }
659
660 StartPhase("addfile");
661 {
662 rocksdb_envoptions_t* env_opt = rocksdb_envoptions_create();
663 rocksdb_options_t* io_options = rocksdb_options_create();
664 rocksdb_sstfilewriter_t* writer =
665 rocksdb_sstfilewriter_create(env_opt, io_options);
666
667 remove(sstfilename);
668 rocksdb_sstfilewriter_open(writer, sstfilename, &err);
669 CheckNoError(err);
670 rocksdb_sstfilewriter_put(writer, "sstk1", 5, "v1", 2, &err);
671 CheckNoError(err);
672 rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v2", 2, &err);
673 CheckNoError(err);
674 rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v3", 2, &err);
675 CheckNoError(err);
676 rocksdb_sstfilewriter_finish(writer, &err);
677 CheckNoError(err);
678
679 rocksdb_ingestexternalfileoptions_t* ing_opt =
680 rocksdb_ingestexternalfileoptions_create();
681 const char* file_list[1] = {sstfilename};
682 rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
683 CheckNoError(err);
684 CheckGet(db, roptions, "sstk1", "v1");
685 CheckGet(db, roptions, "sstk2", "v2");
686 CheckGet(db, roptions, "sstk3", "v3");
687
688 remove(sstfilename);
689 rocksdb_sstfilewriter_open(writer, sstfilename, &err);
690 CheckNoError(err);
691 rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v4", 2, &err);
692 CheckNoError(err);
693 rocksdb_sstfilewriter_put(writer, "sstk22", 6, "v5", 2, &err);
694 CheckNoError(err);
695 rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v6", 2, &err);
696 CheckNoError(err);
697 rocksdb_sstfilewriter_finish(writer, &err);
698 CheckNoError(err);
699
700 rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
701 CheckNoError(err);
702 CheckGet(db, roptions, "sstk1", "v1");
703 CheckGet(db, roptions, "sstk2", "v4");
704 CheckGet(db, roptions, "sstk22", "v5");
705 CheckGet(db, roptions, "sstk3", "v6");
706
707 rocksdb_ingestexternalfileoptions_destroy(ing_opt);
708 rocksdb_sstfilewriter_destroy(writer);
709 rocksdb_options_destroy(io_options);
710 rocksdb_envoptions_destroy(env_opt);
711
712 // Delete all keys we just ingested
713 rocksdb_delete(db, woptions, "sstk1", 5, &err);
714 CheckNoError(err);
715 rocksdb_delete(db, woptions, "sstk2", 5, &err);
716 CheckNoError(err);
717 rocksdb_delete(db, woptions, "sstk22", 6, &err);
718 CheckNoError(err);
719 rocksdb_delete(db, woptions, "sstk3", 5, &err);
720 CheckNoError(err);
721 }
722
723 StartPhase("writebatch");
724 {
725 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
726 rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
727 rocksdb_writebatch_clear(wb);
728 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
729 rocksdb_writebatch_put(wb, "box", 3, "c", 1);
730 rocksdb_writebatch_delete(wb, "bar", 3);
731 rocksdb_write(db, woptions, wb, &err);
732 CheckNoError(err);
733 CheckGet(db, roptions, "foo", "hello");
734 CheckGet(db, roptions, "bar", NULL);
735 CheckGet(db, roptions, "box", "c");
736 int pos = 0;
737 rocksdb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);
738 CheckCondition(pos == 3);
739 rocksdb_writebatch_clear(wb);
740 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
741 rocksdb_writebatch_put(wb, "bay", 3, "d", 1);
742 rocksdb_writebatch_delete_range(wb, "bar", 3, "bay", 3);
743 rocksdb_write(db, woptions, wb, &err);
744 CheckNoError(err);
745 CheckGet(db, roptions, "bar", NULL);
746 CheckGet(db, roptions, "bay", "d");
747 rocksdb_writebatch_clear(wb);
748 const char* start_list[1] = {"bay"};
749 const size_t start_sizes[1] = {3};
750 const char* end_list[1] = {"baz"};
751 const size_t end_sizes[1] = {3};
752 rocksdb_writebatch_delete_rangev(wb, 1, start_list, start_sizes, end_list,
753 end_sizes);
754 rocksdb_write(db, woptions, wb, &err);
755 CheckNoError(err);
756 CheckGet(db, roptions, "bay", NULL);
757 rocksdb_writebatch_destroy(wb);
758 }
759
760 StartPhase("writebatch_vectors");
761 {
762 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
763 const char* k_list[2] = { "z", "ap" };
764 const size_t k_sizes[2] = { 1, 2 };
765 const char* v_list[3] = { "x", "y", "z" };
766 const size_t v_sizes[3] = { 1, 1, 1 };
767 rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
768 rocksdb_write(db, woptions, wb, &err);
769 CheckNoError(err);
770 CheckGet(db, roptions, "zap", "xyz");
771 rocksdb_writebatch_delete(wb, "zap", 3);
772 rocksdb_write(db, woptions, wb, &err);
773 CheckNoError(err);
774 CheckGet(db, roptions, "zap", NULL);
775 rocksdb_writebatch_destroy(wb);
776 }
777
778 StartPhase("writebatch_savepoint");
779 {
780 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
781 rocksdb_writebatch_set_save_point(wb);
782 rocksdb_writebatch_set_save_point(wb);
783 const char* k_list[2] = {"z", "ap"};
784 const size_t k_sizes[2] = {1, 2};
785 const char* v_list[3] = {"x", "y", "z"};
786 const size_t v_sizes[3] = {1, 1, 1};
787 rocksdb_writebatch_pop_save_point(wb, &err);
788 CheckNoError(err);
789 rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
790 rocksdb_writebatch_rollback_to_save_point(wb, &err);
791 CheckNoError(err);
792 rocksdb_write(db, woptions, wb, &err);
793 CheckNoError(err);
794 CheckGet(db, roptions, "zap", NULL);
795 rocksdb_writebatch_destroy(wb);
796 }
797
798 StartPhase("writebatch_rep");
799 {
800 rocksdb_writebatch_t* wb1 = rocksdb_writebatch_create();
801 rocksdb_writebatch_put(wb1, "baz", 3, "d", 1);
802 rocksdb_writebatch_put(wb1, "quux", 4, "e", 1);
803 rocksdb_writebatch_delete(wb1, "quux", 4);
804 size_t repsize1 = 0;
805 const char* rep = rocksdb_writebatch_data(wb1, &repsize1);
806 rocksdb_writebatch_t* wb2 = rocksdb_writebatch_create_from(rep, repsize1);
807 CheckCondition(rocksdb_writebatch_count(wb1) ==
808 rocksdb_writebatch_count(wb2));
809 size_t repsize2 = 0;
810 CheckCondition(
811 memcmp(rep, rocksdb_writebatch_data(wb2, &repsize2), repsize1) == 0);
812 rocksdb_writebatch_destroy(wb1);
813 rocksdb_writebatch_destroy(wb2);
814 }
815
816 StartPhase("writebatch_wi");
817 {
818 rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
819 rocksdb_writebatch_wi_put(wbi, "foo", 3, "a", 1);
820 rocksdb_writebatch_wi_clear(wbi);
821 rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
822 rocksdb_writebatch_wi_put(wbi, "box", 3, "c", 1);
823 rocksdb_writebatch_wi_delete(wbi, "bar", 3);
824 int count = rocksdb_writebatch_wi_count(wbi);
825 CheckCondition(count == 3);
826 size_t size;
827 char* value;
828 value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "box", 3, &size, &err);
829 CheckValue(err, "c", &value, size);
830 value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "bar", 3, &size, &err);
831 CheckValue(err, NULL, &value, size);
832 value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "foo", 3, &size, &err);
833 CheckValue(err, "hello", &value, size);
834 value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "box", 3, &size, &err);
835 CheckValue(err, "c", &value, size);
836 rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
837 CheckNoError(err);
838 CheckGet(db, roptions, "foo", "hello");
839 CheckGet(db, roptions, "bar", NULL);
840 CheckGet(db, roptions, "box", "c");
841 int pos = 0;
842 rocksdb_writebatch_wi_iterate(wbi, &pos, CheckPut, CheckDel);
843 CheckCondition(pos == 3);
844 rocksdb_writebatch_wi_clear(wbi);
845 rocksdb_writebatch_wi_destroy(wbi);
846 }
847
848 StartPhase("writebatch_wi_vectors");
849 {
850 rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
851 const char* k_list[2] = { "z", "ap" };
852 const size_t k_sizes[2] = { 1, 2 };
853 const char* v_list[3] = { "x", "y", "z" };
854 const size_t v_sizes[3] = { 1, 1, 1 };
855 rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
856 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
857 CheckNoError(err);
858 CheckGet(db, roptions, "zap", "xyz");
859 rocksdb_writebatch_wi_delete(wb, "zap", 3);
860 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
861 CheckNoError(err);
862 CheckGet(db, roptions, "zap", NULL);
863 rocksdb_writebatch_wi_destroy(wb);
864 }
865
866 StartPhase("writebatch_wi_savepoint");
867 {
868 rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
869 rocksdb_writebatch_wi_set_save_point(wb);
870 const char* k_list[2] = {"z", "ap"};
871 const size_t k_sizes[2] = {1, 2};
872 const char* v_list[3] = {"x", "y", "z"};
873 const size_t v_sizes[3] = {1, 1, 1};
874 rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
875 rocksdb_writebatch_wi_rollback_to_save_point(wb, &err);
876 CheckNoError(err);
877 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
878 CheckNoError(err);
879 CheckGet(db, roptions, "zap", NULL);
880 rocksdb_writebatch_wi_destroy(wb);
881 }
882
883 StartPhase("iter");
884 {
885 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
886 CheckCondition(!rocksdb_iter_valid(iter));
887 rocksdb_iter_seek_to_first(iter);
888 CheckCondition(rocksdb_iter_valid(iter));
889 CheckIter(iter, "box", "c");
890 rocksdb_iter_next(iter);
891 CheckIter(iter, "foo", "hello");
892 rocksdb_iter_prev(iter);
893 CheckIter(iter, "box", "c");
894 rocksdb_iter_prev(iter);
895 CheckCondition(!rocksdb_iter_valid(iter));
896 rocksdb_iter_seek_to_last(iter);
897 CheckIter(iter, "foo", "hello");
898 rocksdb_iter_seek(iter, "b", 1);
899 CheckIter(iter, "box", "c");
900 rocksdb_iter_seek_for_prev(iter, "g", 1);
901 CheckIter(iter, "foo", "hello");
902 rocksdb_iter_seek_for_prev(iter, "box", 3);
903 CheckIter(iter, "box", "c");
904 rocksdb_iter_get_error(iter, &err);
905 CheckNoError(err);
906 rocksdb_iter_destroy(iter);
907 }
908
909 StartPhase("wbwi_iter");
910 {
911 rocksdb_iterator_t* base_iter = rocksdb_create_iterator(db, roptions);
912 rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
913 rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
914 rocksdb_writebatch_wi_delete(wbi, "foo", 3);
915 rocksdb_iterator_t* iter =
916 rocksdb_writebatch_wi_create_iterator_with_base(wbi, base_iter);
917 CheckCondition(!rocksdb_iter_valid(iter));
918 rocksdb_iter_seek_to_first(iter);
919 CheckCondition(rocksdb_iter_valid(iter));
920 CheckIter(iter, "bar", "b");
921 rocksdb_iter_next(iter);
922 CheckIter(iter, "box", "c");
923 rocksdb_iter_prev(iter);
924 CheckIter(iter, "bar", "b");
925 rocksdb_iter_prev(iter);
926 CheckCondition(!rocksdb_iter_valid(iter));
927 rocksdb_iter_seek_to_last(iter);
928 CheckIter(iter, "box", "c");
929 rocksdb_iter_seek(iter, "b", 1);
930 CheckIter(iter, "bar", "b");
931 rocksdb_iter_seek_for_prev(iter, "c", 1);
932 CheckIter(iter, "box", "c");
933 rocksdb_iter_seek_for_prev(iter, "box", 3);
934 CheckIter(iter, "box", "c");
935 rocksdb_iter_get_error(iter, &err);
936 CheckNoError(err);
937 rocksdb_iter_destroy(iter);
938 rocksdb_writebatch_wi_destroy(wbi);
939 }
940
941 StartPhase("multiget");
942 {
943 const char* keys[3] = { "box", "foo", "notfound" };
944 const size_t keys_sizes[3] = { 3, 3, 8 };
945 char* vals[3];
946 size_t vals_sizes[3];
947 char* errs[3];
948 rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes, errs);
949
950 int i;
951 for (i = 0; i < 3; i++) {
952 CheckEqual(NULL, errs[i], 0);
953 switch (i) {
954 case 0:
955 CheckEqual("c", vals[i], vals_sizes[i]);
956 break;
957 case 1:
958 CheckEqual("hello", vals[i], vals_sizes[i]);
959 break;
960 case 2:
961 CheckEqual(NULL, vals[i], vals_sizes[i]);
962 break;
963 }
964 Free(&vals[i]);
965 }
966 }
967
968 StartPhase("pin_get");
969 {
970 CheckPinGet(db, roptions, "box", "c");
971 CheckPinGet(db, roptions, "foo", "hello");
972 CheckPinGet(db, roptions, "notfound", NULL);
973 }
974
975 StartPhase("approximate_sizes");
976 {
977 int i;
978 int n = 20000;
979 char keybuf[100];
980 char valbuf[100];
981 uint64_t sizes[2];
982 const char* start[2] = { "a", "k00000000000000010000" };
983 size_t start_len[2] = { 1, 21 };
984 const char* limit[2] = { "k00000000000000010000", "z" };
985 size_t limit_len[2] = { 21, 1 };
986 rocksdb_writeoptions_set_sync(woptions, 0);
987 for (i = 0; i < n; i++) {
988 snprintf(keybuf, sizeof(keybuf), "k%020d", i);
989 snprintf(valbuf, sizeof(valbuf), "v%020d", i);
990 rocksdb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),
991 &err);
992 CheckNoError(err);
993 }
994 rocksdb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes,
995 &err);
996 CheckNoError(err);
997 CheckCondition(sizes[0] > 0);
998 CheckCondition(sizes[1] > 0);
999 }
1000
1001 StartPhase("property");
1002 {
1003 char* prop = rocksdb_property_value(db, "nosuchprop");
1004 CheckCondition(prop == NULL);
1005 prop = rocksdb_property_value(db, "rocksdb.stats");
1006 CheckCondition(prop != NULL);
1007 Free(&prop);
1008 }
1009
1010 StartPhase("snapshot");
1011 {
1012 const rocksdb_snapshot_t* snap;
1013 snap = rocksdb_create_snapshot(db);
1014 rocksdb_delete(db, woptions, "foo", 3, &err);
1015 CheckNoError(err);
1016 rocksdb_readoptions_set_snapshot(roptions, snap);
1017 CheckGet(db, roptions, "foo", "hello");
1018 rocksdb_readoptions_set_snapshot(roptions, NULL);
1019 CheckGet(db, roptions, "foo", NULL);
1020 rocksdb_release_snapshot(db, snap);
1021 }
1022
1023 StartPhase("repair");
1024 {
1025 // If we do not compact here, then the lazy deletion of
1026 // files (https://reviews.facebook.net/D6123) would leave
1027 // around deleted files and the repair process will find
1028 // those files and put them back into the database.
1029 rocksdb_compact_range(db, NULL, 0, NULL, 0);
1030 rocksdb_close(db);
1031 rocksdb_options_set_create_if_missing(options, 0);
1032 rocksdb_options_set_error_if_exists(options, 0);
1033 rocksdb_options_set_wal_recovery_mode(options, 2);
1034 rocksdb_repair_db(options, dbname, &err);
1035 CheckNoError(err);
1036 db = rocksdb_open(options, dbname, &err);
1037 CheckNoError(err);
1038 CheckGet(db, roptions, "foo", NULL);
1039 CheckGet(db, roptions, "bar", NULL);
1040 CheckGet(db, roptions, "box", "c");
1041 rocksdb_options_set_create_if_missing(options, 1);
1042 rocksdb_options_set_error_if_exists(options, 1);
1043 }
1044
1045 StartPhase("filter");
1046 for (run = 0; run <= 2; run++) {
1047 // First run uses custom filter
1048 // Second run uses old block-based bloom filter
1049 // Third run uses full bloom filter
1050 CheckNoError(err);
1051 rocksdb_filterpolicy_t* policy;
1052 if (run == 0) {
1053 policy = rocksdb_filterpolicy_create(NULL, FilterDestroy, FilterCreate,
1054 FilterKeyMatch, NULL, FilterName);
1055 } else if (run == 1) {
1056 policy = rocksdb_filterpolicy_create_bloom(8);
1057 } else {
1058 policy = rocksdb_filterpolicy_create_bloom_full(8);
1059 }
1060 rocksdb_block_based_options_set_filter_policy(table_options, policy);
1061
1062 // Create new database
1063 rocksdb_close(db);
1064 rocksdb_destroy_db(options, dbname, &err);
1065 rocksdb_options_set_block_based_table_factory(options, table_options);
1066 db = rocksdb_open(options, dbname, &err);
1067 CheckNoError(err);
1068 rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
1069 CheckNoError(err);
1070 rocksdb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
1071 CheckNoError(err);
1072
1073 {
1074 // Add enough keys to get just one reasonably populated Bloom filter
1075 const int keys_to_add = 1500;
1076 int i;
1077 char keybuf[100];
1078 for (i = 0; i < keys_to_add; i++) {
1079 snprintf(keybuf, sizeof(keybuf), "yes%020d", i);
1080 rocksdb_put(db, woptions, keybuf, strlen(keybuf), "val", 3, &err);
1081 CheckNoError(err);
1082 }
1083 }
1084 rocksdb_compact_range(db, NULL, 0, NULL, 0);
1085
1086 fake_filter_result = 1;
1087 CheckGet(db, roptions, "foo", "foovalue");
1088 CheckGet(db, roptions, "bar", "barvalue");
1089 if (run == 0) {
1090 // Must not find value when custom filter returns false
1091 fake_filter_result = 0;
1092 CheckGet(db, roptions, "foo", NULL);
1093 CheckGet(db, roptions, "bar", NULL);
1094 fake_filter_result = 1;
1095
1096 CheckGet(db, roptions, "foo", "foovalue");
1097 CheckGet(db, roptions, "bar", "barvalue");
1098 }
1099
1100 {
1101 // Query some keys not added to identify Bloom filter implementation
1102 // from false positive queries, using perfcontext to detect Bloom
1103 // filter behavior
1104 rocksdb_perfcontext_t* perf = rocksdb_perfcontext_create();
1105 rocksdb_perfcontext_reset(perf);
1106
1107 const int keys_to_query = 10000;
1108 int i;
1109 char keybuf[100];
1110 for (i = 0; i < keys_to_query; i++) {
1111 fake_filter_result = i % 2;
1112 snprintf(keybuf, sizeof(keybuf), "no%020d", i);
1113 CheckGet(db, roptions, keybuf, NULL);
1114 }
1115
1116 const int hits =
1117 (int)rocksdb_perfcontext_metric(perf, rocksdb_bloom_sst_hit_count);
1118 if (run == 0) {
1119 // Due to half true, half false with fake filter result
1120 CheckCondition(hits == keys_to_query / 2);
1121 } else if (run == 1) {
1122 // Essentially a fingerprint of the block-based Bloom schema
1123 CheckCondition(hits == 241);
1124 } else {
1125 // Essentially a fingerprint of full Bloom schema, format_version=5
1126 CheckCondition(hits == 188);
1127 }
1128 CheckCondition(
1129 (keys_to_query - hits) ==
1130 (int)rocksdb_perfcontext_metric(perf, rocksdb_bloom_sst_miss_count));
1131
1132 rocksdb_perfcontext_destroy(perf);
1133 }
1134
1135 // Reset the policy
1136 rocksdb_block_based_options_set_filter_policy(table_options, NULL);
1137 rocksdb_options_set_block_based_table_factory(options, table_options);
1138 }
1139
1140 StartPhase("compaction_filter");
1141 {
1142 rocksdb_options_t* options_with_filter = rocksdb_options_create();
1143 rocksdb_options_set_create_if_missing(options_with_filter, 1);
1144 rocksdb_compactionfilter_t* cfilter;
1145 cfilter = rocksdb_compactionfilter_create(NULL, CFilterDestroy,
1146 CFilterFilter, CFilterName);
1147 // Create new database
1148 rocksdb_close(db);
1149 rocksdb_destroy_db(options_with_filter, dbname, &err);
1150 rocksdb_options_set_compaction_filter(options_with_filter, cfilter);
1151 db = CheckCompaction(db, options_with_filter, roptions, woptions);
1152
1153 rocksdb_options_set_compaction_filter(options_with_filter, NULL);
1154 rocksdb_compactionfilter_destroy(cfilter);
1155 rocksdb_options_destroy(options_with_filter);
1156 }
1157
1158 StartPhase("compaction_filter_factory");
1159 {
1160 rocksdb_options_t* options_with_filter_factory = rocksdb_options_create();
1161 rocksdb_options_set_create_if_missing(options_with_filter_factory, 1);
1162 rocksdb_compactionfilterfactory_t* factory;
1163 factory = rocksdb_compactionfilterfactory_create(
1164 NULL, CFilterFactoryDestroy, CFilterCreate, CFilterFactoryName);
1165 // Create new database
1166 rocksdb_close(db);
1167 rocksdb_destroy_db(options_with_filter_factory, dbname, &err);
1168 rocksdb_options_set_compaction_filter_factory(options_with_filter_factory,
1169 factory);
1170 db = CheckCompaction(db, options_with_filter_factory, roptions, woptions);
1171
1172 rocksdb_options_set_compaction_filter_factory(
1173 options_with_filter_factory, NULL);
1174 rocksdb_options_destroy(options_with_filter_factory);
1175 }
1176
1177 StartPhase("merge_operator");
1178 {
1179 rocksdb_mergeoperator_t* merge_operator;
1180 merge_operator = rocksdb_mergeoperator_create(
1181 NULL, MergeOperatorDestroy, MergeOperatorFullMerge,
1182 MergeOperatorPartialMerge, NULL, MergeOperatorName);
1183 // Create new database
1184 rocksdb_close(db);
1185 rocksdb_destroy_db(options, dbname, &err);
1186 rocksdb_options_set_merge_operator(options, merge_operator);
1187 db = rocksdb_open(options, dbname, &err);
1188 CheckNoError(err);
1189 rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
1190 CheckNoError(err);
1191 CheckGet(db, roptions, "foo", "foovalue");
1192 rocksdb_merge(db, woptions, "foo", 3, "barvalue", 8, &err);
1193 CheckNoError(err);
1194 CheckGet(db, roptions, "foo", "fake");
1195
1196 // Merge of a non-existing value
1197 rocksdb_merge(db, woptions, "bar", 3, "barvalue", 8, &err);
1198 CheckNoError(err);
1199 CheckGet(db, roptions, "bar", "fake");
1200
1201 }
1202
1203 StartPhase("columnfamilies");
1204 {
1205 rocksdb_close(db);
1206 rocksdb_destroy_db(options, dbname, &err);
1207 CheckNoError(err);
1208
1209 rocksdb_options_t* db_options = rocksdb_options_create();
1210 rocksdb_options_set_create_if_missing(db_options, 1);
1211 db = rocksdb_open(db_options, dbname, &err);
1212 CheckNoError(err)
1213 rocksdb_column_family_handle_t* cfh;
1214 cfh = rocksdb_create_column_family(db, db_options, "cf1", &err);
1215 rocksdb_column_family_handle_destroy(cfh);
1216 CheckNoError(err);
1217 rocksdb_close(db);
1218
1219 size_t cflen;
1220 char** column_fams = rocksdb_list_column_families(db_options, dbname, &cflen, &err);
1221 CheckNoError(err);
1222 CheckEqual("default", column_fams[0], 7);
1223 CheckEqual("cf1", column_fams[1], 3);
1224 CheckCondition(cflen == 2);
1225 rocksdb_list_column_families_destroy(column_fams, cflen);
1226
1227 rocksdb_options_t* cf_options = rocksdb_options_create();
1228
1229 const char* cf_names[2] = {"default", "cf1"};
1230 const rocksdb_options_t* cf_opts[2] = {cf_options, cf_options};
1231 rocksdb_column_family_handle_t* handles[2];
1232 db = rocksdb_open_column_families(db_options, dbname, 2, cf_names, cf_opts, handles, &err);
1233 CheckNoError(err);
1234
1235 rocksdb_put_cf(db, woptions, handles[1], "foo", 3, "hello", 5, &err);
1236 CheckNoError(err);
1237
1238 rocksdb_put_cf(db, woptions, handles[1], "foobar1", 7, "hello1", 6, &err);
1239 CheckNoError(err);
1240 rocksdb_put_cf(db, woptions, handles[1], "foobar2", 7, "hello2", 6, &err);
1241 CheckNoError(err);
1242 rocksdb_put_cf(db, woptions, handles[1], "foobar3", 7, "hello3", 6, &err);
1243 CheckNoError(err);
1244 rocksdb_put_cf(db, woptions, handles[1], "foobar4", 7, "hello4", 6, &err);
1245 CheckNoError(err);
1246
1247 rocksdb_flushoptions_t *flush_options = rocksdb_flushoptions_create();
1248 rocksdb_flushoptions_set_wait(flush_options, 1);
1249 rocksdb_flush_cf(db, flush_options, handles[1], &err);
1250 CheckNoError(err)
1251 rocksdb_flushoptions_destroy(flush_options);
1252
1253 CheckGetCF(db, roptions, handles[1], "foo", "hello");
1254 CheckPinGetCF(db, roptions, handles[1], "foo", "hello");
1255
1256 rocksdb_delete_cf(db, woptions, handles[1], "foo", 3, &err);
1257 CheckNoError(err);
1258
1259 rocksdb_delete_range_cf(db, woptions, handles[1], "foobar2", 7, "foobar4",
1260 7, &err);
1261 CheckNoError(err);
1262
1263 CheckGetCF(db, roptions, handles[1], "foo", NULL);
1264 CheckPinGetCF(db, roptions, handles[1], "foo", NULL);
1265
1266 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
1267 rocksdb_writebatch_put_cf(wb, handles[1], "baz", 3, "a", 1);
1268 rocksdb_writebatch_clear(wb);
1269 rocksdb_writebatch_put_cf(wb, handles[1], "bar", 3, "b", 1);
1270 rocksdb_writebatch_put_cf(wb, handles[1], "box", 3, "c", 1);
1271 rocksdb_writebatch_delete_cf(wb, handles[1], "bar", 3);
1272 rocksdb_write(db, woptions, wb, &err);
1273 CheckNoError(err);
1274 CheckGetCF(db, roptions, handles[1], "baz", NULL);
1275 CheckGetCF(db, roptions, handles[1], "bar", NULL);
1276 CheckGetCF(db, roptions, handles[1], "box", "c");
1277 CheckPinGetCF(db, roptions, handles[1], "baz", NULL);
1278 CheckPinGetCF(db, roptions, handles[1], "bar", NULL);
1279 CheckPinGetCF(db, roptions, handles[1], "box", "c");
1280 rocksdb_writebatch_destroy(wb);
1281
1282 rocksdb_flush_wal(db, 1, &err);
1283 CheckNoError(err);
1284
1285 const char* keys[3] = { "box", "box", "barfooxx" };
1286 const rocksdb_column_family_handle_t* get_handles[3] = { handles[0], handles[1], handles[1] };
1287 const size_t keys_sizes[3] = { 3, 3, 8 };
1288 char* vals[3];
1289 size_t vals_sizes[3];
1290 char* errs[3];
1291 rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals, vals_sizes, errs);
1292
1293 int i;
1294 for (i = 0; i < 3; i++) {
1295 CheckEqual(NULL, errs[i], 0);
1296 switch (i) {
1297 case 0:
1298 CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
1299 break;
1300 case 1:
1301 CheckEqual("c", vals[i], vals_sizes[i]); // bingo
1302 break;
1303 case 2:
1304 CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
1305 break;
1306 }
1307 Free(&vals[i]);
1308 }
1309
1310 {
1311 unsigned char value_found = 0;
1312
1313 CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
1314 NULL, NULL, NULL, 0, NULL));
1315 CheckCondition(!rocksdb_key_may_exist(db, roptions, "invalid_key", 11,
1316 &vals[0], &vals_sizes[0], NULL, 0,
1317 &value_found));
1318 if (value_found) {
1319 Free(&vals[0]);
1320 }
1321
1322 CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
1323 "invalid_key", 11, NULL, NULL,
1324 NULL, 0, NULL));
1325 CheckCondition(!rocksdb_key_may_exist_cf(db, roptions, handles[1],
1326 "invalid_key", 11, &vals[0],
1327 &vals_sizes[0], NULL, 0, NULL));
1328 if (value_found) {
1329 Free(&vals[0]);
1330 }
1331 }
1332
1333 rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]);
1334 CheckCondition(!rocksdb_iter_valid(iter));
1335 rocksdb_iter_seek_to_first(iter);
1336 CheckCondition(rocksdb_iter_valid(iter));
1337
1338 for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
1339 i++;
1340 }
1341 CheckCondition(i == 3);
1342 rocksdb_iter_get_error(iter, &err);
1343 CheckNoError(err);
1344 rocksdb_iter_destroy(iter);
1345
1346 rocksdb_column_family_handle_t* iters_cf_handles[2] = { handles[0], handles[1] };
1347 rocksdb_iterator_t* iters_handles[2];
1348 rocksdb_create_iterators(db, roptions, iters_cf_handles, iters_handles, 2, &err);
1349 CheckNoError(err);
1350
1351 iter = iters_handles[0];
1352 CheckCondition(!rocksdb_iter_valid(iter));
1353 rocksdb_iter_seek_to_first(iter);
1354 CheckCondition(!rocksdb_iter_valid(iter));
1355 rocksdb_iter_destroy(iter);
1356
1357 iter = iters_handles[1];
1358 CheckCondition(!rocksdb_iter_valid(iter));
1359 rocksdb_iter_seek_to_first(iter);
1360 CheckCondition(rocksdb_iter_valid(iter));
1361
1362 for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
1363 i++;
1364 }
1365 CheckCondition(i == 3);
1366 rocksdb_iter_get_error(iter, &err);
1367 CheckNoError(err);
1368 rocksdb_iter_destroy(iter);
1369
1370 rocksdb_drop_column_family(db, handles[1], &err);
1371 CheckNoError(err);
1372 for (i = 0; i < 2; i++) {
1373 rocksdb_column_family_handle_destroy(handles[i]);
1374 }
1375 rocksdb_close(db);
1376 rocksdb_destroy_db(options, dbname, &err);
1377 rocksdb_options_destroy(db_options);
1378 rocksdb_options_destroy(cf_options);
1379 }
1380
1381 StartPhase("prefix");
1382 {
1383 // Create new database
1384 rocksdb_options_set_allow_mmap_reads(options, 1);
1385 rocksdb_options_set_prefix_extractor(options, rocksdb_slicetransform_create_fixed_prefix(3));
1386 rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
1387 rocksdb_options_set_plain_table_factory(options, 4, 10, 0.75, 16);
1388 rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
1389
1390 db = rocksdb_open(options, dbname, &err);
1391 CheckNoError(err);
1392
1393 rocksdb_put(db, woptions, "foo1", 4, "foo", 3, &err);
1394 CheckNoError(err);
1395 rocksdb_put(db, woptions, "foo2", 4, "foo", 3, &err);
1396 CheckNoError(err);
1397 rocksdb_put(db, woptions, "foo3", 4, "foo", 3, &err);
1398 CheckNoError(err);
1399 rocksdb_put(db, woptions, "bar1", 4, "bar", 3, &err);
1400 CheckNoError(err);
1401 rocksdb_put(db, woptions, "bar2", 4, "bar", 3, &err);
1402 CheckNoError(err);
1403 rocksdb_put(db, woptions, "bar3", 4, "bar", 3, &err);
1404 CheckNoError(err);
1405
1406 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
1407 CheckCondition(!rocksdb_iter_valid(iter));
1408
1409 rocksdb_iter_seek(iter, "bar", 3);
1410 rocksdb_iter_get_error(iter, &err);
1411 CheckNoError(err);
1412 CheckCondition(rocksdb_iter_valid(iter));
1413
1414 CheckIter(iter, "bar1", "bar");
1415 rocksdb_iter_next(iter);
1416 CheckIter(iter, "bar2", "bar");
1417 rocksdb_iter_next(iter);
1418 CheckIter(iter, "bar3", "bar");
1419 rocksdb_iter_get_error(iter, &err);
1420 CheckNoError(err);
1421 rocksdb_iter_destroy(iter);
1422
1423 rocksdb_readoptions_set_total_order_seek(roptions, 1);
1424 iter = rocksdb_create_iterator(db, roptions);
1425 CheckCondition(!rocksdb_iter_valid(iter));
1426
1427 rocksdb_iter_seek(iter, "ba", 2);
1428 rocksdb_iter_get_error(iter, &err);
1429 CheckNoError(err);
1430 CheckCondition(rocksdb_iter_valid(iter));
1431 CheckIter(iter, "bar1", "bar");
1432
1433 rocksdb_iter_destroy(iter);
1434 rocksdb_readoptions_set_total_order_seek(roptions, 0);
1435
1436 rocksdb_close(db);
1437 rocksdb_destroy_db(options, dbname, &err);
1438 }
1439
1440 // Check memory usage stats
1441 StartPhase("approximate_memory_usage");
1442 {
1443 // Create database
1444 db = rocksdb_open(options, dbname, &err);
1445 CheckNoError(err);
1446
1447 rocksdb_memory_consumers_t* consumers;
1448 consumers = rocksdb_memory_consumers_create();
1449 rocksdb_memory_consumers_add_db(consumers, db);
1450 rocksdb_memory_consumers_add_cache(consumers, cache);
1451
1452 // take memory usage report before write-read operation
1453 rocksdb_memory_usage_t* mu1;
1454 mu1 = rocksdb_approximate_memory_usage_create(consumers, &err);
1455 CheckNoError(err);
1456
1457 // Put data (this should affect memtables)
1458 rocksdb_put(db, woptions, "memory", 6, "test", 4, &err);
1459 CheckNoError(err);
1460 CheckGet(db, roptions, "memory", "test");
1461
1462 // take memory usage report after write-read operation
1463 rocksdb_memory_usage_t* mu2;
1464 mu2 = rocksdb_approximate_memory_usage_create(consumers, &err);
1465 CheckNoError(err);
1466
1467 // amount of memory used within memtables should grow
1468 CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_total(mu2) >=
1469 rocksdb_approximate_memory_usage_get_mem_table_total(mu1));
1470 CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu2) >=
1471 rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu1));
1472
1473 rocksdb_memory_consumers_destroy(consumers);
1474 rocksdb_approximate_memory_usage_destroy(mu1);
1475 rocksdb_approximate_memory_usage_destroy(mu2);
1476 rocksdb_close(db);
1477 rocksdb_destroy_db(options, dbname, &err);
1478 CheckNoError(err);
1479 }
1480
1481 StartPhase("cuckoo_options");
1482 {
1483 rocksdb_cuckoo_table_options_t* cuckoo_options;
1484 cuckoo_options = rocksdb_cuckoo_options_create();
1485 rocksdb_cuckoo_options_set_hash_ratio(cuckoo_options, 0.5);
1486 rocksdb_cuckoo_options_set_max_search_depth(cuckoo_options, 200);
1487 rocksdb_cuckoo_options_set_cuckoo_block_size(cuckoo_options, 10);
1488 rocksdb_cuckoo_options_set_identity_as_first_hash(cuckoo_options, 1);
1489 rocksdb_cuckoo_options_set_use_module_hash(cuckoo_options, 0);
1490 rocksdb_options_set_cuckoo_table_factory(options, cuckoo_options);
1491
1492 db = rocksdb_open(options, dbname, &err);
1493 CheckNoError(err);
1494
1495 rocksdb_cuckoo_options_destroy(cuckoo_options);
1496 }
1497
1498 StartPhase("options");
1499 {
1500 rocksdb_options_t* o;
1501 o = rocksdb_options_create();
1502
1503 // Set and check options.
1504 rocksdb_options_set_allow_ingest_behind(o, 1);
1505 CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
1506
1507 rocksdb_options_compaction_readahead_size(o, 10);
1508 CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
1509
1510 rocksdb_options_set_create_if_missing(o, 1);
1511 CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
1512
1513 rocksdb_options_set_create_missing_column_families(o, 1);
1514 CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
1515
1516 rocksdb_options_set_error_if_exists(o, 1);
1517 CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
1518
1519 rocksdb_options_set_paranoid_checks(o, 1);
1520 CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
1521
1522 rocksdb_options_set_info_log_level(o, 3);
1523 CheckCondition(3 == rocksdb_options_get_info_log_level(o));
1524
1525 rocksdb_options_set_write_buffer_size(o, 100);
1526 CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
1527
1528 rocksdb_options_set_db_write_buffer_size(o, 1000);
1529 CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
1530
1531 rocksdb_options_set_max_open_files(o, 21);
1532 CheckCondition(21 == rocksdb_options_get_max_open_files(o));
1533
1534 rocksdb_options_set_max_file_opening_threads(o, 5);
1535 CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
1536
1537 rocksdb_options_set_max_total_wal_size(o, 400);
1538 CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
1539
1540 rocksdb_options_set_num_levels(o, 7);
1541 CheckCondition(7 == rocksdb_options_get_num_levels(o));
1542
1543 rocksdb_options_set_level0_file_num_compaction_trigger(o, 4);
1544 CheckCondition(4 ==
1545 rocksdb_options_get_level0_file_num_compaction_trigger(o));
1546
1547 rocksdb_options_set_level0_slowdown_writes_trigger(o, 6);
1548 CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
1549
1550 rocksdb_options_set_level0_stop_writes_trigger(o, 8);
1551 CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
1552
1553 rocksdb_options_set_target_file_size_base(o, 256);
1554 CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
1555
1556 rocksdb_options_set_target_file_size_multiplier(o, 3);
1557 CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
1558
1559 rocksdb_options_set_max_bytes_for_level_base(o, 1024);
1560 CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
1561
1562 rocksdb_options_set_level_compaction_dynamic_level_bytes(o, 1);
1563 CheckCondition(1 ==
1564 rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
1565
1566 rocksdb_options_set_max_bytes_for_level_multiplier(o, 2.0);
1567 CheckCondition(2.0 ==
1568 rocksdb_options_get_max_bytes_for_level_multiplier(o));
1569
1570 rocksdb_options_set_skip_stats_update_on_db_open(o, 1);
1571 CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
1572
1573 rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(o, 1);
1574 CheckCondition(
1575 1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(o));
1576
1577 rocksdb_options_set_max_write_buffer_number(o, 97);
1578 CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
1579
1580 rocksdb_options_set_min_write_buffer_number_to_merge(o, 23);
1581 CheckCondition(23 ==
1582 rocksdb_options_get_min_write_buffer_number_to_merge(o));
1583
1584 rocksdb_options_set_max_write_buffer_number_to_maintain(o, 64);
1585 CheckCondition(64 ==
1586 rocksdb_options_get_max_write_buffer_number_to_maintain(o));
1587
1588 rocksdb_options_set_max_write_buffer_size_to_maintain(o, 50000);
1589 CheckCondition(50000 ==
1590 rocksdb_options_get_max_write_buffer_size_to_maintain(o));
1591
1592 rocksdb_options_set_enable_pipelined_write(o, 1);
1593 CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
1594
1595 rocksdb_options_set_unordered_write(o, 1);
1596 CheckCondition(1 == rocksdb_options_get_unordered_write(o));
1597
1598 rocksdb_options_set_max_subcompactions(o, 123456);
1599 CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
1600
1601 rocksdb_options_set_max_background_jobs(o, 2);
1602 CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
1603
1604 rocksdb_options_set_max_background_compactions(o, 3);
1605 CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
1606
1607 rocksdb_options_set_base_background_compactions(o, 4);
1608 CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
1609
1610 rocksdb_options_set_max_background_flushes(o, 5);
1611 CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
1612
1613 rocksdb_options_set_max_log_file_size(o, 6);
1614 CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
1615
1616 rocksdb_options_set_log_file_time_to_roll(o, 7);
1617 CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
1618
1619 rocksdb_options_set_keep_log_file_num(o, 8);
1620 CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
1621
1622 rocksdb_options_set_recycle_log_file_num(o, 9);
1623 CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
1624
1625 rocksdb_options_set_soft_rate_limit(o, 2.0);
1626 CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
1627
1628 rocksdb_options_set_hard_rate_limit(o, 4.0);
1629 CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
1630
1631 rocksdb_options_set_soft_pending_compaction_bytes_limit(o, 10);
1632 CheckCondition(10 ==
1633 rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
1634
1635 rocksdb_options_set_hard_pending_compaction_bytes_limit(o, 11);
1636 CheckCondition(11 ==
1637 rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
1638
1639 rocksdb_options_set_rate_limit_delay_max_milliseconds(o, 1);
1640 CheckCondition(1 ==
1641 rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
1642
1643 rocksdb_options_set_max_manifest_file_size(o, 12);
1644 CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
1645
1646 rocksdb_options_set_table_cache_numshardbits(o, 13);
1647 CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
1648
1649 rocksdb_options_set_arena_block_size(o, 14);
1650 CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
1651
1652 rocksdb_options_set_use_fsync(o, 1);
1653 CheckCondition(1 == rocksdb_options_get_use_fsync(o));
1654
1655 rocksdb_options_set_WAL_ttl_seconds(o, 15);
1656 CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
1657
1658 rocksdb_options_set_WAL_size_limit_MB(o, 16);
1659 CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
1660
1661 rocksdb_options_set_manifest_preallocation_size(o, 17);
1662 CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
1663
1664 rocksdb_options_set_allow_mmap_reads(o, 1);
1665 CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
1666
1667 rocksdb_options_set_allow_mmap_writes(o, 1);
1668 CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
1669
1670 rocksdb_options_set_use_direct_reads(o, 1);
1671 CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
1672
1673 rocksdb_options_set_use_direct_io_for_flush_and_compaction(o, 1);
1674 CheckCondition(
1675 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
1676
1677 rocksdb_options_set_is_fd_close_on_exec(o, 1);
1678 CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
1679
1680 rocksdb_options_set_skip_log_error_on_recovery(o, 1);
1681 CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
1682
1683 rocksdb_options_set_stats_dump_period_sec(o, 18);
1684 CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
1685
1686 rocksdb_options_set_stats_persist_period_sec(o, 5);
1687 CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
1688
1689 rocksdb_options_set_advise_random_on_open(o, 1);
1690 CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
1691
1692 rocksdb_options_set_access_hint_on_compaction_start(o, 3);
1693 CheckCondition(3 == rocksdb_options_get_access_hint_on_compaction_start(o));
1694
1695 rocksdb_options_set_use_adaptive_mutex(o, 1);
1696 CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
1697
1698 rocksdb_options_set_bytes_per_sync(o, 19);
1699 CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
1700
1701 rocksdb_options_set_wal_bytes_per_sync(o, 20);
1702 CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
1703
1704 rocksdb_options_set_writable_file_max_buffer_size(o, 21);
1705 CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
1706
1707 rocksdb_options_set_allow_concurrent_memtable_write(o, 1);
1708 CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
1709
1710 rocksdb_options_set_enable_write_thread_adaptive_yield(o, 1);
1711 CheckCondition(1 ==
1712 rocksdb_options_get_enable_write_thread_adaptive_yield(o));
1713
1714 rocksdb_options_set_max_sequential_skip_in_iterations(o, 22);
1715 CheckCondition(22 ==
1716 rocksdb_options_get_max_sequential_skip_in_iterations(o));
1717
1718 rocksdb_options_set_disable_auto_compactions(o, 1);
1719 CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
1720
1721 rocksdb_options_set_optimize_filters_for_hits(o, 1);
1722 CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
1723
1724 rocksdb_options_set_delete_obsolete_files_period_micros(o, 23);
1725 CheckCondition(23 ==
1726 rocksdb_options_get_delete_obsolete_files_period_micros(o));
1727
1728 rocksdb_options_set_memtable_prefix_bloom_size_ratio(o, 2.0);
1729 CheckCondition(2.0 ==
1730 rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
1731
1732 rocksdb_options_set_max_compaction_bytes(o, 24);
1733 CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
1734
1735 rocksdb_options_set_memtable_huge_page_size(o, 25);
1736 CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
1737
1738 rocksdb_options_set_max_successive_merges(o, 26);
1739 CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
1740
1741 rocksdb_options_set_bloom_locality(o, 27);
1742 CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
1743
1744 rocksdb_options_set_inplace_update_support(o, 1);
1745 CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
1746
1747 rocksdb_options_set_inplace_update_num_locks(o, 28);
1748 CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
1749
1750 rocksdb_options_set_report_bg_io_stats(o, 1);
1751 CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
1752
1753 rocksdb_options_set_wal_recovery_mode(o, 2);
1754 CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
1755
1756 rocksdb_options_set_compression(o, 5);
1757 CheckCondition(5 == rocksdb_options_get_compression(o));
1758
1759 rocksdb_options_set_bottommost_compression(o, 4);
1760 CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
1761
1762 rocksdb_options_set_compaction_style(o, 2);
1763 CheckCondition(2 == rocksdb_options_get_compaction_style(o));
1764
1765 rocksdb_options_set_atomic_flush(o, 1);
1766 CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
1767
1768 rocksdb_options_set_manual_wal_flush(o, 1);
1769 CheckCondition(1 == rocksdb_options_get_manual_wal_flush(o));
1770
1771 /* Blob Options */
1772 rocksdb_options_set_enable_blob_files(o, 1);
1773 CheckCondition(1 == rocksdb_options_get_enable_blob_files(o));
1774
1775 rocksdb_options_set_min_blob_size(o, 29);
1776 CheckCondition(29 == rocksdb_options_get_min_blob_size(o));
1777
1778 rocksdb_options_set_blob_file_size(o, 30);
1779 CheckCondition(30 == rocksdb_options_get_blob_file_size(o));
1780
1781 rocksdb_options_set_blob_compression_type(o, 4);
1782 CheckCondition(4 == rocksdb_options_get_blob_compression_type(o));
1783
1784 rocksdb_options_set_enable_blob_gc(o, 1);
1785 CheckCondition(1 == rocksdb_options_get_enable_blob_gc(o));
1786
1787 rocksdb_options_set_blob_gc_age_cutoff(o, 0.75);
1788 CheckCondition(0.75 == rocksdb_options_get_blob_gc_age_cutoff(o));
1789
1790 // Create a copy that should be equal to the original.
1791 rocksdb_options_t* copy;
1792 copy = rocksdb_options_create_copy(o);
1793
1794 CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(copy));
1795 CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(copy));
1796 CheckCondition(1 == rocksdb_options_get_create_if_missing(copy));
1797 CheckCondition(1 ==
1798 rocksdb_options_get_create_missing_column_families(copy));
1799 CheckCondition(1 == rocksdb_options_get_error_if_exists(copy));
1800 CheckCondition(1 == rocksdb_options_get_paranoid_checks(copy));
1801 CheckCondition(3 == rocksdb_options_get_info_log_level(copy));
1802 CheckCondition(100 == rocksdb_options_get_write_buffer_size(copy));
1803 CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(copy));
1804 CheckCondition(21 == rocksdb_options_get_max_open_files(copy));
1805 CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(copy));
1806 CheckCondition(400 == rocksdb_options_get_max_total_wal_size(copy));
1807 CheckCondition(7 == rocksdb_options_get_num_levels(copy));
1808 CheckCondition(
1809 4 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
1810 CheckCondition(6 ==
1811 rocksdb_options_get_level0_slowdown_writes_trigger(copy));
1812 CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(copy));
1813 CheckCondition(256 == rocksdb_options_get_target_file_size_base(copy));
1814 CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(copy));
1815 CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(copy));
1816 CheckCondition(
1817 1 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
1818 CheckCondition(2.0 ==
1819 rocksdb_options_get_max_bytes_for_level_multiplier(copy));
1820 CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
1821 CheckCondition(
1822 1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(copy));
1823 CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(copy));
1824 CheckCondition(23 ==
1825 rocksdb_options_get_min_write_buffer_number_to_merge(copy));
1826 CheckCondition(
1827 64 == rocksdb_options_get_max_write_buffer_number_to_maintain(copy));
1828 CheckCondition(50000 ==
1829 rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
1830 CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(copy));
1831 CheckCondition(1 == rocksdb_options_get_unordered_write(copy));
1832 CheckCondition(123456 == rocksdb_options_get_max_subcompactions(copy));
1833 CheckCondition(2 == rocksdb_options_get_max_background_jobs(copy));
1834 CheckCondition(3 == rocksdb_options_get_max_background_compactions(copy));
1835 CheckCondition(4 == rocksdb_options_get_base_background_compactions(copy));
1836 CheckCondition(5 == rocksdb_options_get_max_background_flushes(copy));
1837 CheckCondition(6 == rocksdb_options_get_max_log_file_size(copy));
1838 CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(copy));
1839 CheckCondition(8 == rocksdb_options_get_keep_log_file_num(copy));
1840 CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(copy));
1841 CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(copy));
1842 CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(copy));
1843 CheckCondition(
1844 10 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
1845 CheckCondition(
1846 11 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
1847 CheckCondition(1 ==
1848 rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
1849 CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(copy));
1850 CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(copy));
1851 CheckCondition(14 == rocksdb_options_get_arena_block_size(copy));
1852 CheckCondition(1 == rocksdb_options_get_use_fsync(copy));
1853 CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(copy));
1854 CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(copy));
1855 CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(copy));
1856 CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(copy));
1857 CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(copy));
1858 CheckCondition(1 == rocksdb_options_get_use_direct_reads(copy));
1859 CheckCondition(
1860 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
1861 CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(copy));
1862 CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(copy));
1863 CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(copy));
1864 CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(copy));
1865 CheckCondition(1 == rocksdb_options_get_advise_random_on_open(copy));
1866 CheckCondition(3 ==
1867 rocksdb_options_get_access_hint_on_compaction_start(copy));
1868 CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(copy));
1869 CheckCondition(19 == rocksdb_options_get_bytes_per_sync(copy));
1870 CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(copy));
1871 CheckCondition(21 ==
1872 rocksdb_options_get_writable_file_max_buffer_size(copy));
1873 CheckCondition(1 ==
1874 rocksdb_options_get_allow_concurrent_memtable_write(copy));
1875 CheckCondition(
1876 1 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
1877 CheckCondition(22 ==
1878 rocksdb_options_get_max_sequential_skip_in_iterations(copy));
1879 CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(copy));
1880 CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(copy));
1881 CheckCondition(
1882 23 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
1883 CheckCondition(2.0 ==
1884 rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
1885 CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(copy));
1886 CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(copy));
1887 CheckCondition(26 == rocksdb_options_get_max_successive_merges(copy));
1888 CheckCondition(27 == rocksdb_options_get_bloom_locality(copy));
1889 CheckCondition(1 == rocksdb_options_get_inplace_update_support(copy));
1890 CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(copy));
1891 CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(copy));
1892 CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(copy));
1893 CheckCondition(5 == rocksdb_options_get_compression(copy));
1894 CheckCondition(4 == rocksdb_options_get_bottommost_compression(copy));
1895 CheckCondition(2 == rocksdb_options_get_compaction_style(copy));
1896 CheckCondition(1 == rocksdb_options_get_atomic_flush(copy));
1897
1898 // Copies should be independent.
1899 rocksdb_options_set_allow_ingest_behind(copy, 0);
1900 CheckCondition(0 == rocksdb_options_get_allow_ingest_behind(copy));
1901 CheckCondition(1 == rocksdb_options_get_allow_ingest_behind(o));
1902
1903 rocksdb_options_compaction_readahead_size(copy, 20);
1904 CheckCondition(20 == rocksdb_options_get_compaction_readahead_size(copy));
1905 CheckCondition(10 == rocksdb_options_get_compaction_readahead_size(o));
1906
1907 rocksdb_options_set_create_if_missing(copy, 0);
1908 CheckCondition(0 == rocksdb_options_get_create_if_missing(copy));
1909 CheckCondition(1 == rocksdb_options_get_create_if_missing(o));
1910
1911 rocksdb_options_set_create_missing_column_families(copy, 0);
1912 CheckCondition(0 ==
1913 rocksdb_options_get_create_missing_column_families(copy));
1914 CheckCondition(1 == rocksdb_options_get_create_missing_column_families(o));
1915
1916 rocksdb_options_set_error_if_exists(copy, 0);
1917 CheckCondition(0 == rocksdb_options_get_error_if_exists(copy));
1918 CheckCondition(1 == rocksdb_options_get_error_if_exists(o));
1919
1920 rocksdb_options_set_paranoid_checks(copy, 0);
1921 CheckCondition(0 == rocksdb_options_get_paranoid_checks(copy));
1922 CheckCondition(1 == rocksdb_options_get_paranoid_checks(o));
1923
1924 rocksdb_options_set_info_log_level(copy, 2);
1925 CheckCondition(2 == rocksdb_options_get_info_log_level(copy));
1926 CheckCondition(3 == rocksdb_options_get_info_log_level(o));
1927
1928 rocksdb_options_set_write_buffer_size(copy, 200);
1929 CheckCondition(200 == rocksdb_options_get_write_buffer_size(copy));
1930 CheckCondition(100 == rocksdb_options_get_write_buffer_size(o));
1931
1932 rocksdb_options_set_db_write_buffer_size(copy, 2000);
1933 CheckCondition(2000 == rocksdb_options_get_db_write_buffer_size(copy));
1934 CheckCondition(1000 == rocksdb_options_get_db_write_buffer_size(o));
1935
1936 rocksdb_options_set_max_open_files(copy, 42);
1937 CheckCondition(42 == rocksdb_options_get_max_open_files(copy));
1938 CheckCondition(21 == rocksdb_options_get_max_open_files(o));
1939
1940 rocksdb_options_set_max_file_opening_threads(copy, 3);
1941 CheckCondition(3 == rocksdb_options_get_max_file_opening_threads(copy));
1942 CheckCondition(5 == rocksdb_options_get_max_file_opening_threads(o));
1943
1944 rocksdb_options_set_max_total_wal_size(copy, 4000);
1945 CheckCondition(4000 == rocksdb_options_get_max_total_wal_size(copy));
1946 CheckCondition(400 == rocksdb_options_get_max_total_wal_size(o));
1947
1948 rocksdb_options_set_num_levels(copy, 6);
1949 CheckCondition(6 == rocksdb_options_get_num_levels(copy));
1950 CheckCondition(7 == rocksdb_options_get_num_levels(o));
1951
1952 rocksdb_options_set_level0_file_num_compaction_trigger(copy, 14);
1953 CheckCondition(
1954 14 == rocksdb_options_get_level0_file_num_compaction_trigger(copy));
1955 CheckCondition(4 ==
1956 rocksdb_options_get_level0_file_num_compaction_trigger(o));
1957
1958 rocksdb_options_set_level0_slowdown_writes_trigger(copy, 61);
1959 CheckCondition(61 ==
1960 rocksdb_options_get_level0_slowdown_writes_trigger(copy));
1961 CheckCondition(6 == rocksdb_options_get_level0_slowdown_writes_trigger(o));
1962
1963 rocksdb_options_set_level0_stop_writes_trigger(copy, 17);
1964 CheckCondition(17 == rocksdb_options_get_level0_stop_writes_trigger(copy));
1965 CheckCondition(8 == rocksdb_options_get_level0_stop_writes_trigger(o));
1966
1967 rocksdb_options_set_target_file_size_base(copy, 128);
1968 CheckCondition(128 == rocksdb_options_get_target_file_size_base(copy));
1969 CheckCondition(256 == rocksdb_options_get_target_file_size_base(o));
1970
1971 rocksdb_options_set_target_file_size_multiplier(copy, 13);
1972 CheckCondition(13 == rocksdb_options_get_target_file_size_multiplier(copy));
1973 CheckCondition(3 == rocksdb_options_get_target_file_size_multiplier(o));
1974
1975 rocksdb_options_set_max_bytes_for_level_base(copy, 900);
1976 CheckCondition(900 == rocksdb_options_get_max_bytes_for_level_base(copy));
1977 CheckCondition(1024 == rocksdb_options_get_max_bytes_for_level_base(o));
1978
1979 rocksdb_options_set_level_compaction_dynamic_level_bytes(copy, 0);
1980 CheckCondition(
1981 0 == rocksdb_options_get_level_compaction_dynamic_level_bytes(copy));
1982 CheckCondition(1 ==
1983 rocksdb_options_get_level_compaction_dynamic_level_bytes(o));
1984
1985 rocksdb_options_set_max_bytes_for_level_multiplier(copy, 8.0);
1986 CheckCondition(8.0 ==
1987 rocksdb_options_get_max_bytes_for_level_multiplier(copy));
1988 CheckCondition(2.0 ==
1989 rocksdb_options_get_max_bytes_for_level_multiplier(o));
1990
1991 rocksdb_options_set_skip_stats_update_on_db_open(copy, 0);
1992 CheckCondition(0 == rocksdb_options_get_skip_stats_update_on_db_open(copy));
1993 CheckCondition(1 == rocksdb_options_get_skip_stats_update_on_db_open(o));
1994
1995 rocksdb_options_set_skip_checking_sst_file_sizes_on_db_open(copy, 0);
1996 CheckCondition(
1997 0 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(copy));
1998 CheckCondition(
1999 1 == rocksdb_options_get_skip_checking_sst_file_sizes_on_db_open(o));
2000
2001 rocksdb_options_set_max_write_buffer_number(copy, 2000);
2002 CheckCondition(2000 == rocksdb_options_get_max_write_buffer_number(copy));
2003 CheckCondition(97 == rocksdb_options_get_max_write_buffer_number(o));
2004
2005 rocksdb_options_set_min_write_buffer_number_to_merge(copy, 146);
2006 CheckCondition(146 ==
2007 rocksdb_options_get_min_write_buffer_number_to_merge(copy));
2008 CheckCondition(23 ==
2009 rocksdb_options_get_min_write_buffer_number_to_merge(o));
2010
2011 rocksdb_options_set_max_write_buffer_number_to_maintain(copy, 128);
2012 CheckCondition(
2013 128 == rocksdb_options_get_max_write_buffer_number_to_maintain(copy));
2014 CheckCondition(64 ==
2015 rocksdb_options_get_max_write_buffer_number_to_maintain(o));
2016
2017 rocksdb_options_set_max_write_buffer_size_to_maintain(copy, 9000);
2018 CheckCondition(9000 ==
2019 rocksdb_options_get_max_write_buffer_size_to_maintain(copy));
2020 CheckCondition(50000 ==
2021 rocksdb_options_get_max_write_buffer_size_to_maintain(o));
2022
2023 rocksdb_options_set_enable_pipelined_write(copy, 0);
2024 CheckCondition(0 == rocksdb_options_get_enable_pipelined_write(copy));
2025 CheckCondition(1 == rocksdb_options_get_enable_pipelined_write(o));
2026
2027 rocksdb_options_set_unordered_write(copy, 0);
2028 CheckCondition(0 == rocksdb_options_get_unordered_write(copy));
2029 CheckCondition(1 == rocksdb_options_get_unordered_write(o));
2030
2031 rocksdb_options_set_max_subcompactions(copy, 90001);
2032 CheckCondition(90001 == rocksdb_options_get_max_subcompactions(copy));
2033 CheckCondition(123456 == rocksdb_options_get_max_subcompactions(o));
2034
2035 rocksdb_options_set_max_background_jobs(copy, 12);
2036 CheckCondition(12 == rocksdb_options_get_max_background_jobs(copy));
2037 CheckCondition(2 == rocksdb_options_get_max_background_jobs(o));
2038
2039 rocksdb_options_set_max_background_compactions(copy, 13);
2040 CheckCondition(13 == rocksdb_options_get_max_background_compactions(copy));
2041 CheckCondition(3 == rocksdb_options_get_max_background_compactions(o));
2042
2043 rocksdb_options_set_base_background_compactions(copy, 14);
2044 CheckCondition(14 == rocksdb_options_get_base_background_compactions(copy));
2045 CheckCondition(4 == rocksdb_options_get_base_background_compactions(o));
2046
2047 rocksdb_options_set_max_background_flushes(copy, 15);
2048 CheckCondition(15 == rocksdb_options_get_max_background_flushes(copy));
2049 CheckCondition(5 == rocksdb_options_get_max_background_flushes(o));
2050
2051 rocksdb_options_set_max_log_file_size(copy, 16);
2052 CheckCondition(16 == rocksdb_options_get_max_log_file_size(copy));
2053 CheckCondition(6 == rocksdb_options_get_max_log_file_size(o));
2054
2055 rocksdb_options_set_log_file_time_to_roll(copy, 17);
2056 CheckCondition(17 == rocksdb_options_get_log_file_time_to_roll(copy));
2057 CheckCondition(7 == rocksdb_options_get_log_file_time_to_roll(o));
2058
2059 rocksdb_options_set_keep_log_file_num(copy, 18);
2060 CheckCondition(18 == rocksdb_options_get_keep_log_file_num(copy));
2061 CheckCondition(8 == rocksdb_options_get_keep_log_file_num(o));
2062
2063 rocksdb_options_set_recycle_log_file_num(copy, 19);
2064 CheckCondition(19 == rocksdb_options_get_recycle_log_file_num(copy));
2065 CheckCondition(9 == rocksdb_options_get_recycle_log_file_num(o));
2066
2067 rocksdb_options_set_soft_rate_limit(copy, 4.0);
2068 CheckCondition(4.0 == rocksdb_options_get_soft_rate_limit(copy));
2069 CheckCondition(2.0 == rocksdb_options_get_soft_rate_limit(o));
2070
2071 rocksdb_options_set_hard_rate_limit(copy, 2.0);
2072 CheckCondition(2.0 == rocksdb_options_get_hard_rate_limit(copy));
2073 CheckCondition(4.0 == rocksdb_options_get_hard_rate_limit(o));
2074
2075 rocksdb_options_set_soft_pending_compaction_bytes_limit(copy, 110);
2076 CheckCondition(
2077 110 == rocksdb_options_get_soft_pending_compaction_bytes_limit(copy));
2078 CheckCondition(10 ==
2079 rocksdb_options_get_soft_pending_compaction_bytes_limit(o));
2080
2081 rocksdb_options_set_hard_pending_compaction_bytes_limit(copy, 111);
2082 CheckCondition(
2083 111 == rocksdb_options_get_hard_pending_compaction_bytes_limit(copy));
2084 CheckCondition(11 ==
2085 rocksdb_options_get_hard_pending_compaction_bytes_limit(o));
2086
2087 rocksdb_options_set_rate_limit_delay_max_milliseconds(copy, 0);
2088 CheckCondition(0 ==
2089 rocksdb_options_get_rate_limit_delay_max_milliseconds(copy));
2090 CheckCondition(1 ==
2091 rocksdb_options_get_rate_limit_delay_max_milliseconds(o));
2092
2093 rocksdb_options_set_max_manifest_file_size(copy, 112);
2094 CheckCondition(112 == rocksdb_options_get_max_manifest_file_size(copy));
2095 CheckCondition(12 == rocksdb_options_get_max_manifest_file_size(o));
2096
2097 rocksdb_options_set_table_cache_numshardbits(copy, 113);
2098 CheckCondition(113 == rocksdb_options_get_table_cache_numshardbits(copy));
2099 CheckCondition(13 == rocksdb_options_get_table_cache_numshardbits(o));
2100
2101 rocksdb_options_set_arena_block_size(copy, 114);
2102 CheckCondition(114 == rocksdb_options_get_arena_block_size(copy));
2103 CheckCondition(14 == rocksdb_options_get_arena_block_size(o));
2104
2105 rocksdb_options_set_use_fsync(copy, 0);
2106 CheckCondition(0 == rocksdb_options_get_use_fsync(copy));
2107 CheckCondition(1 == rocksdb_options_get_use_fsync(o));
2108
2109 rocksdb_options_set_WAL_ttl_seconds(copy, 115);
2110 CheckCondition(115 == rocksdb_options_get_WAL_ttl_seconds(copy));
2111 CheckCondition(15 == rocksdb_options_get_WAL_ttl_seconds(o));
2112
2113 rocksdb_options_set_WAL_size_limit_MB(copy, 116);
2114 CheckCondition(116 == rocksdb_options_get_WAL_size_limit_MB(copy));
2115 CheckCondition(16 == rocksdb_options_get_WAL_size_limit_MB(o));
2116
2117 rocksdb_options_set_manifest_preallocation_size(copy, 117);
2118 CheckCondition(117 ==
2119 rocksdb_options_get_manifest_preallocation_size(copy));
2120 CheckCondition(17 == rocksdb_options_get_manifest_preallocation_size(o));
2121
2122 rocksdb_options_set_allow_mmap_reads(copy, 0);
2123 CheckCondition(0 == rocksdb_options_get_allow_mmap_reads(copy));
2124 CheckCondition(1 == rocksdb_options_get_allow_mmap_reads(o));
2125
2126 rocksdb_options_set_allow_mmap_writes(copy, 0);
2127 CheckCondition(0 == rocksdb_options_get_allow_mmap_writes(copy));
2128 CheckCondition(1 == rocksdb_options_get_allow_mmap_writes(o));
2129
2130 rocksdb_options_set_use_direct_reads(copy, 0);
2131 CheckCondition(0 == rocksdb_options_get_use_direct_reads(copy));
2132 CheckCondition(1 == rocksdb_options_get_use_direct_reads(o));
2133
2134 rocksdb_options_set_use_direct_io_for_flush_and_compaction(copy, 0);
2135 CheckCondition(
2136 0 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(copy));
2137 CheckCondition(
2138 1 == rocksdb_options_get_use_direct_io_for_flush_and_compaction(o));
2139
2140 rocksdb_options_set_is_fd_close_on_exec(copy, 0);
2141 CheckCondition(0 == rocksdb_options_get_is_fd_close_on_exec(copy));
2142 CheckCondition(1 == rocksdb_options_get_is_fd_close_on_exec(o));
2143
2144 rocksdb_options_set_skip_log_error_on_recovery(copy, 0);
2145 CheckCondition(0 == rocksdb_options_get_skip_log_error_on_recovery(copy));
2146 CheckCondition(1 == rocksdb_options_get_skip_log_error_on_recovery(o));
2147
2148 rocksdb_options_set_stats_dump_period_sec(copy, 218);
2149 CheckCondition(218 == rocksdb_options_get_stats_dump_period_sec(copy));
2150 CheckCondition(18 == rocksdb_options_get_stats_dump_period_sec(o));
2151
2152 rocksdb_options_set_stats_persist_period_sec(copy, 600);
2153 CheckCondition(600 == rocksdb_options_get_stats_persist_period_sec(copy));
2154 CheckCondition(5 == rocksdb_options_get_stats_persist_period_sec(o));
2155
2156 rocksdb_options_set_advise_random_on_open(copy, 0);
2157 CheckCondition(0 == rocksdb_options_get_advise_random_on_open(copy));
2158 CheckCondition(1 == rocksdb_options_get_advise_random_on_open(o));
2159
2160 rocksdb_options_set_access_hint_on_compaction_start(copy, 2);
2161 CheckCondition(2 ==
2162 rocksdb_options_get_access_hint_on_compaction_start(copy));
2163 CheckCondition(3 == rocksdb_options_get_access_hint_on_compaction_start(o));
2164
2165 rocksdb_options_set_use_adaptive_mutex(copy, 0);
2166 CheckCondition(0 == rocksdb_options_get_use_adaptive_mutex(copy));
2167 CheckCondition(1 == rocksdb_options_get_use_adaptive_mutex(o));
2168
2169 rocksdb_options_set_bytes_per_sync(copy, 219);
2170 CheckCondition(219 == rocksdb_options_get_bytes_per_sync(copy));
2171 CheckCondition(19 == rocksdb_options_get_bytes_per_sync(o));
2172
2173 rocksdb_options_set_wal_bytes_per_sync(copy, 120);
2174 CheckCondition(120 == rocksdb_options_get_wal_bytes_per_sync(copy));
2175 CheckCondition(20 == rocksdb_options_get_wal_bytes_per_sync(o));
2176
2177 rocksdb_options_set_writable_file_max_buffer_size(copy, 121);
2178 CheckCondition(121 ==
2179 rocksdb_options_get_writable_file_max_buffer_size(copy));
2180 CheckCondition(21 == rocksdb_options_get_writable_file_max_buffer_size(o));
2181
2182 rocksdb_options_set_allow_concurrent_memtable_write(copy, 0);
2183 CheckCondition(0 ==
2184 rocksdb_options_get_allow_concurrent_memtable_write(copy));
2185 CheckCondition(1 == rocksdb_options_get_allow_concurrent_memtable_write(o));
2186
2187 rocksdb_options_set_enable_write_thread_adaptive_yield(copy, 0);
2188 CheckCondition(
2189 0 == rocksdb_options_get_enable_write_thread_adaptive_yield(copy));
2190 CheckCondition(1 ==
2191 rocksdb_options_get_enable_write_thread_adaptive_yield(o));
2192
2193 rocksdb_options_set_max_sequential_skip_in_iterations(copy, 122);
2194 CheckCondition(122 ==
2195 rocksdb_options_get_max_sequential_skip_in_iterations(copy));
2196 CheckCondition(22 ==
2197 rocksdb_options_get_max_sequential_skip_in_iterations(o));
2198
2199 rocksdb_options_set_disable_auto_compactions(copy, 0);
2200 CheckCondition(0 == rocksdb_options_get_disable_auto_compactions(copy));
2201 CheckCondition(1 == rocksdb_options_get_disable_auto_compactions(o));
2202
2203 rocksdb_options_set_optimize_filters_for_hits(copy, 0);
2204 CheckCondition(0 == rocksdb_options_get_optimize_filters_for_hits(copy));
2205 CheckCondition(1 == rocksdb_options_get_optimize_filters_for_hits(o));
2206
2207 rocksdb_options_set_delete_obsolete_files_period_micros(copy, 123);
2208 CheckCondition(
2209 123 == rocksdb_options_get_delete_obsolete_files_period_micros(copy));
2210 CheckCondition(23 ==
2211 rocksdb_options_get_delete_obsolete_files_period_micros(o));
2212
2213 rocksdb_options_set_memtable_prefix_bloom_size_ratio(copy, 4.0);
2214 CheckCondition(4.0 ==
2215 rocksdb_options_get_memtable_prefix_bloom_size_ratio(copy));
2216 CheckCondition(2.0 ==
2217 rocksdb_options_get_memtable_prefix_bloom_size_ratio(o));
2218
2219 rocksdb_options_set_max_compaction_bytes(copy, 124);
2220 CheckCondition(124 == rocksdb_options_get_max_compaction_bytes(copy));
2221 CheckCondition(24 == rocksdb_options_get_max_compaction_bytes(o));
2222
2223 rocksdb_options_set_memtable_huge_page_size(copy, 125);
2224 CheckCondition(125 == rocksdb_options_get_memtable_huge_page_size(copy));
2225 CheckCondition(25 == rocksdb_options_get_memtable_huge_page_size(o));
2226
2227 rocksdb_options_set_max_successive_merges(copy, 126);
2228 CheckCondition(126 == rocksdb_options_get_max_successive_merges(copy));
2229 CheckCondition(26 == rocksdb_options_get_max_successive_merges(o));
2230
2231 rocksdb_options_set_bloom_locality(copy, 127);
2232 CheckCondition(127 == rocksdb_options_get_bloom_locality(copy));
2233 CheckCondition(27 == rocksdb_options_get_bloom_locality(o));
2234
2235 rocksdb_options_set_inplace_update_support(copy, 0);
2236 CheckCondition(0 == rocksdb_options_get_inplace_update_support(copy));
2237 CheckCondition(1 == rocksdb_options_get_inplace_update_support(o));
2238
2239 rocksdb_options_set_inplace_update_num_locks(copy, 128);
2240 CheckCondition(128 == rocksdb_options_get_inplace_update_num_locks(copy));
2241 CheckCondition(28 == rocksdb_options_get_inplace_update_num_locks(o));
2242
2243 rocksdb_options_set_report_bg_io_stats(copy, 0);
2244 CheckCondition(0 == rocksdb_options_get_report_bg_io_stats(copy));
2245 CheckCondition(1 == rocksdb_options_get_report_bg_io_stats(o));
2246
2247 rocksdb_options_set_wal_recovery_mode(copy, 1);
2248 CheckCondition(1 == rocksdb_options_get_wal_recovery_mode(copy));
2249 CheckCondition(2 == rocksdb_options_get_wal_recovery_mode(o));
2250
2251 rocksdb_options_set_compression(copy, 4);
2252 CheckCondition(4 == rocksdb_options_get_compression(copy));
2253 CheckCondition(5 == rocksdb_options_get_compression(o));
2254
2255 rocksdb_options_set_bottommost_compression(copy, 3);
2256 CheckCondition(3 == rocksdb_options_get_bottommost_compression(copy));
2257 CheckCondition(4 == rocksdb_options_get_bottommost_compression(o));
2258
2259 rocksdb_options_set_compaction_style(copy, 1);
2260 CheckCondition(1 == rocksdb_options_get_compaction_style(copy));
2261 CheckCondition(2 == rocksdb_options_get_compaction_style(o));
2262
2263 rocksdb_options_set_atomic_flush(copy, 0);
2264 CheckCondition(0 == rocksdb_options_get_atomic_flush(copy));
2265 CheckCondition(1 == rocksdb_options_get_atomic_flush(o));
2266
2267 rocksdb_options_destroy(copy);
2268 rocksdb_options_destroy(o);
2269 }
2270
2271 StartPhase("read_options");
2272 {
2273 rocksdb_readoptions_t* ro;
2274 ro = rocksdb_readoptions_create();
2275
2276 rocksdb_readoptions_set_verify_checksums(ro, 1);
2277 CheckCondition(1 == rocksdb_readoptions_get_verify_checksums(ro));
2278
2279 rocksdb_readoptions_set_fill_cache(ro, 1);
2280 CheckCondition(1 == rocksdb_readoptions_get_fill_cache(ro));
2281
2282 rocksdb_readoptions_set_read_tier(ro, 2);
2283 CheckCondition(2 == rocksdb_readoptions_get_read_tier(ro));
2284
2285 rocksdb_readoptions_set_tailing(ro, 1);
2286 CheckCondition(1 == rocksdb_readoptions_get_tailing(ro));
2287
2288 rocksdb_readoptions_set_readahead_size(ro, 100);
2289 CheckCondition(100 == rocksdb_readoptions_get_readahead_size(ro));
2290
2291 rocksdb_readoptions_set_prefix_same_as_start(ro, 1);
2292 CheckCondition(1 == rocksdb_readoptions_get_prefix_same_as_start(ro));
2293
2294 rocksdb_readoptions_set_pin_data(ro, 1);
2295 CheckCondition(1 == rocksdb_readoptions_get_pin_data(ro));
2296
2297 rocksdb_readoptions_set_total_order_seek(ro, 1);
2298 CheckCondition(1 == rocksdb_readoptions_get_total_order_seek(ro));
2299
2300 rocksdb_readoptions_set_max_skippable_internal_keys(ro, 200);
2301 CheckCondition(200 ==
2302 rocksdb_readoptions_get_max_skippable_internal_keys(ro));
2303
2304 rocksdb_readoptions_set_background_purge_on_iterator_cleanup(ro, 1);
2305 CheckCondition(
2306 1 == rocksdb_readoptions_get_background_purge_on_iterator_cleanup(ro));
2307
2308 rocksdb_readoptions_set_ignore_range_deletions(ro, 1);
2309 CheckCondition(1 == rocksdb_readoptions_get_ignore_range_deletions(ro));
2310
2311 rocksdb_readoptions_set_deadline(ro, 300);
2312 CheckCondition(300 == rocksdb_readoptions_get_deadline(ro));
2313
2314 rocksdb_readoptions_set_io_timeout(ro, 400);
2315 CheckCondition(400 == rocksdb_readoptions_get_io_timeout(ro));
2316
2317 rocksdb_readoptions_destroy(ro);
2318 }
2319
2320 StartPhase("write_options");
2321 {
2322 rocksdb_writeoptions_t* wo;
2323 wo = rocksdb_writeoptions_create();
2324
2325 rocksdb_writeoptions_set_sync(wo, 1);
2326 CheckCondition(1 == rocksdb_writeoptions_get_sync(wo));
2327
2328 rocksdb_writeoptions_disable_WAL(wo, 1);
2329 CheckCondition(1 == rocksdb_writeoptions_get_disable_WAL(wo));
2330
2331 rocksdb_writeoptions_set_ignore_missing_column_families(wo, 1);
2332 CheckCondition(1 ==
2333 rocksdb_writeoptions_get_ignore_missing_column_families(wo));
2334
2335 rocksdb_writeoptions_set_no_slowdown(wo, 1);
2336 CheckCondition(1 == rocksdb_writeoptions_get_no_slowdown(wo));
2337
2338 rocksdb_writeoptions_set_low_pri(wo, 1);
2339 CheckCondition(1 == rocksdb_writeoptions_get_low_pri(wo));
2340
2341 rocksdb_writeoptions_set_memtable_insert_hint_per_batch(wo, 1);
2342 CheckCondition(1 ==
2343 rocksdb_writeoptions_get_memtable_insert_hint_per_batch(wo));
2344
2345 rocksdb_writeoptions_destroy(wo);
2346 }
2347
2348 StartPhase("compact_options");
2349 {
2350 rocksdb_compactoptions_t* co;
2351 co = rocksdb_compactoptions_create();
2352
2353 rocksdb_compactoptions_set_exclusive_manual_compaction(co, 1);
2354 CheckCondition(1 ==
2355 rocksdb_compactoptions_get_exclusive_manual_compaction(co));
2356
2357 rocksdb_compactoptions_set_bottommost_level_compaction(co, 1);
2358 CheckCondition(1 ==
2359 rocksdb_compactoptions_get_bottommost_level_compaction(co));
2360
2361 rocksdb_compactoptions_set_change_level(co, 1);
2362 CheckCondition(1 == rocksdb_compactoptions_get_change_level(co));
2363
2364 rocksdb_compactoptions_set_target_level(co, 1);
2365 CheckCondition(1 == rocksdb_compactoptions_get_target_level(co));
2366
2367 rocksdb_compactoptions_destroy(co);
2368 }
2369
2370 StartPhase("flush_options");
2371 {
2372 rocksdb_flushoptions_t* fo;
2373 fo = rocksdb_flushoptions_create();
2374
2375 rocksdb_flushoptions_set_wait(fo, 1);
2376 CheckCondition(1 == rocksdb_flushoptions_get_wait(fo));
2377
2378 rocksdb_flushoptions_destroy(fo);
2379 }
2380
2381 StartPhase("cache_options");
2382 {
2383 rocksdb_cache_t* co;
2384 co = rocksdb_cache_create_lru(100);
2385 CheckCondition(100 == rocksdb_cache_get_capacity(co));
2386
2387 rocksdb_cache_set_capacity(co, 200);
2388 CheckCondition(200 == rocksdb_cache_get_capacity(co));
2389
2390 rocksdb_cache_destroy(co);
2391 }
2392
2393 StartPhase("jemalloc_nodump_allocator");
2394 {
2395 rocksdb_memory_allocator_t* allocator;
2396 allocator = rocksdb_jemalloc_nodump_allocator_create(&err);
2397 if (err != NULL) {
2398 // not supported on all platforms, allow unsupported error
2399 const char* ni = "Not implemented: ";
2400 size_t ni_len = strlen(ni);
2401 size_t err_len = strlen(err);
2402
2403 CheckCondition(err_len >= ni_len);
2404 CheckCondition(memcmp(ni, err, ni_len) == 0);
2405 Free(&err);
2406 } else {
2407 rocksdb_cache_t* co;
2408 rocksdb_lru_cache_options_t* copts;
2409
2410 copts = rocksdb_lru_cache_options_create();
2411
2412 rocksdb_lru_cache_options_set_capacity(copts, 100);
2413 rocksdb_lru_cache_options_set_memory_allocator(copts, allocator);
2414
2415 co = rocksdb_cache_create_lru_opts(copts);
2416 CheckCondition(100 == rocksdb_cache_get_capacity(co));
2417
2418 rocksdb_cache_destroy(co);
2419 rocksdb_lru_cache_options_destroy(copts);
2420 }
2421 rocksdb_memory_allocator_destroy(allocator);
2422 }
2423
2424 StartPhase("env");
2425 {
2426 rocksdb_env_t* e;
2427 e = rocksdb_create_default_env();
2428
2429 rocksdb_env_set_background_threads(e, 10);
2430 CheckCondition(10 == rocksdb_env_get_background_threads(e));
2431
2432 rocksdb_env_set_high_priority_background_threads(e, 20);
2433 CheckCondition(20 == rocksdb_env_get_high_priority_background_threads(e));
2434
2435 rocksdb_env_set_low_priority_background_threads(e, 30);
2436 CheckCondition(30 == rocksdb_env_get_low_priority_background_threads(e));
2437
2438 rocksdb_env_set_bottom_priority_background_threads(e, 40);
2439 CheckCondition(40 == rocksdb_env_get_bottom_priority_background_threads(e));
2440
2441 rocksdb_env_destroy(e);
2442 }
2443
2444 StartPhase("universal_compaction_options");
2445 {
2446 rocksdb_universal_compaction_options_t* uco;
2447 uco = rocksdb_universal_compaction_options_create();
2448
2449 rocksdb_universal_compaction_options_set_size_ratio(uco, 5);
2450 CheckCondition(5 ==
2451 rocksdb_universal_compaction_options_get_size_ratio(uco));
2452
2453 rocksdb_universal_compaction_options_set_min_merge_width(uco, 15);
2454 CheckCondition(
2455 15 == rocksdb_universal_compaction_options_get_min_merge_width(uco));
2456
2457 rocksdb_universal_compaction_options_set_max_merge_width(uco, 25);
2458 CheckCondition(
2459 25 == rocksdb_universal_compaction_options_get_max_merge_width(uco));
2460
2461 rocksdb_universal_compaction_options_set_max_size_amplification_percent(uco,
2462 35);
2463 CheckCondition(
2464 35 ==
2465 rocksdb_universal_compaction_options_get_max_size_amplification_percent(
2466 uco));
2467
2468 rocksdb_universal_compaction_options_set_compression_size_percent(uco, 45);
2469 CheckCondition(
2470 45 ==
2471 rocksdb_universal_compaction_options_get_compression_size_percent(uco));
2472
2473 rocksdb_universal_compaction_options_set_stop_style(uco, 1);
2474 CheckCondition(1 ==
2475 rocksdb_universal_compaction_options_get_stop_style(uco));
2476
2477 rocksdb_universal_compaction_options_destroy(uco);
2478 }
2479
2480 StartPhase("fifo_compaction_options");
2481 {
2482 rocksdb_fifo_compaction_options_t* fco;
2483 fco = rocksdb_fifo_compaction_options_create();
2484
2485 rocksdb_fifo_compaction_options_set_max_table_files_size(fco, 100000);
2486 CheckCondition(
2487 100000 ==
2488 rocksdb_fifo_compaction_options_get_max_table_files_size(fco));
2489
2490 rocksdb_fifo_compaction_options_destroy(fco);
2491 }
2492
2493 StartPhase("backupable_db_option");
2494 {
2495 rocksdb_backupable_db_options_t* bdo;
2496 bdo = rocksdb_backupable_db_options_create("path");
2497
2498 rocksdb_backupable_db_options_set_share_table_files(bdo, 1);
2499 CheckCondition(1 ==
2500 rocksdb_backupable_db_options_get_share_table_files(bdo));
2501
2502 rocksdb_backupable_db_options_set_sync(bdo, 1);
2503 CheckCondition(1 == rocksdb_backupable_db_options_get_sync(bdo));
2504
2505 rocksdb_backupable_db_options_set_destroy_old_data(bdo, 1);
2506 CheckCondition(1 ==
2507 rocksdb_backupable_db_options_get_destroy_old_data(bdo));
2508
2509 rocksdb_backupable_db_options_set_backup_log_files(bdo, 1);
2510 CheckCondition(1 ==
2511 rocksdb_backupable_db_options_get_backup_log_files(bdo));
2512
2513 rocksdb_backupable_db_options_set_backup_rate_limit(bdo, 123);
2514 CheckCondition(123 ==
2515 rocksdb_backupable_db_options_get_backup_rate_limit(bdo));
2516
2517 rocksdb_backupable_db_options_set_restore_rate_limit(bdo, 37);
2518 CheckCondition(37 ==
2519 rocksdb_backupable_db_options_get_restore_rate_limit(bdo));
2520
2521 rocksdb_backupable_db_options_set_max_background_operations(bdo, 20);
2522 CheckCondition(
2523 20 == rocksdb_backupable_db_options_get_max_background_operations(bdo));
2524
2525 rocksdb_backupable_db_options_set_callback_trigger_interval_size(bdo, 9000);
2526 CheckCondition(
2527 9000 ==
2528 rocksdb_backupable_db_options_get_callback_trigger_interval_size(bdo));
2529
2530 rocksdb_backupable_db_options_set_max_valid_backups_to_open(bdo, 40);
2531 CheckCondition(
2532 40 == rocksdb_backupable_db_options_get_max_valid_backups_to_open(bdo));
2533
2534 rocksdb_backupable_db_options_set_share_files_with_checksum_naming(bdo, 2);
2535 CheckCondition(
2536 2 == rocksdb_backupable_db_options_get_share_files_with_checksum_naming(
2537 bdo));
2538
2539 rocksdb_backupable_db_options_destroy(bdo);
2540 }
2541
2542 StartPhase("compression_options");
2543 {
2544 rocksdb_options_t* co;
2545 co = rocksdb_options_create();
2546
2547 rocksdb_options_set_compression_options_zstd_max_train_bytes(co, 100);
2548 CheckCondition(
2549 100 ==
2550 rocksdb_options_get_compression_options_zstd_max_train_bytes(co));
2551
2552 rocksdb_options_set_compression_options_parallel_threads(co, 2);
2553 CheckCondition(
2554 2 == rocksdb_options_get_compression_options_parallel_threads(co));
2555
2556 rocksdb_options_set_compression_options_max_dict_buffer_bytes(co, 200);
2557 CheckCondition(
2558 200 ==
2559 rocksdb_options_get_compression_options_max_dict_buffer_bytes(co));
2560
2561 rocksdb_options_destroy(co);
2562 }
2563
2564 StartPhase("iterate_upper_bound");
2565 {
2566 // Create new empty database
2567 rocksdb_close(db);
2568 rocksdb_destroy_db(options, dbname, &err);
2569 CheckNoError(err);
2570
2571 rocksdb_options_set_prefix_extractor(options, NULL);
2572 db = rocksdb_open(options, dbname, &err);
2573 CheckNoError(err);
2574
2575 rocksdb_put(db, woptions, "a", 1, "0", 1, &err); CheckNoError(err);
2576 rocksdb_put(db, woptions, "foo", 3, "bar", 3, &err); CheckNoError(err);
2577 rocksdb_put(db, woptions, "foo1", 4, "bar1", 4, &err); CheckNoError(err);
2578 rocksdb_put(db, woptions, "g1", 2, "0", 1, &err); CheckNoError(err);
2579
2580 // testing basic case with no iterate_upper_bound and no prefix_extractor
2581 {
2582 rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
2583 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
2584
2585 rocksdb_iter_seek(iter, "foo", 3);
2586 CheckCondition(rocksdb_iter_valid(iter));
2587 CheckIter(iter, "foo", "bar");
2588
2589 rocksdb_iter_next(iter);
2590 CheckCondition(rocksdb_iter_valid(iter));
2591 CheckIter(iter, "foo1", "bar1");
2592
2593 rocksdb_iter_next(iter);
2594 CheckCondition(rocksdb_iter_valid(iter));
2595 CheckIter(iter, "g1", "0");
2596
2597 rocksdb_iter_destroy(iter);
2598 }
2599
2600 // testing iterate_upper_bound and forward iterator
2601 // to make sure it stops at bound
2602 {
2603 // iterate_upper_bound points beyond the last expected entry
2604 rocksdb_readoptions_set_iterate_upper_bound(roptions, "foo2", 4);
2605
2606 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
2607
2608 rocksdb_iter_seek(iter, "foo", 3);
2609 CheckCondition(rocksdb_iter_valid(iter));
2610 CheckIter(iter, "foo", "bar");
2611
2612 rocksdb_iter_next(iter);
2613 CheckCondition(rocksdb_iter_valid(iter));
2614 CheckIter(iter, "foo1", "bar1");
2615
2616 rocksdb_iter_next(iter);
2617 // should stop here...
2618 CheckCondition(!rocksdb_iter_valid(iter));
2619
2620 rocksdb_iter_destroy(iter);
2621 rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
2622 }
2623 }
2624
2625 StartPhase("transactions");
2626 {
2627 rocksdb_close(db);
2628 rocksdb_destroy_db(options, dbname, &err);
2629 CheckNoError(err);
2630
2631 // open a TransactionDB
2632 txn_db_options = rocksdb_transactiondb_options_create();
2633 txn_options = rocksdb_transaction_options_create();
2634 rocksdb_options_set_create_if_missing(options, 1);
2635 txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
2636 CheckNoError(err);
2637
2638 // put outside a transaction
2639 rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hello", 5, &err);
2640 CheckNoError(err);
2641 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
2642
2643 // delete from outside transaction
2644 rocksdb_transactiondb_delete(txn_db, woptions, "foo", 3, &err);
2645 CheckNoError(err);
2646 CheckTxnDBGet(txn_db, roptions, "foo", NULL);
2647
2648 // write batch into TransactionDB
2649 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
2650 rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
2651 rocksdb_writebatch_clear(wb);
2652 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
2653 rocksdb_writebatch_put(wb, "box", 3, "c", 1);
2654 rocksdb_writebatch_delete(wb, "bar", 3);
2655 rocksdb_transactiondb_write(txn_db, woptions, wb, &err);
2656 rocksdb_writebatch_destroy(wb);
2657 CheckTxnDBGet(txn_db, roptions, "box", "c");
2658 CheckNoError(err);
2659
2660 // begin a transaction
2661 txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
2662 // put
2663 rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
2664 CheckNoError(err);
2665 CheckTxnGet(txn, roptions, "foo", "hello");
2666 // delete
2667 rocksdb_transaction_delete(txn, "foo", 3, &err);
2668 CheckNoError(err);
2669 CheckTxnGet(txn, roptions, "foo", NULL);
2670
2671 rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
2672 CheckNoError(err);
2673
2674 // read from outside transaction, before commit
2675 CheckTxnDBGet(txn_db, roptions, "foo", NULL);
2676
2677 // commit
2678 rocksdb_transaction_commit(txn, &err);
2679 CheckNoError(err);
2680
2681 // read from outside transaction, after commit
2682 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
2683
2684 // reuse old transaction
2685 txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, txn);
2686
2687 // snapshot
2688 const rocksdb_snapshot_t* snapshot;
2689 snapshot = rocksdb_transactiondb_create_snapshot(txn_db);
2690 rocksdb_readoptions_set_snapshot(roptions, snapshot);
2691
2692 rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
2693 CheckNoError(err);
2694
2695 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
2696 rocksdb_readoptions_set_snapshot(roptions, NULL);
2697 rocksdb_transactiondb_release_snapshot(txn_db, snapshot);
2698 CheckTxnDBGet(txn_db, roptions, "foo", "hey");
2699
2700 // iterate
2701 rocksdb_transaction_put(txn, "bar", 3, "hi", 2, &err);
2702 rocksdb_iterator_t* iter = rocksdb_transaction_create_iterator(txn, roptions);
2703 CheckCondition(!rocksdb_iter_valid(iter));
2704 rocksdb_iter_seek_to_first(iter);
2705 CheckCondition(rocksdb_iter_valid(iter));
2706 CheckIter(iter, "bar", "hi");
2707 rocksdb_iter_get_error(iter, &err);
2708 CheckNoError(err);
2709 rocksdb_iter_destroy(iter);
2710
2711 // rollback
2712 rocksdb_transaction_rollback(txn, &err);
2713 CheckNoError(err);
2714 CheckTxnDBGet(txn_db, roptions, "bar", NULL);
2715
2716 // save point
2717 rocksdb_transaction_put(txn, "foo1", 4, "hi1", 3, &err);
2718 rocksdb_transaction_set_savepoint(txn);
2719 CheckTxnGet(txn, roptions, "foo1", "hi1");
2720 rocksdb_transaction_put(txn, "foo2", 4, "hi2", 3, &err);
2721 CheckTxnGet(txn, roptions, "foo2", "hi2");
2722
2723 // rollback to savepoint
2724 rocksdb_transaction_rollback_to_savepoint(txn, &err);
2725 CheckNoError(err);
2726 CheckTxnGet(txn, roptions, "foo2", NULL);
2727 CheckTxnGet(txn, roptions, "foo1", "hi1");
2728 CheckTxnDBGet(txn_db, roptions, "foo1", NULL);
2729 CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
2730 rocksdb_transaction_commit(txn, &err);
2731 CheckNoError(err);
2732 CheckTxnDBGet(txn_db, roptions, "foo1", "hi1");
2733 CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
2734
2735 // Column families.
2736 rocksdb_column_family_handle_t* cfh;
2737 cfh = rocksdb_transactiondb_create_column_family(txn_db, options,
2738 "txn_db_cf", &err);
2739 CheckNoError(err);
2740
2741 rocksdb_transactiondb_put_cf(txn_db, woptions, cfh, "cf_foo", 6, "cf_hello",
2742 8, &err);
2743 CheckNoError(err);
2744 CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
2745
2746 rocksdb_transactiondb_delete_cf(txn_db, woptions, cfh, "cf_foo", 6, &err);
2747 CheckNoError(err);
2748 CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
2749
2750 rocksdb_column_family_handle_destroy(cfh);
2751
2752 // close and destroy
2753 rocksdb_transaction_destroy(txn);
2754 rocksdb_transactiondb_close(txn_db);
2755 rocksdb_destroy_db(options, dbname, &err);
2756 CheckNoError(err);
2757 rocksdb_transaction_options_destroy(txn_options);
2758 rocksdb_transactiondb_options_destroy(txn_db_options);
2759 }
2760
2761 StartPhase("optimistic_transactions");
2762 {
2763 rocksdb_options_t* db_options = rocksdb_options_create();
2764 rocksdb_options_set_create_if_missing(db_options, 1);
2765 rocksdb_options_set_allow_concurrent_memtable_write(db_options, 1);
2766 otxn_db = rocksdb_optimistictransactiondb_open(db_options, dbname, &err);
2767 otxn_options = rocksdb_optimistictransaction_options_create();
2768 rocksdb_transaction_t* txn1 = rocksdb_optimistictransaction_begin(
2769 otxn_db, woptions, otxn_options, NULL);
2770 rocksdb_transaction_t* txn2 = rocksdb_optimistictransaction_begin(
2771 otxn_db, woptions, otxn_options, NULL);
2772 rocksdb_transaction_put(txn1, "key", 3, "value", 5, &err);
2773 CheckNoError(err);
2774 rocksdb_transaction_put(txn2, "key1", 4, "value1", 6, &err);
2775 CheckNoError(err);
2776 CheckTxnGet(txn1, roptions, "key", "value");
2777 rocksdb_transaction_commit(txn1, &err);
2778 CheckNoError(err);
2779 rocksdb_transaction_commit(txn2, &err);
2780 CheckNoError(err);
2781 rocksdb_transaction_destroy(txn1);
2782 rocksdb_transaction_destroy(txn2);
2783
2784 // Check column family
2785 db = rocksdb_optimistictransactiondb_get_base_db(otxn_db);
2786 rocksdb_put(db, woptions, "key", 3, "value", 5, &err);
2787 CheckNoError(err);
2788 rocksdb_column_family_handle_t *cfh1, *cfh2;
2789 cfh1 = rocksdb_create_column_family(db, db_options, "txn_db_cf1", &err);
2790 cfh2 = rocksdb_create_column_family(db, db_options, "txn_db_cf2", &err);
2791 txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
2792 NULL);
2793 rocksdb_transaction_put_cf(txn, cfh1, "key_cf1", 7, "val_cf1", 7, &err);
2794 CheckNoError(err);
2795 rocksdb_transaction_put_cf(txn, cfh2, "key_cf2", 7, "val_cf2", 7, &err);
2796 CheckNoError(err);
2797 rocksdb_transaction_commit(txn, &err);
2798 CheckNoError(err);
2799 txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
2800 txn);
2801 CheckGetCF(db, roptions, cfh1, "key_cf1", "val_cf1");
2802 CheckTxnGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
2803
2804 // Check iterator with column family
2805 rocksdb_transaction_put_cf(txn, cfh1, "key1_cf", 7, "val1_cf", 7, &err);
2806 CheckNoError(err);
2807 rocksdb_iterator_t* iter =
2808 rocksdb_transaction_create_iterator_cf(txn, roptions, cfh1);
2809 CheckCondition(!rocksdb_iter_valid(iter));
2810 rocksdb_iter_seek_to_first(iter);
2811 CheckCondition(rocksdb_iter_valid(iter));
2812 CheckIter(iter, "key1_cf", "val1_cf");
2813 rocksdb_iter_get_error(iter, &err);
2814 CheckNoError(err);
2815 rocksdb_iter_destroy(iter);
2816
2817 rocksdb_transaction_destroy(txn);
2818 rocksdb_column_family_handle_destroy(cfh1);
2819 rocksdb_column_family_handle_destroy(cfh2);
2820 rocksdb_optimistictransactiondb_close_base_db(db);
2821 rocksdb_optimistictransactiondb_close(otxn_db);
2822
2823 // Check open optimistic transaction db with column families
2824 size_t cf_len;
2825 char** column_fams =
2826 rocksdb_list_column_families(db_options, dbname, &cf_len, &err);
2827 CheckNoError(err);
2828 CheckEqual("default", column_fams[0], 7);
2829 CheckEqual("txn_db_cf1", column_fams[1], 10);
2830 CheckEqual("txn_db_cf2", column_fams[2], 10);
2831 CheckCondition(cf_len == 3);
2832 rocksdb_list_column_families_destroy(column_fams, cf_len);
2833
2834 const char* cf_names[3] = {"default", "txn_db_cf1", "txn_db_cf2"};
2835 rocksdb_options_t* cf_options = rocksdb_options_create();
2836 const rocksdb_options_t* cf_opts[3] = {cf_options, cf_options, cf_options};
2837
2838 rocksdb_options_set_error_if_exists(cf_options, 0);
2839 rocksdb_column_family_handle_t* cf_handles[3];
2840 otxn_db = rocksdb_optimistictransactiondb_open_column_families(
2841 db_options, dbname, 3, cf_names, cf_opts, cf_handles, &err);
2842 CheckNoError(err);
2843 rocksdb_transaction_t* txn_cf = rocksdb_optimistictransaction_begin(
2844 otxn_db, woptions, otxn_options, NULL);
2845 CheckTxnGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
2846 CheckTxnGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
2847 CheckTxnGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
2848 rocksdb_transaction_destroy(txn_cf);
2849 rocksdb_options_destroy(cf_options);
2850 rocksdb_column_family_handle_destroy(cf_handles[0]);
2851 rocksdb_column_family_handle_destroy(cf_handles[1]);
2852 rocksdb_column_family_handle_destroy(cf_handles[2]);
2853 rocksdb_optimistictransactiondb_close(otxn_db);
2854 rocksdb_destroy_db(db_options, dbname, &err);
2855 rocksdb_options_destroy(db_options);
2856 rocksdb_optimistictransaction_options_destroy(otxn_options);
2857 CheckNoError(err);
2858 }
2859
2860 // Simple sanity check that setting memtable rep works.
2861 StartPhase("memtable_reps");
2862 {
2863 // Create database with vector memtable.
2864 rocksdb_options_set_memtable_vector_rep(options);
2865 db = rocksdb_open(options, dbname, &err);
2866 CheckNoError(err);
2867
2868 // Create database with hash skiplist memtable.
2869 rocksdb_close(db);
2870 rocksdb_destroy_db(options, dbname, &err);
2871 CheckNoError(err);
2872
2873 rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
2874 db = rocksdb_open(options, dbname, &err);
2875 CheckNoError(err);
2876 }
2877
2878 // Check that secondary instance works.
2879 StartPhase("open_as_secondary");
2880 {
2881 rocksdb_close(db);
2882 rocksdb_destroy_db(options, dbname, &err);
2883
2884 rocksdb_options_t* db_options = rocksdb_options_create();
2885 rocksdb_options_set_create_if_missing(db_options, 1);
2886 db = rocksdb_open(db_options, dbname, &err);
2887 CheckNoError(err);
2888 rocksdb_t* db1;
2889 rocksdb_options_t* opts = rocksdb_options_create();
2890 rocksdb_options_set_max_open_files(opts, -1);
2891 rocksdb_options_set_create_if_missing(opts, 1);
2892 snprintf(secondary_path, sizeof(secondary_path),
2893 "%s/rocksdb_c_test_secondary-%d", GetTempDir(), ((int)geteuid()));
2894 db1 = rocksdb_open_as_secondary(opts, dbname, secondary_path, &err);
2895 CheckNoError(err);
2896
2897 rocksdb_writeoptions_set_sync(woptions, 0);
2898 rocksdb_writeoptions_disable_WAL(woptions, 1);
2899 rocksdb_put(db, woptions, "key0", 4, "value0", 6, &err);
2900 CheckNoError(err);
2901 rocksdb_flushoptions_t* flush_opts = rocksdb_flushoptions_create();
2902 rocksdb_flushoptions_set_wait(flush_opts, 1);
2903 rocksdb_flush(db, flush_opts, &err);
2904 CheckNoError(err);
2905 rocksdb_try_catch_up_with_primary(db1, &err);
2906 CheckNoError(err);
2907 rocksdb_readoptions_t* ropts = rocksdb_readoptions_create();
2908 rocksdb_readoptions_set_verify_checksums(ropts, 1);
2909 rocksdb_readoptions_set_snapshot(ropts, NULL);
2910 CheckGet(db, ropts, "key0", "value0");
2911 CheckGet(db1, ropts, "key0", "value0");
2912
2913 rocksdb_writeoptions_disable_WAL(woptions, 0);
2914 rocksdb_put(db, woptions, "key1", 4, "value1", 6, &err);
2915 CheckNoError(err);
2916 rocksdb_try_catch_up_with_primary(db1, &err);
2917 CheckNoError(err);
2918 CheckGet(db1, ropts, "key0", "value0");
2919 CheckGet(db1, ropts, "key1", "value1");
2920
2921 rocksdb_close(db1);
2922 rocksdb_destroy_db(opts, secondary_path, &err);
2923 CheckNoError(err);
2924
2925 rocksdb_options_destroy(db_options);
2926 rocksdb_options_destroy(opts);
2927 rocksdb_readoptions_destroy(ropts);
2928 rocksdb_flushoptions_destroy(flush_opts);
2929 }
2930
2931 // Simple sanity check that options setting db_paths work.
2932 StartPhase("open_db_paths");
2933 {
2934 rocksdb_close(db);
2935 rocksdb_destroy_db(options, dbname, &err);
2936
2937 const rocksdb_dbpath_t* paths[1] = {dbpath};
2938 rocksdb_options_set_db_paths(options, paths, 1);
2939 db = rocksdb_open(options, dbname, &err);
2940 CheckNoError(err);
2941 }
2942
2943 StartPhase("cancel_all_background_work");
2944 rocksdb_cancel_all_background_work(db, 1);
2945
2946 StartPhase("cleanup");
2947 rocksdb_close(db);
2948 rocksdb_options_destroy(options);
2949 rocksdb_block_based_options_destroy(table_options);
2950 rocksdb_readoptions_destroy(roptions);
2951 rocksdb_writeoptions_destroy(woptions);
2952 rocksdb_compactoptions_destroy(coptions);
2953 rocksdb_cache_destroy(cache);
2954 rocksdb_comparator_destroy(cmp);
2955 rocksdb_dbpath_destroy(dbpath);
2956 rocksdb_env_destroy(env);
2957
2958 fprintf(stderr, "PASS\n");
2959 return 0;
2960 }
2961
2962 #else
2963
main(void)2964 int main(void) {
2965 fprintf(stderr, "SKIPPED\n");
2966 return 0;
2967 }
2968
2969 #endif // !ROCKSDB_LITE
2970