use std::sync::atomic::{AtomicUsize, Ordering};
#[doc(hidden)]
pub struct SizeHint {
value: AtomicUsize,
}
impl SizeHint {
pub const fn new() -> SizeHint {
SizeHint {
value: AtomicUsize::new(0),
}
}
#[inline]
pub fn get(&self) -> usize {
let value = self.value.load(Ordering::Acquire);
value + value / 8 + 75
}
#[inline]
pub fn update(&self, value: usize) {
let mut old = self.value.load(Ordering::Acquire);
if old == 0 {
old = value;
}
self.value
.store(old - old / 4 + value / 4, Ordering::Release);
}
}
impl Default for SizeHint {
fn default() -> Self {
Self::new()
}
}
#[test]
fn test_update() {
let hint = SizeHint::new();
for size in 1..=100 {
let cap = hint.get();
assert!(size <= cap);
assert!(cap <= size + size / 8 + 75);
hint.update(size);
}
}