use scirs2_core::numeric::Float;
use std::collections::HashMap;
use std::fmt::Debug;
use std::time::{Duration, SystemTime};
use super::types::*;
use crate::nas_engine::results::EvaluationResults;
#[derive(Debug)]
pub struct EvaluationCache<T: Float + Debug + Send + Sync + 'static> {
evaluations: HashMap<String, CachedEvaluation<T>>,
metadata: CacheMetadata,
access_patterns: AccessPatterns,
}
#[derive(Debug, Clone)]
pub struct CachedEvaluation<T: Float + Debug + Send + Sync + 'static> {
pub results: EvaluationResults<T>,
pub timestamp: SystemTime,
pub access_count: usize,
pub is_valid: bool,
}
#[derive(Debug, Clone)]
pub struct CacheMetadata {
pub total_entries: usize,
pub cache_size_bytes: usize,
pub last_cleanup: SystemTime,
pub version: String,
}
#[derive(Debug)]
pub struct AccessPatterns {
frequency_distribution: HashMap<String, usize>,
temporal_patterns: Vec<TemporalPattern>,
correlation_patterns: HashMap<String, Vec<String>>,
}
#[derive(Debug, Clone)]
pub struct TemporalPattern {
time_window: Duration,
access_frequency: f64,
pattern_type: TemporalPatternType,
}
impl<T: Float + Debug + Default + Send + Sync> EvaluationCache<T> {
pub(crate) fn new() -> Self {
Self {
evaluations: HashMap::new(),
metadata: CacheMetadata {
total_entries: 0,
cache_size_bytes: 0,
last_cleanup: SystemTime::now(),
version: "1.0.0".to_string(),
},
access_patterns: AccessPatterns {
frequency_distribution: HashMap::new(),
temporal_patterns: Vec::new(),
correlation_patterns: HashMap::new(),
},
}
}
pub(crate) fn get(&self, key: &str) -> Option<&CachedEvaluation<T>> {
self.evaluations.get(key)
}
pub(crate) fn insert(&mut self, key: String, results: EvaluationResults<T>) {
let cached_eval = CachedEvaluation {
results,
timestamp: SystemTime::now(),
access_count: 1,
is_valid: true,
};
self.evaluations.insert(key, cached_eval);
self.metadata.total_entries += 1;
}
pub fn stats(&self) -> &CacheMetadata {
&self.metadata
}
pub fn clear(&mut self) {
self.evaluations.clear();
self.metadata.total_entries = 0;
self.metadata.cache_size_bytes = 0;
self.metadata.last_cleanup = SystemTime::now();
}
pub fn contains(&self, key: &str) -> bool {
self.evaluations.contains_key(key)
}
pub fn len(&self) -> usize {
self.evaluations.len()
}
pub fn is_empty(&self) -> bool {
self.evaluations.is_empty()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_evaluation_cache() {
let mut cache = EvaluationCache::<f64>::new();
assert_eq!(cache.metadata.total_entries, 0);
let results = EvaluationResults {
metric_scores: std::collections::HashMap::new(),
overall_score: 0.95,
confidence_intervals: std::collections::HashMap::new(),
evaluation_time: std::time::Duration::from_secs(100),
success: true,
error_message: None,
cv_results: None,
benchmark_results: std::collections::HashMap::new(),
training_trajectory: vec![],
};
cache.insert("test_key".to_string(), results);
assert_eq!(cache.metadata.total_entries, 1);
assert!(cache.contains("test_key"));
}
}