Skip to main content

mdcs_core/
lattice.rs

1//! Join-semilattice trait - the mathematical foundation of CRDTs
2//!
3//! A join-semilattice (S, ⊔) satisfies:
4//!  - Commutativity: a ⊔ b = b ⊔ a
5//! - Associativity: (a ⊔ b) ⊔ c = a ⊔ (b ⊔ c)
6//! - Idempotence:  a ⊔ a = a
7//!
8//!  These properties guarantee convergence regardless of message order.
9
10use std::cmp::Ordering;
11
12/// The core CRDT trait.  All state-based CRDTs implement this.
13pub trait Lattice: Clone + PartialEq {
14    /// The bottom element (identity for join)
15    fn bottom() -> Self;
16
17    /// Join operation (least upper bound)
18    /// Must be commutative, associative, and idempotent
19    fn join(&self, other: &Self) -> Self;
20
21    /// Partial order derived from join:  a ≤ b iff a ⊔ b = b
22    fn partial_cmp_lattice(&self, other: &Self) -> Option<Ordering> {
23        let joined = self.join(other);
24        if &joined == self && &joined == other {
25            Some(Ordering::Equal)
26        } else if &joined == other {
27            Some(Ordering::Less)
28        } else if &joined == self {
29            Some(Ordering::Greater)
30        } else {
31            None // Concurrent/incomparable
32        }
33    }
34
35    /// Check if self ≤ other in the lattice order
36    fn leq(&self, other: &Self) -> bool {
37        matches!(
38            self.partial_cmp_lattice(other),
39            Some(Ordering::Less) | Some(Ordering::Equal)
40        )
41    }
42
43    /// Join-assign:  self = self ⊔ other
44    fn join_assign(&mut self, other: &Self) {
45        *self = self.join(other);
46    }
47}
48
49/// Marker trait for CRDTs that support delta operations
50pub trait DeltaCRDT: Lattice {
51    /// The delta state type (often the same as Self)
52    type Delta: Lattice;
53
54    /// Split off pending deltas, returning them and resetting internal delta buffer
55    fn split_delta(&mut self) -> Option<Self::Delta>;
56
57    /// Apply a delta to the state
58    fn apply_delta(&mut self, delta: &Self::Delta);
59}