use std::sync::atomic::{AtomicU64, Ordering};
use std::sync::Arc;
#[derive(Debug, Clone)]
pub struct LogicalClock {
counter: Arc<AtomicU64>,
}
impl LogicalClock {
pub fn new() -> Self {
Self {
counter: Arc::new(AtomicU64::new(0)),
}
}
pub fn tick(&self) -> u64 {
self.counter.fetch_add(1, Ordering::SeqCst) + 1
}
pub fn current(&self) -> u64 {
self.counter.load(Ordering::SeqCst)
}
pub fn merge(&self, other: u64) {
loop {
let current = self.counter.load(Ordering::SeqCst);
let new_val = current.max(other) + 1;
if self
.counter
.compare_exchange(current, new_val, Ordering::SeqCst, Ordering::SeqCst)
.is_ok()
{
break;
}
}
}
}
impl Default for LogicalClock {
fn default() -> Self {
Self::new()
}
}