use super::strategies::CompactionStrategy;
use serde::{Deserialize, Serialize};
use std::time::Duration;
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CompactionConfig {
pub strategy: CompactionStrategy,
pub enable_background: bool,
pub compaction_interval: Duration,
pub fragmentation_threshold: f64,
pub batch_size: usize,
pub max_concurrent_batches: usize,
pub pause_between_batches: Duration,
pub max_compaction_duration: Duration,
pub min_free_space_bytes: u64,
pub enable_verification: bool,
pub cpu_priority: u8,
pub memory_limit_bytes: u64,
pub enable_metrics: bool,
pub metrics_retention: Duration,
}
impl Default for CompactionConfig {
fn default() -> Self {
Self {
strategy: CompactionStrategy::Adaptive,
enable_background: true,
compaction_interval: Duration::from_secs(3600), fragmentation_threshold: 0.3, batch_size: 1000,
max_concurrent_batches: 4,
pause_between_batches: Duration::from_millis(100),
max_compaction_duration: Duration::from_secs(300), min_free_space_bytes: 100 * 1024 * 1024, enable_verification: true,
cpu_priority: 10, memory_limit_bytes: 512 * 1024 * 1024, enable_metrics: true,
metrics_retention: Duration::from_secs(7 * 24 * 3600), }
}
}
impl CompactionConfig {
pub fn validate(&self) -> anyhow::Result<()> {
if self.fragmentation_threshold <= 0.0 || self.fragmentation_threshold > 1.0 {
anyhow::bail!("Fragmentation threshold must be in (0.0, 1.0]");
}
if self.batch_size == 0 {
anyhow::bail!("Batch size must be positive");
}
if self.max_concurrent_batches == 0 {
anyhow::bail!("Max concurrent batches must be positive");
}
if self.cpu_priority > 100 {
anyhow::bail!("CPU priority must be in [0, 100]");
}
Ok(())
}
pub fn development() -> Self {
Self {
compaction_interval: Duration::from_secs(60), fragmentation_threshold: 0.1, batch_size: 100,
pause_between_batches: Duration::from_millis(10),
..Default::default()
}
}
pub fn production() -> Self {
Self {
compaction_interval: Duration::from_secs(7200), fragmentation_threshold: 0.5, batch_size: 5000,
max_concurrent_batches: 8,
pause_between_batches: Duration::from_millis(500),
max_compaction_duration: Duration::from_secs(600), memory_limit_bytes: 2 * 1024 * 1024 * 1024, ..Default::default()
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_default_config_is_valid() {
let config = CompactionConfig::default();
assert!(config.validate().is_ok());
}
#[test]
fn test_development_config_is_valid() {
let config = CompactionConfig::development();
assert!(config.validate().is_ok());
}
#[test]
fn test_production_config_is_valid() {
let config = CompactionConfig::production();
assert!(config.validate().is_ok());
}
#[test]
fn test_invalid_fragmentation_threshold() {
let config = CompactionConfig {
fragmentation_threshold: 1.5,
..Default::default()
};
assert!(config.validate().is_err());
}
#[test]
fn test_invalid_batch_size() {
let config = CompactionConfig {
batch_size: 0,
..Default::default()
};
assert!(config.validate().is_err());
}
}