logicaffeine_data/crdt/
lww.rs1use super::Merge;
12use serde::{Deserialize, Serialize};
13
14#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
25pub struct LWWRegister<T> {
26 value: T,
27 timestamp: u64,
29}
30
31impl<T: Default> Default for LWWRegister<T> {
32 fn default() -> Self {
33 Self::new(T::default(), 0)
34 }
35}
36
37impl<T> LWWRegister<T> {
38 pub fn new(value: T, timestamp: u64) -> Self {
43 Self { value, timestamp }
44 }
45
46 pub fn set(&mut self, value: T, timestamp: u64) {
51 self.value = value;
52 self.timestamp = timestamp;
53 }
54
55 pub fn get(&self) -> &T {
57 &self.value
58 }
59
60 pub fn timestamp(&self) -> u64 {
62 self.timestamp
63 }
64}
65
66impl<T: Clone> Merge for LWWRegister<T> {
67 fn merge(&mut self, other: &Self) {
72 if other.timestamp >= self.timestamp {
73 self.value = other.value.clone();
74 self.timestamp = other.timestamp;
75 }
76 }
77}
78
79#[cfg(test)]
82mod tests {
83 use super::*;
84
85 #[test]
86 fn test_lww_new() {
87 let reg = LWWRegister::new("hello".to_string(), 100);
88 assert_eq!(reg.get(), "hello");
89 assert_eq!(reg.timestamp(), 100);
90 }
91
92 #[test]
93 fn test_lww_set() {
94 let mut reg = LWWRegister::new("hello".to_string(), 100);
95 reg.set("world".to_string(), 200);
96 assert_eq!(reg.get(), "world");
97 assert_eq!(reg.timestamp(), 200);
98 }
99
100 #[test]
101 fn test_lww_merge_newer_wins() {
102 let r1 = LWWRegister::new("old".to_string(), 100);
103 let r2 = LWWRegister::new("new".to_string(), 200);
104
105 let mut r1_copy = r1.clone();
106 r1_copy.merge(&r2);
107 assert_eq!(r1_copy.get(), "new");
108 }
109
110 #[test]
111 fn test_lww_merge_older_loses() {
112 let r1 = LWWRegister::new("old".to_string(), 100);
113 let r2 = LWWRegister::new("new".to_string(), 200);
114
115 let mut r2_copy = r2.clone();
116 r2_copy.merge(&r1);
117 assert_eq!(r2_copy.get(), "new");
119 }
120
121 #[test]
122 fn test_lww_merge_idempotent() {
123 let reg = LWWRegister::new("test".to_string(), 100);
124 let mut reg_copy = reg.clone();
125 reg_copy.merge(®);
126 assert_eq!(reg_copy.get(), "test");
127 }
128
129 #[test]
130 fn test_lww_with_int() {
131 let mut reg = LWWRegister::new(42i64, 100);
132 assert_eq!(*reg.get(), 42);
133 reg.set(100, 200);
134 assert_eq!(*reg.get(), 100);
135 }
136
137 #[test]
138 fn test_lww_with_bool() {
139 let mut reg = LWWRegister::new(false, 100);
140 assert_eq!(*reg.get(), false);
141 reg.set(true, 200);
142 assert_eq!(*reg.get(), true);
143 }
144}