git_bug/replica/entity/lamport/
mem.rs1use std::sync::atomic::{AtomicU64, Ordering};
14
15use super::Clock;
16
17#[derive(Debug)]
20pub struct MemClock {
21 counter: AtomicU64,
22}
23
24impl Clock for MemClock {
25 type IncrementError = std::convert::Infallible;
26 type WitnessError = std::convert::Infallible;
27
28 fn time(&self) -> super::Time {
29 super::Time(self.counter.load(Ordering::SeqCst))
30 }
31
32 fn increment(&mut self) -> Result<super::Time, Self::IncrementError> {
33 Ok(super::Time(self.counter.fetch_add(1, Ordering::SeqCst)))
34 }
35
36 fn witness(&mut self, time: super::Time) -> Result<(), Self::WitnessError> {
37 let current = self.time().0;
38 let other = time.0;
39
40 if other <= current {
41 return Ok(());
42 }
43
44 while self
46 .counter
47 .compare_exchange(current, other, Ordering::SeqCst, Ordering::SeqCst)
48 != Ok(current)
49 {
50 }
55
56 Ok(())
57 }
58}
59
60impl Default for MemClock {
61 fn default() -> Self {
62 Self::new()
63 }
64}
65
66impl MemClock {
67 #[must_use]
70 pub fn new() -> Self {
71 Self {
72 counter: AtomicU64::new(1),
73 }
74 }
75
76 #[must_use]
81 pub fn new_with_value(value: u64) -> Self {
82 if value == 0 {
83 todo!("Read invalid value from persisted clock.")
84 }
85
86 Self {
87 counter: AtomicU64::new(value),
88 }
89 }
90}
91
92#[cfg(test)]
93mod test {
94 use super::MemClock;
95 use crate::replica::entity::lamport::test::test_clock;
96
97 #[test]
98 fn test_mem_clock() {
99 let clock = MemClock::new();
100 test_clock(clock);
101 }
102}