#[derive(Debug, Clone, Copy, PartialEq, Eq, Default)]
pub enum SyncMode {
None = 0,
#[default]
Normal = 1,
Full = 2,
}
impl From<i32> for SyncMode {
fn from(value: i32) -> Self {
match value {
0 => SyncMode::None,
2 => SyncMode::Full,
_ => SyncMode::Normal,
}
}
}
impl From<SyncMode> for i32 {
fn from(mode: SyncMode) -> Self {
mode as i32
}
}
pub const DEFAULT_COPY_MAX_TRANSACTION_BYTES: usize = 512 * 1024 * 1024;
pub const DEFAULT_MAX_COMPACTION_INPUT_SEGMENTS: usize = 8;
pub const DEFAULT_MAX_COMPACTION_JOBS: usize = 1;
pub const MAX_COMPACTION_JOBS: usize = 8;
pub const DEFAULT_MAX_COMPACTION_INPUT_BYTES: u64 = 512 * 1024 * 1024;
pub const DEFAULT_MAX_COMPACTION_OUTPUT_BYTES: u64 = 1024 * 1024 * 1024;
pub const DEFAULT_COMPACTION_JOB_TIME_BUDGET_MS: u64 = 20 * 60 * 1000;
pub const DEFAULT_COMPACTION_IO_BYTES_PER_SEC: u64 = 0;
pub const DEFAULT_COMPACTION_DISK_RESERVE_BYTES: u64 = 1024 * 1024 * 1024;
pub const DEFAULT_COMPACTION_RETRY_COOLDOWN_MS: u64 = 30_000;
pub const DEFAULT_L0_SOFT_LIMIT_SEGMENTS: usize = 16;
pub const DEFAULT_L0_HARD_LIMIT_SEGMENTS: usize = 32;
pub const DEFAULT_L0_SOFT_LIMIT_BYTES: u64 = 1024 * 1024 * 1024;
pub const DEFAULT_L0_HARD_LIMIT_BYTES: u64 = 2 * 1024 * 1024 * 1024;
pub const DEFAULT_L0_SOFT_BACKPRESSURE_WAIT_MS: u64 = 100;
pub const DEFAULT_STORAGE_CPU_WORKERS: usize = 0;
pub const DEFAULT_PAGE_CACHE_LEVEL: u8 = 0;
pub const DEFAULT_PAGE_CACHE_MAX_BYTES: u64 = 0;
pub const DEFAULT_PAGE_CACHE_MEMORY_RESERVE: u64 = 0;
pub const MAX_PAGE_CACHE_LEVEL: u8 = 10;
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct PersistenceConfig {
pub enabled: bool,
pub sync_mode: SyncMode,
pub checkpoint_interval: u32,
pub compact_threshold: u32,
pub max_compaction_jobs: usize,
pub storage_cpu_workers: usize,
pub page_cache_level: u8,
pub page_cache_max_bytes: u64,
pub page_cache_memory_reserve: u64,
pub max_compaction_input_segments: usize,
pub max_compaction_input_bytes: u64,
pub max_compaction_output_bytes: u64,
pub compaction_job_time_budget_ms: u64,
pub compaction_io_bytes_per_sec: u64,
pub compaction_disk_reserve_bytes: u64,
pub compaction_retry_cooldown_ms: u64,
pub l0_soft_limit_segments: usize,
pub l0_hard_limit_segments: usize,
pub l0_soft_limit_bytes: u64,
pub l0_hard_limit_bytes: u64,
pub l0_soft_backpressure_wait_ms: u64,
pub wal_flush_trigger: usize,
pub wal_buffer_size: usize,
pub wal_max_size: usize,
pub sync_interval_ms: u32,
pub wal_compression: bool,
pub volume_compression: bool,
pub keep_snapshots: u32,
pub checkpoint_on_close: bool,
pub copy_max_transaction_bytes: usize,
pub target_volume_rows: usize,
pub seal_hot_bytes_threshold: usize,
pub seal_incremental_hot_bytes_threshold: usize,
pub volume_cache_bytes: usize,
pub read_queue_depth: usize,
}
impl Default for PersistenceConfig {
fn default() -> Self {
Self {
enabled: true,
sync_mode: SyncMode::Normal,
checkpoint_interval: 60, compact_threshold: 4, max_compaction_jobs: DEFAULT_MAX_COMPACTION_JOBS,
storage_cpu_workers: DEFAULT_STORAGE_CPU_WORKERS,
page_cache_level: DEFAULT_PAGE_CACHE_LEVEL,
page_cache_max_bytes: DEFAULT_PAGE_CACHE_MAX_BYTES,
page_cache_memory_reserve: DEFAULT_PAGE_CACHE_MEMORY_RESERVE,
max_compaction_input_segments: DEFAULT_MAX_COMPACTION_INPUT_SEGMENTS,
max_compaction_input_bytes: DEFAULT_MAX_COMPACTION_INPUT_BYTES,
max_compaction_output_bytes: DEFAULT_MAX_COMPACTION_OUTPUT_BYTES,
compaction_job_time_budget_ms: DEFAULT_COMPACTION_JOB_TIME_BUDGET_MS,
compaction_io_bytes_per_sec: DEFAULT_COMPACTION_IO_BYTES_PER_SEC,
compaction_disk_reserve_bytes: DEFAULT_COMPACTION_DISK_RESERVE_BYTES,
compaction_retry_cooldown_ms: DEFAULT_COMPACTION_RETRY_COOLDOWN_MS,
l0_soft_limit_segments: DEFAULT_L0_SOFT_LIMIT_SEGMENTS,
l0_hard_limit_segments: DEFAULT_L0_HARD_LIMIT_SEGMENTS,
l0_soft_limit_bytes: DEFAULT_L0_SOFT_LIMIT_BYTES,
l0_hard_limit_bytes: DEFAULT_L0_HARD_LIMIT_BYTES,
l0_soft_backpressure_wait_ms: DEFAULT_L0_SOFT_BACKPRESSURE_WAIT_MS,
wal_flush_trigger: 32 * 1024, wal_buffer_size: 64 * 1024, wal_max_size: 64 * 1024 * 1024, sync_interval_ms: 1000, wal_compression: true, volume_compression: true, keep_snapshots: 3, checkpoint_on_close: true, copy_max_transaction_bytes: DEFAULT_COPY_MAX_TRANSACTION_BYTES,
target_volume_rows: 1_048_576, seal_hot_bytes_threshold: 64 * 1024 * 1024,
seal_incremental_hot_bytes_threshold: 16 * 1024 * 1024,
volume_cache_bytes: 1024 * 1024 * 1024,
read_queue_depth: 1,
}
}
}
impl PersistenceConfig {
pub fn new() -> Self {
Self::default()
}
pub fn durable() -> Self {
Self {
enabled: true,
sync_mode: SyncMode::Full,
checkpoint_interval: 30, compact_threshold: 4,
max_compaction_jobs: DEFAULT_MAX_COMPACTION_JOBS,
storage_cpu_workers: DEFAULT_STORAGE_CPU_WORKERS,
page_cache_level: DEFAULT_PAGE_CACHE_LEVEL,
page_cache_max_bytes: DEFAULT_PAGE_CACHE_MAX_BYTES,
page_cache_memory_reserve: DEFAULT_PAGE_CACHE_MEMORY_RESERVE,
max_compaction_input_segments: DEFAULT_MAX_COMPACTION_INPUT_SEGMENTS,
max_compaction_input_bytes: DEFAULT_MAX_COMPACTION_INPUT_BYTES,
max_compaction_output_bytes: DEFAULT_MAX_COMPACTION_OUTPUT_BYTES,
compaction_job_time_budget_ms: DEFAULT_COMPACTION_JOB_TIME_BUDGET_MS,
compaction_io_bytes_per_sec: DEFAULT_COMPACTION_IO_BYTES_PER_SEC,
compaction_disk_reserve_bytes: DEFAULT_COMPACTION_DISK_RESERVE_BYTES,
compaction_retry_cooldown_ms: DEFAULT_COMPACTION_RETRY_COOLDOWN_MS,
l0_soft_limit_segments: DEFAULT_L0_SOFT_LIMIT_SEGMENTS,
l0_hard_limit_segments: DEFAULT_L0_HARD_LIMIT_SEGMENTS,
l0_soft_limit_bytes: DEFAULT_L0_SOFT_LIMIT_BYTES,
l0_hard_limit_bytes: DEFAULT_L0_HARD_LIMIT_BYTES,
l0_soft_backpressure_wait_ms: DEFAULT_L0_SOFT_BACKPRESSURE_WAIT_MS,
wal_flush_trigger: 8 * 1024, wal_buffer_size: 32 * 1024, wal_max_size: 32 * 1024 * 1024, sync_interval_ms: 0, wal_compression: true,
volume_compression: true,
keep_snapshots: 3,
checkpoint_on_close: true,
copy_max_transaction_bytes: DEFAULT_COPY_MAX_TRANSACTION_BYTES,
target_volume_rows: 1_048_576,
seal_hot_bytes_threshold: 64 * 1024 * 1024,
seal_incremental_hot_bytes_threshold: 16 * 1024 * 1024,
volume_cache_bytes: 512 * 1024 * 1024,
read_queue_depth: 1,
}
}
pub fn fast() -> Self {
Self {
enabled: true,
sync_mode: SyncMode::None,
checkpoint_interval: 120, compact_threshold: 8,
max_compaction_jobs: DEFAULT_MAX_COMPACTION_JOBS,
storage_cpu_workers: DEFAULT_STORAGE_CPU_WORKERS,
page_cache_level: DEFAULT_PAGE_CACHE_LEVEL,
page_cache_max_bytes: DEFAULT_PAGE_CACHE_MAX_BYTES,
page_cache_memory_reserve: DEFAULT_PAGE_CACHE_MEMORY_RESERVE,
max_compaction_input_segments: DEFAULT_MAX_COMPACTION_INPUT_SEGMENTS,
max_compaction_input_bytes: DEFAULT_MAX_COMPACTION_INPUT_BYTES,
max_compaction_output_bytes: DEFAULT_MAX_COMPACTION_OUTPUT_BYTES,
compaction_job_time_budget_ms: DEFAULT_COMPACTION_JOB_TIME_BUDGET_MS,
compaction_io_bytes_per_sec: DEFAULT_COMPACTION_IO_BYTES_PER_SEC,
compaction_disk_reserve_bytes: DEFAULT_COMPACTION_DISK_RESERVE_BYTES,
compaction_retry_cooldown_ms: DEFAULT_COMPACTION_RETRY_COOLDOWN_MS,
l0_soft_limit_segments: DEFAULT_L0_SOFT_LIMIT_SEGMENTS,
l0_hard_limit_segments: DEFAULT_L0_HARD_LIMIT_SEGMENTS,
l0_soft_limit_bytes: DEFAULT_L0_SOFT_LIMIT_BYTES,
l0_hard_limit_bytes: DEFAULT_L0_HARD_LIMIT_BYTES,
l0_soft_backpressure_wait_ms: DEFAULT_L0_SOFT_BACKPRESSURE_WAIT_MS,
wal_flush_trigger: 64 * 1024, wal_buffer_size: 128 * 1024, wal_max_size: 128 * 1024 * 1024, sync_interval_ms: 100, wal_compression: true,
volume_compression: true,
keep_snapshots: 3,
checkpoint_on_close: true,
copy_max_transaction_bytes: DEFAULT_COPY_MAX_TRANSACTION_BYTES,
target_volume_rows: 2_097_152, seal_hot_bytes_threshold: 128 * 1024 * 1024,
seal_incremental_hot_bytes_threshold: 32 * 1024 * 1024,
volume_cache_bytes: 2 * 1024 * 1024 * 1024,
read_queue_depth: 1,
}
}
pub fn with_sync_mode(mut self, mode: SyncMode) -> Self {
self.sync_mode = mode;
self
}
pub fn with_checkpoint_interval(mut self, seconds: u32) -> Self {
self.checkpoint_interval = if seconds == 0 { 0 } else { seconds.max(5) };
self
}
pub fn with_copy_max_transaction_bytes(mut self, bytes: usize) -> Self {
self.copy_max_transaction_bytes = bytes.max(1);
self
}
pub fn with_compact_threshold(mut self, count: u32) -> Self {
self.compact_threshold = count;
self
}
pub fn with_max_compaction_jobs(mut self, count: usize) -> Self {
self.max_compaction_jobs = count.clamp(1, MAX_COMPACTION_JOBS);
self
}
pub fn with_storage_cpu_workers(mut self, workers: usize) -> Self {
self.storage_cpu_workers = workers;
self
}
pub fn with_page_cache_level(mut self, level: u8) -> Self {
self.page_cache_level = level.min(MAX_PAGE_CACHE_LEVEL);
self
}
pub fn with_page_cache_max_bytes(mut self, bytes: u64) -> Self {
self.page_cache_max_bytes = bytes;
self
}
pub fn with_page_cache_memory_reserve(mut self, bytes: u64) -> Self {
self.page_cache_memory_reserve = bytes;
self
}
pub fn with_max_compaction_input_segments(mut self, count: usize) -> Self {
self.max_compaction_input_segments = count.max(1);
self
}
pub fn with_max_compaction_input_bytes(mut self, bytes: u64) -> Self {
self.max_compaction_input_bytes = bytes.max(1);
self
}
pub fn with_max_compaction_output_bytes(mut self, bytes: u64) -> Self {
self.max_compaction_output_bytes = bytes.max(1);
self
}
pub fn with_compaction_job_time_budget_ms(mut self, millis: u64) -> Self {
self.compaction_job_time_budget_ms = millis;
self
}
pub fn with_compaction_io_bytes_per_sec(mut self, bytes: u64) -> Self {
self.compaction_io_bytes_per_sec = bytes;
self
}
pub fn with_compaction_disk_reserve_bytes(mut self, bytes: u64) -> Self {
self.compaction_disk_reserve_bytes = bytes;
self
}
pub fn with_compaction_retry_cooldown_ms(mut self, millis: u64) -> Self {
self.compaction_retry_cooldown_ms = millis;
self
}
pub fn with_l0_segment_limits(mut self, soft: usize, hard: usize) -> Self {
self.l0_soft_limit_segments = soft.max(1);
self.l0_hard_limit_segments = hard.max(self.l0_soft_limit_segments.saturating_add(1));
self
}
pub fn with_l0_byte_limits(mut self, soft: u64, hard: u64) -> Self {
self.l0_soft_limit_bytes = soft.max(1);
self.l0_hard_limit_bytes = hard.max(self.l0_soft_limit_bytes.saturating_add(1));
self
}
pub fn with_l0_soft_backpressure_wait_ms(mut self, millis: u64) -> Self {
self.l0_soft_backpressure_wait_ms = millis;
self
}
pub fn with_wal_compression(mut self, enabled: bool) -> Self {
self.wal_compression = enabled;
self
}
pub fn with_volume_compression(mut self, enabled: bool) -> Self {
self.volume_compression = enabled;
self
}
pub fn with_compression(mut self, enabled: bool) -> Self {
self.wal_compression = enabled;
self.volume_compression = enabled;
self
}
pub fn with_keep_snapshots(mut self, count: u32) -> Self {
self.keep_snapshots = count;
self
}
pub fn with_target_volume_rows(mut self, rows: usize) -> Self {
self.target_volume_rows = rows.max(65_536);
self
}
pub fn with_seal_hot_bytes_threshold(mut self, bytes: usize) -> Self {
self.seal_hot_bytes_threshold = bytes.max(1);
self
}
pub fn with_seal_incremental_hot_bytes_threshold(mut self, bytes: usize) -> Self {
self.seal_incremental_hot_bytes_threshold = bytes.max(1);
self
}
pub fn with_volume_cache_bytes(mut self, bytes: usize) -> Self {
self.volume_cache_bytes = bytes;
self
}
pub fn with_read_queue_depth(mut self, depth: usize) -> Self {
self.read_queue_depth = depth.max(1);
self
}
}
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CleanupConfig {
pub enabled: bool,
pub interval_secs: u64,
pub deleted_row_retention_secs: u64,
pub transaction_retention_secs: u64,
}
impl Default for CleanupConfig {
fn default() -> Self {
Self {
enabled: true,
interval_secs: 60,
deleted_row_retention_secs: 300,
transaction_retention_secs: 3600,
}
}
}
impl CleanupConfig {
pub fn disabled() -> Self {
Self {
enabled: false,
..Default::default()
}
}
pub fn with_interval_secs(mut self, secs: u64) -> Self {
self.interval_secs = secs;
self
}
pub fn with_deleted_row_retention_secs(mut self, secs: u64) -> Self {
self.deleted_row_retention_secs = secs;
self
}
pub fn with_transaction_retention_secs(mut self, secs: u64) -> Self {
self.transaction_retention_secs = secs;
self
}
}
#[derive(Debug, Clone, Default, PartialEq, Eq)]
pub struct Config {
pub path: Option<String>,
pub persistence: PersistenceConfig,
pub cleanup: CleanupConfig,
}
impl Config {
pub fn in_memory() -> Self {
Self {
path: None,
persistence: PersistenceConfig {
enabled: false,
..Default::default()
},
cleanup: CleanupConfig::default(),
}
}
pub fn with_path<P: Into<String>>(path: P) -> Self {
Self {
path: Some(path.into()),
persistence: PersistenceConfig::default(),
cleanup: CleanupConfig::default(),
}
}
pub fn is_persistent(&self) -> bool {
self.path.is_some() && self.persistence.enabled
}
pub fn with_persistence(mut self, config: PersistenceConfig) -> Self {
self.persistence = config;
self
}
pub fn with_cleanup(mut self, config: CleanupConfig) -> Self {
self.cleanup = config;
self
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_sync_mode_default() {
assert_eq!(SyncMode::default(), SyncMode::Normal);
}
#[test]
fn test_sync_mode_from_i32() {
assert_eq!(SyncMode::from(0), SyncMode::None);
assert_eq!(SyncMode::from(1), SyncMode::Normal);
assert_eq!(SyncMode::from(2), SyncMode::Full);
assert_eq!(SyncMode::from(99), SyncMode::Normal); }
#[test]
fn test_persistence_config_default() {
let config = PersistenceConfig::default();
assert!(config.enabled);
assert_eq!(config.sync_mode, SyncMode::Normal);
assert_eq!(config.checkpoint_interval, 60);
assert_eq!(config.compact_threshold, 4);
assert_eq!(config.max_compaction_jobs, DEFAULT_MAX_COMPACTION_JOBS);
assert_eq!(
config.max_compaction_input_segments,
DEFAULT_MAX_COMPACTION_INPUT_SEGMENTS
);
assert_eq!(
config.max_compaction_input_bytes,
DEFAULT_MAX_COMPACTION_INPUT_BYTES
);
assert_eq!(
config.max_compaction_output_bytes,
DEFAULT_MAX_COMPACTION_OUTPUT_BYTES
);
assert_eq!(
config.compaction_job_time_budget_ms,
DEFAULT_COMPACTION_JOB_TIME_BUDGET_MS
);
assert_eq!(
config.compaction_io_bytes_per_sec,
DEFAULT_COMPACTION_IO_BYTES_PER_SEC
);
assert_eq!(
config.compaction_disk_reserve_bytes,
DEFAULT_COMPACTION_DISK_RESERVE_BYTES
);
assert_eq!(
config.compaction_retry_cooldown_ms,
DEFAULT_COMPACTION_RETRY_COOLDOWN_MS
);
assert_eq!(
config.l0_soft_limit_segments,
DEFAULT_L0_SOFT_LIMIT_SEGMENTS
);
assert_eq!(
config.l0_hard_limit_segments,
DEFAULT_L0_HARD_LIMIT_SEGMENTS
);
assert_eq!(config.l0_soft_limit_bytes, DEFAULT_L0_SOFT_LIMIT_BYTES);
assert_eq!(config.l0_hard_limit_bytes, DEFAULT_L0_HARD_LIMIT_BYTES);
assert_eq!(
config.l0_soft_backpressure_wait_ms,
DEFAULT_L0_SOFT_BACKPRESSURE_WAIT_MS
);
assert_eq!(config.wal_flush_trigger, 32 * 1024);
assert_eq!(config.wal_buffer_size, 64 * 1024);
assert_eq!(config.wal_max_size, 64 * 1024 * 1024);
assert_eq!(config.sync_interval_ms, 1000);
assert!(config.wal_compression);
assert_eq!(config.keep_snapshots, 3);
assert_eq!(config.seal_hot_bytes_threshold, 64 * 1024 * 1024);
assert_eq!(
config.seal_incremental_hot_bytes_threshold,
16 * 1024 * 1024
);
assert_eq!(config.volume_cache_bytes, 1024 * 1024 * 1024);
assert_eq!(config.read_queue_depth, 1);
}
#[test]
fn test_persistence_config_durable() {
let config = PersistenceConfig::durable();
assert_eq!(config.sync_mode, SyncMode::Full);
assert_eq!(config.sync_interval_ms, 0);
}
#[test]
fn test_persistence_config_fast() {
let config = PersistenceConfig::fast();
assert_eq!(config.sync_mode, SyncMode::None);
}
#[test]
fn test_persistence_config_builder() {
let config = PersistenceConfig::new()
.with_sync_mode(SyncMode::Full)
.with_checkpoint_interval(120)
.with_compact_threshold(8)
.with_max_compaction_jobs(4)
.with_max_compaction_input_segments(6)
.with_max_compaction_input_bytes(32 * 1024 * 1024)
.with_max_compaction_output_bytes(48 * 1024 * 1024)
.with_compaction_job_time_budget_ms(30_000)
.with_compaction_io_bytes_per_sec(8 * 1024 * 1024)
.with_compaction_disk_reserve_bytes(16 * 1024 * 1024)
.with_compaction_retry_cooldown_ms(5_000)
.with_l0_segment_limits(10, 20)
.with_l0_byte_limits(64 * 1024 * 1024, 128 * 1024 * 1024)
.with_l0_soft_backpressure_wait_ms(25)
.with_seal_hot_bytes_threshold(1024)
.with_seal_incremental_hot_bytes_threshold(512)
.with_volume_cache_bytes(256)
.with_read_queue_depth(8);
assert_eq!(config.sync_mode, SyncMode::Full);
assert_eq!(config.checkpoint_interval, 120);
assert_eq!(config.compact_threshold, 8);
assert_eq!(config.max_compaction_jobs, 4);
assert_eq!(config.max_compaction_input_segments, 6);
assert_eq!(config.max_compaction_input_bytes, 32 * 1024 * 1024);
assert_eq!(config.max_compaction_output_bytes, 48 * 1024 * 1024);
assert_eq!(config.compaction_job_time_budget_ms, 30_000);
assert_eq!(config.compaction_io_bytes_per_sec, 8 * 1024 * 1024);
assert_eq!(config.compaction_disk_reserve_bytes, 16 * 1024 * 1024);
assert_eq!(config.compaction_retry_cooldown_ms, 5_000);
assert_eq!(config.l0_soft_limit_segments, 10);
assert_eq!(config.l0_hard_limit_segments, 20);
assert_eq!(config.l0_soft_limit_bytes, 64 * 1024 * 1024);
assert_eq!(config.l0_hard_limit_bytes, 128 * 1024 * 1024);
assert_eq!(config.l0_soft_backpressure_wait_ms, 25);
assert_eq!(config.seal_hot_bytes_threshold, 1024);
assert_eq!(config.seal_incremental_hot_bytes_threshold, 512);
assert_eq!(config.volume_cache_bytes, 256);
assert_eq!(config.read_queue_depth, 8);
let clamped = PersistenceConfig::new().with_read_queue_depth(0);
assert_eq!(clamped.read_queue_depth, 1);
let clamped = PersistenceConfig::new().with_max_compaction_input_segments(0);
assert_eq!(clamped.max_compaction_input_segments, 1);
let clamped = PersistenceConfig::new().with_max_compaction_jobs(usize::MAX);
assert_eq!(clamped.max_compaction_jobs, MAX_COMPACTION_JOBS);
let clamped = PersistenceConfig::new().with_max_compaction_input_bytes(0);
assert_eq!(clamped.max_compaction_input_bytes, 1);
let clamped = PersistenceConfig::new().with_max_compaction_output_bytes(0);
assert_eq!(clamped.max_compaction_output_bytes, 1);
let clamped = PersistenceConfig::new().with_l0_segment_limits(0, 0);
assert_eq!(clamped.l0_soft_limit_segments, 1);
assert_eq!(clamped.l0_hard_limit_segments, 2);
let clamped = PersistenceConfig::new().with_l0_byte_limits(0, 0);
assert_eq!(clamped.l0_soft_limit_bytes, 1);
assert_eq!(clamped.l0_hard_limit_bytes, 2);
}
#[test]
fn test_persistence_config_compression() {
let config = PersistenceConfig::new().with_compression(false);
assert!(!config.wal_compression);
assert!(!config.volume_compression);
let config = PersistenceConfig::new().with_wal_compression(false);
assert!(!config.wal_compression);
assert!(config.volume_compression);
let config = PersistenceConfig::new().with_volume_compression(false);
assert!(config.wal_compression); assert!(!config.volume_compression);
}
#[test]
fn test_config_in_memory() {
let config = Config::in_memory();
assert!(config.path.is_none());
assert!(!config.persistence.enabled);
assert!(!config.is_persistent());
}
#[test]
fn test_config_with_path() {
let config = Config::with_path("/tmp/test.db");
assert_eq!(config.path, Some("/tmp/test.db".to_string()));
assert!(config.persistence.enabled);
assert!(config.is_persistent());
}
#[test]
fn test_config_builder() {
let config =
Config::with_path("/tmp/test.db").with_persistence(PersistenceConfig::durable());
assert!(config.is_persistent());
assert_eq!(config.persistence.sync_mode, SyncMode::Full);
}
}