extern crate alloc;
use super::{CacheMetrics, CoreCacheMetrics};
use alloc::collections::BTreeMap;
use alloc::string::{String, ToString};
#[derive(Debug, Clone)]
pub struct LfudaCacheMetrics {
pub core: CoreCacheMetrics,
pub global_age: u64,
pub total_aging_events: u64,
pub min_priority: u64,
pub max_priority: u64,
pub total_frequency_increments: u64,
pub items_benefited_from_aging: u64,
pub total_age_distributed: u64,
}
impl LfudaCacheMetrics {
pub fn new(max_cache_size_bytes: u64) -> Self {
Self {
core: CoreCacheMetrics::new(max_cache_size_bytes),
global_age: 0,
total_aging_events: 0,
min_priority: 0,
max_priority: 0,
total_frequency_increments: 0,
items_benefited_from_aging: 0,
total_age_distributed: 0,
}
}
pub fn record_aging_event(&mut self, new_global_age: u64) {
self.total_aging_events += 1;
self.global_age = new_global_age;
}
pub fn record_frequency_increment(&mut self, new_priority: u64) {
self.total_frequency_increments += 1;
if self.min_priority == 0 || new_priority < self.min_priority {
self.min_priority = new_priority;
}
if new_priority > self.max_priority {
self.max_priority = new_priority;
}
}
pub fn record_aging_benefit(&mut self, age_benefit: u64) {
self.items_benefited_from_aging += 1;
self.total_age_distributed += age_benefit;
}
pub fn average_aging_benefit(&self) -> f64 {
if self.items_benefited_from_aging > 0 {
self.total_age_distributed as f64 / self.items_benefited_from_aging as f64
} else {
0.0
}
}
pub fn priority_range(&self) -> u64 {
self.max_priority.saturating_sub(self.min_priority)
}
pub fn aging_effectiveness(&self) -> f64 {
if self.core.evictions > 0 {
self.total_aging_events as f64 / self.core.evictions as f64
} else {
0.0
}
}
pub fn aging_contribution_ratio(&self) -> f64 {
if self.total_frequency_increments > 0 && self.total_age_distributed > 0 {
self.total_age_distributed as f64
/ (self.total_frequency_increments + self.total_age_distributed) as f64
} else {
0.0
}
}
pub fn to_btreemap(&self) -> BTreeMap<String, f64> {
let mut metrics = self.core.to_btreemap();
metrics.insert("global_age".to_string(), self.global_age as f64);
metrics.insert(
"total_aging_events".to_string(),
self.total_aging_events as f64,
);
metrics.insert(
"aging_effectiveness".to_string(),
self.aging_effectiveness(),
);
metrics.insert("min_priority".to_string(), self.min_priority as f64);
metrics.insert("max_priority".to_string(), self.max_priority as f64);
metrics.insert("priority_range".to_string(), self.priority_range() as f64);
metrics.insert(
"total_frequency_increments".to_string(),
self.total_frequency_increments as f64,
);
metrics.insert(
"items_benefited_from_aging".to_string(),
self.items_benefited_from_aging as f64,
);
metrics.insert(
"total_age_distributed".to_string(),
self.total_age_distributed as f64,
);
metrics.insert(
"average_aging_benefit".to_string(),
self.average_aging_benefit(),
);
metrics.insert(
"aging_contribution_ratio".to_string(),
self.aging_contribution_ratio(),
);
if self.core.requests > 0 {
metrics.insert(
"aging_event_rate".to_string(),
self.total_aging_events as f64 / self.core.requests as f64,
);
metrics.insert(
"frequency_increment_rate".to_string(),
self.total_frequency_increments as f64 / self.core.requests as f64,
);
metrics.insert(
"aging_benefit_rate".to_string(),
self.items_benefited_from_aging as f64 / self.core.requests as f64,
);
}
metrics
}
}
impl CacheMetrics for LfudaCacheMetrics {
fn metrics(&self) -> BTreeMap<String, f64> {
self.to_btreemap()
}
fn algorithm_name(&self) -> &'static str {
"LFUDA"
}
}