use super::Cell;
use std::iter::Copied;
use std::ops::Range;
use triomphe::Arc;
pub type SliceIter<'a> = Copied<std::slice::Iter<'a, u64>>;
pub type VecIter = std::vec::IntoIter<u64>;
#[derive(Debug, Clone)]
pub struct ArcIter {
inner: Arc<[u64]>,
offset: usize,
}
impl ArcIter {
pub const fn new(inner: Arc<[u64]>) -> Self {
Self { inner, offset: 0 }
}
}
impl Iterator for ArcIter {
type Item = u64;
fn next(&mut self) -> Option<Self::Item> {
self.inner
.get(self.offset)
.copied()
.inspect(|_| self.offset += 1)
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
if let Some(&v) = self.inner.get(self.offset + n) {
self.offset += n;
Some(v)
} else {
self.offset = self.inner.len();
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.inner.len() - self.offset;
(n, Some(n))
}
}
impl ExactSizeIterator for ArcIter {
fn len(&self) -> usize {
self.inner.len() - self.offset
}
}
#[derive(Debug, Clone)]
pub struct CellIter<I> {
raw_val_iter: I,
max_depth: u8,
}
impl<I> CellIter<I> {
pub(super) const fn new(max_depth: u8, raw_val_iter: I) -> Self {
Self {
max_depth,
raw_val_iter,
}
}
}
impl<I: Iterator<Item = u64>> Iterator for CellIter<I> {
type Item = Cell;
fn next(&mut self) -> Option<Self::Item> {
self.raw_val_iter
.next()
.map(|raw| Cell::decode(raw, self.max_depth))
}
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.raw_val_iter
.nth(n)
.map(|raw| Cell::decode(raw, self.max_depth))
}
fn size_hint(&self) -> (usize, Option<usize>) {
self.raw_val_iter.size_hint()
}
}
impl<I: ExactSizeIterator<Item = u64>> ExactSizeIterator for CellIter<I> {
fn len(&self) -> usize {
self.raw_val_iter.len()
}
}
impl<I: DoubleEndedIterator<Item = u64>> DoubleEndedIterator for CellIter<I> {
fn next_back(&mut self) -> Option<Self::Item> {
self.raw_val_iter
.next_back()
.map(|raw| Cell::decode(raw, self.max_depth))
}
fn nth_back(&mut self, n: usize) -> Option<Self::Item> {
self.raw_val_iter
.nth_back(n)
.map(|raw| Cell::decode(raw, self.max_depth))
}
}
#[derive(Debug, Clone)]
pub struct FlatIter<I> {
max_depth: u8,
deep_size: usize,
raw_val_iter: I,
curr_val: Option<u64>,
curr_val_max: u64,
n_returned: usize,
}
impl<I: Iterator<Item = u64>> FlatIter<I> {
pub(super) fn new(max_depth: u8, deep_size: usize, raw_val_iter: I) -> Self {
let mut flat_iter = Self {
max_depth,
deep_size,
raw_val_iter,
curr_val: None,
curr_val_max: 0_u64,
n_returned: 0_usize,
};
flat_iter.next_cell();
flat_iter
}
pub fn deep_size(&self) -> usize {
self.deep_size
}
pub fn depth(&self) -> u8 {
self.max_depth
}
fn next_cell(&mut self) -> Option<u64> {
match self.raw_val_iter.next() {
None => self.curr_val.take(),
Some(raw_value) => {
let delta_depth = ((raw_value >> 1).trailing_zeros() >> 1) as u8;
let twice_delta_depth = delta_depth << 1;
let hash = raw_value >> (2 + twice_delta_depth);
let val = hash << twice_delta_depth;
self.curr_val_max = val | ((1_u64 << twice_delta_depth) - 1_u64);
self.curr_val.replace(val)
}
}
}
}
impl<I: Iterator<Item = u64>> Iterator for FlatIter<I> {
type Item = u64;
fn next(&mut self) -> Option<u64> {
if let Some(val) = self.curr_val {
self.n_returned += 1;
if val < self.curr_val_max {
self.curr_val.replace(val + 1)
} else {
self.next_cell()
}
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.deep_size - self.n_returned;
(n, Some(n))
}
}
impl<I: Iterator<Item = u64>> ExactSizeIterator for FlatIter<I> {
fn len(&self) -> usize {
self.deep_size - self.n_returned
}
}
#[derive(Debug, Clone)]
pub struct FlatCellIter<I> {
max_depth: u8,
deep_size: usize,
raw_val_iter: I,
curr_val: Option<Cell>,
curr_val_max: u64,
n_returned: usize,
}
impl<I: Iterator<Item = u64>> FlatCellIter<I> {
pub(super) fn new(max_depth: u8, deep_size: usize, raw_val_iter: I) -> Self {
let mut flat_iter = Self {
max_depth,
deep_size,
raw_val_iter,
curr_val: None,
curr_val_max: 0_u64,
n_returned: 0_usize,
};
flat_iter.next_cell();
flat_iter
}
pub fn deep_size(&self) -> usize {
self.deep_size
}
pub fn depth(&self) -> u8 {
self.max_depth
}
fn next_cell(&mut self) -> Option<Cell> {
match self.raw_val_iter.next() {
None => self.curr_val.take(),
Some(raw_value) => {
let delta_depth = ((raw_value >> 1).trailing_zeros() >> 1) as u8;
let twice_delta_depth = delta_depth << 1;
let hash = raw_value >> (2 + twice_delta_depth);
let val = hash << twice_delta_depth;
self.curr_val_max = val | ((1_u64 << twice_delta_depth) - 1_u64);
self.curr_val.replace(Cell {
raw_value,
depth: self.max_depth,
hash: val,
is_full: (raw_value & 1_u64) == 1_u64,
})
}
}
}
}
impl<I: Iterator<Item = u64>> Iterator for FlatCellIter<I> {
type Item = Cell;
fn next(&mut self) -> Option<Cell> {
if let Some(cell) = &self.curr_val {
self.n_returned += 1;
if cell.hash < self.curr_val_max {
let new_cell = Cell {
raw_value: cell.raw_value,
depth: self.max_depth,
hash: cell.hash + 1,
is_full: cell.is_full,
};
self.curr_val.replace(new_cell)
} else {
self.next_cell()
}
} else {
None
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
let n = self.deep_size - self.n_returned;
(n, Some(n))
}
}
impl<I: Iterator<Item = u64>> ExactSizeIterator for FlatCellIter<I> {
fn len(&self) -> usize {
self.deep_size - self.n_returned
}
}
#[derive(Debug, Clone)]
pub struct RangeIter<I> {
max_depth: u8,
raw_val_iter: I,
prev_min: u64,
prev_max: u64,
}
impl<I> RangeIter<I> {
pub const fn new(max_depth: u8, raw_val_iter: I) -> Self {
Self {
max_depth,
raw_val_iter,
prev_min: 0,
prev_max: 0,
}
}
}
impl<I: Iterator<Item = u64>> Iterator for RangeIter<I> {
type Item = Range<u64>;
fn next(&mut self) -> Option<Self::Item> {
self.raw_val_iter
.find_map(|raw| {
let cell = Cell::decode(raw, self.max_depth);
let mut res = None;
if cell.depth < self.max_depth {
let range = crate::to_range(cell.hash, self.max_depth - cell.depth);
if range.start != self.prev_max {
if self.prev_min != self.prev_max {
res = Some(self.prev_min..self.prev_max);
}
self.prev_min = range.start;
}
self.prev_max = range.end;
} else if cell.hash == self.prev_max {
self.prev_max += 1;
} else {
if self.prev_min != self.prev_max {
res = Some(self.prev_min..self.prev_max);
}
self.prev_min = cell.hash;
self.prev_max = cell.hash + 1;
}
res
})
.or_else(|| {
let res = (self.prev_min != self.prev_max).then_some(self.prev_min..self.prev_max);
self.prev_min = self.prev_max;
res
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (mut min, max) = self.raw_val_iter.size_hint();
if min == 0 && self.prev_min != self.prev_max {
min = 1;
}
(min, max.map(|v| v + 1))
}
}
#[derive(Debug, Clone)]
pub struct FlaggedRangeIter<I> {
max_depth: u8,
raw_val_iter: I,
prev_min: u64,
prev_max: u64,
prev_flag: Option<bool>,
}
impl<I> FlaggedRangeIter<I> {
pub const fn new(max_depth: u8, raw_val_iter: I) -> Self {
Self {
max_depth,
raw_val_iter,
prev_min: 0,
prev_max: 0,
prev_flag: None,
}
}
}
impl<I: Iterator<Item = u64>> Iterator for FlaggedRangeIter<I> {
type Item = (bool, Range<u64>);
fn next(&mut self) -> Option<Self::Item> {
self.raw_val_iter
.find_map(|raw| {
let cell = Cell::decode(raw, self.max_depth);
let prev_flag = self.prev_flag.get_or_insert(cell.is_full);
let mut res = None;
if cell.depth < self.max_depth {
let range = crate::to_range(cell.hash, self.max_depth - cell.depth);
if range.start == self.prev_max
&& (self.prev_max == 0 || cell.is_full == *prev_flag)
{
self.prev_max = range.end;
} else {
if self.prev_min != self.prev_max {
res = Some((*prev_flag, self.prev_min..self.prev_max));
}
self.prev_min = range.start;
self.prev_max = range.end;
*prev_flag = cell.is_full;
}
} else if cell.hash == self.prev_max && cell.is_full == *prev_flag {
self.prev_max += 1;
} else {
if self.prev_min != self.prev_max {
res = Some((*prev_flag, self.prev_min..self.prev_max));
}
self.prev_min = cell.hash;
self.prev_max = cell.hash + 1;
*prev_flag = cell.is_full;
}
res
})
.or_else(|| {
let res = (self.prev_min != self.prev_max)
.then_some((self.prev_flag.unwrap(), self.prev_min..self.prev_max));
self.prev_min = self.prev_max;
res
})
}
fn size_hint(&self) -> (usize, Option<usize>) {
let (mut min, max) = self.raw_val_iter.size_hint();
if min == 0 && self.prev_min != self.prev_max {
min = 1;
}
(min, max.map(|v| v + 1))
}
}