Skip to main content

cliffy_protocols/
vector_clock.rs

1use 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, &timestamp) 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        // Check all entries in other
38        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        // Check entries in self that aren't in other
49        for (&node_id, &self_time) in &self.clocks {
50            if !other.clocks.contains_key(&node_id) {
51                // self has a non-zero entry that other doesn't have (implicitly 0)
52                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}