use std::collections::HashMap;
use std::time::{Duration, Instant};
use super::embedding::EmbeddingOptimizer;
use super::error::{RLEmbeddingError, RLEmbeddingResult};
use super::types::{
CacheMetadata, CachedEmbedding, EmbeddingPerformanceResults, EmbeddingQualityMetrics,
EmbeddingState, RLPerformanceMetrics, RLTrainingStats, RuntimeStatistics,
TransferLearningStats,
};
use crate::embedding::{Embedding, HardwareTopology};
use crate::ising::IsingModel;
pub struct CacheManager;
impl CacheManager {
#[must_use]
pub fn check_cache<'a>(
embedding_cache: &'a HashMap<String, CachedEmbedding>,
state: &EmbeddingState,
) -> Option<&'a CachedEmbedding> {
let cache_key = format!(
"{}_{:.2}_{:.2}",
state.problem_features.num_vertices,
state.problem_features.density,
state.problem_features.average_degree
);
embedding_cache.get(&cache_key)
}
pub fn cache_embedding(
embedding_cache: &mut HashMap<String, CachedEmbedding>,
problem: &IsingModel,
embedding: &Embedding,
hardware: &HardwareTopology,
computation_time: Duration,
) -> RLEmbeddingResult<()> {
let cache_key = format!(
"{}_{:.2}_default",
problem.num_qubits,
EmbeddingOptimizer::calculate_problem_density(problem)
);
let cached_embedding = CachedEmbedding {
embedding: embedding.clone(),
quality_metrics: EmbeddingQualityMetrics {
overall_score: EmbeddingOptimizer::evaluate_embedding_quality(embedding, hardware)?,
chain_length_penalty: EmbeddingOptimizer::calculate_average_chain_length(embedding),
connectivity_score: 0.8, utilization_efficiency: EmbeddingOptimizer::calculate_hardware_utilization(
embedding, hardware,
),
predicted_performance: 0.7, },
performance_results: EmbeddingPerformanceResults {
success_probability: 0.8,
average_energy_gap: 1.0,
solution_quality: vec![0.8, 0.9, 0.7],
runtime_stats: RuntimeStatistics {
embedding_time: computation_time,
execution_time: Duration::from_millis(100),
total_time: computation_time + Duration::from_millis(100),
memory_usage: 1024 * 1024, },
},
cache_metadata: CacheMetadata {
created_at: Instant::now(),
last_accessed: Instant::now(),
access_count: 1,
hit_rate: 0.0,
},
};
embedding_cache.insert(cache_key, cached_embedding);
Ok(())
}
pub fn update_cache_statistics(
embedding_cache: &mut HashMap<String, CachedEmbedding>,
cache_key: &str,
) {
if let Some(cached_embedding) = embedding_cache.get_mut(cache_key) {
cached_embedding.cache_metadata.last_accessed = Instant::now();
cached_embedding.cache_metadata.access_count += 1;
}
}
pub fn cleanup_cache(
embedding_cache: &mut HashMap<String, CachedEmbedding>,
max_age: Duration,
) {
let now = Instant::now();
let mut keys_to_remove = Vec::new();
for (key, cached_embedding) in embedding_cache.iter() {
if now.duration_since(cached_embedding.cache_metadata.created_at) > max_age {
keys_to_remove.push(key.clone());
}
}
for key in keys_to_remove {
embedding_cache.remove(&key);
}
}
#[must_use]
pub fn calculate_cache_hit_rate(embedding_cache: &HashMap<String, CachedEmbedding>) -> f64 {
let total_accesses: usize = embedding_cache
.values()
.map(|entry| entry.cache_metadata.access_count)
.sum();
let cache_hits = embedding_cache.len();
if total_accesses > 0 {
cache_hits as f64 / total_accesses as f64
} else {
0.0
}
}
}
pub struct PerformanceTracker;
impl PerformanceTracker {
pub fn update_performance_metrics(
metrics: &mut RLPerformanceMetrics,
embedding_quality: f64,
baseline_quality: f64,
) {
metrics.problems_solved += 1;
let improvement = embedding_quality - baseline_quality;
let alpha = 0.1; metrics.average_improvement =
alpha * improvement + (1.0 - alpha) * metrics.average_improvement;
if improvement > metrics.best_improvement {
metrics.best_improvement = improvement;
}
}
#[must_use]
pub fn calculate_computational_efficiency(
problems_solved: usize,
total_time: Duration,
average_improvement: f64,
) -> f64 {
if total_time.as_secs_f64() > 0.0 {
(problems_solved as f64 * average_improvement) / total_time.as_secs_f64()
} else {
0.0
}
}
pub fn update_convergence_rate(
metrics: &mut RLPerformanceMetrics,
training_stats: &RLTrainingStats,
) {
if training_stats.loss_history.len() > 10 {
let recent_losses =
&training_stats.loss_history[training_stats.loss_history.len() - 10..];
let initial_loss = recent_losses[0];
let final_loss = recent_losses[recent_losses.len() - 1];
if initial_loss > 0.0 {
metrics.convergence_rate = (initial_loss - final_loss) / initial_loss;
}
}
}
pub const fn update_transfer_effectiveness(
metrics: &mut RLPerformanceMetrics,
transfer_stats: &TransferLearningStats,
) {
metrics.transfer_effectiveness = transfer_stats.transfer_effectiveness;
}
#[must_use]
pub fn generate_performance_report(metrics: &RLPerformanceMetrics) -> String {
format!(
"RL Embedding Optimizer Performance Report:\n\
Problems Solved: {}\n\
Average Improvement: {:.3}\n\
Best Improvement: {:.3}\n\
Convergence Rate: {:.3}\n\
Transfer Effectiveness: {:.3}\n\
Computational Efficiency: {:.3}",
metrics.problems_solved,
metrics.average_improvement,
metrics.best_improvement,
metrics.convergence_rate,
metrics.transfer_effectiveness,
metrics.computational_efficiency
)
}
}