use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Default)]
pub struct CacheMetrics {
hits: AtomicU64,
misses: AtomicU64,
inserts: AtomicU64,
evictions: AtomicU64,
}
impl CacheMetrics {
pub fn new() -> Self {
Self::default()
}
pub fn record_hit(&self) {
self.hits.fetch_add(1, Ordering::Relaxed);
}
pub fn record_miss(&self) {
self.misses.fetch_add(1, Ordering::Relaxed);
}
pub fn record_insert(&self) {
self.inserts.fetch_add(1, Ordering::Relaxed);
}
pub fn record_eviction(&self) {
self.evictions.fetch_add(1, Ordering::Relaxed);
}
pub fn hits(&self) -> u64 {
self.hits.load(Ordering::Relaxed)
}
pub fn misses(&self) -> u64 {
self.misses.load(Ordering::Relaxed)
}
pub fn inserts(&self) -> u64 {
self.inserts.load(Ordering::Relaxed)
}
pub fn evictions(&self) -> u64 {
self.evictions.load(Ordering::Relaxed)
}
pub fn total_requests(&self) -> u64 {
self.hits() + self.misses()
}
pub fn hit_ratio(&self) -> f64 {
let total = self.total_requests();
if total == 0 {
0.0
} else {
(self.hits() as f64 / total as f64) * 100.0
}
}
pub fn reset(&self) {
self.hits.store(0, Ordering::Relaxed);
self.misses.store(0, Ordering::Relaxed);
self.inserts.store(0, Ordering::Relaxed);
self.evictions.store(0, Ordering::Relaxed);
}
pub fn summary(&self) -> CacheMetricsSummary {
CacheMetricsSummary {
hits: self.hits(),
misses: self.misses(),
inserts: self.inserts(),
evictions: self.evictions(),
total_requests: self.total_requests(),
hit_ratio: self.hit_ratio(),
}
}
}
#[derive(Debug, Clone)]
pub struct CacheMetricsSummary {
pub hits: u64,
pub misses: u64,
pub inserts: u64,
pub evictions: u64,
pub total_requests: u64,
pub hit_ratio: f64,
}
impl std::fmt::Display for CacheMetricsSummary {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"Cache Metrics: {} hits, {} misses, {:.2}% hit ratio, {} inserts, {} evictions",
self.hits, self.misses, self.hit_ratio, self.inserts, self.evictions
)
}
}