use core::hash::{Hash, Hasher};
use foldhash::SharedSeed;
use foldhash::fast::FoldHasher;
const BUCKET_MUL: u64 = 11_400_714_819_323_198_485;
pub(crate) const SCAN_MAX: usize = 1;
#[inline]
pub(crate) fn hash<T>(x: T, seed: u64) -> u64
where
T: Hash,
{
let mut hasher = FoldHasher::with_seed(seed, SharedSeed::global_fixed());
x.hash(&mut hasher);
hasher.finish()
}
#[expect(
clippy::cast_possible_truncation,
reason = "deliberately taking 32-bit halves"
)]
#[inline]
pub(crate) fn split(hash: u64) -> (u32, u32) {
(hash as u32, (hash >> 32) as u32)
}
#[expect(
clippy::cast_possible_truncation,
reason = "deliberately taking the low 32 hash bits; result is < len so it fits usize"
)]
#[inline]
pub(crate) fn fastrange(hash: u64, len: usize) -> usize {
((u64::from(hash as u32) * len as u64) >> 32) as usize
}
#[inline]
pub(crate) fn bucket(hash: u64, num_buckets: usize) -> usize {
fastrange(hash.wrapping_mul(BUCKET_MUL) >> 32, num_buckets)
}
#[inline]
pub(crate) fn displace(f1: u32, f2: u32, d1: u32, d2: u32) -> u32 {
f1.wrapping_mul(d1).wrapping_add(f2).wrapping_add(d2)
}
#[inline]
pub(crate) const fn fastmod_multiplier(n: usize) -> u64 {
if n != 0 {
(u64::MAX / n as u64).wrapping_add(1)
} else {
0
}
}
#[allow(clippy::cast_possible_truncation)]
#[inline]
pub(crate) fn fastmod(x: u32, multiplier: u64, n: usize) -> usize {
let lowbits = multiplier.wrapping_mul(u64::from(x));
((u128::from(lowbits) * n as u128) >> 64) as usize
}