pub struct Options {Show 22 fields
pub sync_on_write: bool,
pub concurrent_write: u8,
pub gc_timeout: u64,
pub checkpoint_nudge_ms: u64,
pub data_garbage_ratio: u32,
pub gc_eager: bool,
pub blob_file_size: usize,
pub blob_garbage_ratio: usize,
pub blob_gc_ratio: usize,
pub tmp_store: bool,
pub log_root: PathBuf,
pub lru_capacity: usize,
pub stat_mask_cache_count: usize,
pub data_handle_cache_capacity: usize,
pub blob_handle_cache_capacity: usize,
pub data_file_size: usize,
pub wal_buffer_size: usize,
pub max_ckpt_per_txn: usize,
pub wal_file_size: u32,
pub keep_stable_wal_file: bool,
pub truncate_corrupted_wal: bool,
pub observer: Arc<dyn Observer>,
/* private fields */
}Expand description
Configuration options for the Mace storage engine.
Fields§
§sync_on_write: boolForce-sync data to disk for every wal/data write.
The default value is true (use fsync or else use fdatasync). Turning it off may result in
data loss, while turning it on may reduce performance.
concurrent_write: u8Writer group count. Default is Self::CONCURRENT_WRITE and it must be in the range [1, 128]
Once set, it cannot be modified
gc_timeout: u64Garbage collection cycle interval (milliseconds).
checkpoint_nudge_ms: u64Proactive page-checkpoint trigger interval (milliseconds).
When a bucket has pending dirty pages but no foreground write reaches checkpoint thresholds, the evictor triggers checkpoint near this interval to prevent WAL checkpoint stalling.
Set to 0 to disable proactive triggering.
data_garbage_ratio: u32Perform compaction when the garbage ratio exceeds this value, in the range [0, 100]
gc_eager: boolIf true, compact immediately when Self::data_garbage_ratio is reached.
blob_file_size: usizeSize limit of a blob file. Default is Self::BLOB_FILE_SIZE
blob_garbage_ratio: usizeTrigger blob GC when the garbage ratio exceeds this value, in the range [0, 100]
blob_gc_ratio: usizeAt each blob GC cycle, pick the lowest-utilization Self::blob_gc_ratio% of blob files as candidates.
tmp_store: boolWhether this is temporary storage.
If true, db_root will be removed on exit.
log_root: PathBufDirectory where log files are stored.
The default value is db_root/log.
lru_capacity: usizeShared logical-address cache capacity in bytes.
This cache keeps file-loaded blob values and auxiliary history/sibling pages. Resident tree pages and dirty pool pages are accounted elsewhere and are not inserted here. Trimming is best-effort and happens in small rounds, so short-term overshoot is possible.
Different subsystems may transiently hold refs to the same allocation.
stat_mask_cache_count: usizeBitmap-cache entry count for data and blob stats.
data_handle_cache_capacity: usizeMaximum number of open data-file handles cached concurrently, used for loading data pages.
blob_handle_cache_capacity: usizeMaximum number of open blob-file handles cached concurrently, used for loading blob pages.
data_file_size: usizeSize limit of a data file. Minimum is Self::DATA_FILE_SIZE
wal_buffer_size: usizeWAL ring buffer size. Must be greater than the page size and a power of two.
max_ckpt_per_txn: usizeNumber of checkpoints a transaction can span (i.e., transaction length limit).
If a transaction exceeds this limit, it is forcibly aborted.
wal_file_size: u32WAL file size limit that triggers switching to a new WAL file, up to 2GB.
keep_stable_wal_file: boolIf true, remove unused stable WAL files (never used in recovery).
Default is false.
truncate_corrupted_wal: boolIf true, corrupted WAL is truncated during recovery; otherwise recovery panics.
Default is true.
observer: Arc<dyn Observer>Observability callback. Default is no-op.
Implementations§
Source§impl Options
impl Options
pub const CONCURRENT_WRITE: u8 = 16
pub const MAX_CONCURRENT_WRITE: u8 = 128
pub const DATA_FILE_SIZE: usize
pub const BLOB_FILE_SIZE: usize
pub const LRU_CAPACITY: usize
pub const STAT_MASK_CACHE_CNT: usize = 16384
pub const WAL_BUF_SZ: usize
pub const WAL_FILE_SZ: usize
Sourcepub fn new<P: AsRef<Path>>(db_root: P) -> Self
pub fn new<P: AsRef<Path>>(db_root: P) -> Self
Creates a new Options instance with default values and the given database root.
Examples found in repository?
8fn main() -> Result<(), OpCode> {
9 let path = std::env::temp_dir().join(format!("mace_observer_{}", std::process::id()));
10 let _ = std::fs::remove_dir_all(&path);
11
12 let observer = Arc::new(InMemoryObserver::new(256));
13 let mut opt = Options::new(&path);
14 opt.observer = observer.clone();
15
16 let db = Mace::new(opt.validate()?)?;
17 let bucket = db.new_bucket("observe", BucketOptions::default())?;
18
19 let tx = bucket.begin()?;
20 tx.put("k1", "v1")?;
21
22 let r = tx.put("k1", "v2");
23 assert_eq!(r.err(), Some(OpCode::AbortTx));
24 drop(tx);
25
26 let tx = bucket.begin()?;
27 tx.put("k2", "v2")?;
28 tx.commit()?;
29
30 let snapshot = observer.snapshot();
31 print_snapshot(&snapshot);
32 Ok(())
33}More examples
3fn main() -> Result<(), OpCode> {
4 let path = std::env::temp_dir().join("mace");
5 let _ = std::fs::remove_dir_all(&path);
6 let opt = Options::new(path).validate()?;
7 let db = Mace::new(opt)?;
8 let bucket = db.new_bucket("test", BucketOptions::default())?;
9
10 // start a read-write transaction
11 let kv = bucket.begin()?;
12 kv.put("foo", "bar")?;
13 kv.put("fool", "+1s")?;
14 kv.put("foolish", "elder")?;
15
16 // can't create two identical keys
17 let r = kv.put("foolish", "114514").err();
18 assert_eq!(r.unwrap(), OpCode::AbortTx);
19
20 // use `update` for exist key or use `upsert` when unsure
21 let r = kv.update("foolish", "114514");
22 assert!(r.is_ok());
23
24 let r = kv.get("foo")?;
25 assert_eq!(r.slice(), "bar".as_bytes());
26 kv.del("foolish")?;
27 kv.commit()?;
28
29 // rollback
30 let kv = bucket.begin()?;
31 kv.put("mo", "ha")?;
32 drop(kv);
33
34 // start a read-only transaction
35 let view = bucket.view()?;
36 let r = view.get("foo")?;
37 assert_eq!(r.slice(), "bar".as_bytes());
38 let r = view.get("mo");
39 assert_eq!(r.err().unwrap(), OpCode::NotFound);
40
41 // prefix scan
42 let r = view.get("foolish");
43 assert!(r.is_err() && r.err().unwrap() == OpCode::NotFound);
44 let iter = view.seek("foo");
45 assert_eq!(iter.count(), 2);
46
47 Ok(())
48}Sourcepub fn validate(self) -> Result<ParsedOptions, OpCode>
pub fn validate(self) -> Result<ParsedOptions, OpCode>
Validates the options and returns a ParsedOptions instance.
Examples found in repository?
8fn main() -> Result<(), OpCode> {
9 let path = std::env::temp_dir().join(format!("mace_observer_{}", std::process::id()));
10 let _ = std::fs::remove_dir_all(&path);
11
12 let observer = Arc::new(InMemoryObserver::new(256));
13 let mut opt = Options::new(&path);
14 opt.observer = observer.clone();
15
16 let db = Mace::new(opt.validate()?)?;
17 let bucket = db.new_bucket("observe", BucketOptions::default())?;
18
19 let tx = bucket.begin()?;
20 tx.put("k1", "v1")?;
21
22 let r = tx.put("k1", "v2");
23 assert_eq!(r.err(), Some(OpCode::AbortTx));
24 drop(tx);
25
26 let tx = bucket.begin()?;
27 tx.put("k2", "v2")?;
28 tx.commit()?;
29
30 let snapshot = observer.snapshot();
31 print_snapshot(&snapshot);
32 Ok(())
33}More examples
3fn main() -> Result<(), OpCode> {
4 let path = std::env::temp_dir().join("mace");
5 let _ = std::fs::remove_dir_all(&path);
6 let opt = Options::new(path).validate()?;
7 let db = Mace::new(opt)?;
8 let bucket = db.new_bucket("test", BucketOptions::default())?;
9
10 // start a read-write transaction
11 let kv = bucket.begin()?;
12 kv.put("foo", "bar")?;
13 kv.put("fool", "+1s")?;
14 kv.put("foolish", "elder")?;
15
16 // can't create two identical keys
17 let r = kv.put("foolish", "114514").err();
18 assert_eq!(r.unwrap(), OpCode::AbortTx);
19
20 // use `update` for exist key or use `upsert` when unsure
21 let r = kv.update("foolish", "114514");
22 assert!(r.is_ok());
23
24 let r = kv.get("foo")?;
25 assert_eq!(r.slice(), "bar".as_bytes());
26 kv.del("foolish")?;
27 kv.commit()?;
28
29 // rollback
30 let kv = bucket.begin()?;
31 kv.put("mo", "ha")?;
32 drop(kv);
33
34 // start a read-only transaction
35 let view = bucket.view()?;
36 let r = view.get("foo")?;
37 assert_eq!(r.slice(), "bar".as_bytes());
38 let r = view.get("mo");
39 assert_eq!(r.err().unwrap(), OpCode::NotFound);
40
41 // prefix scan
42 let r = view.get("foolish");
43 assert!(r.is_err() && r.err().unwrap() == OpCode::NotFound);
44 let iter = view.seek("foo");
45 assert_eq!(iter.count(), 2);
46
47 Ok(())
48}Sourcepub fn create_dir(&self) -> Result<()>
pub fn create_dir(&self) -> Result<()>
Creates the directory structure for the database.