Struct confitul::CKey

source ·
pub struct CKey { /* private fields */ }
Expand description

CKey implements a consistent hask key. Theory here: https://en.wikipedia.org/wiki/Consistent_hashing

Examples

use confitul::CKey;

let k1 = CKey::new_rand();
let k2 = k1.next();
print!("k1:{:?} k2:{:?}\n", k1, k2);

Implementations§

Make a digest from data and returns a new key from it. Typical usage is to create a a CKey from a string or an object content.

Examples
use confitul::CKey;

let k = CKey::new_digest("/a/unique/path");
assert_eq!("3b818742b0f27cfc10f4de1e5ba5594c975d580c412a31011ad58d36a2b17cdc", format!("{:?}",k));

Generate a random key. This can be time consuming as it is using the OS random generation, which is better from a cryptographic point of view, but possibly slower than a standard prng.

Examples
use confitul::CKey;

let k = CKey::new_rand();
print!("k: {:?}", k);
Examples found in repository?
src/node.rs (line 19)
18
19
20
    pub fn new_rand() -> Node {
        Self::new_with_key(CKey::new_rand())
    }
More examples
Hide additional examples
src/ep.rs (line 33)
32
33
34
35
36
37
38
39
    pub fn new_local() -> EP {
        let key = CKey::new_rand();
        let url = format!("{}:{}", LOCAL, key);
        EP {
            key,
            url: Url::parse(url.as_str()).unwrap(),
        }
    }

Generate a key with the value 0.

Examples
use confitul::CKey;

let k = CKey::new_zero();
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", format!("{:?}", k));

Generate a key with the value 1, the smallest key possible just after zero.

Examples
use confitul::CKey;

let k = CKey::new_unit();
assert_eq!("0000000000000000000000000000000000000000000000000000000000000001", format!("{:?}", k));
Examples found in repository?
src/ckey.rs (line 216)
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
    pub fn next(self) -> CKey {
        self + Self::new_unit()
    }

    /// Return current key minus one.
    ///
    /// # Examples
    /// ```
    /// use confitul::CKey;
    ///
    /// let k = CKey::new_zero();
    /// assert_eq!(CKey::new_last(), k.prev());
    /// ```
    pub fn prev(self) -> CKey {
        self - Self::new_unit()
    }

Generate a key with the last, highest possible value.

Examples
use confitul::CKey;

let k = CKey::new_last();
assert_eq!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", format!("{:?}", k));

Generate a key which is exactly in the middle of the ring.

Examples
use confitul::CKey;

let k = CKey::new_half();
assert_eq!("8000000000000000000000000000000000000000000000000000000000000000", format!("{:?}", k));

Returns true if self is inside lower and upper. Lower limit is excluded, upper is included. This is typically used in a ring to know if a given key is handled by a node. You would ask if key is inside previous node (lower) and this node (upper) and if true -> yes, this is the right node to handle it.

Examples
use confitul::CKey;

let k1 = CKey::from(0.1);
let k2 = CKey::from(0.3);
let k3 = CKey::from(0.9);
assert!(k2.inside(k1, k3));
Examples found in repository?
src/ckey.rs (line 294)
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
    pub fn sort(v: &mut Vec<CKey>, start: CKey) {
        v.sort_by(|a, b| {
            // So here, the logic is to consider that everything is
            // "normalized" so that the start is "key 0" and then we
            // look at the order *after* this starting point.
            //
            // In practice, self is lower than other if self is between
            // start and other.
            //
            // And self is greater than other if other is between start
            // and self.
            if *a == *b {
                Ordering::Equal
            } else if a.inside(start, *b) {
                // Other key is after us, considering the "zero" is start.
                Ordering::Less
            } else {
                Ordering::Greater
            }
        });
    }

Increment current key by one.

Examples
use confitul::CKey;

let mut k = CKey::new_zero();
k.incr();
assert_eq!(CKey::new_unit(), k);

Decrement current key by one.

Examples
use confitul::CKey;

let mut k = CKey::new_zero();
k.decr();
assert_eq!(CKey::new_last(), k);

Return current key plus one.

Examples
use confitul::CKey;

let k = CKey::new_zero();
assert_eq!(CKey::new_unit(), k.next());
Examples found in repository?
src/ckey.rs (line 189)
188
189
190
    pub fn incr(&mut self) {
        *self = self.next();
    }

Return current key minus one.

Examples
use confitul::CKey;

let k = CKey::new_zero();
assert_eq!(CKey::new_last(), k.prev());
Examples found in repository?
src/ckey.rs (line 203)
202
203
204
    pub fn decr(&mut self) {
        *self = self.prev();
    }

Try to convert from a &str.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff").unwrap();
assert_eq!("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff", format!("{:?}", k));
Examples found in repository?
src/ckey.rs (line 418)
417
418
419
    fn try_from(value: &str) -> Result<CKey, Self::Error> {
        Self::parse(value)
    }
More examples
Hide additional examples
src/ep.rs (line 51)
50
51
52
53
54
55
56
57
    pub fn parse(key: &str, url: &str) -> Result<EP, Box<dyn std::error::Error>> {
        let parsed_key = CKey::parse(key)?;
        let parsed_url = Url::parse(url)?;
        Ok(EP {
            key: parsed_key,
            url: parsed_url,
        })
    }

Sort an array of keys, using a start reference.

There is no way to sort keys in an absolute way, since they are virtually on a circle and wrapping, everything depends on where you start from.

This is why there’s a start parameter.

Examples
use confitul::CKey;

let start = CKey::from(0.7);
let k1 = CKey::from(0.2);
let k2 = CKey::from(0.4);
let k3 = CKey::from(0.3);
let k4 = CKey::from(0.9);
let mut sorted = vec![k1, k2, k3, k4];
CKey::sort(&mut sorted, start);
assert_eq!(4, sorted.len());
assert_eq!("0.900000000", format!("{}", sorted[0]));
assert_eq!("0.200000000", format!("{}", sorted[1]));
assert_eq!("0.300000000", format!("{}", sorted[2]));
assert_eq!("0.400000000", format!("{}", sorted[3]));

Trait Implementations§

Add another key.

If the result is outside key space, will loop back, as in wrapping mode. So the result is always within key space.

Examples
use confitul::CKey;

let k1 = CKey::from(0.6f64);
let k2 = CKey::from(0.8f64);
let k_sum = k1 + k2;
assert_eq!("0.400000000", String::from(k_sum));
The resulting type after applying the + operator.

Add an f64.

The value is first converted to a key, considering key space goes from 0 to 1.

Examples
use confitul::CKey;

let k = CKey::from(0.3f64);
assert_eq!("0.700000000", String::from(k + 0.4f64));
The resulting type after applying the + operator.

Add a u32.

The value is first converted to a key, considering key space goes from 0 to 2^32.

Examples
use confitul::CKey;

let k = CKey::from(0.1f64);
assert_eq!("0.100232831", String::from(k + 1_000_000u32))
The resulting type after applying the + operator.

Add a u64.

The value is first converted to a key, considering key space goes from 0 to 2^64.

Examples
use confitul::CKey;

let k = CKey::from(0.1f64);
assert_eq!("0.100542101", String::from(k + 10_000_000_000_000_000u64))
The resulting type after applying the + operator.
Returns a copy of the value. Read more
Performs copy-assignment from source. Read more

Debug-print a key.

The representation we use is an hex dump, the way you would write down the 2^256 integer corresponding to the key.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff").unwrap();
assert_eq!("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff", format!("{:?}", k));
Returns the “default value” for a type. Read more
Deserialize this value from the given Serde deserializer. Read more

Pretty-print a key.

The representation we use is a 9-digits decimal float number, 11 chars in total, including a leading “0.”.

The reason for this is -> 1 billion keys is enough to tell them apart, there CAN be collisions, but it should remain rare. To check for equality, use == operator, do not compare string reprs.

At the same time, decimals between 0 and 1 are easier to reason about when debugging, much more than 64 chars hexa dumps.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff").unwrap();
assert_eq!("0.071111111", format!("{}", k));

Try to convert to a String.

The representation it gives is the fmt::Display impl, which gives a short (not complete/unique) yet readable representation of the key, as a floating point from 0 to 1.

Examples
use confitul::CKey;

let k = CKey::from(0.6 as f64);
assert_eq!("0.600000000", String::from(k));

Convert to an f64, considering the ring goes from 0 to 1.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("123456ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
assert_eq!("0.071111143", format!("{:0.9}", f64::from(k)));

Convert to a u32, considering the ring goes from 0 to 2^32.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("123456ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
assert_eq!(305420031, u32::from(k));

Convert to a u64, considering the ring goes from 0 to 2^64.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::parse("123456ffffffffffffffffffffffffffffffffffffffffffffffffffffffffff").unwrap();
assert_eq!(1311769048983273471, u64::from(k));

Convert from an f64, considering the ring goes from 0 to 1.

Examples
use confitul::CKey;

let k = CKey::from(0.5f64);
assert_eq!("0.500000000", format!("{}", k));

Convert from a u32, considering the ring goes from 0 to 2^32.

Examples
use confitul::CKey;

let k = CKey::from(1073741824u32);
assert_eq!("0.250000000", format!("{}", k));

Convert from a u64, considering the ring goes from 0 to 2^64.

Examples
use confitul::CKey;

let k = CKey::from(1000000000000000000u64);
assert_eq!("0.054210109", format!("{}", k));
Feeds this value into the given Hasher. Read more
Feeds a slice of this type into the given Hasher. Read more
This method tests for self and other values to be equal, and is used by ==.
This method tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Serialize this value into the given Serde serializer. Read more

Sub another key.

If the result is outside key space, will loop back, as in wrapping mode. So the result is always within key space.

Examples
use confitul::CKey;

let k1 = CKey::from(0.5f64);
let k2 = CKey::from(0.9f64);
let k_diff = k1 - k2;
assert_eq!("0.600000000", String::from(k_diff));
The resulting type after applying the - operator.

Sub an f64.

The value is first converted to a key, considering key space goes from 0 to 1.

Examples
use confitul::CKey;

let k = CKey::from(0.3f64);
assert_eq!("0.900000000", String::from(k - 0.4f64));
The resulting type after applying the - operator.

Sub a u32.

The value is first converted to a key, considering key space goes from 0 to 2^32.

Examples
use confitul::CKey;

let k = CKey::from(0.1f64);
assert_eq!("0.099767169", String::from(k - 1_000_000u32))
The resulting type after applying the - operator.

Sub a u64.

The value is first converted to a key, considering key space goes from 0 to 2^64.

Examples
use confitul::CKey;

let k = CKey::from(0.1f64);
assert_eq!("0.099457899", String::from(k - 10_000_000_000_000_000u64))
The resulting type after applying the - operator.

Try to convert from a &str.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::try_from("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff").unwrap();
assert_eq!("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff", format!("{:?}", k));
The type returned in the event of a conversion error.

Try to convert from a String.

Examples
use confitul::CKey;
use std::convert::TryFrom;

let k = CKey::try_from(String::from("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff")).unwrap();
assert_eq!("12345678ffffffff01234567fffffffff00123456ffffffff0012345ffffffff", format!("{:?}", k));
The type returned in the event of a conversion error.

Auto Trait Implementations§

Blanket Implementations§

Gets the TypeId of self. Read more
Immutably borrows from an owned value. Read more
Mutably borrows from an owned value. Read more

Returns the argument unchanged.

Calls U::from(self).

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

Should always be Self
The resulting type after obtaining ownership.
Creates owned data from borrowed data, usually by cloning. Read more
Uses borrowed data to replace owned data, usually by cloning. Read more
Converts the given value to a String. Read more
The type returned in the event of a conversion error.
Performs the conversion.
The type returned in the event of a conversion error.
Performs the conversion.