pub const EXPIRED_REFILL_FETCH_CAP: usize = 1024;
pub fn next_refill_window(
fetched: usize,
returned: usize,
live: usize,
expired: usize,
target: usize,
) -> Option<usize> {
let done = fetched == 0
|| expired == 0
|| live >= target
|| returned < fetched
|| fetched >= EXPIRED_REFILL_FETCH_CAP;
(!done).then(|| fetched.saturating_mul(2).min(EXPIRED_REFILL_FETCH_CAP))
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn the_refill_stops_on_every_bound() {
assert_eq!(next_refill_window(60, 60, 0, 60, 20), Some(120));
assert_eq!(next_refill_window(60, 60, 0, 0, 20), None);
assert_eq!(next_refill_window(60, 60, 20, 40, 20), None);
assert_eq!(next_refill_window(60, 41, 1, 40, 20), None);
assert_eq!(next_refill_window(1024, 1024, 0, 1024, 20), None);
assert_eq!(next_refill_window(0, 0, 0, 0, 0), None);
assert_eq!(next_refill_window(640, 640, 0, 640, 20), Some(1024));
let (mut window, mut rounds) = (1, 0);
while let Some(next) = next_refill_window(window, window, 0, window, 20) {
assert!(next > window, "the window must grow");
window = next;
rounds += 1;
}
assert_eq!((window, rounds), (EXPIRED_REFILL_FETCH_CAP, 10));
}
}