cliffy_protocols/
vector_clock.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3use uuid::Uuid;
4
5#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
6pub struct VectorClock {
7 pub clocks: HashMap<Uuid, u64>,
8}
9
10impl Default for VectorClock {
11 fn default() -> Self {
12 Self::new()
13 }
14}
15
16impl VectorClock {
17 pub fn new() -> Self {
18 Self {
19 clocks: HashMap::new(),
20 }
21 }
22
23 pub fn tick(&mut self, node_id: Uuid) {
24 *self.clocks.entry(node_id).or_insert(0) += 1;
25 }
26
27 pub fn update(&mut self, other: &VectorClock) {
28 for (&node_id, ×tamp) in &other.clocks {
29 let current = self.clocks.entry(node_id).or_insert(0);
30 *current = (*current).max(timestamp);
31 }
32 }
33
34 pub fn happens_before(&self, other: &VectorClock) -> bool {
35 let mut has_smaller = false;
36
37 for (&node_id, &other_time) in &other.clocks {
39 let self_time = *self.clocks.get(&node_id).unwrap_or(&0);
40 if self_time > other_time {
41 return false;
42 }
43 if self_time < other_time {
44 has_smaller = true;
45 }
46 }
47
48 for (&node_id, &self_time) in &self.clocks {
50 if !other.clocks.contains_key(&node_id) {
51 if self_time > 0 {
53 return false;
54 }
55 }
56 }
57
58 has_smaller
59 }
60
61 pub fn concurrent(&self, other: &VectorClock) -> bool {
62 !self.happens_before(other) && !other.happens_before(self)
63 }
64
65 pub fn merge(&self, other: &VectorClock) -> VectorClock {
66 let mut result = self.clone();
67 result.update(other);
68 result
69 }
70}