use std::{marker::PhantomData, sync::Arc};
mod any_vec;
mod avg;
mod change;
mod clone;
mod op;
mod rate;
mod readable;
mod sub;
mod typed;
pub use avg::DeltaAvg;
pub use change::DeltaChange;
pub use op::DeltaOp;
pub use rate::DeltaRate;
pub use sub::DeltaSub;
use crate::{ReadableBoxedVec, VecIndex, VecValue, Version};
pub struct LazyDeltaVec<I, S, T, Op> {
pub(super) name: Arc<str>,
pub(super) base_version: Version,
pub(super) source: ReadableBoxedVec<I, S>,
pub(super) window_starts_version: Version,
#[allow(clippy::type_complexity)]
pub(super) window_starts: Arc<dyn Fn() -> Arc<[I]> + Send + Sync>,
pub(super) _op: PhantomData<(Op, T)>,
}
impl<I, S, T, Op> LazyDeltaVec<I, S, T, Op>
where
I: VecIndex,
S: VecValue,
T: VecValue,
Op: DeltaOp<S, T>,
{
pub fn new(
name: &str,
version: Version,
source: ReadableBoxedVec<I, S>,
window_starts_version: Version,
window_starts: impl Fn() -> Arc<[I]> + Send + Sync + 'static,
) -> Self {
Self {
name: Arc::from(name),
base_version: version,
source,
window_starts_version,
window_starts: Arc::new(window_starts),
_op: PhantomData,
}
}
#[inline]
pub(super) fn bulk_try_fold<B, E>(
&self,
from: usize,
to: usize,
starts: &[I],
init: B,
mut f: impl FnMut(B, T) -> std::result::Result<B, E>,
) -> std::result::Result<B, E> {
if from >= to {
return Ok(init);
}
let read_from = Op::ago_index(starts[from].to_usize())
.unwrap_or(0)
.min(from);
let source_data = self.source.collect_range_dyn(read_from, to);
let mut acc = init;
for i in from..to {
let start = starts[i].to_usize();
let current = source_data[i - read_from].clone();
let ago = match Op::ago_index(start) {
Some(idx) => source_data[idx - read_from].clone(),
None => Op::ago_default(),
};
acc = f(acc, Op::combine(current, ago, Op::count(i, start)))?;
}
Ok(acc)
}
#[inline]
pub(super) fn bulk_for_each(
&self,
from: usize,
to: usize,
starts: &[I],
mut each: impl FnMut(T),
) {
self.bulk_try_fold(from, to, starts, (), |(), v| {
each(v);
Ok::<_, std::convert::Infallible>(())
})
.unwrap_or_else(|e: std::convert::Infallible| match e {})
}
}