use alloc::collections::TryReserveError;
use core::num::NonZeroUsize;
use super::{BytePool, LeaseRecord, LeaseStatus};
#[derive(Debug)]
pub enum BytePoolCreationError {
ExtentCapacityOverflow,
StorageUnavailable { source: TryReserveError },
LeaseStorageUnavailable { source: TryReserveError },
ExtentStorageUnavailable { source: TryReserveError },
}
impl BytePool {
pub fn try_new(
byte_capacity: NonZeroUsize,
maximum_lease_count: NonZeroUsize,
) -> Result<Self, BytePoolCreationError> {
let mut storage = alloc::vec::Vec::new();
storage
.try_reserve_exact(byte_capacity.get())
.map_err(|source| BytePoolCreationError::StorageUnavailable { source })?;
storage.resize(byte_capacity.get(), 0);
let mut leases = alloc::vec::Vec::new();
leases
.try_reserve_exact(maximum_lease_count.get())
.map_err(|source| BytePoolCreationError::LeaseStorageUnavailable { source })?;
for slot in 0..maximum_lease_count.get() {
leases.push(LeaseRecord {
generation: 0,
range: 0..0,
status: core::cell::Cell::new(LeaseStatus::Vacant),
next: core::cell::Cell::new(
slot.checked_add(1)
.filter(|following| *following < maximum_lease_count.get()),
),
});
}
let extent_capacity = maximum_lease_count
.get()
.checked_add(1)
.ok_or(BytePoolCreationError::ExtentCapacityOverflow)?;
let mut free_extents = alloc::vec::Vec::new();
free_extents
.try_reserve_exact(extent_capacity)
.map_err(|source| BytePoolCreationError::ExtentStorageUnavailable { source })?;
free_extents.push(0..byte_capacity.get());
Ok(Self {
storage: storage.into_boxed_slice(),
leases: leases.into_boxed_slice(),
free_extents,
available_lease_head: Some(0),
released_lease_head: core::cell::Cell::new(None),
exhausted_lease_count: 0,
#[cfg(feature = "performance-evidence")]
evidence: super::BytePoolEvidence::new(),
})
}
}