use crate::SeqNo;
use std::sync::{
atomic::{
AtomicU64,
Ordering::{AcqRel, Acquire, Release},
},
Arc,
};
#[derive(Clone, Default, Debug)]
pub struct SequenceNumberCounter(Arc<AtomicU64>);
impl SequenceNumberCounter {
#[must_use]
pub fn new(prev: SeqNo) -> Self {
Self(Arc::new(AtomicU64::new(prev)))
}
#[must_use]
pub fn get(&self) -> SeqNo {
self.0.load(Acquire)
}
#[must_use]
#[allow(clippy::missing_panics_doc, reason = "we should never run out of u64s")]
pub fn next(&self) -> SeqNo {
let seqno = self.0.fetch_add(1, AcqRel);
assert!(seqno < 0x8000_0000_0000_0000, "Ran out of sequence numbers");
seqno
}
pub fn set(&self, seqno: SeqNo) {
self.0.store(seqno, Release);
}
pub fn fetch_max(&self, seqno: SeqNo) {
self.0.fetch_max(seqno, AcqRel);
}
}
#[cfg(test)]
mod tests {
use test_log::test;
#[test]
fn not_max_seqno() {
let counter = super::SequenceNumberCounter::default();
counter.set(0x7FFF_FFFF_FFFF_FFFF);
let _ = counter.next();
}
#[test]
#[should_panic = "Ran out of sequence numbers"]
fn max_seqno() {
let counter = super::SequenceNumberCounter::default();
counter.set(0x8000_0000_0000_0000);
let _ = counter.next();
}
}