brz-memcache 0.0.7

Asynchronous memcached client with sharding, failover, and live configuration
Documentation
// use super::DIST_MOD_RANGE_WITH_SLOT_PREFIX;

// // alg: hash%slot/(slot/shards.len)
// 先对slot取模,然后再按区间进行分布,比如[0,16)分区,每段间隔是4,则分为4个区间:[0,4),[4,8),[8,12),[12,16)
#[derive(Clone, Debug, Default)]
pub struct ModRange {
    slot: u64,
    interval: u64,
    shards: usize,
}

// ModRange 分布方法,默认总范围是[0,256),否则指定slot
impl ModRange {
    pub fn from(num: Option<u64>, shards: usize) -> Self {
        let slot = num.unwrap_or(256);

        assert!(shards > 0 && slot >= shards as u64);
        ModRange {
            slot,
            interval: slot / shards as u64,
            shards,
        }
    }

    pub fn index(&self, hash: i64) -> usize {
        let mut val = hash.wrapping_rem(self.slot as i64);
        if val < 0 {
            tracing::warn!("found negative modrange pre hash:{:?}", val);
            val = val.wrapping_abs();
        }
        let rs = val as u64 / self.interval;
        if rs >= self.shards as u64 {
            // 超出范围,返回最后一个分片
            tracing::warn!(
                "found modrange slot out of bound, rs:{}, shards:{}",
                rs,
                self.shards
            );
            return self.shards - 1;
        }
        rs as usize
    }
}