use super::config::{DEFAULT_RESERVE_FRACTION, MAX_RESERVE_FRACTION, MIN_RESERVE_FRACTION};
use super::layout::GROUP_SIZE;
#[allow(clippy::cast_precision_loss)]
#[inline]
pub(crate) fn usize_to_f64(value: usize) -> f64 {
value as f64
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
#[inline]
pub(crate) fn floor_to_usize(value: f64) -> usize {
value.floor() as usize
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
#[inline]
pub(crate) fn ceil_to_usize(value: f64) -> usize {
value.ceil() as usize
}
#[allow(clippy::cast_possible_truncation, clippy::cast_sign_loss)]
#[inline]
pub(crate) fn round_to_usize(value: f64) -> usize {
value.round() as usize
}
#[inline]
pub(crate) fn max_insertions(capacity: usize, reserve_fraction: f64) -> usize {
capacity.saturating_sub(floor_to_usize(reserve_fraction * usize_to_f64(capacity)))
}
#[inline]
pub(crate) fn capacity_for(start: usize, needed: usize, reserve_fraction: f64) -> Option<usize> {
let mut cap = start;
while max_insertions(cap, reserve_fraction) < needed {
cap = cap.checked_mul(2)?;
}
Some(cap)
}
pub(crate) fn sanitize_reserve_fraction(reserve_fraction: f64) -> f64 {
if reserve_fraction.is_finite() {
reserve_fraction.clamp(MIN_RESERVE_FRACTION, MAX_RESERVE_FRACTION)
} else {
DEFAULT_RESERVE_FRACTION
}
}
pub(crate) fn ceil_three_quarters(value: usize) -> usize {
(value.saturating_mul(3).saturating_add(3)) / 4
}
pub(crate) fn floor_half_reserve_slots(reserve_fraction: f64, value: usize) -> usize {
floor_to_usize((reserve_fraction * usize_to_f64(value)) / 2.0)
}
#[inline]
pub(crate) fn round_up_to_group(value: usize) -> usize {
if value == 0 {
0
} else {
value.div_ceil(GROUP_SIZE) * GROUP_SIZE
}
}
#[inline]
pub(crate) fn round_up_to_pow2_groups(slots: usize) -> usize {
if slots == 0 {
return 0;
}
let groups = slots.div_ceil(GROUP_SIZE).max(1).next_power_of_two();
groups * GROUP_SIZE
}
const GOLDEN_RATIO_U64: u64 = 0x9E37_79B9_7F4A_7C15;
#[inline]
pub(crate) fn level_salt(level_idx: usize) -> u64 {
GOLDEN_RATIO_U64.wrapping_mul((level_idx as u64).wrapping_add(1))
}
#[inline]
#[must_use]
pub(crate) fn fastmod_magic(d: usize) -> u64 {
let d_u32 = u32::try_from(d).expect("fastmod divisor fits in u32");
debug_assert!(d_u32 != 0);
(u64::MAX / u64::from(d_u32)).wrapping_add(1)
}
#[inline]
#[must_use]
#[allow(clippy::cast_possible_truncation)]
pub(crate) fn fastmod_u32(a: u64, m: u64, d: usize) -> usize {
let d_u32 = d as u32;
let a_lo = a as u32;
let lowbits = m.wrapping_mul(u64::from(a_lo));
let result = ((u128::from(lowbits) * u128::from(d_u32)) >> 64) as u32;
result as usize
}