const NAMESPACES: usize = 64;
const NAMESPACE_BYTES: usize = 256;
#[derive(Default)]
pub(super) struct ObservedWatermarks {
watermarks: Vec<(Box<[u8]>, u64)>,
}
impl ObservedWatermarks {
pub(super) fn covers(&mut self, namespace: &[u8], value: u64) -> bool {
let Some(position) = self
.watermarks
.iter()
.position(|(known, _)| **known == *namespace)
else {
return false;
};
let entry = self.watermarks.remove(position);
let covers = entry.1 >= value;
self.watermarks.push(entry);
covers
}
pub(super) fn record(&mut self, namespace: &[u8], watermark: u64) {
if namespace.len() > NAMESPACE_BYTES {
return;
}
if let Some(position) = self
.watermarks
.iter()
.position(|(known, _)| **known == *namespace)
{
let mut entry = self.watermarks.remove(position);
entry.1 = entry.1.max(watermark);
self.watermarks.push(entry);
return;
}
if self.watermarks.len() == NAMESPACES {
self.watermarks.remove(0);
}
self.watermarks.push((namespace.into(), watermark));
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn a_recorded_watermark_covers_only_values_at_or_below_it() {
let mut observed = ObservedWatermarks::default();
assert!(!observed.covers(b"documents", 0));
observed.record(b"documents", 10);
assert!(observed.covers(b"documents", 10));
assert!(observed.covers(b"documents", 0));
assert!(!observed.covers(b"documents", 11));
assert!(!observed.covers(b"vertices", 1));
observed.record(b"documents", 4);
assert!(observed.covers(b"documents", 10));
observed.record(b"documents", 12);
assert!(observed.covers(b"documents", 12));
}
#[test]
fn the_least_recently_observed_namespace_makes_room() {
let mut observed = ObservedWatermarks::default();
for namespace in 0..NAMESPACES as u64 {
observed.record(&namespace.to_be_bytes(), namespace);
}
assert!(observed.covers(&0_u64.to_be_bytes(), 0));
observed.record(b"another", 1);
assert!(observed.covers(&0_u64.to_be_bytes(), 0));
assert!(!observed.covers(&1_u64.to_be_bytes(), 0));
assert!(observed.covers(b"another", 1));
assert_eq!(observed.watermarks.len(), NAMESPACES);
observed.record(&[7; NAMESPACE_BYTES + 1], 3);
assert!(!observed.covers(&[7; NAMESPACE_BYTES + 1], 3));
}
}