use serde::{Deserialize, Serialize};
use std::cmp::Ordering;
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct LamportTimestamp {
pub counter: u64,
pub node_id: String,
}
impl LamportTimestamp {
pub fn new(node_id: &str) -> Self {
Self { counter: 0, node_id: node_id.to_string() }
}
pub fn with_counter(node_id: &str, counter: u64) -> Self {
Self { counter, node_id: node_id.to_string() }
}
pub fn increment(&mut self) -> Self {
self.counter += 1;
self.clone()
}
pub fn merge(&mut self, other: &Self) -> Self {
self.counter = self.counter.max(other.counter) + 1;
self.clone()
}
pub fn happens_before(&self, other: &Self) -> bool {
match self.counter.cmp(&other.counter) {
Ordering::Less => true,
Ordering::Greater => false,
Ordering::Equal => self.node_id < other.node_id,
}
}
pub fn is_concurrent_with(&self, other: &Self) -> bool {
self.counter == other.counter && self.node_id != other.node_id
}
}
impl PartialOrd for LamportTimestamp {
fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl Ord for LamportTimestamp {
fn cmp(&self, other: &Self) -> Ordering {
match self.counter.cmp(&other.counter) {
Ordering::Equal => self.node_id.cmp(&other.node_id),
other => other,
}
}
}