mod consistent;
mod modrange;
mod modula;
mod range;
mod secmod;
mod slotmod;
mod splitmod;
use consistent::Consistent;
use modrange::ModRange;
use modula::Modula;
use self::secmod::SecMod;
use self::slotmod::SlotMod;
use range::Range;
use splitmod::SplitMod;
#[derive(Clone, Debug)]
pub enum Distribute {
Consistent(Consistent),
Modula(Modula),
Range(Range),
ModRange(ModRange),
SplitMod(SplitMod),
SlotMod(SlotMod),
SecMod(SecMod),
}
pub const DIST_RANGE: &str = "range";
pub const DIST_MOD_RANGE: &str = "modrange";
const DIST_RANGE_SLOT_COUNT_DEFAULT: u64 = 256;
use std::ops::Deref;
impl Distribute {
pub fn from<T: Deref<Target = str>>(distribution: &str, names: &[T]) -> Self {
let dist = distribution.to_ascii_lowercase();
let idx = dist.find('-');
let name = &dist[..idx.unwrap_or(dist.len())];
let num = idx.map(|i| dist[i + 1..].parse::<u64>().ok()).flatten();
match name {
"modula" => Self::Modula(Modula::from(names.len(), false)),
"absmodula" => Self::Modula(Modula::from(names.len(), true)),
"ketama" => Self::Consistent(Consistent::from(names)),
"ketama_origin" => Self::Consistent(Consistent::new(names, true)),
"range" => Self::Range(Range::from(num, names.len())),
"modrange" => Self::ModRange(ModRange::from(num, names.len())),
"splitmod" => Self::SplitMod(SplitMod::from(num, names.len())),
"slotmod" => Self::SlotMod(SlotMod::from(num, names.len())),
"secmod" => Self::SecMod(SecMod::from(names.len())),
_ => {
tracing::warn!("'{}' is not valid , use modula instead", distribution);
println!("'{}' is not valid , use modula instead!", distribution);
Self::Modula(Modula::from(names.len(), false))
}
}
}
#[inline]
pub fn index(&self, hash: i64) -> usize {
match self {
Self::Consistent(d) => d.index(hash),
Self::Modula(d) => d.index(hash),
Self::Range(r) => r.index(hash),
Self::ModRange(m) => m.index(hash),
Self::SplitMod(s) => s.index(hash),
Self::SlotMod(s) => s.index(hash),
Self::SecMod(s) => s.index(hash),
}
}
}
impl Default for Distribute {
fn default() -> Self {
Self::Modula(Modula::from(1, false))
}
}