1use 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#[derive(Debug, Clone, Serialize, Deserialize, Default)]
20pub struct UnifiedCacheConfig {
21 pub l1_config: L1CacheConfig,
23 pub l2_config: L2CacheConfig,
25 pub preheating_config: PreheatingConfig,
27 pub tuning_config: TuningConfig,
29 pub monitoring_config: MonitoringConfig,
31}
32
33#[derive(Debug, Clone, Serialize, Deserialize)]
35pub struct L1CacheConfig {
36 pub max_entries: usize,
38 pub max_memory_bytes: u64,
40 pub default_ttl: u64,
42 pub eviction_strategy: EvictionStrategy,
44 pub enable_concurrent_access: bool,
46 pub shard_count: usize,
48 pub promotion_threshold: u64,
50}
51
52impl Default for L1CacheConfig {
53 fn default() -> Self {
54 Self {
55 max_entries: DEFAULT_L1_CAPACITY,
56 max_memory_bytes: DEFAULT_MEMORY_LIMIT_MB * 1024 * 1024,
57 default_ttl: DEFAULT_TTL_SECONDS,
58 eviction_strategy: EvictionStrategy::LRU,
59 enable_concurrent_access: true,
60 shard_count: 0, promotion_threshold: 3, }
63 }
64}
65
66#[derive(Debug, Clone, Serialize, Deserialize)]
68pub struct L2CacheConfig {
69 pub max_entries: usize,
71 pub max_disk_bytes: u64,
73 pub default_ttl: u64,
75 pub cache_dir: PathBuf,
77 pub enable_compression: bool,
79 pub cleanup_interval: u64,
81 pub enable_background_cleanup: bool,
83}
84
85impl Default for L2CacheConfig {
86 fn default() -> Self {
87 Self {
88 max_entries: DEFAULT_L2_CAPACITY,
89 max_disk_bytes: 1024 * 1024 * 1024, default_ttl: DEFAULT_TTL_SECONDS * 24, cache_dir: PathBuf::from(".rez_intelligent_cache"),
92 enable_compression: true,
93 cleanup_interval: 300, enable_background_cleanup: true,
95 }
96 }
97}
98
99#[derive(Debug, Clone, Serialize, Deserialize)]
101pub struct PreheatingConfig {
102 pub enable_predictive_preheating: bool,
104 pub enable_pattern_learning: bool,
106 pub min_confidence_threshold: f64,
108 pub max_preheat_entries: usize,
110 pub max_concurrent_preheats: usize,
112 pub max_preheat_queue_size: usize,
114 pub preheat_interval: u64,
116 pub preheat_window_seconds: u64,
118 pub pattern_window_seconds: u64,
120 pub enable_background_preheat: bool,
122 pub max_cpu_usage: f64,
124 pub history_size: usize,
126}
127
128impl Default for PreheatingConfig {
129 fn default() -> Self {
130 Self {
131 enable_predictive_preheating: true,
132 enable_pattern_learning: true,
133 min_confidence_threshold: 0.7,
134 max_preheat_entries: 100,
135 max_concurrent_preheats: 10,
136 max_preheat_queue_size: 1000,
137 preheat_interval: 60, preheat_window_seconds: 300, pattern_window_seconds: 3600, enable_background_preheat: true,
141 max_cpu_usage: 0.1, history_size: 10000,
143 }
144 }
145}
146
147#[derive(Debug, Clone, Serialize, Deserialize)]
149pub struct TuningConfig {
150 pub enable_adaptive_tuning: bool,
152 pub tuning_interval: u64,
154 pub target_hit_rate: f64,
156 pub min_hit_rate: f64,
158 pub max_adjustment_factor: f64,
160 pub min_confidence_for_auto_tuning: f64,
162 pub performance_window_size: usize,
164 pub min_samples_for_tuning: usize,
166 pub enable_ttl_adaptation: bool,
168 pub enable_capacity_adaptation: bool,
170 pub enable_eviction_adaptation: bool,
172 pub stability_window: usize,
174}
175
176impl Default for TuningConfig {
177 fn default() -> Self {
178 Self {
179 enable_adaptive_tuning: true,
180 tuning_interval: 300, target_hit_rate: 0.9, min_hit_rate: 0.8, max_adjustment_factor: 0.1, min_confidence_for_auto_tuning: 0.8,
185 performance_window_size: 100,
186 min_samples_for_tuning: 10,
187 enable_ttl_adaptation: true,
188 enable_capacity_adaptation: true,
189 enable_eviction_adaptation: false, stability_window: 5,
191 }
192 }
193}
194
195#[derive(Debug, Clone, Serialize, Deserialize)]
197pub struct MonitoringConfig {
198 pub enable_detailed_stats: bool,
200 pub stats_interval: u64,
202 pub enable_performance_metrics: bool,
204 pub enable_event_logging: bool,
206 pub max_events_in_memory: usize,
208 pub enable_realtime_monitoring: bool,
210}
211
212impl Default for MonitoringConfig {
213 fn default() -> Self {
214 Self {
215 enable_detailed_stats: true,
216 stats_interval: 60, enable_performance_metrics: true,
218 enable_event_logging: false, max_events_in_memory: 1000,
220 enable_realtime_monitoring: false, }
222 }
223}
224
225#[derive(Debug, Clone, Serialize, Deserialize)]
227pub struct TimeoutConfig {
228 pub get_timeout: Duration,
230 pub put_timeout: Duration,
232 pub cleanup_timeout: Duration,
234 pub preheat_timeout: Duration,
236}
237
238impl Default for TimeoutConfig {
239 fn default() -> Self {
240 Self {
241 get_timeout: Duration::from_millis(100),
242 put_timeout: Duration::from_millis(500),
243 cleanup_timeout: Duration::from_secs(30),
244 preheat_timeout: Duration::from_secs(10),
245 }
246 }
247}
248
249impl UnifiedCacheConfig {
250 pub fn high_performance() -> Self {
252 Self {
253 l1_config: L1CacheConfig {
254 max_entries: 50000,
255 max_memory_bytes: 500 * 1024 * 1024, enable_concurrent_access: true,
257 shard_count: num_cpus::get() * 2,
258 ..Default::default()
259 },
260 l2_config: L2CacheConfig {
261 max_entries: 500000,
262 max_disk_bytes: 5 * 1024 * 1024 * 1024, enable_compression: true,
264 enable_background_cleanup: true,
265 ..Default::default()
266 },
267 preheating_config: PreheatingConfig {
268 enable_predictive_preheating: true,
269 min_confidence_threshold: 0.6,
270 max_preheat_entries: 500,
271 max_cpu_usage: 0.2, ..Default::default()
273 },
274 tuning_config: TuningConfig {
275 enable_adaptive_tuning: true,
276 tuning_interval: 120, max_adjustment_factor: 0.15, ..Default::default()
279 },
280 monitoring_config: MonitoringConfig {
281 enable_detailed_stats: true,
282 enable_performance_metrics: true,
283 enable_realtime_monitoring: true,
284 ..Default::default()
285 },
286 }
287 }
288
289 pub fn low_memory() -> Self {
291 Self {
292 l1_config: L1CacheConfig {
293 max_entries: 1000,
294 max_memory_bytes: 10 * 1024 * 1024, ..Default::default()
296 },
297 l2_config: L2CacheConfig {
298 max_entries: 10000,
299 max_disk_bytes: 100 * 1024 * 1024, enable_compression: true,
301 ..Default::default()
302 },
303 preheating_config: PreheatingConfig {
304 enable_predictive_preheating: false, ..Default::default()
306 },
307 tuning_config: TuningConfig {
308 enable_adaptive_tuning: false, ..Default::default()
310 },
311 monitoring_config: MonitoringConfig {
312 enable_detailed_stats: false,
313 enable_performance_metrics: false,
314 ..Default::default()
315 },
316 }
317 }
318
319 pub fn validate(&self) -> Result<(), String> {
321 if self.l1_config.max_entries == 0 {
322 return Err("L1 max_entries must be greater than 0".to_string());
323 }
324
325 if self.l2_config.max_entries == 0 {
326 return Err("L2 max_entries must be greater than 0".to_string());
327 }
328
329 if self.preheating_config.min_confidence_threshold < 0.0
330 || self.preheating_config.min_confidence_threshold > 1.0
331 {
332 return Err(
333 "Preheating min_confidence_threshold must be between 0.0 and 1.0".to_string(),
334 );
335 }
336
337 if self.tuning_config.min_hit_rate < 0.0 || self.tuning_config.min_hit_rate > 1.0 {
338 return Err("Tuning min_hit_rate must be between 0.0 and 1.0".to_string());
339 }
340
341 Ok(())
342 }
343}
344
345#[cfg(test)]
346mod tests {
347 use super::*;
348
349 #[test]
350 fn test_default_config() {
351 let config = UnifiedCacheConfig::default();
352 assert!(config.validate().is_ok());
353 }
354
355 #[test]
356 fn test_high_performance_config() {
357 let config = UnifiedCacheConfig::high_performance();
358 assert!(config.validate().is_ok());
359 assert!(config.l1_config.max_entries > DEFAULT_L1_CAPACITY);
360 }
361
362 #[test]
363 fn test_low_memory_config() {
364 let config = UnifiedCacheConfig::low_memory();
365 assert!(config.validate().is_ok());
366 assert!(config.l1_config.max_entries < DEFAULT_L1_CAPACITY);
367 assert!(!config.preheating_config.enable_predictive_preheating);
368 }
369
370 #[test]
371 fn test_config_validation() {
372 let mut config = UnifiedCacheConfig::default();
373 config.l1_config.max_entries = 0;
374 assert!(config.validate().is_err());
375 }
376}