pub mod blocks;
mod ranker;
pub mod super_blocks;
#[cfg(test)]
mod test;
pub use ranker::BiRank;
pub trait BasicBlock: Send + Sync {
const N: usize;
const B: usize;
const W: usize;
const INCLUSIVE: bool = false;
fn new(rank: u64, data: &[u8]) -> Self;
fn rank(&self, pos: usize) -> u64 {
assert!(pos < Self::N);
unsafe { self.rank_unchecked(pos) }
}
unsafe fn rank_unchecked(&self, pos: usize) -> u64;
}
pub trait SuperBlock<BB: BasicBlock>: Sync + Send + Sized {
fn new(ranks: u64, data: &[u8]) -> Self;
fn get(&self, block_idx: usize) -> u64;
const BLOCKS_PER_SUPERBLOCK: usize = if BB::W == 0 {
1
} else if BB::W == 64 {
usize::MAX
} else {
(((1u128 << BB::W) / BB::N as u128) as usize - 1).next_power_of_two() / 2
};
const BYTES_PER_SUPERBLOCK: usize = Self::BLOCKS_PER_SUPERBLOCK.saturating_mul(BB::B);
}
pub trait BiRanker: Sync + Sized {
fn new_packed(seq: &[u64]) -> Self;
fn size(&self) -> usize;
unsafe fn rank_unchecked(&self, pos: usize) -> u64;
const HAS_PREFETCH: bool = false;
fn prefetch(&self, _pos: usize) {}
}