adder_codec_core/codec/compressed/fenwick/
simple.rs1#![allow(missing_docs, unused)]
3use arithmetic_coding_adder_dep::Model;
6
7use super::Weights;
8use crate::codec::compressed::fenwick::ValueError;
9
10#[derive(Debug, Clone)]
11pub struct FenwickModel {
12 weights: Weights,
13 max_denominator: u64,
14 panic_on_saturation: bool,
15}
16
17#[must_use]
18pub struct Builder {
19 model: FenwickModel,
20}
21
22impl Builder {
23 fn new(n_symbols: usize, max_denominator: u64) -> Self {
24 let weights = Weights::new(n_symbols);
25 let model = FenwickModel {
26 weights,
27 max_denominator,
28 panic_on_saturation: false,
29 };
30 Self { model }
31 }
32
33 pub fn panic_on_saturation(mut self) -> Self {
34 self.model.panic_on_saturation = true;
35 self
36 }
37
38 #[must_use]
39 pub fn build(self) -> FenwickModel {
40 self.model
41 }
42}
43
44impl FenwickModel {
45 pub fn builder(n_symbols: usize, max_denominator: u64) -> Builder {
46 Builder::new(n_symbols, max_denominator)
47 }
48}
49
50impl Model for FenwickModel {
51 type B = u64;
52 type Symbol = usize;
53 type ValueError = ValueError;
54
55 fn probability(
56 &self,
57 symbol: Option<&Self::Symbol>,
58 ) -> Result<std::ops::Range<Self::B>, Self::ValueError> {
59 if let Some(s) = symbol.copied() {
60 if s >= self.weights.len() {
61 Err(ValueError(s))
62 } else {
63 Ok(self.weights.range(Some(s)))
64 }
65 } else {
66 Ok(self.weights.range(None))
67 }
68 }
69
70 fn max_denominator(&self) -> Self::B {
71 self.max_denominator
72 }
73
74 fn symbol(&self, value: Self::B) -> Option<Self::Symbol> {
75 self.weights.symbol(value)
76 }
77
78 fn denominator(&self) -> Self::B {
79 self.weights.total()
80 }
81
82 fn update(&mut self, symbol: Option<&Self::Symbol>) {
83 if self.panic_on_saturation {
84 debug_assert!(
85 self.denominator() < self.max_denominator,
86 "hit max denominator!"
87 );
88 }
89 if self.denominator() < self.max_denominator {
90 self.weights.update(symbol.copied(), 1);
91 }
92 }
93}