#![allow(unreachable_pub)]
pub type Bucket = wide::u8x16;
pub const BUCKET_SIZE: usize = std::mem::size_of::<Bucket>();
pub trait ProbeStrategy {
fn new(len: usize, hash: u64) -> Self;
fn next(&mut self) -> Option<usize>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct LinearProbe {
len: usize,
remaining: usize,
pos: usize,
}
impl ProbeStrategy for LinearProbe {
fn new(len: usize, hash: u64) -> Self {
debug_assert!(len > 0);
let pos = ((hash >> 7) as usize) % len;
Self {
len,
remaining: len,
pos,
}
}
#[inline(always)]
fn next(&mut self) -> Option<usize> {
if self.remaining == 0 {
return None;
}
let p = self.pos;
self.pos = (self.pos + 1) % self.len;
self.remaining -= 1;
Some(p)
}
}
#[inline]
pub const fn control_byte_from_hash(hash: u64) -> u8 {
((hash & 0x7F) as u8) | 0x80
}
#[inline]
pub fn match_mask(group: &Bucket, tag: u8) -> u32 {
group.simd_eq(Bucket::splat(tag)).to_bitmask()
}
#[inline]
pub fn split_hash(index_bits: u8, hash: u64) -> (u64, usize) {
let hash_mask: u64 = (-1_i64 as u64) << (index_bits as usize);
let index_mask = !hash_mask;
(hash & hash_mask, (hash & index_mask) as usize)
}