use std::collections::BTreeMap;
use crate::mm2::OffsetSync;
#[derive(Default)]
pub struct OffsetSyncStore {
syncs: BTreeMap<(String, i32), BTreeMap<i64, i64>>,
}
impl OffsetSyncStore {
pub fn ingest(&mut self, s: OffsetSync) {
self.syncs
.entry((s.topic, s.partition))
.or_default()
.insert(s.upstream, s.downstream);
}
#[must_use]
pub fn translate(&self, topic: &str, partition: i32, committed: i64) -> Option<i64> {
let m = self.syncs.get(&(topic.to_string(), partition))?;
let (&up, &down) = m.range(..=committed).next_back()?;
Some(down + (committed - up))
}
}
#[cfg(test)]
mod tests {
use assert2::assert;
use super::*;
use crate::mm2::OffsetSync;
#[test]
fn translates_at_or_before_nearest_sync() {
let mut s = OffsetSyncStore::default();
s.ingest(OffsetSync {
topic: "orders".into(),
partition: 0,
upstream: 100,
downstream: 70,
});
s.ingest(OffsetSync {
topic: "orders".into(),
partition: 0,
upstream: 200,
downstream: 165,
});
assert!(s.translate("orders", 0, 250) == Some(215)); assert!(s.translate("orders", 0, 150) == Some(120)); assert!(s.translate("orders", 0, 50) == None); assert!(s.translate("orders", 9, 100) == None); }
}