use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Default)]
pub struct CacheStats {
hits: AtomicU64,
misses: AtomicU64,
inserts: AtomicU64,
evictions: AtomicU64,
expirations: AtomicU64,
}
impl CacheStats {
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 record_expiration(&self) {
self.expirations.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 expirations(&self) -> u64 {
self.expirations.load(Ordering::Relaxed)
}
pub fn hit_rate(&self) -> f64 {
let hits = self.hits();
let total = hits + self.misses();
if total == 0 {
0.0
} else {
hits as f64 / total as f64
}
}
pub fn total_requests(&self) -> u64 {
self.hits() + self.misses()
}
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);
self.expirations.store(0, Ordering::Relaxed);
}
pub fn snapshot(&self) -> CacheStatsSnapshot {
CacheStatsSnapshot {
hits: self.hits(),
misses: self.misses(),
inserts: self.inserts(),
evictions: self.evictions(),
expirations: self.expirations(),
}
}
}
#[derive(Debug, Clone)]
pub struct CacheStatsSnapshot {
pub hits: u64,
pub misses: u64,
pub inserts: u64,
pub evictions: u64,
pub expirations: u64,
}
impl CacheStatsSnapshot {
pub fn hit_rate(&self) -> f64 {
let total = self.hits + self.misses;
if total == 0 {
0.0
} else {
self.hits as f64 / total as f64
}
}
pub fn total_requests(&self) -> u64 {
self.hits + self.misses
}
}
impl std::fmt::Display for CacheStatsSnapshot {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(
f,
"CacheStats {{ hits: {}, misses: {}, hit_rate: {:.2}%, inserts: {}, evictions: {}, expirations: {} }}",
self.hits,
self.misses,
self.hit_rate() * 100.0,
self.inserts,
self.evictions,
self.expirations
)
}
}