Struct vclock::VClock

source ·
pub struct VClock<K = usize, I = usize>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,
{ /* private fields */ }
Expand description

Vector clock with generic types.

Internally, it is just simple hash map containing integers, or at least something you can increase and compare.

The key can be anything which can be hashed and cloned.

The key and counter both need to support Clone as internally, especially when merging, some copies need to be made. The implementation tries to call .clone() as rarely as possible.

Sometimes the Rust compiler can infer the type of the counter, but it may not always be the case. Type aliases, such as VClock64, are here as syntaxic sugar.

§Examples

use vclock::VClock;

let mut c: VClock<&str>=VClock::default();
c.incr(&"a");
c.incr(&"a");
c.incr(&"a");
c.incr(&"a");
c.incr(&"b");
assert_eq!(Some(3), c.get(&"a"));
assert_eq!(Some(0), c.get(&"b"));
assert_eq!(None, c.get(&"c"));

Implementations§

source§

impl<K, I> VClock<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

source

pub fn new(key: K) -> VClock<K, I>

Initialize a new vector clock with only one contributor. It is useful to avoid the new() then incr() pattern, as it performs both operations at once, without copying anything.

§Examples
use vclock::VClock;

let c = VClock::<&str, u16>::new("foo"); // c is now foo:0
assert_eq!("{len: 1, weight: 1, max: {\"foo\": 0}}", format!("{}", c));
source

pub fn get(&self, key: &K) -> Option<I>

Returns the counter associated to a given key.

§Examples
use vclock::VClock;

let mut c = VClock::new("foo"); // c is now foo:0
c.incr(&"foo"); // c is now foo:1
c.incr(&"bar"); // c is now foo:1, bar:0
assert_eq!(1, c.get(&"foo").unwrap());
assert_eq!(0, c.get(&"bar").unwrap());
assert_eq!(None, c.get(&"unknown"));
source

pub fn len(&self) -> usize

Returns the number of elements in a VClock.

§Examples
use vclock::VClock;

let mut c = VClock::<&str, u8>::default();
assert_eq!(0, c.len());
c.incr(&"foo");
assert_eq!(1, c.len());
c.incr(&"foo");
assert_eq!(1, c.len());
c.incr(&"bar");
assert_eq!(2, c.len());
source

pub fn weight(&self) -> I

Returns the total of all values, plus the number of values.

This is mostly a debugging feature. You should not use this to compare clocks. If a < b then a.weight() < b.weight() but the reciprocity is not true. However it can be useful to have this information when auditing behavior.

§Examples
use vclock::VClock;

let mut c = VClock::<&str, u32>::default();
assert_eq!(0, c.weight());
c.incr(&"foo");
assert_eq!(1, c.weight());
c.incr(&"foo");
assert_eq!(2, c.weight());
c.incr(&"foo");
assert_eq!(3, c.weight());
c.incr(&"bar");
assert_eq!(4, c.weight());
c.incr(&"bar");
assert_eq!(5, c.weight());
source

pub fn max(&self) -> Option<(&K, I)>

Returns the max key,value pair.

This is mostly a debugging feature. You should not use this to compare clocks. If a < b then a.max() <= b.max() but the reciprocity is not true. However it can be useful to have this information when auditing behavior.

§Examples
use vclock::VClock;

let mut c = VClock::default();
assert_eq!(None, c.max());
c.incr(&"foo");
assert_eq!((&"foo", 0), c.max().unwrap());
c.incr(&"foo");
assert_eq!((&"foo", 1), c.max().unwrap());
c.incr(&"bar");
assert_eq!((&"foo", 1), c.max().unwrap());
source

pub fn incr(&mut self, key: &K)

Increment a vector clock in-place.

§Examples
use vclock::VClock;

let mut c = VClock::<&str, u64>::new("foo"); // c is now foo:0
c.incr(&"foo"); // c is now foo:1
c.incr(&"bar"); // c is now foo:1, bar:0
assert_eq!("{len: 2, weight: 3, max: {\"foo\": 1}}", format!("{}", c));
source

pub fn next(self, key: &K) -> VClock<K, I>

Increments a vector clock. This is pretty much the same as incr but it takes ownership on the vector clock.

§Examples
use vclock::VClock;
let c1 = VClock::<&str, u16>::new("a");
let c2 = c1.clone().next(&"a").next(&"b");
assert_eq!(1, c2.get(&"a").unwrap());
assert_eq!(0, c2.get(&"b").unwrap());
source

pub fn merge(&mut self, other: &VClock<K, I>)

Merge a key with another one, in-place, taking the max of all history points.

If there is a parentship between a and b, just take the greater of both.

§Examples
use vclock::VClock;

let mut c1 = VClock::<&str, u32>::new("a");
let c2 = VClock::<&str, u32>::new("b");
c1.merge(&c2);
assert_eq!(Some(0), c1.get(&"a"));
assert_eq!(Some(0), c1.get(&"b"));
source

pub fn combine(self, other: &VClock<K, I>) -> VClock<K, I>

Combine a key with another one, taking ownership.

If there is a parentship between a and b, just take the greater of both.

§Examples
use vclock::VClock;

let c1 = VClock::new("a");
let c2 = VClock::new("b").next(&"b");
let c3 = VClock::new("c");
let c4 = c1.combine(&c2).combine(&c3);
assert_eq!(0, c4.get(&"a").unwrap());
assert_eq!(1, c4.get(&"b").unwrap());
assert_eq!(0, c4.get(&"c").unwrap());

Trait Implementations§

source§

impl<K, I> Clone for VClock<K, I>
where K: Eq + Hash + Clone + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Clone,

source§

fn clone(&self) -> VClock<K, I>

Returns a copy of the value. Read more
1.0.0 · source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
source§

impl<K, I> Debug for VClock<K, I>
where K: Eq + Hash + Clone + Debug, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Debug,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
source§

impl<K, I> Default for VClock<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

source§

fn default() -> VClock<K, I>

Return a VClock with no history at all.

§Examples
use vclock::VClock;

let c1: VClock<&str, u64> = VClock::default();
assert_eq!(0, c1.len());
assert_eq!(0, c1.weight());
source§

impl<'de, K, I> Deserialize<'de> for VClock<K, I>
where K: Eq + Hash + Clone + Deserialize<'de>, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Deserialize<'de>,

source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
source§

impl<K, I> Display for VClock<K, I>
where K: Eq + Hash + Clone + Display, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Display,

source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Pretty print the vector clock, it does not dump all the data, only a few key values.

§Examples
use vclock::VClock;

let mut c = VClock::<&str, usize>::default();
assert_eq!("{len: 0, weight: 0}", format!("{}", c));
c.incr(&"a");
assert_eq!("{len: 1, weight: 1, max: {\"a\": 0}}", format!("{}", c));
c.incr(&"b");
c.incr(&"b");
assert_eq!("{len: 2, weight: 3, max: {\"b\": 1}}", format!("{}", c));
source§

impl<K, I> From<HashMap<K, I>> for VClock<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

source§

fn from(src: HashMap<K, I>) -> VClock<K, I>

Build a vector clock from a hash map containing u64 values.

§Examples
use vclock::VClock;
use std::collections::HashMap;

let mut m = HashMap::new();
m.insert("a", 3u64);
m.insert("b", 5u64);
let c = VClock::from(m);
assert_eq!(2, c.len());
assert_eq!(3, c.get(&"a").unwrap());
assert_eq!(5, c.get(&"b").unwrap());
source§

impl<K, I> From<VClock<K, I>> for HashMap<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

source§

fn from(src: VClock<K, I>) -> HashMap<K, I>

Build a vector clock from a hash map containing u64 values.

§Examples
use vclock::VClock;
use std::collections::HashMap;

let mut c = VClock::default();
c.incr(&"a");
c.incr(&"a");
c.incr(&"b");
let m = HashMap::from(c);
assert_eq!(2, m.len());
assert_eq!(Some(&1), m.get(&"a"));
assert_eq!(Some(&0), m.get(&"b"));
source§

impl<K, I> PartialEq for VClock<K, I>
where K: Eq + Hash + Clone + PartialEq, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + PartialEq,

source§

fn eq(&self, other: &VClock<K, I>) -> bool

This method tests for self and other values to be equal, and is used by ==.
1.0.0 · source§

fn ne(&self, other: &Rhs) -> bool

This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
source§

impl<K, I> PartialOrd for VClock<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

Vector clocks are partially ordered, and this is exactly what they are useful for. If the order is explicitly returned, it means one can fast-forward or fast-rewind from one point to the other in history. If not, that is, if None is returned, it means there is a conflict, and no way to directly go to one point from the other.

source§

fn partial_cmp(&self, other: &Self) -> Option<Ordering>

Compares the vector clock with another one. Note that really, this is a partial order, if both a<=b and a>=b return false, it means there is no direct parentship link between clocks.

§Examples
use vclock::VClock;
use std::cmp::Ordering;

// Two vector clocks holding same values are equal.
let mut c1 = VClock::<&str, u32>::new("a");
let mut c2 = VClock::<&str, u32>::new("a");
assert_eq!(Some(Ordering::Equal), c1.partial_cmp(&c2));
assert!(c1 <= c2);

// Two vector clocks with a direct parentship are ordered.
c2.incr(&"a");
assert_eq!(Some(Ordering::Less), c1.partial_cmp(&c2));
assert_eq!(Some(Ordering::Greater), c2.partial_cmp(&c1));
assert!(c1 < c2);
assert!(c2 > c1);

// Two vector clocks without a direct parentship are not ordered.
c1.incr(&"b");
assert_eq!(None, c1.partial_cmp(&c2));
assert_eq!(None, c2.partial_cmp(&c1));
assert!(!(c1 < c2));
assert!(!(c2 > c1));
1.0.0 · source§

fn lt(&self, other: &Rhs) -> bool

This method tests less than (for self and other) and is used by the < operator. Read more
1.0.0 · source§

fn le(&self, other: &Rhs) -> bool

This method tests less than or equal to (for self and other) and is used by the <= operator. Read more
1.0.0 · source§

fn gt(&self, other: &Rhs) -> bool

This method tests greater than (for self and other) and is used by the > operator. Read more
1.0.0 · source§

fn ge(&self, other: &Rhs) -> bool

This method tests greater than or equal to (for self and other) and is used by the >= operator. Read more
source§

impl<K, I> Serialize for VClock<K, I>
where K: Eq + Hash + Clone + Serialize, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Serialize,

source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
source§

impl<K, I> Eq for VClock<K, I>
where K: Eq + Hash + Clone + Eq, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone + Eq,

source§

impl<K, I> StructuralPartialEq for VClock<K, I>
where K: Eq + Hash + Clone, I: Add<I, Output = I> + AddAssign<I> + From<u8> + Ord + Default + Clone,

Auto Trait Implementations§

§

impl<K, I> Freeze for VClock<K, I>

§

impl<K, I> RefUnwindSafe for VClock<K, I>

§

impl<K, I> Send for VClock<K, I>
where I: Send, K: Send,

§

impl<K, I> Sync for VClock<K, I>
where I: Sync, K: Sync,

§

impl<K, I> Unpin for VClock<K, I>
where I: Unpin, K: Unpin,

§

impl<K, I> UnwindSafe for VClock<K, I>
where I: UnwindSafe, K: UnwindSafe,

Blanket Implementations§

source§

impl<T> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> ToOwned for T
where T: Clone,

§

type Owned = T

The resulting type after obtaining ownership.
source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
source§

impl<T> ToString for T
where T: Display + ?Sized,

source§

default fn to_string(&self) -> String

Converts the given value to a String. Read more
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,