use std::sync::atomic::{AtomicUsize, Ordering};
const MAX_RENDER_CAPACITY_HINT: usize = 32 * 1024 * 1024;
#[derive(Default)]
pub(crate) struct RenderCapacityHint {
last: AtomicUsize,
previous: AtomicUsize,
}
impl RenderCapacityHint {
pub(crate) fn get(&self) -> usize {
let len = self
.last
.load(Ordering::Relaxed)
.min(self.previous.load(Ordering::Relaxed));
len.saturating_add(len / 8).min(MAX_RENDER_CAPACITY_HINT)
}
pub(crate) fn record(&self, len: usize) {
let last = self.last.load(Ordering::Relaxed);
self.previous.store(last, Ordering::Relaxed);
self.last.store(len, Ordering::Relaxed);
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn single_large_render_does_not_inflate_next_reservation() {
let hint = RenderCapacityHint::default();
hint.record(2_000);
hint.record(2_000);
hint.record(4_000_000);
assert_eq!(hint.get(), 2_250);
hint.record(4_000_000);
assert_eq!(hint.get(), 4_500_000);
}
#[test]
fn reservation_is_capped() {
let hint = RenderCapacityHint::default();
hint.record(usize::MAX);
hint.record(usize::MAX);
assert_eq!(hint.get(), MAX_RENDER_CAPACITY_HINT);
}
}