# Task 03: LWWRegister ## Delivers `LWWRegister` in `tidal/src/replication/crdt/lww_register.rs`. HLC-timestamped value with `merge` taking the higher timestamp. Tie-breaking by `node_id`. Used for hard negatives (hide/mute/block) which require last-writer-wins semantics across regions. ## Complexity: S ## Dependencies - Task 01 (HlcTimestamp) ## Technical Design ```rust // tidal/src/replication/crdt/lww_register.rs /// Last-Writer-Wins register with HLC timestamp. /// /// Resolves concurrent writes by `HlcTimestamp` ordering: /// - Higher `wall_ns` wins /// - Same wall, higher `logical` wins /// - Same wall + logical, higher `node_id` wins (deterministic tie-break) /// /// The value `None` represents "not yet written." #[derive(Debug, Clone, PartialEq, serde::Serialize, serde::Deserialize)] pub struct LWWRegister { value: Option, timestamp: Option, } impl LWWRegister { pub fn empty() -> Self { Self { value: None, timestamp: None } } /// Write a new value with the given HLC timestamp. /// /// Only advances the register if `ts > self.timestamp`. pub fn write(&mut self, value: T, ts: HlcTimestamp) { if self.timestamp.map_or(true, |cur| ts > cur) { self.value = Some(value); self.timestamp = Some(ts); } } /// Merge another register into this one. /// /// The register with the higher timestamp wins. pub fn merge(&mut self, other: &LWWRegister) { if let Some(other_ts) = other.timestamp { if self.timestamp.map_or(true, |cur| other_ts > cur) { self.value = other.value.clone(); self.timestamp = other.timestamp; } } } /// Current value of the register. pub fn get(&self) -> Option<&T> { self.value.as_ref() } /// The HLC timestamp of the last write. pub fn timestamp(&self) -> Option { self.timestamp } } impl Default for LWWRegister { fn default() -> Self { Self::empty() } } ``` ## Acceptance Criteria - [ ] `LWWRegister::write(value, ts)` accepts writes with higher timestamps only - [ ] `LWWRegister::merge` takes the value with the higher HLC timestamp - [ ] Concurrent writes at the same wall time resolve by `logical` then `node_id` - [ ] `LWWRegister::merge` is commutative: `merge(A, B) == merge(B, A)` (property test) - [ ] `LWWRegister::merge` is associative and idempotent (property tests) - [ ] `T: Clone + PartialEq` bound is sufficient; no `Ord` required - [ ] Used for `HardNegAction` in Phase 8.4; `T` will be `HardNegAction` enum - [ ] `cargo clippy -D warnings` and `cargo fmt` pass