oxirs_vec/compaction/
config.rs

1//! Configuration for compaction system
2
3use super::strategies::CompactionStrategy;
4use serde::{Deserialize, Serialize};
5use std::time::Duration;
6
7/// Compaction configuration
8#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct CompactionConfig {
10    /// Compaction strategy
11    pub strategy: CompactionStrategy,
12    /// Enable background compaction
13    pub enable_background: bool,
14    /// Compaction interval for periodic strategy
15    pub compaction_interval: Duration,
16    /// Fragmentation threshold (0.0 - 1.0) to trigger compaction
17    pub fragmentation_threshold: f64,
18    /// Batch size (number of vectors to process at once)
19    pub batch_size: usize,
20    /// Maximum concurrent batches
21    pub max_concurrent_batches: usize,
22    /// Pause between batches (to avoid impacting queries)
23    pub pause_between_batches: Duration,
24    /// Maximum compaction duration before pausing
25    pub max_compaction_duration: Duration,
26    /// Minimum free space to trigger compaction (bytes)
27    pub min_free_space_bytes: u64,
28    /// Enable verification after compaction
29    pub enable_verification: bool,
30    /// CPU priority (0-100, lower = more background)
31    pub cpu_priority: u8,
32    /// Memory limit for compaction (bytes)
33    pub memory_limit_bytes: u64,
34    /// Enable metrics collection
35    pub enable_metrics: bool,
36    /// Metrics retention period
37    pub metrics_retention: Duration,
38}
39
40impl Default for CompactionConfig {
41    fn default() -> Self {
42        Self {
43            strategy: CompactionStrategy::Adaptive,
44            enable_background: true,
45            compaction_interval: Duration::from_secs(3600), // 1 hour
46            fragmentation_threshold: 0.3,                   // 30%
47            batch_size: 1000,
48            max_concurrent_batches: 4,
49            pause_between_batches: Duration::from_millis(100),
50            max_compaction_duration: Duration::from_secs(300), // 5 minutes
51            min_free_space_bytes: 100 * 1024 * 1024,           // 100 MB
52            enable_verification: true,
53            cpu_priority: 10,                      // Low priority
54            memory_limit_bytes: 512 * 1024 * 1024, // 512 MB
55            enable_metrics: true,
56            metrics_retention: Duration::from_secs(7 * 24 * 3600), // 7 days
57        }
58    }
59}
60
61impl CompactionConfig {
62    /// Validate configuration
63    pub fn validate(&self) -> anyhow::Result<()> {
64        if self.fragmentation_threshold <= 0.0 || self.fragmentation_threshold > 1.0 {
65            anyhow::bail!("Fragmentation threshold must be in (0.0, 1.0]");
66        }
67        if self.batch_size == 0 {
68            anyhow::bail!("Batch size must be positive");
69        }
70        if self.max_concurrent_batches == 0 {
71            anyhow::bail!("Max concurrent batches must be positive");
72        }
73        if self.cpu_priority > 100 {
74            anyhow::bail!("CPU priority must be in [0, 100]");
75        }
76        Ok(())
77    }
78
79    /// Create development configuration (aggressive compaction)
80    pub fn development() -> Self {
81        Self {
82            compaction_interval: Duration::from_secs(60), // 1 minute
83            fragmentation_threshold: 0.1,                 // 10%
84            batch_size: 100,
85            pause_between_batches: Duration::from_millis(10),
86            ..Default::default()
87        }
88    }
89
90    /// Create production configuration (conservative compaction)
91    pub fn production() -> Self {
92        Self {
93            compaction_interval: Duration::from_secs(7200), // 2 hours
94            fragmentation_threshold: 0.5,                   // 50%
95            batch_size: 5000,
96            max_concurrent_batches: 8,
97            pause_between_batches: Duration::from_millis(500),
98            max_compaction_duration: Duration::from_secs(600), // 10 minutes
99            memory_limit_bytes: 2 * 1024 * 1024 * 1024,        // 2 GB
100            ..Default::default()
101        }
102    }
103}
104
105#[cfg(test)]
106mod tests {
107    use super::*;
108
109    #[test]
110    fn test_default_config_is_valid() {
111        let config = CompactionConfig::default();
112        assert!(config.validate().is_ok());
113    }
114
115    #[test]
116    fn test_development_config_is_valid() {
117        let config = CompactionConfig::development();
118        assert!(config.validate().is_ok());
119    }
120
121    #[test]
122    fn test_production_config_is_valid() {
123        let config = CompactionConfig::production();
124        assert!(config.validate().is_ok());
125    }
126
127    #[test]
128    fn test_invalid_fragmentation_threshold() {
129        let config = CompactionConfig {
130            fragmentation_threshold: 1.5,
131            ..Default::default()
132        };
133        assert!(config.validate().is_err());
134    }
135
136    #[test]
137    fn test_invalid_batch_size() {
138        let config = CompactionConfig {
139            batch_size: 0,
140            ..Default::default()
141        };
142        assert!(config.validate().is_err());
143    }
144}