mappum_rocksdb/db_options.rs
1// Copyright 2014 Tyler Neely
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::ffi::{CStr, CString};
16use std::mem;
17use std::path::Path;
18
19use libc::{self, c_int, c_uchar, c_uint, c_void, size_t};
20
21use crate::{
22 compaction_filter::{self, filter_callback, CompactionFilterCallback, CompactionFilterFn},
23 comparator::{self, ComparatorCallback, CompareFn},
24 ffi,
25 merge_operator::{
26 self, full_merge_callback, partial_merge_callback, MergeFn, MergeOperatorCallback,
27 },
28 slice_transform::SliceTransform,
29 BlockBasedIndexType, BlockBasedOptions, DBCompactionStyle, DBCompressionType, DBRecoveryMode,
30 FlushOptions, MemtableFactory, Options, PlainTableFactoryOptions, WriteOptions,
31};
32
33pub fn new_cache(capacity: size_t) -> *mut ffi::rocksdb_cache_t {
34 unsafe { ffi::rocksdb_cache_create_lru(capacity) }
35}
36
37// Safety note: auto-implementing Send on most db-related types is prevented by the inner FFI
38// pointer. In most cases, however, this pointer is Send-safe because it is never aliased and
39// rocksdb internally does not rely on thread-local information for its user-exposed types.
40unsafe impl Send for Options {}
41unsafe impl Send for WriteOptions {}
42unsafe impl Send for BlockBasedOptions {}
43// Sync is similarly safe for many types because they do not expose interior mutability, and their
44// use within the rocksdb library is generally behind a const reference
45unsafe impl Sync for Options {}
46unsafe impl Sync for WriteOptions {}
47unsafe impl Sync for BlockBasedOptions {}
48
49impl Drop for Options {
50 fn drop(&mut self) {
51 unsafe {
52 ffi::rocksdb_options_destroy(self.inner);
53 }
54 }
55}
56
57impl Drop for BlockBasedOptions {
58 fn drop(&mut self) {
59 unsafe {
60 ffi::rocksdb_block_based_options_destroy(self.inner);
61 }
62 }
63}
64
65impl Drop for FlushOptions {
66 fn drop(&mut self) {
67 unsafe {
68 ffi::rocksdb_flushoptions_destroy(self.inner);
69 }
70 }
71}
72
73impl Drop for WriteOptions {
74 fn drop(&mut self) {
75 unsafe {
76 ffi::rocksdb_writeoptions_destroy(self.inner);
77 }
78 }
79}
80
81impl BlockBasedOptions {
82 pub fn set_block_size(&mut self, size: usize) {
83 unsafe {
84 ffi::rocksdb_block_based_options_set_block_size(self.inner, size);
85 }
86 }
87
88 pub fn set_lru_cache(&mut self, size: size_t) {
89 let cache = new_cache(size);
90 unsafe {
91 // Since cache is wrapped in shared_ptr, we don't need to
92 // call rocksdb_cache_destroy explicitly.
93 ffi::rocksdb_block_based_options_set_block_cache(self.inner, cache);
94 }
95 }
96
97 pub fn disable_cache(&mut self) {
98 unsafe {
99 ffi::rocksdb_block_based_options_set_no_block_cache(self.inner, true as c_uchar);
100 }
101 }
102
103 pub fn set_bloom_filter(&mut self, bits_per_key: c_int, block_based: bool) {
104 unsafe {
105 let bloom = if block_based {
106 ffi::rocksdb_filterpolicy_create_bloom(bits_per_key)
107 } else {
108 ffi::rocksdb_filterpolicy_create_bloom_full(bits_per_key)
109 };
110
111 ffi::rocksdb_block_based_options_set_filter_policy(self.inner, bloom);
112 }
113 }
114
115 pub fn set_cache_index_and_filter_blocks(&mut self, v: bool) {
116 unsafe {
117 ffi::rocksdb_block_based_options_set_cache_index_and_filter_blocks(self.inner, v as u8);
118 }
119 }
120
121 /// Defines the index type to be used for SS-table lookups.
122 ///
123 /// # Example
124 ///
125 /// ```
126 /// use rocksdb::{BlockBasedOptions, BlockBasedIndexType, Options};
127 ///
128 /// let mut opts = Options::default();
129 /// let mut block_opts = BlockBasedOptions::default();
130 /// block_opts.set_index_type(BlockBasedIndexType::HashSearch);
131 /// ```
132 pub fn set_index_type(&mut self, index_type: BlockBasedIndexType) {
133 let index = index_type as i32;
134 unsafe {
135 ffi::rocksdb_block_based_options_set_index_type(self.inner, index);
136 }
137 }
138
139 /// If cache_index_and_filter_blocks is true and the below is true, then
140 /// filter and index blocks are stored in the cache, but a reference is
141 /// held in the "table reader" object so the blocks are pinned and only
142 /// evicted from cache when the table reader is freed.
143 ///
144 /// Default: false.
145 pub fn set_pin_l0_filter_and_index_blocks_in_cache(&mut self, v: bool) {
146 unsafe {
147 ffi::rocksdb_block_based_options_set_pin_l0_filter_and_index_blocks_in_cache(
148 self.inner,
149 v as c_uchar,
150 );
151 }
152 }
153
154 /// Format version, reserved for backward compatibility.
155 /// See https://github.com/facebook/rocksdb/blob/f059c7d9b96300091e07429a60f4ad55dac84859/include/rocksdb/table.h#L249-L274.
156 ///
157 /// Default: 2.
158 pub fn set_format_version(&mut self, version: i32) {
159 unsafe {
160 ffi::rocksdb_block_based_options_set_format_version(self.inner, version);
161 }
162 }
163
164 /// Number of keys between restart points for delta encoding of keys.
165 /// This parameter can be changed dynamically. Most clients should
166 /// leave this parameter alone. The minimum value allowed is 1. Any smaller
167 /// value will be silently overwritten with 1.
168 ///
169 /// Default: 16.
170 pub fn set_block_restart_interval(&mut self, interval: i32) {
171 unsafe {
172 ffi::rocksdb_block_based_options_set_block_restart_interval(self.inner, interval);
173 }
174 }
175
176 /// Same as block_restart_interval but used for the index block.
177 /// If you don't plan to run RocksDB before version 5.16 and you are
178 /// using `index_block_restart_interval` > 1, you should
179 /// probably set the `format_version` to >= 4 as it would reduce the index size.
180 ///
181 /// Default: 1.
182 pub fn set_index_block_restart_interval(&mut self, interval: i32) {
183 unsafe {
184 ffi::rocksdb_block_based_options_set_index_block_restart_interval(self.inner, interval);
185 }
186 }
187}
188
189impl Default for BlockBasedOptions {
190 fn default() -> BlockBasedOptions {
191 let block_opts = unsafe { ffi::rocksdb_block_based_options_create() };
192 if block_opts.is_null() {
193 panic!("Could not create RocksDB block based options");
194 }
195 BlockBasedOptions { inner: block_opts }
196 }
197}
198
199impl Options {
200 /// By default, RocksDB uses only one background thread for flush and
201 /// compaction. Calling this function will set it up such that total of
202 /// `total_threads` is used. Good value for `total_threads` is the number of
203 /// cores. You almost definitely want to call this function if your system is
204 /// bottlenecked by RocksDB.
205 ///
206 /// # Example
207 ///
208 /// ```
209 /// use rocksdb::Options;
210 ///
211 /// let mut opts = Options::default();
212 /// opts.increase_parallelism(3);
213 /// ```
214 pub fn increase_parallelism(&mut self, parallelism: i32) {
215 unsafe {
216 ffi::rocksdb_options_increase_parallelism(self.inner, parallelism);
217 }
218 }
219
220 pub fn optimize_level_style_compaction(&mut self, memtable_memory_budget: usize) {
221 unsafe {
222 ffi::rocksdb_options_optimize_level_style_compaction(
223 self.inner,
224 memtable_memory_budget as u64,
225 );
226 }
227 }
228
229 /// If true, the database will be created if it is missing.
230 ///
231 /// Default: `false`
232 ///
233 /// # Example
234 ///
235 /// ```
236 /// use rocksdb::Options;
237 ///
238 /// let mut opts = Options::default();
239 /// opts.create_if_missing(true);
240 /// ```
241 pub fn create_if_missing(&mut self, create_if_missing: bool) {
242 unsafe {
243 ffi::rocksdb_options_set_create_if_missing(self.inner, create_if_missing as c_uchar);
244 }
245 }
246
247 /// If true, any column families that didn't exist when opening the database
248 /// will be created.
249 ///
250 /// Default: `false`
251 ///
252 /// # Example
253 ///
254 /// ```
255 /// use rocksdb::Options;
256 ///
257 /// let mut opts = Options::default();
258 /// opts.create_missing_column_families(true);
259 /// ```
260 pub fn create_missing_column_families(&mut self, create_missing_cfs: bool) {
261 unsafe {
262 ffi::rocksdb_options_set_create_missing_column_families(
263 self.inner,
264 create_missing_cfs as c_uchar,
265 );
266 }
267 }
268
269 /// Sets the compression algorithm that will be used for the bottommost level that
270 /// contain files. If level-compaction is used, this option will only affect
271 /// levels after base level.
272 ///
273 /// Default: DBCompressionType::None
274 ///
275 /// # Example
276 ///
277 /// ```
278 /// use rocksdb::{Options, DBCompressionType};
279 ///
280 /// let mut opts = Options::default();
281 /// opts.set_compression_type(DBCompressionType::Snappy);
282 /// ```
283 pub fn set_compression_type(&mut self, t: DBCompressionType) {
284 unsafe {
285 ffi::rocksdb_options_set_compression(self.inner, t as c_int);
286 }
287 }
288
289 /// Different levels can have different compression policies. There
290 /// are cases where most lower levels would like to use quick compression
291 /// algorithms while the higher levels (which have more data) use
292 /// compression algorithms that have better compression but could
293 /// be slower. This array, if non-empty, should have an entry for
294 /// each level of the database; these override the value specified in
295 /// the previous field 'compression'.
296 ///
297 /// # Example
298 ///
299 /// ```
300 /// use rocksdb::{Options, DBCompressionType};
301 ///
302 /// let mut opts = Options::default();
303 /// opts.set_compression_per_level(&[
304 /// DBCompressionType::None,
305 /// DBCompressionType::None,
306 /// DBCompressionType::Snappy,
307 /// DBCompressionType::Snappy,
308 /// DBCompressionType::Snappy
309 /// ]);
310 /// ```
311 pub fn set_compression_per_level(&mut self, level_types: &[DBCompressionType]) {
312 unsafe {
313 let mut level_types: Vec<_> = level_types.iter().map(|&t| t as c_int).collect();
314 ffi::rocksdb_options_set_compression_per_level(
315 self.inner,
316 level_types.as_mut_ptr(),
317 level_types.len() as size_t,
318 )
319 }
320 }
321
322 /// Maximum size of dictionaries used to prime the compression library.
323 /// Enabling dictionary can improve compression ratios when there are
324 /// repetitions across data blocks.
325 ///
326 /// The dictionary is created by sampling the SST file data. If
327 /// `zstd_max_train_bytes` is nonzero, the samples are passed through zstd's
328 /// dictionary generator. Otherwise, the random samples are used directly as
329 /// the dictionary.
330 ///
331 /// When compression dictionary is disabled, we compress and write each block
332 /// before buffering data for the next one. When compression dictionary is
333 /// enabled, we buffer all SST file data in-memory so we can sample it, as data
334 /// can only be compressed and written after the dictionary has been finalized.
335 /// So users of this feature may see increased memory usage.
336 ///
337 /// Default: `0`
338 ///
339 /// # Example
340 ///
341 /// ```
342 /// use rocksdb::Options;
343 ///
344 /// let mut opts = Options::default();
345 /// opts.set_compression_options(4, 5, 6, 7);
346 /// ```
347 pub fn set_compression_options(
348 &mut self,
349 w_bits: c_int,
350 level: c_int,
351 strategy: c_int,
352 max_dict_bytes: c_int,
353 ) {
354 unsafe {
355 ffi::rocksdb_options_set_compression_options(
356 self.inner,
357 w_bits,
358 level,
359 strategy,
360 max_dict_bytes,
361 );
362 }
363 }
364
365 /// If non-zero, we perform bigger reads when doing compaction. If you're
366 /// running RocksDB on spinning disks, you should set this to at least 2MB.
367 /// That way RocksDB's compaction is doing sequential instead of random reads.
368 ///
369 /// When non-zero, we also force new_table_reader_for_compaction_inputs to
370 /// true.
371 ///
372 /// Default: `0`
373 pub fn set_compaction_readahead_size(&mut self, compaction_readahead_size: usize) {
374 unsafe {
375 ffi::rocksdb_options_compaction_readahead_size(
376 self.inner,
377 compaction_readahead_size as usize,
378 );
379 }
380 }
381
382 /// Allow RocksDB to pick dynamic base of bytes for levels.
383 /// With this feature turned on, RocksDB will automatically adjust max bytes for each level.
384 /// The goal of this feature is to have lower bound on size amplification.
385 ///
386 /// Default: false.
387 pub fn set_level_compaction_dynamic_level_bytes(&mut self, v: bool) {
388 unsafe {
389 ffi::rocksdb_options_set_level_compaction_dynamic_level_bytes(self.inner, v as c_uchar);
390 }
391 }
392
393 pub fn set_merge_operator(
394 &mut self,
395 name: &str,
396 full_merge_fn: MergeFn,
397 partial_merge_fn: Option<MergeFn>,
398 ) {
399 let cb = Box::new(MergeOperatorCallback {
400 name: CString::new(name.as_bytes()).unwrap(),
401 full_merge_fn,
402 partial_merge_fn: partial_merge_fn.unwrap_or(full_merge_fn),
403 });
404
405 unsafe {
406 let mo = ffi::rocksdb_mergeoperator_create(
407 mem::transmute(cb),
408 Some(merge_operator::destructor_callback),
409 Some(full_merge_callback),
410 Some(partial_merge_callback),
411 None,
412 Some(merge_operator::name_callback),
413 );
414 ffi::rocksdb_options_set_merge_operator(self.inner, mo);
415 }
416 }
417
418 #[deprecated(
419 since = "0.5.0",
420 note = "add_merge_operator has been renamed to set_merge_operator"
421 )]
422 pub fn add_merge_operator(&mut self, name: &str, merge_fn: MergeFn) {
423 self.set_merge_operator(name, merge_fn, None);
424 }
425
426 /// Sets a compaction filter used to determine if entries should be kept, changed,
427 /// or removed during compaction.
428 ///
429 /// An example use case is to remove entries with an expired TTL.
430 ///
431 /// If you take a snapshot of the database, only values written since the last
432 /// snapshot will be passed through the compaction filter.
433 ///
434 /// If multi-threaded compaction is used, `filter_fn` may be called multiple times
435 /// simultaneously.
436 pub fn set_compaction_filter<F>(&mut self, name: &str, filter_fn: F)
437 where
438 F: CompactionFilterFn + Send + 'static,
439 {
440 let cb = Box::new(CompactionFilterCallback {
441 name: CString::new(name.as_bytes()).unwrap(),
442 filter_fn,
443 });
444
445 unsafe {
446 let cf = ffi::rocksdb_compactionfilter_create(
447 mem::transmute(cb),
448 Some(compaction_filter::destructor_callback::<F>),
449 Some(filter_callback::<F>),
450 Some(compaction_filter::name_callback::<F>),
451 );
452 ffi::rocksdb_options_set_compaction_filter(self.inner, cf);
453 }
454 }
455
456 /// Sets the comparator used to define the order of keys in the table.
457 /// Default: a comparator that uses lexicographic byte-wise ordering
458 ///
459 /// The client must ensure that the comparator supplied here has the same
460 /// name and orders keys *exactly* the same as the comparator provided to
461 /// previous open calls on the same DB.
462 pub fn set_comparator(&mut self, name: &str, compare_fn: CompareFn) {
463 let cb = Box::new(ComparatorCallback {
464 name: CString::new(name.as_bytes()).unwrap(),
465 f: compare_fn,
466 });
467
468 unsafe {
469 let cmp = ffi::rocksdb_comparator_create(
470 mem::transmute(cb),
471 Some(comparator::destructor_callback),
472 Some(comparator::compare_callback),
473 Some(comparator::name_callback),
474 );
475 ffi::rocksdb_options_set_comparator(self.inner, cmp);
476 }
477 }
478
479 pub fn set_prefix_extractor(&mut self, prefix_extractor: SliceTransform) {
480 unsafe { ffi::rocksdb_options_set_prefix_extractor(self.inner, prefix_extractor.inner) }
481 }
482
483 #[deprecated(
484 since = "0.5.0",
485 note = "add_comparator has been renamed to set_comparator"
486 )]
487 pub fn add_comparator(&mut self, name: &str, compare_fn: CompareFn) {
488 self.set_comparator(name, compare_fn);
489 }
490
491 pub fn optimize_for_point_lookup(&mut self, cache_size: u64) {
492 unsafe {
493 ffi::rocksdb_options_optimize_for_point_lookup(self.inner, cache_size);
494 }
495 }
496
497 /// Sets the optimize_filters_for_hits flag
498 ///
499 /// Default: `false`
500 ///
501 /// # Example
502 ///
503 /// ```
504 /// use rocksdb::Options;
505 ///
506 /// let mut opts = Options::default();
507 /// opts.set_optimize_filters_for_hits(true);
508 /// ```
509 pub fn set_optimize_filters_for_hits(&mut self, optimize_for_hits: bool) {
510 unsafe {
511 ffi::rocksdb_options_set_optimize_filters_for_hits(
512 self.inner,
513 optimize_for_hits as c_int,
514 );
515 }
516 }
517
518 /// Sets the number of open files that can be used by the DB. You may need to
519 /// increase this if your database has a large working set. Value `-1` means
520 /// files opened are always kept open. You can estimate number of files based
521 /// on target_file_size_base and target_file_size_multiplier for level-based
522 /// compaction. For universal-style compaction, you can usually set it to `-1`.
523 ///
524 /// Default: `-1`
525 ///
526 /// # Example
527 ///
528 /// ```
529 /// use rocksdb::Options;
530 ///
531 /// let mut opts = Options::default();
532 /// opts.set_max_open_files(10);
533 /// ```
534 pub fn set_max_open_files(&mut self, nfiles: c_int) {
535 unsafe {
536 ffi::rocksdb_options_set_max_open_files(self.inner, nfiles);
537 }
538 }
539
540 /// If true, then every store to stable storage will issue a fsync.
541 /// If false, then every store to stable storage will issue a fdatasync.
542 /// This parameter should be set to true while storing data to
543 /// filesystem like ext3 that can lose files after a reboot.
544 ///
545 /// Default: `false`
546 ///
547 /// # Example
548 ///
549 /// ```
550 /// use rocksdb::Options;
551 ///
552 /// let mut opts = Options::default();
553 /// opts.set_use_fsync(true);
554 /// ```
555 pub fn set_use_fsync(&mut self, useit: bool) {
556 unsafe { ffi::rocksdb_options_set_use_fsync(self.inner, useit as c_int) }
557 }
558
559 /// Allows OS to incrementally sync files to disk while they are being
560 /// written, asynchronously, in the background. This operation can be used
561 /// to smooth out write I/Os over time. Users shouldn't rely on it for
562 /// persistency guarantee.
563 /// Issue one request for every bytes_per_sync written. `0` turns it off.
564 ///
565 /// Default: `0`
566 ///
567 /// You may consider using rate_limiter to regulate write rate to device.
568 /// When rate limiter is enabled, it automatically enables bytes_per_sync
569 /// to 1MB.
570 ///
571 /// This option applies to table files
572 ///
573 /// # Example
574 ///
575 /// ```
576 /// use rocksdb::Options;
577 ///
578 /// let mut opts = Options::default();
579 /// opts.set_bytes_per_sync(1024 * 1024);
580 /// ```
581 pub fn set_bytes_per_sync(&mut self, nbytes: u64) {
582 unsafe {
583 ffi::rocksdb_options_set_bytes_per_sync(self.inner, nbytes);
584 }
585 }
586
587 /// If true, allow multi-writers to update mem tables in parallel.
588 /// Only some memtable_factory-s support concurrent writes; currently it
589 /// is implemented only for SkipListFactory. Concurrent memtable writes
590 /// are not compatible with inplace_update_support or filter_deletes.
591 /// It is strongly recommended to set enable_write_thread_adaptive_yield
592 /// if you are going to use this feature.
593 ///
594 /// Default: true
595 ///
596 /// # Example
597 ///
598 /// ```
599 /// use rocksdb::Options;
600 ///
601 /// let mut opts = Options::default();
602 /// opts.set_allow_concurrent_memtable_write(false);
603 /// ```
604 pub fn set_allow_concurrent_memtable_write(&mut self, allow: bool) {
605 unsafe {
606 ffi::rocksdb_options_set_allow_concurrent_memtable_write(self.inner, allow as c_uchar)
607 }
608 }
609
610 /// Enable direct I/O mode for reading
611 /// they may or may not improve performance depending on the use case
612 ///
613 /// Files will be opened in "direct I/O" mode
614 /// which means that data read from the disk will not be cached or
615 /// buffered. The hardware buffer of the devices may however still
616 /// be used. Memory mapped files are not impacted by these parameters.
617 ///
618 /// Default: false
619 ///
620 /// # Example
621 ///
622 /// ```
623 /// use rocksdb::Options;
624 ///
625 /// let mut opts = Options::default();
626 /// opts.set_use_direct_reads(true);
627 /// ```
628 pub fn set_use_direct_reads(&mut self, enabled: bool) {
629 unsafe {
630 ffi::rocksdb_options_set_use_direct_reads(self.inner, enabled as c_uchar);
631 }
632 }
633
634 /// Enable direct I/O mode for flush and compaction
635 ///
636 /// Files will be opened in "direct I/O" mode
637 /// which means that data written to the disk will not be cached or
638 /// buffered. The hardware buffer of the devices may however still
639 /// be used. Memory mapped files are not impacted by these parameters.
640 /// they may or may not improve performance depending on the use case
641 ///
642 /// Default: false
643 ///
644 /// # Example
645 ///
646 /// ```
647 /// use rocksdb::Options;
648 ///
649 /// let mut opts = Options::default();
650 /// opts.set_use_direct_io_for_flush_and_compaction(true);
651 /// ```
652 pub fn set_use_direct_io_for_flush_and_compaction(&mut self, enabled: bool) {
653 unsafe {
654 ffi::rocksdb_options_set_use_direct_io_for_flush_and_compaction(
655 self.inner,
656 enabled as c_uchar,
657 );
658 }
659 }
660
661 /// Hints to the OS that it should not buffer disk I/O. Enabling this
662 /// parameter may improve performance but increases pressure on the
663 /// system cache.
664 ///
665 /// The exact behavior of this parameter is platform dependent.
666 ///
667 /// On POSIX systems, after RocksDB reads data from disk it will
668 /// mark the pages as "unneeded". The operating system may - or may not
669 /// - evict these pages from memory, reducing pressure on the system
670 /// cache. If the disk block is requested again this can result in
671 /// additional disk I/O.
672 ///
673 /// On WINDOWS systems, files will be opened in "unbuffered I/O" mode
674 /// which means that data read from the disk will not be cached or
675 /// bufferized. The hardware buffer of the devices may however still
676 /// be used. Memory mapped files are not impacted by this parameter.
677 ///
678 /// Default: true
679 ///
680 /// # Example
681 ///
682 /// ```
683 /// #[allow(deprecated)]
684 /// use rocksdb::Options;
685 ///
686 /// let mut opts = Options::default();
687 /// opts.set_allow_os_buffer(false);
688 /// ```
689 #[deprecated(
690 since = "0.7.0",
691 note = "replaced with set_use_direct_reads/set_use_direct_io_for_flush_and_compaction methods"
692 )]
693 pub fn set_allow_os_buffer(&mut self, is_allow: bool) {
694 self.set_use_direct_reads(!is_allow);
695 self.set_use_direct_io_for_flush_and_compaction(!is_allow);
696 }
697
698 /// Sets the number of shards used for table cache.
699 ///
700 /// Default: `6`
701 ///
702 /// # Example
703 ///
704 /// ```
705 /// use rocksdb::Options;
706 ///
707 /// let mut opts = Options::default();
708 /// opts.set_table_cache_num_shard_bits(4);
709 /// ```
710 pub fn set_table_cache_num_shard_bits(&mut self, nbits: c_int) {
711 unsafe {
712 ffi::rocksdb_options_set_table_cache_numshardbits(self.inner, nbits);
713 }
714 }
715
716 /// Sets the minimum number of write buffers that will be merged together
717 /// before writing to storage. If set to `1`, then
718 /// all write buffers are flushed to L0 as individual files and this increases
719 /// read amplification because a get request has to check in all of these
720 /// files. Also, an in-memory merge may result in writing lesser
721 /// data to storage if there are duplicate records in each of these
722 /// individual write buffers.
723 ///
724 /// Default: `1`
725 ///
726 /// # Example
727 ///
728 /// ```
729 /// use rocksdb::Options;
730 ///
731 /// let mut opts = Options::default();
732 /// opts.set_min_write_buffer_number(2);
733 /// ```
734 pub fn set_min_write_buffer_number(&mut self, nbuf: c_int) {
735 unsafe {
736 ffi::rocksdb_options_set_min_write_buffer_number_to_merge(self.inner, nbuf);
737 }
738 }
739
740 /// Sets the maximum number of write buffers that are built up in memory.
741 /// The default and the minimum number is 2, so that when 1 write buffer
742 /// is being flushed to storage, new writes can continue to the other
743 /// write buffer.
744 /// If max_write_buffer_number > 3, writing will be slowed down to
745 /// options.delayed_write_rate if we are writing to the last write buffer
746 /// allowed.
747 ///
748 /// Default: `2`
749 ///
750 /// # Example
751 ///
752 /// ```
753 /// use rocksdb::Options;
754 ///
755 /// let mut opts = Options::default();
756 /// opts.set_max_write_buffer_number(4);
757 /// ```
758 pub fn set_max_write_buffer_number(&mut self, nbuf: c_int) {
759 unsafe {
760 ffi::rocksdb_options_set_max_write_buffer_number(self.inner, nbuf);
761 }
762 }
763
764 /// Sets the amount of data to build up in memory (backed by an unsorted log
765 /// on disk) before converting to a sorted on-disk file.
766 ///
767 /// Larger values increase performance, especially during bulk loads.
768 /// Up to max_write_buffer_number write buffers may be held in memory
769 /// at the same time,
770 /// so you may wish to adjust this parameter to control memory usage.
771 /// Also, a larger write buffer will result in a longer recovery time
772 /// the next time the database is opened.
773 ///
774 /// Note that write_buffer_size is enforced per column family.
775 /// See db_write_buffer_size for sharing memory across column families.
776 ///
777 /// Default: `0x4000000` (64MiB)
778 ///
779 /// Dynamically changeable through SetOptions() API
780 ///
781 /// # Example
782 ///
783 /// ```
784 /// use rocksdb::Options;
785 ///
786 /// let mut opts = Options::default();
787 /// opts.set_write_buffer_size(128 * 1024 * 1024);
788 /// ```
789 pub fn set_write_buffer_size(&mut self, size: usize) {
790 unsafe {
791 ffi::rocksdb_options_set_write_buffer_size(self.inner, size);
792 }
793 }
794
795 /// Amount of data to build up in memtables across all column
796 /// families before writing to disk.
797 ///
798 /// This is distinct from write_buffer_size, which enforces a limit
799 /// for a single memtable.
800 ///
801 /// This feature is disabled by default. Specify a non-zero value
802 /// to enable it.
803 ///
804 /// Default: 0 (disabled)
805 ///
806 /// # Example
807 ///
808 /// ```
809 /// use rocksdb::Options;
810 ///
811 /// let mut opts = Options::default();
812 /// opts.set_db_write_buffer_size(128 * 1024 * 1024);
813 /// ```
814 pub fn set_db_write_buffer_size(&mut self, size: usize) {
815 unsafe {
816 ffi::rocksdb_options_set_db_write_buffer_size(self.inner, size);
817 }
818 }
819
820 /// Control maximum total data size for a level.
821 /// max_bytes_for_level_base is the max total for level-1.
822 /// Maximum number of bytes for level L can be calculated as
823 /// (max_bytes_for_level_base) * (max_bytes_for_level_multiplier ^ (L-1))
824 /// For example, if max_bytes_for_level_base is 200MB, and if
825 /// max_bytes_for_level_multiplier is 10, total data size for level-1
826 /// will be 200MB, total file size for level-2 will be 2GB,
827 /// and total file size for level-3 will be 20GB.
828 ///
829 /// Default: `0x10000000` (256MiB).
830 ///
831 /// Dynamically changeable through SetOptions() API
832 ///
833 /// # Example
834 ///
835 /// ```
836 /// use rocksdb::Options;
837 ///
838 /// let mut opts = Options::default();
839 /// opts.set_max_bytes_for_level_base(512 * 1024 * 1024);
840 /// ```
841 pub fn set_max_bytes_for_level_base(&mut self, size: u64) {
842 unsafe {
843 ffi::rocksdb_options_set_max_bytes_for_level_base(self.inner, size);
844 }
845 }
846
847 /// Default: `10`
848 ///
849 /// # Example
850 ///
851 /// ```
852 /// use rocksdb::Options;
853 ///
854 /// let mut opts = Options::default();
855 /// opts.set_max_bytes_for_level_multiplier(4.0);
856 /// ```
857 pub fn set_max_bytes_for_level_multiplier(&mut self, mul: f64) {
858 unsafe {
859 ffi::rocksdb_options_set_max_bytes_for_level_multiplier(self.inner, mul);
860 }
861 }
862
863 /// The manifest file is rolled over on reaching this limit.
864 /// The older manifest file be deleted.
865 /// The default value is MAX_INT so that roll-over does not take place.
866 ///
867 /// # Example
868 ///
869 /// ```
870 /// use rocksdb::Options;
871 ///
872 /// let mut opts = Options::default();
873 /// opts.set_max_manifest_file_size(20 * 1024 * 1024);
874 /// ```
875 pub fn set_max_manifest_file_size(&mut self, size: usize) {
876 unsafe {
877 ffi::rocksdb_options_set_max_manifest_file_size(self.inner, size);
878 }
879 }
880
881 /// Sets the target file size for compaction.
882 /// target_file_size_base is per-file size for level-1.
883 /// Target file size for level L can be calculated by
884 /// target_file_size_base * (target_file_size_multiplier ^ (L-1))
885 /// For example, if target_file_size_base is 2MB and
886 /// target_file_size_multiplier is 10, then each file on level-1 will
887 /// be 2MB, and each file on level 2 will be 20MB,
888 /// and each file on level-3 will be 200MB.
889 ///
890 /// Default: `0x4000000` (64MiB)
891 ///
892 /// Dynamically changeable through SetOptions() API
893 ///
894 /// # Example
895 ///
896 /// ```
897 /// use rocksdb::Options;
898 ///
899 /// let mut opts = Options::default();
900 /// opts.set_target_file_size_base(128 * 1024 * 1024);
901 /// ```
902 pub fn set_target_file_size_base(&mut self, size: u64) {
903 unsafe {
904 ffi::rocksdb_options_set_target_file_size_base(self.inner, size);
905 }
906 }
907
908 /// Sets the minimum number of write buffers that will be merged together
909 /// before writing to storage. If set to `1`, then
910 /// all write buffers are flushed to L0 as individual files and this increases
911 /// read amplification because a get request has to check in all of these
912 /// files. Also, an in-memory merge may result in writing lesser
913 /// data to storage if there are duplicate records in each of these
914 /// individual write buffers.
915 ///
916 /// Default: `1`
917 ///
918 /// # Example
919 ///
920 /// ```
921 /// use rocksdb::Options;
922 ///
923 /// let mut opts = Options::default();
924 /// opts.set_min_write_buffer_number_to_merge(2);
925 /// ```
926 pub fn set_min_write_buffer_number_to_merge(&mut self, to_merge: c_int) {
927 unsafe {
928 ffi::rocksdb_options_set_min_write_buffer_number_to_merge(self.inner, to_merge);
929 }
930 }
931
932 /// Sets the number of files to trigger level-0 compaction. A value < `0` means that
933 /// level-0 compaction will not be triggered by number of files at all.
934 ///
935 /// Default: `4`
936 ///
937 /// Dynamically changeable through SetOptions() API
938 ///
939 /// # Example
940 ///
941 /// ```
942 /// use rocksdb::Options;
943 ///
944 /// let mut opts = Options::default();
945 /// opts.set_level_zero_file_num_compaction_trigger(8);
946 /// ```
947 pub fn set_level_zero_file_num_compaction_trigger(&mut self, n: c_int) {
948 unsafe {
949 ffi::rocksdb_options_set_level0_file_num_compaction_trigger(self.inner, n);
950 }
951 }
952
953 /// Sets the soft limit on number of level-0 files. We start slowing down writes at this
954 /// point. A value < `0` means that no writing slow down will be triggered by
955 /// number of files in level-0.
956 ///
957 /// Default: `20`
958 ///
959 /// Dynamically changeable through SetOptions() API
960 ///
961 /// # Example
962 ///
963 /// ```
964 /// use rocksdb::Options;
965 ///
966 /// let mut opts = Options::default();
967 /// opts.set_level_zero_slowdown_writes_trigger(10);
968 /// ```
969 pub fn set_level_zero_slowdown_writes_trigger(&mut self, n: c_int) {
970 unsafe {
971 ffi::rocksdb_options_set_level0_slowdown_writes_trigger(self.inner, n);
972 }
973 }
974
975 /// Sets the maximum number of level-0 files. We stop writes at this point.
976 ///
977 /// Default: `24`
978 ///
979 /// Dynamically changeable through SetOptions() API
980 ///
981 /// # Example
982 ///
983 /// ```
984 /// use rocksdb::Options;
985 ///
986 /// let mut opts = Options::default();
987 /// opts.set_level_zero_stop_writes_trigger(48);
988 /// ```
989 pub fn set_level_zero_stop_writes_trigger(&mut self, n: c_int) {
990 unsafe {
991 ffi::rocksdb_options_set_level0_stop_writes_trigger(self.inner, n);
992 }
993 }
994
995 /// Sets the compaction style.
996 ///
997 /// Default: DBCompactionStyle::Level
998 ///
999 /// # Example
1000 ///
1001 /// ```
1002 /// use rocksdb::{Options, DBCompactionStyle};
1003 ///
1004 /// let mut opts = Options::default();
1005 /// opts.set_compaction_style(DBCompactionStyle::Universal);
1006 /// ```
1007 pub fn set_compaction_style(&mut self, style: DBCompactionStyle) {
1008 unsafe {
1009 ffi::rocksdb_options_set_compaction_style(self.inner, style as c_int);
1010 }
1011 }
1012
1013 /// Sets the maximum number of concurrent background compaction jobs, submitted to
1014 /// the default LOW priority thread pool.
1015 /// We first try to schedule compactions based on
1016 /// `base_background_compactions`. If the compaction cannot catch up , we
1017 /// will increase number of compaction threads up to
1018 /// `max_background_compactions`.
1019 ///
1020 /// If you're increasing this, also consider increasing number of threads in
1021 /// LOW priority thread pool. For more information, see
1022 /// Env::SetBackgroundThreads
1023 ///
1024 /// Default: `1`
1025 ///
1026 /// # Example
1027 ///
1028 /// ```
1029 /// use rocksdb::Options;
1030 ///
1031 /// let mut opts = Options::default();
1032 /// opts.set_max_background_compactions(2);
1033 /// ```
1034 pub fn set_max_background_compactions(&mut self, n: c_int) {
1035 unsafe {
1036 ffi::rocksdb_options_set_max_background_compactions(self.inner, n);
1037 }
1038 }
1039
1040 /// Sets the maximum number of concurrent background memtable flush jobs, submitted to
1041 /// the HIGH priority thread pool.
1042 ///
1043 /// By default, all background jobs (major compaction and memtable flush) go
1044 /// to the LOW priority pool. If this option is set to a positive number,
1045 /// memtable flush jobs will be submitted to the HIGH priority pool.
1046 /// It is important when the same Env is shared by multiple db instances.
1047 /// Without a separate pool, long running major compaction jobs could
1048 /// potentially block memtable flush jobs of other db instances, leading to
1049 /// unnecessary Put stalls.
1050 ///
1051 /// If you're increasing this, also consider increasing number of threads in
1052 /// HIGH priority thread pool. For more information, see
1053 /// Env::SetBackgroundThreads
1054 ///
1055 /// Default: `1`
1056 ///
1057 /// # Example
1058 ///
1059 /// ```
1060 /// use rocksdb::Options;
1061 ///
1062 /// let mut opts = Options::default();
1063 /// opts.set_max_background_flushes(2);
1064 /// ```
1065 pub fn set_max_background_flushes(&mut self, n: c_int) {
1066 unsafe {
1067 ffi::rocksdb_options_set_max_background_flushes(self.inner, n);
1068 }
1069 }
1070
1071 /// Disables automatic compactions. Manual compactions can still
1072 /// be issued on this column family
1073 ///
1074 /// Default: `false`
1075 ///
1076 /// Dynamically changeable through SetOptions() API
1077 ///
1078 /// # Example
1079 ///
1080 /// ```
1081 /// use rocksdb::Options;
1082 ///
1083 /// let mut opts = Options::default();
1084 /// opts.set_disable_auto_compactions(true);
1085 /// ```
1086 pub fn set_disable_auto_compactions(&mut self, disable: bool) {
1087 unsafe { ffi::rocksdb_options_set_disable_auto_compactions(self.inner, disable as c_int) }
1088 }
1089
1090 /// Defines the underlying memtable implementation.
1091 /// See https://github.com/facebook/rocksdb/wiki/MemTable for more information.
1092 /// Defaults to using a skiplist.
1093 ///
1094 /// # Example
1095 ///
1096 /// ```
1097 /// use rocksdb::{Options, MemtableFactory};
1098 /// let mut opts = Options::default();
1099 /// let factory = MemtableFactory::HashSkipList {
1100 /// bucket_count: 1_000_000,
1101 /// height: 4,
1102 /// branching_factor: 4,
1103 /// };
1104 ///
1105 /// opts.set_allow_concurrent_memtable_write(false);
1106 /// opts.set_memtable_factory(factory);
1107 /// ```
1108 pub fn set_memtable_factory(&mut self, factory: MemtableFactory) {
1109 match factory {
1110 MemtableFactory::Vector => unsafe {
1111 ffi::rocksdb_options_set_memtable_vector_rep(self.inner);
1112 },
1113 MemtableFactory::HashSkipList {
1114 bucket_count,
1115 height,
1116 branching_factor,
1117 } => unsafe {
1118 ffi::rocksdb_options_set_hash_skip_list_rep(
1119 self.inner,
1120 bucket_count,
1121 height,
1122 branching_factor,
1123 );
1124 },
1125 MemtableFactory::HashLinkList { bucket_count } => unsafe {
1126 ffi::rocksdb_options_set_hash_link_list_rep(self.inner, bucket_count);
1127 },
1128 };
1129 }
1130
1131 pub fn set_block_based_table_factory(&mut self, factory: &BlockBasedOptions) {
1132 unsafe {
1133 ffi::rocksdb_options_set_block_based_table_factory(self.inner, factory.inner);
1134 }
1135 }
1136
1137 /// See https://github.com/facebook/rocksdb/wiki/PlainTable-Format.
1138 ///
1139 /// ```
1140 /// use rocksdb::{Options, PlainTableFactoryOptions};
1141 ///
1142 /// let mut opts = Options::default();
1143 /// let factory_opts = PlainTableFactoryOptions {
1144 /// user_key_length: 0,
1145 /// bloom_bits_per_key: 20,
1146 /// hash_table_ratio: 0.75,
1147 /// index_sparseness: 16,
1148 /// };
1149 ///
1150 /// opts.set_plain_table_factory(&factory_opts);
1151 /// ```
1152 pub fn set_plain_table_factory(&mut self, options: &PlainTableFactoryOptions) {
1153 unsafe {
1154 ffi::rocksdb_options_set_plain_table_factory(
1155 self.inner,
1156 options.user_key_length,
1157 options.bloom_bits_per_key,
1158 options.hash_table_ratio,
1159 options.index_sparseness,
1160 );
1161 }
1162 }
1163
1164 /// Measure IO stats in compactions and flushes, if `true`.
1165 ///
1166 /// Default: `false`
1167 ///
1168 /// # Example
1169 ///
1170 /// ```
1171 /// use rocksdb::Options;
1172 ///
1173 /// let mut opts = Options::default();
1174 /// opts.set_report_bg_io_stats(true);
1175 /// ```
1176 pub fn set_report_bg_io_stats(&mut self, enable: bool) {
1177 unsafe {
1178 ffi::rocksdb_options_set_report_bg_io_stats(self.inner, enable as c_int);
1179 }
1180 }
1181
1182 /// Once write-ahead logs exceed this size, we will start forcing the flush of
1183 /// column families whose memtables are backed by the oldest live WAL file
1184 /// (i.e. the ones that are causing all the space amplification).
1185 ///
1186 /// Default: `0`
1187 ///
1188 /// # Example
1189 ///
1190 /// ```
1191 /// use rocksdb::Options;
1192 ///
1193 /// let mut opts = Options::default();
1194 /// // Set max total wal size to 1G.
1195 /// opts.set_max_total_wal_size(1 << 30);
1196 /// ```
1197 pub fn set_max_total_wal_size(&mut self, size: u64) {
1198 unsafe {
1199 ffi::rocksdb_options_set_max_total_wal_size(self.inner, size);
1200 }
1201 }
1202
1203 /// Recovery mode to control the consistency while replaying WAL.
1204 ///
1205 /// Default: DBRecoveryMode::PointInTime
1206 ///
1207 /// # Example
1208 ///
1209 /// ```
1210 /// use rocksdb::{Options, DBRecoveryMode};
1211 ///
1212 /// let mut opts = Options::default();
1213 /// opts.set_wal_recovery_mode(DBRecoveryMode::AbsoluteConsistency);
1214 /// ```
1215 pub fn set_wal_recovery_mode(&mut self, mode: DBRecoveryMode) {
1216 unsafe {
1217 ffi::rocksdb_options_set_wal_recovery_mode(self.inner, mode as c_int);
1218 }
1219 }
1220
1221 pub fn enable_statistics(&mut self) {
1222 unsafe {
1223 ffi::rocksdb_options_enable_statistics(self.inner);
1224 }
1225 }
1226
1227 pub fn get_statistics(&self) -> Option<String> {
1228 unsafe {
1229 let value = ffi::rocksdb_options_statistics_get_string(self.inner);
1230 if value.is_null() {
1231 return None;
1232 }
1233
1234 // Must have valid UTF-8 format.
1235 let s = CStr::from_ptr(value).to_str().unwrap().to_owned();
1236 libc::free(value as *mut c_void);
1237 Some(s)
1238 }
1239 }
1240
1241 /// If not zero, dump `rocksdb.stats` to LOG every `stats_dump_period_sec`.
1242 ///
1243 /// Default: `600` (10 mins)
1244 ///
1245 /// # Example
1246 ///
1247 /// ```
1248 /// use rocksdb::Options;
1249 ///
1250 /// let mut opts = Options::default();
1251 /// opts.set_stats_dump_period_sec(300);
1252 /// ```
1253 pub fn set_stats_dump_period_sec(&mut self, period: c_uint) {
1254 unsafe {
1255 ffi::rocksdb_options_set_stats_dump_period_sec(self.inner, period);
1256 }
1257 }
1258
1259 /// When set to true, reading SST files will opt out of the filesystem's
1260 /// readahead. Setting this to false may improve sequential iteration
1261 /// performance.
1262 ///
1263 /// Default: `true`
1264 pub fn set_advise_random_on_open(&mut self, advise: bool) {
1265 unsafe { ffi::rocksdb_options_set_advise_random_on_open(self.inner, advise as c_uchar) }
1266 }
1267
1268 /// Sets the number of levels for this database.
1269 pub fn set_num_levels(&mut self, n: c_int) {
1270 unsafe {
1271 ffi::rocksdb_options_set_num_levels(self.inner, n);
1272 }
1273 }
1274
1275 /// When a `prefix_extractor` is defined through `opts.set_prefix_extractor` this
1276 /// creates a prefix bloom filter for each memtable with the size of
1277 /// `write_buffer_size * memtable_prefix_bloom_ratio` (capped at 0.25).
1278 ///
1279 /// Default: `0`
1280 ///
1281 /// # Example
1282 ///
1283 /// ```
1284 /// use rocksdb::{Options, SliceTransform};
1285 ///
1286 /// let mut opts = Options::default();
1287 /// let transform = SliceTransform::create_fixed_prefix(10);
1288 /// opts.set_prefix_extractor(transform);
1289 /// opts.set_memtable_prefix_bloom_ratio(0.2);
1290 /// ```
1291 pub fn set_memtable_prefix_bloom_ratio(&mut self, ratio: f64) {
1292 unsafe {
1293 ffi::rocksdb_options_set_memtable_prefix_bloom_size_ratio(self.inner, ratio);
1294 }
1295 }
1296
1297 /// Specifies the absolute path of the directory the
1298 /// write-ahead log (WAL) should be written to.
1299 ///
1300 /// Default: same directory as the database
1301 ///
1302 /// # Example
1303 ///
1304 /// ```
1305 /// use rocksdb::Options;
1306 ///
1307 /// let mut opts = Options::default();
1308 /// opts.set_wal_dir("/path/to/dir");
1309 /// ```
1310 pub fn set_wal_dir<P: AsRef<Path>>(&mut self, path: P) {
1311 let p = CString::new(path.as_ref().to_string_lossy().as_bytes()).unwrap();
1312 unsafe {
1313 ffi::rocksdb_options_set_wal_dir(self.inner, p.as_ptr());
1314 }
1315 }
1316
1317 /// If true, then DB::Open() will not update the statistics used to optimize
1318 /// compaction decision by loading table properties from many files.
1319 /// Turning off this feature will improve DBOpen time especially in disk environment.
1320 ///
1321 /// Default: false
1322 pub fn set_skip_stats_update_on_db_open(&mut self, skip: bool) {
1323 unsafe {
1324 ffi::rocksdb_options_set_skip_stats_update_on_db_open(self.inner, skip as c_uchar);
1325 }
1326 }
1327
1328 /// Specify the maximal number of info log files to be kept.
1329 pub fn set_keep_log_file_num(&mut self, nfiles: usize) {
1330 unsafe {
1331 ffi::rocksdb_options_set_keep_log_file_num(self.inner, nfiles);
1332 }
1333 }
1334
1335 /// Allow the OS to mmap file for writing.
1336 ///
1337 /// Default: false
1338 ///
1339 /// # Example
1340 ///
1341 /// ```
1342 /// use rocksdb::Options;
1343 ///
1344 /// let mut options = Options::default();
1345 /// options.set_allow_mmap_writes(true);
1346 /// ```
1347 pub fn set_allow_mmap_writes(&mut self, is_enabled: bool) {
1348 unsafe {
1349 ffi::rocksdb_options_set_allow_mmap_writes(self.inner, is_enabled as c_uchar);
1350 }
1351 }
1352
1353 /// Allow the OS to mmap file for reading sst tables.
1354 ///
1355 /// Default: false
1356 ///
1357 /// # Example
1358 ///
1359 /// ```
1360 /// use rocksdb::Options;
1361 ///
1362 /// let mut options = Options::default();
1363 /// options.set_allow_mmap_reads(true);
1364 /// ```
1365 pub fn set_allow_mmap_reads(&mut self, is_enabled: bool) {
1366 unsafe {
1367 ffi::rocksdb_options_set_allow_mmap_reads(self.inner, is_enabled as c_uchar);
1368 }
1369 }
1370
1371 /// Guarantee that all column families are flushed together atomically.
1372 /// This option applies to both manual flushes (`db.flush()`) and automatic
1373 /// background flushes caused when memtables are filled.
1374 ///
1375 /// Default: false
1376 ///
1377 /// # Example
1378 ///
1379 /// ```
1380 /// use rocksdb::Options;
1381 ///
1382 /// let mut options = Options::default();
1383 /// options.set_atomic_flush(true);
1384 /// ```
1385 pub fn set_atomic_flush(&mut self, atomic_flush: bool) {
1386 unsafe {
1387 ffi::rocksdb_options_set_atomic_flush(self.inner, atomic_flush as c_uchar);
1388 }
1389 }
1390
1391 /// Use to control write rate of flush and compaction. Flush has higher
1392 /// priority than compaction.
1393 /// If rate limiter is enabled, bytes_per_sync is set to 1MB by default.
1394 ///
1395 /// Default: disable
1396 ///
1397 /// # Example
1398 ///
1399 /// ```
1400 /// use rocksdb::Options;
1401 ///
1402 /// let mut options = Options::default();
1403 /// options.set_ratelimiter(1024 * 1024, 100 * 1000, 10);
1404 /// ```
1405 pub fn set_ratelimiter(
1406 &mut self,
1407 rate_bytes_per_sec: i64,
1408 refill_period_us: i64,
1409 fairness: i32,
1410 ) {
1411 unsafe {
1412 let ratelimiter =
1413 ffi::rocksdb_ratelimiter_create(rate_bytes_per_sec, refill_period_us, fairness);
1414 // Since limiter is wrapped in shared_ptr, we don't need to
1415 // call rocksdb_ratelimiter_destroy explicitly.
1416 ffi::rocksdb_options_set_ratelimiter(self.inner, ratelimiter);
1417 }
1418 }
1419}
1420
1421impl Default for Options {
1422 fn default() -> Options {
1423 unsafe {
1424 let opts = ffi::rocksdb_options_create();
1425 if opts.is_null() {
1426 panic!("Could not create RocksDB options");
1427 }
1428 Options { inner: opts }
1429 }
1430 }
1431}
1432
1433impl FlushOptions {
1434 pub fn new() -> FlushOptions {
1435 FlushOptions::default()
1436 }
1437
1438 /// Waits until the flush is done.
1439 ///
1440 /// Default: true
1441 ///
1442 /// # Example
1443 ///
1444 /// ```
1445 /// use rocksdb::FlushOptions;
1446 ///
1447 /// let mut options = FlushOptions::default();
1448 /// options.set_wait(false);
1449 /// ```
1450 pub fn set_wait(&mut self, wait: bool) {
1451 unsafe {
1452 ffi::rocksdb_flushoptions_set_wait(self.inner, wait as c_uchar);
1453 }
1454 }
1455}
1456
1457impl Default for FlushOptions {
1458 fn default() -> FlushOptions {
1459 let flush_opts = unsafe { ffi::rocksdb_flushoptions_create() };
1460 if flush_opts.is_null() {
1461 panic!("Could not create RocksDB flush options");
1462 }
1463 FlushOptions { inner: flush_opts }
1464 }
1465}
1466
1467impl WriteOptions {
1468 pub fn new() -> WriteOptions {
1469 WriteOptions::default()
1470 }
1471
1472 pub fn set_sync(&mut self, sync: bool) {
1473 unsafe {
1474 ffi::rocksdb_writeoptions_set_sync(self.inner, sync as c_uchar);
1475 }
1476 }
1477
1478 pub fn disable_wal(&mut self, disable: bool) {
1479 unsafe {
1480 ffi::rocksdb_writeoptions_disable_WAL(self.inner, disable as c_int);
1481 }
1482 }
1483}
1484
1485impl Default for WriteOptions {
1486 fn default() -> WriteOptions {
1487 let write_opts = unsafe { ffi::rocksdb_writeoptions_create() };
1488 if write_opts.is_null() {
1489 panic!("Could not create RocksDB write options");
1490 }
1491 WriteOptions { inner: write_opts }
1492 }
1493}
1494
1495#[cfg(test)]
1496mod tests {
1497 use crate::{MemtableFactory, Options};
1498
1499 #[test]
1500 fn test_enable_statistics() {
1501 let mut opts = Options::default();
1502 opts.enable_statistics();
1503 opts.set_stats_dump_period_sec(60);
1504 assert!(opts.get_statistics().is_some());
1505
1506 let opts = Options::default();
1507 assert!(opts.get_statistics().is_none());
1508 }
1509
1510 #[test]
1511 fn test_set_memtable_factory() {
1512 let mut opts = Options::default();
1513 opts.set_memtable_factory(MemtableFactory::Vector);
1514 opts.set_memtable_factory(MemtableFactory::HashLinkList { bucket_count: 100 });
1515 opts.set_memtable_factory(MemtableFactory::HashSkipList {
1516 bucket_count: 100,
1517 height: 4,
1518 branching_factor: 4,
1519 });
1520 }
1521}