Skip to main content

logicaffeine_data/crdt/
latest.rs

1//! A last-writer register ordered by LAMPORT time, for the values of a shared map.
2//!
3//! Unlike [`super::LWWRegister`] (whose caller supplies a timestamp), a `LatestWrite` is stamped by the
4//! map that holds it with the number of events that map has observed — so a write that has SEEN another
5//! write always carries the larger stamp. Two concurrent writes can share a stamp; the larger value then
6//! wins. Ordering by `(stamp, value)` makes the merge a join over a total order: commutative,
7//! associative, idempotent, and independent of replica ids and wall clocks.
8
9use super::Merge;
10use serde::{Deserialize, Serialize};
11
12/// One value of a shared map, with the Lamport stamp of the write that produced it.
13#[derive(Debug, Clone, Default, PartialEq, Eq, Serialize, Deserialize)]
14pub struct LatestWrite<T> {
15    stamp: u64,
16    value: T,
17}
18
19impl<T> LatestWrite<T> {
20    /// A register holding `value`, written at Lamport time `stamp`.
21    pub fn new(value: T, stamp: u64) -> Self {
22        Self { stamp, value }
23    }
24
25    /// The current value.
26    pub fn get(&self) -> &T {
27        &self.value
28    }
29
30    /// The Lamport stamp of the write that produced the current value.
31    pub fn stamp(&self) -> u64 {
32        self.stamp
33    }
34
35    /// Overwrite with `value` at Lamport time `stamp`.
36    pub fn write(&mut self, value: T, stamp: u64) {
37        self.stamp = stamp;
38        self.value = value;
39    }
40}
41
42impl<T: Ord + Clone> Merge for LatestWrite<T> {
43    fn merge(&mut self, other: &Self) {
44        if (other.stamp, &other.value) > (self.stamp, &self.value) {
45            self.stamp = other.stamp;
46            self.value = other.value.clone();
47        }
48    }
49}
50
51#[cfg(test)]
52#[path = "../../../logicaffeine_tests/unit/logicaffeine_data/crdt/latest/tests.rs"]
53mod tests;