safemesh_crdt/crdt/
lww_register.rs1use crate::{Crdt, MergeError, Mergeable, RecordId, WireError};
6
7#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
9pub struct LwwDot {
10 pub timestamp: u64,
11 pub replica: u64,
12}
13
14#[derive(Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
16pub struct LwwEntry<V: Ord> {
17 pub dot: LwwDot,
18 pub value: V,
19}
20
21#[derive(Clone, Debug, PartialEq, Eq)]
23pub struct LwwRegisterDelta<V: Ord> {
24 pub timestamp: u64,
25 pub replica: u64,
26 pub value: V,
27}
28
29#[derive(Clone, Debug, PartialEq, Eq)]
35pub struct LwwRegister<V: Ord> {
36 entry: Option<LwwEntry<V>>,
37}
38
39impl<V: Ord> LwwRegister<V> {
40 pub fn new() -> Self {
41 LwwRegister { entry: None }
42 }
43
44 pub fn set(&mut self, timestamp: u64, replica: u64, value: V) {
45 self.apply_entry(LwwEntry {
46 dot: LwwDot { timestamp, replica },
47 value,
48 });
49 }
50
51 pub fn entry(&self) -> Option<&LwwEntry<V>> {
52 self.entry.as_ref()
53 }
54
55 pub fn value(&self) -> Option<&V> {
56 self.entry.as_ref().map(|entry| &entry.value)
57 }
58
59 fn apply_entry(&mut self, entry: LwwEntry<V>) {
60 match &self.entry {
61 Some(current) if current >= &entry => {}
62 _ => self.entry = Some(entry),
63 }
64 }
65}
66
67impl<V: Ord> Default for LwwRegister<V> {
68 fn default() -> Self {
69 Self::new()
70 }
71}
72
73impl<V: Ord + Clone> LwwRegister<V> {
74 pub fn merge(&mut self, other: &Self) {
75 if let Some(entry) = other.entry.clone() {
76 self.apply_entry(entry);
77 }
78 }
79}
80
81impl<V: Ord + Clone> Mergeable for LwwRegister<V> {
82 fn merge(&mut self, other: &Self) -> Result<(), MergeError> {
83 LwwRegister::merge(self, other);
84 Ok(())
85 }
86}
87
88impl<V: Ord + Clone> Crdt for LwwRegister<V> {
89 type Delta = LwwRegisterDelta<V>;
90
91 fn validate_record(&self, id: RecordId, delta: &Self::Delta) -> Result<(), WireError> {
94 id.require_positive_sequence("LWW register")?;
95 if delta.replica != id.replica {
96 return Err(WireError::OwnershipViolation);
97 }
98 Ok(())
99 }
100
101 fn apply_delta(&mut self, delta: Self::Delta) {
102 self.set(delta.timestamp, delta.replica, delta.value);
103 }
104}