#![cfg(feature = "storage")]
use core::num::NonZeroUsize;
use pipecircuit::storage::byte_pool::{
BytePool, BytePoolLeaseOutcome, BytePoolRecycleOutcome, BytePoolResumeOutcome,
};
#[global_allocator]
static ALLOCATOR: dhat::Alloc = dhat::Alloc;
#[test]
fn owner_tokens_are_reserved_at_construction_and_reused_without_allocating()
-> Result<(), &'static str> {
let profiler = dhat::Profiler::builder().testing().build();
let calibration = core::hint::black_box(Box::new([7_u8; 64]));
let stats = dhat::HeapStats::get();
drop(profiler);
assert!(stats.total_blocks > 0);
assert!(stats.total_bytes >= 64);
drop(calibration);
let bytes = NonZeroUsize::new(1024).ok_or("bytes")?;
let request = NonZeroUsize::new(16).ok_or("request")?;
for slots in [1, 4, 64] {
let slots = NonZeroUsize::new(slots).ok_or("slots")?;
let profiler = dhat::Profiler::builder().testing().build();
let mut pool = BytePool::try_new(bytes, slots).map_err(|_| "pool")?;
let construction = dhat::HeapStats::get();
drop(profiler);
println!(
"slots={slots} construction_blocks={} construction_bytes={}",
construction.total_blocks, construction.total_bytes
);
let profiler = dhat::Profiler::builder().testing().build();
for _ in 0..512 {
let BytePoolLeaseOutcome::Leased(mut lease) = pool.lease(request) else {
return Err("lease");
};
lease.bytes_mut().fill(7);
let address = lease.bytes().as_ptr();
let mut retained = lease.retain();
for _ in 0..8 {
let BytePoolResumeOutcome::Resumed(lease) = pool.resume(retained) else {
return Err("resume");
};
assert_eq!(lease.bytes().as_ptr(), address);
assert_eq!(lease.bytes(), &[7; 16]);
retained = lease.retain();
}
assert_eq!(pool.recycle(retained), BytePoolRecycleOutcome::Recycled);
assert_eq!(pool.statistics().free_byte_capacity, bytes.get());
}
let steady = dhat::HeapStats::get();
drop(profiler);
assert_eq!(steady.total_blocks, 0);
assert_eq!(steady.total_bytes, 0);
println!(
"slots={slots} steady_blocks={} steady_bytes={}",
steady.total_blocks, steady.total_bytes
);
}
Ok(())
}