use std::sync::atomic::{AtomicU64, Ordering};
use std::time::{SystemTime, UNIX_EPOCH};
pub(crate) static HASH_COUNTER: AtomicU64 = AtomicU64::new(0);
pub(super) fn simple_hash_fraction_for(task_id: &str) -> f64 {
let nanos = u64::try_from(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos(),
)
.unwrap_or(u64::MAX);
let seq = HASH_COUNTER.fetch_add(1, Ordering::Relaxed);
let task_hash = hash_task_id(task_id);
let seed = nanos ^ seq ^ task_hash;
let hash = seed
.wrapping_mul(6_364_136_223_846_793_005)
.wrapping_add(1_442_695_040_888_963_407);
f64::from(u16::try_from(hash % 10000).unwrap_or(0)) / 10000.0
}
pub(crate) fn simple_hash_index_for(len: usize, task_id: &str) -> usize {
if len == 0 {
return 0;
}
let nanos = u64::try_from(
SystemTime::now()
.duration_since(UNIX_EPOCH)
.unwrap_or_default()
.as_nanos(),
)
.unwrap_or(u64::MAX);
let seq = HASH_COUNTER.fetch_add(1, Ordering::Relaxed);
let task_hash = hash_task_id(task_id);
let seed = nanos ^ seq ^ task_hash;
let hash = seed
.wrapping_mul(6_364_136_223_846_793_005)
.wrapping_add(1_442_695_040_888_963_407);
usize::try_from(hash % len as u64).unwrap_or(0)
}
fn hash_task_id(task_id: &str) -> u64 {
task_id.bytes().fold(0u64, |acc, b| {
acc.wrapping_mul(31).wrapping_add(u64::from(b))
})
}