pipecircuit 0.0.10

Correct. Robust. Fast. Portable.
Documentation
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(),
        })
    }
}