#![allow(dead_code)]
use crate::util::mix::rapid_mix;
pub(crate) const DEFAULT_SEED: u64 = 0;
const DEFAULT_SECRETS: [u64; 7] = [
0x2d358dccaa6c78a5,
0x8bb84b93962eacc9,
0x4b33a62ed433d4a3,
0x4d5a2da51de1aa47,
0xa0761d6478bd642f,
0xe7037ed1a0b428db,
0x90ed1765281c388c,
];
pub const DEFAULT_RAPID_SECRETS: RapidSecrets = RapidSecrets::seed_cpp(DEFAULT_SEED);
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct RapidSecrets {
pub seed: u64,
pub secrets: [u64; 7],
}
impl RapidSecrets {
#[inline]
pub const fn seed(seed: u64) -> Self {
let seed = premix_seed(seed, 0);
let mut secrets = [0; 7];
secrets[0] = premix_seed(seed, 0);
secrets[1] = premix_seed(secrets[0], 1);
secrets[2] = premix_seed(secrets[1], 2);
secrets[3] = premix_seed(secrets[2], 3);
secrets[4] = premix_seed(secrets[3], 4);
secrets[5] = premix_seed(secrets[4], 5);
secrets[6] = premix_seed(secrets[5], 6);
Self { seed, secrets }
}
#[inline]
pub const fn reseed(&self) -> Self {
Self {
seed: premix_seed(self.seed, 6),
secrets: self.secrets,
}
}
#[inline]
pub const fn seed_cpp(seed: u64) -> Self {
Self {
seed: rapidhash_seed(seed),
secrets: DEFAULT_SECRETS,
}
}
#[inline]
pub fn random() -> Self {
let seed = crate::inner::seeding::seed::get_seed();
let secrets = crate::inner::seeding::secrets::get_secrets();
Self {
seed,
secrets: *secrets,
}
}
}
#[inline(always)]
pub(super) const fn rapidhash_seed(seed: u64) -> u64 {
seed ^ rapid_mix::<false>(seed ^ DEFAULT_SECRETS[2], DEFAULT_SECRETS[1])
}
#[inline]
const fn premix_seed(mut seed: u64, i: usize) -> u64 {
seed ^= rapid_mix::<false>(seed ^ DEFAULT_SECRETS[2], DEFAULT_SECRETS[i]);
const HI: u64 = 0xFFFF << 48;
const MI: u64 = 0xFFFF << 24;
const LO: u64 = 0xFFFF;
if (seed & HI) == 0 {
seed |= 1u64 << 63;
}
if (seed & MI) == 0 {
seed |= 1u64 << 31;
}
if (seed & LO) == 0 {
seed |= 1u64;
}
seed
}