use std::sync::atomic::{AtomicI64, Ordering};
use dashmap::DashMap;
#[derive(Debug, Default)]
pub struct OffsetStore {
inner: DashMap<String, AtomicI64>,
}
impl OffsetStore {
pub fn new() -> Self {
Self::default()
}
pub fn alloc(&self, topic: &str) -> i64 {
let cell = self
.inner
.entry(topic.to_string())
.or_insert_with(|| AtomicI64::new(1));
cell.fetch_add(1, Ordering::SeqCst)
}
pub fn head(&self, topic: &str) -> i64 {
self.inner
.get(topic)
.map(|c| c.load(Ordering::SeqCst) - 1)
.unwrap_or(0)
}
pub fn remove(&self, topic: &str) {
self.inner.remove(topic);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn alloc_monotonic() {
let s = OffsetStore::new();
assert_eq!(s.alloc("t"), 1);
assert_eq!(s.alloc("t"), 2);
assert_eq!(s.alloc("t"), 3);
assert_eq!(s.head("t"), 3);
}
#[test]
fn per_topic() {
let s = OffsetStore::new();
s.alloc("a");
s.alloc("a");
s.alloc("b");
assert_eq!(s.head("a"), 2);
assert_eq!(s.head("b"), 1);
}
}