#[cfg(feature = "rand")]
use rand::Rng;
#[cfg(not(feature = "rand"))]
struct LcgJitter {
state: u64,
}
#[cfg(not(feature = "rand"))]
impl LcgJitter {
const fn new(seed: u64) -> Self {
Self { state: seed | 1 }
}
const fn next(&mut self) -> u64 {
const M: u64 = (1u64 << 31) - 1;
self.state = self.state.wrapping_mul(48271) % M;
self.state
}
fn spins(seed: u64, attempt: u32, max_spins: u32) -> u32 {
if max_spins == 0 {
return 0;
}
let mut lcg = Self::new(seed.wrapping_add(u64::from(attempt)));
u32::try_from(lcg.next() % u64::from(max_spins)).unwrap_or(0)
}
}
#[cfg(feature = "rand")]
pub(in crate::kairos::backoff) fn jitter_spins(jitter: Option<u32>, _attempt: u32) -> u32 {
jitter
.filter(|&max| max > 0)
.map_or(0, |max| rand::rng().random_range(0..max))
}
#[cfg(not(feature = "rand"))]
pub(in crate::kairos::backoff) fn jitter_spins(jitter: Option<(u64, u32)>, attempt: u32) -> u32 {
jitter.map_or(0, |(seed, max)| LcgJitter::spins(seed, attempt, max))
}