use super::{AssignStorageSiteTrait, HasIngestCapacityTrait, SteadyAlgo, TiltedAlgo};
use crate::_auxlib as aux;
#[allow(non_snake_case)]
pub fn has_ingest_capacity<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> bool {
let half_S: Uint = S >> 1;
let has_capacity_1st: bool = SteadyAlgo::has_ingest_capacity(half_S, T >> 1);
let has_capacity_2nd =
T == Uint::zero() || TiltedAlgo::has_ingest_capacity(half_S, (T - Uint::one()) >> 1);
has_capacity_1st && has_capacity_2nd
}
#[allow(non_snake_case)]
pub fn _assign_storage_site<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> Uint {
debug_assert!(has_ingest_capacity(S, T));
let half_S: Uint = S >> 1;
let half_T: Uint = T >> 1;
if T & Uint::one() == Uint::zero() {
let site: Uint = SteadyAlgo::_assign_storage_site(half_S, half_T);
if site == half_S {
S
} else {
site
}
} else {
half_S + TiltedAlgo::_assign_storage_site(half_S, half_T)
}
}
#[allow(non_snake_case)]
pub fn assign_storage_site<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> Option<Uint> {
let k = _assign_storage_site(S, T);
if k == S {
None
} else {
Some(k)
}
}
pub struct Algo;
#[allow(non_snake_case)]
impl HasIngestCapacityTrait for Algo {
fn has_ingest_capacity<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> bool {
has_ingest_capacity::<Uint>(S, T)
}
}
#[allow(non_snake_case)]
impl AssignStorageSiteTrait for Algo {
fn _assign_storage_site<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> Uint {
_assign_storage_site::<Uint>(S, T)
}
fn assign_storage_site<Uint: aux::UnsignedTrait>(S: Uint, T: Uint) -> Option<Uint> {
assign_storage_site::<Uint>(S, T)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_smoke_has_ingest_capacity() {
has_ingest_capacity::<u32>(16, 101);
}
#[test]
fn test_smoke_assign_storage_site() {
assign_storage_site::<u32>(16, 101);
}
#[test]
fn test_smoke_impl_assign_storage_site() {
_assign_storage_site::<u32>(16, 101);
}
}