pub struct MemoryPressure {
_bytes: Vec<u8>,
size_bytes: usize,
}
impl MemoryPressure {
pub fn allocate(size_bytes: usize) -> Self {
let bytes = vec![0u8; size_bytes];
Self {
_bytes: bytes,
size_bytes,
}
}
pub fn try_allocate(size_bytes: usize) -> Result<Self, std::collections::TryReserveError> {
let mut bytes: Vec<u8> = Vec::new();
bytes.try_reserve_exact(size_bytes)?;
bytes.resize(size_bytes, 0);
Ok(Self {
_bytes: bytes,
size_bytes,
})
}
pub fn size_bytes(&self) -> usize {
self.size_bytes
}
pub fn allocate_kib(kib: usize) -> Self {
Self::allocate(kib.saturating_mul(1024))
}
pub fn allocate_mib(mib: usize) -> Self {
Self::allocate(mib.saturating_mul(1024 * 1024))
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn allocate_holds_requested_bytes() {
let g = MemoryPressure::allocate(64 * 1024);
assert_eq!(g.size_bytes(), 64 * 1024);
}
#[test]
fn try_allocate_succeeds_for_small_allocations() {
let g = MemoryPressure::try_allocate(4 * 1024).unwrap();
assert_eq!(g.size_bytes(), 4 * 1024);
}
#[test]
fn allocate_kib_and_mib_helpers() {
let g_kib = MemoryPressure::allocate_kib(8);
assert_eq!(g_kib.size_bytes(), 8 * 1024);
let g_mib = MemoryPressure::allocate_mib(1);
assert_eq!(g_mib.size_bytes(), 1024 * 1024);
}
#[test]
fn dropping_guard_releases_memory() {
{
let _g = MemoryPressure::allocate(16 * 1024);
}
}
#[test]
fn try_allocate_huge_returns_err() {
let r = MemoryPressure::try_allocate(usize::MAX);
assert!(r.is_err());
}
}