diff --git a/radicle-crdt/src/change.rs b/radicle-crdt/src/change.rs index 17035f81..1605f6be 100644 --- a/radicle-crdt/src/change.rs +++ b/radicle-crdt/src/change.rs @@ -100,13 +100,14 @@ impl Actor { /// Create a new change. pub fn change(&mut self, action: A) -> Change { let author = *self.signer.public_key(); - let clock = self.clock.tick(); + let clock = self.clock; let change = Change { action, author, clock, }; self.changes.insert((self.clock, author), change.clone()); + self.clock.tick(); change } diff --git a/radicle-crdt/src/clock.rs b/radicle-crdt/src/clock.rs index 62f57376..6202bdea 100644 --- a/radicle-crdt/src/clock.rs +++ b/radicle-crdt/src/clock.rs @@ -29,6 +29,11 @@ impl Lamport { self.counter.merge(other.counter); self.tick() } + + /// Reset clock to default state. + pub fn reset(&mut self) { + self.counter = Max::default(); + } } impl From for Lamport { diff --git a/radicle-crdt/src/lwwmap.rs b/radicle-crdt/src/lwwmap.rs index b7c25031..cecc6ded 100644 --- a/radicle-crdt/src/lwwmap.rs +++ b/radicle-crdt/src/lwwmap.rs @@ -2,11 +2,14 @@ use std::collections::btree_map::Entry; use std::collections::BTreeMap; use crate::lwwreg::LWWReg; -use crate::Semilattice; +use crate::{clock, Semilattice}; /// Last-Write-Wins Map. +/// +/// In case a value is added and removed under a key at the same time, +/// the "add" takes precedence over the "remove". #[derive(Debug, Clone, PartialEq, Eq)] -pub struct LWWMap { +pub struct LWWMap { inner: BTreeMap, C>>, } diff --git a/radicle-crdt/src/lwwset.rs b/radicle-crdt/src/lwwset.rs index fc1d5b8a..690a83de 100644 --- a/radicle-crdt/src/lwwset.rs +++ b/radicle-crdt/src/lwwset.rs @@ -2,6 +2,9 @@ use crate::clock; use crate::{lwwmap::LWWMap, Semilattice}; /// Last-Write-Wins Set. +/// +/// In case the same value is added and removed at the same time, +/// the "add" takes precedence over the "remove". #[derive(Debug, Clone, PartialEq, Eq)] pub struct LWWSet { inner: LWWMap, @@ -129,6 +132,14 @@ mod tests { set.remove('a', 2); assert!(!set.contains(&'a')); assert!(!set.iter().any(|c| *c == 'a')); + + set.insert('b', 3); + set.remove('b', 3); + assert!(set.contains(&'b')); // Insert precedence. + + set.remove('c', 3); + set.insert('c', 3); + assert!(set.contains(&'c')); // Insert precedence. } #[test]