use core::cmp::Ordering;
#[cfg(feature = "serde")]
use serde::{Deserialize, Serialize};
pub type ReplicaId = u64;
#[must_use]
pub fn new_replica_id() -> ReplicaId {
let mut bytes = [0u8; 8];
getrandom::fill(&mut bytes).expect("OS entropy unavailable");
u64::from_le_bytes(bytes)
}
#[derive(Copy, Clone, Eq, PartialEq, Hash, Debug)]
#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
pub struct OpId {
pub counter: u64,
pub replica: ReplicaId,
}
impl OpId {
#[inline]
#[must_use]
pub const fn new(counter: u64, replica: ReplicaId) -> Self {
Self { counter, replica }
}
}
impl Ord for OpId {
fn cmp(&self, other: &Self) -> Ordering {
self.counter
.cmp(&other.counter)
.then_with(|| self.replica.cmp(&other.replica))
}
}
impl PartialOrd for OpId {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn ordering_is_lex_counter_first() {
let a = OpId::new(1, 99);
let b = OpId::new(2, 1);
let c = OpId::new(2, 50);
assert!(a < b);
assert!(b < c);
assert!(a < c);
}
#[test]
fn equality_requires_both_components() {
assert_ne!(OpId::new(1, 1), OpId::new(1, 2));
assert_ne!(OpId::new(1, 1), OpId::new(2, 1));
assert_eq!(OpId::new(1, 1), OpId::new(1, 1));
}
}