#![allow(dead_code)]
use std::time::SystemTime;
use std::sync::{
LazyLock,
Mutex,
};
static RNG: LazyLock<Mutex<SplitMix64>> = LazyLock::new(|| Mutex::new(SplitMix64::new()));
#[inline]
pub(crate) fn u64() -> u64 { RNG.lock().unwrap().u64() }
#[inline]
pub(crate) fn bool() -> bool { RNG.lock().unwrap().bool() }
#[inline]
pub(crate) fn seed() -> u64 { RNG.lock().unwrap().seed() }
pub(crate) fn set_seed(seed: u64) { RNG.lock().unwrap().set_seed(seed) }
struct SplitMix64 {
state: u64,
}
impl SplitMix64 {
pub fn new() -> Self { Self::from_seed(seed_from_clock()) }
pub fn from_seed(seed: u64) -> Self { Self { state: seed } }
#[inline]
pub fn seed(&self) -> u64 { self.state }
#[inline]
pub fn set_seed(&mut self, seed: u64) { self.state = seed }
#[inline]
pub fn u64(&mut self) -> u64 { self.next() }
#[inline]
pub fn bool(&mut self) -> bool { self.next() & 1 == 1 }
fn next(&mut self) -> u64 {
self.state = self.state.wrapping_add(0x9e37_79b9_7f4a_7c15);
let mut z = self.state;
z = (z ^ (z >> 30)).wrapping_mul(0xbf58_476d_1ce4_e5b9);
z = (z ^ (z >> 27)).wrapping_mul(0x94d0_49bb_1331_11eb);
z ^ (z >> 31)
}
}
fn seed_from_clock() -> u64 {
let now = SystemTime::now().duration_since(SystemTime::UNIX_EPOCH).unwrap();
let secs = now.as_secs();
let ns = now.subsec_nanos();
let seed = u64::from(ns) << 32 | secs;
murmur64(seed)
}
fn murmur64(x: u64) -> u64 {
let mut x = x;
x ^= x >> 33;
x = x.wrapping_mul(0xff51_afd7_ed55_8ccd);
x ^= x >> 33;
x = x.wrapping_mul(0xc4ce_b9fe_1a85_ec53);
x ^= x >> 33;
x
}