arithmetic-coding 0.3.1

fast and flexible arithmetic coding library
Documentation
use std::{fs::File, io::Read, ops::Range};

use arithmetic_coding::Model;
use fenwick_model::{simple::FenwickModel, ValueError};

mod common;

#[derive(Debug, Clone)]
pub struct StringModel {
    fenwick_model: FenwickModel,
}

impl StringModel {
    #[must_use]
    pub fn new(symbols: usize) -> Self {
        let fenwick_model = FenwickModel::builder(symbols, 1 << 20)
            .panic_on_saturation()
            .build();
        Self { fenwick_model }
    }
}

#[derive(Debug, thiserror::Error)]
#[error("invalid character: {0}")]
pub struct Error(char);

impl Model for StringModel {
    type B = u64;
    type Symbol = u8;
    type ValueError = ValueError;

    fn probability(
        &self,
        symbol: Option<&Self::Symbol>,
    ) -> Result<Range<Self::B>, Self::ValueError> {
        let fenwick_symbol = symbol.map(|c| *c as usize);
        self.fenwick_model.probability(fenwick_symbol.as_ref())
    }

    fn symbol(&self, value: Self::B) -> Option<Self::Symbol> {
        self.fenwick_model.symbol(value).map(|x| x as u8)
    }

    fn max_denominator(&self) -> Self::B {
        self.fenwick_model.max_denominator()
    }

    fn denominator(&self) -> Self::B {
        self.fenwick_model.denominator()
    }
}

fn round_trip(input: &[u8]) {
    let model = StringModel::new(256);

    common::round_trip(model, input);
}

use criterion::{black_box, criterion_group, criterion_main, Criterion};

#[allow(clippy::missing_panics_doc)]
pub fn criterion_benchmark(c: &mut Criterion) {
    let mut input_string = String::new();
    File::open("./resources/sherlock.txt")
        .unwrap()
        .read_to_string(&mut input_string)
        .unwrap();

    let truncated: String = input_string.chars().take(3428).collect();
    let input = truncated.as_bytes();

    c.bench_function("round trip", |b| b.iter(|| round_trip(black_box(input))));
}

criterion_group!(benches, criterion_benchmark);
criterion_main!(benches);