extern crate alloc;
use super::{CacheMetrics, CoreCacheMetrics};
use alloc::collections::BTreeMap;
use alloc::string::{String, ToString};
#[derive(Debug, Clone)]
pub struct SlruCacheMetrics {
pub core: CoreCacheMetrics,
pub probationary_size: u64,
pub protected_size: u64,
pub protected_max_size: u64,
pub total_promotions: u64,
pub total_demotions: u64,
pub probationary_hits: u64,
pub protected_hits: u64,
pub probationary_evictions: u64,
pub protected_evictions: u64,
}
impl SlruCacheMetrics {
pub fn new(max_cache_size_bytes: u64, protected_max_size: u64) -> Self {
Self {
core: CoreCacheMetrics::new(max_cache_size_bytes),
probationary_size: 0,
protected_size: 0,
protected_max_size,
total_promotions: 0,
total_demotions: 0,
probationary_hits: 0,
protected_hits: 0,
probationary_evictions: 0,
protected_evictions: 0,
}
}
pub fn record_promotion(&mut self) {
self.total_promotions += 1;
}
pub fn record_demotion(&mut self) {
self.total_demotions += 1;
}
pub fn record_probationary_hit(&mut self, object_size: u64) {
self.core.record_hit(object_size);
self.probationary_hits += 1;
}
pub fn record_protected_hit(&mut self, object_size: u64) {
self.core.record_hit(object_size);
self.protected_hits += 1;
}
pub fn record_probationary_eviction(&mut self, evicted_size: u64) {
self.core.record_eviction(evicted_size);
self.probationary_evictions += 1;
}
pub fn record_protected_eviction(&mut self, evicted_size: u64) {
self.core.record_eviction(evicted_size);
self.protected_evictions += 1;
}
pub fn record_probationary_removal(&mut self, removed_size: u64) {
self.core.record_removal(removed_size);
}
pub fn record_protected_removal(&mut self, removed_size: u64) {
self.core.record_removal(removed_size);
}
pub fn update_segment_sizes(&mut self, probationary_size: u64, protected_size: u64) {
self.probationary_size = probationary_size;
self.protected_size = protected_size;
}
pub fn protection_ratio(&self) -> f64 {
if self.core.cache_hits > 0 {
self.protected_hits as f64 / self.core.cache_hits as f64
} else {
0.0
}
}
pub fn promotion_efficiency(&self) -> f64 {
if self.probationary_hits > 0 {
self.total_promotions as f64 / self.probationary_hits as f64
} else {
0.0
}
}
pub fn protected_utilization(&self) -> f64 {
if self.protected_max_size > 0 {
self.protected_size as f64 / self.protected_max_size as f64
} else {
0.0
}
}
pub fn to_btreemap(&self) -> BTreeMap<String, f64> {
let mut metrics = self.core.to_btreemap();
metrics.insert(
"probationary_size".to_string(),
self.probationary_size as f64,
);
metrics.insert("protected_size".to_string(), self.protected_size as f64);
metrics.insert(
"protected_max_size".to_string(),
self.protected_max_size as f64,
);
metrics.insert(
"protected_utilization".to_string(),
self.protected_utilization(),
);
metrics.insert("total_promotions".to_string(), self.total_promotions as f64);
metrics.insert("total_demotions".to_string(), self.total_demotions as f64);
metrics.insert(
"probationary_hits".to_string(),
self.probationary_hits as f64,
);
metrics.insert("protected_hits".to_string(), self.protected_hits as f64);
metrics.insert("protection_ratio".to_string(), self.protection_ratio());
metrics.insert(
"probationary_evictions".to_string(),
self.probationary_evictions as f64,
);
metrics.insert(
"protected_evictions".to_string(),
self.protected_evictions as f64,
);
metrics.insert(
"promotion_efficiency".to_string(),
self.promotion_efficiency(),
);
if self.core.requests > 0 {
metrics.insert(
"promotion_rate".to_string(),
self.total_promotions as f64 / self.core.requests as f64,
);
metrics.insert(
"demotion_rate".to_string(),
self.total_demotions as f64 / self.core.requests as f64,
);
}
metrics
}
}
impl CacheMetrics for SlruCacheMetrics {
fn metrics(&self) -> BTreeMap<String, f64> {
self.to_btreemap()
}
fn algorithm_name(&self) -> &'static str {
"SLRU"
}
}