pipecircuit 0.0.12

Correct. Robust. Fast. Portable.
Documentation
use alloc::{collections::TryReserveError, vec::Vec};

use super::{DenseKeyIndex, EMPTY_ROW};

const MINIMUM_BUCKETS: usize = 8;

pub(in crate::storage::warp_table) enum DenseKeyIndexCreationError {
    CapacityOverflow { maximum_rows: usize },
    StorageUnavailable { source: TryReserveError },
}

impl DenseKeyIndex {
    pub(in crate::storage::warp_table) fn try_new(
        maximum_rows: usize,
    ) -> Result<Self, DenseKeyIndexCreationError> {
        let bucket_count = maximum_rows
            .checked_mul(2)
            .map(|count| count.max(MINIMUM_BUCKETS))
            .and_then(usize::checked_next_power_of_two)
            .ok_or(DenseKeyIndexCreationError::CapacityOverflow { maximum_rows })?;
        let mut buckets = Vec::new();
        buckets
            .try_reserve_exact(bucket_count)
            .map_err(|source| DenseKeyIndexCreationError::StorageUnavailable { source })?;
        buckets.resize(bucket_count, EMPTY_ROW);
        Ok(Self { buckets })
    }
}