use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug)]
pub struct ApqMetrics {
hits: AtomicU64,
misses: AtomicU64,
stored: AtomicU64,
errors: AtomicU64,
}
impl ApqMetrics {
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_store(&self) {
self.stored.fetch_add(1, Ordering::Relaxed);
}
pub fn record_error(&self) {
self.errors.fetch_add(1, Ordering::Relaxed);
}
#[must_use]
pub fn get_hits(&self) -> u64 {
self.hits.load(Ordering::Relaxed)
}
#[must_use]
pub fn get_misses(&self) -> u64 {
self.misses.load(Ordering::Relaxed)
}
#[must_use]
pub fn get_stored(&self) -> u64 {
self.stored.load(Ordering::Relaxed)
}
#[must_use]
pub fn get_errors(&self) -> u64 {
self.errors.load(Ordering::Relaxed)
}
#[must_use]
pub fn hit_rate(&self) -> f64 {
let hits = self.hits.load(Ordering::Relaxed);
let misses = self.misses.load(Ordering::Relaxed);
if hits + misses == 0 {
0.0
} else {
#[allow(clippy::cast_precision_loss)]
{
hits as f64 / (hits + misses) as f64
}
}
}
#[must_use]
pub fn as_json(&self) -> serde_json::Value {
serde_json::json!({
"hits": self.get_hits(),
"misses": self.get_misses(),
"stored": self.get_stored(),
"errors": self.get_errors(),
"hit_rate": self.hit_rate(),
})
}
pub fn reset(&self) {
self.hits.store(0, Ordering::Relaxed);
self.misses.store(0, Ordering::Relaxed);
self.stored.store(0, Ordering::Relaxed);
self.errors.store(0, Ordering::Relaxed);
}
}
impl Default for ApqMetrics {
fn default() -> Self {
Self {
hits: AtomicU64::new(0),
misses: AtomicU64::new(0),
stored: AtomicU64::new(0),
errors: AtomicU64::new(0),
}
}
}