rez_next_cache/
cache_config.rs

1//! Cache configuration and settings
2//!
3//! This module provides unified configuration for all cache types,
4//! integrating with existing cache configurations while adding
5//! intelligent caching features.
6
7use crate::{
8    EvictionStrategy, DEFAULT_L1_CAPACITY, DEFAULT_L2_CAPACITY, DEFAULT_MEMORY_LIMIT_MB,
9    DEFAULT_TTL_SECONDS,
10};
11use serde::{Deserialize, Serialize};
12use std::path::PathBuf;
13use std::time::Duration;
14
15/// Unified cache configuration
16///
17/// This configuration integrates settings for multi-level caching,
18/// predictive preheating, and adaptive tuning.
19#[derive(Debug, Clone, Serialize, Deserialize)]
20pub struct UnifiedCacheConfig {
21    /// L1 cache configuration (memory cache)
22    pub l1_config: L1CacheConfig,
23    /// L2 cache configuration (disk cache)
24    pub l2_config: L2CacheConfig,
25    /// Predictive preheating configuration
26    pub preheating_config: PreheatingConfig,
27    /// Adaptive tuning configuration
28    pub tuning_config: TuningConfig,
29    /// Monitoring and statistics configuration
30    pub monitoring_config: MonitoringConfig,
31}
32
33impl Default for UnifiedCacheConfig {
34    fn default() -> Self {
35        Self {
36            l1_config: L1CacheConfig::default(),
37            l2_config: L2CacheConfig::default(),
38            preheating_config: PreheatingConfig::default(),
39            tuning_config: TuningConfig::default(),
40            monitoring_config: MonitoringConfig::default(),
41        }
42    }
43}
44
45/// L1 (memory) cache configuration
46#[derive(Debug, Clone, Serialize, Deserialize)]
47pub struct L1CacheConfig {
48    /// Maximum number of entries in L1 cache
49    pub max_entries: usize,
50    /// Maximum memory usage in bytes
51    pub max_memory_bytes: u64,
52    /// Default TTL for L1 entries (in seconds)
53    pub default_ttl: u64,
54    /// Eviction strategy
55    pub eviction_strategy: EvictionStrategy,
56    /// Enable concurrent access optimization
57    pub enable_concurrent_access: bool,
58    /// Shard count for DashMap (0 = auto-detect)
59    pub shard_count: usize,
60    /// Promotion threshold (access count to promote from L2 to L1)
61    pub promotion_threshold: u64,
62}
63
64impl Default for L1CacheConfig {
65    fn default() -> Self {
66        Self {
67            max_entries: DEFAULT_L1_CAPACITY,
68            max_memory_bytes: DEFAULT_MEMORY_LIMIT_MB * 1024 * 1024,
69            default_ttl: DEFAULT_TTL_SECONDS,
70            eviction_strategy: EvictionStrategy::LRU,
71            enable_concurrent_access: true,
72            shard_count: 0,         // Auto-detect based on CPU cores
73            promotion_threshold: 3, // Promote after 3 accesses
74        }
75    }
76}
77
78/// L2 (disk) cache configuration
79#[derive(Debug, Clone, Serialize, Deserialize)]
80pub struct L2CacheConfig {
81    /// Maximum number of entries in L2 cache
82    pub max_entries: usize,
83    /// Maximum disk usage in bytes
84    pub max_disk_bytes: u64,
85    /// Default TTL for L2 entries (in seconds)
86    pub default_ttl: u64,
87    /// Cache directory path
88    pub cache_dir: PathBuf,
89    /// Enable compression for disk storage
90    pub enable_compression: bool,
91    /// Cleanup interval (in seconds)
92    pub cleanup_interval: u64,
93    /// Enable background cleanup
94    pub enable_background_cleanup: bool,
95}
96
97impl Default for L2CacheConfig {
98    fn default() -> Self {
99        Self {
100            max_entries: DEFAULT_L2_CAPACITY,
101            max_disk_bytes: 1024 * 1024 * 1024,    // 1 GB
102            default_ttl: DEFAULT_TTL_SECONDS * 24, // 24 hours for disk cache
103            cache_dir: PathBuf::from(".rez_intelligent_cache"),
104            enable_compression: true,
105            cleanup_interval: 300, // 5 minutes
106            enable_background_cleanup: true,
107        }
108    }
109}
110
111/// Predictive preheating configuration
112#[derive(Debug, Clone, Serialize, Deserialize)]
113pub struct PreheatingConfig {
114    /// Enable predictive preheating
115    pub enable_predictive_preheating: bool,
116    /// Enable pattern learning
117    pub enable_pattern_learning: bool,
118    /// Minimum prediction confidence threshold (0.0 to 1.0)
119    pub min_confidence_threshold: f64,
120    /// Maximum number of entries to preheat per cycle
121    pub max_preheat_entries: usize,
122    /// Maximum concurrent preheating operations
123    pub max_concurrent_preheats: usize,
124    /// Maximum preheating queue size
125    pub max_preheat_queue_size: usize,
126    /// Preheating interval (in seconds)
127    pub preheat_interval: u64,
128    /// Preheating window (seconds before predicted access)
129    pub preheat_window_seconds: u64,
130    /// Pattern window for learning (in seconds)
131    pub pattern_window_seconds: u64,
132    /// Enable background preheating
133    pub enable_background_preheat: bool,
134    /// Maximum CPU usage for preheating (0.0 to 1.0)
135    pub max_cpu_usage: f64,
136    /// Access pattern history size
137    pub history_size: usize,
138}
139
140impl Default for PreheatingConfig {
141    fn default() -> Self {
142        Self {
143            enable_predictive_preheating: true,
144            enable_pattern_learning: true,
145            min_confidence_threshold: 0.7,
146            max_preheat_entries: 100,
147            max_concurrent_preheats: 10,
148            max_preheat_queue_size: 1000,
149            preheat_interval: 60,         // 1 minute
150            preheat_window_seconds: 300,  // 5 minutes
151            pattern_window_seconds: 3600, // 1 hour
152            enable_background_preheat: true,
153            max_cpu_usage: 0.1, // 10% CPU usage limit
154            history_size: 10000,
155        }
156    }
157}
158
159/// Adaptive tuning configuration
160#[derive(Debug, Clone, Serialize, Deserialize)]
161pub struct TuningConfig {
162    /// Enable adaptive tuning
163    pub enable_adaptive_tuning: bool,
164    /// Tuning interval (in seconds)
165    pub tuning_interval: u64,
166    /// Target hit rate for optimization
167    pub target_hit_rate: f64,
168    /// Minimum hit rate threshold for tuning
169    pub min_hit_rate: f64,
170    /// Maximum adjustment factor per tuning cycle
171    pub max_adjustment_factor: f64,
172    /// Minimum confidence for automatic tuning
173    pub min_confidence_for_auto_tuning: f64,
174    /// Performance window size for analysis
175    pub performance_window_size: usize,
176    /// Minimum samples required for tuning decisions
177    pub min_samples_for_tuning: usize,
178    /// Enable TTL adaptation
179    pub enable_ttl_adaptation: bool,
180    /// Enable capacity adaptation
181    pub enable_capacity_adaptation: bool,
182    /// Enable eviction strategy adaptation
183    pub enable_eviction_adaptation: bool,
184    /// Stability window size (number of cycles)
185    pub stability_window: usize,
186}
187
188impl Default for TuningConfig {
189    fn default() -> Self {
190        Self {
191            enable_adaptive_tuning: true,
192            tuning_interval: 300,       // 5 minutes
193            target_hit_rate: 0.9,       // 90% target hit rate
194            min_hit_rate: 0.8,          // 80% minimum hit rate
195            max_adjustment_factor: 0.1, // 10% maximum adjustment
196            min_confidence_for_auto_tuning: 0.8,
197            performance_window_size: 100,
198            min_samples_for_tuning: 10,
199            enable_ttl_adaptation: true,
200            enable_capacity_adaptation: true,
201            enable_eviction_adaptation: false, // Conservative default
202            stability_window: 5,
203        }
204    }
205}
206
207/// Monitoring and statistics configuration
208#[derive(Debug, Clone, Serialize, Deserialize)]
209pub struct MonitoringConfig {
210    /// Enable detailed statistics collection
211    pub enable_detailed_stats: bool,
212    /// Statistics collection interval (in seconds)
213    pub stats_interval: u64,
214    /// Enable performance metrics
215    pub enable_performance_metrics: bool,
216    /// Enable cache event logging
217    pub enable_event_logging: bool,
218    /// Maximum number of events to keep in memory
219    pub max_events_in_memory: usize,
220    /// Enable real-time monitoring
221    pub enable_realtime_monitoring: bool,
222}
223
224impl Default for MonitoringConfig {
225    fn default() -> Self {
226        Self {
227            enable_detailed_stats: true,
228            stats_interval: 60, // 1 minute
229            enable_performance_metrics: true,
230            enable_event_logging: false, // Disabled by default for performance
231            max_events_in_memory: 1000,
232            enable_realtime_monitoring: false, // Disabled by default
233        }
234    }
235}
236
237/// Cache operation timeout configuration
238#[derive(Debug, Clone, Serialize, Deserialize)]
239pub struct TimeoutConfig {
240    /// Timeout for cache get operations
241    pub get_timeout: Duration,
242    /// Timeout for cache put operations
243    pub put_timeout: Duration,
244    /// Timeout for cache cleanup operations
245    pub cleanup_timeout: Duration,
246    /// Timeout for preheating operations
247    pub preheat_timeout: Duration,
248}
249
250impl Default for TimeoutConfig {
251    fn default() -> Self {
252        Self {
253            get_timeout: Duration::from_millis(100),
254            put_timeout: Duration::from_millis(500),
255            cleanup_timeout: Duration::from_secs(30),
256            preheat_timeout: Duration::from_secs(10),
257        }
258    }
259}
260
261impl UnifiedCacheConfig {
262    /// Create a configuration optimized for high performance
263    pub fn high_performance() -> Self {
264        Self {
265            l1_config: L1CacheConfig {
266                max_entries: 50000,
267                max_memory_bytes: 500 * 1024 * 1024, // 500 MB
268                enable_concurrent_access: true,
269                shard_count: num_cpus::get() * 2,
270                ..Default::default()
271            },
272            l2_config: L2CacheConfig {
273                max_entries: 500000,
274                max_disk_bytes: 5 * 1024 * 1024 * 1024, // 5 GB
275                enable_compression: true,
276                enable_background_cleanup: true,
277                ..Default::default()
278            },
279            preheating_config: PreheatingConfig {
280                enable_predictive_preheating: true,
281                min_confidence_threshold: 0.6,
282                max_preheat_entries: 500,
283                max_cpu_usage: 0.2, // 20% CPU usage
284                ..Default::default()
285            },
286            tuning_config: TuningConfig {
287                enable_adaptive_tuning: true,
288                tuning_interval: 120,        // 2 minutes
289                max_adjustment_factor: 0.15, // 15% adjustment
290                ..Default::default()
291            },
292            monitoring_config: MonitoringConfig {
293                enable_detailed_stats: true,
294                enable_performance_metrics: true,
295                enable_realtime_monitoring: true,
296                ..Default::default()
297            },
298        }
299    }
300
301    /// Create a configuration optimized for low memory usage
302    pub fn low_memory() -> Self {
303        Self {
304            l1_config: L1CacheConfig {
305                max_entries: 1000,
306                max_memory_bytes: 10 * 1024 * 1024, // 10 MB
307                ..Default::default()
308            },
309            l2_config: L2CacheConfig {
310                max_entries: 10000,
311                max_disk_bytes: 100 * 1024 * 1024, // 100 MB
312                enable_compression: true,
313                ..Default::default()
314            },
315            preheating_config: PreheatingConfig {
316                enable_predictive_preheating: false, // Disable preheating to save memory
317                ..Default::default()
318            },
319            tuning_config: TuningConfig {
320                enable_adaptive_tuning: false, // Disable tuning to save CPU
321                ..Default::default()
322            },
323            monitoring_config: MonitoringConfig {
324                enable_detailed_stats: false,
325                enable_performance_metrics: false,
326                ..Default::default()
327            },
328        }
329    }
330
331    /// Validate the configuration
332    pub fn validate(&self) -> Result<(), String> {
333        if self.l1_config.max_entries == 0 {
334            return Err("L1 max_entries must be greater than 0".to_string());
335        }
336
337        if self.l2_config.max_entries == 0 {
338            return Err("L2 max_entries must be greater than 0".to_string());
339        }
340
341        if self.preheating_config.min_confidence_threshold < 0.0
342            || self.preheating_config.min_confidence_threshold > 1.0
343        {
344            return Err(
345                "Preheating min_confidence_threshold must be between 0.0 and 1.0".to_string(),
346            );
347        }
348
349        if self.tuning_config.min_hit_rate < 0.0 || self.tuning_config.min_hit_rate > 1.0 {
350            return Err("Tuning min_hit_rate must be between 0.0 and 1.0".to_string());
351        }
352
353        Ok(())
354    }
355}
356
357#[cfg(test)]
358mod tests {
359    use super::*;
360
361    #[test]
362    fn test_default_config() {
363        let config = UnifiedCacheConfig::default();
364        assert!(config.validate().is_ok());
365    }
366
367    #[test]
368    fn test_high_performance_config() {
369        let config = UnifiedCacheConfig::high_performance();
370        assert!(config.validate().is_ok());
371        assert!(config.l1_config.max_entries > DEFAULT_L1_CAPACITY);
372    }
373
374    #[test]
375    fn test_low_memory_config() {
376        let config = UnifiedCacheConfig::low_memory();
377        assert!(config.validate().is_ok());
378        assert!(config.l1_config.max_entries < DEFAULT_L1_CAPACITY);
379        assert!(!config.preheating_config.enable_predictive_preheating);
380    }
381
382    #[test]
383    fn test_config_validation() {
384        let mut config = UnifiedCacheConfig::default();
385        config.l1_config.max_entries = 0;
386        assert!(config.validate().is_err());
387    }
388}