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§
source§impl CKey
impl CKey
sourcepub fn new_digest(data: impl AsRef<[u8]>) -> Self
pub fn new_digest(data: impl AsRef<[u8]>) -> Self
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));sourcepub fn new_rand() -> Self
pub fn new_rand() -> Self
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?
More examples
sourcepub fn new_zero() -> Self
pub fn new_zero() -> Self
Generate a key with the value 0.
Examples
use confitul::CKey;
let k = CKey::new_zero();
assert_eq!("0000000000000000000000000000000000000000000000000000000000000000", format!("{:?}", k));sourcepub fn new_unit() -> Self
pub fn new_unit() -> Self
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?
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()
}sourcepub fn new_last() -> Self
pub fn new_last() -> Self
Generate a key with the last, highest possible value.
Examples
use confitul::CKey;
let k = CKey::new_last();
assert_eq!("ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff", format!("{:?}", k));sourcepub fn new_half() -> Self
pub fn new_half() -> Self
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));sourcepub fn inside(self, lower: CKey, upper: CKey) -> bool
pub fn inside(self, lower: CKey, upper: CKey) -> bool
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?
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
}
});
}sourcepub fn incr(&mut self)
pub fn incr(&mut self)
Increment current key by one.
Examples
use confitul::CKey;
let mut k = CKey::new_zero();
k.incr();
assert_eq!(CKey::new_unit(), k);sourcepub fn decr(&mut self)
pub fn decr(&mut self)
Decrement current key by one.
Examples
use confitul::CKey;
let mut k = CKey::new_zero();
k.decr();
assert_eq!(CKey::new_last(), k);sourcepub fn next(self) -> CKey
pub fn next(self) -> CKey
Return current key plus one.
Examples
use confitul::CKey;
let k = CKey::new_zero();
assert_eq!(CKey::new_unit(), k.next());sourcepub fn prev(self) -> CKey
pub fn prev(self) -> CKey
Return current key minus one.
Examples
use confitul::CKey;
let k = CKey::new_zero();
assert_eq!(CKey::new_last(), k.prev());sourcepub fn parse(value: &str) -> Result<CKey, <Self as TryFrom<&str>>::Error>
pub fn parse(value: &str) -> Result<CKey, <Self as TryFrom<&str>>::Error>
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?
More examples
sourcepub fn sort(v: &mut Vec<CKey>, start: CKey)
pub fn sort(v: &mut Vec<CKey>, start: CKey)
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§
source§impl Add<CKey> for CKey
impl Add<CKey> for CKey
source§fn add(self, other: CKey) -> CKey
fn add(self, other: CKey) -> CKey
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));source§impl Add<f64> for CKey
impl Add<f64> for CKey
source§impl Add<u32> for CKey
impl Add<u32> for CKey
source§impl Add<u64> for CKey
impl Add<u64> for CKey
source§impl Debug for CKey
impl Debug for CKey
source§fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error>
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));source§impl<'de> Deserialize<'de> for CKey
impl<'de> Deserialize<'de> for CKey
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 Display for CKey
impl Display for CKey
source§fn fmt(&self, f: &mut Formatter<'_>) -> Result
fn fmt(&self, f: &mut Formatter<'_>) -> Result
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));source§impl From<CKey> for String
impl From<CKey> for String
source§fn from(k: CKey) -> String
fn from(k: CKey) -> String
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));source§impl From<CKey> for f64
impl From<CKey> for f64
source§fn from(k: CKey) -> f64
fn from(k: CKey) -> f64
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)));source§impl PartialEq<CKey> for CKey
impl PartialEq<CKey> for CKey
source§impl Sub<CKey> for CKey
impl Sub<CKey> for CKey
source§fn sub(self, other: CKey) -> CKey
fn sub(self, other: CKey) -> CKey
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));source§impl Sub<f64> for CKey
impl Sub<f64> for CKey
source§impl Sub<u32> for CKey
impl Sub<u32> for CKey
source§impl Sub<u64> for CKey
impl Sub<u64> for CKey
source§impl TryFrom<&str> for CKey
impl TryFrom<&str> for CKey
source§fn try_from(value: &str) -> Result<CKey, Self::Error>
fn try_from(value: &str) -> Result<CKey, Self::Error>
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));§type Error = FromHexError
type Error = FromHexError
source§impl TryFrom<String> for CKey
impl TryFrom<String> for CKey
source§fn try_from(value: String) -> Result<CKey, Self::Error>
fn try_from(value: String) -> Result<CKey, Self::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));