use crate::Bin;
#[must_use]
pub fn recompute_neighborhood_depth(
connected_per_bin: &[u8; 32],
saturation: u8,
low_watermark: u8,
) -> Bin {
let mut candidate: u8 = 0;
let mut found_unsaturated = false;
for (i, count) in connected_per_bin.iter().enumerate() {
if *count < saturation {
candidate = i as u8;
found_unsaturated = true;
break;
}
}
if !found_unsaturated {
candidate = crate::MAX_PO;
}
if low_watermark == 0 {
return Bin::new_unchecked(candidate);
}
let mut sum: u32 = 0;
let mut depth: u8 = candidate;
for i in (0..connected_per_bin.len()).rev() {
let idx = i as u8;
if idx < candidate {
break;
}
sum = sum.saturating_add(u32::from(connected_per_bin[i]));
if sum >= u32::from(low_watermark) {
depth = idx;
break;
}
}
if depth > candidate {
depth = candidate;
}
Bin::new_unchecked(depth)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn empty_table_depth_is_zero() {
assert_eq!(recompute_neighborhood_depth(&[0u8; 32], 8, 2), Bin::ZERO);
}
#[test]
fn fully_saturated_depth_anchored_by_watermark() {
let counts = [8u8; 32];
let depth = recompute_neighborhood_depth(&counts, 8, 2);
assert_eq!(depth, Bin::MAX);
}
#[test]
fn shallow_unsaturated_caps_depth() {
let mut counts = [8u8; 32];
counts[3] = 1;
let depth = recompute_neighborhood_depth(&counts, 8, 2);
assert!(depth.get() <= 3);
}
#[test]
fn zero_watermark_returns_candidate() {
let mut counts = [8u8; 32];
counts[5] = 2;
let depth = recompute_neighborhood_depth(&counts, 8, 0);
assert_eq!(depth, Bin::new(5).unwrap());
}
#[test]
fn very_sparse_tail_keeps_depth_shallow() {
let mut counts = [0u8; 32];
counts[0] = 3;
let depth = recompute_neighborhood_depth(&counts, 8, 2);
assert_eq!(depth, Bin::ZERO);
}
}