use std::{hash::Hash, sync::Arc};
use equivalent::Equivalent;
use foyer_common::strict_assert;
use super::Indexer;
use crate::{eviction::Eviction, record::Record};
pub struct Sentry<I>
where
I: Indexer,
{
indexer: I,
}
impl<I> Default for Sentry<I>
where
I: Indexer,
{
fn default() -> Self {
Self { indexer: I::default() }
}
}
impl<I> Indexer for Sentry<I>
where
I: Indexer,
{
type Eviction = I::Eviction;
fn insert(&mut self, record: Arc<Record<Self::Eviction>>) -> Option<Arc<Record<Self::Eviction>>> {
strict_assert!(!record.is_in_indexer());
record.set_in_indexer(true);
self.indexer.insert(record).inspect(|old| {
strict_assert!(old.is_in_indexer());
old.set_in_indexer(false);
})
}
fn get<Q>(&self, hash: u64, key: &Q) -> Option<&Arc<Record<Self::Eviction>>>
where
Q: Hash + Equivalent<<Self::Eviction as Eviction>::Key> + ?Sized,
{
self.indexer.get(hash, key).inspect(|r| {
strict_assert!(r.is_in_indexer());
})
}
fn remove<Q>(&mut self, hash: u64, key: &Q) -> Option<Arc<Record<Self::Eviction>>>
where
Q: Hash + Equivalent<<Self::Eviction as Eviction>::Key> + ?Sized,
{
self.indexer.remove(hash, key).inspect(|r| {
strict_assert!(r.is_in_indexer());
r.set_in_indexer(false)
})
}
fn drain(&mut self) -> impl Iterator<Item = Arc<Record<Self::Eviction>>> {
self.indexer.drain().inspect(|r| {
strict_assert!(r.is_in_indexer());
r.set_in_indexer(false)
})
}
}