use std::sync::Arc;
use std::sync::atomic::{AtomicU64, Ordering};
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct StoreMetrics {
pub hits: u64,
pub misses: u64,
pub inserts: u64,
pub updates: u64,
pub removes: u64,
pub evictions: u64,
}
#[derive(Debug, Default)]
pub struct StoreEvictionHook {
evictions: AtomicU64,
}
impl StoreEvictionHook {
pub fn record_eviction(&self) {
self.evictions.fetch_add(1, Ordering::Relaxed);
}
pub fn metrics(&self) -> StoreMetrics {
StoreMetrics {
evictions: self.evictions.load(Ordering::Relaxed),
..StoreMetrics::default()
}
}
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub struct StoreFull;
pub trait StoreCore<K, V> {
fn get(&self, key: &K) -> Option<Arc<V>>;
fn contains(&self, key: &K) -> bool;
fn len(&self) -> usize;
fn is_empty(&self) -> bool {
self.len() == 0
}
fn capacity(&self) -> usize;
fn metrics(&self) -> StoreMetrics {
StoreMetrics::default()
}
fn record_eviction(&self) {}
}
pub trait StoreMut<K, V>: StoreCore<K, V> {
fn try_insert(&mut self, key: K, value: Arc<V>) -> Result<Option<Arc<V>>, StoreFull>;
fn remove(&mut self, key: &K) -> Option<Arc<V>>;
fn clear(&mut self);
}
pub trait ConcurrentStore<K, V>: StoreCore<K, V> + Send + Sync {
fn try_insert(&self, key: K, value: Arc<V>) -> Result<Option<Arc<V>>, StoreFull>;
fn remove(&self, key: &K) -> Option<Arc<V>>;
fn clear(&self);
}
pub trait StoreFactory<K, V> {
type Store: StoreCore<K, V>;
fn create(capacity: usize) -> Self::Store;
}