use alloc::collections::TryReserveError;
use core::marker::PhantomData;
use super::blocks::storage_dimensions;
use super::{RangeIndex, RangeIndexKey};
#[derive(Debug)]
pub enum RangeIndexCreationError {
InvalidBitWidth { bits: u32 },
CapacityOverflow { maximum_rows: usize, bits: u32 },
StorageUnavailable { source: TryReserveError },
}
impl<Key: RangeIndexKey> RangeIndex<Key> {
pub fn try_new(maximum_rows: usize) -> Result<Self, RangeIndexCreationError> {
if !(1..=u64::BITS).contains(&Key::BITS) {
return Err(RangeIndexCreationError::InvalidBitWidth { bits: Key::BITS });
}
let Some((_, storage_words)) = storage_dimensions(maximum_rows, Key::BITS) else {
return Err(RangeIndexCreationError::CapacityOverflow {
maximum_rows,
bits: Key::BITS,
});
};
let mut blocks = alloc::vec::Vec::new();
blocks
.try_reserve_exact(storage_words)
.map_err(|source| RangeIndexCreationError::StorageUnavailable { source })?;
blocks.resize(storage_words, 0);
Ok(Self {
maximum_rows,
member_count: 0,
blocks,
key: PhantomData,
})
}
}