1use std::ffi::CStr;
17
18use libc;
19use libc::{c_char, c_uchar, c_int, c_void, size_t};
20use local_encoding::{Encoding, Encoder};
21
22pub enum DBOptionsOpaque {}
23pub type DBOptions = *const DBOptionsOpaque;
24
25pub enum DBInstanceOpaque {}
26pub type DBInstance = *const DBInstanceOpaque;
27
28pub enum DBWriteOptionsOpaque {}
29pub type DBWriteOptions = *const DBWriteOptionsOpaque;
30
31pub enum DBReadOptionsOpaque {}
32pub type DBReadOptions = *const DBReadOptionsOpaque;
33
34pub enum DBMergeOperatorOpaque {}
35pub type DBMergeOperator = *const DBMergeOperatorOpaque;
36
37pub enum DBBlockBasedTableOptionsOpaque {}
38pub type DBBlockBasedTableOptions = *const DBBlockBasedTableOptionsOpaque;
39
40pub enum DBCacheOpaque {}
41pub type DBCache = *const DBCacheOpaque;
42
43pub enum DBFilterPolicyOpaque {}
44pub type DBFilterPolicy = *const DBFilterPolicyOpaque;
45
46pub enum DBSnapshotOpaque {}
47pub type DBSnapshot = *const DBSnapshotOpaque;
48
49pub enum DBIteratorOpaque {}
50pub type DBIterator = *const DBIteratorOpaque;
51
52pub enum DBCFHandleOpaque {}
53pub type DBCFHandle = *const DBCFHandleOpaque;
54
55pub enum DBWriteBatchOpaque {}
56pub type DBWriteBatch = *const DBWriteBatchOpaque;
57
58pub enum DBComparatorOpaque {}
59pub type DBComparator = *const DBComparatorOpaque;
60
61pub enum DBSliceTransformOpaque {}
62pub type DBSliceTransform = *const DBSliceTransformOpaque;
63
64pub const BLOCK_BASED_INDEX_TYPE_BINARY_SEARCH: c_int = 0;
65pub const BLOCK_BASED_INDEX_TYPE_HASH_SEARCH: c_int = 1;
66
67pub fn new_bloom_filter(bits: c_int) -> DBFilterPolicy {
68 unsafe { rocksdb_filterpolicy_create_bloom(bits) }
69}
70
71pub fn new_cache(capacity: size_t) -> DBCache {
72 unsafe { rocksdb_cache_create_lru(capacity) }
73}
74
75#[repr(C)]
76pub enum DBCompressionType {
77 DBNoCompression = 0,
78 DBSnappyCompression = 1,
79 DBZlibCompression = 2,
80 DBBz2Compression = 3,
81 DBLz4Compression = 4,
82 DBLz4hcCompression = 5,
83}
84
85#[repr(C)]
86pub enum DBCompactionStyle {
87 DBLevelCompaction = 0,
88 DBUniversalCompaction = 1,
89 DBFifoCompaction = 2,
90}
91
92#[repr(C)]
93pub enum DBUniversalCompactionStyle {
94 rocksdb_similar_size_compaction_stop_style = 0,
95 rocksdb_total_size_compaction_stop_style = 1,
96}
97
98pub fn error_message(ptr: *const i8) -> String {
99 let c_str = unsafe { CStr::from_ptr(ptr as *const _) };
100 let s = Encoding::ANSI.to_string(c_str.to_bytes())
101 .unwrap_or_else(|_| "Error converting string".to_owned());
102 unsafe {
103 libc::free(ptr as *mut libc::c_void);
104 }
105 s
106}
107
108#[link(name = "rocksdb")]
111extern "C" {
112 pub fn rocksdb_options_create() -> DBOptions;
113 pub fn rocksdb_options_destroy(opts: DBOptions);
114 pub fn rocksdb_cache_create_lru(capacity: size_t) -> DBCache;
115 pub fn rocksdb_cache_destroy(cache: DBCache);
116 pub fn rocksdb_block_based_options_create() -> DBBlockBasedTableOptions;
117 pub fn rocksdb_block_based_options_destroy(opts: DBBlockBasedTableOptions);
118 pub fn rocksdb_block_based_options_set_block_size(
119 block_options: DBBlockBasedTableOptions,
120 block_size: size_t);
121 pub fn rocksdb_block_based_options_set_block_size_deviation(
122 block_options: DBBlockBasedTableOptions,
123 block_size_deviation: c_int);
124 pub fn rocksdb_block_based_options_set_block_restart_interval(
125 block_options: DBBlockBasedTableOptions,
126 block_restart_interval: c_int);
127 pub fn rocksdb_block_based_options_set_filter_policy(
128 block_options: DBBlockBasedTableOptions,
129 filter_policy: DBFilterPolicy);
130 pub fn rocksdb_block_based_options_set_no_block_cache(
131 block_options: DBBlockBasedTableOptions, no_block_cache: bool);
132 pub fn rocksdb_block_based_options_set_block_cache(
133 block_options: DBBlockBasedTableOptions, block_cache: DBCache);
134 pub fn rocksdb_block_based_options_set_block_cache_compressed(
135 block_options: DBBlockBasedTableOptions,
136 block_cache_compressed: DBCache);
137 pub fn rocksdb_block_based_options_set_whole_key_filtering(
138 ck_options: DBBlockBasedTableOptions, doit: bool);
139 pub fn rocksdb_options_set_block_based_table_factory(
140 options: DBOptions,
141 block_options: DBBlockBasedTableOptions);
142 pub fn rocksdb_block_based_options_set_index_type(
143 block_options: DBBlockBasedTableOptions,
144 index_type: c_int);
145 pub fn rocksdb_options_increase_parallelism(options: DBOptions,
146 threads: c_int);
147 pub fn rocksdb_options_optimize_level_style_compaction(
148 options: DBOptions, memtable_memory_budget: c_int);
149 pub fn rocksdb_options_set_create_if_missing(options: DBOptions, v: bool);
150 pub fn rocksdb_options_set_max_open_files(options: DBOptions,
151 files: c_int);
152 pub fn rocksdb_options_set_use_fsync(options: DBOptions, v: c_int);
153 pub fn rocksdb_options_set_bytes_per_sync(options: DBOptions, bytes: u64);
154 pub fn rocksdb_options_optimize_for_point_lookup(options: DBOptions,
155 block_cache_size_mb: u64);
156 pub fn rocksdb_options_set_table_cache_numshardbits(options: DBOptions,
157 bits: c_int);
158 pub fn rocksdb_options_set_max_write_buffer_number(options: DBOptions,
159 bufno: c_int);
160 pub fn rocksdb_options_set_min_write_buffer_number_to_merge(
161 options: DBOptions, bufno: c_int);
162 pub fn rocksdb_options_set_level0_file_num_compaction_trigger(
163 options: DBOptions, no: c_int);
164 pub fn rocksdb_options_set_level0_slowdown_writes_trigger(
165 options: DBOptions, no: c_int);
166 pub fn rocksdb_options_set_level0_stop_writes_trigger(options: DBOptions,
167 no: c_int);
168 pub fn rocksdb_options_set_write_buffer_size(options: DBOptions,
169 bytes: usize);
170 pub fn rocksdb_options_set_db_write_buffer_size(options: DBOptions,
171 bytes: usize);
172 pub fn rocksdb_options_set_target_file_size_base(options: DBOptions,
173 bytes: u64);
174 pub fn rocksdb_options_set_target_file_size_multiplier(options: DBOptions,
175 mul: c_int);
176 pub fn rocksdb_options_set_max_log_file_size(options: DBOptions,
177 bytes: usize);
178 pub fn rocksdb_options_set_max_manifest_file_size(options: DBOptions,
179 bytes: usize);
180 pub fn rocksdb_options_set_hash_skip_list_rep(options: DBOptions,
181 bytes: usize,
182 a1: i32,
183 a2: i32);
184 pub fn rocksdb_options_set_compaction_style(options: DBOptions,
185 cs: DBCompactionStyle);
186 pub fn rocksdb_options_set_compression(options: DBOptions,
187 compression_style_no: c_int);
188 pub fn rocksdb_options_set_max_background_compactions(
189 options: DBOptions, max_bg_compactions: c_int);
190 pub fn rocksdb_options_set_max_background_flushes(options: DBOptions,
191 max_bg_flushes: c_int);
192 pub fn rocksdb_options_set_disable_auto_compactions(options: DBOptions,
193 v: c_int);
194 pub fn rocksdb_options_set_prefix_extractor(options: DBOptions,
195 slice_transform: DBSliceTransform);
196 pub fn rocksdb_filterpolicy_create_bloom(bits_per_key: c_int)
197 -> DBFilterPolicy;
198 pub fn rocksdb_filterpolicy_destroy(filter: DBFilterPolicy);
199 pub fn rocksdb_open(options: DBOptions,
200 path: *const i8,
201 err: *mut *const i8)
202 -> DBInstance;
203 pub fn rocksdb_writeoptions_create() -> DBWriteOptions;
204 pub fn rocksdb_writeoptions_destroy(writeopts: DBWriteOptions);
205 pub fn rocksdb_writeoptions_set_sync(writeopts: DBWriteOptions, v: bool);
206 pub fn rocksdb_writeoptions_disable_WAL(writeopts: DBWriteOptions,
207 v: c_int);
208 pub fn rocksdb_put(db: DBInstance,
209 writeopts: DBWriteOptions,
210 k: *const u8,
211 kLen: size_t,
212 v: *const u8,
213 vLen: size_t,
214 err: *mut *const i8);
215 pub fn rocksdb_put_cf(db: DBInstance,
216 writeopts: DBWriteOptions,
217 cf: DBCFHandle,
218 k: *const u8,
219 kLen: size_t,
220 v: *const u8,
221 vLen: size_t,
222 err: *mut *const i8);
223 pub fn rocksdb_readoptions_create() -> DBReadOptions;
224 pub fn rocksdb_readoptions_destroy(readopts: DBReadOptions);
225 pub fn rocksdb_readoptions_set_verify_checksums(readopts: DBReadOptions,
226 v: bool);
227 pub fn rocksdb_readoptions_set_fill_cache(readopts: DBReadOptions,
228 v: bool);
229 pub fn rocksdb_readoptions_set_snapshot(readopts: DBReadOptions,
230 snapshot: DBSnapshot); pub fn rocksdb_readoptions_set_iterate_upper_bound(readopts: DBReadOptions,
232 k: *const u8,
233 kLen: size_t);
234 pub fn rocksdb_readoptions_set_read_tier(readopts: DBReadOptions,
235 tier: c_int);
236 pub fn rocksdb_readoptions_set_tailing(readopts: DBReadOptions, v: bool);
237
238 pub fn rocksdb_get(db: DBInstance,
239 readopts: DBReadOptions,
240 k: *const u8,
241 kLen: size_t,
242 valLen: *const size_t,
243 err: *mut *const i8)
244 -> *mut c_void;
245 pub fn rocksdb_get_cf(db: DBInstance,
246 readopts: DBReadOptions,
247 cf_handle: DBCFHandle,
248 k: *const u8,
249 kLen: size_t,
250 valLen: *const size_t,
251 err: *mut *const i8)
252 -> *mut c_void;
253 pub fn rocksdb_create_iterator(db: DBInstance,
254 readopts: DBReadOptions)
255 -> DBIterator;
256 pub fn rocksdb_create_iterator_cf(db: DBInstance,
257 readopts: DBReadOptions,
258 cf_handle: DBCFHandle)
259 -> DBIterator;
260 pub fn rocksdb_create_snapshot(db: DBInstance) -> DBSnapshot;
261 pub fn rocksdb_release_snapshot(db: DBInstance, snapshot: DBSnapshot);
262
263 pub fn rocksdb_delete(db: DBInstance,
264 writeopts: DBWriteOptions,
265 k: *const u8,
266 kLen: size_t,
267 err: *mut *const i8)
268 -> *mut c_void;
269 pub fn rocksdb_delete_cf(db: DBInstance,
270 writeopts: DBWriteOptions,
271 cf: DBCFHandle,
272 k: *const u8,
273 kLen: size_t,
274 err: *mut *const i8)
275 -> *mut c_void;
276 pub fn rocksdb_close(db: DBInstance);
277 pub fn rocksdb_destroy_db(options: DBOptions,
278 path: *const i8,
279 err: *mut *const i8);
280 pub fn rocksdb_repair_db(options: DBOptions,
281 path: *const i8,
282 err: *mut *const i8);
283 pub fn rocksdb_merge(db: DBInstance,
285 writeopts: DBWriteOptions,
286 k: *const u8,
287 kLen: size_t,
288 v: *const u8,
289 vLen: size_t,
290 err: *mut *const i8);
291 pub fn rocksdb_merge_cf(db: DBInstance,
292 writeopts: DBWriteOptions,
293 cf: DBCFHandle,
294 k: *const u8,
295 kLen: size_t,
296 v: *const u8,
297 vLen: size_t,
298 err: *mut *const i8);
299 pub fn rocksdb_mergeoperator_create(
300 state: *mut c_void,
301 destroy: extern fn(*mut c_void) -> (),
302 full_merge: extern fn (arg: *mut c_void,
303 key: *const c_char, key_len: size_t,
304 existing_value: *const c_char,
305 existing_value_len: size_t,
306 operands_list: *const *const c_char,
307 operands_list_len: *const size_t,
308 num_operands: c_int, success: *mut u8,
309 new_value_length: *mut size_t
310 ) -> *const c_char,
311 partial_merge: extern fn(arg: *mut c_void,
312 key: *const c_char, key_len: size_t,
313 operands_list: *const *const c_char,
314 operands_list_len: *const size_t,
315 num_operands: c_int, success: *mut u8,
316 new_value_length: *mut size_t
317 ) -> *const c_char,
318 delete_value: Option<extern "C" fn(*mut c_void,
319 value: *const c_char,
320 value_len: *mut size_t
321 ) -> ()>,
322 name_fn: extern fn(*mut c_void) -> *const c_char,
323 ) -> DBMergeOperator;
324 pub fn rocksdb_mergeoperator_destroy(mo: DBMergeOperator);
325 pub fn rocksdb_options_set_merge_operator(options: DBOptions,
326 mo: DBMergeOperator);
327 pub fn rocksdb_iter_destroy(iter: DBIterator);
329 pub fn rocksdb_iter_valid(iter: DBIterator) -> bool;
330 pub fn rocksdb_iter_seek_to_first(iter: DBIterator);
331 pub fn rocksdb_iter_seek_to_last(iter: DBIterator);
332 pub fn rocksdb_iter_seek(iter: DBIterator, key: *const u8, klen: size_t);
333 pub fn rocksdb_iter_next(iter: DBIterator);
334 pub fn rocksdb_iter_prev(iter: DBIterator);
335 pub fn rocksdb_iter_key(iter: DBIterator, klen: *mut size_t) -> *mut u8;
336 pub fn rocksdb_iter_value(iter: DBIterator, vlen: *mut size_t) -> *mut u8;
337 pub fn rocksdb_iter_get_error(iter: DBIterator, err: *mut *const u8);
338 pub fn rocksdb_write(db: DBInstance,
340 writeopts: DBWriteOptions,
341 batch: DBWriteBatch,
342 err: *mut *const i8);
343 pub fn rocksdb_writebatch_create() -> DBWriteBatch;
344 pub fn rocksdb_writebatch_create_from(rep: *const u8,
345 size: size_t)
346 -> DBWriteBatch;
347 pub fn rocksdb_writebatch_destroy(batch: DBWriteBatch);
348 pub fn rocksdb_writebatch_clear(batch: DBWriteBatch);
349 pub fn rocksdb_writebatch_count(batch: DBWriteBatch) -> c_int;
350 pub fn rocksdb_writebatch_put(batch: DBWriteBatch,
351 key: *const u8,
352 klen: size_t,
353 val: *const u8,
354 vlen: size_t);
355 pub fn rocksdb_writebatch_put_cf(batch: DBWriteBatch,
356 cf: DBCFHandle,
357 key: *const u8,
358 klen: size_t,
359 val: *const u8,
360 vlen: size_t);
361 pub fn rocksdb_writebatch_merge(batch: DBWriteBatch,
362 key: *const u8,
363 klen: size_t,
364 val: *const u8,
365 vlen: size_t);
366 pub fn rocksdb_writebatch_merge_cf(batch: DBWriteBatch,
367 cf: DBCFHandle,
368 key: *const u8,
369 klen: size_t,
370 val: *const u8,
371 vlen: size_t);
372 pub fn rocksdb_writebatch_delete(batch: DBWriteBatch,
373 key: *const u8,
374 klen: size_t);
375 pub fn rocksdb_writebatch_delete_cf(batch: DBWriteBatch,
376 cf: DBCFHandle,
377 key: *const u8,
378 klen: size_t);
379 pub fn rocksdb_writebatch_iterate(
380 batch: DBWriteBatch,
381 state: *mut c_void,
382 put_fn: extern fn(state: *mut c_void,
383 k: *const u8, klen: size_t,
384 v: *const u8, vlen: size_t),
385 deleted_fn: extern fn(state: *mut c_void,
386 k: *const u8, klen: size_t));
387 pub fn rocksdb_writebatch_data(batch: DBWriteBatch,
388 size: *mut size_t)
389 -> *const u8;
390
391 pub fn rocksdb_options_set_comparator(options: DBOptions,
393 cb: DBComparator);
394 pub fn rocksdb_comparator_create(state: *mut c_void,
395 destroy: extern "C" fn(*mut c_void) -> (),
396 compare: extern "C" fn(arg: *mut c_void,
397 a: *const c_char,
398 alen: size_t,
399 b: *const c_char,
400 blen: size_t)
401 -> c_int,
402 name_fn: extern "C" fn(*mut c_void)
403 -> *const c_char)
404 -> DBComparator;
405 pub fn rocksdb_comparator_destroy(cmp: DBComparator);
406
407 pub fn rocksdb_open_column_families(options: DBOptions,
409 path: *const i8,
410 num_column_families: c_int,
411 column_family_names: *const *const i8,
412 column_family_options: *const DBOptions,
413 column_family_handles: *const DBCFHandle,
414 err: *mut *const i8
415 ) -> DBInstance;
416 pub fn rocksdb_create_column_family(db: DBInstance,
417 column_family_options: DBOptions,
418 column_family_name: *const i8,
419 err: *mut *const i8)
420 -> DBCFHandle;
421 pub fn rocksdb_drop_column_family(db: DBInstance,
422 column_family_handle: DBCFHandle,
423 err: *mut *const i8);
424 pub fn rocksdb_column_family_handle_destroy(column_family_handle: DBCFHandle);
425
426 pub fn rocksdb_slicetransform_create(state: *mut c_void,
428 destructor: Option<extern "C" fn(arg1: *mut c_void) -> ()>,
429 transform: Option<extern "C" fn(arg1: *mut c_void,
430 key: *const c_char,
431 length: size_t,
432 dst_length: *mut size_t)
433 -> *mut c_char>,
434 in_domain: Option<extern "C" fn(arg1: *mut c_void,
435 key: *const c_char,
436 length: size_t)
437 -> c_uchar>,
438 in_range: Option<extern "C" fn(arg1: *mut c_void,
439 key: *const c_char,
440 length: size_t)
441 -> c_uchar>,
442 name: Option<extern "C" fn(arg1: *mut c_void)
443 -> *const c_char>) -> DBSliceTransform;
444 pub fn rocksdb_slicetransform_create_fixed_prefix(size: size_t) -> DBSliceTransform;
445 pub fn rocksdb_slicetransform_create_noop() -> DBSliceTransform;
446 pub fn rocksdb_slicetransform_destroy(slice_transform: DBSliceTransform);
447
448 pub fn rocksdb_get_options_from_string(base_options: DBOptions, opts: *const i8, new_options: DBOptions, err: *mut *const i8);
449
450 pub fn rocksdb_property_int(
451 db: DBInstance,
452 prop: *const c_char,
453 value: *mut u64
454 ) -> c_int;
455
456 pub fn rocksdb_property_value(
457 db: DBInstance,
458 prop: *const c_char,
459 ) -> *const c_char;
460
461 pub fn rocksdb_property_value_cf(
462 db: DBInstance,
463 cf: DBCFHandle,
464 prop: *const c_char,
465 ) -> *const c_char;
466}
467
468#[test]
469fn internal() {
470 unsafe {
471 use std::ffi::CString;
472 let opts = rocksdb_options_create();
473 assert!(!opts.is_null());
474
475 rocksdb_options_increase_parallelism(opts, 0);
476 rocksdb_options_optimize_level_style_compaction(opts, 0);
477 rocksdb_options_set_create_if_missing(opts, true);
478
479 let rustpath = "_rust_rocksdb_internaltest";
480 let cpath = CString::new(rustpath).unwrap();
481 let cpath_ptr = cpath.as_ptr();
482
483 let mut err: *const i8 = 0 as *const i8;
484 let err_ptr: *mut *const i8 = &mut err;
485 let db = rocksdb_open(opts, cpath_ptr as *const _, err_ptr);
486 if !err.is_null() {
487 println!("failed to open rocksdb: {}", error_message(err));
488 }
489 assert!(err.is_null());
490
491 let writeopts = rocksdb_writeoptions_create();
492 assert!(!writeopts.is_null());
493
494 let key = b"name\x00";
495 let val = b"spacejam\x00";
496 rocksdb_put(db,
497 writeopts.clone(),
498 key.as_ptr(),
499 4,
500 val.as_ptr(),
501 8,
502 err_ptr);
503 rocksdb_writeoptions_destroy(writeopts);
504 assert!(err.is_null());
505
506 let readopts = rocksdb_readoptions_create();
507 assert!(!readopts.is_null());
508
509 let val_len: size_t = 0;
510 let val_len_ptr = &val_len as *const size_t;
511 rocksdb_get(db,
512 readopts.clone(),
513 key.as_ptr(),
514 4,
515 val_len_ptr,
516 err_ptr);
517 rocksdb_readoptions_destroy(readopts);
518 assert!(err.is_null());
519 rocksdb_close(db);
520 rocksdb_destroy_db(opts, cpath_ptr as *const _, err_ptr);
521 assert!(err.is_null());
522
523 let base_options = rocksdb_options_create();
524 let opts_string = CString::new("rate_limiter_bytes_per_sec=1024").unwrap();
525 let opts_string_ptr = opts_string.as_ptr();
526 let new_options = rocksdb_options_create();
527 let mut err: *const i8 = 0 as *const i8;
528 let err_ptr: *mut *const i8 = &mut err;
529 rocksdb_get_options_from_string(base_options, opts_string_ptr as *const _, new_options, err_ptr);
530 if !err.is_null() {
531 println!("failed to open rocksdb: {}", error_message(err));
532 }
533 }
534}