1#![allow(dead_code)]
8
9use crate::{similarity::SimilarityMetric, Vector, VectorId};
10use anyhow::Result;
11use serde::{Deserialize, Serialize};
12use std::collections::{BTreeMap, HashMap, VecDeque};
13use std::hash::{Hash, Hasher};
14use std::sync::atomic::{AtomicU64, Ordering};
15use std::time::{Duration, Instant, SystemTime};
16use tracing::{debug, info, warn};
17
18#[derive(Debug)]
20pub struct AdaptiveIntelligentCache {
21 tiers: Vec<CacheTier>,
23 pattern_analyzer: AccessPatternAnalyzer,
25 prefetcher: PredictivePrefetcher,
27 optimizer: CacheOptimizer,
29 metrics: CachePerformanceMetrics,
31 config: CacheConfiguration,
33 ml_models: MLModels,
35}
36
37#[derive(Debug)]
39pub struct CacheTier {
40 #[allow(dead_code)]
42 tier_id: u32,
43 storage: Box<dyn CacheStorage>,
45 eviction_policy: Box<dyn EvictionPolicy>,
47 access_tracker: AccessTracker,
49 config: TierConfiguration,
51 stats: TierStatistics,
53}
54
55#[allow(dead_code)]
57#[derive(Debug, Clone)]
58pub struct AccessPatternAnalyzer {
59 access_history: VecDeque<AccessEvent>,
61 seasonal_detector: SeasonalPatternDetector,
63 query_clustering: QueryClusteringEngine,
65 temporal_predictor: TemporalAccessPredictor,
67}
68
69#[allow(dead_code)]
71#[derive(Debug)]
72pub struct PredictivePrefetcher {
73 prefetch_queue: VecDeque<PrefetchItem>,
75 models: PrefetchModels,
77 strategies: Vec<PrefetchStrategy>,
79 performance: PrefetchPerformance,
81}
82
83#[allow(dead_code)]
85#[derive(Debug)]
86pub struct CacheOptimizer {
87 algorithms: Vec<Box<dyn OptimizationAlgorithm>>,
89 optimization_history: Vec<OptimizationEvent>,
91 current_state: OptimizationState,
93 improvements: ImprovementTracker,
95}
96
97#[derive(Debug, Default)]
99pub struct CachePerformanceMetrics {
100 pub hit_count: AtomicU64,
102 pub miss_count: AtomicU64,
103 pub total_requests: AtomicU64,
104
105 pub avg_hit_latency_ns: AtomicU64,
107 pub avg_miss_latency_ns: AtomicU64,
108 pub p99_latency_ns: AtomicU64,
109
110 pub requests_per_second: AtomicU64,
112 pub bytes_per_second: AtomicU64,
113
114 pub cache_efficiency_score: f64,
116 pub memory_utilization: f64,
117 pub fragmentation_ratio: f64,
118
119 pub tier_metrics: HashMap<u32, TierMetrics>,
121
122 pub historical_metrics: VecDeque<HistoricalMetric>,
124}
125
126impl Clone for CachePerformanceMetrics {
127 fn clone(&self) -> Self {
128 Self {
129 hit_count: AtomicU64::new(self.hit_count.load(Ordering::SeqCst)),
130 miss_count: AtomicU64::new(self.miss_count.load(Ordering::SeqCst)),
131 total_requests: AtomicU64::new(self.total_requests.load(Ordering::SeqCst)),
132 avg_hit_latency_ns: AtomicU64::new(self.avg_hit_latency_ns.load(Ordering::SeqCst)),
133 avg_miss_latency_ns: AtomicU64::new(self.avg_miss_latency_ns.load(Ordering::SeqCst)),
134 p99_latency_ns: AtomicU64::new(self.p99_latency_ns.load(Ordering::SeqCst)),
135 requests_per_second: AtomicU64::new(self.requests_per_second.load(Ordering::SeqCst)),
136 bytes_per_second: AtomicU64::new(self.bytes_per_second.load(Ordering::SeqCst)),
137 cache_efficiency_score: self.cache_efficiency_score,
138 memory_utilization: self.memory_utilization,
139 fragmentation_ratio: self.fragmentation_ratio,
140 tier_metrics: self.tier_metrics.clone(),
141 historical_metrics: self.historical_metrics.clone(),
142 }
143 }
144}
145
146impl Serialize for CachePerformanceMetrics {
147 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
148 where
149 S: serde::Serializer,
150 {
151 use serde::ser::SerializeStruct;
152 let mut state = serializer.serialize_struct("CachePerformanceMetrics", 11)?;
153 state.serialize_field("hit_count", &self.hit_count.load(Ordering::SeqCst))?;
154 state.serialize_field("miss_count", &self.miss_count.load(Ordering::SeqCst))?;
155 state.serialize_field(
156 "total_requests",
157 &self.total_requests.load(Ordering::SeqCst),
158 )?;
159 state.serialize_field(
160 "avg_hit_latency_ns",
161 &self.avg_hit_latency_ns.load(Ordering::SeqCst),
162 )?;
163 state.serialize_field(
164 "avg_miss_latency_ns",
165 &self.avg_miss_latency_ns.load(Ordering::SeqCst),
166 )?;
167 state.serialize_field(
168 "p99_latency_ns",
169 &self.p99_latency_ns.load(Ordering::SeqCst),
170 )?;
171 state.serialize_field(
172 "requests_per_second",
173 &self.requests_per_second.load(Ordering::SeqCst),
174 )?;
175 state.serialize_field(
176 "bytes_per_second",
177 &self.bytes_per_second.load(Ordering::SeqCst),
178 )?;
179 state.serialize_field("cache_efficiency_score", &self.cache_efficiency_score)?;
180 state.serialize_field("memory_utilization", &self.memory_utilization)?;
181 state.serialize_field("fragmentation_ratio", &self.fragmentation_ratio)?;
182 state.serialize_field("tier_metrics", &self.tier_metrics)?;
183 state.serialize_field("historical_metrics", &self.historical_metrics)?;
184 state.end()
185 }
186}
187
188impl<'de> Deserialize<'de> for CachePerformanceMetrics {
189 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
190 where
191 D: serde::Deserializer<'de>,
192 {
193 use serde::de::{self, MapAccess, Visitor};
194 use std::fmt;
195
196 #[derive(Deserialize)]
197 #[serde(field_identifier, rename_all = "snake_case")]
198 enum Field {
199 HitCount,
200 MissCount,
201 TotalRequests,
202 AvgHitLatencyNs,
203 AvgMissLatencyNs,
204 P99LatencyNs,
205 RequestsPerSecond,
206 BytesPerSecond,
207 CacheEfficiencyScore,
208 MemoryUtilization,
209 FragmentationRatio,
210 TierMetrics,
211 HistoricalMetrics,
212 }
213
214 struct CachePerformanceMetricsVisitor;
215
216 impl<'de> Visitor<'de> for CachePerformanceMetricsVisitor {
217 type Value = CachePerformanceMetrics;
218
219 fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
220 formatter.write_str("struct CachePerformanceMetrics")
221 }
222
223 fn visit_map<V>(self, mut map: V) -> Result<CachePerformanceMetrics, V::Error>
224 where
225 V: MapAccess<'de>,
226 {
227 let mut hit_count = None;
228 let mut miss_count = None;
229 let mut total_requests = None;
230 let mut avg_hit_latency_ns = None;
231 let mut avg_miss_latency_ns = None;
232 let mut p99_latency_ns = None;
233 let mut requests_per_second = None;
234 let mut bytes_per_second = None;
235 let mut cache_efficiency_score = None;
236 let mut memory_utilization = None;
237 let mut fragmentation_ratio = None;
238 let mut tier_metrics = None;
239 let mut historical_metrics = None;
240
241 while let Some(key) = map.next_key()? {
242 match key {
243 Field::HitCount => {
244 if hit_count.is_some() {
245 return Err(de::Error::duplicate_field("hit_count"));
246 }
247 hit_count = Some(map.next_value::<u64>()?);
248 }
249 Field::MissCount => {
250 if miss_count.is_some() {
251 return Err(de::Error::duplicate_field("miss_count"));
252 }
253 miss_count = Some(map.next_value::<u64>()?);
254 }
255 Field::TotalRequests => {
256 if total_requests.is_some() {
257 return Err(de::Error::duplicate_field("total_requests"));
258 }
259 total_requests = Some(map.next_value::<u64>()?);
260 }
261 Field::AvgHitLatencyNs => {
262 if avg_hit_latency_ns.is_some() {
263 return Err(de::Error::duplicate_field("avg_hit_latency_ns"));
264 }
265 avg_hit_latency_ns = Some(map.next_value::<u64>()?);
266 }
267 Field::AvgMissLatencyNs => {
268 if avg_miss_latency_ns.is_some() {
269 return Err(de::Error::duplicate_field("avg_miss_latency_ns"));
270 }
271 avg_miss_latency_ns = Some(map.next_value::<u64>()?);
272 }
273 Field::P99LatencyNs => {
274 if p99_latency_ns.is_some() {
275 return Err(de::Error::duplicate_field("p99_latency_ns"));
276 }
277 p99_latency_ns = Some(map.next_value::<u64>()?);
278 }
279 Field::RequestsPerSecond => {
280 if requests_per_second.is_some() {
281 return Err(de::Error::duplicate_field("requests_per_second"));
282 }
283 requests_per_second = Some(map.next_value::<u64>()?);
284 }
285 Field::BytesPerSecond => {
286 if bytes_per_second.is_some() {
287 return Err(de::Error::duplicate_field("bytes_per_second"));
288 }
289 bytes_per_second = Some(map.next_value::<u64>()?);
290 }
291 Field::CacheEfficiencyScore => {
292 if cache_efficiency_score.is_some() {
293 return Err(de::Error::duplicate_field("cache_efficiency_score"));
294 }
295 cache_efficiency_score = Some(map.next_value()?);
296 }
297 Field::MemoryUtilization => {
298 if memory_utilization.is_some() {
299 return Err(de::Error::duplicate_field("memory_utilization"));
300 }
301 memory_utilization = Some(map.next_value()?);
302 }
303 Field::FragmentationRatio => {
304 if fragmentation_ratio.is_some() {
305 return Err(de::Error::duplicate_field("fragmentation_ratio"));
306 }
307 fragmentation_ratio = Some(map.next_value()?);
308 }
309 Field::TierMetrics => {
310 if tier_metrics.is_some() {
311 return Err(de::Error::duplicate_field("tier_metrics"));
312 }
313 tier_metrics = Some(map.next_value()?);
314 }
315 Field::HistoricalMetrics => {
316 if historical_metrics.is_some() {
317 return Err(de::Error::duplicate_field("historical_metrics"));
318 }
319 historical_metrics = Some(map.next_value()?);
320 }
321 }
322 }
323
324 Ok(CachePerformanceMetrics {
325 hit_count: AtomicU64::new(hit_count.unwrap_or(0)),
326 miss_count: AtomicU64::new(miss_count.unwrap_or(0)),
327 total_requests: AtomicU64::new(total_requests.unwrap_or(0)),
328 avg_hit_latency_ns: AtomicU64::new(avg_hit_latency_ns.unwrap_or(0)),
329 avg_miss_latency_ns: AtomicU64::new(avg_miss_latency_ns.unwrap_or(0)),
330 p99_latency_ns: AtomicU64::new(p99_latency_ns.unwrap_or(0)),
331 requests_per_second: AtomicU64::new(requests_per_second.unwrap_or(0)),
332 bytes_per_second: AtomicU64::new(bytes_per_second.unwrap_or(0)),
333 cache_efficiency_score: cache_efficiency_score.unwrap_or(0.0),
334 memory_utilization: memory_utilization.unwrap_or(0.0),
335 fragmentation_ratio: fragmentation_ratio.unwrap_or(0.0),
336 tier_metrics: tier_metrics.unwrap_or_default(),
337 historical_metrics: historical_metrics.unwrap_or_default(),
338 })
339 }
340 }
341
342 deserializer.deserialize_struct(
343 "CachePerformanceMetrics",
344 &[
345 "hit_count",
346 "miss_count",
347 "total_requests",
348 "avg_hit_latency_ns",
349 "avg_miss_latency_ns",
350 "p99_latency_ns",
351 "requests_per_second",
352 "bytes_per_second",
353 "cache_efficiency_score",
354 "memory_utilization",
355 "fragmentation_ratio",
356 "tier_metrics",
357 "historical_metrics",
358 ],
359 CachePerformanceMetricsVisitor,
360 )
361 }
362}
363
364#[derive(Debug, Clone, Serialize, Deserialize)]
366pub struct CacheConfiguration {
367 pub max_total_size_bytes: u64,
369 pub num_tiers: u32,
371 pub tier_size_ratios: Vec<f64>,
373 pub default_ttl_seconds: u64,
375 pub optimization_interval_seconds: u64,
377 pub ml_update_interval_seconds: u64,
379 pub enable_prefetching: bool,
381 pub enable_adaptive_optimization: bool,
383 pub monitoring_config: MonitoringConfiguration,
385}
386
387#[derive(Debug)]
389pub struct MLModels {
390 access_predictor: AccessPredictionModel,
392 hit_probability_model: HitProbabilityModel,
394 tier_placement_model: TierPlacementModel,
396 eviction_timing_model: EvictionTimingModel,
398}
399
400pub trait CacheStorage: Send + Sync + std::fmt::Debug {
402 fn store(&mut self, key: CacheKey, value: CacheValue, ttl: Option<Duration>) -> Result<()>;
404
405 fn retrieve(&self, key: &CacheKey) -> Option<CacheValue>;
407
408 fn remove(&mut self, key: &CacheKey) -> bool;
410
411 fn size_info(&self) -> CacheSizeInfo;
413
414 fn clear(&mut self);
416
417 fn statistics(&self) -> StorageStatistics;
419}
420
421pub trait EvictionPolicy: Send + Sync + std::fmt::Debug {
423 fn evict(&mut self, current_size: u64, target_size: u64, items: &[CacheItem]) -> Vec<CacheKey>;
425
426 fn on_access(&mut self, key: &CacheKey, access_time: Instant);
428
429 fn on_store(&mut self, key: &CacheKey, size: u64, store_time: Instant);
431
432 fn statistics(&self) -> EvictionStatistics;
434}
435
436pub trait OptimizationAlgorithm: Send + Sync + std::fmt::Debug {
438 fn optimize_cache(
440 &mut self,
441 tiers: &[CacheTier],
442 metrics: &CachePerformanceMetrics,
443 config: &CacheConfiguration,
444 ) -> Result<OptimizationResult>;
445
446 fn name(&self) -> &str;
448
449 fn score(&self, metrics: &CachePerformanceMetrics) -> f64;
451}
452
453#[derive(Debug, Clone, PartialEq)]
456pub struct CacheKey {
457 pub query_vector: Vec<u8>, pub similarity_metric: SimilarityMetric,
459 pub parameters: HashMap<String, String>,
460}
461
462impl Hash for CacheKey {
463 fn hash<H: Hasher>(&self, state: &mut H) {
464 self.query_vector.hash(state);
465 std::mem::discriminant(&self.similarity_metric).hash(state);
467 let mut params: Vec<_> = self.parameters.iter().collect();
469 params.sort_by_key(|(k, _)| *k);
470 params.hash(state);
471 }
472}
473
474impl Eq for CacheKey {}
475
476#[derive(Debug, Clone)]
477pub struct CacheValue {
478 pub results: Vec<(VectorId, f32)>, pub metadata: CacheMetadata,
480 pub created_at: SystemTime,
481 pub last_accessed: SystemTime,
482 pub access_count: u32,
483}
484
485#[derive(Debug, Clone)]
486pub struct CacheMetadata {
487 pub size_bytes: u64,
488 pub computation_cost: f64,
489 pub quality_score: f64,
490 pub staleness_factor: f64,
491}
492
493#[derive(Debug, Clone)]
494pub struct AccessEvent {
495 pub timestamp: SystemTime,
496 pub key: CacheKey,
497 pub hit: bool,
498 pub latency_ns: u64,
499 pub user_context: Option<String>,
500}
501
502#[derive(Debug, Clone)]
503pub struct PrefetchItem {
504 pub key: CacheKey,
505 pub priority: f64,
506 pub predicted_access_time: SystemTime,
507 pub confidence: f64,
508 pub strategy: PrefetchStrategy,
509}
510
511#[derive(Debug, Clone, Copy, PartialEq, Eq)]
512pub enum PrefetchStrategy {
513 SequentialPattern,
514 SeasonalPattern,
515 SimilarityBased,
516 UserBehavior,
517 MachineLearning,
518}
519
520#[derive(Debug, Clone)]
521pub struct CacheItem {
522 pub key: CacheKey,
523 pub value: CacheValue,
524 pub tier_id: u32,
525 pub last_access: Instant,
526 pub access_frequency: f64,
527}
528
529#[derive(Debug, Clone, Default)]
530pub struct CacheSizeInfo {
531 pub used_bytes: u64,
532 pub available_bytes: u64,
533 pub total_capacity_bytes: u64,
534 pub item_count: u64,
535}
536
537#[derive(Debug, Clone, Default)]
538pub struct StorageStatistics {
539 pub read_operations: u64,
540 pub write_operations: u64,
541 pub delete_operations: u64,
542 pub avg_operation_latency_ns: u64,
543 pub fragmentation_ratio: f64,
544}
545
546#[derive(Debug, Clone, Default)]
547pub struct EvictionStatistics {
548 pub total_evictions: u64,
549 pub false_evictions: u64, pub eviction_accuracy: f64,
551 pub avg_item_lifetime: Duration,
552}
553
554#[derive(Debug, Clone)]
555pub struct OptimizationResult {
556 pub improvement_score: f64,
557 pub changes_applied: Vec<OptimizationChange>,
558 pub estimated_impact: EstimatedImpact,
559}
560
561#[derive(Debug, Clone)]
562pub struct OptimizationChange {
563 pub change_type: OptimizationChangeType,
564 pub description: String,
565 pub tier_id: Option<u32>,
566 pub old_value: String,
567 pub new_value: String,
568}
569
570#[derive(Debug, Clone, Copy)]
571pub enum OptimizationChangeType {
572 TierSizeAdjustment,
573 EvictionPolicyChange,
574 TTLAdjustment,
575 PrefetchingStrategy,
576 TierRebalancing,
577}
578
579#[derive(Debug, Clone, Default)]
580pub struct EstimatedImpact {
581 pub hit_rate_improvement: f64,
582 pub latency_reduction: f64,
583 pub memory_efficiency_gain: f64,
584 pub cost_reduction: f64,
585}
586
587#[derive(Debug, Clone)]
589pub struct TierConfiguration {
590 pub max_size_bytes: u64,
591 pub default_ttl: Duration,
592 pub compression_enabled: bool,
593 pub persistence_enabled: bool,
594 pub replication_factor: u32,
595}
596
597#[derive(Debug, Clone, Default, Serialize, Deserialize)]
598pub struct TierStatistics {
599 pub hit_count: u64,
600 pub miss_count: u64,
601 pub eviction_count: u64,
602 pub size_bytes: u64,
603 pub item_count: u64,
604 pub avg_access_time: Duration,
605}
606
607#[derive(Debug, Clone, Default, Serialize, Deserialize)]
608pub struct TierMetrics {
609 pub hit_rate: f64,
610 pub utilization: f64,
611 pub avg_item_size: u64,
612 pub hotness_score: f64,
613}
614
615#[derive(Debug, Clone, Serialize, Deserialize)]
616pub struct HistoricalMetric {
617 pub timestamp: SystemTime,
618 pub hit_rate: f64,
619 pub latency_p99: u64,
620 pub throughput: f64,
621 pub memory_usage: u64,
622}
623
624#[derive(Debug, Clone)]
625pub struct AccessTracker {
626 access_counts: HashMap<CacheKey, u64>,
627 access_times: HashMap<CacheKey, VecDeque<SystemTime>>,
628 hot_keys: BTreeMap<u64, CacheKey>, }
630
631#[derive(Debug, Clone)]
632pub struct SeasonalPatternDetector {
633 hourly_patterns: [f64; 24],
634 daily_patterns: [f64; 7],
635 monthly_patterns: [f64; 31],
636 pattern_confidence: f64,
637}
638
639#[derive(Debug, Clone)]
640pub struct QueryClusteringEngine {
641 clusters: Vec<QueryCluster>,
642 cluster_assignments: HashMap<CacheKey, u32>,
643 cluster_centroids: Vec<Vector>,
644}
645
646#[derive(Debug, Clone)]
647pub struct QueryCluster {
648 pub cluster_id: u32,
649 pub centroid: Vector,
650 pub members: Vec<CacheKey>,
651 pub access_pattern: AccessPattern,
652}
653
654#[derive(Debug, Clone)]
655pub struct AccessPattern {
656 pub frequency: f64,
657 pub seasonality: SeasonalityInfo,
658 pub correlation_score: f64,
659}
660
661#[derive(Debug, Clone)]
662pub struct SeasonalityInfo {
663 pub has_daily_pattern: bool,
664 pub has_weekly_pattern: bool,
665 pub peak_hours: Vec<u8>,
666 pub peak_days: Vec<u8>,
667}
668
669#[derive(Debug, Clone)]
670pub struct TemporalAccessPredictor {
671 time_series_models: HashMap<CacheKey, TimeSeriesModel>,
672 global_trend_model: GlobalTrendModel,
673 prediction_horizon: Duration,
674}
675
676#[derive(Debug, Clone)]
677pub struct TimeSeriesModel {
678 pub coefficients: Vec<f64>,
679 pub seasonal_components: Vec<f64>,
680 pub trend_component: f64,
681 pub accuracy_score: f64,
682}
683
684#[derive(Debug, Clone)]
685pub struct GlobalTrendModel {
686 pub hourly_multipliers: [f64; 24],
687 pub daily_multipliers: [f64; 7],
688 pub base_rate: f64,
689}
690
691#[derive(Debug, Clone)]
692pub struct PrefetchModels {
693 pub similarity_model: SimilarityPrefetchModel,
694 pub sequence_model: SequencePrefetchModel,
695 pub user_behavior_model: UserBehaviorModel,
696}
697
698#[derive(Debug, Clone)]
699pub struct SimilarityPrefetchModel {
700 pub similarity_threshold: f64,
701 pub prefetch_depth: u32,
702 pub confidence_weights: Vec<f64>,
703}
704
705#[derive(Debug, Clone)]
706pub struct SequencePrefetchModel {
707 pub sequence_patterns: HashMap<Vec<CacheKey>, f64>, pub max_sequence_length: u32,
709 pub min_confidence: f64,
710}
711
712#[derive(Debug, Clone)]
713pub struct UserBehaviorModel {
714 pub user_profiles: HashMap<String, UserProfile>,
715 pub default_profile: UserProfile,
716}
717
718#[derive(Debug, Clone)]
719pub struct UserProfile {
720 pub typical_query_patterns: Vec<QueryPattern>,
721 pub access_frequency: f64,
722 pub preference_weights: HashMap<SimilarityMetric, f64>,
723}
724
725#[derive(Debug, Clone)]
726pub struct QueryPattern {
727 pub pattern_vector: Vector,
728 pub frequency: f64,
729 pub time_distribution: Vec<f64>, }
731
732#[derive(Debug, Clone)]
733pub struct PrefetchPerformance {
734 pub successful_prefetches: u64,
735 pub failed_prefetches: u64,
736 pub cache_space_saved: u64,
737 pub avg_prediction_accuracy: f64,
738}
739
740#[derive(Debug, Clone)]
741pub struct OptimizationEvent {
742 pub timestamp: SystemTime,
743 pub algorithm: String,
744 pub changes: Vec<OptimizationChange>,
745 pub before_metrics: CachePerformanceMetrics,
746 pub after_metrics: Option<CachePerformanceMetrics>,
747}
748
749#[derive(Debug, Clone)]
750pub struct OptimizationState {
751 pub last_optimization: SystemTime,
752 pub optimization_frequency: Duration,
753 pub pending_optimizations: Vec<String>,
754 pub optimization_backlog: u32,
755}
756
757#[derive(Debug, Clone)]
758pub struct ImprovementTracker {
759 pub baseline_metrics: CachePerformanceMetrics,
760 pub current_improvement: f64,
761 pub improvement_history: VecDeque<ImprovementPoint>,
762 pub regression_detection: RegressionDetector,
763}
764
765#[derive(Debug, Clone)]
766pub struct ImprovementPoint {
767 pub timestamp: SystemTime,
768 pub improvement_score: f64,
769 pub optimization_applied: String,
770}
771
772#[derive(Debug, Clone)]
773pub struct RegressionDetector {
774 pub regression_threshold: f64,
775 pub detection_window: Duration,
776 pub recent_scores: VecDeque<f64>,
777}
778
779#[derive(Debug, Clone)]
780pub struct AccessPredictionModel {
781 pub model_weights: Vec<f64>,
782 pub feature_extractors: Vec<FeatureExtractor>,
783 pub prediction_accuracy: f64,
784}
785
786#[derive(Debug, Clone)]
787pub struct HitProbabilityModel {
788 pub probability_matrix: HashMap<(CacheKey, u32), f64>, pub model_confidence: f64,
790 pub last_update: SystemTime,
791}
792
793#[derive(Debug, Clone)]
794pub struct TierPlacementModel {
795 pub placement_scores: HashMap<CacheKey, Vec<f64>>, pub optimization_objective: OptimizationObjective,
797}
798
799#[derive(Debug, Clone)]
800pub struct EvictionTimingModel {
801 pub survival_functions: HashMap<CacheKey, SurvivalFunction>,
802 pub hazard_rates: HashMap<CacheKey, f64>,
803}
804
805#[derive(Debug, Clone)]
806pub struct SurvivalFunction {
807 pub time_points: Vec<Duration>,
808 pub survival_probabilities: Vec<f64>,
809}
810
811#[derive(Debug, Clone)]
812pub enum FeatureExtractor {
813 AccessFrequency,
814 RecencyScore,
815 SizeMetric,
816 ComputationCost,
817 UserContext,
818 TemporalFeatures,
819}
820
821#[derive(Debug, Clone, Copy)]
822pub enum OptimizationObjective {
823 MaximizeHitRate,
824 MinimizeLatency,
825 MaximizeThroughput,
826 MinimizeCost,
827 BalancedPerformance,
828}
829
830#[derive(Debug, Clone, Serialize, Deserialize)]
831pub struct MonitoringConfiguration {
832 pub enable_detailed_metrics: bool,
833 pub metrics_retention_days: u32,
834 pub alert_thresholds: AlertThresholds,
835 pub export_prometheus: bool,
836}
837
838#[derive(Debug, Clone, Serialize, Deserialize)]
839pub struct AlertThresholds {
840 pub min_hit_rate: f64,
841 pub max_latency_p99_ms: f64,
842 pub max_memory_utilization: f64,
843 pub min_cache_efficiency: f64,
844}
845
846impl AdaptiveIntelligentCache {
847 pub fn new(config: CacheConfiguration) -> Result<Self> {
849 info!(
850 "Initializing Adaptive Intelligent Cache with {} tiers",
851 config.num_tiers
852 );
853
854 let mut tiers = Vec::new();
855 let tier_sizes = Self::calculate_tier_sizes(&config);
856
857 for (tier_id, size) in tier_sizes.into_iter().enumerate() {
858 let tier_config = TierConfiguration {
859 max_size_bytes: size,
860 default_ttl: Duration::from_secs(config.default_ttl_seconds),
861 compression_enabled: tier_id > 0, persistence_enabled: tier_id == config.num_tiers as usize - 1, replication_factor: if tier_id == 0 { 1 } else { 2 }, };
865
866 let storage = Self::create_storage_for_tier(tier_id as u32, &tier_config)?;
867 let eviction_policy = Self::create_eviction_policy_for_tier(tier_id as u32);
868
869 let tier = CacheTier {
870 tier_id: tier_id as u32,
871 storage,
872 eviction_policy,
873 access_tracker: AccessTracker::new(),
874 config: tier_config,
875 stats: TierStatistics::default(),
876 };
877
878 tiers.push(tier);
879 }
880
881 Ok(Self {
882 tiers,
883 pattern_analyzer: AccessPatternAnalyzer::new(),
884 prefetcher: PredictivePrefetcher::new(),
885 optimizer: CacheOptimizer::new(),
886 metrics: CachePerformanceMetrics::default(),
887 config,
888 ml_models: MLModels::new()?,
889 })
890 }
891
892 pub fn store(&mut self, key: CacheKey, value: CacheValue) -> Result<()> {
894 let start_time = Instant::now();
895
896 let optimal_tier = self
898 .ml_models
899 .tier_placement_model
900 .predict_optimal_tier(&key, &value);
901
902 let tier = &mut self.tiers[optimal_tier as usize];
904 tier.storage
905 .store(key.clone(), value.clone(), Some(tier.config.default_ttl))?;
906
907 tier.access_tracker.on_store(&key);
909 self.update_store_metrics(optimal_tier, start_time.elapsed());
910
911 self.check_and_evict(optimal_tier)?;
913
914 self.ml_models
916 .update_with_store_event(&key, &value, optimal_tier);
917
918 debug!(
919 "Stored cache item in tier {} with key hash {:?}",
920 optimal_tier,
921 self.hash_key(&key)
922 );
923 Ok(())
924 }
925
926 pub fn retrieve(&mut self, key: &CacheKey) -> Option<CacheValue> {
928 let start_time = Instant::now();
929
930 for (tier_index, tier) in self.tiers.iter_mut().enumerate() {
932 if let Some(mut value) = tier.storage.retrieve(key) {
933 value.last_accessed = SystemTime::now();
935 value.access_count += 1;
936
937 tier.access_tracker.on_access(key, Instant::now());
938 self.update_hit_metrics(tier_index as u32, start_time.elapsed());
939
940 if tier_index > 0 && self.should_promote(key, &value, tier_index) {
942 if let Err(e) = self.promote_item(key.clone(), value.clone(), tier_index) {
943 warn!("Failed to promote cache item: {}", e);
944 }
945 }
946
947 self.pattern_analyzer.record_access(AccessEvent {
949 timestamp: SystemTime::now(),
950 key: key.clone(),
951 hit: true,
952 latency_ns: start_time.elapsed().as_nanos() as u64,
953 user_context: None, });
955
956 if self.config.enable_prefetching {
958 self.prefetcher.trigger_prefetch_analysis(key, &value);
959 }
960
961 return Some(value);
962 }
963 }
964
965 self.update_miss_metrics(start_time.elapsed());
967 self.pattern_analyzer.record_access(AccessEvent {
968 timestamp: SystemTime::now(),
969 key: key.clone(),
970 hit: false,
971 latency_ns: start_time.elapsed().as_nanos() as u64,
972 user_context: None,
973 });
974
975 None
976 }
977
978 pub fn remove(&mut self, key: &CacheKey) -> bool {
980 let mut removed = false;
981 for tier in &mut self.tiers {
982 if tier.storage.remove(key) {
983 tier.access_tracker.on_remove(key);
984 removed = true;
985 }
986 }
987 removed
988 }
989
990 pub fn get_statistics(&self) -> CacheStatistics {
992 let total_hits = self.metrics.hit_count.load(Ordering::Relaxed);
993 let total_misses = self.metrics.miss_count.load(Ordering::Relaxed);
994 let total_requests = total_hits + total_misses;
995
996 let hit_rate = if total_requests > 0 {
997 total_hits as f64 / total_requests as f64
998 } else {
999 0.0
1000 };
1001
1002 CacheStatistics {
1003 hit_rate,
1004 miss_rate: 1.0 - hit_rate,
1005 total_requests,
1006 avg_hit_latency_ns: self.metrics.avg_hit_latency_ns.load(Ordering::Relaxed),
1007 avg_miss_latency_ns: self.metrics.avg_miss_latency_ns.load(Ordering::Relaxed),
1008 cache_efficiency: self.metrics.cache_efficiency_score,
1009 memory_utilization: self.calculate_memory_utilization(),
1010 tier_statistics: self.collect_tier_statistics(),
1011 prefetch_statistics: self.prefetcher.get_statistics(),
1012 optimization_statistics: self.optimizer.get_statistics(),
1013 }
1014 }
1015
1016 pub fn optimize(&mut self) -> Result<OptimizationResult> {
1018 if !self.config.enable_adaptive_optimization {
1019 return Ok(OptimizationResult {
1020 improvement_score: 0.0,
1021 changes_applied: vec![],
1022 estimated_impact: EstimatedImpact::default(),
1023 });
1024 }
1025
1026 info!("Running cache optimization cycle");
1027 let before_metrics = self.metrics.clone();
1028
1029 let mut total_improvement = 0.0;
1030 let mut all_changes = Vec::new();
1031
1032 let mut algorithms = std::mem::take(&mut self.optimizer.algorithms);
1035 for algorithm in &mut algorithms {
1036 match algorithm.optimize_cache(&self.tiers, &self.metrics, &self.config) {
1037 Ok(result) => {
1038 total_improvement += result.improvement_score;
1039 all_changes.extend(result.changes_applied);
1040 info!(
1041 "Optimization algorithm '{}' achieved {:.2}% improvement",
1042 algorithm.name(),
1043 result.improvement_score * 100.0
1044 );
1045 }
1046 Err(e) => {
1047 warn!(
1048 "Optimization algorithm '{}' failed: {}",
1049 algorithm.name(),
1050 e
1051 );
1052 }
1053 }
1054 }
1055 self.optimizer.algorithms = algorithms;
1057
1058 self.optimizer.record_optimization_event(OptimizationEvent {
1060 timestamp: SystemTime::now(),
1061 algorithm: "combined".to_string(),
1062 changes: all_changes.clone(),
1063 before_metrics,
1064 after_metrics: None, });
1066
1067 Ok(OptimizationResult {
1068 improvement_score: total_improvement,
1069 changes_applied: all_changes,
1070 estimated_impact: self.estimate_optimization_impact(total_improvement),
1071 })
1072 }
1073
1074 pub fn export_performance_data(&self, format: ExportFormat) -> Result<String> {
1076 match format {
1077 ExportFormat::Json => {
1078 let data = CachePerformanceData {
1079 metrics: self.metrics.clone(),
1080 statistics: self.get_statistics(),
1081 configuration: self.config.clone(),
1082 access_patterns: self.pattern_analyzer.export_patterns(),
1083 optimization_history: self.optimizer.export_history(),
1084 };
1085 Ok(serde_json::to_string_pretty(&data)?)
1086 }
1087 ExportFormat::Prometheus => self.export_prometheus_metrics(),
1088 ExportFormat::Csv => self.export_csv_metrics(),
1089 }
1090 }
1091
1092 fn calculate_tier_sizes(config: &CacheConfiguration) -> Vec<u64> {
1095 let total_size = config.max_total_size_bytes;
1096 config
1097 .tier_size_ratios
1098 .iter()
1099 .map(|ratio| (total_size as f64 * ratio) as u64)
1100 .collect()
1101 }
1102
1103 fn create_storage_for_tier(
1104 tier_id: u32,
1105 config: &TierConfiguration,
1106 ) -> Result<Box<dyn CacheStorage>> {
1107 match tier_id {
1108 0 => Ok(Box::new(MemoryStorage::new(config.max_size_bytes))),
1109 1 => Ok(Box::new(CompressedStorage::new(config.max_size_bytes))),
1110 _ => Ok(Box::new(PersistentStorage::new(config.max_size_bytes)?)),
1111 }
1112 }
1113
1114 fn create_eviction_policy_for_tier(tier_id: u32) -> Box<dyn EvictionPolicy> {
1115 match tier_id {
1116 0 => Box::new(LRUEvictionPolicy::new()),
1117 1 => Box::new(LFUEvictionPolicy::new()),
1118 _ => Box::new(AdaptiveEvictionPolicy::new()),
1119 }
1120 }
1121
1122 fn should_promote(&self, _key: &CacheKey, value: &CacheValue, current_tier: usize) -> bool {
1123 let access_frequency = value.access_count as f64;
1125 let recency_score = self.calculate_recency_score(value.last_accessed);
1126 let size_penalty = value.metadata.size_bytes as f64 / 1024.0; let promotion_score = access_frequency * recency_score / size_penalty;
1129 promotion_score > 2.0 && current_tier > 0
1130 }
1131
1132 fn promote_item(&mut self, key: CacheKey, value: CacheValue, from_tier: usize) -> Result<()> {
1133 if from_tier == 0 {
1134 return Ok(()); }
1136
1137 let target_tier = from_tier - 1;
1138
1139 self.tiers[from_tier].storage.remove(&key);
1141
1142 let default_ttl = self.tiers[target_tier].config.default_ttl;
1144 self.tiers[target_tier]
1145 .storage
1146 .store(key, value, Some(default_ttl))?;
1147
1148 debug!(
1149 "Promoted cache item from tier {} to tier {}",
1150 from_tier, target_tier
1151 );
1152 Ok(())
1153 }
1154
1155 fn calculate_recency_score(&self, last_accessed: SystemTime) -> f64 {
1156 let now = SystemTime::now();
1157 let duration = now.duration_since(last_accessed).unwrap_or(Duration::ZERO);
1158 let hours = duration.as_secs_f64() / 3600.0;
1159
1160 (-hours / 24.0).exp()
1162 }
1163
1164 fn check_and_evict(&mut self, tier_id: u32) -> Result<()> {
1165 let size_info = {
1166 let tier = &self.tiers[tier_id as usize];
1167 tier.storage.size_info()
1168 };
1169
1170 if size_info.used_bytes > self.tiers[tier_id as usize].config.max_size_bytes {
1171 let target_size =
1172 (self.tiers[tier_id as usize].config.max_size_bytes as f64 * 0.8) as u64; let items = self.collect_tier_items(tier_id);
1174
1175 let keys_to_evict = {
1176 let tier = &mut self.tiers[tier_id as usize];
1177 tier.eviction_policy
1178 .evict(size_info.used_bytes, target_size, &items)
1179 };
1180
1181 let tier = &mut self.tiers[tier_id as usize];
1182 for key in keys_to_evict {
1183 tier.storage.remove(&key);
1184 tier.stats.eviction_count += 1;
1185 }
1186 }
1187
1188 Ok(())
1189 }
1190
1191 fn collect_tier_items(&self, _tier_id: u32) -> Vec<CacheItem> {
1192 Vec::new()
1195 }
1196
1197 fn hash_key(&self, key: &CacheKey) -> u64 {
1198 use std::collections::hash_map::DefaultHasher;
1199 let mut hasher = DefaultHasher::new();
1200 key.hash(&mut hasher);
1201 hasher.finish()
1202 }
1203
1204 fn update_store_metrics(&mut self, tier_id: u32, _latency: Duration) {
1205 if let Some(_tier_metrics) = self.metrics.tier_metrics.get_mut(&tier_id) {
1207 }
1209 }
1210
1211 fn update_hit_metrics(&mut self, _tier_id: u32, latency: Duration) {
1212 self.metrics.hit_count.fetch_add(1, Ordering::Relaxed);
1213 self.metrics.total_requests.fetch_add(1, Ordering::Relaxed);
1214
1215 let latency_ns = latency.as_nanos() as u64;
1217 self.metrics
1218 .avg_hit_latency_ns
1219 .store(latency_ns, Ordering::Relaxed);
1220 }
1221
1222 fn update_miss_metrics(&mut self, latency: Duration) {
1223 self.metrics.miss_count.fetch_add(1, Ordering::Relaxed);
1224 self.metrics.total_requests.fetch_add(1, Ordering::Relaxed);
1225
1226 let latency_ns = latency.as_nanos() as u64;
1227 self.metrics
1228 .avg_miss_latency_ns
1229 .store(latency_ns, Ordering::Relaxed);
1230 }
1231
1232 fn calculate_memory_utilization(&self) -> f64 {
1233 let total_used: u64 = self
1234 .tiers
1235 .iter()
1236 .map(|tier| tier.storage.size_info().used_bytes)
1237 .sum();
1238 let total_capacity: u64 = self
1239 .tiers
1240 .iter()
1241 .map(|tier| tier.storage.size_info().total_capacity_bytes)
1242 .sum();
1243
1244 if total_capacity > 0 {
1245 total_used as f64 / total_capacity as f64
1246 } else {
1247 0.0
1248 }
1249 }
1250
1251 fn collect_tier_statistics(&self) -> Vec<TierStatistics> {
1252 self.tiers.iter().map(|tier| tier.stats.clone()).collect()
1253 }
1254
1255 fn estimate_optimization_impact(&self, improvement_score: f64) -> EstimatedImpact {
1256 EstimatedImpact {
1257 hit_rate_improvement: improvement_score * 0.1,
1258 latency_reduction: improvement_score * 0.05,
1259 memory_efficiency_gain: improvement_score * 0.08,
1260 cost_reduction: improvement_score * 0.03,
1261 }
1262 }
1263
1264 fn export_prometheus_metrics(&self) -> Result<String> {
1265 let mut metrics = String::new();
1266
1267 let hit_count = self.metrics.hit_count.load(Ordering::Relaxed);
1268 let miss_count = self.metrics.miss_count.load(Ordering::Relaxed);
1269 let total = hit_count + miss_count;
1270
1271 metrics.push_str(&format!("oxirs_cache_hits_total {hit_count}\n"));
1272 metrics.push_str(&format!("oxirs_cache_misses_total {miss_count}\n"));
1273 metrics.push_str(&format!("oxirs_cache_requests_total {total}\n"));
1274
1275 if total > 0 {
1276 let hit_rate = hit_count as f64 / total as f64;
1277 metrics.push_str(&format!("oxirs_cache_hit_rate {hit_rate:.4}\n"));
1278 }
1279
1280 metrics.push_str(&format!(
1281 "oxirs_cache_memory_utilization {:.4}\n",
1282 self.calculate_memory_utilization()
1283 ));
1284 metrics.push_str(&format!(
1285 "oxirs_cache_efficiency_score {:.4}\n",
1286 self.metrics.cache_efficiency_score
1287 ));
1288
1289 Ok(metrics)
1290 }
1291
1292 fn export_csv_metrics(&self) -> Result<String> {
1293 let mut csv = String::new();
1294 csv.push_str("metric,value,timestamp\n");
1295
1296 let now = SystemTime::now()
1297 .duration_since(SystemTime::UNIX_EPOCH)?
1298 .as_secs();
1299 let hit_count = self.metrics.hit_count.load(Ordering::Relaxed);
1300 let miss_count = self.metrics.miss_count.load(Ordering::Relaxed);
1301
1302 csv.push_str(&format!("hit_count,{hit_count},{now}\n"));
1303 csv.push_str(&format!("miss_count,{miss_count},{now}\n"));
1304 csv.push_str(&format!(
1305 "memory_utilization,{:.4},{}\n",
1306 self.calculate_memory_utilization(),
1307 now
1308 ));
1309
1310 Ok(csv)
1311 }
1312}
1313
1314#[derive(Debug)]
1317pub struct MemoryStorage {
1318 data: HashMap<CacheKey, CacheValue>,
1319 max_size: u64,
1320 current_size: u64,
1321}
1322
1323impl MemoryStorage {
1324 pub fn new(max_size: u64) -> Self {
1325 Self {
1326 data: HashMap::new(),
1327 max_size,
1328 current_size: 0,
1329 }
1330 }
1331}
1332
1333impl CacheStorage for MemoryStorage {
1334 fn store(&mut self, key: CacheKey, value: CacheValue, _ttl: Option<Duration>) -> Result<()> {
1335 let size = value.metadata.size_bytes;
1336 if self.current_size + size <= self.max_size {
1337 self.data.insert(key, value);
1338 self.current_size += size;
1339 }
1340 Ok(())
1341 }
1342
1343 fn retrieve(&self, key: &CacheKey) -> Option<CacheValue> {
1344 self.data.get(key).cloned()
1345 }
1346
1347 fn remove(&mut self, key: &CacheKey) -> bool {
1348 if let Some(value) = self.data.remove(key) {
1349 self.current_size -= value.metadata.size_bytes;
1350 true
1351 } else {
1352 false
1353 }
1354 }
1355
1356 fn size_info(&self) -> CacheSizeInfo {
1357 CacheSizeInfo {
1358 used_bytes: self.current_size,
1359 available_bytes: self.max_size - self.current_size,
1360 total_capacity_bytes: self.max_size,
1361 item_count: self.data.len() as u64,
1362 }
1363 }
1364
1365 fn clear(&mut self) {
1366 self.data.clear();
1367 self.current_size = 0;
1368 }
1369
1370 fn statistics(&self) -> StorageStatistics {
1371 StorageStatistics::default()
1372 }
1373}
1374
1375#[derive(Debug, Clone, Serialize, Deserialize)]
1379pub struct CacheStatistics {
1380 pub hit_rate: f64,
1381 pub miss_rate: f64,
1382 pub total_requests: u64,
1383 pub avg_hit_latency_ns: u64,
1384 pub avg_miss_latency_ns: u64,
1385 pub cache_efficiency: f64,
1386 pub memory_utilization: f64,
1387 pub tier_statistics: Vec<TierStatistics>,
1388 pub prefetch_statistics: PrefetchStatistics,
1389 pub optimization_statistics: OptimizationStatistics,
1390}
1391
1392#[derive(Debug, Clone, Serialize, Deserialize)]
1393pub struct PrefetchStatistics {
1394 pub successful_prefetches: u64,
1395 pub failed_prefetches: u64,
1396 pub prefetch_hit_rate: f64,
1397 pub avg_prediction_accuracy: f64,
1398}
1399
1400#[derive(Debug, Clone, Serialize, Deserialize)]
1401pub struct OptimizationStatistics {
1402 pub total_optimizations: u64,
1403 pub successful_optimizations: u64,
1404 pub avg_improvement_score: f64,
1405 pub last_optimization: Option<SystemTime>,
1406}
1407
1408#[derive(Debug, Clone, Serialize, Deserialize)]
1409pub struct CachePerformanceData {
1410 pub metrics: CachePerformanceMetrics,
1411 pub statistics: CacheStatistics,
1412 pub configuration: CacheConfiguration,
1413 pub access_patterns: String, pub optimization_history: String, }
1416
1417#[derive(Debug, Clone, Copy)]
1418pub enum ExportFormat {
1419 Json,
1420 Prometheus,
1421 Csv,
1422}
1423
1424impl Default for AccessPatternAnalyzer {
1426 fn default() -> Self {
1427 Self::new()
1428 }
1429}
1430
1431impl AccessPatternAnalyzer {
1432 pub fn new() -> Self {
1433 Self {
1434 access_history: VecDeque::new(),
1435 seasonal_detector: SeasonalPatternDetector::new(),
1436 query_clustering: QueryClusteringEngine::new(),
1437 temporal_predictor: TemporalAccessPredictor::new(),
1438 }
1439 }
1440
1441 pub fn record_access(&mut self, _event: AccessEvent) {
1442 }
1444
1445 pub fn export_patterns(&self) -> String {
1446 "{}".to_string() }
1448}
1449
1450impl Default for SeasonalPatternDetector {
1452 fn default() -> Self {
1453 Self::new()
1454 }
1455}
1456
1457impl SeasonalPatternDetector {
1458 pub fn new() -> Self {
1459 Self {
1460 hourly_patterns: [1.0; 24],
1461 daily_patterns: [1.0; 7],
1462 monthly_patterns: [1.0; 31],
1463 pattern_confidence: 0.0,
1464 }
1465 }
1466}
1467
1468impl Default for QueryClusteringEngine {
1469 fn default() -> Self {
1470 Self::new()
1471 }
1472}
1473
1474impl QueryClusteringEngine {
1475 pub fn new() -> Self {
1476 Self {
1477 clusters: Vec::new(),
1478 cluster_assignments: HashMap::new(),
1479 cluster_centroids: Vec::new(),
1480 }
1481 }
1482}
1483
1484impl Default for TemporalAccessPredictor {
1485 fn default() -> Self {
1486 Self::new()
1487 }
1488}
1489
1490impl TemporalAccessPredictor {
1491 pub fn new() -> Self {
1492 Self {
1493 time_series_models: HashMap::new(),
1494 global_trend_model: GlobalTrendModel {
1495 hourly_multipliers: [1.0; 24],
1496 daily_multipliers: [1.0; 7],
1497 base_rate: 1.0,
1498 },
1499 prediction_horizon: Duration::from_secs(3600),
1500 }
1501 }
1502}
1503
1504impl Default for PredictivePrefetcher {
1505 fn default() -> Self {
1506 Self::new()
1507 }
1508}
1509
1510impl PredictivePrefetcher {
1511 pub fn new() -> Self {
1512 Self {
1513 prefetch_queue: VecDeque::new(),
1514 models: PrefetchModels::new(),
1515 strategies: vec![
1516 PrefetchStrategy::SequentialPattern,
1517 PrefetchStrategy::SimilarityBased,
1518 PrefetchStrategy::MachineLearning,
1519 ],
1520 performance: PrefetchPerformance {
1521 successful_prefetches: 0,
1522 failed_prefetches: 0,
1523 cache_space_saved: 0,
1524 avg_prediction_accuracy: 0.0,
1525 },
1526 }
1527 }
1528
1529 pub fn trigger_prefetch_analysis(&mut self, _key: &CacheKey, _value: &CacheValue) {
1530 }
1532
1533 pub fn get_statistics(&self) -> PrefetchStatistics {
1534 PrefetchStatistics {
1535 successful_prefetches: self.performance.successful_prefetches,
1536 failed_prefetches: self.performance.failed_prefetches,
1537 prefetch_hit_rate: if self.performance.successful_prefetches
1538 + self.performance.failed_prefetches
1539 > 0
1540 {
1541 self.performance.successful_prefetches as f64
1542 / (self.performance.successful_prefetches + self.performance.failed_prefetches)
1543 as f64
1544 } else {
1545 0.0
1546 },
1547 avg_prediction_accuracy: self.performance.avg_prediction_accuracy,
1548 }
1549 }
1550}
1551
1552impl Default for PrefetchModels {
1553 fn default() -> Self {
1554 Self::new()
1555 }
1556}
1557
1558impl PrefetchModels {
1559 pub fn new() -> Self {
1560 Self {
1561 similarity_model: SimilarityPrefetchModel {
1562 similarity_threshold: 0.8,
1563 prefetch_depth: 5,
1564 confidence_weights: vec![1.0, 0.8, 0.6, 0.4, 0.2],
1565 },
1566 sequence_model: SequencePrefetchModel {
1567 sequence_patterns: HashMap::new(),
1568 max_sequence_length: 5,
1569 min_confidence: 0.7,
1570 },
1571 user_behavior_model: UserBehaviorModel {
1572 user_profiles: HashMap::new(),
1573 default_profile: UserProfile {
1574 typical_query_patterns: Vec::new(),
1575 access_frequency: 1.0,
1576 preference_weights: HashMap::new(),
1577 },
1578 },
1579 }
1580 }
1581}
1582
1583impl Default for CacheOptimizer {
1584 fn default() -> Self {
1585 Self::new()
1586 }
1587}
1588
1589impl CacheOptimizer {
1590 pub fn new() -> Self {
1591 Self {
1592 algorithms: vec![], optimization_history: Vec::new(),
1594 current_state: OptimizationState {
1595 last_optimization: SystemTime::now(),
1596 optimization_frequency: Duration::from_secs(3600),
1597 pending_optimizations: Vec::new(),
1598 optimization_backlog: 0,
1599 },
1600 improvements: ImprovementTracker {
1601 baseline_metrics: CachePerformanceMetrics::default(),
1602 current_improvement: 0.0,
1603 improvement_history: VecDeque::new(),
1604 regression_detection: RegressionDetector {
1605 regression_threshold: -0.05,
1606 detection_window: Duration::from_secs(1800),
1607 recent_scores: VecDeque::new(),
1608 },
1609 },
1610 }
1611 }
1612
1613 pub fn record_optimization_event(&mut self, event: OptimizationEvent) {
1614 self.optimization_history.push(event);
1615 }
1616
1617 pub fn get_statistics(&self) -> OptimizationStatistics {
1618 OptimizationStatistics {
1619 total_optimizations: self.optimization_history.len() as u64,
1620 successful_optimizations: self
1621 .optimization_history
1622 .iter()
1623 .filter(|e| !e.changes.is_empty())
1624 .count() as u64,
1625 avg_improvement_score: self.improvements.current_improvement,
1626 last_optimization: self.optimization_history.last().map(|e| e.timestamp),
1627 }
1628 }
1629
1630 pub fn export_history(&self) -> String {
1631 "{}".to_string() }
1633}
1634
1635impl MLModels {
1636 pub fn new() -> Result<Self> {
1637 Ok(Self {
1638 access_predictor: AccessPredictionModel {
1639 model_weights: vec![1.0, 0.8, 0.6, 0.4],
1640 feature_extractors: vec![
1641 FeatureExtractor::AccessFrequency,
1642 FeatureExtractor::RecencyScore,
1643 FeatureExtractor::SizeMetric,
1644 FeatureExtractor::ComputationCost,
1645 ],
1646 prediction_accuracy: 0.75,
1647 },
1648 hit_probability_model: HitProbabilityModel {
1649 probability_matrix: HashMap::new(),
1650 model_confidence: 0.8,
1651 last_update: SystemTime::now(),
1652 },
1653 tier_placement_model: TierPlacementModel {
1654 placement_scores: HashMap::new(),
1655 optimization_objective: OptimizationObjective::BalancedPerformance,
1656 },
1657 eviction_timing_model: EvictionTimingModel {
1658 survival_functions: HashMap::new(),
1659 hazard_rates: HashMap::new(),
1660 },
1661 })
1662 }
1663
1664 pub fn update_with_store_event(&mut self, _key: &CacheKey, _value: &CacheValue, _tier: u32) {
1665 }
1667}
1668
1669impl TierPlacementModel {
1670 pub fn predict_optimal_tier(&self, _key: &CacheKey, _value: &CacheValue) -> u32 {
1671 0
1673 }
1674}
1675
1676impl Default for AccessTracker {
1677 fn default() -> Self {
1678 Self::new()
1679 }
1680}
1681
1682impl AccessTracker {
1683 pub fn new() -> Self {
1684 Self {
1685 access_counts: HashMap::new(),
1686 access_times: HashMap::new(),
1687 hot_keys: BTreeMap::new(),
1688 }
1689 }
1690
1691 pub fn on_access(&mut self, key: &CacheKey, _access_time: Instant) {
1692 *self.access_counts.entry(key.clone()).or_insert(0) += 1;
1693 self.access_times
1694 .entry(key.clone())
1695 .or_default()
1696 .push_back(SystemTime::now());
1697 }
1698
1699 pub fn on_store(&mut self, key: &CacheKey) {
1700 self.access_times.entry(key.clone()).or_default();
1702 }
1703
1704 pub fn on_remove(&mut self, key: &CacheKey) {
1705 self.access_counts.remove(key);
1706 self.access_times.remove(key);
1707 }
1708}
1709
1710#[derive(Debug)]
1712pub struct LRUEvictionPolicy {
1713 access_order: VecDeque<CacheKey>,
1714}
1715
1716impl Default for LRUEvictionPolicy {
1717 fn default() -> Self {
1718 Self::new()
1719 }
1720}
1721
1722impl LRUEvictionPolicy {
1723 pub fn new() -> Self {
1724 Self {
1725 access_order: VecDeque::new(),
1726 }
1727 }
1728}
1729
1730impl EvictionPolicy for LRUEvictionPolicy {
1731 fn evict(
1732 &mut self,
1733 current_size: u64,
1734 target_size: u64,
1735 _items: &[CacheItem],
1736 ) -> Vec<CacheKey> {
1737 let bytes_to_evict = current_size.saturating_sub(target_size);
1738 let items_to_evict = (bytes_to_evict / 1024).max(1) as usize; self.access_order
1741 .iter()
1742 .take(items_to_evict)
1743 .cloned()
1744 .collect()
1745 }
1746
1747 fn on_access(&mut self, key: &CacheKey, _access_time: Instant) {
1748 if let Some(pos) = self.access_order.iter().position(|k| k == key) {
1750 let key = self.access_order.remove(pos).unwrap();
1751 self.access_order.push_back(key);
1752 }
1753 }
1754
1755 fn on_store(&mut self, key: &CacheKey, _size: u64, _store_time: Instant) {
1756 self.access_order.push_back(key.clone());
1757 }
1758
1759 fn statistics(&self) -> EvictionStatistics {
1760 EvictionStatistics::default()
1761 }
1762}
1763
1764#[derive(Debug)]
1765pub struct LFUEvictionPolicy {
1766 frequency_map: HashMap<CacheKey, u64>,
1767}
1768
1769impl Default for LFUEvictionPolicy {
1770 fn default() -> Self {
1771 Self::new()
1772 }
1773}
1774
1775impl LFUEvictionPolicy {
1776 pub fn new() -> Self {
1777 Self {
1778 frequency_map: HashMap::new(),
1779 }
1780 }
1781}
1782
1783impl EvictionPolicy for LFUEvictionPolicy {
1784 fn evict(
1785 &mut self,
1786 current_size: u64,
1787 target_size: u64,
1788 _items: &[CacheItem],
1789 ) -> Vec<CacheKey> {
1790 let bytes_to_evict = current_size.saturating_sub(target_size);
1791 let items_to_evict = (bytes_to_evict / 1024).max(1) as usize;
1792
1793 let mut frequency_pairs: Vec<_> = self.frequency_map.iter().collect();
1794 frequency_pairs.sort_by_key(|&(_, &freq)| freq);
1795
1796 frequency_pairs
1797 .iter()
1798 .take(items_to_evict)
1799 .map(|(key, _)| (*key).clone())
1800 .collect()
1801 }
1802
1803 fn on_access(&mut self, key: &CacheKey, _access_time: Instant) {
1804 *self.frequency_map.entry(key.clone()).or_insert(0) += 1;
1805 }
1806
1807 fn on_store(&mut self, key: &CacheKey, _size: u64, _store_time: Instant) {
1808 self.frequency_map.insert(key.clone(), 0);
1809 }
1810
1811 fn statistics(&self) -> EvictionStatistics {
1812 EvictionStatistics::default()
1813 }
1814}
1815
1816#[derive(Debug)]
1817pub struct AdaptiveEvictionPolicy {
1818 lru_component: LRUEvictionPolicy,
1819 lfu_component: LFUEvictionPolicy,
1820 lru_weight: f64,
1821}
1822
1823impl Default for AdaptiveEvictionPolicy {
1824 fn default() -> Self {
1825 Self::new()
1826 }
1827}
1828
1829impl AdaptiveEvictionPolicy {
1830 pub fn new() -> Self {
1831 Self {
1832 lru_component: LRUEvictionPolicy::new(),
1833 lfu_component: LFUEvictionPolicy::new(),
1834 lru_weight: 0.5,
1835 }
1836 }
1837}
1838
1839impl EvictionPolicy for AdaptiveEvictionPolicy {
1840 fn evict(&mut self, current_size: u64, target_size: u64, items: &[CacheItem]) -> Vec<CacheKey> {
1841 let lru_candidates = self.lru_component.evict(current_size, target_size, items);
1843 let lfu_candidates = self.lfu_component.evict(current_size, target_size, items);
1844
1845 let lru_count = (lru_candidates.len() as f64 * self.lru_weight) as usize;
1847 let mut result = Vec::new();
1848 result.extend(lru_candidates.into_iter().take(lru_count));
1849 result.extend(lfu_candidates.into_iter().take(items.len() - lru_count));
1850
1851 result
1852 }
1853
1854 fn on_access(&mut self, key: &CacheKey, access_time: Instant) {
1855 self.lru_component.on_access(key, access_time);
1856 self.lfu_component.on_access(key, access_time);
1857 }
1858
1859 fn on_store(&mut self, key: &CacheKey, size: u64, store_time: Instant) {
1860 self.lru_component.on_store(key, size, store_time);
1861 self.lfu_component.on_store(key, size, store_time);
1862 }
1863
1864 fn statistics(&self) -> EvictionStatistics {
1865 EvictionStatistics::default()
1866 }
1867}
1868
1869#[derive(Debug)]
1871pub struct CompressedStorage {
1872 inner: MemoryStorage,
1873}
1874
1875impl CompressedStorage {
1876 pub fn new(max_size: u64) -> Self {
1877 Self {
1878 inner: MemoryStorage::new(max_size),
1879 }
1880 }
1881}
1882
1883impl CacheStorage for CompressedStorage {
1884 fn store(&mut self, key: CacheKey, value: CacheValue, ttl: Option<Duration>) -> Result<()> {
1885 self.inner.store(key, value, ttl)
1887 }
1888
1889 fn retrieve(&self, key: &CacheKey) -> Option<CacheValue> {
1890 self.inner.retrieve(key)
1892 }
1893
1894 fn remove(&mut self, key: &CacheKey) -> bool {
1895 self.inner.remove(key)
1896 }
1897
1898 fn size_info(&self) -> CacheSizeInfo {
1899 self.inner.size_info()
1900 }
1901
1902 fn clear(&mut self) {
1903 self.inner.clear()
1904 }
1905
1906 fn statistics(&self) -> StorageStatistics {
1907 self.inner.statistics()
1908 }
1909}
1910
1911#[derive(Debug)]
1912pub struct PersistentStorage {
1913 inner: MemoryStorage,
1914}
1915
1916impl PersistentStorage {
1917 pub fn new(max_size: u64) -> Result<Self> {
1918 Ok(Self {
1919 inner: MemoryStorage::new(max_size),
1920 })
1921 }
1922}
1923
1924impl CacheStorage for PersistentStorage {
1925 fn store(&mut self, key: CacheKey, value: CacheValue, ttl: Option<Duration>) -> Result<()> {
1926 self.inner.store(key, value, ttl)
1928 }
1929
1930 fn retrieve(&self, key: &CacheKey) -> Option<CacheValue> {
1931 self.inner.retrieve(key)
1933 }
1934
1935 fn remove(&mut self, key: &CacheKey) -> bool {
1936 self.inner.remove(key)
1937 }
1938
1939 fn size_info(&self) -> CacheSizeInfo {
1940 self.inner.size_info()
1941 }
1942
1943 fn clear(&mut self) {
1944 self.inner.clear()
1945 }
1946
1947 fn statistics(&self) -> StorageStatistics {
1948 self.inner.statistics()
1949 }
1950}
1951
1952impl Default for CacheConfiguration {
1953 fn default() -> Self {
1954 Self {
1955 max_total_size_bytes: 1024 * 1024 * 1024, num_tiers: 3,
1957 tier_size_ratios: vec![0.5, 0.3, 0.2], default_ttl_seconds: 3600, optimization_interval_seconds: 300, ml_update_interval_seconds: 900, enable_prefetching: true,
1962 enable_adaptive_optimization: true,
1963 monitoring_config: MonitoringConfiguration {
1964 enable_detailed_metrics: true,
1965 metrics_retention_days: 7,
1966 alert_thresholds: AlertThresholds {
1967 min_hit_rate: 0.8,
1968 max_latency_p99_ms: 100.0,
1969 max_memory_utilization: 0.9,
1970 min_cache_efficiency: 0.7,
1971 },
1972 export_prometheus: true,
1973 },
1974 }
1975 }
1976}
1977
1978#[cfg(test)]
1979mod tests {
1980 use super::*;
1981
1982 #[test]
1983 fn test_adaptive_cache_creation() {
1984 let config = CacheConfiguration::default();
1985 let cache = AdaptiveIntelligentCache::new(config).unwrap();
1986 assert_eq!(cache.tiers.len(), 3);
1987 }
1988
1989 #[test]
1990 fn test_cache_store_and_retrieve() {
1991 let config = CacheConfiguration::default();
1992 let mut cache = AdaptiveIntelligentCache::new(config).unwrap();
1993
1994 let key = CacheKey {
1995 query_vector: vec![1, 2, 3, 4],
1996 similarity_metric: SimilarityMetric::Cosine,
1997 parameters: HashMap::new(),
1998 };
1999
2000 let value = CacheValue {
2001 results: vec![("vec1".to_string(), 0.95)],
2002 metadata: CacheMetadata {
2003 size_bytes: 1024,
2004 computation_cost: 0.5,
2005 quality_score: 0.9,
2006 staleness_factor: 0.1,
2007 },
2008 created_at: SystemTime::now(),
2009 last_accessed: SystemTime::now(),
2010 access_count: 1,
2011 };
2012
2013 cache.store(key.clone(), value.clone()).unwrap();
2014 let retrieved = cache.retrieve(&key);
2015
2016 assert!(retrieved.is_some());
2017 let retrieved_value = retrieved.unwrap();
2018 assert_eq!(retrieved_value.results, value.results);
2019 }
2020
2021 #[test]
2022 fn test_cache_statistics() {
2023 let config = CacheConfiguration::default();
2024 let cache = AdaptiveIntelligentCache::new(config).unwrap();
2025 let stats = cache.get_statistics();
2026
2027 assert_eq!(stats.total_requests, 0);
2028 assert_eq!(stats.hit_rate, 0.0);
2029 }
2030
2031 #[test]
2032 fn test_cache_optimization() {
2033 let config = CacheConfiguration::default();
2034 let mut cache = AdaptiveIntelligentCache::new(config).unwrap();
2035
2036 let result = cache.optimize().unwrap();
2037 assert!(result.improvement_score >= 0.0);
2038 }
2039
2040 #[test]
2041 fn test_performance_data_export() {
2042 let config = CacheConfiguration::default();
2043 let cache = AdaptiveIntelligentCache::new(config).unwrap();
2044
2045 let json_export = cache.export_performance_data(ExportFormat::Json).unwrap();
2046 assert!(!json_export.is_empty());
2047
2048 let prometheus_export = cache
2049 .export_performance_data(ExportFormat::Prometheus)
2050 .unwrap();
2051 assert!(!prometheus_export.is_empty());
2052 }
2053
2054 #[test]
2055 fn test_eviction_policies() {
2056 let mut lru = LRUEvictionPolicy::new();
2057 let key = CacheKey {
2058 query_vector: vec![1, 2, 3],
2059 similarity_metric: SimilarityMetric::Cosine,
2060 parameters: HashMap::new(),
2061 };
2062
2063 lru.on_store(&key, 1024, Instant::now());
2064 lru.on_access(&key, Instant::now());
2065
2066 let items = vec![];
2067 let evicted = lru.evict(2048, 1024, &items);
2068 assert!(!evicted.is_empty());
2069 }
2070}