pub struct VClock<A: Ord> {
pub dots: BTreeMap<A, u64>,
}
Expand description
A VClock
is a standard vector clock.
It contains a set of “actors” and associated counters.
When a particular actor witnesses a mutation, their associated
counter in a VClock
is incremented. VClock
is typically used
as metadata for associated application data, rather than as the
container for application data. VClock
just tracks causality.
It can tell you if something causally descends something else,
or if different replicas are “concurrent” (were mutated in
isolation, and need to be resolved externally).
Fields§
§dots: BTreeMap<A, u64>
dots is the mapping from actors to their associated counters
Implementations§
source§impl<A: Ord> VClock<A>
impl<A: Ord> VClock<A>
sourcepub fn clone_without(&self, base_clock: &VClock<A>) -> VClock<A>where
A: Clone,
pub fn clone_without(&self, base_clock: &VClock<A>) -> VClock<A>where A: Clone,
Returns a clone of self but with information that is older than given clock is forgotten
sourcepub fn inc(&self, actor: A) -> Dot<A>where
A: Clone,
pub fn inc(&self, actor: A) -> Dot<A>where A: Clone,
Generate Op to increment an actor’s counter.
Examples
use crdts::{VClock, CmRDT};
let mut a = VClock::new();
// `a.inc()` does not mutate the vclock!
let op = a.inc("A");
assert_eq!(a, VClock::new());
// we must apply the op to the VClock to have
// its edit take effect.
a.apply(op.clone());
assert_eq!(a.get(&"A"), 1);
// Op's can be replicated to another node and
// applied to the local state there.
let mut other_node = VClock::new();
other_node.apply(op);
assert_eq!(other_node.get(&"A"), 1);
sourcepub fn get(&self, actor: &A) -> u64
pub fn get(&self, actor: &A) -> u64
Return the associated counter for this actor. All actors not in the vclock have an implied count of 0
sourcepub fn concurrent(&self, other: &VClock<A>) -> bool
pub fn concurrent(&self, other: &VClock<A>) -> bool
True if two vector clocks have diverged.
Examples
use crdts::{VClock, CmRDT};
let (mut a, mut b) = (VClock::new(), VClock::new());
a.apply(a.inc("A"));
b.apply(b.inc("B"));
assert!(a.concurrent(&b));
sourcepub fn intersection(left: &VClock<A>, right: &VClock<A>) -> VClock<A>where
A: Clone,
pub fn intersection(left: &VClock<A>, right: &VClock<A>) -> VClock<A>where A: Clone,
Returns the common elements (same actor and counter)
for two VClock
instances.
sourcepub fn glb(&mut self, other: &Self)
pub fn glb(&mut self, other: &Self)
Reduces this VClock to the greatest-lower-bound of the given VClock and itsef, as an example see the following code.
use crdts::{VClock, Dot, ResetRemove, CmRDT};
let mut c = VClock::new();
c.apply(Dot::new(23, 6));
c.apply(Dot::new(89, 14));
let c2 = c.clone();
c.glb(&c2); // this is a no-op since `glb { c, c } = c`
assert_eq!(c, c2);
c.apply(Dot::new(43, 1));
assert_eq!(c.get(&43), 1);
c.glb(&c2); // should remove the 43 => 1 entry
assert_eq!(c.get(&43), 0);
Trait Implementations§
source§impl<A: Ord + Clone + Debug> CmRDT for VClock<A>
impl<A: Ord + Clone + Debug> CmRDT for VClock<A>
source§fn apply(&mut self, dot: Self::Op)
fn apply(&mut self, dot: Self::Op)
Monotonically adds the given actor version to this VClock.
Examples
use crdts::{VClock, Dot, CmRDT};
let mut v = VClock::new();
v.apply(Dot::new("A", 2));
// now all dots applied to `v` from actor `A` where
// the counter is not bigger than 2 are nops.
v.apply(Dot::new("A", 0));
assert_eq!(v.get(&"A"), 2);
§type Op = Dot<A>
type Op = Dot<A>
§type Validation = DotRange<A>
type Validation = DotRange<A>
validate_op
.source§fn validate_op(&self, dot: &Self::Op) -> Result<(), Self::Validation>
fn validate_op(&self, dot: &Self::Op) -> Result<(), Self::Validation>
source§impl<A: Ord + Clone + Debug> CvRDT for VClock<A>
impl<A: Ord + Clone + Debug> CvRDT for VClock<A>
§type Validation = Infallible
type Validation = Infallible
validate_merge
.source§fn validate_merge(&self, _other: &Self) -> Result<(), Self::Validation>
fn validate_merge(&self, _other: &Self) -> Result<(), Self::Validation>
source§impl<'de, A> Deserialize<'de> for VClock<A>where
A: Deserialize<'de> + Ord,
impl<'de, A> Deserialize<'de> for VClock<A>where A: Deserialize<'de> + Ord,
source§fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where
__D: Deserializer<'de>,
fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>where __D: Deserializer<'de>,
source§impl<A: Ord> IntoIterator for VClock<A>
impl<A: Ord> IntoIterator for VClock<A>
source§impl<A: PartialEq + Ord> PartialEq<VClock<A>> for VClock<A>
impl<A: PartialEq + Ord> PartialEq<VClock<A>> for VClock<A>
source§impl<A: Ord> PartialOrd<VClock<A>> for VClock<A>
impl<A: Ord> PartialOrd<VClock<A>> for VClock<A>
1.0.0 · source§fn le(&self, other: &Rhs) -> bool
fn le(&self, other: &Rhs) -> bool
self
and other
) and is used by the <=
operator. Read moresource§impl<A: Ord> ResetRemove<A> for VClock<A>
impl<A: Ord> ResetRemove<A> for VClock<A>
source§fn reset_remove(&mut self, other: &Self)
fn reset_remove(&mut self, other: &Self)
Forget any actors that have smaller counts than the count in the given vclock