use crate::prelude::*;
use dsi_bitstream::{prelude::CodesStats, traits::BitSeek};
#[derive(Debug, Clone, Default)]
pub struct DecoderStats {
pub outdegrees: CodesStats,
pub reference_offsets: CodesStats,
pub block_counts: CodesStats,
pub blocks: CodesStats,
pub interval_counts: CodesStats,
pub interval_starts: CodesStats,
pub interval_lens: CodesStats,
pub first_residuals: CodesStats,
pub residuals: CodesStats,
}
impl DecoderStats {
pub fn update(&mut self, rhs: &Self) {
self.outdegrees.add(&rhs.outdegrees);
self.reference_offsets.add(&rhs.reference_offsets);
self.block_counts.add(&rhs.block_counts);
self.blocks.add(&rhs.blocks);
self.interval_counts.add(&rhs.interval_counts);
self.interval_starts.add(&rhs.interval_starts);
self.interval_lens.add(&rhs.interval_lens);
self.first_residuals.add(&rhs.first_residuals);
self.residuals.add(&rhs.residuals);
}
}
impl std::ops::AddAssign<&Self> for DecoderStats {
fn add_assign(&mut self, rhs: &Self) {
self.update(rhs);
}
}
impl core::iter::Sum for DecoderStats {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
iter.fold(Self::default(), |mut acc, x| {
acc.update(&x);
acc
})
}
}
pub struct StatsDecoder<D: Decode> {
pub codes_reader: D,
pub stats: DecoderStats,
}
impl<D: Decode> StatsDecoder<D> {
#[inline(always)]
pub fn new(codes_reader: D, stats: DecoderStats) -> Self {
Self {
codes_reader,
stats,
}
}
}
impl<D: Decode> BitSeek for StatsDecoder<D>
where
D: BitSeek,
{
type Error = <D as BitSeek>::Error;
#[inline(always)]
fn bit_pos(&mut self) -> Result<u64, Self::Error> {
self.codes_reader.bit_pos()
}
#[inline(always)]
fn set_bit_pos(&mut self, bit_pos: u64) -> Result<(), Self::Error> {
self.codes_reader.set_bit_pos(bit_pos)
}
}
impl<D: Decode> Decode for StatsDecoder<D> {
#[inline(always)]
fn read_outdegree(&mut self) -> u64 {
self.stats
.outdegrees
.update(self.codes_reader.read_outdegree())
}
#[inline(always)]
fn read_reference_offset(&mut self) -> u64 {
self.stats
.reference_offsets
.update(self.codes_reader.read_reference_offset())
}
#[inline(always)]
fn read_block_count(&mut self) -> u64 {
self.stats
.block_counts
.update(self.codes_reader.read_block_count())
}
#[inline(always)]
fn read_block(&mut self) -> u64 {
self.stats.blocks.update(self.codes_reader.read_block())
}
#[inline(always)]
fn read_interval_count(&mut self) -> u64 {
self.stats
.interval_counts
.update(self.codes_reader.read_interval_count())
}
#[inline(always)]
fn read_interval_start(&mut self) -> u64 {
self.stats
.interval_starts
.update(self.codes_reader.read_interval_start())
}
#[inline(always)]
fn read_interval_len(&mut self) -> u64 {
self.stats
.interval_lens
.update(self.codes_reader.read_interval_len())
}
#[inline(always)]
fn read_first_residual(&mut self) -> u64 {
self.stats
.first_residuals
.update(self.codes_reader.read_first_residual())
}
#[inline(always)]
fn read_residual(&mut self) -> u64 {
self.stats
.residuals
.update(self.codes_reader.read_residual())
}
}