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 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74
use std::error::Error; use std::hash::Hash; use crate::VClock; /// Common Actor type. Actors are unique identifier for every `thing` mutating a VClock. /// VClock based CRDT's will need to expose this Actor type to the user. pub trait Actor: Ord + Clone + Hash {} impl<A: Ord + Clone + Hash> Actor for A {} /// State based CRDT's replicate by transmitting the entire CRDT state. pub trait CvRDT { /// The validation error returned by `validate_merge`. type Validation: Error; /// Some CRDT's have stricter requirements on how they must be used. /// To avoid violating these requirements, CRDT's provide an interface /// to optionally validate merge compatibility before attempting to merge. /// /// An `Ok(())` response signals that the merge is safe to proceed. /// Otherwise a structured error is returned to help you determine what /// is wrong with the merge. fn validate_merge(&self, other: &Self) -> Result<(), Self::Validation>; /// Merge the given CRDT into the current CRDT. fn merge(&mut self, other: Self); } /// Operation based CRDT's replicate by transmitting each operation. pub trait CmRDT { /// Op defines a mutation to the CRDT. /// As long as Op's from one actor are replayed in exactly the same order they /// were generated by that actor, the CRDT will converge. In other words, we must /// have a total ordering on each actors operations, while requiring only a partial /// order over all ops. /// E.g. /// /// * Actor A produces ops A1, A2 /// * Actor B produces ops B1, B2 /// /// the only valid orderings are: /// * A1 < A2 < B1 < B2 /// * A1 < B1 < A2 < B2 /// * B1 < A1 < A2 < B2 /// * A1 < B1 < B2 < A2 /// * B1 < A1 < B2 < A2 /// * B1 < B2 < A1 < A2 /// /// Applying ops in any of the valid orders will converge to the same CRDT state /// /// Op's must be idempotent, meaning any Op may be applied more than once. type Op; /// The validation error returned by `validate_op`. type Validation: Error; /// Some CRDT's have stricter requirements on how they must be used. /// To avoid violating these requirements, CRDT's provide an interface /// to optionally validate op's before they are applied. /// /// An `Ok(())` response signals that this operation is safe to apply. /// Otherwise a structured error is returned to help you determine what /// is wrong with the operation fn validate_op(&self, op: &Self::Op) -> Result<(), Self::Validation>; /// Apply an Op to the CRDT fn apply(&mut self, op: Self::Op); } /// CRDT's are causal if they are built on top of vector clocks. pub trait ResetRemove<A: Ord> { /// Remove data that is strictly smaller than this clock fn reset_remove(&mut self, clock: &VClock<A>); }