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;