extern crate alloc;
use super::{CacheMetrics, CoreCacheMetrics};
use alloc::collections::BTreeMap;
use alloc::string::{String, ToString};
#[derive(Debug, Clone)]
pub struct GdsfCacheMetrics {
pub core: CoreCacheMetrics,
pub global_age: f64,
pub total_aging_events: u64,
pub min_priority: f64,
pub max_priority: f64,
pub total_frequency: u64,
pub total_item_size_processed: u64,
pub small_items_cached: u64,
pub large_items_cached: u64,
pub size_based_evictions: u64,
pub total_frequency_size_ratio: f64,
}
impl GdsfCacheMetrics {
pub fn new(max_cache_size_bytes: u64) -> Self {
Self {
core: CoreCacheMetrics::new(max_cache_size_bytes),
global_age: 0.0,
total_aging_events: 0,
min_priority: 0.0,
max_priority: 0.0,
total_frequency: 0,
total_item_size_processed: 0,
small_items_cached: 0,
large_items_cached: 0,
size_based_evictions: 0,
total_frequency_size_ratio: 0.0,
}
}
pub fn record_aging_event(&mut self, new_global_age: f64) {
self.total_aging_events += 1;
self.global_age = new_global_age;
}
pub fn record_item_access(&mut self, frequency: u64, size: u64, priority: f64) {
self.total_frequency += frequency;
self.total_item_size_processed += size;
if size > 0 {
let freq_size_ratio = frequency as f64 / size as f64;
self.total_frequency_size_ratio += freq_size_ratio;
}
if self.min_priority == 0.0 || priority < self.min_priority {
self.min_priority = priority;
}
if priority > self.max_priority {
self.max_priority = priority;
}
}
pub fn record_item_cached(&mut self, size: u64, average_size: f64) {
if size as f64 <= average_size {
self.small_items_cached += 1;
} else {
self.large_items_cached += 1;
}
}
pub fn record_size_based_eviction(&mut self) {
self.size_based_evictions += 1;
}
pub fn average_frequency(&self) -> f64 {
if self.core.requests > 0 {
self.total_frequency as f64 / self.core.requests as f64
} else {
0.0
}
}
pub fn average_item_size(&self) -> f64 {
if self.core.requests > 0 {
self.total_item_size_processed as f64 / self.core.requests as f64
} else {
0.0
}
}
pub fn average_frequency_size_ratio(&self) -> f64 {
if self.core.requests > 0 {
self.total_frequency_size_ratio / self.core.requests as f64
} else {
0.0
}
}
pub fn priority_range(&self) -> f64 {
if self.max_priority >= self.min_priority {
self.max_priority - self.min_priority
} else {
0.0
}
}
pub fn size_distribution_balance(&self) -> f64 {
let total_cached = self.small_items_cached + self.large_items_cached;
if total_cached > 0 {
self.small_items_cached as f64 / total_cached as f64
} else {
0.0
}
}
pub fn size_eviction_efficiency(&self) -> f64 {
if self.core.evictions > 0 {
self.size_based_evictions as f64 / self.core.evictions 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);
metrics.insert(
"total_aging_events".to_string(),
self.total_aging_events as f64,
);
metrics.insert("min_priority".to_string(), self.min_priority);
metrics.insert("max_priority".to_string(), self.max_priority);
metrics.insert("priority_range".to_string(), self.priority_range());
metrics.insert("total_frequency".to_string(), self.total_frequency as f64);
metrics.insert("average_frequency".to_string(), self.average_frequency());
metrics.insert(
"total_item_size_processed".to_string(),
self.total_item_size_processed as f64,
);
metrics.insert("average_item_size".to_string(), self.average_item_size());
metrics.insert(
"small_items_cached".to_string(),
self.small_items_cached as f64,
);
metrics.insert(
"large_items_cached".to_string(),
self.large_items_cached as f64,
);
metrics.insert(
"size_distribution_balance".to_string(),
self.size_distribution_balance(),
);
metrics.insert(
"total_frequency_size_ratio".to_string(),
self.total_frequency_size_ratio,
);
metrics.insert(
"average_frequency_size_ratio".to_string(),
self.average_frequency_size_ratio(),
);
metrics.insert(
"size_based_evictions".to_string(),
self.size_based_evictions as f64,
);
metrics.insert(
"size_eviction_efficiency".to_string(),
self.size_eviction_efficiency(),
);
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(
"size_based_eviction_rate".to_string(),
self.size_based_evictions as f64 / self.core.requests as f64,
);
}
metrics
}
}
impl CacheMetrics for GdsfCacheMetrics {
fn metrics(&self) -> BTreeMap<String, f64> {
self.to_btreemap()
}
fn algorithm_name(&self) -> &'static str {
"GDSF"
}
}