use std::collections::HashSet;
use fuel_core_types::fuel_compression::RegistryKey;
use crate::ports::EvictorDb;
#[derive(Debug)]
#[must_use = "Evictor must be committed to the database to persist state"]
pub(crate) struct CacheEvictor<T> {
keep_keys: HashSet<RegistryKey>,
next_key: RegistryKey,
_keyspace_marker: std::marker::PhantomData<T>,
}
impl<T> CacheEvictor<T> {
pub fn new_from_db<D>(
db: &mut D,
keep_keys: HashSet<RegistryKey>,
) -> anyhow::Result<Self>
where
D: EvictorDb<T>,
{
let latest_key = db.get_latest_assigned_key()?;
let next_key = if let Some(latest_key) = latest_key {
latest_key.next()
} else {
RegistryKey::ZERO
};
Ok(Self {
keep_keys,
next_key,
_keyspace_marker: std::marker::PhantomData,
})
}
pub fn next_key(&mut self) -> RegistryKey {
debug_assert!(self.keep_keys.len() < 2usize.pow(24).saturating_sub(2));
while self.keep_keys.contains(&self.next_key) {
self.next_key = self.next_key.next();
}
self.keep_keys.insert(self.next_key);
self.next_key
}
pub fn commit<D>(self, db: &mut D) -> anyhow::Result<()>
where
D: EvictorDb<T>,
{
db.set_latest_assigned_key(self.next_key)
}
}