]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/c_test.c
import 14.2.4 nautilus point release
[ceph.git] / ceph / src / rocksdb / db / c_test.c
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
5 #include <stdio.h>
6
7 #ifndef ROCKSDB_LITE // Lite does not support C API
8
9 #include "rocksdb/c.h"
10
11 #include <stddef.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include <sys/types.h>
15 #ifndef OS_WIN
16 #include <unistd.h>
17 #endif
18 #include <inttypes.h>
19
20 // Can not use port/port.h macros as this is a c file
21 #ifdef OS_WIN
22 #include <windows.h>
23
24 // Ok for uniqueness
25 int geteuid() {
26 int result = 0;
27
28 result = ((int)GetCurrentProcessId() << 16);
29 result |= (int)GetCurrentThreadId();
30
31 return result;
32 }
33
34 // VS < 2015
35 #if defined(_MSC_VER) && (_MSC_VER < 1900)
36 #define snprintf _snprintf
37 #endif
38
39 #endif
40
41 const char* phase = "";
42 static char dbname[200];
43 static char sstfilename[200];
44 static char dbbackupname[200];
45 static char dbcheckpointname[200];
46 static char dbpathname[200];
47
48 static void StartPhase(const char* name) {
49 fprintf(stderr, "=== Test %s\n", name);
50 phase = name;
51 }
52 #ifdef _MSC_VER
53 #pragma warning(push)
54 #pragma warning (disable: 4996) // getenv security warning
55 #endif
56 static const char* GetTempDir(void) {
57 const char* ret = getenv("TEST_TMPDIR");
58 if (ret == NULL || ret[0] == '\0')
59 ret = "/tmp";
60 return ret;
61 }
62 #ifdef _MSC_VER
63 #pragma warning(pop)
64 #endif
65
66 #define CheckNoError(err) \
67 if ((err) != NULL) { \
68 fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, (err)); \
69 abort(); \
70 }
71
72 #define CheckCondition(cond) \
73 if (!(cond)) { \
74 fprintf(stderr, "%s:%d: %s: %s\n", __FILE__, __LINE__, phase, #cond); \
75 abort(); \
76 }
77
78 static void CheckEqual(const char* expected, const char* v, size_t n) {
79 if (expected == NULL && v == NULL) {
80 // ok
81 } else if (expected != NULL && v != NULL && n == strlen(expected) &&
82 memcmp(expected, v, n) == 0) {
83 // ok
84 return;
85 } else {
86 fprintf(stderr, "%s: expected '%s', got '%s'\n",
87 phase,
88 (expected ? expected : "(null)"),
89 (v ? v : "(null"));
90 abort();
91 }
92 }
93
94 static void Free(char** ptr) {
95 if (*ptr) {
96 free(*ptr);
97 *ptr = NULL;
98 }
99 }
100
101 static void CheckValue(
102 char* err,
103 const char* expected,
104 char** actual,
105 size_t actual_length) {
106 CheckNoError(err);
107 CheckEqual(expected, *actual, actual_length);
108 Free(actual);
109 }
110
111 static void CheckGet(
112 rocksdb_t* db,
113 const rocksdb_readoptions_t* options,
114 const char* key,
115 const char* expected) {
116 char* err = NULL;
117 size_t val_len;
118 char* val;
119 val = rocksdb_get(db, options, key, strlen(key), &val_len, &err);
120 CheckNoError(err);
121 CheckEqual(expected, val, val_len);
122 Free(&val);
123 }
124
125 static void CheckGetCF(
126 rocksdb_t* db,
127 const rocksdb_readoptions_t* options,
128 rocksdb_column_family_handle_t* handle,
129 const char* key,
130 const char* expected) {
131 char* err = NULL;
132 size_t val_len;
133 char* val;
134 val = rocksdb_get_cf(db, options, handle, key, strlen(key), &val_len, &err);
135 CheckNoError(err);
136 CheckEqual(expected, val, val_len);
137 Free(&val);
138 }
139
140 static void CheckPinGet(rocksdb_t* db, const rocksdb_readoptions_t* options,
141 const char* key, const char* expected) {
142 char* err = NULL;
143 size_t val_len;
144 const char* val;
145 rocksdb_pinnableslice_t* p;
146 p = rocksdb_get_pinned(db, options, key, strlen(key), &err);
147 CheckNoError(err);
148 val = rocksdb_pinnableslice_value(p, &val_len);
149 CheckEqual(expected, val, val_len);
150 rocksdb_pinnableslice_destroy(p);
151 }
152
153 static void CheckPinGetCF(rocksdb_t* db, const rocksdb_readoptions_t* options,
154 rocksdb_column_family_handle_t* handle,
155 const char* key, const char* expected) {
156 char* err = NULL;
157 size_t val_len;
158 const char* val;
159 rocksdb_pinnableslice_t* p;
160 p = rocksdb_get_pinned_cf(db, options, handle, key, strlen(key), &err);
161 CheckNoError(err);
162 val = rocksdb_pinnableslice_value(p, &val_len);
163 CheckEqual(expected, val, val_len);
164 rocksdb_pinnableslice_destroy(p);
165 }
166
167 static void CheckIter(rocksdb_iterator_t* iter,
168 const char* key, const char* val) {
169 size_t len;
170 const char* str;
171 str = rocksdb_iter_key(iter, &len);
172 CheckEqual(key, str, len);
173 str = rocksdb_iter_value(iter, &len);
174 CheckEqual(val, str, len);
175 }
176
177 // Callback from rocksdb_writebatch_iterate()
178 static void CheckPut(void* ptr,
179 const char* k, size_t klen,
180 const char* v, size_t vlen) {
181 int* state = (int*) ptr;
182 CheckCondition(*state < 2);
183 switch (*state) {
184 case 0:
185 CheckEqual("bar", k, klen);
186 CheckEqual("b", v, vlen);
187 break;
188 case 1:
189 CheckEqual("box", k, klen);
190 CheckEqual("c", v, vlen);
191 break;
192 }
193 (*state)++;
194 }
195
196 // Callback from rocksdb_writebatch_iterate()
197 static void CheckDel(void* ptr, const char* k, size_t klen) {
198 int* state = (int*) ptr;
199 CheckCondition(*state == 2);
200 CheckEqual("bar", k, klen);
201 (*state)++;
202 }
203
204 static void CmpDestroy(void* arg) { (void)arg; }
205
206 static int CmpCompare(void* arg, const char* a, size_t alen,
207 const char* b, size_t blen) {
208 (void)arg;
209 size_t n = (alen < blen) ? alen : blen;
210 int r = memcmp(a, b, n);
211 if (r == 0) {
212 if (alen < blen) r = -1;
213 else if (alen > blen) r = +1;
214 }
215 return r;
216 }
217
218 static const char* CmpName(void* arg) {
219 (void)arg;
220 return "foo";
221 }
222
223 // Custom filter policy
224 static unsigned char fake_filter_result = 1;
225 static void FilterDestroy(void* arg) { (void)arg; }
226 static const char* FilterName(void* arg) {
227 (void)arg;
228 return "TestFilter";
229 }
230 static char* FilterCreate(
231 void* arg,
232 const char* const* key_array, const size_t* key_length_array,
233 int num_keys,
234 size_t* filter_length) {
235 (void)arg;
236 (void)key_array;
237 (void)key_length_array;
238 (void)num_keys;
239 *filter_length = 4;
240 char* result = malloc(4);
241 memcpy(result, "fake", 4);
242 return result;
243 }
244 static unsigned char FilterKeyMatch(
245 void* arg,
246 const char* key, size_t length,
247 const char* filter, size_t filter_length) {
248 (void)arg;
249 (void)key;
250 (void)length;
251 CheckCondition(filter_length == 4);
252 CheckCondition(memcmp(filter, "fake", 4) == 0);
253 return fake_filter_result;
254 }
255
256 // Custom compaction filter
257 static void CFilterDestroy(void* arg) { (void)arg; }
258 static const char* CFilterName(void* arg) {
259 (void)arg;
260 return "foo";
261 }
262 static unsigned char CFilterFilter(void* arg, int level, const char* key,
263 size_t key_length,
264 const char* existing_value,
265 size_t value_length, char** new_value,
266 size_t* new_value_length,
267 unsigned char* value_changed) {
268 (void)arg;
269 (void)level;
270 (void)existing_value;
271 (void)value_length;
272 if (key_length == 3) {
273 if (memcmp(key, "bar", key_length) == 0) {
274 return 1;
275 } else if (memcmp(key, "baz", key_length) == 0) {
276 *value_changed = 1;
277 *new_value = "newbazvalue";
278 *new_value_length = 11;
279 return 0;
280 }
281 }
282 return 0;
283 }
284
285 static void CFilterFactoryDestroy(void* arg) { (void)arg; }
286 static const char* CFilterFactoryName(void* arg) {
287 (void)arg;
288 return "foo";
289 }
290 static rocksdb_compactionfilter_t* CFilterCreate(
291 void* arg, rocksdb_compactionfiltercontext_t* context) {
292 (void)arg;
293 (void)context;
294 return rocksdb_compactionfilter_create(NULL, CFilterDestroy, CFilterFilter,
295 CFilterName);
296 }
297
298 static rocksdb_t* CheckCompaction(rocksdb_t* db, rocksdb_options_t* options,
299 rocksdb_readoptions_t* roptions,
300 rocksdb_writeoptions_t* woptions) {
301 char* err = NULL;
302 db = rocksdb_open(options, dbname, &err);
303 CheckNoError(err);
304 rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
305 CheckNoError(err);
306 CheckGet(db, roptions, "foo", "foovalue");
307 rocksdb_put(db, woptions, "bar", 3, "barvalue", 8, &err);
308 CheckNoError(err);
309 CheckGet(db, roptions, "bar", "barvalue");
310 rocksdb_put(db, woptions, "baz", 3, "bazvalue", 8, &err);
311 CheckNoError(err);
312 CheckGet(db, roptions, "baz", "bazvalue");
313
314 // Force compaction
315 rocksdb_compact_range(db, NULL, 0, NULL, 0);
316 // should have filtered bar, but not foo
317 CheckGet(db, roptions, "foo", "foovalue");
318 CheckGet(db, roptions, "bar", NULL);
319 CheckGet(db, roptions, "baz", "newbazvalue");
320 return db;
321 }
322
323 // Custom merge operator
324 static void MergeOperatorDestroy(void* arg) { (void)arg; }
325 static const char* MergeOperatorName(void* arg) {
326 (void)arg;
327 return "TestMergeOperator";
328 }
329 static char* MergeOperatorFullMerge(
330 void* arg,
331 const char* key, size_t key_length,
332 const char* existing_value, size_t existing_value_length,
333 const char* const* operands_list, const size_t* operands_list_length,
334 int num_operands,
335 unsigned char* success, size_t* new_value_length) {
336 (void)arg;
337 (void)key;
338 (void)key_length;
339 (void)existing_value;
340 (void)existing_value_length;
341 (void)operands_list;
342 (void)operands_list_length;
343 (void)num_operands;
344 *new_value_length = 4;
345 *success = 1;
346 char* result = malloc(4);
347 memcpy(result, "fake", 4);
348 return result;
349 }
350 static char* MergeOperatorPartialMerge(
351 void* arg,
352 const char* key, size_t key_length,
353 const char* const* operands_list, const size_t* operands_list_length,
354 int num_operands,
355 unsigned char* success, size_t* new_value_length) {
356 (void)arg;
357 (void)key;
358 (void)key_length;
359 (void)operands_list;
360 (void)operands_list_length;
361 (void)num_operands;
362 *new_value_length = 4;
363 *success = 1;
364 char* result = malloc(4);
365 memcpy(result, "fake", 4);
366 return result;
367 }
368
369 static void CheckTxnGet(
370 rocksdb_transaction_t* txn,
371 const rocksdb_readoptions_t* options,
372 const char* key,
373 const char* expected) {
374 char* err = NULL;
375 size_t val_len;
376 char* val;
377 val = rocksdb_transaction_get(txn, options, key, strlen(key), &val_len, &err);
378 CheckNoError(err);
379 CheckEqual(expected, val, val_len);
380 Free(&val);
381 }
382
383 static void CheckTxnGetCF(rocksdb_transaction_t* txn,
384 const rocksdb_readoptions_t* options,
385 rocksdb_column_family_handle_t* column_family,
386 const char* key, const char* expected) {
387 char* err = NULL;
388 size_t val_len;
389 char* val;
390 val = rocksdb_transaction_get_cf(txn, options, column_family, key,
391 strlen(key), &val_len, &err);
392 CheckNoError(err);
393 CheckEqual(expected, val, val_len);
394 Free(&val);
395 }
396
397 static void CheckTxnDBGet(
398 rocksdb_transactiondb_t* txn_db,
399 const rocksdb_readoptions_t* options,
400 const char* key,
401 const char* expected) {
402 char* err = NULL;
403 size_t val_len;
404 char* val;
405 val = rocksdb_transactiondb_get(txn_db, options, key, strlen(key), &val_len, &err);
406 CheckNoError(err);
407 CheckEqual(expected, val, val_len);
408 Free(&val);
409 }
410
411 static void CheckTxnDBGetCF(rocksdb_transactiondb_t* txn_db,
412 const rocksdb_readoptions_t* options,
413 rocksdb_column_family_handle_t* column_family,
414 const char* key, const char* expected) {
415 char* err = NULL;
416 size_t val_len;
417 char* val;
418 val = rocksdb_transactiondb_get_cf(txn_db, options, column_family, key,
419 strlen(key), &val_len, &err);
420 CheckNoError(err);
421 CheckEqual(expected, val, val_len);
422 Free(&val);
423 }
424
425 int main(int argc, char** argv) {
426 (void)argc;
427 (void)argv;
428 rocksdb_t* db;
429 rocksdb_comparator_t* cmp;
430 rocksdb_cache_t* cache;
431 rocksdb_dbpath_t *dbpath;
432 rocksdb_env_t* env;
433 rocksdb_options_t* options;
434 rocksdb_compactoptions_t* coptions;
435 rocksdb_block_based_table_options_t* table_options;
436 rocksdb_readoptions_t* roptions;
437 rocksdb_writeoptions_t* woptions;
438 rocksdb_ratelimiter_t* rate_limiter;
439 rocksdb_transactiondb_t* txn_db;
440 rocksdb_transactiondb_options_t* txn_db_options;
441 rocksdb_transaction_t* txn;
442 rocksdb_transaction_options_t* txn_options;
443 rocksdb_optimistictransactiondb_t* otxn_db;
444 rocksdb_optimistictransaction_options_t* otxn_options;
445 char* err = NULL;
446 int run = -1;
447
448 snprintf(dbname, sizeof(dbname),
449 "%s/rocksdb_c_test-%d",
450 GetTempDir(),
451 ((int) geteuid()));
452
453 snprintf(dbbackupname, sizeof(dbbackupname),
454 "%s/rocksdb_c_test-%d-backup",
455 GetTempDir(),
456 ((int) geteuid()));
457
458 snprintf(dbcheckpointname, sizeof(dbcheckpointname),
459 "%s/rocksdb_c_test-%d-checkpoint",
460 GetTempDir(),
461 ((int) geteuid()));
462
463 snprintf(sstfilename, sizeof(sstfilename),
464 "%s/rocksdb_c_test-%d-sst",
465 GetTempDir(),
466 ((int)geteuid()));
467
468 snprintf(dbpathname, sizeof(dbpathname),
469 "%s/rocksdb_c_test-%d-dbpath",
470 GetTempDir(),
471 ((int) geteuid()));
472
473 StartPhase("create_objects");
474 cmp = rocksdb_comparator_create(NULL, CmpDestroy, CmpCompare, CmpName);
475 dbpath = rocksdb_dbpath_create(dbpathname, 1024 * 1024);
476 env = rocksdb_create_default_env();
477 cache = rocksdb_cache_create_lru(100000);
478
479 options = rocksdb_options_create();
480 rocksdb_options_set_comparator(options, cmp);
481 rocksdb_options_set_error_if_exists(options, 1);
482 rocksdb_options_set_env(options, env);
483 rocksdb_options_set_info_log(options, NULL);
484 rocksdb_options_set_write_buffer_size(options, 100000);
485 rocksdb_options_set_paranoid_checks(options, 1);
486 rocksdb_options_set_max_open_files(options, 10);
487 rocksdb_options_set_base_background_compactions(options, 1);
488 table_options = rocksdb_block_based_options_create();
489 rocksdb_block_based_options_set_block_cache(table_options, cache);
490 rocksdb_options_set_block_based_table_factory(options, table_options);
491
492 rocksdb_options_set_compression(options, rocksdb_no_compression);
493 rocksdb_options_set_compression_options(options, -14, -1, 0, 0);
494 int compression_levels[] = {rocksdb_no_compression, rocksdb_no_compression,
495 rocksdb_no_compression, rocksdb_no_compression};
496 rocksdb_options_set_compression_per_level(options, compression_levels, 4);
497 rate_limiter = rocksdb_ratelimiter_create(1000 * 1024 * 1024, 100 * 1000, 10);
498 rocksdb_options_set_ratelimiter(options, rate_limiter);
499 rocksdb_ratelimiter_destroy(rate_limiter);
500
501 roptions = rocksdb_readoptions_create();
502 rocksdb_readoptions_set_verify_checksums(roptions, 1);
503 rocksdb_readoptions_set_fill_cache(roptions, 1);
504
505 woptions = rocksdb_writeoptions_create();
506 rocksdb_writeoptions_set_sync(woptions, 1);
507
508 coptions = rocksdb_compactoptions_create();
509 rocksdb_compactoptions_set_exclusive_manual_compaction(coptions, 1);
510
511 StartPhase("destroy");
512 rocksdb_destroy_db(options, dbname, &err);
513 Free(&err);
514
515 StartPhase("open_error");
516 rocksdb_open(options, dbname, &err);
517 CheckCondition(err != NULL);
518 Free(&err);
519
520 StartPhase("open");
521 rocksdb_options_set_create_if_missing(options, 1);
522 db = rocksdb_open(options, dbname, &err);
523 CheckNoError(err);
524 CheckGet(db, roptions, "foo", NULL);
525
526 StartPhase("put");
527 rocksdb_put(db, woptions, "foo", 3, "hello", 5, &err);
528 CheckNoError(err);
529 CheckGet(db, roptions, "foo", "hello");
530
531 StartPhase("backup_and_restore");
532 {
533 rocksdb_destroy_db(options, dbbackupname, &err);
534 CheckNoError(err);
535
536 rocksdb_backup_engine_t *be = rocksdb_backup_engine_open(options, dbbackupname, &err);
537 CheckNoError(err);
538
539 rocksdb_backup_engine_create_new_backup(be, db, &err);
540 CheckNoError(err);
541
542 // need a change to trigger a new backup
543 rocksdb_delete(db, woptions, "does-not-exist", 14, &err);
544 CheckNoError(err);
545
546 rocksdb_backup_engine_create_new_backup(be, db, &err);
547 CheckNoError(err);
548
549 const rocksdb_backup_engine_info_t* bei = rocksdb_backup_engine_get_backup_info(be);
550 CheckCondition(rocksdb_backup_engine_info_count(bei) > 1);
551 rocksdb_backup_engine_info_destroy(bei);
552
553 rocksdb_backup_engine_purge_old_backups(be, 1, &err);
554 CheckNoError(err);
555
556 bei = rocksdb_backup_engine_get_backup_info(be);
557 CheckCondition(rocksdb_backup_engine_info_count(bei) == 1);
558 rocksdb_backup_engine_info_destroy(bei);
559
560 rocksdb_delete(db, woptions, "foo", 3, &err);
561 CheckNoError(err);
562
563 rocksdb_close(db);
564
565 rocksdb_destroy_db(options, dbname, &err);
566 CheckNoError(err);
567
568 rocksdb_restore_options_t *restore_options = rocksdb_restore_options_create();
569 rocksdb_restore_options_set_keep_log_files(restore_options, 0);
570 rocksdb_backup_engine_restore_db_from_latest_backup(be, dbname, dbname, restore_options, &err);
571 CheckNoError(err);
572 rocksdb_restore_options_destroy(restore_options);
573
574 rocksdb_options_set_error_if_exists(options, 0);
575 db = rocksdb_open(options, dbname, &err);
576 CheckNoError(err);
577 rocksdb_options_set_error_if_exists(options, 1);
578
579 CheckGet(db, roptions, "foo", "hello");
580
581 rocksdb_backup_engine_close(be);
582 }
583
584 StartPhase("checkpoint");
585 {
586 rocksdb_destroy_db(options, dbcheckpointname, &err);
587 CheckNoError(err);
588
589 rocksdb_checkpoint_t* checkpoint = rocksdb_checkpoint_object_create(db, &err);
590 CheckNoError(err);
591
592 rocksdb_checkpoint_create(checkpoint, dbcheckpointname, 0, &err);
593 CheckNoError(err);
594
595 // start a new database from the checkpoint
596 rocksdb_close(db);
597 rocksdb_options_set_error_if_exists(options, 0);
598 db = rocksdb_open(options, dbcheckpointname, &err);
599 CheckNoError(err);
600
601 CheckGet(db, roptions, "foo", "hello");
602
603 rocksdb_checkpoint_object_destroy(checkpoint);
604
605 rocksdb_close(db);
606 rocksdb_destroy_db(options, dbcheckpointname, &err);
607 CheckNoError(err);
608
609 db = rocksdb_open(options, dbname, &err);
610 CheckNoError(err);
611 rocksdb_options_set_error_if_exists(options, 1);
612 }
613
614 StartPhase("compactall");
615 rocksdb_compact_range(db, NULL, 0, NULL, 0);
616 CheckGet(db, roptions, "foo", "hello");
617
618 StartPhase("compactrange");
619 rocksdb_compact_range(db, "a", 1, "z", 1);
620 CheckGet(db, roptions, "foo", "hello");
621
622 StartPhase("compactallopt");
623 rocksdb_compact_range_opt(db, coptions, NULL, 0, NULL, 0);
624 CheckGet(db, roptions, "foo", "hello");
625
626 StartPhase("compactrangeopt");
627 rocksdb_compact_range_opt(db, coptions, "a", 1, "z", 1);
628 CheckGet(db, roptions, "foo", "hello");
629
630 // Simple check cache usage
631 StartPhase("cache_usage");
632 {
633 rocksdb_readoptions_set_pin_data(roptions, 1);
634 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
635 rocksdb_iter_seek(iter, "foo", 3);
636
637 size_t usage = rocksdb_cache_get_usage(cache);
638 CheckCondition(usage > 0);
639
640 size_t pin_usage = rocksdb_cache_get_pinned_usage(cache);
641 CheckCondition(pin_usage > 0);
642
643 rocksdb_iter_next(iter);
644 rocksdb_iter_destroy(iter);
645 rocksdb_readoptions_set_pin_data(roptions, 0);
646 }
647
648 StartPhase("addfile");
649 {
650 rocksdb_envoptions_t* env_opt = rocksdb_envoptions_create();
651 rocksdb_options_t* io_options = rocksdb_options_create();
652 rocksdb_sstfilewriter_t* writer =
653 rocksdb_sstfilewriter_create(env_opt, io_options);
654
655 remove(sstfilename);
656 rocksdb_sstfilewriter_open(writer, sstfilename, &err);
657 CheckNoError(err);
658 rocksdb_sstfilewriter_put(writer, "sstk1", 5, "v1", 2, &err);
659 CheckNoError(err);
660 rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v2", 2, &err);
661 CheckNoError(err);
662 rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v3", 2, &err);
663 CheckNoError(err);
664 rocksdb_sstfilewriter_finish(writer, &err);
665 CheckNoError(err);
666
667 rocksdb_ingestexternalfileoptions_t* ing_opt =
668 rocksdb_ingestexternalfileoptions_create();
669 const char* file_list[1] = {sstfilename};
670 rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
671 CheckNoError(err);
672 CheckGet(db, roptions, "sstk1", "v1");
673 CheckGet(db, roptions, "sstk2", "v2");
674 CheckGet(db, roptions, "sstk3", "v3");
675
676 remove(sstfilename);
677 rocksdb_sstfilewriter_open(writer, sstfilename, &err);
678 CheckNoError(err);
679 rocksdb_sstfilewriter_put(writer, "sstk2", 5, "v4", 2, &err);
680 CheckNoError(err);
681 rocksdb_sstfilewriter_put(writer, "sstk22", 6, "v5", 2, &err);
682 CheckNoError(err);
683 rocksdb_sstfilewriter_put(writer, "sstk3", 5, "v6", 2, &err);
684 CheckNoError(err);
685 rocksdb_sstfilewriter_finish(writer, &err);
686 CheckNoError(err);
687
688 rocksdb_ingest_external_file(db, file_list, 1, ing_opt, &err);
689 CheckNoError(err);
690 CheckGet(db, roptions, "sstk1", "v1");
691 CheckGet(db, roptions, "sstk2", "v4");
692 CheckGet(db, roptions, "sstk22", "v5");
693 CheckGet(db, roptions, "sstk3", "v6");
694
695 rocksdb_ingestexternalfileoptions_destroy(ing_opt);
696 rocksdb_sstfilewriter_destroy(writer);
697 rocksdb_options_destroy(io_options);
698 rocksdb_envoptions_destroy(env_opt);
699
700 // Delete all keys we just ingested
701 rocksdb_delete(db, woptions, "sstk1", 5, &err);
702 CheckNoError(err);
703 rocksdb_delete(db, woptions, "sstk2", 5, &err);
704 CheckNoError(err);
705 rocksdb_delete(db, woptions, "sstk22", 6, &err);
706 CheckNoError(err);
707 rocksdb_delete(db, woptions, "sstk3", 5, &err);
708 CheckNoError(err);
709 }
710
711 StartPhase("writebatch");
712 {
713 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
714 rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
715 rocksdb_writebatch_clear(wb);
716 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
717 rocksdb_writebatch_put(wb, "box", 3, "c", 1);
718 rocksdb_writebatch_delete(wb, "bar", 3);
719 rocksdb_write(db, woptions, wb, &err);
720 CheckNoError(err);
721 CheckGet(db, roptions, "foo", "hello");
722 CheckGet(db, roptions, "bar", NULL);
723 CheckGet(db, roptions, "box", "c");
724 int pos = 0;
725 rocksdb_writebatch_iterate(wb, &pos, CheckPut, CheckDel);
726 CheckCondition(pos == 3);
727 rocksdb_writebatch_clear(wb);
728 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
729 rocksdb_writebatch_put(wb, "bay", 3, "d", 1);
730 rocksdb_writebatch_delete_range(wb, "bar", 3, "bay", 3);
731 rocksdb_write(db, woptions, wb, &err);
732 CheckNoError(err);
733 CheckGet(db, roptions, "bar", NULL);
734 CheckGet(db, roptions, "bay", "d");
735 rocksdb_writebatch_clear(wb);
736 const char* start_list[1] = {"bay"};
737 const size_t start_sizes[1] = {3};
738 const char* end_list[1] = {"baz"};
739 const size_t end_sizes[1] = {3};
740 rocksdb_writebatch_delete_rangev(wb, 1, start_list, start_sizes, end_list,
741 end_sizes);
742 rocksdb_write(db, woptions, wb, &err);
743 CheckNoError(err);
744 CheckGet(db, roptions, "bay", NULL);
745 rocksdb_writebatch_destroy(wb);
746 }
747
748 StartPhase("writebatch_vectors");
749 {
750 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
751 const char* k_list[2] = { "z", "ap" };
752 const size_t k_sizes[2] = { 1, 2 };
753 const char* v_list[3] = { "x", "y", "z" };
754 const size_t v_sizes[3] = { 1, 1, 1 };
755 rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
756 rocksdb_write(db, woptions, wb, &err);
757 CheckNoError(err);
758 CheckGet(db, roptions, "zap", "xyz");
759 rocksdb_writebatch_delete(wb, "zap", 3);
760 rocksdb_write(db, woptions, wb, &err);
761 CheckNoError(err);
762 CheckGet(db, roptions, "zap", NULL);
763 rocksdb_writebatch_destroy(wb);
764 }
765
766 StartPhase("writebatch_savepoint");
767 {
768 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
769 rocksdb_writebatch_set_save_point(wb);
770 rocksdb_writebatch_set_save_point(wb);
771 const char* k_list[2] = {"z", "ap"};
772 const size_t k_sizes[2] = {1, 2};
773 const char* v_list[3] = {"x", "y", "z"};
774 const size_t v_sizes[3] = {1, 1, 1};
775 rocksdb_writebatch_pop_save_point(wb, &err);
776 CheckNoError(err);
777 rocksdb_writebatch_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
778 rocksdb_writebatch_rollback_to_save_point(wb, &err);
779 CheckNoError(err);
780 rocksdb_write(db, woptions, wb, &err);
781 CheckNoError(err);
782 CheckGet(db, roptions, "zap", NULL);
783 rocksdb_writebatch_destroy(wb);
784 }
785
786 StartPhase("writebatch_rep");
787 {
788 rocksdb_writebatch_t* wb1 = rocksdb_writebatch_create();
789 rocksdb_writebatch_put(wb1, "baz", 3, "d", 1);
790 rocksdb_writebatch_put(wb1, "quux", 4, "e", 1);
791 rocksdb_writebatch_delete(wb1, "quux", 4);
792 size_t repsize1 = 0;
793 const char* rep = rocksdb_writebatch_data(wb1, &repsize1);
794 rocksdb_writebatch_t* wb2 = rocksdb_writebatch_create_from(rep, repsize1);
795 CheckCondition(rocksdb_writebatch_count(wb1) ==
796 rocksdb_writebatch_count(wb2));
797 size_t repsize2 = 0;
798 CheckCondition(
799 memcmp(rep, rocksdb_writebatch_data(wb2, &repsize2), repsize1) == 0);
800 rocksdb_writebatch_destroy(wb1);
801 rocksdb_writebatch_destroy(wb2);
802 }
803
804 StartPhase("writebatch_wi");
805 {
806 rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
807 rocksdb_writebatch_wi_put(wbi, "foo", 3, "a", 1);
808 rocksdb_writebatch_wi_clear(wbi);
809 rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
810 rocksdb_writebatch_wi_put(wbi, "box", 3, "c", 1);
811 rocksdb_writebatch_wi_delete(wbi, "bar", 3);
812 int count = rocksdb_writebatch_wi_count(wbi);
813 CheckCondition(count == 3);
814 size_t size;
815 char* value;
816 value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "box", 3, &size, &err);
817 CheckValue(err, "c", &value, size);
818 value = rocksdb_writebatch_wi_get_from_batch(wbi, options, "bar", 3, &size, &err);
819 CheckValue(err, NULL, &value, size);
820 value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "foo", 3, &size, &err);
821 CheckValue(err, "hello", &value, size);
822 value = rocksdb_writebatch_wi_get_from_batch_and_db(wbi, db, roptions, "box", 3, &size, &err);
823 CheckValue(err, "c", &value, size);
824 rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
825 CheckNoError(err);
826 CheckGet(db, roptions, "foo", "hello");
827 CheckGet(db, roptions, "bar", NULL);
828 CheckGet(db, roptions, "box", "c");
829 int pos = 0;
830 rocksdb_writebatch_wi_iterate(wbi, &pos, CheckPut, CheckDel);
831 CheckCondition(pos == 3);
832 rocksdb_writebatch_wi_clear(wbi);
833 rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
834 rocksdb_writebatch_wi_put(wbi, "bay", 3, "d", 1);
835 rocksdb_writebatch_wi_delete_range(wbi, "bar", 3, "bay", 3);
836 rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
837 CheckNoError(err);
838 CheckGet(db, roptions, "bar", NULL);
839 CheckGet(db, roptions, "bay", "d");
840 rocksdb_writebatch_wi_clear(wbi);
841 const char* start_list[1] = {"bay"};
842 const size_t start_sizes[1] = {3};
843 const char* end_list[1] = {"baz"};
844 const size_t end_sizes[1] = {3};
845 rocksdb_writebatch_wi_delete_rangev(wbi, 1, start_list, start_sizes, end_list,
846 end_sizes);
847 rocksdb_write_writebatch_wi(db, woptions, wbi, &err);
848 CheckNoError(err);
849 CheckGet(db, roptions, "bay", NULL);
850 rocksdb_writebatch_wi_destroy(wbi);
851 }
852
853 StartPhase("writebatch_wi_vectors");
854 {
855 rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
856 const char* k_list[2] = { "z", "ap" };
857 const size_t k_sizes[2] = { 1, 2 };
858 const char* v_list[3] = { "x", "y", "z" };
859 const size_t v_sizes[3] = { 1, 1, 1 };
860 rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
861 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
862 CheckNoError(err);
863 CheckGet(db, roptions, "zap", "xyz");
864 rocksdb_writebatch_wi_delete(wb, "zap", 3);
865 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
866 CheckNoError(err);
867 CheckGet(db, roptions, "zap", NULL);
868 rocksdb_writebatch_wi_destroy(wb);
869 }
870
871 StartPhase("writebatch_wi_savepoint");
872 {
873 rocksdb_writebatch_wi_t* wb = rocksdb_writebatch_wi_create(0, 1);
874 rocksdb_writebatch_wi_set_save_point(wb);
875 const char* k_list[2] = {"z", "ap"};
876 const size_t k_sizes[2] = {1, 2};
877 const char* v_list[3] = {"x", "y", "z"};
878 const size_t v_sizes[3] = {1, 1, 1};
879 rocksdb_writebatch_wi_putv(wb, 2, k_list, k_sizes, 3, v_list, v_sizes);
880 rocksdb_writebatch_wi_rollback_to_save_point(wb, &err);
881 CheckNoError(err);
882 rocksdb_write_writebatch_wi(db, woptions, wb, &err);
883 CheckNoError(err);
884 CheckGet(db, roptions, "zap", NULL);
885 rocksdb_writebatch_wi_destroy(wb);
886 }
887
888 StartPhase("iter");
889 {
890 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
891 CheckCondition(!rocksdb_iter_valid(iter));
892 rocksdb_iter_seek_to_first(iter);
893 CheckCondition(rocksdb_iter_valid(iter));
894 CheckIter(iter, "box", "c");
895 rocksdb_iter_next(iter);
896 CheckIter(iter, "foo", "hello");
897 rocksdb_iter_prev(iter);
898 CheckIter(iter, "box", "c");
899 rocksdb_iter_prev(iter);
900 CheckCondition(!rocksdb_iter_valid(iter));
901 rocksdb_iter_seek_to_last(iter);
902 CheckIter(iter, "foo", "hello");
903 rocksdb_iter_seek(iter, "b", 1);
904 CheckIter(iter, "box", "c");
905 rocksdb_iter_seek_for_prev(iter, "g", 1);
906 CheckIter(iter, "foo", "hello");
907 rocksdb_iter_seek_for_prev(iter, "box", 3);
908 CheckIter(iter, "box", "c");
909 rocksdb_iter_get_error(iter, &err);
910 CheckNoError(err);
911 rocksdb_iter_destroy(iter);
912 }
913
914 StartPhase("wbwi_iter");
915 {
916 rocksdb_iterator_t* base_iter = rocksdb_create_iterator(db, roptions);
917 rocksdb_writebatch_wi_t* wbi = rocksdb_writebatch_wi_create(0, 1);
918 rocksdb_writebatch_wi_put(wbi, "bar", 3, "b", 1);
919 rocksdb_writebatch_wi_delete(wbi, "foo", 3);
920 rocksdb_iterator_t* iter =
921 rocksdb_writebatch_wi_create_iterator_with_base(wbi, base_iter);
922 CheckCondition(!rocksdb_iter_valid(iter));
923 rocksdb_iter_seek_to_first(iter);
924 CheckCondition(rocksdb_iter_valid(iter));
925 CheckIter(iter, "bar", "b");
926 rocksdb_iter_next(iter);
927 CheckIter(iter, "box", "c");
928 rocksdb_iter_prev(iter);
929 CheckIter(iter, "bar", "b");
930 rocksdb_iter_prev(iter);
931 CheckCondition(!rocksdb_iter_valid(iter));
932 rocksdb_iter_seek_to_last(iter);
933 CheckIter(iter, "box", "c");
934 rocksdb_iter_seek(iter, "b", 1);
935 CheckIter(iter, "bar", "b");
936 rocksdb_iter_seek_for_prev(iter, "c", 1);
937 CheckIter(iter, "box", "c");
938 rocksdb_iter_seek_for_prev(iter, "box", 3);
939 CheckIter(iter, "box", "c");
940 rocksdb_iter_get_error(iter, &err);
941 CheckNoError(err);
942 rocksdb_iter_destroy(iter);
943 rocksdb_writebatch_wi_destroy(wbi);
944 }
945
946 StartPhase("multiget");
947 {
948 const char* keys[3] = { "box", "foo", "notfound" };
949 const size_t keys_sizes[3] = { 3, 3, 8 };
950 char* vals[3];
951 size_t vals_sizes[3];
952 char* errs[3];
953 rocksdb_multi_get(db, roptions, 3, keys, keys_sizes, vals, vals_sizes, errs);
954
955 int i;
956 for (i = 0; i < 3; i++) {
957 CheckEqual(NULL, errs[i], 0);
958 switch (i) {
959 case 0:
960 CheckEqual("c", vals[i], vals_sizes[i]);
961 break;
962 case 1:
963 CheckEqual("hello", vals[i], vals_sizes[i]);
964 break;
965 case 2:
966 CheckEqual(NULL, vals[i], vals_sizes[i]);
967 break;
968 }
969 Free(&vals[i]);
970 }
971 }
972
973 StartPhase("pin_get");
974 {
975 CheckPinGet(db, roptions, "box", "c");
976 CheckPinGet(db, roptions, "foo", "hello");
977 CheckPinGet(db, roptions, "notfound", NULL);
978 }
979
980 StartPhase("approximate_sizes");
981 {
982 int i;
983 int n = 20000;
984 char keybuf[100];
985 char valbuf[100];
986 uint64_t sizes[2];
987 const char* start[2] = { "a", "k00000000000000010000" };
988 size_t start_len[2] = { 1, 21 };
989 const char* limit[2] = { "k00000000000000010000", "z" };
990 size_t limit_len[2] = { 21, 1 };
991 rocksdb_writeoptions_set_sync(woptions, 0);
992 for (i = 0; i < n; i++) {
993 snprintf(keybuf, sizeof(keybuf), "k%020d", i);
994 snprintf(valbuf, sizeof(valbuf), "v%020d", i);
995 rocksdb_put(db, woptions, keybuf, strlen(keybuf), valbuf, strlen(valbuf),
996 &err);
997 CheckNoError(err);
998 }
999 rocksdb_approximate_sizes(db, 2, start, start_len, limit, limit_len, sizes);
1000 CheckCondition(sizes[0] > 0);
1001 CheckCondition(sizes[1] > 0);
1002 }
1003
1004 StartPhase("property");
1005 {
1006 char* prop = rocksdb_property_value(db, "nosuchprop");
1007 CheckCondition(prop == NULL);
1008 prop = rocksdb_property_value(db, "rocksdb.stats");
1009 CheckCondition(prop != NULL);
1010 Free(&prop);
1011 }
1012
1013 StartPhase("snapshot");
1014 {
1015 const rocksdb_snapshot_t* snap;
1016 snap = rocksdb_create_snapshot(db);
1017 rocksdb_delete(db, woptions, "foo", 3, &err);
1018 CheckNoError(err);
1019 rocksdb_readoptions_set_snapshot(roptions, snap);
1020 CheckGet(db, roptions, "foo", "hello");
1021 rocksdb_readoptions_set_snapshot(roptions, NULL);
1022 CheckGet(db, roptions, "foo", NULL);
1023 rocksdb_release_snapshot(db, snap);
1024 }
1025
1026 StartPhase("repair");
1027 {
1028 // If we do not compact here, then the lazy deletion of
1029 // files (https://reviews.facebook.net/D6123) would leave
1030 // around deleted files and the repair process will find
1031 // those files and put them back into the database.
1032 rocksdb_compact_range(db, NULL, 0, NULL, 0);
1033 rocksdb_close(db);
1034 rocksdb_options_set_create_if_missing(options, 0);
1035 rocksdb_options_set_error_if_exists(options, 0);
1036 rocksdb_options_set_wal_recovery_mode(options, 2);
1037 rocksdb_repair_db(options, dbname, &err);
1038 CheckNoError(err);
1039 db = rocksdb_open(options, dbname, &err);
1040 CheckNoError(err);
1041 CheckGet(db, roptions, "foo", NULL);
1042 CheckGet(db, roptions, "bar", NULL);
1043 CheckGet(db, roptions, "box", "c");
1044 rocksdb_options_set_create_if_missing(options, 1);
1045 rocksdb_options_set_error_if_exists(options, 1);
1046 }
1047
1048 StartPhase("filter");
1049 for (run = 0; run < 2; run++) {
1050 // First run uses custom filter, second run uses bloom filter
1051 CheckNoError(err);
1052 rocksdb_filterpolicy_t* policy;
1053 if (run == 0) {
1054 policy = rocksdb_filterpolicy_create(
1055 NULL, FilterDestroy, FilterCreate, FilterKeyMatch, NULL, FilterName);
1056 } else {
1057 policy = rocksdb_filterpolicy_create_bloom(10);
1058 }
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 rocksdb_compact_range(db, NULL, 0, NULL, 0);
1073
1074 fake_filter_result = 1;
1075 CheckGet(db, roptions, "foo", "foovalue");
1076 CheckGet(db, roptions, "bar", "barvalue");
1077 if (phase == 0) {
1078 // Must not find value when custom filter returns false
1079 fake_filter_result = 0;
1080 CheckGet(db, roptions, "foo", NULL);
1081 CheckGet(db, roptions, "bar", NULL);
1082 fake_filter_result = 1;
1083
1084 CheckGet(db, roptions, "foo", "foovalue");
1085 CheckGet(db, roptions, "bar", "barvalue");
1086 }
1087 // Reset the policy
1088 rocksdb_block_based_options_set_filter_policy(table_options, NULL);
1089 rocksdb_options_set_block_based_table_factory(options, table_options);
1090 }
1091
1092 StartPhase("compaction_filter");
1093 {
1094 rocksdb_options_t* options_with_filter = rocksdb_options_create();
1095 rocksdb_options_set_create_if_missing(options_with_filter, 1);
1096 rocksdb_compactionfilter_t* cfilter;
1097 cfilter = rocksdb_compactionfilter_create(NULL, CFilterDestroy,
1098 CFilterFilter, CFilterName);
1099 // Create new database
1100 rocksdb_close(db);
1101 rocksdb_destroy_db(options_with_filter, dbname, &err);
1102 rocksdb_options_set_compaction_filter(options_with_filter, cfilter);
1103 db = CheckCompaction(db, options_with_filter, roptions, woptions);
1104
1105 rocksdb_options_set_compaction_filter(options_with_filter, NULL);
1106 rocksdb_compactionfilter_destroy(cfilter);
1107 rocksdb_options_destroy(options_with_filter);
1108 }
1109
1110 StartPhase("compaction_filter_factory");
1111 {
1112 rocksdb_options_t* options_with_filter_factory = rocksdb_options_create();
1113 rocksdb_options_set_create_if_missing(options_with_filter_factory, 1);
1114 rocksdb_compactionfilterfactory_t* factory;
1115 factory = rocksdb_compactionfilterfactory_create(
1116 NULL, CFilterFactoryDestroy, CFilterCreate, CFilterFactoryName);
1117 // Create new database
1118 rocksdb_close(db);
1119 rocksdb_destroy_db(options_with_filter_factory, dbname, &err);
1120 rocksdb_options_set_compaction_filter_factory(options_with_filter_factory,
1121 factory);
1122 db = CheckCompaction(db, options_with_filter_factory, roptions, woptions);
1123
1124 rocksdb_options_set_compaction_filter_factory(
1125 options_with_filter_factory, NULL);
1126 rocksdb_options_destroy(options_with_filter_factory);
1127 }
1128
1129 StartPhase("merge_operator");
1130 {
1131 rocksdb_mergeoperator_t* merge_operator;
1132 merge_operator = rocksdb_mergeoperator_create(
1133 NULL, MergeOperatorDestroy, MergeOperatorFullMerge,
1134 MergeOperatorPartialMerge, NULL, MergeOperatorName);
1135 // Create new database
1136 rocksdb_close(db);
1137 rocksdb_destroy_db(options, dbname, &err);
1138 rocksdb_options_set_merge_operator(options, merge_operator);
1139 db = rocksdb_open(options, dbname, &err);
1140 CheckNoError(err);
1141 rocksdb_put(db, woptions, "foo", 3, "foovalue", 8, &err);
1142 CheckNoError(err);
1143 CheckGet(db, roptions, "foo", "foovalue");
1144 rocksdb_merge(db, woptions, "foo", 3, "barvalue", 8, &err);
1145 CheckNoError(err);
1146 CheckGet(db, roptions, "foo", "fake");
1147
1148 // Merge of a non-existing value
1149 rocksdb_merge(db, woptions, "bar", 3, "barvalue", 8, &err);
1150 CheckNoError(err);
1151 CheckGet(db, roptions, "bar", "fake");
1152
1153 }
1154
1155 StartPhase("columnfamilies");
1156 {
1157 rocksdb_close(db);
1158 rocksdb_destroy_db(options, dbname, &err);
1159 CheckNoError(err);
1160
1161 rocksdb_options_t* db_options = rocksdb_options_create();
1162 rocksdb_options_set_create_if_missing(db_options, 1);
1163 db = rocksdb_open(db_options, dbname, &err);
1164 CheckNoError(err)
1165 rocksdb_column_family_handle_t* cfh;
1166 cfh = rocksdb_create_column_family(db, db_options, "cf1", &err);
1167 rocksdb_column_family_handle_destroy(cfh);
1168 CheckNoError(err);
1169 rocksdb_close(db);
1170
1171 size_t cflen;
1172 char** column_fams = rocksdb_list_column_families(db_options, dbname, &cflen, &err);
1173 CheckNoError(err);
1174 CheckEqual("default", column_fams[0], 7);
1175 CheckEqual("cf1", column_fams[1], 3);
1176 CheckCondition(cflen == 2);
1177 rocksdb_list_column_families_destroy(column_fams, cflen);
1178
1179 rocksdb_options_t* cf_options = rocksdb_options_create();
1180
1181 const char* cf_names[2] = {"default", "cf1"};
1182 const rocksdb_options_t* cf_opts[2] = {cf_options, cf_options};
1183 rocksdb_column_family_handle_t* handles[2];
1184 db = rocksdb_open_column_families(db_options, dbname, 2, cf_names, cf_opts, handles, &err);
1185 CheckNoError(err);
1186
1187 rocksdb_put_cf(db, woptions, handles[1], "foo", 3, "hello", 5, &err);
1188 CheckNoError(err);
1189
1190 CheckGetCF(db, roptions, handles[1], "foo", "hello");
1191 CheckPinGetCF(db, roptions, handles[1], "foo", "hello");
1192
1193 rocksdb_delete_cf(db, woptions, handles[1], "foo", 3, &err);
1194 CheckNoError(err);
1195
1196 CheckGetCF(db, roptions, handles[1], "foo", NULL);
1197 CheckPinGetCF(db, roptions, handles[1], "foo", NULL);
1198
1199 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
1200 rocksdb_writebatch_put_cf(wb, handles[1], "baz", 3, "a", 1);
1201 rocksdb_writebatch_clear(wb);
1202 rocksdb_writebatch_put_cf(wb, handles[1], "bar", 3, "b", 1);
1203 rocksdb_writebatch_put_cf(wb, handles[1], "box", 3, "c", 1);
1204 rocksdb_writebatch_delete_cf(wb, handles[1], "bar", 3);
1205 rocksdb_write(db, woptions, wb, &err);
1206 CheckNoError(err);
1207 CheckGetCF(db, roptions, handles[1], "baz", NULL);
1208 CheckGetCF(db, roptions, handles[1], "bar", NULL);
1209 CheckGetCF(db, roptions, handles[1], "box", "c");
1210 CheckPinGetCF(db, roptions, handles[1], "baz", NULL);
1211 CheckPinGetCF(db, roptions, handles[1], "bar", NULL);
1212 CheckPinGetCF(db, roptions, handles[1], "box", "c");
1213 rocksdb_writebatch_destroy(wb);
1214
1215 const char* keys[3] = { "box", "box", "barfooxx" };
1216 const rocksdb_column_family_handle_t* get_handles[3] = { handles[0], handles[1], handles[1] };
1217 const size_t keys_sizes[3] = { 3, 3, 8 };
1218 char* vals[3];
1219 size_t vals_sizes[3];
1220 char* errs[3];
1221 rocksdb_multi_get_cf(db, roptions, get_handles, 3, keys, keys_sizes, vals, vals_sizes, errs);
1222
1223 int i;
1224 for (i = 0; i < 3; i++) {
1225 CheckEqual(NULL, errs[i], 0);
1226 switch (i) {
1227 case 0:
1228 CheckEqual(NULL, vals[i], vals_sizes[i]); // wrong cf
1229 break;
1230 case 1:
1231 CheckEqual("c", vals[i], vals_sizes[i]); // bingo
1232 break;
1233 case 2:
1234 CheckEqual(NULL, vals[i], vals_sizes[i]); // normal not found
1235 break;
1236 }
1237 Free(&vals[i]);
1238 }
1239
1240 rocksdb_iterator_t* iter = rocksdb_create_iterator_cf(db, roptions, handles[1]);
1241 CheckCondition(!rocksdb_iter_valid(iter));
1242 rocksdb_iter_seek_to_first(iter);
1243 CheckCondition(rocksdb_iter_valid(iter));
1244
1245 for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
1246 i++;
1247 }
1248 CheckCondition(i == 1);
1249 rocksdb_iter_get_error(iter, &err);
1250 CheckNoError(err);
1251 rocksdb_iter_destroy(iter);
1252
1253 rocksdb_column_family_handle_t* iters_cf_handles[2] = { handles[0], handles[1] };
1254 rocksdb_iterator_t* iters_handles[2];
1255 rocksdb_create_iterators(db, roptions, iters_cf_handles, iters_handles, 2, &err);
1256 CheckNoError(err);
1257
1258 iter = iters_handles[0];
1259 CheckCondition(!rocksdb_iter_valid(iter));
1260 rocksdb_iter_seek_to_first(iter);
1261 CheckCondition(!rocksdb_iter_valid(iter));
1262 rocksdb_iter_destroy(iter);
1263
1264 iter = iters_handles[1];
1265 CheckCondition(!rocksdb_iter_valid(iter));
1266 rocksdb_iter_seek_to_first(iter);
1267 CheckCondition(rocksdb_iter_valid(iter));
1268
1269 for (i = 0; rocksdb_iter_valid(iter) != 0; rocksdb_iter_next(iter)) {
1270 i++;
1271 }
1272 CheckCondition(i == 1);
1273 rocksdb_iter_get_error(iter, &err);
1274 CheckNoError(err);
1275 rocksdb_iter_destroy(iter);
1276
1277 rocksdb_drop_column_family(db, handles[1], &err);
1278 CheckNoError(err);
1279 for (i = 0; i < 2; i++) {
1280 rocksdb_column_family_handle_destroy(handles[i]);
1281 }
1282 rocksdb_close(db);
1283 rocksdb_destroy_db(options, dbname, &err);
1284 rocksdb_options_destroy(db_options);
1285 rocksdb_options_destroy(cf_options);
1286 }
1287
1288 StartPhase("prefix");
1289 {
1290 // Create new database
1291 rocksdb_options_set_allow_mmap_reads(options, 1);
1292 rocksdb_options_set_prefix_extractor(options, rocksdb_slicetransform_create_fixed_prefix(3));
1293 rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
1294 rocksdb_options_set_plain_table_factory(options, 4, 10, 0.75, 16);
1295 rocksdb_options_set_allow_concurrent_memtable_write(options, 0);
1296
1297 db = rocksdb_open(options, dbname, &err);
1298 CheckNoError(err);
1299
1300 rocksdb_put(db, woptions, "foo1", 4, "foo", 3, &err);
1301 CheckNoError(err);
1302 rocksdb_put(db, woptions, "foo2", 4, "foo", 3, &err);
1303 CheckNoError(err);
1304 rocksdb_put(db, woptions, "foo3", 4, "foo", 3, &err);
1305 CheckNoError(err);
1306 rocksdb_put(db, woptions, "bar1", 4, "bar", 3, &err);
1307 CheckNoError(err);
1308 rocksdb_put(db, woptions, "bar2", 4, "bar", 3, &err);
1309 CheckNoError(err);
1310 rocksdb_put(db, woptions, "bar3", 4, "bar", 3, &err);
1311 CheckNoError(err);
1312
1313 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
1314 CheckCondition(!rocksdb_iter_valid(iter));
1315
1316 rocksdb_iter_seek(iter, "bar", 3);
1317 rocksdb_iter_get_error(iter, &err);
1318 CheckNoError(err);
1319 CheckCondition(rocksdb_iter_valid(iter));
1320
1321 CheckIter(iter, "bar1", "bar");
1322 rocksdb_iter_next(iter);
1323 CheckIter(iter, "bar2", "bar");
1324 rocksdb_iter_next(iter);
1325 CheckIter(iter, "bar3", "bar");
1326 rocksdb_iter_get_error(iter, &err);
1327 CheckNoError(err);
1328 rocksdb_iter_destroy(iter);
1329
1330 rocksdb_readoptions_set_total_order_seek(roptions, 1);
1331 iter = rocksdb_create_iterator(db, roptions);
1332 CheckCondition(!rocksdb_iter_valid(iter));
1333
1334 rocksdb_iter_seek(iter, "ba", 2);
1335 rocksdb_iter_get_error(iter, &err);
1336 CheckNoError(err);
1337 CheckCondition(rocksdb_iter_valid(iter));
1338 CheckIter(iter, "bar1", "bar");
1339
1340 rocksdb_iter_destroy(iter);
1341 rocksdb_readoptions_set_total_order_seek(roptions, 0);
1342
1343 rocksdb_close(db);
1344 rocksdb_destroy_db(options, dbname, &err);
1345 }
1346
1347 // Check memory usage stats
1348 StartPhase("approximate_memory_usage");
1349 {
1350 // Create database
1351 db = rocksdb_open(options, dbname, &err);
1352 CheckNoError(err);
1353
1354 rocksdb_memory_consumers_t* consumers;
1355 consumers = rocksdb_memory_consumers_create();
1356 rocksdb_memory_consumers_add_db(consumers, db);
1357 rocksdb_memory_consumers_add_cache(consumers, cache);
1358
1359 // take memory usage report before write-read operation
1360 rocksdb_memory_usage_t* mu1;
1361 mu1 = rocksdb_approximate_memory_usage_create(consumers, &err);
1362 CheckNoError(err);
1363
1364 // Put data (this should affect memtables)
1365 rocksdb_put(db, woptions, "memory", 6, "test", 4, &err);
1366 CheckNoError(err);
1367 CheckGet(db, roptions, "memory", "test");
1368
1369 // take memory usage report after write-read operation
1370 rocksdb_memory_usage_t* mu2;
1371 mu2 = rocksdb_approximate_memory_usage_create(consumers, &err);
1372 CheckNoError(err);
1373
1374 // amount of memory used within memtables should grow
1375 CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_total(mu2) >=
1376 rocksdb_approximate_memory_usage_get_mem_table_total(mu1));
1377 CheckCondition(rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu2) >=
1378 rocksdb_approximate_memory_usage_get_mem_table_unflushed(mu1));
1379
1380 rocksdb_memory_consumers_destroy(consumers);
1381 rocksdb_approximate_memory_usage_destroy(mu1);
1382 rocksdb_approximate_memory_usage_destroy(mu2);
1383 rocksdb_close(db);
1384 rocksdb_destroy_db(options, dbname, &err);
1385 CheckNoError(err);
1386 }
1387
1388 StartPhase("cuckoo_options");
1389 {
1390 rocksdb_cuckoo_table_options_t* cuckoo_options;
1391 cuckoo_options = rocksdb_cuckoo_options_create();
1392 rocksdb_cuckoo_options_set_hash_ratio(cuckoo_options, 0.5);
1393 rocksdb_cuckoo_options_set_max_search_depth(cuckoo_options, 200);
1394 rocksdb_cuckoo_options_set_cuckoo_block_size(cuckoo_options, 10);
1395 rocksdb_cuckoo_options_set_identity_as_first_hash(cuckoo_options, 1);
1396 rocksdb_cuckoo_options_set_use_module_hash(cuckoo_options, 0);
1397 rocksdb_options_set_cuckoo_table_factory(options, cuckoo_options);
1398
1399 db = rocksdb_open(options, dbname, &err);
1400 CheckNoError(err);
1401
1402 rocksdb_cuckoo_options_destroy(cuckoo_options);
1403 }
1404
1405 StartPhase("iterate_upper_bound");
1406 {
1407 // Create new empty database
1408 rocksdb_close(db);
1409 rocksdb_destroy_db(options, dbname, &err);
1410 CheckNoError(err);
1411
1412 rocksdb_options_set_prefix_extractor(options, NULL);
1413 db = rocksdb_open(options, dbname, &err);
1414 CheckNoError(err);
1415
1416 rocksdb_put(db, woptions, "a", 1, "0", 1, &err); CheckNoError(err);
1417 rocksdb_put(db, woptions, "foo", 3, "bar", 3, &err); CheckNoError(err);
1418 rocksdb_put(db, woptions, "foo1", 4, "bar1", 4, &err); CheckNoError(err);
1419 rocksdb_put(db, woptions, "g1", 2, "0", 1, &err); CheckNoError(err);
1420
1421 // testing basic case with no iterate_upper_bound and no prefix_extractor
1422 {
1423 rocksdb_readoptions_set_iterate_upper_bound(roptions, NULL, 0);
1424 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
1425
1426 rocksdb_iter_seek(iter, "foo", 3);
1427 CheckCondition(rocksdb_iter_valid(iter));
1428 CheckIter(iter, "foo", "bar");
1429
1430 rocksdb_iter_next(iter);
1431 CheckCondition(rocksdb_iter_valid(iter));
1432 CheckIter(iter, "foo1", "bar1");
1433
1434 rocksdb_iter_next(iter);
1435 CheckCondition(rocksdb_iter_valid(iter));
1436 CheckIter(iter, "g1", "0");
1437
1438 rocksdb_iter_destroy(iter);
1439 }
1440
1441 // testing iterate_upper_bound and forward iterator
1442 // to make sure it stops at bound
1443 {
1444 // iterate_upper_bound points beyond the last expected entry
1445 rocksdb_readoptions_set_iterate_upper_bound(roptions, "foo2", 4);
1446
1447 rocksdb_iterator_t* iter = rocksdb_create_iterator(db, roptions);
1448
1449 rocksdb_iter_seek(iter, "foo", 3);
1450 CheckCondition(rocksdb_iter_valid(iter));
1451 CheckIter(iter, "foo", "bar");
1452
1453 rocksdb_iter_next(iter);
1454 CheckCondition(rocksdb_iter_valid(iter));
1455 CheckIter(iter, "foo1", "bar1");
1456
1457 rocksdb_iter_next(iter);
1458 // should stop here...
1459 CheckCondition(!rocksdb_iter_valid(iter));
1460
1461 rocksdb_iter_destroy(iter);
1462 }
1463 }
1464
1465 StartPhase("transactions");
1466 {
1467 rocksdb_close(db);
1468 rocksdb_destroy_db(options, dbname, &err);
1469 CheckNoError(err);
1470
1471 // open a TransactionDB
1472 txn_db_options = rocksdb_transactiondb_options_create();
1473 txn_options = rocksdb_transaction_options_create();
1474 rocksdb_options_set_create_if_missing(options, 1);
1475 txn_db = rocksdb_transactiondb_open(options, txn_db_options, dbname, &err);
1476 CheckNoError(err);
1477
1478 // put outside a transaction
1479 rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hello", 5, &err);
1480 CheckNoError(err);
1481 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
1482
1483 // delete from outside transaction
1484 rocksdb_transactiondb_delete(txn_db, woptions, "foo", 3, &err);
1485 CheckNoError(err);
1486 CheckTxnDBGet(txn_db, roptions, "foo", NULL);
1487
1488 // write batch into TransactionDB
1489 rocksdb_writebatch_t* wb = rocksdb_writebatch_create();
1490 rocksdb_writebatch_put(wb, "foo", 3, "a", 1);
1491 rocksdb_writebatch_clear(wb);
1492 rocksdb_writebatch_put(wb, "bar", 3, "b", 1);
1493 rocksdb_writebatch_put(wb, "box", 3, "c", 1);
1494 rocksdb_writebatch_delete(wb, "bar", 3);
1495 rocksdb_transactiondb_write(txn_db, woptions, wb, &err);
1496 rocksdb_writebatch_destroy(wb);
1497 CheckTxnDBGet(txn_db, roptions, "box", "c");
1498 CheckNoError(err);
1499
1500 // begin a transaction
1501 txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, NULL);
1502 // put
1503 rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
1504 CheckNoError(err);
1505 CheckTxnGet(txn, roptions, "foo", "hello");
1506 // delete
1507 rocksdb_transaction_delete(txn, "foo", 3, &err);
1508 CheckNoError(err);
1509 CheckTxnGet(txn, roptions, "foo", NULL);
1510
1511 rocksdb_transaction_put(txn, "foo", 3, "hello", 5, &err);
1512 CheckNoError(err);
1513
1514 // read from outside transaction, before commit
1515 CheckTxnDBGet(txn_db, roptions, "foo", NULL);
1516
1517 // commit
1518 rocksdb_transaction_commit(txn, &err);
1519 CheckNoError(err);
1520
1521 // read from outside transaction, after commit
1522 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
1523
1524 // reuse old transaction
1525 txn = rocksdb_transaction_begin(txn_db, woptions, txn_options, txn);
1526
1527 // snapshot
1528 const rocksdb_snapshot_t* snapshot;
1529 snapshot = rocksdb_transactiondb_create_snapshot(txn_db);
1530 rocksdb_readoptions_set_snapshot(roptions, snapshot);
1531
1532 rocksdb_transactiondb_put(txn_db, woptions, "foo", 3, "hey", 3, &err);
1533 CheckNoError(err);
1534
1535 CheckTxnDBGet(txn_db, roptions, "foo", "hello");
1536 rocksdb_readoptions_set_snapshot(roptions, NULL);
1537 rocksdb_transactiondb_release_snapshot(txn_db, snapshot);
1538 CheckTxnDBGet(txn_db, roptions, "foo", "hey");
1539
1540 // iterate
1541 rocksdb_transaction_put(txn, "bar", 3, "hi", 2, &err);
1542 rocksdb_iterator_t* iter = rocksdb_transaction_create_iterator(txn, roptions);
1543 CheckCondition(!rocksdb_iter_valid(iter));
1544 rocksdb_iter_seek_to_first(iter);
1545 CheckCondition(rocksdb_iter_valid(iter));
1546 CheckIter(iter, "bar", "hi");
1547 rocksdb_iter_get_error(iter, &err);
1548 CheckNoError(err);
1549 rocksdb_iter_destroy(iter);
1550
1551 // rollback
1552 rocksdb_transaction_rollback(txn, &err);
1553 CheckNoError(err);
1554 CheckTxnDBGet(txn_db, roptions, "bar", NULL);
1555
1556 // save point
1557 rocksdb_transaction_put(txn, "foo1", 4, "hi1", 3, &err);
1558 rocksdb_transaction_set_savepoint(txn);
1559 CheckTxnGet(txn, roptions, "foo1", "hi1");
1560 rocksdb_transaction_put(txn, "foo2", 4, "hi2", 3, &err);
1561 CheckTxnGet(txn, roptions, "foo2", "hi2");
1562
1563 // rollback to savepoint
1564 rocksdb_transaction_rollback_to_savepoint(txn, &err);
1565 CheckNoError(err);
1566 CheckTxnGet(txn, roptions, "foo2", NULL);
1567 CheckTxnGet(txn, roptions, "foo1", "hi1");
1568 CheckTxnDBGet(txn_db, roptions, "foo1", NULL);
1569 CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
1570 rocksdb_transaction_commit(txn, &err);
1571 CheckNoError(err);
1572 CheckTxnDBGet(txn_db, roptions, "foo1", "hi1");
1573 CheckTxnDBGet(txn_db, roptions, "foo2", NULL);
1574
1575 // Column families.
1576 rocksdb_column_family_handle_t* cfh;
1577 cfh = rocksdb_transactiondb_create_column_family(txn_db, options,
1578 "txn_db_cf", &err);
1579 CheckNoError(err);
1580
1581 rocksdb_transactiondb_put_cf(txn_db, woptions, cfh, "cf_foo", 6, "cf_hello",
1582 8, &err);
1583 CheckNoError(err);
1584 CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", "cf_hello");
1585
1586 rocksdb_transactiondb_delete_cf(txn_db, woptions, cfh, "cf_foo", 6, &err);
1587 CheckNoError(err);
1588 CheckTxnDBGetCF(txn_db, roptions, cfh, "cf_foo", NULL);
1589
1590 rocksdb_column_family_handle_destroy(cfh);
1591
1592 // close and destroy
1593 rocksdb_transaction_destroy(txn);
1594 rocksdb_transactiondb_close(txn_db);
1595 rocksdb_destroy_db(options, dbname, &err);
1596 CheckNoError(err);
1597 rocksdb_transaction_options_destroy(txn_options);
1598 rocksdb_transactiondb_options_destroy(txn_db_options);
1599 }
1600
1601 StartPhase("optimistic_transactions");
1602 {
1603 rocksdb_options_t* db_options = rocksdb_options_create();
1604 rocksdb_options_set_create_if_missing(db_options, 1);
1605 rocksdb_options_set_allow_concurrent_memtable_write(db_options, 1);
1606 otxn_db = rocksdb_optimistictransactiondb_open(db_options, dbname, &err);
1607 otxn_options = rocksdb_optimistictransaction_options_create();
1608 rocksdb_transaction_t* txn1 = rocksdb_optimistictransaction_begin(
1609 otxn_db, woptions, otxn_options, NULL);
1610 rocksdb_transaction_t* txn2 = rocksdb_optimistictransaction_begin(
1611 otxn_db, woptions, otxn_options, NULL);
1612 rocksdb_transaction_put(txn1, "key", 3, "value", 5, &err);
1613 CheckNoError(err);
1614 rocksdb_transaction_put(txn2, "key1", 4, "value1", 6, &err);
1615 CheckNoError(err);
1616 CheckTxnGet(txn1, roptions, "key", "value");
1617 rocksdb_transaction_commit(txn1, &err);
1618 CheckNoError(err);
1619 rocksdb_transaction_commit(txn2, &err);
1620 CheckNoError(err);
1621 rocksdb_transaction_destroy(txn1);
1622 rocksdb_transaction_destroy(txn2);
1623
1624 // Check column family
1625 db = rocksdb_optimistictransactiondb_get_base_db(otxn_db);
1626 rocksdb_put(db, woptions, "key", 3, "value", 5, &err);
1627 CheckNoError(err);
1628 rocksdb_column_family_handle_t *cfh1, *cfh2;
1629 cfh1 = rocksdb_create_column_family(db, db_options, "txn_db_cf1", &err);
1630 cfh2 = rocksdb_create_column_family(db, db_options, "txn_db_cf2", &err);
1631 txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
1632 NULL);
1633 rocksdb_transaction_put_cf(txn, cfh1, "key_cf1", 7, "val_cf1", 7, &err);
1634 CheckNoError(err);
1635 rocksdb_transaction_put_cf(txn, cfh2, "key_cf2", 7, "val_cf2", 7, &err);
1636 CheckNoError(err);
1637 rocksdb_transaction_commit(txn, &err);
1638 CheckNoError(err);
1639 txn = rocksdb_optimistictransaction_begin(otxn_db, woptions, otxn_options,
1640 txn);
1641 CheckGetCF(db, roptions, cfh1, "key_cf1", "val_cf1");
1642 CheckTxnGetCF(txn, roptions, cfh1, "key_cf1", "val_cf1");
1643
1644 // Check iterator with column family
1645 rocksdb_transaction_put_cf(txn, cfh1, "key1_cf", 7, "val1_cf", 7, &err);
1646 CheckNoError(err);
1647 rocksdb_iterator_t* iter =
1648 rocksdb_transaction_create_iterator_cf(txn, roptions, cfh1);
1649 CheckCondition(!rocksdb_iter_valid(iter));
1650 rocksdb_iter_seek_to_first(iter);
1651 CheckCondition(rocksdb_iter_valid(iter));
1652 CheckIter(iter, "key1_cf", "val1_cf");
1653 rocksdb_iter_get_error(iter, &err);
1654 CheckNoError(err);
1655 rocksdb_iter_destroy(iter);
1656
1657 rocksdb_transaction_destroy(txn);
1658 rocksdb_column_family_handle_destroy(cfh1);
1659 rocksdb_column_family_handle_destroy(cfh2);
1660 rocksdb_optimistictransactiondb_close_base_db(db);
1661 rocksdb_optimistictransactiondb_close(otxn_db);
1662
1663 // Check open optimistic transaction db with column families
1664 size_t cf_len;
1665 char** column_fams =
1666 rocksdb_list_column_families(db_options, dbname, &cf_len, &err);
1667 CheckNoError(err);
1668 CheckEqual("default", column_fams[0], 7);
1669 CheckEqual("txn_db_cf1", column_fams[1], 10);
1670 CheckEqual("txn_db_cf2", column_fams[2], 10);
1671 CheckCondition(cf_len == 3);
1672 rocksdb_list_column_families_destroy(column_fams, cf_len);
1673
1674 const char* cf_names[3] = {"default", "txn_db_cf1", "txn_db_cf2"};
1675 rocksdb_options_t* cf_options = rocksdb_options_create();
1676 const rocksdb_options_t* cf_opts[3] = {cf_options, cf_options, cf_options};
1677
1678 rocksdb_options_set_error_if_exists(cf_options, 0);
1679 rocksdb_column_family_handle_t* cf_handles[3];
1680 otxn_db = rocksdb_optimistictransactiondb_open_column_families(
1681 db_options, dbname, 3, cf_names, cf_opts, cf_handles, &err);
1682 CheckNoError(err);
1683 rocksdb_transaction_t* txn_cf = rocksdb_optimistictransaction_begin(
1684 otxn_db, woptions, otxn_options, NULL);
1685 CheckTxnGetCF(txn_cf, roptions, cf_handles[0], "key", "value");
1686 CheckTxnGetCF(txn_cf, roptions, cf_handles[1], "key_cf1", "val_cf1");
1687 CheckTxnGetCF(txn_cf, roptions, cf_handles[2], "key_cf2", "val_cf2");
1688 rocksdb_transaction_destroy(txn_cf);
1689 rocksdb_options_destroy(cf_options);
1690 rocksdb_column_family_handle_destroy(cf_handles[0]);
1691 rocksdb_column_family_handle_destroy(cf_handles[1]);
1692 rocksdb_column_family_handle_destroy(cf_handles[2]);
1693 rocksdb_optimistictransactiondb_close(otxn_db);
1694 rocksdb_destroy_db(db_options, dbname, &err);
1695 rocksdb_options_destroy(db_options);
1696 rocksdb_optimistictransaction_options_destroy(otxn_options);
1697 CheckNoError(err);
1698 }
1699
1700 // Simple sanity check that setting memtable rep works.
1701 StartPhase("memtable_reps");
1702 {
1703 // Create database with vector memtable.
1704 rocksdb_options_set_memtable_vector_rep(options);
1705 db = rocksdb_open(options, dbname, &err);
1706 CheckNoError(err);
1707
1708 // Create database with hash skiplist memtable.
1709 rocksdb_close(db);
1710 rocksdb_destroy_db(options, dbname, &err);
1711 CheckNoError(err);
1712
1713 rocksdb_options_set_hash_skip_list_rep(options, 5000, 4, 4);
1714 db = rocksdb_open(options, dbname, &err);
1715 CheckNoError(err);
1716 }
1717
1718 // Simple sanity check that options setting db_paths work.
1719 StartPhase("open_db_paths");
1720 {
1721 rocksdb_close(db);
1722 rocksdb_destroy_db(options, dbname, &err);
1723
1724 const rocksdb_dbpath_t* paths[1] = {dbpath};
1725 rocksdb_options_set_db_paths(options, paths, 1);
1726 db = rocksdb_open(options, dbname, &err);
1727 CheckNoError(err);
1728 }
1729
1730 StartPhase("cleanup");
1731 rocksdb_close(db);
1732 rocksdb_options_destroy(options);
1733 rocksdb_block_based_options_destroy(table_options);
1734 rocksdb_readoptions_destroy(roptions);
1735 rocksdb_writeoptions_destroy(woptions);
1736 rocksdb_compactoptions_destroy(coptions);
1737 rocksdb_cache_destroy(cache);
1738 rocksdb_comparator_destroy(cmp);
1739 rocksdb_dbpath_destroy(dbpath);
1740 rocksdb_env_destroy(env);
1741
1742 fprintf(stderr, "PASS\n");
1743 return 0;
1744 }
1745
1746 #else
1747
1748 int main() {
1749 fprintf(stderr, "SKIPPED\n");
1750 return 0;
1751 }
1752
1753 #endif // !ROCKSDB_LITE