oxihuman_core/
clock_version_vector.rs1#![allow(dead_code)]
4
5use std::collections::HashMap;
6
7pub struct ClockVersionVector {
9 pub clocks: HashMap<String, u64>,
10}
11
12impl ClockVersionVector {
13 pub fn new() -> Self {
14 ClockVersionVector {
15 clocks: HashMap::new(),
16 }
17 }
18}
19
20impl Default for ClockVersionVector {
21 fn default() -> Self {
22 Self::new()
23 }
24}
25
26pub fn new_clock_version_vector() -> ClockVersionVector {
27 ClockVersionVector::new()
28}
29
30pub fn cvv_increment(v: &mut ClockVersionVector, node: &str) {
31 let counter = v.clocks.entry(node.to_string()).or_insert(0);
32 *counter += 1;
33}
34
35pub fn cvv_get(v: &ClockVersionVector, node: &str) -> u64 {
36 *v.clocks.get(node).unwrap_or(&0)
37}
38
39pub fn cvv_merge(a: &ClockVersionVector, b: &ClockVersionVector) -> ClockVersionVector {
40 let mut merged = ClockVersionVector::new();
41 for (k, &va) in &a.clocks {
42 let vb = *b.clocks.get(k).unwrap_or(&0);
43 merged.clocks.insert(k.clone(), va.max(vb));
44 }
45 for (k, &vb) in &b.clocks {
46 if !merged.clocks.contains_key(k) {
47 merged.clocks.insert(k.clone(), vb);
48 }
49 }
50 merged
51}
52
53pub fn cvv_dominates(a: &ClockVersionVector, b: &ClockVersionVector) -> bool {
55 for (k, &vb) in &b.clocks {
56 if cvv_get(a, k) < vb {
57 return false;
58 }
59 }
60 true
61}
62
63pub fn cvv_concurrent(a: &ClockVersionVector, b: &ClockVersionVector) -> bool {
64 !cvv_dominates(a, b) && !cvv_dominates(b, a)
65}
66
67pub fn cvv_node_count(v: &ClockVersionVector) -> usize {
68 v.clocks.len()
69}
70
71#[cfg(test)]
72mod tests {
73 use super::*;
74
75 #[test]
76 fn test_new_empty() {
77 let v = new_clock_version_vector();
79 assert_eq!(cvv_node_count(&v), 0);
80 }
81
82 #[test]
83 fn test_increment_and_get() {
84 let mut v = new_clock_version_vector();
86 cvv_increment(&mut v, "A");
87 cvv_increment(&mut v, "A");
88 assert_eq!(cvv_get(&v, "A"), 2);
89 }
90
91 #[test]
92 fn test_get_unknown() {
93 let v = new_clock_version_vector();
95 assert_eq!(cvv_get(&v, "X"), 0);
96 }
97
98 #[test]
99 fn test_merge() {
100 let mut a = new_clock_version_vector();
102 let mut b = new_clock_version_vector();
103 cvv_increment(&mut a, "A");
104 cvv_increment(&mut a, "A");
105 cvv_increment(&mut b, "A");
106 cvv_increment(&mut b, "B");
107 let m = cvv_merge(&a, &b);
108 assert_eq!(cvv_get(&m, "A"), 2);
109 assert_eq!(cvv_get(&m, "B"), 1);
110 }
111
112 #[test]
113 fn test_dominates() {
114 let mut a = new_clock_version_vector();
116 let mut b = new_clock_version_vector();
117 cvv_increment(&mut a, "A");
118 cvv_increment(&mut a, "A");
119 cvv_increment(&mut b, "A");
120 assert!(cvv_dominates(&a, &b));
121 assert!(!cvv_dominates(&b, &a));
122 }
123
124 #[test]
125 fn test_concurrent() {
126 let mut a = new_clock_version_vector();
128 let mut b = new_clock_version_vector();
129 cvv_increment(&mut a, "A");
130 cvv_increment(&mut b, "B");
131 assert!(cvv_concurrent(&a, &b));
132 }
133
134 #[test]
135 fn test_node_count() {
136 let mut v = new_clock_version_vector();
138 cvv_increment(&mut v, "X");
139 cvv_increment(&mut v, "Y");
140 cvv_increment(&mut v, "X");
141 assert_eq!(cvv_node_count(&v), 2);
142 }
143
144 #[test]
145 fn test_default() {
146 let v = ClockVersionVector::default();
148 assert_eq!(v.clocks.len(), 0);
149 }
150}