extern crate siphasher;
use siphasher::sip::SipHasher;
use std::cmp::Ordering;
use std::fmt::Debug;
use std::hash::BuildHasher;
pub mod coordinator;
mod crud;
mod iterator;
#[derive(Clone, PartialEq, Debug)]
pub struct DefaultHashBuilder;
impl BuildHasher for DefaultHashBuilder {
type Hasher = SipHasher;
fn build_hasher(&self) -> Self::Hasher {
SipHasher::new()
}
}
#[derive(Clone, Debug)]
struct Node<T> {
key: u64,
node: T,
virtual_id: usize,
}
impl<T> Node<T> {
fn new(key: u64, node: T, virtual_id: usize) -> Node<T> {
Node {
key,
node,
virtual_id,
}
}
}
impl<T> PartialEq for Node<T> {
fn eq(&self, other: &Node<T>) -> bool {
self.key == other.key
}
}
impl<T> Eq for Node<T> {}
impl<T> PartialOrd for Node<T> {
fn partial_cmp(&self, other: &Node<T>) -> Option<Ordering> {
Some(self.cmp(other))
}
}
impl<T> Ord for Node<T> {
fn cmp(&self, other: &Node<T>) -> Ordering {
self.key.cmp(&other.key)
}
}
#[derive(Clone, PartialEq, Debug)]
pub struct HashRing<T, S = DefaultHashBuilder> {
hash_builder: S,
ring: Vec<Node<T>>,
replicas: usize,
vnodes: usize,
}
impl<T> Default for HashRing<T> {
fn default() -> Self {
HashRing {
hash_builder: DefaultHashBuilder,
ring: Vec::new(),
replicas: 2,
vnodes: 200,
}
}
}
impl<T> HashRing<T> {
pub fn new(replicas: usize, vnodes: usize) -> HashRing<T> {
HashRing {
hash_builder: DefaultHashBuilder,
ring: Vec::new(),
replicas,
vnodes: vnodes.max(1),
}
}
}
impl<T, S> HashRing<T, S> {
pub fn len(&self) -> usize {
self.ring.len() / self.vnodes
}
pub fn vlen(&self) -> usize {
self.ring.len()
}
pub fn is_empty(&self) -> bool {
self.ring.len() == 0
}
pub fn with_hasher(replicas: usize, vnodes: usize, hash_builder: S) -> HashRing<T, S> {
HashRing {
hash_builder,
ring: Vec::new(),
replicas,
vnodes,
}
}
}