use super::{traits::Storable, VarVec, VarVecError};
use crate::common::codec_reader::{CodecReader, VarVecBitReader};
use dsi_bitstream::{
dispatch::{CodesRead, StaticCodeRead},
prelude::{BitRead, BitSeek, Endianness},
};
use std::fmt;
pub struct VarVecSeqReader<'a, T: Storable, E: Endianness, B: AsRef<[u64]>>
where
for<'b> VarVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
intvec: &'a VarVec<T, E, B>,
reader: VarVecBitReader<'a, E>,
code_reader: CodecReader<'a, E>,
current_index: usize,
}
impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> VarVecSeqReader<'a, T, E, B>
where
for<'b> VarVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
pub(super) fn new(intvec: &'a VarVec<T, E, B>) -> Self {
let code_reader = CodecReader::new(intvec.encoding);
Self {
intvec,
reader: VarVecBitReader::new(dsi_bitstream::impls::MemWordReader::new_inf(
intvec.data.as_ref(),
)),
code_reader,
current_index: 0,
}
}
pub fn get(&mut self, index: usize) -> Result<Option<T>, VarVecError> {
if index >= self.intvec.len {
return Ok(None);
}
Ok(Some(unsafe { self.get_unchecked(index) }))
}
pub unsafe fn get_unchecked(&mut self, index: usize) -> T {
debug_assert!(
index < self.intvec.len,
"Index out of bounds: index was {} but length was {}",
index,
self.intvec.len
);
let k = self.intvec.k;
let (target_sample_block, current_sample_block, block_start) = if k.is_power_of_two() {
let k_exp = k.trailing_zeros();
let tsb = index >> k_exp;
let csb = if self.current_index == 0 {
usize::MAX
} else {
(self.current_index - 1) >> k_exp
};
(tsb, csb, tsb << k_exp)
} else {
let tsb = index / k;
let csb = if self.current_index == 0 {
usize::MAX
} else {
(self.current_index - 1) / k
};
(tsb, csb, tsb * k)
};
if index < self.current_index || target_sample_block != current_sample_block {
let start_bit = unsafe { self.intvec.samples.get_unchecked(target_sample_block) };
self.reader.set_bit_pos(start_bit).unwrap();
self.current_index = block_start;
}
for _ in self.current_index..index {
self.code_reader.read(&mut self.reader).unwrap();
}
let word = self.code_reader.read(&mut self.reader).unwrap();
self.current_index = index + 1;
Storable::from_word(word)
}
}
impl<T: Storable, E: Endianness, B: AsRef<[u64]>> fmt::Debug for VarVecSeqReader<'_, T, E, B>
where
for<'b> VarVecBitReader<'b, E>: BitRead<E, Error = core::convert::Infallible>
+ CodesRead<E>
+ BitSeek<Error = core::convert::Infallible>,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("VarVecSeqReader").finish_non_exhaustive()
}
}