Skip to main content

atomr_distributed_data/
register.rs

1//! Last-writer-wins register. akka.net: `LWWRegister`.
2
3use serde::{Deserialize, Serialize};
4
5use crate::traits::CrdtMerge;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
8pub struct LwwRegister<T: Clone> {
9    value: T,
10    timestamp: u64,
11    node: String,
12}
13
14impl<T: Clone> LwwRegister<T> {
15    pub fn new(node: impl Into<String>, value: T, timestamp: u64) -> Self {
16        Self { value, timestamp, node: node.into() }
17    }
18
19    pub fn value(&self) -> &T {
20        &self.value
21    }
22
23    pub fn timestamp(&self) -> u64 {
24        self.timestamp
25    }
26
27    pub fn set(&mut self, value: T, timestamp: u64, node: impl Into<String>) {
28        if timestamp > self.timestamp {
29            self.value = value;
30            self.timestamp = timestamp;
31            self.node = node.into();
32        }
33    }
34}
35
36impl<T: Clone> CrdtMerge for LwwRegister<T> {
37    fn merge(&mut self, other: &Self) {
38        if other.timestamp > self.timestamp || (other.timestamp == self.timestamp && other.node > self.node) {
39            *self = other.clone();
40        }
41    }
42}
43
44#[cfg(test)]
45mod tests {
46    use super::*;
47
48    #[test]
49    fn later_wins() {
50        let mut a = LwwRegister::new("n1", "alpha", 1);
51        let b = LwwRegister::new("n2", "beta", 2);
52        a.merge(&b);
53        assert_eq!(*a.value(), "beta");
54    }
55}