Files
ruvnet--RuView/vendor/sublinear-time-solver/crates/rustc-hyperopt/src/cache.rs
T
rUv 407b46b206 feat: vendor midstream and sublinear-time-solver libraries (#109)
Add ruvnet/midstream (AIMDS real-time inference) and
ruvnet/sublinear-time-solver (sublinear optimization algorithms)
as vendored dependencies under vendor/.
2026-03-02 23:34:05 -05:00

236 lines
6.9 KiB
Rust

//! Multi-tier cache management system
use crate::{
error::{OptimizerError, Result},
optimizer::CacheConfig,
pattern_db::CompilationPattern,
};
use dashmap::DashMap;
use parking_lot::RwLock;
use serde::{Deserialize, Serialize};
use std::{sync::Arc, time::Instant};
/// Multi-tier cache manager for compilation artifacts
pub struct CacheManager {
config: CacheConfig,
hot_cache: Arc<DashMap<String, CacheEntry>>,
warm_cache: Arc<DashMap<String, CacheEntry>>,
cold_cache: Arc<DashMap<String, CacheEntry>>,
stats: Arc<RwLock<CacheStats>>,
}
impl CacheManager {
/// Create a new cache manager with default configuration
pub fn new() -> Result<Self> {
Ok(Self::with_config(CacheConfig::default())?)
}
/// Create with custom configuration
pub fn with_config(config: CacheConfig) -> Result<Self> {
Ok(Self {
config,
hot_cache: Arc::new(DashMap::new()),
warm_cache: Arc::new(DashMap::new()),
cold_cache: Arc::new(DashMap::new()),
stats: Arc::new(RwLock::new(CacheStats::default())),
})
}
/// Pre-seed caches with known patterns
pub async fn pre_seed_with_patterns(&self, patterns: &[CompilationPattern]) -> Result<()> {
let mut stats = self.stats.write();
stats.pre_seed_operations += 1;
for pattern in patterns {
// Simulate pre-seeding by adding pattern entries to warm cache
let entry = CacheEntry {
data: pattern.fingerprint.clone(),
created_at: chrono::Utc::now(),
last_accessed: chrono::Utc::now(),
access_count: 0,
size_bytes: pattern.fingerprint.len(),
};
self.warm_cache.insert(pattern.pattern_id.clone(), entry);
stats.entries_pre_seeded += 1;
}
Ok(())
}
/// Perform intelligent cache warming
pub async fn intelligent_warm(&self) -> Result<WarmingResult> {
let start_time = Instant::now();
let mut stats = self.stats.write();
stats.warming_operations += 1;
// Simulate intelligent warming by promoting entries from cold to warm
let entries_warmed = self.promote_cold_to_warm().await?;
let warming_time = start_time.elapsed();
stats.total_warming_time += warming_time;
Ok(WarmingResult {
entries_warmed,
warming_time,
cache_hit_rate: self.calculate_hit_rate(),
})
}
/// Get an entry from the cache hierarchy
pub async fn get(&self, key: &str) -> Option<Vec<u8>> {
let mut stats = self.stats.write();
stats.total_accesses += 1;
// Check hot cache first
if let Some(mut entry) = self.hot_cache.get_mut(key) {
entry.last_accessed = chrono::Utc::now();
entry.access_count += 1;
stats.hot_hits += 1;
return Some(entry.data.clone());
}
// Check warm cache
if let Some(entry) = self.warm_cache.get(key) {
let mut entry_clone = entry.clone();
entry_clone.last_accessed = chrono::Utc::now();
entry_clone.access_count += 1;
// Promote to hot cache
self.hot_cache.insert(key.to_string(), entry_clone.clone());
stats.warm_hits += 1;
return Some(entry_clone.data);
}
// Check cold cache
if let Some(entry) = self.cold_cache.get(key) {
let mut entry_clone = entry.clone();
entry_clone.last_accessed = chrono::Utc::now();
entry_clone.access_count += 1;
// Promote to warm cache
self.warm_cache.insert(key.to_string(), entry_clone.clone());
stats.cold_hits += 1;
return Some(entry_clone.data);
}
stats.misses += 1;
None
}
/// Store an entry in the cache
pub async fn put(&self, key: String, data: Vec<u8>) -> Result<()> {
let entry = CacheEntry {
data,
created_at: chrono::Utc::now(),
last_accessed: chrono::Utc::now(),
access_count: 0,
size_bytes: 0, // Would calculate actual size
};
// Store in hot cache for immediate access
self.hot_cache.insert(key, entry);
let mut stats = self.stats.write();
stats.total_insertions += 1;
Ok(())
}
/// Clear all caches
pub async fn clear_all(&self) -> Result<()> {
self.hot_cache.clear();
self.warm_cache.clear();
self.cold_cache.clear();
let mut stats = self.stats.write();
*stats = CacheStats::default();
Ok(())
}
/// Get current cache statistics
pub fn get_stats(&self) -> CacheStats {
self.stats.read().clone()
}
async fn promote_cold_to_warm(&self) -> Result<usize> {
let mut promoted = 0;
// Simplified promotion logic
for entry in self.cold_cache.iter() {
if entry.access_count > 0 {
let (key, value) = entry.pair();
self.warm_cache.insert(key.clone(), value.clone());
promoted += 1;
if promoted >= 10 {
break; // Limit promotions per warming cycle
}
}
}
Ok(promoted)
}
fn calculate_hit_rate(&self) -> f64 {
let stats = self.stats.read();
if stats.total_accesses == 0 {
return 0.0;
}
let total_hits = stats.hot_hits + stats.warm_hits + stats.cold_hits;
(total_hits as f64) / (stats.total_accesses as f64) * 100.0
}
}
/// Result of cache warming operation
#[derive(Debug, Clone)]
pub struct WarmingResult {
/// Number of entries warmed
pub entries_warmed: usize,
/// Time spent warming
pub warming_time: std::time::Duration,
/// Current cache hit rate
pub cache_hit_rate: f64,
}
/// Cache entry with metadata
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CacheEntry {
/// Cached data
pub data: Vec<u8>,
/// When entry was created
pub created_at: chrono::DateTime<chrono::Utc>,
/// Last access time
pub last_accessed: chrono::DateTime<chrono::Utc>,
/// Number of times accessed
pub access_count: u64,
/// Size in bytes
pub size_bytes: usize,
}
/// Cache performance statistics
#[derive(Debug, Clone, Default)]
pub struct CacheStats {
/// Total cache accesses
pub total_accesses: u64,
/// Hot cache hits
pub hot_hits: u64,
/// Warm cache hits
pub warm_hits: u64,
/// Cold cache hits
pub cold_hits: u64,
/// Cache misses
pub misses: u64,
/// Total insertions
pub total_insertions: u64,
/// Pre-seed operations performed
pub pre_seed_operations: u64,
/// Entries pre-seeded
pub entries_pre_seeded: u64,
/// Warming operations performed
pub warming_operations: u64,
/// Total time spent warming
pub total_warming_time: std::time::Duration,
}