use std::iter::FusedIterator;
use crate::{Code, Coding, TreeDegree};
#[derive(Copy, Clone)]
pub struct LevelIterator<'coding, ValueType, D> {
coding: &'coding Coding<ValueType, D>,
last_value_index: usize,
level_size: u32,
level: u32
}
impl<'coding, ValueType, D: TreeDegree> LevelIterator<'coding, ValueType, D> {
pub fn new(coding: &'coding Coding<ValueType, D>) -> Self {
Self {
coding,
level_size: coding.degree.as_u32(),
last_value_index: 0,
level: 0
}
}
}
impl<'coding, ValueType, D: TreeDegree> FusedIterator for LevelIterator<'coding, ValueType, D> {}
impl<'coding, ValueType, D: TreeDegree> ExactSizeIterator for LevelIterator<'coding, ValueType, D> {
fn len(&self) -> usize {
self.coding.internal_nodes_count.len() - self.level as usize
}
}
impl<'coding, ValueType, D: TreeDegree> Iterator for LevelIterator<'coding, ValueType, D> {
type Item = (&'coding [ValueType], u32, u32);
fn next(&mut self) -> Option<Self::Item> {
(self.last_value_index != self.coding.values.len()).then(|| {
let value_index = self.last_value_index;
let internal_nodes = self.coding.internal_nodes_count[self.level as usize];
self.level += 1;
let leaves_count = self.level_size - internal_nodes;
self.last_value_index = (value_index + leaves_count as usize).min(self.coding.values.len());
self.level_size = self.coding.degree * internal_nodes;
(&self.coding.values[value_index..self.last_value_index], internal_nodes, self.level)
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
#[derive(Copy, Clone)]
pub struct CodesIterator<'coding, ValueType, D> {
level_iterator: LevelIterator<'coding, ValueType, D>,
value_index: usize,
bits: u32,
}
impl<'coding, ValueType, D: TreeDegree> CodesIterator<'coding, ValueType, D> {
#[inline] pub fn new(coding: &'coding Coding<ValueType, D>) -> Self {
Self {
level_iterator: LevelIterator::new(coding),
value_index: 0,
bits: 0
}
}
}
impl<'coding, ValueType, D: TreeDegree> FusedIterator for CodesIterator<'coding, ValueType, D> {}
impl<'coding, ValueType, D: TreeDegree> ExactSizeIterator for CodesIterator<'coding, ValueType, D> {
#[inline] fn len(&self) -> usize {
self.level_iterator.coding.values.len() - self.value_index
}
}
impl<'coding, ValueType, D: TreeDegree> Iterator for CodesIterator<'coding, ValueType, D> {
type Item = (&'coding ValueType, Code);
fn next(&mut self) -> Option<Self::Item> {
while self.value_index == self.level_iterator.last_value_index {
let (_, first_code_bits, _) = self.level_iterator.next()?;
self.bits = first_code_bits;
}
let result = (&self.level_iterator.coding.values[self.value_index],
Code{ content: self.bits, len: self.level_iterator.level });
self.value_index += 1;
self.bits += 1;
Some(result)
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}
#[derive(Copy, Clone)]
pub struct ReversedCodesIterator<'coding, ValueType, D>(CodesIterator<'coding, ValueType, D>);
impl<'coding, ValueType, D: TreeDegree> ReversedCodesIterator<'coding, ValueType, D> {
#[inline] pub fn new(coding: &'coding Coding<ValueType, D>) -> Self { Self(CodesIterator::new(coding)) }
}
impl<'coding, ValueType, D: TreeDegree> FusedIterator for ReversedCodesIterator<'coding, ValueType, D> {}
impl<'coding, ValueType, D: TreeDegree> ExactSizeIterator for ReversedCodesIterator<'coding, ValueType, D> {
#[inline] fn len(&self) -> usize { self.0.len() }
}
impl<'coding, ValueType, D: TreeDegree> Iterator for ReversedCodesIterator<'coding, ValueType, D> {
type Item = (&'coding ValueType, Code);
#[inline] fn next(&mut self) -> Option<Self::Item> {
let mut result = self.0.next()?;
self.0.level_iterator.coding.reverse_code(&mut result.1);
Some(result)
}
#[inline] fn size_hint(&self) -> (usize, Option<usize>) {
let len = self.len();
(len, Some(len))
}
}