quantrs2_device/mid_circuit_measurements/
monitoring.rs

1//! Performance monitoring and optimization caching components
2
3use super::results::*;
4use crate::DeviceResult;
5use std::collections::{HashMap, VecDeque};
6use std::time::{Duration, Instant, SystemTime};
7
8/// Performance summary for aggregated metrics
9#[derive(Debug, Clone)]
10pub struct PerformanceSummary {
11    pub total_executions: usize,
12    pub average_execution_time: Duration,
13    pub success_rate: f64,
14    pub cache_hit_rate: f64,
15    pub optimization_savings: f64,
16    pub resource_utilization: f64,
17    pub interval_summaries: Vec<IntervalSummary>,
18    pub overall_stats: OverallStatistics,
19    pub active_alerts: Vec<PerformanceAlert>,
20    pub performance_trends: PerformanceTrend,
21    pub monitoring_window: Duration,
22    pub last_updated: SystemTime,
23}
24
25impl Default for PerformanceSummary {
26    fn default() -> Self {
27        Self {
28            total_executions: 0,
29            average_execution_time: Duration::from_secs(0),
30            success_rate: 0.0,
31            cache_hit_rate: 0.0,
32            optimization_savings: 0.0,
33            resource_utilization: 0.0,
34            interval_summaries: vec![],
35            overall_stats: OverallStatistics::default(),
36            active_alerts: vec![],
37            performance_trends: PerformanceTrend::default(),
38            monitoring_window: Duration::from_secs(300),
39            last_updated: SystemTime::now(),
40        }
41    }
42}
43
44/// Performance alert for threshold breaches
45#[derive(Debug, Clone)]
46pub struct PerformanceAlert {
47    pub alert_type: String,
48    pub message: String,
49    pub severity: String,
50    pub timestamp: SystemTime,
51    pub metric_value: f64,
52    pub threshold_value: f64,
53}
54
55/// Interval summary for time-based aggregations
56#[derive(Debug, Clone, Default)]
57pub struct IntervalSummary {
58    pub interval: Duration,
59    pub total_executions: usize,
60    pub average_execution_time: Duration,
61    pub success_rate: f64,
62    pub throughput: f64,
63}
64
65/// Overall statistics across all intervals
66#[derive(Debug, Clone, Default)]
67pub struct OverallStatistics {
68    pub total_executions: usize,
69    pub overall_success_rate: f64,
70    pub peak_throughput: f64,
71    pub average_latency: Duration,
72    pub resource_utilization: f64,
73}
74
75/// Performance trend analysis
76#[derive(Debug, Clone)]
77pub struct PerformanceTrend {
78    pub trend_direction: String,
79    pub trend_strength: f64,
80    pub prediction_confidence: f64,
81    pub time_window: Duration,
82}
83
84impl Default for PerformanceTrend {
85    fn default() -> Self {
86        Self {
87            trend_direction: "Stable".to_string(),
88            trend_strength: 0.0,
89            prediction_confidence: 0.5,
90            time_window: Duration::from_secs(300),
91        }
92    }
93}
94
95/// Cache statistics
96#[derive(Debug, Clone, Default)]
97pub struct CacheStatistics {
98    pub total_entries: usize,
99    pub total_access_count: usize,
100    pub hit_rate: f64,
101    pub cache_hit_rate: f64,
102    pub miss_rate: f64,
103    pub eviction_rate: f64,
104    pub memory_usage: f64,
105    pub avg_age: Duration,
106}
107
108/// Performance monitor for tracking measurement execution metrics
109pub struct PerformanceMonitor {
110    monitoring_enabled: bool,
111    metrics_history: VecDeque<TimestampedMetrics>,
112    alert_thresholds: AlertThresholds,
113    monitoring_window: Duration,
114    aggregation_intervals: Vec<Duration>,
115}
116
117impl PerformanceMonitor {
118    /// Create new performance monitor
119    pub fn new() -> Self {
120        Self {
121            monitoring_enabled: true,
122            metrics_history: VecDeque::with_capacity(10000),
123            alert_thresholds: AlertThresholds::default(),
124            monitoring_window: Duration::from_secs(3600), // 1 hour
125            aggregation_intervals: vec![
126                Duration::from_secs(60),   // 1 minute
127                Duration::from_secs(300),  // 5 minutes
128                Duration::from_secs(900),  // 15 minutes
129                Duration::from_secs(3600), // 1 hour
130            ],
131        }
132    }
133
134    /// Create performance monitor with custom configuration
135    pub fn with_config(alert_thresholds: AlertThresholds, monitoring_window: Duration) -> Self {
136        Self {
137            monitoring_enabled: true,
138            metrics_history: VecDeque::with_capacity(10000),
139            alert_thresholds,
140            monitoring_window,
141            aggregation_intervals: vec![
142                Duration::from_secs(60),
143                Duration::from_secs(300),
144                Duration::from_secs(900),
145                Duration::from_secs(3600),
146            ],
147        }
148    }
149
150    /// Record performance metrics
151    pub fn record_metrics(&mut self, metrics: &PerformanceMetrics) -> DeviceResult<()> {
152        if !self.monitoring_enabled {
153            return Ok(());
154        }
155
156        let timestamped_metrics = TimestampedMetrics {
157            timestamp: SystemTime::now(),
158            metrics: metrics.clone(),
159        };
160
161        self.metrics_history.push_back(timestamped_metrics);
162
163        // Clean old metrics outside monitoring window
164        self.cleanup_old_metrics()?;
165
166        Ok(())
167    }
168
169    /// Get current performance summary
170    pub fn get_performance_summary(&self) -> DeviceResult<PerformanceSummary> {
171        if self.metrics_history.is_empty() {
172            return Ok(PerformanceSummary::default());
173        }
174
175        // Calculate aggregated metrics for different time intervals
176        let mut interval_summaries = HashMap::new();
177        for &interval in &self.aggregation_intervals {
178            let summary = self.calculate_interval_summary(interval)?;
179            interval_summaries.insert(interval, summary);
180        }
181
182        // Calculate overall statistics
183        let overall_stats = self.calculate_overall_statistics()?;
184
185        // Detect performance alerts
186        let active_alerts = self.detect_performance_alerts()?;
187
188        // Calculate performance trends
189        let performance_trends = self.calculate_performance_trends()?;
190
191        Ok(PerformanceSummary {
192            total_executions: overall_stats.total_executions,
193            average_execution_time: overall_stats.average_latency,
194            success_rate: overall_stats.overall_success_rate,
195            cache_hit_rate: 0.8,       // Placeholder
196            optimization_savings: 0.1, // Placeholder
197            resource_utilization: 0.7, // Placeholder
198            interval_summaries: interval_summaries.into_values().collect(),
199            overall_stats,
200            active_alerts,
201            performance_trends: performance_trends.into_iter().next().unwrap_or_default(),
202            monitoring_window: self.monitoring_window,
203            last_updated: SystemTime::now(),
204        })
205    }
206
207    /// Check for performance alerts
208    pub fn check_alerts(&self) -> DeviceResult<Vec<PerformanceAlert>> {
209        self.detect_performance_alerts()
210    }
211
212    /// Get metrics for specific time range
213    pub fn get_metrics_in_range(
214        &self,
215        start_time: SystemTime,
216        end_time: SystemTime,
217    ) -> DeviceResult<Vec<TimestampedMetrics>> {
218        let metrics = self
219            .metrics_history
220            .iter()
221            .filter(|m| m.timestamp >= start_time && m.timestamp <= end_time)
222            .cloned()
223            .collect();
224
225        Ok(metrics)
226    }
227
228    /// Export metrics for analysis
229    pub fn export_metrics(&self, format: ExportFormat) -> DeviceResult<String> {
230        match format {
231            ExportFormat::Json => self.export_as_json(),
232            ExportFormat::Csv => self.export_as_csv(),
233            ExportFormat::Metrics => self.export_as_prometheus_metrics(),
234        }
235    }
236
237    /// Cleanup old metrics outside monitoring window
238    fn cleanup_old_metrics(&mut self) -> DeviceResult<()> {
239        let cutoff_time = SystemTime::now()
240            .checked_sub(self.monitoring_window)
241            .unwrap_or(SystemTime::UNIX_EPOCH);
242
243        while let Some(front_metric) = self.metrics_history.front() {
244            if front_metric.timestamp < cutoff_time {
245                self.metrics_history.pop_front();
246            } else {
247                break;
248            }
249        }
250
251        Ok(())
252    }
253
254    /// Calculate summary for specific time interval
255    fn calculate_interval_summary(&self, interval: Duration) -> DeviceResult<IntervalSummary> {
256        let cutoff_time = SystemTime::now()
257            .checked_sub(interval)
258            .unwrap_or(SystemTime::UNIX_EPOCH);
259
260        let recent_metrics: Vec<&PerformanceMetrics> = self
261            .metrics_history
262            .iter()
263            .filter(|m| m.timestamp >= cutoff_time)
264            .map(|m| &m.metrics)
265            .collect();
266
267        if recent_metrics.is_empty() {
268            return Ok(IntervalSummary::default());
269        }
270
271        // Calculate aggregated statistics
272        let count = recent_metrics.len();
273        let avg_success_rate = recent_metrics
274            .iter()
275            .map(|m| m.measurement_success_rate)
276            .sum::<f64>()
277            / count as f64;
278
279        let avg_efficiency = recent_metrics
280            .iter()
281            .map(|m| m.classical_efficiency)
282            .sum::<f64>()
283            / count as f64;
284
285        let avg_fidelity = recent_metrics
286            .iter()
287            .map(|m| m.circuit_fidelity)
288            .sum::<f64>()
289            / count as f64;
290
291        let avg_error_rate = recent_metrics
292            .iter()
293            .map(|m| m.measurement_error_rate)
294            .sum::<f64>()
295            / count as f64;
296
297        let avg_timing_overhead = recent_metrics
298            .iter()
299            .map(|m| m.timing_overhead)
300            .sum::<f64>()
301            / count as f64;
302
303        // Calculate min/max
304        let min_success_rate = recent_metrics
305            .iter()
306            .map(|m| m.measurement_success_rate)
307            .fold(f64::INFINITY, f64::min);
308
309        let max_success_rate = recent_metrics
310            .iter()
311            .map(|m| m.measurement_success_rate)
312            .fold(f64::NEG_INFINITY, f64::max);
313
314        Ok(IntervalSummary {
315            interval,
316            total_executions: count,
317            average_execution_time: Duration::from_millis((avg_efficiency * 1000.0) as u64),
318            success_rate: avg_success_rate,
319            throughput: count as f64 / interval.as_secs_f64(),
320        })
321    }
322
323    /// Calculate overall statistics
324    fn calculate_overall_statistics(&self) -> DeviceResult<OverallStatistics> {
325        if self.metrics_history.is_empty() {
326            return Ok(OverallStatistics::default());
327        }
328
329        let all_metrics: Vec<&PerformanceMetrics> =
330            self.metrics_history.iter().map(|m| &m.metrics).collect();
331
332        let total_samples = all_metrics.len();
333        let uptime = self.calculate_uptime()?;
334        let availability = self.calculate_availability(&all_metrics);
335        let throughput = self.calculate_throughput();
336        let reliability_score = self.calculate_reliability_score(&all_metrics);
337
338        Ok(OverallStatistics {
339            total_executions: total_samples,
340            overall_success_rate: availability,
341            peak_throughput: throughput,
342            average_latency: uptime / total_samples.max(1) as u32,
343            resource_utilization: reliability_score,
344        })
345    }
346
347    /// Detect performance alerts
348    fn detect_performance_alerts(&self) -> DeviceResult<Vec<PerformanceAlert>> {
349        let mut alerts = Vec::new();
350
351        if self.metrics_history.is_empty() {
352            return Ok(alerts);
353        }
354
355        let latest_metrics = &self
356            .metrics_history
357            .back()
358            .expect("metrics_history not empty after is_empty check")
359            .metrics;
360
361        // Check success rate alert
362        if latest_metrics.measurement_success_rate < self.alert_thresholds.min_success_rate {
363            alerts.push(PerformanceAlert {
364                alert_type: "LowSuccessRate".to_string(),
365                message: format!(
366                    "Measurement success rate ({:.2}%) below threshold ({:.2}%)",
367                    latest_metrics.measurement_success_rate * 100.0,
368                    self.alert_thresholds.min_success_rate * 100.0
369                ),
370                severity: if latest_metrics.measurement_success_rate < 0.8 {
371                    "Critical".to_string()
372                } else {
373                    "Warning".to_string()
374                },
375                timestamp: SystemTime::now(),
376                metric_value: latest_metrics.measurement_success_rate,
377                threshold_value: self.alert_thresholds.min_success_rate,
378            });
379        }
380
381        // Check error rate alert
382        if latest_metrics.measurement_error_rate > self.alert_thresholds.max_error_rate {
383            alerts.push(PerformanceAlert {
384                alert_type: "HighErrorRate".to_string(),
385                message: format!(
386                    "Error rate ({:.2}%) above threshold ({:.2}%)",
387                    latest_metrics.measurement_error_rate * 100.0,
388                    self.alert_thresholds.max_error_rate * 100.0
389                ),
390                severity: if latest_metrics.measurement_error_rate > 0.1 {
391                    "Critical".to_string()
392                } else {
393                    "Warning".to_string()
394                },
395                timestamp: SystemTime::now(),
396                metric_value: latest_metrics.measurement_error_rate,
397                threshold_value: self.alert_thresholds.max_error_rate,
398            });
399        }
400
401        // Check timing overhead alert
402        if latest_metrics.timing_overhead > self.alert_thresholds.max_timing_overhead {
403            alerts.push(PerformanceAlert {
404                alert_type: "HighLatency".to_string(),
405                message: format!(
406                    "Timing overhead ({:.2}) above threshold ({:.2})",
407                    latest_metrics.timing_overhead, self.alert_thresholds.max_timing_overhead
408                ),
409                severity: "Warning".to_string(),
410                timestamp: SystemTime::now(),
411                metric_value: latest_metrics.timing_overhead,
412                threshold_value: self.alert_thresholds.max_timing_overhead,
413            });
414        }
415
416        // Check efficiency alert
417        if latest_metrics.classical_efficiency < self.alert_thresholds.min_efficiency {
418            alerts.push(PerformanceAlert {
419                alert_type: "LowEfficiency".to_string(),
420                message: format!(
421                    "Classical efficiency ({:.2}%) below threshold ({:.2}%)",
422                    latest_metrics.classical_efficiency * 100.0,
423                    self.alert_thresholds.min_efficiency * 100.0
424                ),
425                severity: "Info".to_string(),
426                timestamp: SystemTime::now(),
427                metric_value: latest_metrics.classical_efficiency,
428                threshold_value: self.alert_thresholds.min_efficiency,
429            });
430        }
431
432        Ok(alerts)
433    }
434
435    /// Calculate performance trends
436    fn calculate_performance_trends(&self) -> DeviceResult<Vec<PerformanceTrend>> {
437        let mut trends = Vec::new();
438
439        if self.metrics_history.len() < 5 {
440            return Ok(trends);
441        }
442
443        // Success rate trend
444        let success_rates: Vec<f64> = self
445            .metrics_history
446            .iter()
447            .map(|m| m.metrics.measurement_success_rate)
448            .collect();
449
450        let success_rate_trend = self.calculate_trend(&success_rates);
451        trends.push(PerformanceTrend {
452            trend_direction: format!("{:?}", self.classify_trend_direction(success_rate_trend)),
453            trend_strength: success_rate_trend.abs(),
454            prediction_confidence: 0.8,
455            time_window: self.monitoring_window,
456        });
457
458        // Error rate trend
459        let error_rates: Vec<f64> = self
460            .metrics_history
461            .iter()
462            .map(|m| m.metrics.measurement_error_rate)
463            .collect();
464
465        let error_rate_trend = self.calculate_trend(&error_rates);
466        trends.push(PerformanceTrend {
467            trend_direction: format!("{:?}", self.classify_trend_direction(error_rate_trend)),
468            trend_strength: error_rate_trend.abs(),
469            prediction_confidence: 0.8,
470            time_window: self.monitoring_window,
471        });
472
473        Ok(trends)
474    }
475
476    /// Export metrics as JSON
477    fn export_as_json(&self) -> DeviceResult<String> {
478        use std::fmt::Write;
479        // Simplified JSON export
480        let mut json_data = String::from("{\n");
481        writeln!(
482            json_data,
483            "  \"total_samples\": {},",
484            self.metrics_history.len()
485        )
486        .expect("String write infallible");
487        writeln!(
488            json_data,
489            "  \"monitoring_window_secs\": {},",
490            self.monitoring_window.as_secs()
491        )
492        .expect("String write infallible");
493        json_data.push_str("  \"metrics\": [\n");
494
495        for (i, metric) in self.metrics_history.iter().enumerate() {
496            writeln!(
497                json_data,
498                "    {{\"timestamp\": {}, \"success_rate\": {:.4}, \"error_rate\": {:.4}}}",
499                metric
500                    .timestamp
501                    .duration_since(SystemTime::UNIX_EPOCH)
502                    .unwrap_or(Duration::ZERO)
503                    .as_secs(),
504                metric.metrics.measurement_success_rate,
505                metric.metrics.measurement_error_rate
506            )
507            .expect("String write infallible");
508            if i < self.metrics_history.len() - 1 {
509                json_data.push(',');
510            }
511            json_data.push('\n');
512        }
513
514        json_data.push_str("  ]\n}");
515        Ok(json_data)
516    }
517
518    /// Export metrics as CSV
519    fn export_as_csv(&self) -> DeviceResult<String> {
520        use std::fmt::Write;
521        let mut csv_data =
522            String::from("timestamp,success_rate,error_rate,efficiency,fidelity,timing_overhead\n");
523
524        for metric in &self.metrics_history {
525            writeln!(
526                csv_data,
527                "{},{:.4},{:.4},{:.4},{:.4},{:.4}",
528                metric
529                    .timestamp
530                    .duration_since(SystemTime::UNIX_EPOCH)
531                    .unwrap_or(Duration::ZERO)
532                    .as_secs(),
533                metric.metrics.measurement_success_rate,
534                metric.metrics.measurement_error_rate,
535                metric.metrics.classical_efficiency,
536                metric.metrics.circuit_fidelity,
537                metric.metrics.timing_overhead
538            )
539            .expect("String write infallible");
540        }
541
542        Ok(csv_data)
543    }
544
545    /// Export metrics in Prometheus format
546    fn export_as_prometheus_metrics(&self) -> DeviceResult<String> {
547        use std::fmt::Write;
548        if self.metrics_history.is_empty() {
549            return Ok(String::new());
550        }
551
552        let latest = &self
553            .metrics_history
554            .back()
555            .expect("metrics_history not empty after is_empty check")
556            .metrics;
557        let timestamp = SystemTime::now()
558            .duration_since(SystemTime::UNIX_EPOCH)
559            .unwrap_or(Duration::ZERO)
560            .as_millis();
561
562        let mut prometheus_data = String::new();
563
564        writeln!(
565            prometheus_data,
566            "measurement_success_rate {} {}",
567            latest.measurement_success_rate, timestamp
568        )
569        .expect("String write infallible");
570
571        writeln!(
572            prometheus_data,
573            "measurement_error_rate {} {}",
574            latest.measurement_error_rate, timestamp
575        )
576        .expect("String write infallible");
577
578        writeln!(
579            prometheus_data,
580            "classical_efficiency {} {}",
581            latest.classical_efficiency, timestamp
582        )
583        .expect("String write infallible");
584
585        writeln!(
586            prometheus_data,
587            "circuit_fidelity {} {}",
588            latest.circuit_fidelity, timestamp
589        )
590        .expect("String write infallible");
591
592        writeln!(
593            prometheus_data,
594            "timing_overhead {} {}",
595            latest.timing_overhead, timestamp
596        )
597        .expect("String write infallible");
598
599        Ok(prometheus_data)
600    }
601
602    // Helper methods
603    fn calculate_standard_deviation(&self, values: &[f64]) -> f64 {
604        if values.len() <= 1 {
605            return 0.0;
606        }
607
608        let mean = values.iter().sum::<f64>() / values.len() as f64;
609        let variance =
610            values.iter().map(|&x| (x - mean).powi(2)).sum::<f64>() / (values.len() - 1) as f64;
611
612        variance.sqrt()
613    }
614
615    fn calculate_uptime(&self) -> DeviceResult<Duration> {
616        if self.metrics_history.is_empty() {
617            return Ok(Duration::ZERO);
618        }
619
620        let first_timestamp = self
621            .metrics_history
622            .front()
623            .expect("metrics_history not empty after is_empty check")
624            .timestamp;
625        let last_timestamp = self
626            .metrics_history
627            .back()
628            .expect("metrics_history not empty after is_empty check")
629            .timestamp;
630
631        Ok(last_timestamp
632            .duration_since(first_timestamp)
633            .unwrap_or(Duration::ZERO))
634    }
635
636    fn calculate_availability(&self, metrics: &[&PerformanceMetrics]) -> f64 {
637        if metrics.is_empty() {
638            return 0.0;
639        }
640
641        let successful_measurements = metrics
642            .iter()
643            .filter(|m| m.measurement_success_rate > 0.9)
644            .count();
645
646        successful_measurements as f64 / metrics.len() as f64
647    }
648
649    fn calculate_throughput(&self) -> f64 {
650        if self.metrics_history.len() < 2 {
651            return 0.0;
652        }
653
654        let time_span = self.calculate_uptime().unwrap_or(Duration::ZERO);
655        if time_span.as_secs() == 0 {
656            return 0.0;
657        }
658
659        self.metrics_history.len() as f64 / time_span.as_secs() as f64
660    }
661
662    fn calculate_reliability_score(&self, metrics: &[&PerformanceMetrics]) -> f64 {
663        if metrics.is_empty() {
664            return 0.0;
665        }
666
667        let avg_success_rate = metrics
668            .iter()
669            .map(|m| m.measurement_success_rate)
670            .sum::<f64>()
671            / metrics.len() as f64;
672
673        let avg_fidelity =
674            metrics.iter().map(|m| m.circuit_fidelity).sum::<f64>() / metrics.len() as f64;
675
676        f64::midpoint(avg_success_rate, avg_fidelity)
677    }
678
679    fn calculate_data_quality_score(&self, metrics: &[&PerformanceMetrics]) -> f64 {
680        if metrics.is_empty() {
681            return 0.0;
682        }
683
684        // Simple data quality based on completeness and consistency
685        let complete_measurements = metrics
686            .iter()
687            .filter(|m| m.measurement_success_rate > 0.0 && m.circuit_fidelity > 0.0)
688            .count();
689
690        complete_measurements as f64 / metrics.len() as f64
691    }
692
693    fn calculate_trend(&self, values: &[f64]) -> f64 {
694        if values.len() < 2 {
695            return 0.0;
696        }
697
698        let n = values.len() as f64;
699        let x_sum = (0..values.len()).map(|i| i as f64).sum::<f64>();
700        let y_sum = values.iter().sum::<f64>();
701        let xy_sum = values
702            .iter()
703            .enumerate()
704            .map(|(i, &y)| i as f64 * y)
705            .sum::<f64>();
706        let x2_sum = (0..values.len()).map(|i| (i as f64).powi(2)).sum::<f64>();
707
708        let denominator = n.mul_add(x2_sum, -(x_sum * x_sum));
709        if denominator.abs() > 1e-10 {
710            n.mul_add(xy_sum, -(x_sum * y_sum)) / denominator
711        } else {
712            0.0
713        }
714    }
715
716    fn classify_trend_direction(
717        &self,
718        trend_slope: f64,
719    ) -> crate::mid_circuit_measurements::results::TrendDirection {
720        if trend_slope > 0.01 {
721            crate::mid_circuit_measurements::results::TrendDirection::Increasing
722        } else if trend_slope < -0.01 {
723            crate::mid_circuit_measurements::results::TrendDirection::Decreasing
724        } else {
725            crate::mid_circuit_measurements::results::TrendDirection::Stable
726        }
727    }
728}
729
730/// Optimization cache for storing and retrieving optimization results
731pub struct OptimizationCache {
732    cache_enabled: bool,
733    cache: HashMap<String, CachedOptimization>,
734    max_cache_size: usize,
735    cache_ttl: Duration,
736}
737
738impl OptimizationCache {
739    /// Create new optimization cache
740    pub fn new() -> Self {
741        Self {
742            cache_enabled: true,
743            cache: HashMap::new(),
744            max_cache_size: 1000,
745            cache_ttl: Duration::from_secs(3600), // 1 hour
746        }
747    }
748
749    /// Store optimization result in cache
750    pub fn store_optimization(
751        &mut self,
752        key: String,
753        optimization: OptimizationResult,
754    ) -> DeviceResult<()> {
755        if !self.cache_enabled {
756            return Ok(());
757        }
758
759        let cached_optimization = CachedOptimization {
760            result: optimization,
761            cached_at: SystemTime::now(),
762            access_count: 0,
763        };
764
765        self.cache.insert(key, cached_optimization);
766
767        // Cleanup old entries if cache is full
768        if self.cache.len() > self.max_cache_size {
769            self.cleanup_cache()?;
770        }
771
772        Ok(())
773    }
774
775    /// Retrieve optimization result from cache
776    pub fn get_optimization(&mut self, key: &str) -> Option<OptimizationResult> {
777        if !self.cache_enabled {
778            return None;
779        }
780
781        // Check if entry exists and is valid
782        let is_valid = if let Some(cached) = self.cache.get(key) {
783            SystemTime::now()
784                .duration_since(cached.cached_at)
785                .unwrap_or(Duration::MAX)
786                < self.cache_ttl
787        } else {
788            false
789        };
790
791        if is_valid {
792            if let Some(cached) = self.cache.get_mut(key) {
793                cached.access_count += 1;
794                return Some(cached.result.clone());
795            }
796        } else {
797            // Remove expired entry
798            self.cache.remove(key);
799        }
800
801        None
802    }
803
804    /// Check if optimization is cached
805    pub fn contains_key(&self, key: &str) -> bool {
806        if !self.cache_enabled {
807            return false;
808        }
809
810        if let Some(cached) = self.cache.get(key) {
811            SystemTime::now()
812                .duration_since(cached.cached_at)
813                .unwrap_or(Duration::MAX)
814                < self.cache_ttl
815        } else {
816            false
817        }
818    }
819
820    /// Clear cache
821    pub fn clear(&mut self) {
822        self.cache.clear();
823    }
824
825    /// Get cache statistics
826    pub fn get_cache_stats(&self) -> CacheStatistics {
827        let total_entries = self.cache.len();
828        let total_access_count = self.cache.values().map(|c| c.access_count as usize).sum();
829
830        let avg_age = if total_entries > 0 {
831            let total_age: Duration = self
832                .cache
833                .values()
834                .map(|c| {
835                    SystemTime::now()
836                        .duration_since(c.cached_at)
837                        .unwrap_or(Duration::ZERO)
838                })
839                .sum();
840            total_age / total_entries as u32
841        } else {
842            Duration::ZERO
843        };
844
845        CacheStatistics {
846            total_entries,
847            total_access_count,
848            hit_rate: 0.8,       // Placeholder - would need hit/miss tracking
849            cache_hit_rate: 0.8, // Placeholder - would need hit/miss tracking
850            miss_rate: 0.2,
851            eviction_rate: 0.1,
852            memory_usage: (total_entries * 100) as f64, // Estimated bytes
853            avg_age,
854        }
855    }
856
857    /// Cleanup old cache entries
858    fn cleanup_cache(&mut self) -> DeviceResult<()> {
859        let now = SystemTime::now();
860
861        // Remove expired entries
862        self.cache.retain(|_, cached| {
863            now.duration_since(cached.cached_at)
864                .unwrap_or(Duration::MAX)
865                < self.cache_ttl
866        });
867
868        // If still over limit, remove least recently used entries
869        if self.cache.len() > self.max_cache_size {
870            let mut entries: Vec<(String, u32)> = self
871                .cache
872                .iter()
873                .map(|(k, v)| (k.clone(), v.access_count))
874                .collect();
875
876            entries.sort_by_key(|(_, count)| *count);
877
878            let to_remove = self.cache.len() - self.max_cache_size;
879            for (key, _) in entries.iter().take(to_remove) {
880                self.cache.remove(key);
881            }
882        }
883
884        Ok(())
885    }
886}
887
888// Supporting types and default implementations
889
890#[derive(Debug, Clone)]
891pub struct TimestampedMetrics {
892    pub timestamp: SystemTime,
893    pub metrics: PerformanceMetrics,
894}
895
896#[derive(Debug, Clone)]
897pub struct AlertThresholds {
898    pub min_success_rate: f64,
899    pub max_error_rate: f64,
900    pub max_timing_overhead: f64,
901    pub min_efficiency: f64,
902}
903
904impl Default for AlertThresholds {
905    fn default() -> Self {
906        Self {
907            min_success_rate: 0.9,
908            max_error_rate: 0.05,
909            max_timing_overhead: 2.0,
910            min_efficiency: 0.8,
911        }
912    }
913}
914
915#[derive(Debug, Clone)]
916pub struct CachedOptimization {
917    pub result: OptimizationResult,
918    pub cached_at: SystemTime,
919    pub access_count: u32,
920}
921
922#[derive(Debug, Clone)]
923pub enum ExportFormat {
924    Json,
925    Csv,
926    Metrics,
927}
928
929#[derive(Debug, Clone)]
930pub enum AlertType {
931    LowSuccessRate,
932    HighErrorRate,
933    HighLatency,
934    LowEfficiency,
935}
936
937#[derive(Debug, Clone)]
938pub enum AlertSeverity {
939    Critical,
940    Warning,
941    Info,
942}
943
944impl Default for PerformanceMonitor {
945    fn default() -> Self {
946        Self::new()
947    }
948}
949
950impl Default for OptimizationCache {
951    fn default() -> Self {
952        Self::new()
953    }
954}