pipecircuit 0.0.18

Correct. Robust. Fast. Portable. Pick four.
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,
    },
    LeaseIdentityStorageUnavailable {
        slot: usize,
        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() {
            let mut identity = alloc::vec::Vec::new();
            identity.try_reserve_exact(1).map_err(|source| {
                BytePoolCreationError::LeaseIdentityStorageUnavailable { slot, source }
            })?;
            identity.push(0_u8);
            let identity = identity.into_boxed_slice();
            let identity_address = identity.as_ptr().addr();
            leases.push(LeaseRecord {
                identity: core::cell::Cell::new(identity),
                identity_address,
                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(),
        })
    }
}