1use super::results::*;
4use crate::DeviceResult;
5use std::collections::{HashMap, VecDeque};
6use std::time::{Duration, Instant, SystemTime};
7
8#[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#[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#[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#[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#[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#[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
108pub 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 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), aggregation_intervals: vec![
126 Duration::from_secs(60), Duration::from_secs(300), Duration::from_secs(900), Duration::from_secs(3600), ],
131 }
132 }
133
134 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 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 self.cleanup_old_metrics()?;
165
166 Ok(())
167 }
168
169 pub fn get_performance_summary(&self) -> DeviceResult<PerformanceSummary> {
171 if self.metrics_history.is_empty() {
172 return Ok(PerformanceSummary::default());
173 }
174
175 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 let overall_stats = self.calculate_overall_statistics()?;
184
185 let active_alerts = self.detect_performance_alerts()?;
187
188 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, optimization_savings: 0.1, resource_utilization: 0.7, 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 pub fn check_alerts(&self) -> DeviceResult<Vec<PerformanceAlert>> {
209 self.detect_performance_alerts()
210 }
211
212 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 fn export_as_json(&self) -> DeviceResult<String> {
478 use std::fmt::Write;
479 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 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 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 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 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
730pub 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 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), }
747 }
748
749 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 if self.cache.len() > self.max_cache_size {
769 self.cleanup_cache()?;
770 }
771
772 Ok(())
773 }
774
775 pub fn get_optimization(&mut self, key: &str) -> Option<OptimizationResult> {
777 if !self.cache_enabled {
778 return None;
779 }
780
781 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 self.cache.remove(key);
799 }
800
801 None
802 }
803
804 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 pub fn clear(&mut self) {
822 self.cache.clear();
823 }
824
825 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, cache_hit_rate: 0.8, miss_rate: 0.2,
851 eviction_rate: 0.1,
852 memory_usage: (total_entries * 100) as f64, avg_age,
854 }
855 }
856
857 fn cleanup_cache(&mut self) -> DeviceResult<()> {
859 let now = SystemTime::now();
860
861 self.cache.retain(|_, cached| {
863 now.duration_since(cached.cached_at)
864 .unwrap_or(Duration::MAX)
865 < self.cache_ttl
866 });
867
868 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#[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}