use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
use crate::tinylfu::{FrequencyTracker, TinyLFUTracker};
pub struct MeteredFrequencyTracker {
inner: Arc<dyn FrequencyTracker<u128>>,
touches: AtomicU64,
count_calls: AtomicU64,
}
impl MeteredFrequencyTracker {
pub fn new(inner: Arc<dyn FrequencyTracker<u128>>) -> Arc<Self> {
Arc::new(Self {
inner,
touches: AtomicU64::new(0),
count_calls: AtomicU64::new(0),
})
}
pub fn with_tinylfu(capacity: usize) -> Arc<Self> {
Self::new(Arc::new(TinyLFUTracker::new(capacity)))
}
pub fn touches(&self) -> u64 {
self.touches.load(Ordering::Relaxed)
}
pub fn count_calls(&self) -> u64 {
self.count_calls.load(Ordering::Relaxed)
}
pub fn reset(&self) {
self.touches.store(0, Ordering::Relaxed);
self.count_calls.store(0, Ordering::Relaxed);
}
}
impl FrequencyTracker<u128> for MeteredFrequencyTracker {
fn touch(&self, key: u128) {
self.touches.fetch_add(1, Ordering::Relaxed);
self.inner.touch(key);
}
fn count(&self, key: u128) -> u32 {
self.count_calls.fetch_add(1, Ordering::Relaxed);
self.inner.count(key)
}
}