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 VarVecReader<'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>,
{
pub(super) intvec: &'a VarVec<T, E, B>,
pub(super) reader: VarVecBitReader<'a, E>,
pub(super) code_reader: CodecReader<'a, E>,
}
impl<'a, T: Storable, E: Endianness, B: AsRef<[u64]>> VarVecReader<'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 bit_reader = VarVecBitReader::new(dsi_bitstream::impls::MemWordReader::new_inf(
intvec.data.as_ref(),
));
let code_reader = CodecReader::new(intvec.encoding);
Self {
intvec,
reader: bit_reader,
code_reader,
}
}
#[inline]
pub fn get(&mut self, index: usize) -> Result<Option<T>, VarVecError> {
if index >= self.intvec.len {
return Ok(None);
}
let value = unsafe { self.get_unchecked(index) };
Ok(Some(value))
}
#[inline]
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 (sample_index, start_index) = if k.is_power_of_two() {
let k_exp = k.trailing_zeros();
let si = index >> k_exp;
(si, si << k_exp)
} else {
let si = index / k;
(si, si * k)
};
let start_bit = unsafe { self.intvec.samples.get_unchecked(sample_index) };
self.reader.set_bit_pos(start_bit).unwrap();
for _ in start_index..index {
self.code_reader.read(&mut self.reader).unwrap();
}
let word = self.code_reader.read(&mut self.reader).unwrap();
Storable::from_word(word)
}
}
impl<T: Storable, E: Endianness, B: AsRef<[u64]>> fmt::Debug for VarVecReader<'_, 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("VarVecReader").finish_non_exhaustive()
}
}