mod adaptive_linear;
mod adaptive_tree;
#[cfg(test)]
mod tests;
use super::Error;
use super::Result;
pub use self::adaptive_linear::AdaptiveLinearModel;
pub use self::adaptive_tree::AdaptiveTreeModel;
pub trait Model {
fn parameters<'a>(&'a self) -> &'a Parameters;
fn total_frequency(&self) -> u64;
fn get_frequency(&mut self, symbol: usize) -> Result<(u64, u64)>;
fn get_symbol(&mut self, value: u64) -> Result<(usize, u64, u64)>;
#[cfg(debug_assertions)]
fn get_freq_table(&self) -> Vec<(u64, u64)>;
}
#[derive(Clone)]
pub struct Parameters {
pub symbol_bits: usize,
pub symbol_eof: usize,
pub symbol_count: usize,
pub freq_bits: usize,
pub freq_max: u64,
pub code_bits: usize,
pub code_min: u64,
pub code_one_fourth: u64,
pub code_half: u64,
pub code_three_fourths: u64,
pub code_max: u64,
}
impl Parameters {
pub fn new(symbol: usize, frequency: usize, code: usize) -> Result<Parameters> {
if symbol < 1 || frequency < symbol + 2 || code < frequency + 2 || 64 < code + frequency {
Err(Error::InvalidInput)
} else {
Ok(Parameters {
symbol_bits: symbol,
symbol_eof: 1 << symbol,
symbol_count: (1 << symbol) + 1,
freq_bits: frequency,
freq_max: (1 << frequency) - 1,
code_bits: code,
code_min: 0,
code_one_fourth: 1 << (code - 2),
code_half: 2 << (code - 2),
code_three_fourths: 3 << (code - 2),
code_max: (1 << code) - 1,
})
}
}
}