1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52
use rustc_serialize::{Encodable, Decodable}; /// `LWWReg` is a simple CRDT that contains an arbitrary value /// along with an `Ord` that tracks causality. It is the responsibility /// of the user to guarantee that the source of the causal element /// is monotonic. Don't use timestamps unless you are comfortable /// with divergence. #[derive(Debug, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub struct LWWReg<T: PartialEq, A: Ord + Encodable + Decodable> { /// `value` is the opaque element contained within this CRDT pub value: T, /// `dot` should be a monotonic value associated with this value pub dot: A, } impl<T: PartialEq, A: Ord + Encodable + Decodable> LWWReg<T, A> { /// Combines two `LWWReg` instances according to the dot that /// tracks causality. Panics if the dot is identical but the /// contained element is different. If you would prefer divergence, /// use `merge_unsafe` below. /// /// #Panics /// `merge` will panic if passed a `LWWReg` instance with an /// identical dot but different element, indicating a breach /// of monotonicity. /// /// ``` /// use crdts::LWWReg; /// let mut l1 = LWWReg { value: 1, dot: 2 }; /// let l2 = LWWReg { value: 3, dot: 2 }; /// // panics /// // l1.merge(l2); /// ``` pub fn merge(&mut self, other: LWWReg<T, A>) { if other.dot > self.dot { self.value = other.value; self.dot = other.dot; } else if other.dot == self.dot && other.value != self.value { panic!("LWWReg::merge called on elements with an identical dot but different values."); } } /// Combines two `LWWReg` instances according to the dot that /// tracks causality. This allows replicas to diverge if the dot /// is identical but the element is not. pub unsafe fn merge_unsafe(&mut self, other: LWWReg<T, A>) { if other.dot > self.dot { self.value = other.value; self.dot = other.dot; } } }