use super::*;
use crate::error::{CoreError, CoreResult};
#[cfg(feature = "gpu")]
use std::collections::HashMap;
#[cfg(feature = "gpu")]
use std::time::{Duration, Instant};
#[cfg(feature = "gpu")]
use crate::gpu::{
auto_tuning::{KernelParameters, PerformanceMetrics},
tensor_cores::{TensorCoreConfig, TensorOperation},
};
#[cfg(all(feature = "serde", feature = "gpu"))]
#[cfg(feature = "serialization")]
use serde::{Deserialize, Serialize};
#[allow(dead_code)]
#[derive(Debug)]
pub struct SmartCacheSystem {
configuration_cache: HashMap<String, CachedConfiguration>,
#[allow(dead_code)]
cache_analytics: CacheAnalytics,
#[allow(dead_code)]
eviction_policy: EvictionPolicy,
#[allow(dead_code)]
prefetch_engine: PrefetchEngine,
#[allow(dead_code)]
cache_optimizer: CacheOptimizer,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CachedConfiguration {
pub id: String,
pub tensor_config: TensorCoreConfig,
pub kernel_params: KernelParameters,
pub performance: PerformanceMetrics,
pub usage_stats: UsageStatistics,
pub cached_at: Instant,
pub last_accessed: Instant,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct UsageStatistics {
pub access_count: u64,
pub hit_rate: f64,
pub avg_improvement: f64,
pub success_rate: f64,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CacheAnalytics {
pub hit_rate: f64,
pub miss_rate: f64,
pub avg_lookup_time: Duration,
pub utilization: f64,
pub eviction_rate: f64,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum EvictionPolicy {
LRU, LFU, FIFO, Random,
TTL, Adaptive, }
#[allow(dead_code)]
#[derive(Debug)]
pub struct PrefetchEngine {
#[allow(dead_code)]
prefetch_algorithms: Vec<PrefetchAlgorithm>,
#[allow(dead_code)]
pattern_analyzer: AccessPatternAnalyzer,
#[allow(dead_code)]
prefetch_decisions: Vec<PrefetchDecision>,
#[allow(dead_code)]
prefetch_metrics: PrefetchMetrics,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum PrefetchAlgorithm {
SequentialPrefetch,
StridePrefetch,
PatternBasedPrefetch,
MLBasedPrefetch,
GraphBasedPrefetch,
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct AccessPatternAnalyzer {
patterns: Vec<AccessPattern>,
pattern_confidence: HashMap<String, f64>,
pattern_predictions: Vec<PatternPrediction>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum AccessPattern {
Sequential,
Random,
Temporal,
Spatial,
LoopingPattern,
Custom(String),
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PatternPrediction {
pub pattern: AccessPattern,
pub next_access: String,
pub confidence: f64,
pub timestamp: Instant,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PrefetchDecision {
pub item_id: String,
pub algorithm: PrefetchAlgorithm,
pub confidence: f64,
pub timestamp: Instant,
pub success: Option<bool>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct PrefetchMetrics {
pub accuracy: f64,
pub hit_rate: f64,
pub bandwidth_saved: f64,
pub latency_reduction: Duration,
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct CacheOptimizer {
optimization_strategies: Vec<CacheOptimizationStrategy>,
performance_model: CachePerformanceModel,
optimization_history: Vec<CacheOptimizationDecision>,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub enum CacheOptimizationStrategy {
SizeOptimization,
ReplacementOptimization,
PrefetchOptimization,
PartitioningOptimization,
CompressionOptimization,
}
#[allow(dead_code)]
#[derive(Debug)]
pub struct CachePerformanceModel {
parameters: HashMap<String, f64>,
predictions: HashMap<String, f64>,
accuracy: f64,
}
#[allow(dead_code)]
#[derive(Debug, Clone)]
pub struct CacheOptimizationDecision {
pub optimization_type: CacheOptimizationStrategy,
pub parameters: HashMap<String, f64>,
pub expected_improvement: f64,
pub actual_improvement: Option<f64>,
pub timestamp: Instant,
}
impl SmartCacheSystem {
pub fn new() -> CoreResult<Self> {
Ok(Self {
configuration_cache: HashMap::new(),
cache_analytics: CacheAnalytics {
hit_rate: 0.0,
miss_rate: 1.0,
avg_lookup_time: Duration::from_micros(10),
utilization: 0.0,
eviction_rate: 0.0,
},
eviction_policy: EvictionPolicy::Adaptive,
prefetch_engine: PrefetchEngine::new()?,
cache_optimizer: CacheOptimizer::new()?,
})
}
pub fn lookup_configuration(
&mut self,
operation: &TensorOperation,
) -> CoreResult<Option<CachedConfiguration>> {
let cache_key = self.generate_cache_key(operation)?;
if let Some(cached_config) = self.configuration_cache.get_mut(&cache_key) {
cached_config.last_accessed = Instant::now();
cached_config.usage_stats.access_count += 1;
let config_clone = cached_config.clone();
self.update_hit_statistics();
Ok(Some(config_clone))
} else {
self.update_miss_statistics();
self.predict_and_prefetch(operation)?;
Ok(None)
}
}
pub fn store_configuration(
&mut self,
operation: &TensorOperation,
config: TensorCoreConfig,
kernel_params: KernelParameters,
performance: PerformanceMetrics,
) -> CoreResult<()> {
let cache_key = self.generate_cache_key(operation)?;
let cached_config = CachedConfiguration {
id: cache_key.clone(),
tensor_config: config,
kernel_params,
performance,
usage_stats: UsageStatistics {
access_count: 1,
hit_rate: 0.0,
avg_improvement: 0.0,
success_rate: 1.0,
},
cached_at: Instant::now(),
last_accessed: Instant::now(),
};
if self.configuration_cache.len() >= self.get_max_cache_size() {
self.evict_entry()?;
}
self.configuration_cache.insert(cache_key, cached_config);
self.update_cache_analytics();
Ok(())
}
fn generate_cache_key(&self, operation: &TensorOperation) -> CoreResult<String> {
let key = format!(
"{}_{}_{}_{}_{}",
operation.dimensions.0, operation.dimensions.1, operation.dimensions.2, format!("{:?}", operation.input_type).len() as u8, format!("{:?}", operation.op_type).len() as u8 );
Ok(key)
}
fn get_max_cache_size(&self) -> usize {
1000 }
fn evict_entry(&mut self) -> CoreResult<()> {
match self.eviction_policy {
EvictionPolicy::LRU => self.evict_lru(),
EvictionPolicy::LFU => self.evict_lfu(),
EvictionPolicy::FIFO => self.evict_fifo(),
EvictionPolicy::Random => self.evict_random(),
EvictionPolicy::TTL => self.evict_ttl(),
EvictionPolicy::Adaptive => self.evict_adaptive(),
}
}
fn evict_lru(&mut self) -> CoreResult<()> {
let mut oldest_key = None;
let mut oldest_time = Instant::now();
for (key, config) in &self.configuration_cache {
if config.last_accessed < oldest_time {
oldest_time = config.last_accessed;
oldest_key = Some(key.clone());
}
}
if let Some(key) = oldest_key {
self.configuration_cache.remove(&key);
}
Ok(())
}
fn evict_lfu(&mut self) -> CoreResult<()> {
let mut lfu_key = None;
let mut min_access_count = u64::MAX;
for (key, config) in &self.configuration_cache {
if config.usage_stats.access_count < min_access_count {
min_access_count = config.usage_stats.access_count;
lfu_key = Some(key.clone());
}
}
if let Some(key) = lfu_key {
self.configuration_cache.remove(&key);
}
Ok(())
}
fn evict_fifo(&mut self) -> CoreResult<()> {
let mut oldest_key = None;
let mut oldest_time = Instant::now();
for (key, config) in &self.configuration_cache {
if config.cached_at < oldest_time {
oldest_time = config.cached_at;
oldest_key = Some(key.clone());
}
}
if let Some(key) = oldest_key {
self.configuration_cache.remove(&key);
}
Ok(())
}
fn evict_random(&mut self) -> CoreResult<()> {
if !self.configuration_cache.is_empty() {
let keys: Vec<_> = self.configuration_cache.keys().cloned().collect();
let random_index = rand_index(keys.len());
if let Some(key) = keys.get(random_index) {
self.configuration_cache.remove(key);
}
}
Ok(())
}
fn evict_ttl(&mut self) -> CoreResult<()> {
let ttl = Duration::from_secs(3600); let cutoff_time = Instant::now() - ttl;
let keys_to_remove: Vec<_> = self
.configuration_cache
.iter()
.filter(|(_, config)| config.cached_at < cutoff_time)
.map(|(key, _)| key.clone())
.collect();
for key in keys_to_remove {
self.configuration_cache.remove(&key);
}
if self.configuration_cache.len() >= self.get_max_cache_size() {
self.evict_lru()?;
}
Ok(())
}
fn evict_adaptive(&mut self) -> CoreResult<()> {
let mut eviction_scores: Vec<(String, f64)> = Vec::new();
for (key, config) in &self.configuration_cache {
let age_factor = config.cached_at.elapsed().as_secs_f64() / 3600.0; let access_factor = 1.0 / (config.usage_stats.access_count as f64 + 1.0);
let performance_factor = 1.0 / (config.performance.throughput + 1.0);
let success_factor = 1.0 - config.usage_stats.success_rate;
let score = age_factor + access_factor + performance_factor + success_factor;
eviction_scores.push((key.clone(), score));
}
eviction_scores.sort_by(|a, b| b.1.partial_cmp(&a.1).expect("Operation failed"));
if let Some((key, _)) = eviction_scores.first() {
self.configuration_cache.remove(key);
}
Ok(())
}
fn update_hit_statistics(&mut self) {
let total_hits = self.cache_analytics.hit_rate * 100.0 + 1.0;
let total_accesses = total_hits / self.cache_analytics.hit_rate.max(0.01);
self.cache_analytics.hit_rate = total_hits / (total_accesses + 1.0);
self.cache_analytics.miss_rate = 1.0 - self.cache_analytics.hit_rate;
}
fn update_miss_statistics(&mut self) {
let total_misses = self.cache_analytics.miss_rate * 100.0 + 1.0;
let total_accesses = total_misses / self.cache_analytics.miss_rate.max(0.01);
self.cache_analytics.miss_rate = total_misses / (total_accesses + 1.0);
self.cache_analytics.hit_rate = 1.0 - self.cache_analytics.miss_rate;
}
fn update_cache_analytics(&mut self) {
self.cache_analytics.utilization =
self.configuration_cache.len() as f64 / self.get_max_cache_size() as f64;
}
fn predict_and_prefetch(&mut self, operation: &TensorOperation) -> CoreResult<()> {
let pattern = self.analyze_access_pattern(operation)?;
if let Some(prediction) = self.predict_next_access(&pattern)? {
self.prefetch_configuration(&prediction)?;
}
Ok(())
}
fn analyze_access_pattern(&self, operation: &TensorOperation) -> CoreResult<AccessPattern> {
if operation.dimensions.0 > 32 {
Ok(AccessPattern::Sequential)
} else if operation.dimensions.1 > 512 {
Ok(AccessPattern::Temporal)
} else {
Ok(AccessPattern::Random)
}
}
fn predict_next_access(&self, pattern: &AccessPattern) -> CoreResult<Option<String>> {
match pattern {
AccessPattern::Sequential => {
Ok(Some("next_sequential_config".to_string()))
}
AccessPattern::Temporal => {
Ok(Some("temporal_config".to_string()))
}
_ => Ok(None),
}
}
fn prefetch_configuration(&mut self, config_id: &str) -> CoreResult<()> {
println!("Prefetching configuration: {}", config_id);
Ok(())
}
pub fn get_cache_analytics(&self) -> &CacheAnalytics {
&self.cache_analytics
}
pub fn clear_cache(&mut self) {
self.configuration_cache.clear();
self.cache_analytics = CacheAnalytics {
hit_rate: 0.0,
miss_rate: 1.0,
avg_lookup_time: Duration::from_micros(10),
utilization: 0.0,
eviction_rate: 0.0,
};
}
pub fn cache_size(&self) -> usize {
self.configuration_cache.len()
}
pub fn optimize_cache(&mut self) -> CoreResult<()> {
let current_hit_rate = self.cache_analytics.hit_rate;
if current_hit_rate < 0.5 {
self.eviction_policy = EvictionPolicy::Adaptive;
} else if current_hit_rate > 0.9 {
}
Ok(())
}
}
impl PrefetchEngine {
pub fn new() -> CoreResult<Self> {
Ok(Self {
prefetch_algorithms: vec![PrefetchAlgorithm::MLBasedPrefetch],
pattern_analyzer: AccessPatternAnalyzer {
patterns: vec![],
pattern_confidence: HashMap::new(),
pattern_predictions: vec![],
},
prefetch_decisions: Vec::new(),
prefetch_metrics: PrefetchMetrics {
accuracy: 0.8,
hit_rate: 0.7,
bandwidth_saved: 0.3,
latency_reduction: Duration::from_millis(5),
},
})
}
pub fn analyze_and_prefetch(
&mut self,
access_history: &[String],
) -> CoreResult<Vec<PrefetchDecision>> {
let patterns = self.detect_patterns(access_history)?;
let mut decisions = Vec::new();
for pattern in patterns {
if let Some(decision) = self.make_prefetch_decision(&pattern)? {
decisions.push(decision);
}
}
self.prefetch_decisions.extend(decisions.clone());
Ok(decisions)
}
fn detect_patterns(&mut self, access_history: &[String]) -> CoreResult<Vec<AccessPattern>> {
let mut detected_patterns = Vec::new();
if access_history.len() > 3 {
let mut is_sequential = true;
for i in 1..access_history.len() {
if !self.is_sequential_access(&access_history[i - 1], &access_history[i]) {
is_sequential = false;
break;
}
}
if is_sequential {
detected_patterns.push(AccessPattern::Sequential);
self.pattern_analyzer
.pattern_confidence
.insert("sequential".to_string(), 0.9);
}
if self.has_looping_pattern(access_history) {
detected_patterns.push(AccessPattern::LoopingPattern);
self.pattern_analyzer
.pattern_confidence
.insert("looping".to_string(), 0.8);
}
}
self.pattern_analyzer
.patterns
.extend(detected_patterns.clone());
Ok(detected_patterns)
}
fn is_sequential_access(&self, prev: &str, curr: &str) -> bool {
curr > prev && curr.len() == prev.len()
}
fn has_looping_pattern(&self, access_history: &[String]) -> bool {
if access_history.len() < 6 {
return false;
}
let half_len = access_history.len() / 2;
let first_half = &access_history[0..half_len];
let second_half = &access_history[half_len..2 * half_len];
first_half == second_half
}
fn make_prefetch_decision(
&self,
pattern: &AccessPattern,
) -> CoreResult<Option<PrefetchDecision>> {
match pattern {
AccessPattern::Sequential => Ok(Some(PrefetchDecision {
item_id: "next_sequential_item".to_string(),
algorithm: PrefetchAlgorithm::SequentialPrefetch,
confidence: 0.9,
timestamp: Instant::now(),
success: None,
})),
AccessPattern::LoopingPattern => Ok(Some(PrefetchDecision {
item_id: "loop_start_item".to_string(),
algorithm: PrefetchAlgorithm::PatternBasedPrefetch,
confidence: 0.8,
timestamp: Instant::now(),
success: None,
})),
_ => Ok(None),
}
}
pub fn update_prefetch_effectiveness(&mut self, decision_id: &str, was_successful: bool) {
for decision in &mut self.prefetch_decisions {
if decision.item_id == decision_id {
decision.success = Some(was_successful);
break;
}
}
self.recalculate_metrics();
}
fn recalculate_metrics(&mut self) {
let total_decisions = self.prefetch_decisions.len();
if total_decisions == 0 {
return;
}
let successful_decisions = self
.prefetch_decisions
.iter()
.filter(|d| d.success == Some(true))
.count();
self.prefetch_metrics.accuracy = successful_decisions as f64 / total_decisions as f64;
self.prefetch_metrics.hit_rate = self.prefetch_metrics.accuracy;
self.prefetch_metrics.bandwidth_saved = self.prefetch_metrics.accuracy * 0.4;
self.prefetch_metrics.latency_reduction =
Duration::from_millis((self.prefetch_metrics.accuracy * 10.0) as u64);
}
pub fn get_prefetch_metrics(&self) -> &PrefetchMetrics {
&self.prefetch_metrics
}
}
impl CacheOptimizer {
pub fn new() -> CoreResult<Self> {
Ok(Self {
optimization_strategies: vec![CacheOptimizationStrategy::SizeOptimization],
performance_model: CachePerformanceModel {
parameters: HashMap::new(),
predictions: HashMap::new(),
accuracy: 0.85,
},
optimization_history: Vec::new(),
})
}
pub fn optimize(
&mut self,
cache_analytics: &CacheAnalytics,
) -> CoreResult<Vec<CacheOptimizationDecision>> {
let mut decisions = Vec::new();
if cache_analytics.hit_rate < 0.5 {
let decision = self.optimize_cache_size(cache_analytics)?;
decisions.push(decision);
}
if cache_analytics.avg_lookup_time > Duration::from_millis(1) {
let decision = self.optimize_partitioning(cache_analytics)?;
decisions.push(decision);
}
if cache_analytics.utilization > 0.9 {
let decision = self.optimize_compression(cache_analytics)?;
decisions.push(decision);
}
self.optimization_history.extend(decisions.clone());
Ok(decisions)
}
fn optimize_cache_size(
&self,
analytics: &CacheAnalytics,
) -> CoreResult<CacheOptimizationDecision> {
let current_size = 1000.0; let suggested_size = current_size * (1.0 + (0.5 - analytics.hit_rate));
let mut parameters = HashMap::new();
parameters.insert("cache_size".to_string(), suggested_size);
Ok(CacheOptimizationDecision {
optimization_type: CacheOptimizationStrategy::SizeOptimization,
parameters,
expected_improvement: 0.1, actual_improvement: None,
timestamp: Instant::now(),
})
}
fn optimize_partitioning(
&self,
analytics: &CacheAnalytics,
) -> CoreResult<CacheOptimizationDecision> {
let mut parameters = HashMap::new();
parameters.insert("partition_count".to_string(), 4.0);
parameters.insert("partition_strategy".to_string(), 1.0);
Ok(CacheOptimizationDecision {
optimization_type: CacheOptimizationStrategy::PartitioningOptimization,
parameters,
expected_improvement: 0.05, actual_improvement: None,
timestamp: Instant::now(),
})
}
fn optimize_compression(
&self,
analytics: &CacheAnalytics,
) -> CoreResult<CacheOptimizationDecision> {
let mut parameters = HashMap::new();
parameters.insert("compression_ratio".to_string(), 0.7);
parameters.insert("compression_algorithm".to_string(), 2.0);
Ok(CacheOptimizationDecision {
optimization_type: CacheOptimizationStrategy::CompressionOptimization,
parameters,
expected_improvement: 0.15, actual_improvement: None,
timestamp: Instant::now(),
})
}
pub fn update_optimization_result(&mut self, optimization_id: usize, actual_improvement: f64) {
if let Some(decision) = self.optimization_history.get_mut(optimization_id) {
decision.actual_improvement = Some(actual_improvement);
}
self.update_model_accuracy();
}
fn update_model_accuracy(&mut self) {
let predictions_with_actuals: Vec<_> = self
.optimization_history
.iter()
.filter(|d| d.actual_improvement.is_some())
.collect();
if !predictions_with_actuals.is_empty() {
let total_error: f64 = predictions_with_actuals
.iter()
.map(|d| {
let actual = d.actual_improvement.expect("Operation failed");
let predicted = d.expected_improvement;
(actual - predicted).abs()
})
.sum();
let mean_error = total_error / predictions_with_actuals.len() as f64;
self.performance_model.accuracy = 1.0 - mean_error.min(1.0);
}
}
}
impl Default for AccessPatternAnalyzer {
fn default() -> Self {
Self::new()
}
}
impl AccessPatternAnalyzer {
pub fn new() -> Self {
Self {
patterns: Vec::new(),
pattern_confidence: HashMap::new(),
pattern_predictions: Vec::new(),
}
}
pub fn analyze_patterns(
&mut self,
access_history: &[String],
) -> CoreResult<Vec<AccessPattern>> {
let mut detected_patterns = Vec::new();
if self.has_spatial_locality(access_history) {
detected_patterns.push(AccessPattern::Spatial);
self.pattern_confidence.insert("spatial".to_string(), 0.8);
}
if self.has_temporal_locality(access_history) {
detected_patterns.push(AccessPattern::Temporal);
self.pattern_confidence.insert("temporal".to_string(), 0.7);
}
if self.has_sequential_access(access_history) {
detected_patterns.push(AccessPattern::Sequential);
self.pattern_confidence
.insert("sequential".to_string(), 0.9);
}
self.patterns.extend(detected_patterns.clone());
Ok(detected_patterns)
}
fn has_spatial_locality(&self, access_history: &[String]) -> bool {
if access_history.len() < 3 {
return false;
}
let mut similar_pairs = 0;
for i in 1..access_history.len() {
if self.strings_are_similar(&access_history[i - 1], &access_history[i]) {
similar_pairs += 1;
}
}
similar_pairs as f64 / (access_history.len() - 1) as f64 > 0.6
}
fn has_temporal_locality(&self, access_history: &[String]) -> bool {
let mut unique_accesses = std::collections::HashSet::new();
let mut repeated_accesses = 0;
for access in access_history {
if unique_accesses.contains(access) {
repeated_accesses += 1;
} else {
unique_accesses.insert(access.clone());
}
}
repeated_accesses as f64 / access_history.len() as f64 > 0.3
}
fn has_sequential_access(&self, access_history: &[String]) -> bool {
if access_history.len() < 3 {
return false;
}
let mut sequential_count = 0;
for i in 1..access_history.len() {
if access_history[i] > access_history[i - 1] {
sequential_count += 1;
}
}
sequential_count as f64 / (access_history.len() - 1) as f64 > 0.8
}
fn strings_are_similar(&self, a: &str, b: &str) -> bool {
if a.len() != b.len() {
return false;
}
let mut differences = 0;
for (char_a, char_b) in a.chars().zip(b.chars()) {
if char_a != char_b {
differences += 1;
}
}
differences <= a.len() / 3 }
pub fn predict_next_accesses(
&mut self,
current_access: &str,
) -> CoreResult<Vec<PatternPrediction>> {
let mut predictions = Vec::new();
for pattern in &self.patterns {
if let Some(confidence) = self.pattern_confidence.get(&pattern_to_string(pattern)) {
let prediction = match pattern {
AccessPattern::Sequential => PatternPrediction {
pattern: pattern.clone(),
next_access: self.predict_sequential_next(current_access),
confidence: *confidence,
timestamp: Instant::now(),
},
AccessPattern::Temporal => PatternPrediction {
pattern: pattern.clone(),
next_access: self.predict_temporal_next(current_access),
confidence: *confidence,
timestamp: Instant::now(),
},
_ => {
PatternPrediction {
pattern: pattern.clone(),
next_access: current_access.to_string(),
confidence: *confidence * 0.5, timestamp: Instant::now(),
}
}
};
predictions.push(prediction);
}
}
self.pattern_predictions.extend(predictions.clone());
Ok(predictions)
}
fn predict_sequential_next(&self, current: &str) -> String {
format!("{}_next", current)
}
fn predict_temporal_next(&self, current: &str) -> String {
format!("{}_temporal", current)
}
}
fn pattern_to_string(pattern: &AccessPattern) -> String {
match pattern {
AccessPattern::Sequential => "sequential".to_string(),
AccessPattern::Random => "random".to_string(),
AccessPattern::Temporal => "temporal".to_string(),
AccessPattern::Spatial => "spatial".to_string(),
AccessPattern::LoopingPattern => "looping".to_string(),
AccessPattern::Custom(name) => name.clone(),
}
}
fn rand_index(max: usize) -> usize {
use std::collections::hash_map::DefaultHasher;
use std::hash::{Hash, Hasher};
use std::time::SystemTime;
let mut hasher = DefaultHasher::new();
SystemTime::now().hash(&mut hasher);
let hash = hasher.finish();
(hash as usize) % max.max(1)
}
impl Default for UsageStatistics {
fn default() -> Self {
Self {
access_count: 0,
hit_rate: 0.0,
avg_improvement: 0.0,
success_rate: 0.0,
}
}
}
impl Default for CacheAnalytics {
fn default() -> Self {
Self {
hit_rate: 0.0,
miss_rate: 1.0,
avg_lookup_time: Duration::from_micros(10),
utilization: 0.0,
eviction_rate: 0.0,
}
}
}
impl Default for PrefetchMetrics {
fn default() -> Self {
Self {
accuracy: 0.0,
hit_rate: 0.0,
bandwidth_saved: 0.0,
latency_reduction: Duration::default(),
}
}
}