use std::ops::AddAssign;
use crate::{AnyVec, VecIndex, VecValue, cursor::Cursor};
pub const READ_CHUNK_SIZE: usize = 4096;
pub trait ReadableVec<I: VecIndex, T: VecValue>: AnyVec {
fn read_into_at(&self, from: usize, to: usize, buf: &mut Vec<T>);
fn for_each_range_dyn_at(&self, from: usize, to: usize, f: &mut dyn FnMut(T));
fn fold_range_at<B, F: FnMut(B, T) -> B>(&self, from: usize, to: usize, init: B, f: F) -> B
where
Self: Sized;
fn try_fold_range_at<B, E, F: FnMut(B, T) -> std::result::Result<B, E>>(
&self,
from: usize,
to: usize,
init: B,
f: F,
) -> std::result::Result<B, E>
where
Self: Sized;
#[inline]
fn read_into(&self, from: I, to: I, buf: &mut Vec<T>) {
self.read_into_at(from.to_usize(), to.to_usize(), buf)
}
#[inline]
fn cursor(&self) -> Cursor<'_, I, T, Self>
where
Self: Sized,
{
Cursor::new(self)
}
#[inline]
fn for_each_range_dyn(&self, from: I, to: I, f: &mut dyn FnMut(T)) {
self.for_each_range_dyn_at(from.to_usize(), to.to_usize(), f)
}
#[inline]
fn fold_range<B, F: FnMut(B, T) -> B>(&self, from: I, to: I, init: B, f: F) -> B
where
Self: Sized,
{
self.fold_range_at(from.to_usize(), to.to_usize(), init, f)
}
#[inline]
fn try_fold_range<B, E, F: FnMut(B, T) -> std::result::Result<B, E>>(
&self,
from: I,
to: I,
init: B,
f: F,
) -> std::result::Result<B, E>
where
Self: Sized,
{
self.try_fold_range_at(from.to_usize(), to.to_usize(), init, f)
}
#[inline]
fn for_each_range<F: FnMut(T)>(&self, from: I, to: I, f: F)
where
Self: Sized,
{
self.for_each_range_at(from.to_usize(), to.to_usize(), f)
}
#[inline]
fn collect_range(&self, from: I, to: I) -> Vec<T>
where
Self: Sized,
{
self.collect_range_at(from.to_usize(), to.to_usize())
}
#[inline]
fn collect_one(&self, index: I) -> Option<T> {
self.collect_one_at(index.to_usize())
}
#[inline]
fn min(&self, from: I, to: I) -> Option<T>
where
Self: Sized,
T: PartialOrd,
{
self.min_at(from.to_usize(), to.to_usize())
}
#[inline]
fn max(&self, from: I, to: I) -> Option<T>
where
Self: Sized,
T: PartialOrd,
{
self.max_at(from.to_usize(), to.to_usize())
}
#[inline]
fn sum(&self, from: I, to: I) -> Option<T>
where
Self: Sized,
T: AddAssign + From<u8>,
{
self.sum_at(from.to_usize(), to.to_usize())
}
#[inline]
fn for_each_range_at<F: FnMut(T)>(&self, from: usize, to: usize, mut f: F)
where
Self: Sized,
{
self.fold_range_at(from, to, (), |(), v| f(v));
}
#[inline]
fn try_for_each_range_at<E, F: FnMut(T) -> std::result::Result<(), E>>(
&self,
from: usize,
to: usize,
mut f: F,
) -> std::result::Result<(), E>
where
Self: Sized,
{
self.try_fold_range_at(from, to, (), |(), v| f(v))
}
#[inline]
fn for_each<F: FnMut(T)>(&self, f: F)
where
Self: Sized,
{
self.for_each_range_at(0, self.len(), f);
}
#[inline]
fn fold<B, F: FnMut(B, T) -> B>(&self, init: B, f: F) -> B
where
Self: Sized,
{
self.fold_range_at(0, self.len(), init, f)
}
#[inline]
fn collect_range_at(&self, from: usize, to: usize) -> Vec<T>
where
Self: Sized,
{
self.collect_range_dyn(from, to)
}
#[inline]
fn collect_range_into_at(&self, from: usize, to: usize, buf: &mut Vec<T>) {
buf.clear();
self.read_into_at(from, to, buf);
}
#[inline]
fn collect_range_dyn(&self, from: usize, to: usize) -> Vec<T> {
let mut buf = Vec::with_capacity(to.saturating_sub(from));
self.read_into_at(from, to, &mut buf);
buf
}
#[inline]
fn collect(&self) -> Vec<T>
where
Self: Sized,
{
self.collect_range_at(0, self.len())
}
#[inline(always)]
fn collect_one_at(&self, index: usize) -> Option<T> {
if index >= self.len() {
return None;
}
let mut result = None;
self.for_each_range_dyn_at(index, index + 1, &mut |v| result = Some(v));
result
}
#[inline]
fn collect_first(&self) -> Option<T> {
self.collect_one_at(0)
}
#[inline]
fn collect_last(&self) -> Option<T> {
let len = self.len();
if len > 0 {
self.collect_one_at(len - 1)
} else {
None
}
}
#[inline]
fn collect_signed_range(&self, from: Option<i64>, to: Option<i64>) -> Vec<T>
where
Self: Sized,
{
let from = from.map(|i| self.i64_to_usize(i)).unwrap_or(0);
let to = to
.map(|i| self.i64_to_usize(i))
.unwrap_or_else(|| self.len());
self.collect_range_at(from, to)
}
#[inline]
fn collect_signed_range_dyn(&self, from: Option<i64>, to: Option<i64>) -> Vec<T> {
let from = from.map(|i| self.i64_to_usize(i)).unwrap_or(0);
let to = to
.map(|i| self.i64_to_usize(i))
.unwrap_or_else(|| self.len());
self.collect_range_dyn(from, to)
}
#[inline]
fn collect_dyn(&self) -> Vec<T> {
self.collect_range_dyn(0, self.len())
}
fn read_sorted_into_at(&self, indices: &[usize], out: &mut Vec<T>) {
let mut cursor = Cursor::new(self);
out.reserve(indices.len());
indices.iter().for_each(|&i| {
if let Some(v) = cursor.get(i) {
out.push(v);
}
});
}
#[inline]
fn read_sorted_at(&self, indices: &[usize]) -> Vec<T> {
let mut out = Vec::with_capacity(indices.len());
self.read_sorted_into_at(indices, &mut out);
out
}
#[inline]
fn read_sorted_into(&self, indices: &[I], out: &mut Vec<T>) {
let raw: Vec<usize> = indices.iter().map(|i| i.to_usize()).collect();
self.read_sorted_into_at(&raw, out);
}
#[inline]
fn read_sorted(&self, indices: &[I]) -> Vec<T> {
let mut out = Vec::with_capacity(indices.len());
self.read_sorted_into(indices, &mut out);
out
}
#[inline]
fn min_at(&self, from: usize, to: usize) -> Option<T>
where
Self: Sized,
T: PartialOrd,
{
self.fold_range_at(from, to, None, |acc: Option<T>, v| match acc {
Some(cur) if cur <= v => Some(cur),
_ => Some(v),
})
}
#[inline]
fn min_dyn(&self, from: usize, to: usize) -> Option<T>
where
T: PartialOrd,
{
let mut result: Option<T> = None;
self.for_each_range_dyn_at(from, to, &mut |v| match &result {
Some(cur) if *cur <= v => {}
_ => result = Some(v),
});
result
}
#[inline]
fn max_at(&self, from: usize, to: usize) -> Option<T>
where
Self: Sized,
T: PartialOrd,
{
self.fold_range_at(from, to, None, |acc: Option<T>, v| match acc {
Some(cur) if cur >= v => Some(cur),
_ => Some(v),
})
}
#[inline]
fn max_dyn(&self, from: usize, to: usize) -> Option<T>
where
T: PartialOrd,
{
let mut result: Option<T> = None;
self.for_each_range_dyn_at(from, to, &mut |v| match &result {
Some(cur) if *cur >= v => {}
_ => result = Some(v),
});
result
}
#[inline]
fn sum_at(&self, from: usize, to: usize) -> Option<T>
where
Self: Sized,
T: AddAssign + From<u8>,
{
let mut has_values = false;
let result = self.fold_range_at(from, to, T::from(0), |mut acc, v| {
acc += v;
has_values = true;
acc
});
has_values.then_some(result)
}
#[inline]
fn sum_dyn(&self, from: usize, to: usize) -> Option<T>
where
T: AddAssign + From<u8>,
{
let mut result = T::from(0);
let mut has_values = false;
self.for_each_range_dyn_at(from, to, &mut |v| {
result += v;
has_values = true;
});
has_values.then_some(result)
}
}
pub trait ReadableCloneableVec<I: VecIndex, T: VecValue>: ReadableVec<I, T> {
fn read_only_boxed_clone(&self) -> Box<dyn ReadableCloneableVec<I, T>>;
}
impl<I: VecIndex, T: VecValue, U> ReadableCloneableVec<I, T> for U
where
U: 'static + ReadableVec<I, T> + Clone,
{
fn read_only_boxed_clone(&self) -> Box<dyn ReadableCloneableVec<I, T>> {
Box::new(self.clone())
}
}
impl<I: VecIndex, T: VecValue> Clone for Box<dyn ReadableCloneableVec<I, T>> {
fn clone(&self) -> Self {
self.read_only_boxed_clone()
}
}
pub type ReadableBoxedVec<I, T> = Box<dyn ReadableCloneableVec<I, T>>;