datacake_crdt/lib.rs
1//! # Datacake CRDT
2//!
3//! An implementation of Riak's ORSWOT CRDT which is a CRDT which allows for removal of old
4//! tombstones once a new event has been observed.
5//!
6//! The set is built upon the second supported structure `HLCTimestamp` which is a Hybrid Logical Clock
7//! which guarantees the timestamp will always be unique and monotonic (providing it's used correctly.)
8//!
9//! ### Basic Example
10//! ```rust
11//! use std::time::Duration;
12//! use datacake_crdt::{OrSWotSet, HLCTimestamp};
13//!
14//! let mut node_a = HLCTimestamp::now(0, 0);
15//!
16//! // Simulating a node begin slightly ahead.
17//! let mut node_b = HLCTimestamp::new(node_a.datacake_timestamp() + Duration::from_secs(5), 0, 1);
18//!
19//! // We only have one effective source here.
20//! let mut node_a_set = OrSWotSet::<1>::default();
21//! let mut node_b_set = OrSWotSet::<1>::default();
22//!
23//! // Insert a new key with a new timestamp in set A.
24//! node_a_set.insert(1, node_a.send().unwrap());
25//!
26//! // Insert a new entry in set B.
27//! node_b_set.insert(2, node_b.send().unwrap());
28//!
29//! // Let some time pass for demonstration purposes.
30//! std::thread::sleep(Duration::from_millis(500));
31//!
32//! // Set A has key `1` removed.
33//! node_a_set.delete(1, node_a.send().unwrap());
34//!
35//! // Merging set B with set A and vice versa.
36//! // Our sets are now aligned without conflicts.
37//! node_b_set.merge(node_a_set.clone());
38//! node_a_set.merge(node_b_set.clone());
39//!
40//! // Set A and B should both see that key `1` has been deleted.
41//! assert!(node_a_set.get(&1).is_none(), "Key should be correctly removed.");
42//! assert!(node_b_set.get(&1).is_none(), "Key should be correctly removed.");
43//! ```
44//!
45//! ### Inspirations
46//! - [CRDTs for Mortals by James Long](https://www.youtube.com/watch?v=iEFcmfmdh2w)
47//! - [Big(ger) Sets: Making CRDT Sets Scale in Riak by Russell Brown](https://www.youtube.com/watch?v=f20882ZSdkU)
48//! - ["CRDTs Illustrated" by Arnout Engelen](https://www.youtube.com/watch?v=9xFfOhasiOE)
49
50mod orswot;
51mod timestamp;
52
53#[cfg(feature = "rkyv-support")]
54pub use orswot::BadState;
55pub use orswot::{Key, OrSWotSet, StateChanges};
56pub use timestamp::{
57 get_datacake_timestamp,
58 get_unix_timestamp_ms,
59 HLCTimestamp,
60 InvalidFormat,
61 TimestampError,
62 DATACAKE_EPOCH,
63 TIMESTAMP_MAX,
64};