]> git.proxmox.com Git - ceph.git/blob - ceph/src/rocksdb/db/c.cc
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / src / rocksdb / db / c.cc
1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under the BSD-style license found in the
3 // LICENSE file in the root directory of this source tree. An additional grant
4 // of patent rights can be found in the PATENTS file in the same directory.
5 //
6 // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7 // Use of this source code is governed by a BSD-style license that can be
8 // found in the LICENSE file. See the AUTHORS file for names of contributors.
9
10 #ifndef ROCKSDB_LITE
11
12 #include "rocksdb/c.h"
13
14 #include <stdlib.h>
15 #include "port/port.h"
16 #include "rocksdb/cache.h"
17 #include "rocksdb/compaction_filter.h"
18 #include "rocksdb/comparator.h"
19 #include "rocksdb/convenience.h"
20 #include "rocksdb/db.h"
21 #include "rocksdb/env.h"
22 #include "rocksdb/filter_policy.h"
23 #include "rocksdb/iterator.h"
24 #include "rocksdb/merge_operator.h"
25 #include "rocksdb/options.h"
26 #include "rocksdb/status.h"
27 #include "rocksdb/write_batch.h"
28 #include "rocksdb/memtablerep.h"
29 #include "rocksdb/universal_compaction.h"
30 #include "rocksdb/statistics.h"
31 #include "rocksdb/slice_transform.h"
32 #include "rocksdb/table.h"
33 #include "rocksdb/rate_limiter.h"
34 #include "rocksdb/utilities/backupable_db.h"
35 #include "rocksdb/utilities/write_batch_with_index.h"
36 #include "utilities/merge_operators.h"
37
38 using rocksdb::BytewiseComparator;
39 using rocksdb::Cache;
40 using rocksdb::ColumnFamilyDescriptor;
41 using rocksdb::ColumnFamilyHandle;
42 using rocksdb::ColumnFamilyOptions;
43 using rocksdb::CompactionFilter;
44 using rocksdb::CompactionFilterFactory;
45 using rocksdb::CompactionFilterContext;
46 using rocksdb::CompactionOptionsFIFO;
47 using rocksdb::Comparator;
48 using rocksdb::CompressionType;
49 using rocksdb::WALRecoveryMode;
50 using rocksdb::DB;
51 using rocksdb::DBOptions;
52 using rocksdb::Env;
53 using rocksdb::EnvOptions;
54 using rocksdb::InfoLogLevel;
55 using rocksdb::FileLock;
56 using rocksdb::FilterPolicy;
57 using rocksdb::FlushOptions;
58 using rocksdb::IngestExternalFileOptions;
59 using rocksdb::Iterator;
60 using rocksdb::Logger;
61 using rocksdb::MergeOperator;
62 using rocksdb::MergeOperators;
63 using rocksdb::NewBloomFilterPolicy;
64 using rocksdb::NewLRUCache;
65 using rocksdb::Options;
66 using rocksdb::BlockBasedTableOptions;
67 using rocksdb::CuckooTableOptions;
68 using rocksdb::RandomAccessFile;
69 using rocksdb::Range;
70 using rocksdb::ReadOptions;
71 using rocksdb::SequentialFile;
72 using rocksdb::Slice;
73 using rocksdb::SliceParts;
74 using rocksdb::SliceTransform;
75 using rocksdb::Snapshot;
76 using rocksdb::SstFileWriter;
77 using rocksdb::Status;
78 using rocksdb::WritableFile;
79 using rocksdb::WriteBatch;
80 using rocksdb::WriteBatchWithIndex;
81 using rocksdb::WriteOptions;
82 using rocksdb::LiveFileMetaData;
83 using rocksdb::BackupEngine;
84 using rocksdb::BackupableDBOptions;
85 using rocksdb::BackupInfo;
86 using rocksdb::RestoreOptions;
87 using rocksdb::CompactRangeOptions;
88 using rocksdb::RateLimiter;
89 using rocksdb::NewGenericRateLimiter;
90
91 using std::shared_ptr;
92
93 extern "C" {
94
95 struct rocksdb_t { DB* rep; };
96 struct rocksdb_backup_engine_t { BackupEngine* rep; };
97 struct rocksdb_backup_engine_info_t { std::vector<BackupInfo> rep; };
98 struct rocksdb_restore_options_t { RestoreOptions rep; };
99 struct rocksdb_iterator_t { Iterator* rep; };
100 struct rocksdb_writebatch_t { WriteBatch rep; };
101 struct rocksdb_writebatch_wi_t { WriteBatchWithIndex* rep; };
102 struct rocksdb_snapshot_t { const Snapshot* rep; };
103 struct rocksdb_flushoptions_t { FlushOptions rep; };
104 struct rocksdb_fifo_compaction_options_t { CompactionOptionsFIFO rep; };
105 struct rocksdb_readoptions_t {
106 ReadOptions rep;
107 Slice upper_bound; // stack variable to set pointer to in ReadOptions
108 };
109 struct rocksdb_writeoptions_t { WriteOptions rep; };
110 struct rocksdb_options_t { Options rep; };
111 struct rocksdb_compactoptions_t {
112 CompactRangeOptions rep;
113 };
114 struct rocksdb_block_based_table_options_t { BlockBasedTableOptions rep; };
115 struct rocksdb_cuckoo_table_options_t { CuckooTableOptions rep; };
116 struct rocksdb_seqfile_t { SequentialFile* rep; };
117 struct rocksdb_randomfile_t { RandomAccessFile* rep; };
118 struct rocksdb_writablefile_t { WritableFile* rep; };
119 struct rocksdb_filelock_t { FileLock* rep; };
120 struct rocksdb_logger_t { shared_ptr<Logger> rep; };
121 struct rocksdb_cache_t { shared_ptr<Cache> rep; };
122 struct rocksdb_livefiles_t { std::vector<LiveFileMetaData> rep; };
123 struct rocksdb_column_family_handle_t { ColumnFamilyHandle* rep; };
124 struct rocksdb_envoptions_t { EnvOptions rep; };
125 struct rocksdb_ingestexternalfileoptions_t { IngestExternalFileOptions rep; };
126 struct rocksdb_sstfilewriter_t { SstFileWriter* rep; };
127 struct rocksdb_ratelimiter_t { RateLimiter* rep; };
128
129 struct rocksdb_compactionfiltercontext_t {
130 CompactionFilter::Context rep;
131 };
132
133 struct rocksdb_compactionfilter_t : public CompactionFilter {
134 void* state_;
135 void (*destructor_)(void*);
136 unsigned char (*filter_)(
137 void*,
138 int level,
139 const char* key, size_t key_length,
140 const char* existing_value, size_t value_length,
141 char** new_value, size_t *new_value_length,
142 unsigned char* value_changed);
143 const char* (*name_)(void*);
144 unsigned char ignore_snapshots_;
145
146 virtual ~rocksdb_compactionfilter_t() {
147 (*destructor_)(state_);
148 }
149
150 virtual bool Filter(int level, const Slice& key, const Slice& existing_value,
151 std::string* new_value,
152 bool* value_changed) const override {
153 char* c_new_value = nullptr;
154 size_t new_value_length = 0;
155 unsigned char c_value_changed = 0;
156 unsigned char result = (*filter_)(
157 state_,
158 level,
159 key.data(), key.size(),
160 existing_value.data(), existing_value.size(),
161 &c_new_value, &new_value_length, &c_value_changed);
162 if (c_value_changed) {
163 new_value->assign(c_new_value, new_value_length);
164 *value_changed = true;
165 }
166 return result;
167 }
168
169 virtual const char* Name() const override { return (*name_)(state_); }
170
171 virtual bool IgnoreSnapshots() const override { return ignore_snapshots_; }
172 };
173
174 struct rocksdb_compactionfilterfactory_t : public CompactionFilterFactory {
175 void* state_;
176 void (*destructor_)(void*);
177 rocksdb_compactionfilter_t* (*create_compaction_filter_)(
178 void*, rocksdb_compactionfiltercontext_t* context);
179 const char* (*name_)(void*);
180
181 virtual ~rocksdb_compactionfilterfactory_t() { (*destructor_)(state_); }
182
183 virtual std::unique_ptr<CompactionFilter> CreateCompactionFilter(
184 const CompactionFilter::Context& context) override {
185 rocksdb_compactionfiltercontext_t ccontext;
186 ccontext.rep = context;
187 CompactionFilter* cf = (*create_compaction_filter_)(state_, &ccontext);
188 return std::unique_ptr<CompactionFilter>(cf);
189 }
190
191 virtual const char* Name() const override { return (*name_)(state_); }
192 };
193
194 struct rocksdb_comparator_t : public Comparator {
195 void* state_;
196 void (*destructor_)(void*);
197 int (*compare_)(
198 void*,
199 const char* a, size_t alen,
200 const char* b, size_t blen);
201 const char* (*name_)(void*);
202
203 virtual ~rocksdb_comparator_t() {
204 (*destructor_)(state_);
205 }
206
207 virtual int Compare(const Slice& a, const Slice& b) const override {
208 return (*compare_)(state_, a.data(), a.size(), b.data(), b.size());
209 }
210
211 virtual const char* Name() const override { return (*name_)(state_); }
212
213 // No-ops since the C binding does not support key shortening methods.
214 virtual void FindShortestSeparator(std::string*,
215 const Slice&) const override {}
216 virtual void FindShortSuccessor(std::string* key) const override {}
217 };
218
219 struct rocksdb_filterpolicy_t : public FilterPolicy {
220 void* state_;
221 void (*destructor_)(void*);
222 const char* (*name_)(void*);
223 char* (*create_)(
224 void*,
225 const char* const* key_array, const size_t* key_length_array,
226 int num_keys,
227 size_t* filter_length);
228 unsigned char (*key_match_)(
229 void*,
230 const char* key, size_t length,
231 const char* filter, size_t filter_length);
232 void (*delete_filter_)(
233 void*,
234 const char* filter, size_t filter_length);
235
236 virtual ~rocksdb_filterpolicy_t() {
237 (*destructor_)(state_);
238 }
239
240 virtual const char* Name() const override { return (*name_)(state_); }
241
242 virtual void CreateFilter(const Slice* keys, int n,
243 std::string* dst) const override {
244 std::vector<const char*> key_pointers(n);
245 std::vector<size_t> key_sizes(n);
246 for (int i = 0; i < n; i++) {
247 key_pointers[i] = keys[i].data();
248 key_sizes[i] = keys[i].size();
249 }
250 size_t len;
251 char* filter = (*create_)(state_, &key_pointers[0], &key_sizes[0], n, &len);
252 dst->append(filter, len);
253
254 if (delete_filter_ != nullptr) {
255 (*delete_filter_)(state_, filter, len);
256 } else {
257 free(filter);
258 }
259 }
260
261 virtual bool KeyMayMatch(const Slice& key,
262 const Slice& filter) const override {
263 return (*key_match_)(state_, key.data(), key.size(),
264 filter.data(), filter.size());
265 }
266 };
267
268 struct rocksdb_mergeoperator_t : public MergeOperator {
269 void* state_;
270 void (*destructor_)(void*);
271 const char* (*name_)(void*);
272 char* (*full_merge_)(
273 void*,
274 const char* key, size_t key_length,
275 const char* existing_value, size_t existing_value_length,
276 const char* const* operands_list, const size_t* operands_list_length,
277 int num_operands,
278 unsigned char* success, size_t* new_value_length);
279 char* (*partial_merge_)(void*, const char* key, size_t key_length,
280 const char* const* operands_list,
281 const size_t* operands_list_length, int num_operands,
282 unsigned char* success, size_t* new_value_length);
283 void (*delete_value_)(
284 void*,
285 const char* value, size_t value_length);
286
287 virtual ~rocksdb_mergeoperator_t() {
288 (*destructor_)(state_);
289 }
290
291 virtual const char* Name() const override { return (*name_)(state_); }
292
293 virtual bool FullMergeV2(const MergeOperationInput& merge_in,
294 MergeOperationOutput* merge_out) const override {
295 size_t n = merge_in.operand_list.size();
296 std::vector<const char*> operand_pointers(n);
297 std::vector<size_t> operand_sizes(n);
298 for (size_t i = 0; i < n; i++) {
299 Slice operand(merge_in.operand_list[i]);
300 operand_pointers[i] = operand.data();
301 operand_sizes[i] = operand.size();
302 }
303
304 const char* existing_value_data = nullptr;
305 size_t existing_value_len = 0;
306 if (merge_in.existing_value != nullptr) {
307 existing_value_data = merge_in.existing_value->data();
308 existing_value_len = merge_in.existing_value->size();
309 }
310
311 unsigned char success;
312 size_t new_value_len;
313 char* tmp_new_value = (*full_merge_)(
314 state_, merge_in.key.data(), merge_in.key.size(), existing_value_data,
315 existing_value_len, &operand_pointers[0], &operand_sizes[0],
316 static_cast<int>(n), &success, &new_value_len);
317 merge_out->new_value.assign(tmp_new_value, new_value_len);
318
319 if (delete_value_ != nullptr) {
320 (*delete_value_)(state_, tmp_new_value, new_value_len);
321 } else {
322 free(tmp_new_value);
323 }
324
325 return success;
326 }
327
328 virtual bool PartialMergeMulti(const Slice& key,
329 const std::deque<Slice>& operand_list,
330 std::string* new_value,
331 Logger* logger) const override {
332 size_t operand_count = operand_list.size();
333 std::vector<const char*> operand_pointers(operand_count);
334 std::vector<size_t> operand_sizes(operand_count);
335 for (size_t i = 0; i < operand_count; ++i) {
336 Slice operand(operand_list[i]);
337 operand_pointers[i] = operand.data();
338 operand_sizes[i] = operand.size();
339 }
340
341 unsigned char success;
342 size_t new_value_len;
343 char* tmp_new_value = (*partial_merge_)(
344 state_, key.data(), key.size(), &operand_pointers[0], &operand_sizes[0],
345 static_cast<int>(operand_count), &success, &new_value_len);
346 new_value->assign(tmp_new_value, new_value_len);
347
348 if (delete_value_ != nullptr) {
349 (*delete_value_)(state_, tmp_new_value, new_value_len);
350 } else {
351 free(tmp_new_value);
352 }
353
354 return success;
355 }
356 };
357
358 struct rocksdb_env_t {
359 Env* rep;
360 bool is_default;
361 };
362
363 struct rocksdb_slicetransform_t : public SliceTransform {
364 void* state_;
365 void (*destructor_)(void*);
366 const char* (*name_)(void*);
367 char* (*transform_)(
368 void*,
369 const char* key, size_t length,
370 size_t* dst_length);
371 unsigned char (*in_domain_)(
372 void*,
373 const char* key, size_t length);
374 unsigned char (*in_range_)(
375 void*,
376 const char* key, size_t length);
377
378 virtual ~rocksdb_slicetransform_t() {
379 (*destructor_)(state_);
380 }
381
382 virtual const char* Name() const override { return (*name_)(state_); }
383
384 virtual Slice Transform(const Slice& src) const override {
385 size_t len;
386 char* dst = (*transform_)(state_, src.data(), src.size(), &len);
387 return Slice(dst, len);
388 }
389
390 virtual bool InDomain(const Slice& src) const override {
391 return (*in_domain_)(state_, src.data(), src.size());
392 }
393
394 virtual bool InRange(const Slice& src) const override {
395 return (*in_range_)(state_, src.data(), src.size());
396 }
397 };
398
399 struct rocksdb_universal_compaction_options_t {
400 rocksdb::CompactionOptionsUniversal *rep;
401 };
402
403 static bool SaveError(char** errptr, const Status& s) {
404 assert(errptr != nullptr);
405 if (s.ok()) {
406 return false;
407 } else if (*errptr == nullptr) {
408 *errptr = strdup(s.ToString().c_str());
409 } else {
410 // TODO(sanjay): Merge with existing error?
411 // This is a bug if *errptr is not created by malloc()
412 free(*errptr);
413 *errptr = strdup(s.ToString().c_str());
414 }
415 return true;
416 }
417
418 static char* CopyString(const std::string& str) {
419 char* result = reinterpret_cast<char*>(malloc(sizeof(char) * str.size()));
420 memcpy(result, str.data(), sizeof(char) * str.size());
421 return result;
422 }
423
424 rocksdb_t* rocksdb_open(
425 const rocksdb_options_t* options,
426 const char* name,
427 char** errptr) {
428 DB* db;
429 if (SaveError(errptr, DB::Open(options->rep, std::string(name), &db))) {
430 return nullptr;
431 }
432 rocksdb_t* result = new rocksdb_t;
433 result->rep = db;
434 return result;
435 }
436
437 rocksdb_t* rocksdb_open_for_read_only(
438 const rocksdb_options_t* options,
439 const char* name,
440 unsigned char error_if_log_file_exist,
441 char** errptr) {
442 DB* db;
443 if (SaveError(errptr, DB::OpenForReadOnly(options->rep, std::string(name), &db, error_if_log_file_exist))) {
444 return nullptr;
445 }
446 rocksdb_t* result = new rocksdb_t;
447 result->rep = db;
448 return result;
449 }
450
451 rocksdb_backup_engine_t* rocksdb_backup_engine_open(
452 const rocksdb_options_t* options, const char* path, char** errptr) {
453 BackupEngine* be;
454 if (SaveError(errptr, BackupEngine::Open(options->rep.env,
455 BackupableDBOptions(path,
456 nullptr,
457 true,
458 options->rep.info_log.get()),
459 &be))) {
460 return nullptr;
461 }
462 rocksdb_backup_engine_t* result = new rocksdb_backup_engine_t;
463 result->rep = be;
464 return result;
465 }
466
467 void rocksdb_backup_engine_create_new_backup(rocksdb_backup_engine_t* be,
468 rocksdb_t* db, char** errptr) {
469 SaveError(errptr, be->rep->CreateNewBackup(db->rep));
470 }
471
472 void rocksdb_backup_engine_purge_old_backups(rocksdb_backup_engine_t* be,
473 uint32_t num_backups_to_keep,
474 char** errptr) {
475 SaveError(errptr, be->rep->PurgeOldBackups(num_backups_to_keep));
476 }
477
478 rocksdb_restore_options_t* rocksdb_restore_options_create() {
479 return new rocksdb_restore_options_t;
480 }
481
482 void rocksdb_restore_options_destroy(rocksdb_restore_options_t* opt) {
483 delete opt;
484 }
485
486 void rocksdb_restore_options_set_keep_log_files(rocksdb_restore_options_t* opt,
487 int v) {
488 opt->rep.keep_log_files = v;
489 }
490
491 void rocksdb_backup_engine_restore_db_from_latest_backup(
492 rocksdb_backup_engine_t* be, const char* db_dir, const char* wal_dir,
493 const rocksdb_restore_options_t* restore_options, char** errptr) {
494 SaveError(errptr, be->rep->RestoreDBFromLatestBackup(std::string(db_dir),
495 std::string(wal_dir),
496 restore_options->rep));
497 }
498
499 const rocksdb_backup_engine_info_t* rocksdb_backup_engine_get_backup_info(
500 rocksdb_backup_engine_t* be) {
501 rocksdb_backup_engine_info_t* result = new rocksdb_backup_engine_info_t;
502 be->rep->GetBackupInfo(&result->rep);
503 return result;
504 }
505
506 int rocksdb_backup_engine_info_count(const rocksdb_backup_engine_info_t* info) {
507 return static_cast<int>(info->rep.size());
508 }
509
510 int64_t rocksdb_backup_engine_info_timestamp(
511 const rocksdb_backup_engine_info_t* info, int index) {
512 return info->rep[index].timestamp;
513 }
514
515 uint32_t rocksdb_backup_engine_info_backup_id(
516 const rocksdb_backup_engine_info_t* info, int index) {
517 return info->rep[index].backup_id;
518 }
519
520 uint64_t rocksdb_backup_engine_info_size(
521 const rocksdb_backup_engine_info_t* info, int index) {
522 return info->rep[index].size;
523 }
524
525 uint32_t rocksdb_backup_engine_info_number_files(
526 const rocksdb_backup_engine_info_t* info, int index) {
527 return info->rep[index].number_files;
528 }
529
530 void rocksdb_backup_engine_info_destroy(
531 const rocksdb_backup_engine_info_t* info) {
532 delete info;
533 }
534
535 void rocksdb_backup_engine_close(rocksdb_backup_engine_t* be) {
536 delete be->rep;
537 delete be;
538 }
539
540 void rocksdb_close(rocksdb_t* db) {
541 delete db->rep;
542 delete db;
543 }
544
545 void rocksdb_options_set_uint64add_merge_operator(rocksdb_options_t* opt) {
546 opt->rep.merge_operator = rocksdb::MergeOperators::CreateUInt64AddOperator();
547 }
548
549 rocksdb_t* rocksdb_open_column_families(
550 const rocksdb_options_t* db_options,
551 const char* name,
552 int num_column_families,
553 const char** column_family_names,
554 const rocksdb_options_t** column_family_options,
555 rocksdb_column_family_handle_t** column_family_handles,
556 char** errptr) {
557 std::vector<ColumnFamilyDescriptor> column_families;
558 for (int i = 0; i < num_column_families; i++) {
559 column_families.push_back(ColumnFamilyDescriptor(
560 std::string(column_family_names[i]),
561 ColumnFamilyOptions(column_family_options[i]->rep)));
562 }
563
564 DB* db;
565 std::vector<ColumnFamilyHandle*> handles;
566 if (SaveError(errptr, DB::Open(DBOptions(db_options->rep),
567 std::string(name), column_families, &handles, &db))) {
568 return nullptr;
569 }
570
571 for (size_t i = 0; i < handles.size(); i++) {
572 rocksdb_column_family_handle_t* c_handle = new rocksdb_column_family_handle_t;
573 c_handle->rep = handles[i];
574 column_family_handles[i] = c_handle;
575 }
576 rocksdb_t* result = new rocksdb_t;
577 result->rep = db;
578 return result;
579 }
580
581 rocksdb_t* rocksdb_open_for_read_only_column_families(
582 const rocksdb_options_t* db_options,
583 const char* name,
584 int num_column_families,
585 const char** column_family_names,
586 const rocksdb_options_t** column_family_options,
587 rocksdb_column_family_handle_t** column_family_handles,
588 unsigned char error_if_log_file_exist,
589 char** errptr) {
590 std::vector<ColumnFamilyDescriptor> column_families;
591 for (int i = 0; i < num_column_families; i++) {
592 column_families.push_back(ColumnFamilyDescriptor(
593 std::string(column_family_names[i]),
594 ColumnFamilyOptions(column_family_options[i]->rep)));
595 }
596
597 DB* db;
598 std::vector<ColumnFamilyHandle*> handles;
599 if (SaveError(errptr, DB::OpenForReadOnly(DBOptions(db_options->rep),
600 std::string(name), column_families, &handles, &db, error_if_log_file_exist))) {
601 return nullptr;
602 }
603
604 for (size_t i = 0; i < handles.size(); i++) {
605 rocksdb_column_family_handle_t* c_handle = new rocksdb_column_family_handle_t;
606 c_handle->rep = handles[i];
607 column_family_handles[i] = c_handle;
608 }
609 rocksdb_t* result = new rocksdb_t;
610 result->rep = db;
611 return result;
612 }
613
614 char** rocksdb_list_column_families(
615 const rocksdb_options_t* options,
616 const char* name,
617 size_t* lencfs,
618 char** errptr) {
619 std::vector<std::string> fams;
620 SaveError(errptr,
621 DB::ListColumnFamilies(DBOptions(options->rep),
622 std::string(name), &fams));
623
624 *lencfs = fams.size();
625 char** column_families = static_cast<char**>(malloc(sizeof(char*) * fams.size()));
626 for (size_t i = 0; i < fams.size(); i++) {
627 column_families[i] = strdup(fams[i].c_str());
628 }
629 return column_families;
630 }
631
632 void rocksdb_list_column_families_destroy(char** list, size_t len) {
633 for (size_t i = 0; i < len; ++i) {
634 free(list[i]);
635 }
636 free(list);
637 }
638
639 rocksdb_column_family_handle_t* rocksdb_create_column_family(
640 rocksdb_t* db,
641 const rocksdb_options_t* column_family_options,
642 const char* column_family_name,
643 char** errptr) {
644 rocksdb_column_family_handle_t* handle = new rocksdb_column_family_handle_t;
645 SaveError(errptr,
646 db->rep->CreateColumnFamily(ColumnFamilyOptions(column_family_options->rep),
647 std::string(column_family_name), &(handle->rep)));
648 return handle;
649 }
650
651 void rocksdb_drop_column_family(
652 rocksdb_t* db,
653 rocksdb_column_family_handle_t* handle,
654 char** errptr) {
655 SaveError(errptr, db->rep->DropColumnFamily(handle->rep));
656 }
657
658 void rocksdb_column_family_handle_destroy(rocksdb_column_family_handle_t* handle) {
659 delete handle->rep;
660 delete handle;
661 }
662
663 void rocksdb_put(
664 rocksdb_t* db,
665 const rocksdb_writeoptions_t* options,
666 const char* key, size_t keylen,
667 const char* val, size_t vallen,
668 char** errptr) {
669 SaveError(errptr,
670 db->rep->Put(options->rep, Slice(key, keylen), Slice(val, vallen)));
671 }
672
673 void rocksdb_put_cf(
674 rocksdb_t* db,
675 const rocksdb_writeoptions_t* options,
676 rocksdb_column_family_handle_t* column_family,
677 const char* key, size_t keylen,
678 const char* val, size_t vallen,
679 char** errptr) {
680 SaveError(errptr,
681 db->rep->Put(options->rep, column_family->rep,
682 Slice(key, keylen), Slice(val, vallen)));
683 }
684
685 void rocksdb_delete(
686 rocksdb_t* db,
687 const rocksdb_writeoptions_t* options,
688 const char* key, size_t keylen,
689 char** errptr) {
690 SaveError(errptr, db->rep->Delete(options->rep, Slice(key, keylen)));
691 }
692
693 void rocksdb_delete_cf(
694 rocksdb_t* db,
695 const rocksdb_writeoptions_t* options,
696 rocksdb_column_family_handle_t* column_family,
697 const char* key, size_t keylen,
698 char** errptr) {
699 SaveError(errptr, db->rep->Delete(options->rep, column_family->rep,
700 Slice(key, keylen)));
701 }
702
703 void rocksdb_merge(
704 rocksdb_t* db,
705 const rocksdb_writeoptions_t* options,
706 const char* key, size_t keylen,
707 const char* val, size_t vallen,
708 char** errptr) {
709 SaveError(errptr,
710 db->rep->Merge(options->rep, Slice(key, keylen), Slice(val, vallen)));
711 }
712
713 void rocksdb_merge_cf(
714 rocksdb_t* db,
715 const rocksdb_writeoptions_t* options,
716 rocksdb_column_family_handle_t* column_family,
717 const char* key, size_t keylen,
718 const char* val, size_t vallen,
719 char** errptr) {
720 SaveError(errptr,
721 db->rep->Merge(options->rep, column_family->rep,
722 Slice(key, keylen), Slice(val, vallen)));
723 }
724
725 void rocksdb_write(
726 rocksdb_t* db,
727 const rocksdb_writeoptions_t* options,
728 rocksdb_writebatch_t* batch,
729 char** errptr) {
730 SaveError(errptr, db->rep->Write(options->rep, &batch->rep));
731 }
732
733 char* rocksdb_get(
734 rocksdb_t* db,
735 const rocksdb_readoptions_t* options,
736 const char* key, size_t keylen,
737 size_t* vallen,
738 char** errptr) {
739 char* result = nullptr;
740 std::string tmp;
741 Status s = db->rep->Get(options->rep, Slice(key, keylen), &tmp);
742 if (s.ok()) {
743 *vallen = tmp.size();
744 result = CopyString(tmp);
745 } else {
746 *vallen = 0;
747 if (!s.IsNotFound()) {
748 SaveError(errptr, s);
749 }
750 }
751 return result;
752 }
753
754 char* rocksdb_get_cf(
755 rocksdb_t* db,
756 const rocksdb_readoptions_t* options,
757 rocksdb_column_family_handle_t* column_family,
758 const char* key, size_t keylen,
759 size_t* vallen,
760 char** errptr) {
761 char* result = nullptr;
762 std::string tmp;
763 Status s = db->rep->Get(options->rep, column_family->rep,
764 Slice(key, keylen), &tmp);
765 if (s.ok()) {
766 *vallen = tmp.size();
767 result = CopyString(tmp);
768 } else {
769 *vallen = 0;
770 if (!s.IsNotFound()) {
771 SaveError(errptr, s);
772 }
773 }
774 return result;
775 }
776
777 void rocksdb_multi_get(
778 rocksdb_t* db,
779 const rocksdb_readoptions_t* options,
780 size_t num_keys, const char* const* keys_list,
781 const size_t* keys_list_sizes,
782 char** values_list, size_t* values_list_sizes,
783 char** errs) {
784 std::vector<Slice> keys(num_keys);
785 for (size_t i = 0; i < num_keys; i++) {
786 keys[i] = Slice(keys_list[i], keys_list_sizes[i]);
787 }
788 std::vector<std::string> values(num_keys);
789 std::vector<Status> statuses = db->rep->MultiGet(options->rep, keys, &values);
790 for (size_t i = 0; i < num_keys; i++) {
791 if (statuses[i].ok()) {
792 values_list[i] = CopyString(values[i]);
793 values_list_sizes[i] = values[i].size();
794 errs[i] = nullptr;
795 } else {
796 values_list[i] = nullptr;
797 values_list_sizes[i] = 0;
798 if (!statuses[i].IsNotFound()) {
799 errs[i] = strdup(statuses[i].ToString().c_str());
800 } else {
801 errs[i] = nullptr;
802 }
803 }
804 }
805 }
806
807 void rocksdb_multi_get_cf(
808 rocksdb_t* db,
809 const rocksdb_readoptions_t* options,
810 const rocksdb_column_family_handle_t* const* column_families,
811 size_t num_keys, const char* const* keys_list,
812 const size_t* keys_list_sizes,
813 char** values_list, size_t* values_list_sizes,
814 char** errs) {
815 std::vector<Slice> keys(num_keys);
816 std::vector<ColumnFamilyHandle*> cfs(num_keys);
817 for (size_t i = 0; i < num_keys; i++) {
818 keys[i] = Slice(keys_list[i], keys_list_sizes[i]);
819 cfs[i] = column_families[i]->rep;
820 }
821 std::vector<std::string> values(num_keys);
822 std::vector<Status> statuses = db->rep->MultiGet(options->rep, cfs, keys, &values);
823 for (size_t i = 0; i < num_keys; i++) {
824 if (statuses[i].ok()) {
825 values_list[i] = CopyString(values[i]);
826 values_list_sizes[i] = values[i].size();
827 errs[i] = nullptr;
828 } else {
829 values_list[i] = nullptr;
830 values_list_sizes[i] = 0;
831 if (!statuses[i].IsNotFound()) {
832 errs[i] = strdup(statuses[i].ToString().c_str());
833 } else {
834 errs[i] = nullptr;
835 }
836 }
837 }
838 }
839
840 rocksdb_iterator_t* rocksdb_create_iterator(
841 rocksdb_t* db,
842 const rocksdb_readoptions_t* options) {
843 rocksdb_iterator_t* result = new rocksdb_iterator_t;
844 result->rep = db->rep->NewIterator(options->rep);
845 return result;
846 }
847
848 rocksdb_iterator_t* rocksdb_create_iterator_cf(
849 rocksdb_t* db,
850 const rocksdb_readoptions_t* options,
851 rocksdb_column_family_handle_t* column_family) {
852 rocksdb_iterator_t* result = new rocksdb_iterator_t;
853 result->rep = db->rep->NewIterator(options->rep, column_family->rep);
854 return result;
855 }
856
857 void rocksdb_create_iterators(
858 rocksdb_t *db,
859 rocksdb_readoptions_t* opts,
860 rocksdb_column_family_handle_t** column_families,
861 rocksdb_iterator_t** iterators,
862 size_t size,
863 char** errptr) {
864 std::vector<ColumnFamilyHandle*> column_families_vec;
865 for (size_t i = 0; i < size; i++) {
866 column_families_vec.push_back(column_families[i]->rep);
867 }
868
869 std::vector<Iterator*> res;
870 Status status = db->rep->NewIterators(opts->rep, column_families_vec, &res);
871 assert(res.size() == size);
872 if (SaveError(errptr, status)) {
873 return;
874 }
875
876 for (size_t i = 0; i < size; i++) {
877 iterators[i] = new rocksdb_iterator_t;
878 iterators[i]->rep = res[i];
879 }
880 }
881
882 const rocksdb_snapshot_t* rocksdb_create_snapshot(
883 rocksdb_t* db) {
884 rocksdb_snapshot_t* result = new rocksdb_snapshot_t;
885 result->rep = db->rep->GetSnapshot();
886 return result;
887 }
888
889 void rocksdb_release_snapshot(
890 rocksdb_t* db,
891 const rocksdb_snapshot_t* snapshot) {
892 db->rep->ReleaseSnapshot(snapshot->rep);
893 delete snapshot;
894 }
895
896 char* rocksdb_property_value(
897 rocksdb_t* db,
898 const char* propname) {
899 std::string tmp;
900 if (db->rep->GetProperty(Slice(propname), &tmp)) {
901 // We use strdup() since we expect human readable output.
902 return strdup(tmp.c_str());
903 } else {
904 return nullptr;
905 }
906 }
907
908 int rocksdb_property_int(
909 rocksdb_t* db,
910 const char* propname,
911 uint64_t *out_val) {
912 if (db->rep->GetIntProperty(Slice(propname), out_val)) {
913 return 0;
914 } else {
915 return -1;
916 }
917 }
918
919 char* rocksdb_property_value_cf(
920 rocksdb_t* db,
921 rocksdb_column_family_handle_t* column_family,
922 const char* propname) {
923 std::string tmp;
924 if (db->rep->GetProperty(column_family->rep, Slice(propname), &tmp)) {
925 // We use strdup() since we expect human readable output.
926 return strdup(tmp.c_str());
927 } else {
928 return nullptr;
929 }
930 }
931
932 void rocksdb_approximate_sizes(
933 rocksdb_t* db,
934 int num_ranges,
935 const char* const* range_start_key, const size_t* range_start_key_len,
936 const char* const* range_limit_key, const size_t* range_limit_key_len,
937 uint64_t* sizes) {
938 Range* ranges = new Range[num_ranges];
939 for (int i = 0; i < num_ranges; i++) {
940 ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]);
941 ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]);
942 }
943 db->rep->GetApproximateSizes(ranges, num_ranges, sizes);
944 delete[] ranges;
945 }
946
947 void rocksdb_approximate_sizes_cf(
948 rocksdb_t* db,
949 rocksdb_column_family_handle_t* column_family,
950 int num_ranges,
951 const char* const* range_start_key, const size_t* range_start_key_len,
952 const char* const* range_limit_key, const size_t* range_limit_key_len,
953 uint64_t* sizes) {
954 Range* ranges = new Range[num_ranges];
955 for (int i = 0; i < num_ranges; i++) {
956 ranges[i].start = Slice(range_start_key[i], range_start_key_len[i]);
957 ranges[i].limit = Slice(range_limit_key[i], range_limit_key_len[i]);
958 }
959 db->rep->GetApproximateSizes(column_family->rep, ranges, num_ranges, sizes);
960 delete[] ranges;
961 }
962
963 void rocksdb_delete_file(
964 rocksdb_t* db,
965 const char* name) {
966 db->rep->DeleteFile(name);
967 }
968
969 const rocksdb_livefiles_t* rocksdb_livefiles(
970 rocksdb_t* db) {
971 rocksdb_livefiles_t* result = new rocksdb_livefiles_t;
972 db->rep->GetLiveFilesMetaData(&result->rep);
973 return result;
974 }
975
976 void rocksdb_compact_range(
977 rocksdb_t* db,
978 const char* start_key, size_t start_key_len,
979 const char* limit_key, size_t limit_key_len) {
980 Slice a, b;
981 db->rep->CompactRange(
982 CompactRangeOptions(),
983 // Pass nullptr Slice if corresponding "const char*" is nullptr
984 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
985 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr));
986 }
987
988 void rocksdb_compact_range_cf(
989 rocksdb_t* db,
990 rocksdb_column_family_handle_t* column_family,
991 const char* start_key, size_t start_key_len,
992 const char* limit_key, size_t limit_key_len) {
993 Slice a, b;
994 db->rep->CompactRange(
995 CompactRangeOptions(), column_family->rep,
996 // Pass nullptr Slice if corresponding "const char*" is nullptr
997 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
998 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr));
999 }
1000
1001 void rocksdb_compact_range_opt(rocksdb_t* db, rocksdb_compactoptions_t* opt,
1002 const char* start_key, size_t start_key_len,
1003 const char* limit_key, size_t limit_key_len) {
1004 Slice a, b;
1005 db->rep->CompactRange(
1006 opt->rep,
1007 // Pass nullptr Slice if corresponding "const char*" is nullptr
1008 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
1009 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr));
1010 }
1011
1012 void rocksdb_compact_range_cf_opt(rocksdb_t* db,
1013 rocksdb_column_family_handle_t* column_family,
1014 rocksdb_compactoptions_t* opt,
1015 const char* start_key, size_t start_key_len,
1016 const char* limit_key, size_t limit_key_len) {
1017 Slice a, b;
1018 db->rep->CompactRange(
1019 opt->rep, column_family->rep,
1020 // Pass nullptr Slice if corresponding "const char*" is nullptr
1021 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
1022 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr));
1023 }
1024
1025 void rocksdb_flush(
1026 rocksdb_t* db,
1027 const rocksdb_flushoptions_t* options,
1028 char** errptr) {
1029 SaveError(errptr, db->rep->Flush(options->rep));
1030 }
1031
1032 void rocksdb_disable_file_deletions(
1033 rocksdb_t* db,
1034 char** errptr) {
1035 SaveError(errptr, db->rep->DisableFileDeletions());
1036 }
1037
1038 void rocksdb_enable_file_deletions(
1039 rocksdb_t* db,
1040 unsigned char force,
1041 char** errptr) {
1042 SaveError(errptr, db->rep->EnableFileDeletions(force));
1043 }
1044
1045 void rocksdb_destroy_db(
1046 const rocksdb_options_t* options,
1047 const char* name,
1048 char** errptr) {
1049 SaveError(errptr, DestroyDB(name, options->rep));
1050 }
1051
1052 void rocksdb_repair_db(
1053 const rocksdb_options_t* options,
1054 const char* name,
1055 char** errptr) {
1056 SaveError(errptr, RepairDB(name, options->rep));
1057 }
1058
1059 void rocksdb_iter_destroy(rocksdb_iterator_t* iter) {
1060 delete iter->rep;
1061 delete iter;
1062 }
1063
1064 unsigned char rocksdb_iter_valid(const rocksdb_iterator_t* iter) {
1065 return iter->rep->Valid();
1066 }
1067
1068 void rocksdb_iter_seek_to_first(rocksdb_iterator_t* iter) {
1069 iter->rep->SeekToFirst();
1070 }
1071
1072 void rocksdb_iter_seek_to_last(rocksdb_iterator_t* iter) {
1073 iter->rep->SeekToLast();
1074 }
1075
1076 void rocksdb_iter_seek(rocksdb_iterator_t* iter, const char* k, size_t klen) {
1077 iter->rep->Seek(Slice(k, klen));
1078 }
1079
1080 void rocksdb_iter_seek_for_prev(rocksdb_iterator_t* iter, const char* k,
1081 size_t klen) {
1082 iter->rep->SeekForPrev(Slice(k, klen));
1083 }
1084
1085 void rocksdb_iter_next(rocksdb_iterator_t* iter) {
1086 iter->rep->Next();
1087 }
1088
1089 void rocksdb_iter_prev(rocksdb_iterator_t* iter) {
1090 iter->rep->Prev();
1091 }
1092
1093 const char* rocksdb_iter_key(const rocksdb_iterator_t* iter, size_t* klen) {
1094 Slice s = iter->rep->key();
1095 *klen = s.size();
1096 return s.data();
1097 }
1098
1099 const char* rocksdb_iter_value(const rocksdb_iterator_t* iter, size_t* vlen) {
1100 Slice s = iter->rep->value();
1101 *vlen = s.size();
1102 return s.data();
1103 }
1104
1105 void rocksdb_iter_get_error(const rocksdb_iterator_t* iter, char** errptr) {
1106 SaveError(errptr, iter->rep->status());
1107 }
1108
1109 rocksdb_writebatch_t* rocksdb_writebatch_create() {
1110 return new rocksdb_writebatch_t;
1111 }
1112
1113 rocksdb_writebatch_t* rocksdb_writebatch_create_from(const char* rep,
1114 size_t size) {
1115 rocksdb_writebatch_t* b = new rocksdb_writebatch_t;
1116 b->rep = WriteBatch(std::string(rep, size));
1117 return b;
1118 }
1119
1120 void rocksdb_writebatch_destroy(rocksdb_writebatch_t* b) {
1121 delete b;
1122 }
1123
1124 void rocksdb_writebatch_clear(rocksdb_writebatch_t* b) {
1125 b->rep.Clear();
1126 }
1127
1128 int rocksdb_writebatch_count(rocksdb_writebatch_t* b) {
1129 return b->rep.Count();
1130 }
1131
1132 void rocksdb_writebatch_put(
1133 rocksdb_writebatch_t* b,
1134 const char* key, size_t klen,
1135 const char* val, size_t vlen) {
1136 b->rep.Put(Slice(key, klen), Slice(val, vlen));
1137 }
1138
1139 void rocksdb_writebatch_put_cf(
1140 rocksdb_writebatch_t* b,
1141 rocksdb_column_family_handle_t* column_family,
1142 const char* key, size_t klen,
1143 const char* val, size_t vlen) {
1144 b->rep.Put(column_family->rep, Slice(key, klen), Slice(val, vlen));
1145 }
1146
1147 void rocksdb_writebatch_putv(
1148 rocksdb_writebatch_t* b,
1149 int num_keys, const char* const* keys_list,
1150 const size_t* keys_list_sizes,
1151 int num_values, const char* const* values_list,
1152 const size_t* values_list_sizes) {
1153 std::vector<Slice> key_slices(num_keys);
1154 for (int i = 0; i < num_keys; i++) {
1155 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1156 }
1157 std::vector<Slice> value_slices(num_values);
1158 for (int i = 0; i < num_values; i++) {
1159 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1160 }
1161 b->rep.Put(SliceParts(key_slices.data(), num_keys),
1162 SliceParts(value_slices.data(), num_values));
1163 }
1164
1165 void rocksdb_writebatch_putv_cf(
1166 rocksdb_writebatch_t* b,
1167 rocksdb_column_family_handle_t* column_family,
1168 int num_keys, const char* const* keys_list,
1169 const size_t* keys_list_sizes,
1170 int num_values, const char* const* values_list,
1171 const size_t* values_list_sizes) {
1172 std::vector<Slice> key_slices(num_keys);
1173 for (int i = 0; i < num_keys; i++) {
1174 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1175 }
1176 std::vector<Slice> value_slices(num_values);
1177 for (int i = 0; i < num_values; i++) {
1178 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1179 }
1180 b->rep.Put(column_family->rep, SliceParts(key_slices.data(), num_keys),
1181 SliceParts(value_slices.data(), num_values));
1182 }
1183
1184 void rocksdb_writebatch_merge(
1185 rocksdb_writebatch_t* b,
1186 const char* key, size_t klen,
1187 const char* val, size_t vlen) {
1188 b->rep.Merge(Slice(key, klen), Slice(val, vlen));
1189 }
1190
1191 void rocksdb_writebatch_merge_cf(
1192 rocksdb_writebatch_t* b,
1193 rocksdb_column_family_handle_t* column_family,
1194 const char* key, size_t klen,
1195 const char* val, size_t vlen) {
1196 b->rep.Merge(column_family->rep, Slice(key, klen), Slice(val, vlen));
1197 }
1198
1199 void rocksdb_writebatch_mergev(
1200 rocksdb_writebatch_t* b,
1201 int num_keys, const char* const* keys_list,
1202 const size_t* keys_list_sizes,
1203 int num_values, const char* const* values_list,
1204 const size_t* values_list_sizes) {
1205 std::vector<Slice> key_slices(num_keys);
1206 for (int i = 0; i < num_keys; i++) {
1207 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1208 }
1209 std::vector<Slice> value_slices(num_values);
1210 for (int i = 0; i < num_values; i++) {
1211 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1212 }
1213 b->rep.Merge(SliceParts(key_slices.data(), num_keys),
1214 SliceParts(value_slices.data(), num_values));
1215 }
1216
1217 void rocksdb_writebatch_mergev_cf(
1218 rocksdb_writebatch_t* b,
1219 rocksdb_column_family_handle_t* column_family,
1220 int num_keys, const char* const* keys_list,
1221 const size_t* keys_list_sizes,
1222 int num_values, const char* const* values_list,
1223 const size_t* values_list_sizes) {
1224 std::vector<Slice> key_slices(num_keys);
1225 for (int i = 0; i < num_keys; i++) {
1226 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1227 }
1228 std::vector<Slice> value_slices(num_values);
1229 for (int i = 0; i < num_values; i++) {
1230 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1231 }
1232 b->rep.Merge(column_family->rep, SliceParts(key_slices.data(), num_keys),
1233 SliceParts(value_slices.data(), num_values));
1234 }
1235
1236 void rocksdb_writebatch_delete(
1237 rocksdb_writebatch_t* b,
1238 const char* key, size_t klen) {
1239 b->rep.Delete(Slice(key, klen));
1240 }
1241
1242 void rocksdb_writebatch_delete_cf(
1243 rocksdb_writebatch_t* b,
1244 rocksdb_column_family_handle_t* column_family,
1245 const char* key, size_t klen) {
1246 b->rep.Delete(column_family->rep, Slice(key, klen));
1247 }
1248
1249 void rocksdb_writebatch_deletev(
1250 rocksdb_writebatch_t* b,
1251 int num_keys, const char* const* keys_list,
1252 const size_t* keys_list_sizes) {
1253 std::vector<Slice> key_slices(num_keys);
1254 for (int i = 0; i < num_keys; i++) {
1255 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1256 }
1257 b->rep.Delete(SliceParts(key_slices.data(), num_keys));
1258 }
1259
1260 void rocksdb_writebatch_deletev_cf(
1261 rocksdb_writebatch_t* b,
1262 rocksdb_column_family_handle_t* column_family,
1263 int num_keys, const char* const* keys_list,
1264 const size_t* keys_list_sizes) {
1265 std::vector<Slice> key_slices(num_keys);
1266 for (int i = 0; i < num_keys; i++) {
1267 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1268 }
1269 b->rep.Delete(column_family->rep, SliceParts(key_slices.data(), num_keys));
1270 }
1271
1272 void rocksdb_writebatch_delete_range(rocksdb_writebatch_t* b,
1273 const char* start_key,
1274 size_t start_key_len, const char* end_key,
1275 size_t end_key_len) {
1276 b->rep.DeleteRange(Slice(start_key, start_key_len),
1277 Slice(end_key, end_key_len));
1278 }
1279
1280 void rocksdb_writebatch_delete_range_cf(
1281 rocksdb_writebatch_t* b, rocksdb_column_family_handle_t* column_family,
1282 const char* start_key, size_t start_key_len, const char* end_key,
1283 size_t end_key_len) {
1284 b->rep.DeleteRange(column_family->rep, Slice(start_key, start_key_len),
1285 Slice(end_key, end_key_len));
1286 }
1287
1288 void rocksdb_writebatch_delete_rangev(rocksdb_writebatch_t* b, int num_keys,
1289 const char* const* start_keys_list,
1290 const size_t* start_keys_list_sizes,
1291 const char* const* end_keys_list,
1292 const size_t* end_keys_list_sizes) {
1293 std::vector<Slice> start_key_slices(num_keys);
1294 std::vector<Slice> end_key_slices(num_keys);
1295 for (int i = 0; i < num_keys; i++) {
1296 start_key_slices[i] = Slice(start_keys_list[i], start_keys_list_sizes[i]);
1297 end_key_slices[i] = Slice(end_keys_list[i], end_keys_list_sizes[i]);
1298 }
1299 b->rep.DeleteRange(SliceParts(start_key_slices.data(), num_keys),
1300 SliceParts(end_key_slices.data(), num_keys));
1301 }
1302
1303 void rocksdb_writebatch_delete_rangev_cf(
1304 rocksdb_writebatch_t* b, rocksdb_column_family_handle_t* column_family,
1305 int num_keys, const char* const* start_keys_list,
1306 const size_t* start_keys_list_sizes, const char* const* end_keys_list,
1307 const size_t* end_keys_list_sizes) {
1308 std::vector<Slice> start_key_slices(num_keys);
1309 std::vector<Slice> end_key_slices(num_keys);
1310 for (int i = 0; i < num_keys; i++) {
1311 start_key_slices[i] = Slice(start_keys_list[i], start_keys_list_sizes[i]);
1312 end_key_slices[i] = Slice(end_keys_list[i], end_keys_list_sizes[i]);
1313 }
1314 b->rep.DeleteRange(column_family->rep,
1315 SliceParts(start_key_slices.data(), num_keys),
1316 SliceParts(end_key_slices.data(), num_keys));
1317 }
1318
1319 void rocksdb_writebatch_put_log_data(
1320 rocksdb_writebatch_t* b,
1321 const char* blob, size_t len) {
1322 b->rep.PutLogData(Slice(blob, len));
1323 }
1324
1325 void rocksdb_writebatch_iterate(
1326 rocksdb_writebatch_t* b,
1327 void* state,
1328 void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen),
1329 void (*deleted)(void*, const char* k, size_t klen)) {
1330 class H : public WriteBatch::Handler {
1331 public:
1332 void* state_;
1333 void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen);
1334 void (*deleted_)(void*, const char* k, size_t klen);
1335 virtual void Put(const Slice& key, const Slice& value) override {
1336 (*put_)(state_, key.data(), key.size(), value.data(), value.size());
1337 }
1338 virtual void Delete(const Slice& key) override {
1339 (*deleted_)(state_, key.data(), key.size());
1340 }
1341 };
1342 H handler;
1343 handler.state_ = state;
1344 handler.put_ = put;
1345 handler.deleted_ = deleted;
1346 b->rep.Iterate(&handler);
1347 }
1348
1349 const char* rocksdb_writebatch_data(rocksdb_writebatch_t* b, size_t* size) {
1350 *size = b->rep.GetDataSize();
1351 return b->rep.Data().c_str();
1352 }
1353
1354 void rocksdb_writebatch_set_save_point(rocksdb_writebatch_t* b) {
1355 b->rep.SetSavePoint();
1356 }
1357
1358 void rocksdb_writebatch_rollback_to_save_point(rocksdb_writebatch_t* b,
1359 char** errptr) {
1360 SaveError(errptr, b->rep.RollbackToSavePoint());
1361 }
1362
1363 rocksdb_writebatch_wi_t* rocksdb_writebatch_wi_create(size_t reserved_bytes, unsigned char overwrite_key) {
1364 rocksdb_writebatch_wi_t* b = new rocksdb_writebatch_wi_t;
1365 b->rep = new WriteBatchWithIndex(BytewiseComparator(), reserved_bytes, overwrite_key);
1366 return b;
1367 }
1368
1369 void rocksdb_writebatch_wi_destroy(rocksdb_writebatch_wi_t* b) {
1370 if (b->rep) {
1371 delete b->rep;
1372 }
1373 delete b;
1374 }
1375
1376 void rocksdb_writebatch_wi_clear(rocksdb_writebatch_wi_t* b) {
1377 b->rep->Clear();
1378 }
1379
1380 int rocksdb_writebatch_wi_count(rocksdb_writebatch_wi_t* b) {
1381 return b->rep->GetWriteBatch()->Count();
1382 }
1383
1384 void rocksdb_writebatch_wi_put(
1385 rocksdb_writebatch_wi_t* b,
1386 const char* key, size_t klen,
1387 const char* val, size_t vlen) {
1388 b->rep->Put(Slice(key, klen), Slice(val, vlen));
1389 }
1390
1391 void rocksdb_writebatch_wi_put_cf(
1392 rocksdb_writebatch_wi_t* b,
1393 rocksdb_column_family_handle_t* column_family,
1394 const char* key, size_t klen,
1395 const char* val, size_t vlen) {
1396 b->rep->Put(column_family->rep, Slice(key, klen), Slice(val, vlen));
1397 }
1398
1399 void rocksdb_writebatch_wi_putv(
1400 rocksdb_writebatch_wi_t* b,
1401 int num_keys, const char* const* keys_list,
1402 const size_t* keys_list_sizes,
1403 int num_values, const char* const* values_list,
1404 const size_t* values_list_sizes) {
1405 std::vector<Slice> key_slices(num_keys);
1406 for (int i = 0; i < num_keys; i++) {
1407 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1408 }
1409 std::vector<Slice> value_slices(num_values);
1410 for (int i = 0; i < num_values; i++) {
1411 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1412 }
1413 b->rep->Put(SliceParts(key_slices.data(), num_keys),
1414 SliceParts(value_slices.data(), num_values));
1415 }
1416
1417 void rocksdb_writebatch_wi_putv_cf(
1418 rocksdb_writebatch_wi_t* b,
1419 rocksdb_column_family_handle_t* column_family,
1420 int num_keys, const char* const* keys_list,
1421 const size_t* keys_list_sizes,
1422 int num_values, const char* const* values_list,
1423 const size_t* values_list_sizes) {
1424 std::vector<Slice> key_slices(num_keys);
1425 for (int i = 0; i < num_keys; i++) {
1426 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1427 }
1428 std::vector<Slice> value_slices(num_values);
1429 for (int i = 0; i < num_values; i++) {
1430 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1431 }
1432 b->rep->Put(column_family->rep, SliceParts(key_slices.data(), num_keys),
1433 SliceParts(value_slices.data(), num_values));
1434 }
1435
1436 void rocksdb_writebatch_wi_merge(
1437 rocksdb_writebatch_wi_t* b,
1438 const char* key, size_t klen,
1439 const char* val, size_t vlen) {
1440 b->rep->Merge(Slice(key, klen), Slice(val, vlen));
1441 }
1442
1443 void rocksdb_writebatch_wi_merge_cf(
1444 rocksdb_writebatch_wi_t* b,
1445 rocksdb_column_family_handle_t* column_family,
1446 const char* key, size_t klen,
1447 const char* val, size_t vlen) {
1448 b->rep->Merge(column_family->rep, Slice(key, klen), Slice(val, vlen));
1449 }
1450
1451 void rocksdb_writebatch_wi_mergev(
1452 rocksdb_writebatch_wi_t* b,
1453 int num_keys, const char* const* keys_list,
1454 const size_t* keys_list_sizes,
1455 int num_values, const char* const* values_list,
1456 const size_t* values_list_sizes) {
1457 std::vector<Slice> key_slices(num_keys);
1458 for (int i = 0; i < num_keys; i++) {
1459 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1460 }
1461 std::vector<Slice> value_slices(num_values);
1462 for (int i = 0; i < num_values; i++) {
1463 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1464 }
1465 b->rep->Merge(SliceParts(key_slices.data(), num_keys),
1466 SliceParts(value_slices.data(), num_values));
1467 }
1468
1469 void rocksdb_writebatch_wi_mergev_cf(
1470 rocksdb_writebatch_wi_t* b,
1471 rocksdb_column_family_handle_t* column_family,
1472 int num_keys, const char* const* keys_list,
1473 const size_t* keys_list_sizes,
1474 int num_values, const char* const* values_list,
1475 const size_t* values_list_sizes) {
1476 std::vector<Slice> key_slices(num_keys);
1477 for (int i = 0; i < num_keys; i++) {
1478 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1479 }
1480 std::vector<Slice> value_slices(num_values);
1481 for (int i = 0; i < num_values; i++) {
1482 value_slices[i] = Slice(values_list[i], values_list_sizes[i]);
1483 }
1484 b->rep->Merge(column_family->rep, SliceParts(key_slices.data(), num_keys),
1485 SliceParts(value_slices.data(), num_values));
1486 }
1487
1488 void rocksdb_writebatch_wi_delete(
1489 rocksdb_writebatch_wi_t* b,
1490 const char* key, size_t klen) {
1491 b->rep->Delete(Slice(key, klen));
1492 }
1493
1494 void rocksdb_writebatch_wi_delete_cf(
1495 rocksdb_writebatch_wi_t* b,
1496 rocksdb_column_family_handle_t* column_family,
1497 const char* key, size_t klen) {
1498 b->rep->Delete(column_family->rep, Slice(key, klen));
1499 }
1500
1501 void rocksdb_writebatch_wi_deletev(
1502 rocksdb_writebatch_wi_t* b,
1503 int num_keys, const char* const* keys_list,
1504 const size_t* keys_list_sizes) {
1505 std::vector<Slice> key_slices(num_keys);
1506 for (int i = 0; i < num_keys; i++) {
1507 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1508 }
1509 b->rep->Delete(SliceParts(key_slices.data(), num_keys));
1510 }
1511
1512 void rocksdb_writebatch_wi_deletev_cf(
1513 rocksdb_writebatch_wi_t* b,
1514 rocksdb_column_family_handle_t* column_family,
1515 int num_keys, const char* const* keys_list,
1516 const size_t* keys_list_sizes) {
1517 std::vector<Slice> key_slices(num_keys);
1518 for (int i = 0; i < num_keys; i++) {
1519 key_slices[i] = Slice(keys_list[i], keys_list_sizes[i]);
1520 }
1521 b->rep->Delete(column_family->rep, SliceParts(key_slices.data(), num_keys));
1522 }
1523
1524 void rocksdb_writebatch_wi_delete_range(rocksdb_writebatch_wi_t* b,
1525 const char* start_key,
1526 size_t start_key_len, const char* end_key,
1527 size_t end_key_len) {
1528 b->rep->DeleteRange(Slice(start_key, start_key_len),
1529 Slice(end_key, end_key_len));
1530 }
1531
1532 void rocksdb_writebatch_wi_delete_range_cf(
1533 rocksdb_writebatch_wi_t* b, rocksdb_column_family_handle_t* column_family,
1534 const char* start_key, size_t start_key_len, const char* end_key,
1535 size_t end_key_len) {
1536 b->rep->DeleteRange(column_family->rep, Slice(start_key, start_key_len),
1537 Slice(end_key, end_key_len));
1538 }
1539
1540 void rocksdb_writebatch_wi_delete_rangev(rocksdb_writebatch_wi_t* b, int num_keys,
1541 const char* const* start_keys_list,
1542 const size_t* start_keys_list_sizes,
1543 const char* const* end_keys_list,
1544 const size_t* end_keys_list_sizes) {
1545 std::vector<Slice> start_key_slices(num_keys);
1546 std::vector<Slice> end_key_slices(num_keys);
1547 for (int i = 0; i < num_keys; i++) {
1548 start_key_slices[i] = Slice(start_keys_list[i], start_keys_list_sizes[i]);
1549 end_key_slices[i] = Slice(end_keys_list[i], end_keys_list_sizes[i]);
1550 }
1551 b->rep->DeleteRange(SliceParts(start_key_slices.data(), num_keys),
1552 SliceParts(end_key_slices.data(), num_keys));
1553 }
1554
1555 void rocksdb_writebatch_wi_delete_rangev_cf(
1556 rocksdb_writebatch_wi_t* b, rocksdb_column_family_handle_t* column_family,
1557 int num_keys, const char* const* start_keys_list,
1558 const size_t* start_keys_list_sizes, const char* const* end_keys_list,
1559 const size_t* end_keys_list_sizes) {
1560 std::vector<Slice> start_key_slices(num_keys);
1561 std::vector<Slice> end_key_slices(num_keys);
1562 for (int i = 0; i < num_keys; i++) {
1563 start_key_slices[i] = Slice(start_keys_list[i], start_keys_list_sizes[i]);
1564 end_key_slices[i] = Slice(end_keys_list[i], end_keys_list_sizes[i]);
1565 }
1566 b->rep->DeleteRange(column_family->rep,
1567 SliceParts(start_key_slices.data(), num_keys),
1568 SliceParts(end_key_slices.data(), num_keys));
1569 }
1570
1571 void rocksdb_writebatch_wi_put_log_data(
1572 rocksdb_writebatch_wi_t* b,
1573 const char* blob, size_t len) {
1574 b->rep->PutLogData(Slice(blob, len));
1575 }
1576
1577 void rocksdb_writebatch_wi_iterate(
1578 rocksdb_writebatch_wi_t* b,
1579 void* state,
1580 void (*put)(void*, const char* k, size_t klen, const char* v, size_t vlen),
1581 void (*deleted)(void*, const char* k, size_t klen)) {
1582 class H : public WriteBatch::Handler {
1583 public:
1584 void* state_;
1585 void (*put_)(void*, const char* k, size_t klen, const char* v, size_t vlen);
1586 void (*deleted_)(void*, const char* k, size_t klen);
1587 virtual void Put(const Slice& key, const Slice& value) override {
1588 (*put_)(state_, key.data(), key.size(), value.data(), value.size());
1589 }
1590 virtual void Delete(const Slice& key) override {
1591 (*deleted_)(state_, key.data(), key.size());
1592 }
1593 };
1594 H handler;
1595 handler.state_ = state;
1596 handler.put_ = put;
1597 handler.deleted_ = deleted;
1598 b->rep->GetWriteBatch()->Iterate(&handler);
1599 }
1600
1601 const char* rocksdb_writebatch_wi_data(rocksdb_writebatch_wi_t* b, size_t* size) {
1602 WriteBatch* wb = b->rep->GetWriteBatch();
1603 *size = wb->GetDataSize();
1604 return wb->Data().c_str();
1605 }
1606
1607 void rocksdb_writebatch_wi_set_save_point(rocksdb_writebatch_wi_t* b) {
1608 b->rep->SetSavePoint();
1609 }
1610
1611 void rocksdb_writebatch_wi_rollback_to_save_point(rocksdb_writebatch_wi_t* b,
1612 char** errptr) {
1613 SaveError(errptr, b->rep->RollbackToSavePoint());
1614 }
1615
1616 rocksdb_iterator_t* rocksdb_writebatch_wi_create_iterator_with_base(
1617 rocksdb_writebatch_wi_t* wbwi,
1618 rocksdb_iterator_t* base_iterator) {
1619 rocksdb_iterator_t* result = new rocksdb_iterator_t;
1620 result->rep = wbwi->rep->NewIteratorWithBase(base_iterator->rep);
1621 delete base_iterator;
1622 return result;
1623 }
1624
1625 rocksdb_iterator_t* rocksdb_writebatch_wi_create_iterator_with_base_cf(
1626 rocksdb_writebatch_wi_t* wbwi,
1627 rocksdb_iterator_t* base_iterator,
1628 rocksdb_column_family_handle_t* column_family) {
1629 rocksdb_iterator_t* result = new rocksdb_iterator_t;
1630 result->rep = wbwi->rep->NewIteratorWithBase(column_family->rep, base_iterator->rep);
1631 delete base_iterator;
1632 return result;
1633 }
1634
1635 char* rocksdb_writebatch_wi_get_from_batch(
1636 rocksdb_writebatch_wi_t* wbwi,
1637 const rocksdb_options_t* options,
1638 const char* key, size_t keylen,
1639 size_t* vallen,
1640 char** errptr) {
1641 char* result = nullptr;
1642 std::string tmp;
1643 Status s = wbwi->rep->GetFromBatch(options->rep, Slice(key, keylen), &tmp);
1644 if (s.ok()) {
1645 *vallen = tmp.size();
1646 result = CopyString(tmp);
1647 } else {
1648 *vallen = 0;
1649 if (!s.IsNotFound()) {
1650 SaveError(errptr, s);
1651 }
1652 }
1653 return result;
1654 }
1655
1656 char* rocksdb_writebatch_wi_get_from_batch_cf(
1657 rocksdb_writebatch_wi_t* wbwi,
1658 const rocksdb_options_t* options,
1659 rocksdb_column_family_handle_t* column_family,
1660 const char* key, size_t keylen,
1661 size_t* vallen,
1662 char** errptr) {
1663 char* result = nullptr;
1664 std::string tmp;
1665 Status s = wbwi->rep->GetFromBatch(column_family->rep, options->rep,
1666 Slice(key, keylen), &tmp);
1667 if (s.ok()) {
1668 *vallen = tmp.size();
1669 result = CopyString(tmp);
1670 } else {
1671 *vallen = 0;
1672 if (!s.IsNotFound()) {
1673 SaveError(errptr, s);
1674 }
1675 }
1676 return result;
1677 }
1678
1679 char* rocksdb_writebatch_wi_get_from_batch_and_db(
1680 rocksdb_writebatch_wi_t* wbwi,
1681 rocksdb_t* db,
1682 const rocksdb_readoptions_t* options,
1683 const char* key, size_t keylen,
1684 size_t* vallen,
1685 char** errptr) {
1686 char* result = nullptr;
1687 std::string tmp;
1688 Status s = wbwi->rep->GetFromBatchAndDB(db->rep, options->rep, Slice(key, keylen), &tmp);
1689 if (s.ok()) {
1690 *vallen = tmp.size();
1691 result = CopyString(tmp);
1692 } else {
1693 *vallen = 0;
1694 if (!s.IsNotFound()) {
1695 SaveError(errptr, s);
1696 }
1697 }
1698 return result;
1699 }
1700
1701 char* rocksdb_writebatch_wi_get_from_batch_and_db_cf(
1702 rocksdb_writebatch_wi_t* wbwi,
1703 rocksdb_t* db,
1704 const rocksdb_readoptions_t* options,
1705 rocksdb_column_family_handle_t* column_family,
1706 const char* key, size_t keylen,
1707 size_t* vallen,
1708 char** errptr) {
1709 char* result = nullptr;
1710 std::string tmp;
1711 Status s = wbwi->rep->GetFromBatchAndDB(db->rep, options->rep, column_family->rep,
1712 Slice(key, keylen), &tmp);
1713 if (s.ok()) {
1714 *vallen = tmp.size();
1715 result = CopyString(tmp);
1716 } else {
1717 *vallen = 0;
1718 if (!s.IsNotFound()) {
1719 SaveError(errptr, s);
1720 }
1721 }
1722 return result;
1723 }
1724
1725 void rocksdb_write_writebatch_wi(
1726 rocksdb_t* db,
1727 const rocksdb_writeoptions_t* options,
1728 rocksdb_writebatch_wi_t* wbwi,
1729 char** errptr) {
1730 WriteBatch* wb = wbwi->rep->GetWriteBatch();
1731 SaveError(errptr, db->rep->Write(options->rep, wb));
1732 }
1733
1734 rocksdb_block_based_table_options_t*
1735 rocksdb_block_based_options_create() {
1736 return new rocksdb_block_based_table_options_t;
1737 }
1738
1739 void rocksdb_block_based_options_destroy(
1740 rocksdb_block_based_table_options_t* options) {
1741 delete options;
1742 }
1743
1744 void rocksdb_block_based_options_set_block_size(
1745 rocksdb_block_based_table_options_t* options, size_t block_size) {
1746 options->rep.block_size = block_size;
1747 }
1748
1749 void rocksdb_block_based_options_set_block_size_deviation(
1750 rocksdb_block_based_table_options_t* options, int block_size_deviation) {
1751 options->rep.block_size_deviation = block_size_deviation;
1752 }
1753
1754 void rocksdb_block_based_options_set_block_restart_interval(
1755 rocksdb_block_based_table_options_t* options, int block_restart_interval) {
1756 options->rep.block_restart_interval = block_restart_interval;
1757 }
1758
1759 void rocksdb_block_based_options_set_filter_policy(
1760 rocksdb_block_based_table_options_t* options,
1761 rocksdb_filterpolicy_t* filter_policy) {
1762 options->rep.filter_policy.reset(filter_policy);
1763 }
1764
1765 void rocksdb_block_based_options_set_no_block_cache(
1766 rocksdb_block_based_table_options_t* options,
1767 unsigned char no_block_cache) {
1768 options->rep.no_block_cache = no_block_cache;
1769 }
1770
1771 void rocksdb_block_based_options_set_block_cache(
1772 rocksdb_block_based_table_options_t* options,
1773 rocksdb_cache_t* block_cache) {
1774 if (block_cache) {
1775 options->rep.block_cache = block_cache->rep;
1776 }
1777 }
1778
1779 void rocksdb_block_based_options_set_block_cache_compressed(
1780 rocksdb_block_based_table_options_t* options,
1781 rocksdb_cache_t* block_cache_compressed) {
1782 if (block_cache_compressed) {
1783 options->rep.block_cache_compressed = block_cache_compressed->rep;
1784 }
1785 }
1786
1787 void rocksdb_block_based_options_set_whole_key_filtering(
1788 rocksdb_block_based_table_options_t* options, unsigned char v) {
1789 options->rep.whole_key_filtering = v;
1790 }
1791
1792 void rocksdb_block_based_options_set_format_version(
1793 rocksdb_block_based_table_options_t* options, int v) {
1794 options->rep.format_version = v;
1795 }
1796
1797 void rocksdb_block_based_options_set_index_type(
1798 rocksdb_block_based_table_options_t* options, int v) {
1799 options->rep.index_type = static_cast<BlockBasedTableOptions::IndexType>(v);
1800 }
1801
1802 void rocksdb_block_based_options_set_hash_index_allow_collision(
1803 rocksdb_block_based_table_options_t* options, unsigned char v) {
1804 options->rep.hash_index_allow_collision = v;
1805 }
1806
1807 void rocksdb_block_based_options_set_cache_index_and_filter_blocks(
1808 rocksdb_block_based_table_options_t* options, unsigned char v) {
1809 options->rep.cache_index_and_filter_blocks = v;
1810 }
1811
1812 void rocksdb_block_based_options_set_pin_l0_filter_and_index_blocks_in_cache(
1813 rocksdb_block_based_table_options_t* options, unsigned char v) {
1814 options->rep.pin_l0_filter_and_index_blocks_in_cache = v;
1815 }
1816
1817 void rocksdb_options_set_block_based_table_factory(
1818 rocksdb_options_t *opt,
1819 rocksdb_block_based_table_options_t* table_options) {
1820 if (table_options) {
1821 opt->rep.table_factory.reset(
1822 rocksdb::NewBlockBasedTableFactory(table_options->rep));
1823 }
1824 }
1825
1826
1827 rocksdb_cuckoo_table_options_t*
1828 rocksdb_cuckoo_options_create() {
1829 return new rocksdb_cuckoo_table_options_t;
1830 }
1831
1832 void rocksdb_cuckoo_options_destroy(
1833 rocksdb_cuckoo_table_options_t* options) {
1834 delete options;
1835 }
1836
1837 void rocksdb_cuckoo_options_set_hash_ratio(
1838 rocksdb_cuckoo_table_options_t* options, double v) {
1839 options->rep.hash_table_ratio = v;
1840 }
1841
1842 void rocksdb_cuckoo_options_set_max_search_depth(
1843 rocksdb_cuckoo_table_options_t* options, uint32_t v) {
1844 options->rep.max_search_depth = v;
1845 }
1846
1847 void rocksdb_cuckoo_options_set_cuckoo_block_size(
1848 rocksdb_cuckoo_table_options_t* options, uint32_t v) {
1849 options->rep.cuckoo_block_size = v;
1850 }
1851
1852 void rocksdb_cuckoo_options_set_identity_as_first_hash(
1853 rocksdb_cuckoo_table_options_t* options, unsigned char v) {
1854 options->rep.identity_as_first_hash = v;
1855 }
1856
1857 void rocksdb_cuckoo_options_set_use_module_hash(
1858 rocksdb_cuckoo_table_options_t* options, unsigned char v) {
1859 options->rep.use_module_hash = v;
1860 }
1861
1862 void rocksdb_options_set_cuckoo_table_factory(
1863 rocksdb_options_t *opt,
1864 rocksdb_cuckoo_table_options_t* table_options) {
1865 if (table_options) {
1866 opt->rep.table_factory.reset(
1867 rocksdb::NewCuckooTableFactory(table_options->rep));
1868 }
1869 }
1870
1871 void rocksdb_set_options(
1872 rocksdb_t* db, int count, const char* const keys[], const char* const values[], char** errptr) {
1873 std::unordered_map<std::string, std::string> options_map;
1874 for (int i=0; i<count; i++)
1875 options_map[keys[i]] = values[i];
1876 SaveError(errptr,
1877 db->rep->SetOptions(options_map));
1878 }
1879
1880 rocksdb_options_t* rocksdb_options_create() {
1881 return new rocksdb_options_t;
1882 }
1883
1884 void rocksdb_options_destroy(rocksdb_options_t* options) {
1885 delete options;
1886 }
1887
1888 void rocksdb_options_increase_parallelism(
1889 rocksdb_options_t* opt, int total_threads) {
1890 opt->rep.IncreaseParallelism(total_threads);
1891 }
1892
1893 void rocksdb_options_optimize_for_point_lookup(
1894 rocksdb_options_t* opt, uint64_t block_cache_size_mb) {
1895 opt->rep.OptimizeForPointLookup(block_cache_size_mb);
1896 }
1897
1898 void rocksdb_options_optimize_level_style_compaction(
1899 rocksdb_options_t* opt, uint64_t memtable_memory_budget) {
1900 opt->rep.OptimizeLevelStyleCompaction(memtable_memory_budget);
1901 }
1902
1903 void rocksdb_options_optimize_universal_style_compaction(
1904 rocksdb_options_t* opt, uint64_t memtable_memory_budget) {
1905 opt->rep.OptimizeUniversalStyleCompaction(memtable_memory_budget);
1906 }
1907
1908 void rocksdb_options_set_compaction_filter(
1909 rocksdb_options_t* opt,
1910 rocksdb_compactionfilter_t* filter) {
1911 opt->rep.compaction_filter = filter;
1912 }
1913
1914 void rocksdb_options_set_compaction_filter_factory(
1915 rocksdb_options_t* opt, rocksdb_compactionfilterfactory_t* factory) {
1916 opt->rep.compaction_filter_factory =
1917 std::shared_ptr<CompactionFilterFactory>(factory);
1918 }
1919
1920 void rocksdb_options_compaction_readahead_size(
1921 rocksdb_options_t* opt, size_t s) {
1922 opt->rep.compaction_readahead_size = s;
1923 }
1924
1925 void rocksdb_options_set_comparator(
1926 rocksdb_options_t* opt,
1927 rocksdb_comparator_t* cmp) {
1928 opt->rep.comparator = cmp;
1929 }
1930
1931 void rocksdb_options_set_merge_operator(
1932 rocksdb_options_t* opt,
1933 rocksdb_mergeoperator_t* merge_operator) {
1934 opt->rep.merge_operator = std::shared_ptr<MergeOperator>(merge_operator);
1935 }
1936
1937
1938 void rocksdb_options_set_create_if_missing(
1939 rocksdb_options_t* opt, unsigned char v) {
1940 opt->rep.create_if_missing = v;
1941 }
1942
1943 void rocksdb_options_set_create_missing_column_families(
1944 rocksdb_options_t* opt, unsigned char v) {
1945 opt->rep.create_missing_column_families = v;
1946 }
1947
1948 void rocksdb_options_set_error_if_exists(
1949 rocksdb_options_t* opt, unsigned char v) {
1950 opt->rep.error_if_exists = v;
1951 }
1952
1953 void rocksdb_options_set_paranoid_checks(
1954 rocksdb_options_t* opt, unsigned char v) {
1955 opt->rep.paranoid_checks = v;
1956 }
1957
1958 void rocksdb_options_set_env(rocksdb_options_t* opt, rocksdb_env_t* env) {
1959 opt->rep.env = (env ? env->rep : nullptr);
1960 }
1961
1962 void rocksdb_options_set_info_log(rocksdb_options_t* opt, rocksdb_logger_t* l) {
1963 if (l) {
1964 opt->rep.info_log = l->rep;
1965 }
1966 }
1967
1968 void rocksdb_options_set_info_log_level(
1969 rocksdb_options_t* opt, int v) {
1970 opt->rep.info_log_level = static_cast<InfoLogLevel>(v);
1971 }
1972
1973 void rocksdb_options_set_db_write_buffer_size(rocksdb_options_t* opt,
1974 size_t s) {
1975 opt->rep.db_write_buffer_size = s;
1976 }
1977
1978 void rocksdb_options_set_write_buffer_size(rocksdb_options_t* opt, size_t s) {
1979 opt->rep.write_buffer_size = s;
1980 }
1981
1982 void rocksdb_options_set_max_open_files(rocksdb_options_t* opt, int n) {
1983 opt->rep.max_open_files = n;
1984 }
1985
1986 void rocksdb_options_set_max_total_wal_size(rocksdb_options_t* opt, uint64_t n) {
1987 opt->rep.max_total_wal_size = n;
1988 }
1989
1990 void rocksdb_options_set_target_file_size_base(
1991 rocksdb_options_t* opt, uint64_t n) {
1992 opt->rep.target_file_size_base = n;
1993 }
1994
1995 void rocksdb_options_set_target_file_size_multiplier(
1996 rocksdb_options_t* opt, int n) {
1997 opt->rep.target_file_size_multiplier = n;
1998 }
1999
2000 void rocksdb_options_set_max_bytes_for_level_base(
2001 rocksdb_options_t* opt, uint64_t n) {
2002 opt->rep.max_bytes_for_level_base = n;
2003 }
2004
2005 void rocksdb_options_set_level_compaction_dynamic_level_bytes(
2006 rocksdb_options_t* opt, unsigned char v) {
2007 opt->rep.level_compaction_dynamic_level_bytes = v;
2008 }
2009
2010 void rocksdb_options_set_max_bytes_for_level_multiplier(rocksdb_options_t* opt,
2011 double n) {
2012 opt->rep.max_bytes_for_level_multiplier = n;
2013 }
2014
2015 void rocksdb_options_set_max_compaction_bytes(rocksdb_options_t* opt,
2016 uint64_t n) {
2017 opt->rep.max_compaction_bytes = n;
2018 }
2019
2020 void rocksdb_options_set_max_bytes_for_level_multiplier_additional(
2021 rocksdb_options_t* opt, int* level_values, size_t num_levels) {
2022 opt->rep.max_bytes_for_level_multiplier_additional.resize(num_levels);
2023 for (size_t i = 0; i < num_levels; ++i) {
2024 opt->rep.max_bytes_for_level_multiplier_additional[i] = level_values[i];
2025 }
2026 }
2027
2028 void rocksdb_options_enable_statistics(rocksdb_options_t* opt) {
2029 opt->rep.statistics = rocksdb::CreateDBStatistics();
2030 }
2031
2032 void rocksdb_options_set_num_levels(rocksdb_options_t* opt, int n) {
2033 opt->rep.num_levels = n;
2034 }
2035
2036 void rocksdb_options_set_level0_file_num_compaction_trigger(
2037 rocksdb_options_t* opt, int n) {
2038 opt->rep.level0_file_num_compaction_trigger = n;
2039 }
2040
2041 void rocksdb_options_set_level0_slowdown_writes_trigger(
2042 rocksdb_options_t* opt, int n) {
2043 opt->rep.level0_slowdown_writes_trigger = n;
2044 }
2045
2046 void rocksdb_options_set_level0_stop_writes_trigger(
2047 rocksdb_options_t* opt, int n) {
2048 opt->rep.level0_stop_writes_trigger = n;
2049 }
2050
2051 void rocksdb_options_set_max_mem_compaction_level(rocksdb_options_t* opt,
2052 int n) {}
2053
2054 void rocksdb_options_set_wal_recovery_mode(rocksdb_options_t* opt,int mode) {
2055 opt->rep.wal_recovery_mode = static_cast<WALRecoveryMode>(mode);
2056 }
2057
2058 void rocksdb_options_set_compression(rocksdb_options_t* opt, int t) {
2059 opt->rep.compression = static_cast<CompressionType>(t);
2060 }
2061
2062 void rocksdb_options_set_compression_per_level(rocksdb_options_t* opt,
2063 int* level_values,
2064 size_t num_levels) {
2065 opt->rep.compression_per_level.resize(num_levels);
2066 for (size_t i = 0; i < num_levels; ++i) {
2067 opt->rep.compression_per_level[i] =
2068 static_cast<CompressionType>(level_values[i]);
2069 }
2070 }
2071
2072 void rocksdb_options_set_compression_options(rocksdb_options_t* opt, int w_bits,
2073 int level, int strategy,
2074 int max_dict_bytes) {
2075 opt->rep.compression_opts.window_bits = w_bits;
2076 opt->rep.compression_opts.level = level;
2077 opt->rep.compression_opts.strategy = strategy;
2078 opt->rep.compression_opts.max_dict_bytes = max_dict_bytes;
2079 }
2080
2081 void rocksdb_options_set_prefix_extractor(
2082 rocksdb_options_t* opt, rocksdb_slicetransform_t* prefix_extractor) {
2083 opt->rep.prefix_extractor.reset(prefix_extractor);
2084 }
2085
2086 void rocksdb_options_set_use_fsync(
2087 rocksdb_options_t* opt, int use_fsync) {
2088 opt->rep.use_fsync = use_fsync;
2089 }
2090
2091 void rocksdb_options_set_db_log_dir(
2092 rocksdb_options_t* opt, const char* db_log_dir) {
2093 opt->rep.db_log_dir = db_log_dir;
2094 }
2095
2096 void rocksdb_options_set_wal_dir(
2097 rocksdb_options_t* opt, const char* v) {
2098 opt->rep.wal_dir = v;
2099 }
2100
2101 void rocksdb_options_set_WAL_ttl_seconds(rocksdb_options_t* opt, uint64_t ttl) {
2102 opt->rep.WAL_ttl_seconds = ttl;
2103 }
2104
2105 void rocksdb_options_set_WAL_size_limit_MB(
2106 rocksdb_options_t* opt, uint64_t limit) {
2107 opt->rep.WAL_size_limit_MB = limit;
2108 }
2109
2110 void rocksdb_options_set_manifest_preallocation_size(
2111 rocksdb_options_t* opt, size_t v) {
2112 opt->rep.manifest_preallocation_size = v;
2113 }
2114
2115 // noop
2116 void rocksdb_options_set_purge_redundant_kvs_while_flush(rocksdb_options_t* opt,
2117 unsigned char v) {}
2118
2119 void rocksdb_options_set_use_direct_reads(rocksdb_options_t* opt,
2120 unsigned char v) {
2121 opt->rep.use_direct_reads = v;
2122 }
2123
2124 void rocksdb_options_set_use_direct_io_for_flush_and_compaction(
2125 rocksdb_options_t* opt, unsigned char v) {
2126 opt->rep.use_direct_io_for_flush_and_compaction = v;
2127 }
2128
2129 void rocksdb_options_set_allow_mmap_reads(
2130 rocksdb_options_t* opt, unsigned char v) {
2131 opt->rep.allow_mmap_reads = v;
2132 }
2133
2134 void rocksdb_options_set_allow_mmap_writes(
2135 rocksdb_options_t* opt, unsigned char v) {
2136 opt->rep.allow_mmap_writes = v;
2137 }
2138
2139 void rocksdb_options_set_is_fd_close_on_exec(
2140 rocksdb_options_t* opt, unsigned char v) {
2141 opt->rep.is_fd_close_on_exec = v;
2142 }
2143
2144 void rocksdb_options_set_skip_log_error_on_recovery(
2145 rocksdb_options_t* opt, unsigned char v) {
2146 opt->rep.skip_log_error_on_recovery = v;
2147 }
2148
2149 void rocksdb_options_set_stats_dump_period_sec(
2150 rocksdb_options_t* opt, unsigned int v) {
2151 opt->rep.stats_dump_period_sec = v;
2152 }
2153
2154 void rocksdb_options_set_advise_random_on_open(
2155 rocksdb_options_t* opt, unsigned char v) {
2156 opt->rep.advise_random_on_open = v;
2157 }
2158
2159 void rocksdb_options_set_access_hint_on_compaction_start(
2160 rocksdb_options_t* opt, int v) {
2161 switch(v) {
2162 case 0:
2163 opt->rep.access_hint_on_compaction_start = rocksdb::Options::NONE;
2164 break;
2165 case 1:
2166 opt->rep.access_hint_on_compaction_start = rocksdb::Options::NORMAL;
2167 break;
2168 case 2:
2169 opt->rep.access_hint_on_compaction_start = rocksdb::Options::SEQUENTIAL;
2170 break;
2171 case 3:
2172 opt->rep.access_hint_on_compaction_start = rocksdb::Options::WILLNEED;
2173 break;
2174 }
2175 }
2176
2177 void rocksdb_options_set_use_adaptive_mutex(
2178 rocksdb_options_t* opt, unsigned char v) {
2179 opt->rep.use_adaptive_mutex = v;
2180 }
2181
2182 void rocksdb_options_set_bytes_per_sync(
2183 rocksdb_options_t* opt, uint64_t v) {
2184 opt->rep.bytes_per_sync = v;
2185 }
2186
2187 void rocksdb_options_set_allow_concurrent_memtable_write(rocksdb_options_t* opt,
2188 unsigned char v) {
2189 opt->rep.allow_concurrent_memtable_write = v;
2190 }
2191
2192 void rocksdb_options_set_enable_write_thread_adaptive_yield(
2193 rocksdb_options_t* opt, unsigned char v) {
2194 opt->rep.enable_write_thread_adaptive_yield = v;
2195 }
2196
2197 void rocksdb_options_set_max_sequential_skip_in_iterations(
2198 rocksdb_options_t* opt, uint64_t v) {
2199 opt->rep.max_sequential_skip_in_iterations = v;
2200 }
2201
2202 void rocksdb_options_set_max_write_buffer_number(rocksdb_options_t* opt, int n) {
2203 opt->rep.max_write_buffer_number = n;
2204 }
2205
2206 void rocksdb_options_set_min_write_buffer_number_to_merge(rocksdb_options_t* opt, int n) {
2207 opt->rep.min_write_buffer_number_to_merge = n;
2208 }
2209
2210 void rocksdb_options_set_max_write_buffer_number_to_maintain(
2211 rocksdb_options_t* opt, int n) {
2212 opt->rep.max_write_buffer_number_to_maintain = n;
2213 }
2214
2215 void rocksdb_options_set_max_background_compactions(rocksdb_options_t* opt, int n) {
2216 opt->rep.max_background_compactions = n;
2217 }
2218
2219 void rocksdb_options_set_base_background_compactions(rocksdb_options_t* opt,
2220 int n) {
2221 opt->rep.base_background_compactions = n;
2222 }
2223
2224 void rocksdb_options_set_max_background_flushes(rocksdb_options_t* opt, int n) {
2225 opt->rep.max_background_flushes = n;
2226 }
2227
2228 void rocksdb_options_set_max_log_file_size(rocksdb_options_t* opt, size_t v) {
2229 opt->rep.max_log_file_size = v;
2230 }
2231
2232 void rocksdb_options_set_log_file_time_to_roll(rocksdb_options_t* opt, size_t v) {
2233 opt->rep.log_file_time_to_roll = v;
2234 }
2235
2236 void rocksdb_options_set_keep_log_file_num(rocksdb_options_t* opt, size_t v) {
2237 opt->rep.keep_log_file_num = v;
2238 }
2239
2240 void rocksdb_options_set_recycle_log_file_num(rocksdb_options_t* opt,
2241 size_t v) {
2242 opt->rep.recycle_log_file_num = v;
2243 }
2244
2245 void rocksdb_options_set_soft_rate_limit(rocksdb_options_t* opt, double v) {
2246 opt->rep.soft_rate_limit = v;
2247 }
2248
2249 void rocksdb_options_set_hard_rate_limit(rocksdb_options_t* opt, double v) {
2250 opt->rep.hard_rate_limit = v;
2251 }
2252
2253 void rocksdb_options_set_soft_pending_compaction_bytes_limit(rocksdb_options_t* opt, size_t v) {
2254 opt->rep.soft_pending_compaction_bytes_limit = v;
2255 }
2256
2257 void rocksdb_options_set_hard_pending_compaction_bytes_limit(rocksdb_options_t* opt, size_t v) {
2258 opt->rep.hard_pending_compaction_bytes_limit = v;
2259 }
2260
2261 void rocksdb_options_set_rate_limit_delay_max_milliseconds(
2262 rocksdb_options_t* opt, unsigned int v) {
2263 opt->rep.rate_limit_delay_max_milliseconds = v;
2264 }
2265
2266 void rocksdb_options_set_max_manifest_file_size(
2267 rocksdb_options_t* opt, size_t v) {
2268 opt->rep.max_manifest_file_size = v;
2269 }
2270
2271 void rocksdb_options_set_table_cache_numshardbits(
2272 rocksdb_options_t* opt, int v) {
2273 opt->rep.table_cache_numshardbits = v;
2274 }
2275
2276 void rocksdb_options_set_table_cache_remove_scan_count_limit(
2277 rocksdb_options_t* opt, int v) {
2278 // this option is deprecated
2279 }
2280
2281 void rocksdb_options_set_arena_block_size(
2282 rocksdb_options_t* opt, size_t v) {
2283 opt->rep.arena_block_size = v;
2284 }
2285
2286 void rocksdb_options_set_disable_auto_compactions(rocksdb_options_t* opt, int disable) {
2287 opt->rep.disable_auto_compactions = disable;
2288 }
2289
2290 void rocksdb_options_set_optimize_filters_for_hits(rocksdb_options_t* opt, int v) {
2291 opt->rep.optimize_filters_for_hits = v;
2292 }
2293
2294 void rocksdb_options_set_delete_obsolete_files_period_micros(
2295 rocksdb_options_t* opt, uint64_t v) {
2296 opt->rep.delete_obsolete_files_period_micros = v;
2297 }
2298
2299 void rocksdb_options_prepare_for_bulk_load(rocksdb_options_t* opt) {
2300 opt->rep.PrepareForBulkLoad();
2301 }
2302
2303 void rocksdb_options_set_memtable_vector_rep(rocksdb_options_t *opt) {
2304 opt->rep.memtable_factory.reset(new rocksdb::VectorRepFactory);
2305 }
2306
2307 void rocksdb_options_set_memtable_prefix_bloom_size_ratio(
2308 rocksdb_options_t* opt, double v) {
2309 opt->rep.memtable_prefix_bloom_size_ratio = v;
2310 }
2311
2312 void rocksdb_options_set_memtable_huge_page_size(rocksdb_options_t* opt,
2313 size_t v) {
2314 opt->rep.memtable_huge_page_size = v;
2315 }
2316
2317 void rocksdb_options_set_hash_skip_list_rep(
2318 rocksdb_options_t *opt, size_t bucket_count,
2319 int32_t skiplist_height, int32_t skiplist_branching_factor) {
2320 rocksdb::MemTableRepFactory* factory = rocksdb::NewHashSkipListRepFactory(
2321 bucket_count, skiplist_height, skiplist_branching_factor);
2322 opt->rep.memtable_factory.reset(factory);
2323 }
2324
2325 void rocksdb_options_set_hash_link_list_rep(
2326 rocksdb_options_t *opt, size_t bucket_count) {
2327 opt->rep.memtable_factory.reset(rocksdb::NewHashLinkListRepFactory(bucket_count));
2328 }
2329
2330 void rocksdb_options_set_plain_table_factory(
2331 rocksdb_options_t *opt, uint32_t user_key_len, int bloom_bits_per_key,
2332 double hash_table_ratio, size_t index_sparseness) {
2333 rocksdb::PlainTableOptions options;
2334 options.user_key_len = user_key_len;
2335 options.bloom_bits_per_key = bloom_bits_per_key;
2336 options.hash_table_ratio = hash_table_ratio;
2337 options.index_sparseness = index_sparseness;
2338
2339 rocksdb::TableFactory* factory = rocksdb::NewPlainTableFactory(options);
2340 opt->rep.table_factory.reset(factory);
2341 }
2342
2343 void rocksdb_options_set_max_successive_merges(
2344 rocksdb_options_t* opt, size_t v) {
2345 opt->rep.max_successive_merges = v;
2346 }
2347
2348 void rocksdb_options_set_bloom_locality(
2349 rocksdb_options_t* opt, uint32_t v) {
2350 opt->rep.bloom_locality = v;
2351 }
2352
2353 void rocksdb_options_set_inplace_update_support(
2354 rocksdb_options_t* opt, unsigned char v) {
2355 opt->rep.inplace_update_support = v;
2356 }
2357
2358 void rocksdb_options_set_inplace_update_num_locks(
2359 rocksdb_options_t* opt, size_t v) {
2360 opt->rep.inplace_update_num_locks = v;
2361 }
2362
2363 void rocksdb_options_set_report_bg_io_stats(
2364 rocksdb_options_t* opt, int v) {
2365 opt->rep.report_bg_io_stats = v;
2366 }
2367
2368 void rocksdb_options_set_compaction_style(rocksdb_options_t *opt, int style) {
2369 opt->rep.compaction_style = static_cast<rocksdb::CompactionStyle>(style);
2370 }
2371
2372 void rocksdb_options_set_universal_compaction_options(rocksdb_options_t *opt, rocksdb_universal_compaction_options_t *uco) {
2373 opt->rep.compaction_options_universal = *(uco->rep);
2374 }
2375
2376 void rocksdb_options_set_fifo_compaction_options(
2377 rocksdb_options_t* opt,
2378 rocksdb_fifo_compaction_options_t* fifo) {
2379 opt->rep.compaction_options_fifo = fifo->rep;
2380 }
2381
2382 char *rocksdb_options_statistics_get_string(rocksdb_options_t *opt) {
2383 rocksdb::Statistics *statistics = opt->rep.statistics.get();
2384 if (statistics) {
2385 return strdup(statistics->ToString().c_str());
2386 }
2387 return nullptr;
2388 }
2389
2390 void rocksdb_options_set_ratelimiter(rocksdb_options_t *opt, rocksdb_ratelimiter_t *limiter) {
2391 opt->rep.rate_limiter.reset(limiter->rep);
2392 limiter->rep = nullptr;
2393 }
2394
2395 rocksdb_ratelimiter_t* rocksdb_ratelimiter_create(
2396 int64_t rate_bytes_per_sec,
2397 int64_t refill_period_us,
2398 int32_t fairness) {
2399 rocksdb_ratelimiter_t* rate_limiter = new rocksdb_ratelimiter_t;
2400 rate_limiter->rep = NewGenericRateLimiter(rate_bytes_per_sec,
2401 refill_period_us, fairness);
2402 return rate_limiter;
2403 }
2404
2405 void rocksdb_ratelimiter_destroy(rocksdb_ratelimiter_t *limiter) {
2406 if (limiter->rep) {
2407 delete limiter->rep;
2408 }
2409 delete limiter;
2410 }
2411
2412 /*
2413 TODO:
2414 DB::OpenForReadOnly
2415 DB::KeyMayExist
2416 DB::GetOptions
2417 DB::GetSortedWalFiles
2418 DB::GetLatestSequenceNumber
2419 DB::GetUpdatesSince
2420 DB::GetDbIdentity
2421 DB::RunManualCompaction
2422 custom cache
2423 table_properties_collectors
2424 */
2425
2426 rocksdb_compactionfilter_t* rocksdb_compactionfilter_create(
2427 void* state,
2428 void (*destructor)(void*),
2429 unsigned char (*filter)(
2430 void*,
2431 int level,
2432 const char* key, size_t key_length,
2433 const char* existing_value, size_t value_length,
2434 char** new_value, size_t *new_value_length,
2435 unsigned char* value_changed),
2436 const char* (*name)(void*)) {
2437 rocksdb_compactionfilter_t* result = new rocksdb_compactionfilter_t;
2438 result->state_ = state;
2439 result->destructor_ = destructor;
2440 result->filter_ = filter;
2441 result->ignore_snapshots_ = false;
2442 result->name_ = name;
2443 return result;
2444 }
2445
2446 void rocksdb_compactionfilter_set_ignore_snapshots(
2447 rocksdb_compactionfilter_t* filter,
2448 unsigned char whether_ignore) {
2449 filter->ignore_snapshots_ = whether_ignore;
2450 }
2451
2452 void rocksdb_compactionfilter_destroy(rocksdb_compactionfilter_t* filter) {
2453 delete filter;
2454 }
2455
2456 unsigned char rocksdb_compactionfiltercontext_is_full_compaction(
2457 rocksdb_compactionfiltercontext_t* context) {
2458 return context->rep.is_full_compaction;
2459 }
2460
2461 unsigned char rocksdb_compactionfiltercontext_is_manual_compaction(
2462 rocksdb_compactionfiltercontext_t* context) {
2463 return context->rep.is_manual_compaction;
2464 }
2465
2466 rocksdb_compactionfilterfactory_t* rocksdb_compactionfilterfactory_create(
2467 void* state, void (*destructor)(void*),
2468 rocksdb_compactionfilter_t* (*create_compaction_filter)(
2469 void*, rocksdb_compactionfiltercontext_t* context),
2470 const char* (*name)(void*)) {
2471 rocksdb_compactionfilterfactory_t* result =
2472 new rocksdb_compactionfilterfactory_t;
2473 result->state_ = state;
2474 result->destructor_ = destructor;
2475 result->create_compaction_filter_ = create_compaction_filter;
2476 result->name_ = name;
2477 return result;
2478 }
2479
2480 void rocksdb_compactionfilterfactory_destroy(
2481 rocksdb_compactionfilterfactory_t* factory) {
2482 delete factory;
2483 }
2484
2485 rocksdb_comparator_t* rocksdb_comparator_create(
2486 void* state,
2487 void (*destructor)(void*),
2488 int (*compare)(
2489 void*,
2490 const char* a, size_t alen,
2491 const char* b, size_t blen),
2492 const char* (*name)(void*)) {
2493 rocksdb_comparator_t* result = new rocksdb_comparator_t;
2494 result->state_ = state;
2495 result->destructor_ = destructor;
2496 result->compare_ = compare;
2497 result->name_ = name;
2498 return result;
2499 }
2500
2501 void rocksdb_comparator_destroy(rocksdb_comparator_t* cmp) {
2502 delete cmp;
2503 }
2504
2505 rocksdb_filterpolicy_t* rocksdb_filterpolicy_create(
2506 void* state,
2507 void (*destructor)(void*),
2508 char* (*create_filter)(
2509 void*,
2510 const char* const* key_array, const size_t* key_length_array,
2511 int num_keys,
2512 size_t* filter_length),
2513 unsigned char (*key_may_match)(
2514 void*,
2515 const char* key, size_t length,
2516 const char* filter, size_t filter_length),
2517 void (*delete_filter)(
2518 void*,
2519 const char* filter, size_t filter_length),
2520 const char* (*name)(void*)) {
2521 rocksdb_filterpolicy_t* result = new rocksdb_filterpolicy_t;
2522 result->state_ = state;
2523 result->destructor_ = destructor;
2524 result->create_ = create_filter;
2525 result->key_match_ = key_may_match;
2526 result->delete_filter_ = delete_filter;
2527 result->name_ = name;
2528 return result;
2529 }
2530
2531 void rocksdb_filterpolicy_destroy(rocksdb_filterpolicy_t* filter) {
2532 delete filter;
2533 }
2534
2535 rocksdb_filterpolicy_t* rocksdb_filterpolicy_create_bloom_format(int bits_per_key, bool original_format) {
2536 // Make a rocksdb_filterpolicy_t, but override all of its methods so
2537 // they delegate to a NewBloomFilterPolicy() instead of user
2538 // supplied C functions.
2539 struct Wrapper : public rocksdb_filterpolicy_t {
2540 const FilterPolicy* rep_;
2541 ~Wrapper() { delete rep_; }
2542 const char* Name() const override { return rep_->Name(); }
2543 void CreateFilter(const Slice* keys, int n,
2544 std::string* dst) const override {
2545 return rep_->CreateFilter(keys, n, dst);
2546 }
2547 bool KeyMayMatch(const Slice& key, const Slice& filter) const override {
2548 return rep_->KeyMayMatch(key, filter);
2549 }
2550 static void DoNothing(void*) { }
2551 };
2552 Wrapper* wrapper = new Wrapper;
2553 wrapper->rep_ = NewBloomFilterPolicy(bits_per_key, original_format);
2554 wrapper->state_ = nullptr;
2555 wrapper->delete_filter_ = nullptr;
2556 wrapper->destructor_ = &Wrapper::DoNothing;
2557 return wrapper;
2558 }
2559
2560 rocksdb_filterpolicy_t* rocksdb_filterpolicy_create_bloom_full(int bits_per_key) {
2561 return rocksdb_filterpolicy_create_bloom_format(bits_per_key, false);
2562 }
2563
2564 rocksdb_filterpolicy_t* rocksdb_filterpolicy_create_bloom(int bits_per_key) {
2565 return rocksdb_filterpolicy_create_bloom_format(bits_per_key, true);
2566 }
2567
2568 rocksdb_mergeoperator_t* rocksdb_mergeoperator_create(
2569 void* state, void (*destructor)(void*),
2570 char* (*full_merge)(void*, const char* key, size_t key_length,
2571 const char* existing_value,
2572 size_t existing_value_length,
2573 const char* const* operands_list,
2574 const size_t* operands_list_length, int num_operands,
2575 unsigned char* success, size_t* new_value_length),
2576 char* (*partial_merge)(void*, const char* key, size_t key_length,
2577 const char* const* operands_list,
2578 const size_t* operands_list_length, int num_operands,
2579 unsigned char* success, size_t* new_value_length),
2580 void (*delete_value)(void*, const char* value, size_t value_length),
2581 const char* (*name)(void*)) {
2582 rocksdb_mergeoperator_t* result = new rocksdb_mergeoperator_t;
2583 result->state_ = state;
2584 result->destructor_ = destructor;
2585 result->full_merge_ = full_merge;
2586 result->partial_merge_ = partial_merge;
2587 result->delete_value_ = delete_value;
2588 result->name_ = name;
2589 return result;
2590 }
2591
2592 void rocksdb_mergeoperator_destroy(rocksdb_mergeoperator_t* merge_operator) {
2593 delete merge_operator;
2594 }
2595
2596 rocksdb_readoptions_t* rocksdb_readoptions_create() {
2597 return new rocksdb_readoptions_t;
2598 }
2599
2600 void rocksdb_readoptions_destroy(rocksdb_readoptions_t* opt) {
2601 delete opt;
2602 }
2603
2604 void rocksdb_readoptions_set_verify_checksums(
2605 rocksdb_readoptions_t* opt,
2606 unsigned char v) {
2607 opt->rep.verify_checksums = v;
2608 }
2609
2610 void rocksdb_readoptions_set_fill_cache(
2611 rocksdb_readoptions_t* opt, unsigned char v) {
2612 opt->rep.fill_cache = v;
2613 }
2614
2615 void rocksdb_readoptions_set_snapshot(
2616 rocksdb_readoptions_t* opt,
2617 const rocksdb_snapshot_t* snap) {
2618 opt->rep.snapshot = (snap ? snap->rep : nullptr);
2619 }
2620
2621 void rocksdb_readoptions_set_iterate_upper_bound(
2622 rocksdb_readoptions_t* opt,
2623 const char* key, size_t keylen) {
2624 if (key == nullptr) {
2625 opt->upper_bound = Slice();
2626 opt->rep.iterate_upper_bound = nullptr;
2627
2628 } else {
2629 opt->upper_bound = Slice(key, keylen);
2630 opt->rep.iterate_upper_bound = &opt->upper_bound;
2631 }
2632 }
2633
2634 void rocksdb_readoptions_set_read_tier(
2635 rocksdb_readoptions_t* opt, int v) {
2636 opt->rep.read_tier = static_cast<rocksdb::ReadTier>(v);
2637 }
2638
2639 void rocksdb_readoptions_set_tailing(
2640 rocksdb_readoptions_t* opt, unsigned char v) {
2641 opt->rep.tailing = v;
2642 }
2643
2644 void rocksdb_readoptions_set_readahead_size(
2645 rocksdb_readoptions_t* opt, size_t v) {
2646 opt->rep.readahead_size = v;
2647 }
2648
2649 void rocksdb_readoptions_set_pin_data(rocksdb_readoptions_t* opt,
2650 unsigned char v) {
2651 opt->rep.pin_data = v;
2652 }
2653
2654 void rocksdb_readoptions_set_total_order_seek(rocksdb_readoptions_t* opt,
2655 unsigned char v) {
2656 opt->rep.total_order_seek = v;
2657 }
2658
2659 rocksdb_writeoptions_t* rocksdb_writeoptions_create() {
2660 return new rocksdb_writeoptions_t;
2661 }
2662
2663 void rocksdb_writeoptions_destroy(rocksdb_writeoptions_t* opt) {
2664 delete opt;
2665 }
2666
2667 void rocksdb_writeoptions_set_sync(
2668 rocksdb_writeoptions_t* opt, unsigned char v) {
2669 opt->rep.sync = v;
2670 }
2671
2672 void rocksdb_writeoptions_disable_WAL(rocksdb_writeoptions_t* opt, int disable) {
2673 opt->rep.disableWAL = disable;
2674 }
2675
2676 rocksdb_compactoptions_t* rocksdb_compactoptions_create() {
2677 return new rocksdb_compactoptions_t;
2678 }
2679
2680 void rocksdb_compactoptions_destroy(rocksdb_compactoptions_t* opt) {
2681 delete opt;
2682 }
2683
2684 void rocksdb_compactoptions_set_exclusive_manual_compaction(
2685 rocksdb_compactoptions_t* opt, unsigned char v) {
2686 opt->rep.exclusive_manual_compaction = v;
2687 }
2688
2689 void rocksdb_compactoptions_set_change_level(rocksdb_compactoptions_t* opt,
2690 unsigned char v) {
2691 opt->rep.change_level = v;
2692 }
2693
2694 void rocksdb_compactoptions_set_target_level(rocksdb_compactoptions_t* opt,
2695 int n) {
2696 opt->rep.target_level = n;
2697 }
2698
2699 rocksdb_flushoptions_t* rocksdb_flushoptions_create() {
2700 return new rocksdb_flushoptions_t;
2701 }
2702
2703 void rocksdb_flushoptions_destroy(rocksdb_flushoptions_t* opt) {
2704 delete opt;
2705 }
2706
2707 void rocksdb_flushoptions_set_wait(
2708 rocksdb_flushoptions_t* opt, unsigned char v) {
2709 opt->rep.wait = v;
2710 }
2711
2712 rocksdb_cache_t* rocksdb_cache_create_lru(size_t capacity) {
2713 rocksdb_cache_t* c = new rocksdb_cache_t;
2714 c->rep = NewLRUCache(capacity);
2715 return c;
2716 }
2717
2718 void rocksdb_cache_destroy(rocksdb_cache_t* cache) {
2719 delete cache;
2720 }
2721
2722 void rocksdb_cache_set_capacity(rocksdb_cache_t* cache, size_t capacity) {
2723 cache->rep->SetCapacity(capacity);
2724 }
2725
2726 size_t rocksdb_cache_get_usage(rocksdb_cache_t* cache) {
2727 return cache->rep->GetUsage();
2728 }
2729
2730 size_t rocksdb_cache_get_pinned_usage(rocksdb_cache_t* cache) {
2731 return cache->rep->GetPinnedUsage();
2732 }
2733
2734 rocksdb_env_t* rocksdb_create_default_env() {
2735 rocksdb_env_t* result = new rocksdb_env_t;
2736 result->rep = Env::Default();
2737 result->is_default = true;
2738 return result;
2739 }
2740
2741 rocksdb_env_t* rocksdb_create_mem_env() {
2742 rocksdb_env_t* result = new rocksdb_env_t;
2743 result->rep = rocksdb::NewMemEnv(Env::Default());
2744 result->is_default = false;
2745 return result;
2746 }
2747
2748 void rocksdb_env_set_background_threads(rocksdb_env_t* env, int n) {
2749 env->rep->SetBackgroundThreads(n);
2750 }
2751
2752 void rocksdb_env_set_high_priority_background_threads(rocksdb_env_t* env, int n) {
2753 env->rep->SetBackgroundThreads(n, Env::HIGH);
2754 }
2755
2756 void rocksdb_env_join_all_threads(rocksdb_env_t* env) {
2757 env->rep->WaitForJoin();
2758 }
2759
2760 void rocksdb_env_destroy(rocksdb_env_t* env) {
2761 if (!env->is_default) delete env->rep;
2762 delete env;
2763 }
2764
2765 rocksdb_envoptions_t* rocksdb_envoptions_create() {
2766 rocksdb_envoptions_t* opt = new rocksdb_envoptions_t;
2767 return opt;
2768 }
2769
2770 void rocksdb_envoptions_destroy(rocksdb_envoptions_t* opt) { delete opt; }
2771
2772 rocksdb_sstfilewriter_t* rocksdb_sstfilewriter_create(
2773 const rocksdb_envoptions_t* env, const rocksdb_options_t* io_options) {
2774 rocksdb_sstfilewriter_t* writer = new rocksdb_sstfilewriter_t;
2775 writer->rep = new SstFileWriter(env->rep, io_options->rep);
2776 return writer;
2777 }
2778
2779 rocksdb_sstfilewriter_t* rocksdb_sstfilewriter_create_with_comparator(
2780 const rocksdb_envoptions_t* env, const rocksdb_options_t* io_options,
2781 const rocksdb_comparator_t* comparator) {
2782 rocksdb_sstfilewriter_t* writer = new rocksdb_sstfilewriter_t;
2783 writer->rep = new SstFileWriter(env->rep, io_options->rep);
2784 return writer;
2785 }
2786
2787 void rocksdb_sstfilewriter_open(rocksdb_sstfilewriter_t* writer,
2788 const char* name, char** errptr) {
2789 SaveError(errptr, writer->rep->Open(std::string(name)));
2790 }
2791
2792 void rocksdb_sstfilewriter_add(rocksdb_sstfilewriter_t* writer, const char* key,
2793 size_t keylen, const char* val, size_t vallen,
2794 char** errptr) {
2795 SaveError(errptr, writer->rep->Add(Slice(key, keylen), Slice(val, vallen)));
2796 }
2797
2798 void rocksdb_sstfilewriter_finish(rocksdb_sstfilewriter_t* writer,
2799 char** errptr) {
2800 SaveError(errptr, writer->rep->Finish(NULL));
2801 }
2802
2803 void rocksdb_sstfilewriter_destroy(rocksdb_sstfilewriter_t* writer) {
2804 delete writer->rep;
2805 delete writer;
2806 }
2807
2808 rocksdb_ingestexternalfileoptions_t*
2809 rocksdb_ingestexternalfileoptions_create() {
2810 rocksdb_ingestexternalfileoptions_t* opt =
2811 new rocksdb_ingestexternalfileoptions_t;
2812 return opt;
2813 }
2814
2815 void rocksdb_ingestexternalfileoptions_set_move_files(
2816 rocksdb_ingestexternalfileoptions_t* opt, unsigned char move_files) {
2817 opt->rep.move_files = move_files;
2818 }
2819
2820 void rocksdb_ingestexternalfileoptions_set_snapshot_consistency(
2821 rocksdb_ingestexternalfileoptions_t* opt,
2822 unsigned char snapshot_consistency) {
2823 opt->rep.snapshot_consistency = snapshot_consistency;
2824 }
2825
2826 void rocksdb_ingestexternalfileoptions_set_allow_global_seqno(
2827 rocksdb_ingestexternalfileoptions_t* opt,
2828 unsigned char allow_global_seqno) {
2829 opt->rep.allow_global_seqno = allow_global_seqno;
2830 }
2831
2832 void rocksdb_ingestexternalfileoptions_set_allow_blocking_flush(
2833 rocksdb_ingestexternalfileoptions_t* opt,
2834 unsigned char allow_blocking_flush) {
2835 opt->rep.allow_blocking_flush = allow_blocking_flush;
2836 }
2837
2838 void rocksdb_ingestexternalfileoptions_destroy(
2839 rocksdb_ingestexternalfileoptions_t* opt) {
2840 delete opt;
2841 }
2842
2843 void rocksdb_ingest_external_file(
2844 rocksdb_t* db, const char* const* file_list, const size_t list_len,
2845 const rocksdb_ingestexternalfileoptions_t* opt, char** errptr) {
2846 std::vector<std::string> files(list_len);
2847 for (size_t i = 0; i < list_len; ++i) {
2848 files[i] = std::string(file_list[i]);
2849 }
2850 SaveError(errptr, db->rep->IngestExternalFile(files, opt->rep));
2851 }
2852
2853 void rocksdb_ingest_external_file_cf(
2854 rocksdb_t* db, rocksdb_column_family_handle_t* handle,
2855 const char* const* file_list, const size_t list_len,
2856 const rocksdb_ingestexternalfileoptions_t* opt, char** errptr) {
2857 std::vector<std::string> files(list_len);
2858 for (size_t i = 0; i < list_len; ++i) {
2859 files[i] = std::string(file_list[i]);
2860 }
2861 SaveError(errptr, db->rep->IngestExternalFile(handle->rep, files, opt->rep));
2862 }
2863
2864 rocksdb_slicetransform_t* rocksdb_slicetransform_create(
2865 void* state,
2866 void (*destructor)(void*),
2867 char* (*transform)(
2868 void*,
2869 const char* key, size_t length,
2870 size_t* dst_length),
2871 unsigned char (*in_domain)(
2872 void*,
2873 const char* key, size_t length),
2874 unsigned char (*in_range)(
2875 void*,
2876 const char* key, size_t length),
2877 const char* (*name)(void*)) {
2878 rocksdb_slicetransform_t* result = new rocksdb_slicetransform_t;
2879 result->state_ = state;
2880 result->destructor_ = destructor;
2881 result->transform_ = transform;
2882 result->in_domain_ = in_domain;
2883 result->in_range_ = in_range;
2884 result->name_ = name;
2885 return result;
2886 }
2887
2888 void rocksdb_slicetransform_destroy(rocksdb_slicetransform_t* st) {
2889 delete st;
2890 }
2891
2892 rocksdb_slicetransform_t* rocksdb_slicetransform_create_fixed_prefix(size_t prefixLen) {
2893 struct Wrapper : public rocksdb_slicetransform_t {
2894 const SliceTransform* rep_;
2895 ~Wrapper() { delete rep_; }
2896 const char* Name() const override { return rep_->Name(); }
2897 Slice Transform(const Slice& src) const override {
2898 return rep_->Transform(src);
2899 }
2900 bool InDomain(const Slice& src) const override {
2901 return rep_->InDomain(src);
2902 }
2903 bool InRange(const Slice& src) const override { return rep_->InRange(src); }
2904 static void DoNothing(void*) { }
2905 };
2906 Wrapper* wrapper = new Wrapper;
2907 wrapper->rep_ = rocksdb::NewFixedPrefixTransform(prefixLen);
2908 wrapper->state_ = nullptr;
2909 wrapper->destructor_ = &Wrapper::DoNothing;
2910 return wrapper;
2911 }
2912
2913 rocksdb_slicetransform_t* rocksdb_slicetransform_create_noop() {
2914 struct Wrapper : public rocksdb_slicetransform_t {
2915 const SliceTransform* rep_;
2916 ~Wrapper() { delete rep_; }
2917 const char* Name() const override { return rep_->Name(); }
2918 Slice Transform(const Slice& src) const override {
2919 return rep_->Transform(src);
2920 }
2921 bool InDomain(const Slice& src) const override {
2922 return rep_->InDomain(src);
2923 }
2924 bool InRange(const Slice& src) const override { return rep_->InRange(src); }
2925 static void DoNothing(void*) { }
2926 };
2927 Wrapper* wrapper = new Wrapper;
2928 wrapper->rep_ = rocksdb::NewNoopTransform();
2929 wrapper->state_ = nullptr;
2930 wrapper->destructor_ = &Wrapper::DoNothing;
2931 return wrapper;
2932 }
2933
2934 rocksdb_universal_compaction_options_t* rocksdb_universal_compaction_options_create() {
2935 rocksdb_universal_compaction_options_t* result = new rocksdb_universal_compaction_options_t;
2936 result->rep = new rocksdb::CompactionOptionsUniversal;
2937 return result;
2938 }
2939
2940 void rocksdb_universal_compaction_options_set_size_ratio(
2941 rocksdb_universal_compaction_options_t* uco, int ratio) {
2942 uco->rep->size_ratio = ratio;
2943 }
2944
2945 void rocksdb_universal_compaction_options_set_min_merge_width(
2946 rocksdb_universal_compaction_options_t* uco, int w) {
2947 uco->rep->min_merge_width = w;
2948 }
2949
2950 void rocksdb_universal_compaction_options_set_max_merge_width(
2951 rocksdb_universal_compaction_options_t* uco, int w) {
2952 uco->rep->max_merge_width = w;
2953 }
2954
2955 void rocksdb_universal_compaction_options_set_max_size_amplification_percent(
2956 rocksdb_universal_compaction_options_t* uco, int p) {
2957 uco->rep->max_size_amplification_percent = p;
2958 }
2959
2960 void rocksdb_universal_compaction_options_set_compression_size_percent(
2961 rocksdb_universal_compaction_options_t* uco, int p) {
2962 uco->rep->compression_size_percent = p;
2963 }
2964
2965 void rocksdb_universal_compaction_options_set_stop_style(
2966 rocksdb_universal_compaction_options_t* uco, int style) {
2967 uco->rep->stop_style = static_cast<rocksdb::CompactionStopStyle>(style);
2968 }
2969
2970 void rocksdb_universal_compaction_options_destroy(
2971 rocksdb_universal_compaction_options_t* uco) {
2972 delete uco->rep;
2973 delete uco;
2974 }
2975
2976 rocksdb_fifo_compaction_options_t* rocksdb_fifo_compaction_options_create() {
2977 rocksdb_fifo_compaction_options_t* result = new rocksdb_fifo_compaction_options_t;
2978 result->rep = CompactionOptionsFIFO();
2979 return result;
2980 }
2981
2982 void rocksdb_fifo_compaction_options_set_max_table_files_size(
2983 rocksdb_fifo_compaction_options_t* fifo_opts, uint64_t size) {
2984 fifo_opts->rep.max_table_files_size = size;
2985 }
2986
2987 void rocksdb_fifo_compaction_options_destroy(
2988 rocksdb_fifo_compaction_options_t* fifo_opts) {
2989 delete fifo_opts;
2990 }
2991
2992 void rocksdb_options_set_min_level_to_compress(rocksdb_options_t* opt, int level) {
2993 if (level >= 0) {
2994 assert(level <= opt->rep.num_levels);
2995 opt->rep.compression_per_level.resize(opt->rep.num_levels);
2996 for (int i = 0; i < level; i++) {
2997 opt->rep.compression_per_level[i] = rocksdb::kNoCompression;
2998 }
2999 for (int i = level; i < opt->rep.num_levels; i++) {
3000 opt->rep.compression_per_level[i] = opt->rep.compression;
3001 }
3002 }
3003 }
3004
3005 int rocksdb_livefiles_count(
3006 const rocksdb_livefiles_t* lf) {
3007 return static_cast<int>(lf->rep.size());
3008 }
3009
3010 const char* rocksdb_livefiles_name(
3011 const rocksdb_livefiles_t* lf,
3012 int index) {
3013 return lf->rep[index].name.c_str();
3014 }
3015
3016 int rocksdb_livefiles_level(
3017 const rocksdb_livefiles_t* lf,
3018 int index) {
3019 return lf->rep[index].level;
3020 }
3021
3022 size_t rocksdb_livefiles_size(
3023 const rocksdb_livefiles_t* lf,
3024 int index) {
3025 return lf->rep[index].size;
3026 }
3027
3028 const char* rocksdb_livefiles_smallestkey(
3029 const rocksdb_livefiles_t* lf,
3030 int index,
3031 size_t* size) {
3032 *size = lf->rep[index].smallestkey.size();
3033 return lf->rep[index].smallestkey.data();
3034 }
3035
3036 const char* rocksdb_livefiles_largestkey(
3037 const rocksdb_livefiles_t* lf,
3038 int index,
3039 size_t* size) {
3040 *size = lf->rep[index].largestkey.size();
3041 return lf->rep[index].largestkey.data();
3042 }
3043
3044 extern void rocksdb_livefiles_destroy(
3045 const rocksdb_livefiles_t* lf) {
3046 delete lf;
3047 }
3048
3049 void rocksdb_get_options_from_string(const rocksdb_options_t* base_options,
3050 const char* opts_str,
3051 rocksdb_options_t* new_options,
3052 char** errptr) {
3053 SaveError(errptr,
3054 GetOptionsFromString(base_options->rep, std::string(opts_str),
3055 &new_options->rep));
3056 }
3057
3058 void rocksdb_delete_file_in_range(rocksdb_t* db, const char* start_key,
3059 size_t start_key_len, const char* limit_key,
3060 size_t limit_key_len, char** errptr) {
3061 Slice a, b;
3062 SaveError(
3063 errptr,
3064 DeleteFilesInRange(
3065 db->rep, db->rep->DefaultColumnFamily(),
3066 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
3067 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr)));
3068 }
3069
3070 void rocksdb_delete_file_in_range_cf(
3071 rocksdb_t* db, rocksdb_column_family_handle_t* column_family,
3072 const char* start_key, size_t start_key_len, const char* limit_key,
3073 size_t limit_key_len, char** errptr) {
3074 Slice a, b;
3075 SaveError(
3076 errptr,
3077 DeleteFilesInRange(
3078 db->rep, column_family->rep,
3079 (start_key ? (a = Slice(start_key, start_key_len), &a) : nullptr),
3080 (limit_key ? (b = Slice(limit_key, limit_key_len), &b) : nullptr)));
3081 }
3082
3083 void rocksdb_free(void* ptr) { free(ptr); }
3084
3085 } // end extern "C"
3086
3087 #endif // !ROCKSDB_LITE