use tessarikv_types::ValueKind;
#[derive(Debug, Clone)]
pub(crate) struct Retention {
boundaries: Vec<u64>,
}
#[derive(Debug)]
pub(crate) struct KeyRetention<'a> {
retention: &'a Retention,
last_stripe: Option<usize>,
}
impl Retention {
pub(crate) fn new(visible: u64, snapshots: &[u64]) -> Self {
let mut boundaries: Vec<u64> = snapshots
.iter()
.copied()
.filter(|snapshot| *snapshot < visible)
.collect();
boundaries.push(visible);
boundaries.sort_unstable();
boundaries.dedup();
Self { boundaries }
}
pub(crate) fn key(&self) -> KeyRetention<'_> {
KeyRetention {
retention: self,
last_stripe: None,
}
}
}
impl KeyRetention<'_> {
pub(crate) fn keeps(
&mut self,
sequence: u64,
kind: ValueKind,
deeper_holds_key: impl FnOnce() -> bool,
) -> bool {
let boundaries = &self.retention.boundaries;
let stripe = boundaries.partition_point(|boundary| *boundary < sequence);
if stripe == boundaries.len() {
return true;
}
if self.last_stripe == Some(stripe) {
return false;
}
self.last_stripe = Some(stripe);
!(kind == ValueKind::Delete && stripe == 0 && !deeper_holds_key())
}
}