use std::hash::Hasher;
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub struct DrawSite {
pub tag: &'static str,
pub site_id: u64,
}
impl DrawSite {
pub const fn new(tag: &'static str, site_id: u64) -> Self {
Self { tag, site_id }
}
}
pub trait RandomProvider: Send {
fn sample_exp_seconds(&mut self, site: DrawSite, rate: f64) -> f64;
}
pub const fn fnv1a64(s: &str) -> u64 {
let bytes = s.as_bytes();
let mut hash: u64 = 0xcbf29ce484222325;
let mut i = 0;
while i < bytes.len() {
hash ^= bytes[i] as u64;
hash = hash.wrapping_mul(0x100000001b3);
i += 1;
}
hash
}
#[macro_export]
macro_rules! draw_site {
($tag:expr) => {{
const _SITE_ID: u64 = $crate::randomness::fnv1a64(concat!(
module_path!(),
"::",
file!(),
":",
line!(),
":",
column!(),
":",
$tag,
));
$crate::randomness::DrawSite::new($tag, _SITE_ID)
}};
}
pub fn runtime_site_id(tag: &str, label: &str) -> u64 {
let mut h = std::collections::hash_map::DefaultHasher::new();
h.write(tag.as_bytes());
h.write(label.as_bytes());
h.finish()
}