persistent_kv/
config.rs

1#[derive(Copy, Clone, PartialEq, Debug)]
2pub enum SyncMode {
3    /// Execute a full sync operation(s) after every single key write. This is
4    /// _very_ slow (~milliseconds) but minimizes risk of data loss. If the local
5    /// process fails, data loss is not possible. In the event of a OS level failure
6    /// or power event, data loss is unlikely but still technically possible e.g.
7    /// if the hardware further delays writes without the OS knowing.
8    /// Note: The implementation uses File::sync_all(), so all caveats from there apply.
9    BlockAndSync,
10
11    /// Blocks on but does not explicitly sync file system operation(s). This is
12    /// reasonably fast (~microseconds). In this mode, calling
13    /// [`super::PersistentKeyValueStore::set`] or
14    /// [`super::PersistentKeyValueStore::unset`] on a key still blocks on the
15    /// syscall to append to the write log. This means that local process failures
16    /// should not lead to data loss. OS level failures or power events are possible
17    /// data loss concerning writes that occured in the seconds prior.
18    BlockNoExplicitSync,
19
20    /// Allows for in-memory buffering of writes before writing to disk. There
21    /// is no limit on the size of frequency of the buffer, so at worst a disk
22    /// write may not occur until the store instance is dropped.
23    Buffered,
24}
25
26#[derive(Clone, PartialEq, Debug)]
27pub struct Config {
28    /// If true, we will not write any snapshot / restore events to stdout.
29    /// By default this is on as such events are rare and will be helpful to spot
30    /// unexpected config or runtime issues.
31    pub silent: bool,
32
33    /// The interval at which full snapshots should be created. The unit counted is the
34    /// number of key-value pairs modified (created, updated or deleted) meaning if
35    /// `snapshot_interval` is 10,000, then a snapshot will be created every 10,000
36    /// key-value pairs modified.
37    ///
38    /// Notes:
39    ///  - Snapshots may be skipped if we cannot keep up with the number of changes.
40    ///  - Snapshots are created asynchronously and do not block reads or writes to
41    ///    the main store (except for a brief lock to create a memory data copy).
42    ///  - Snapshots are not required for the store to have basic persistence
43    ///    guarantees as all modifications are written to a write-ahead log first.
44    ///    However, regular snapshotting compacts the write-ahead log and helps
45    ///      keep disk usage and startup time to be bounded by
46    ///         O(number of keys)
47    ///      rather than
48    ///         O(number of modifications)
49    pub snapshot_interval: u64,
50
51    /// The number of buckets to use for the memory store, each responsible for a part
52    /// of the keyspace. This is a trade-off between memory overhead and contention
53    /// avoidance in multithreaded operation. Each bucket has its own dictionary,
54    /// supporting data structure and mutex.
55    pub memory_bucket_count: usize,
56
57    /// File system synchronization model.
58    pub sync_mode: SyncMode,
59
60    /// The number of threads to use for IO operations. This includes reading and writing
61    /// of snapshots and influences (but not fully determines) number of shards used.
62    pub target_io_parallelism_snapshots: u64,
63
64    /// The number of shards to use for the write log (this is directly the file count used)
65    pub target_io_parallelism_writelog: u64,
66
67    /// The targeted size for a snapshot shard. This is not a hard limit. This number influences
68    /// (but not fully determines) number of shards used for snapshots.
69    pub target_snapshot_shard_size_bytes: usize,
70
71    /// Whether to make use of positioned writes e.g. write_at() instead of seek() + write().
72    /// This uses OS specific extensions and enables higher effective concurrency for writes.
73    pub use_positioned_writes: bool,
74}
75
76impl Default for Config {
77    fn default() -> Config {
78        Self {
79            snapshot_interval: 10000,
80            memory_bucket_count: 32,
81            sync_mode: SyncMode::BlockNoExplicitSync,
82            silent: false,
83            target_io_parallelism_snapshots: 8,
84            target_io_parallelism_writelog: 1,
85            target_snapshot_shard_size_bytes: 1024 * 1024 * 1024, // 1 GB
86
87            #[cfg(target_os = "windows")]
88            use_positioned_writes: false,
89            #[cfg(not(target_os = "windows"))]
90            use_positioned_writes: true,
91        }
92    }
93}