use arrow_array::UInt32Array;
use crate::error::IndexError;
use crate::selection::PhysicalSelection;
use crate::storage::PermutationStorage;
#[derive(Debug)]
pub struct PermutationIndex {
pub(crate) storage: PermutationStorage,
}
impl PermutationIndex {
pub fn natural(n: u64) -> Result<Self, IndexError> {
if n > u64::from(u32::MAX) {
return Err(IndexError::TooManyRows(n));
}
#[allow(clippy::cast_possible_truncation)]
let permutation = UInt32Array::from_iter_values(0..n as u32);
Ok(Self {
storage: PermutationStorage::InMemory(permutation),
})
}
pub(crate) fn from_array(permutation: UInt32Array) -> Self {
Self {
storage: PermutationStorage::InMemory(permutation),
}
}
pub(crate) fn from_storage(storage: PermutationStorage) -> Self {
Self { storage }
}
pub fn len(&self) -> u64 {
self.storage.len() as u64
}
pub fn is_empty(&self) -> bool {
self.storage.len() == 0
}
pub fn read_range(&self, start: usize, end: usize) -> Vec<u32> {
self.storage.read_range(start, end)
}
pub fn into_vec(self) -> Vec<u32> {
self.storage.into_vec()
}
#[must_use]
pub fn slice(&self, offset: usize, length: usize) -> Self {
match &self.storage {
PermutationStorage::InMemory(arr) => Self {
storage: PermutationStorage::InMemory(arr.slice(offset, length)),
},
#[cfg(feature = "mmap")]
PermutationStorage::Mmap { .. } => {
let ids = self.storage.read_range(offset, offset + length);
Self::from_array(UInt32Array::from(ids))
}
#[cfg(feature = "persist")]
PermutationStorage::MmapPersisted { .. } => {
let ids = self.storage.read_range(offset, offset + length);
Self::from_array(UInt32Array::from(ids))
}
}
}
pub fn to_physical_selection(&self, start: usize, end: usize) -> (PhysicalSelection, Vec<u32>) {
let virtual_ids = self.read_range(start, end);
let selection = PhysicalSelection::from_ids(virtual_ids.iter().copied());
(selection, virtual_ids)
}
}