boarddown_core/crdt/
vector.rs1use serde::{Deserialize, Serialize};
2use std::collections::HashMap;
3
4#[derive(Debug, Clone)]
5pub struct VectorClock {
6 clock: HashMap<u64, u64>,
7}
8
9impl VectorClock {
10 pub fn new() -> Self {
11 Self {
12 clock: HashMap::new(),
13 }
14 }
15
16 pub fn get(&self, client_id: u64) -> u64 {
17 self.clock.get(&client_id).copied().unwrap_or(0)
18 }
19
20 pub fn increment(&mut self, client_id: u64) -> u64 {
21 let next = self.get(client_id) + 1;
22 self.clock.insert(client_id, next);
23 next
24 }
25
26 pub fn merge(&self, other: &Self) -> Self {
27 let mut result = self.clone();
28 for (client_id, seq) in &other.clock {
29 let current = result.get(*client_id);
30 if seq > ¤t {
31 result.clock.insert(*client_id, *seq);
32 }
33 }
34 result
35 }
36
37 pub fn happens_before(&self, other: &Self) -> bool {
38 let all_keys: std::collections::HashSet<_> = self.clock.keys().chain(other.clock.keys()).collect();
39
40 let mut has_strictly_less = false;
41
42 for key in all_keys {
43 let self_val = self.get(*key);
44 let other_val = other.get(*key);
45
46 if self_val > other_val {
47 return false;
48 }
49 if self_val < other_val {
50 has_strictly_less = true;
51 }
52 }
53
54 has_strictly_less
55 }
56
57 pub fn is_concurrent(&self, other: &Self) -> bool {
58 !self.happens_before(other) && !other.happens_before(self)
59 }
60}
61
62impl Default for VectorClock {
63 fn default() -> Self {
64 Self::new()
65 }
66}
67
68impl Serialize for VectorClock {
69 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
70 where
71 S: serde::Serializer,
72 {
73 self.clock.serialize(serializer)
74 }
75}
76
77impl<'de> Deserialize<'de> for VectorClock {
78 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
79 where
80 D: serde::Deserializer<'de>,
81 {
82 let clock: HashMap<u64, u64> = HashMap::deserialize(deserializer)?;
83 Ok(Self { clock })
84 }
85}