mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-05-17 13:24:49 -07:00
vecs: part 11
This commit is contained in:
21
crates/brk_vecs/src/variants/computed/computation.rs
Normal file
21
crates/brk_vecs/src/variants/computed/computation.rs
Normal file
@@ -0,0 +1,21 @@
|
||||
use clap_derive::ValueEnum;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
#[derive(
|
||||
Default, Debug, PartialEq, PartialOrd, Ord, Eq, Clone, Copy, Serialize, Deserialize, ValueEnum,
|
||||
)]
|
||||
pub enum Computation {
|
||||
Eager,
|
||||
#[default]
|
||||
Lazy,
|
||||
}
|
||||
|
||||
impl Computation {
|
||||
pub fn eager(&self) -> bool {
|
||||
*self == Self::Eager
|
||||
}
|
||||
|
||||
pub fn lazy(&self) -> bool {
|
||||
*self == Self::Lazy
|
||||
}
|
||||
}
|
||||
382
crates/brk_vecs/src/variants/computed/mod.rs
Normal file
382
crates/brk_vecs/src/variants/computed/mod.rs
Normal file
@@ -0,0 +1,382 @@
|
||||
use std::{borrow::Cow, sync::Arc};
|
||||
|
||||
use brk_core::{Result, StoredPhantom, Version};
|
||||
use brk_exit::Exit;
|
||||
|
||||
use crate::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyVec, BaseVecIterator, BoxedAnyIterableVec,
|
||||
BoxedVecIterator, CollectableVec, File, Format, StoredIndex, StoredType,
|
||||
};
|
||||
|
||||
use super::{
|
||||
ComputeFrom1, ComputeFrom2, ComputeFrom3, EagerVec, LazyVecFrom1, LazyVecFrom1Iterator,
|
||||
LazyVecFrom2, LazyVecFrom2Iterator, LazyVecFrom3, LazyVecFrom3Iterator, StoredVecIterator,
|
||||
};
|
||||
|
||||
mod computation;
|
||||
|
||||
pub use computation::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum Dependencies<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
S3T: Clone,
|
||||
{
|
||||
From1(BoxedAnyIterableVec<S1I, S1T>, ComputeFrom1<I, T, S1I, S1T>),
|
||||
From2(
|
||||
(BoxedAnyIterableVec<S1I, S1T>, BoxedAnyIterableVec<S2I, S2T>),
|
||||
ComputeFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
),
|
||||
From3(
|
||||
(
|
||||
BoxedAnyIterableVec<S1I, S1T>,
|
||||
BoxedAnyIterableVec<S2I, S2T>,
|
||||
BoxedAnyIterableVec<S3I, S3T>,
|
||||
),
|
||||
ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
),
|
||||
}
|
||||
|
||||
pub type ComputedVecFrom1<I, T, S1I, S1T> =
|
||||
ComputedVec<I, T, S1I, S1T, StoredPhantom, StoredPhantom, StoredPhantom, StoredPhantom>;
|
||||
pub type ComputedVecFrom2<I, T, S1I, S1T, S2I, S2T> =
|
||||
ComputedVec<I, T, S1I, S1T, S2I, S2T, StoredPhantom, StoredPhantom>;
|
||||
pub type ComputedVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T> =
|
||||
ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
S3T: Clone,
|
||||
{
|
||||
Eager {
|
||||
vec: EagerVec<I, T>,
|
||||
deps: Dependencies<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
},
|
||||
LazyFrom1(LazyVecFrom1<I, T, S1I, S1T>),
|
||||
LazyFrom2(LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>),
|
||||
LazyFrom3(LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>),
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
pub fn forced_import_or_init_from_1(
|
||||
computation: Computation,
|
||||
file: &Arc<File>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
format: Format,
|
||||
source: BoxedAnyIterableVec<S1I, S1T>,
|
||||
compute: ComputeFrom1<I, T, S1I, S1T>,
|
||||
) -> Result<Self> {
|
||||
Ok(match computation {
|
||||
Computation::Eager => Self::Eager {
|
||||
vec: EagerVec::forced_import(file, name, version, format)?,
|
||||
deps: Dependencies::From1(source, compute),
|
||||
},
|
||||
Computation::Lazy => {
|
||||
Self::LazyFrom1(LazyVecFrom1::init(name, version, source, compute))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn forced_import_or_init_from_2(
|
||||
computation: Computation,
|
||||
file: &Arc<File>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
format: Format,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
compute: ComputeFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
) -> Result<Self> {
|
||||
Ok(match computation {
|
||||
Computation::Eager => Self::Eager {
|
||||
vec: EagerVec::forced_import(file, name, version, format)?,
|
||||
deps: Dependencies::From2((source1, source2), compute),
|
||||
},
|
||||
Computation::Lazy => {
|
||||
Self::LazyFrom2(LazyVecFrom2::init(name, version, source1, source2, compute))
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn forced_import_or_init_from_3(
|
||||
computation: Computation,
|
||||
file: &Arc<File>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
format: Format,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
source3: BoxedAnyIterableVec<S3I, S3T>,
|
||||
compute: ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
) -> Result<Self> {
|
||||
Ok(match computation {
|
||||
Computation::Eager => Self::Eager {
|
||||
vec: EagerVec::forced_import(file, name, version, format)?,
|
||||
deps: Dependencies::From3((source1, source2, source3), compute),
|
||||
},
|
||||
Computation::Lazy => Self::LazyFrom3(LazyVecFrom3::init(
|
||||
name, version, source1, source2, source3, compute,
|
||||
)),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute_if_necessary<T2>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
len_source: &impl AnyIterableVec<I, T2>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let (vec, dependencies) = if let ComputedVec::Eager {
|
||||
vec,
|
||||
deps: dependencies,
|
||||
} = self
|
||||
{
|
||||
(vec, dependencies)
|
||||
} else {
|
||||
return Ok(());
|
||||
};
|
||||
|
||||
let len = len_source.len();
|
||||
|
||||
match dependencies {
|
||||
Dependencies::From1(source, compute) => {
|
||||
let version = source.version();
|
||||
let mut iter = source.iter();
|
||||
let t = |i: I| compute(i, &mut *iter).map(|v| (i, v)).unwrap();
|
||||
vec.compute_to(max_from, len, version, t, exit)
|
||||
}
|
||||
Dependencies::From2((source1, source2), compute) => {
|
||||
let version = source1.version() + source2.version();
|
||||
let mut iter1 = source1.iter();
|
||||
let mut iter2 = source2.iter();
|
||||
let t = |i: I| {
|
||||
compute(i, &mut *iter1, &mut *iter2)
|
||||
.map(|v| (i, v))
|
||||
.unwrap()
|
||||
};
|
||||
vec.compute_to(max_from, len, version, t, exit)
|
||||
}
|
||||
Dependencies::From3((source1, source2, source3), compute) => {
|
||||
let version = source1.version() + source2.version() + source3.version();
|
||||
let mut iter1 = source1.iter();
|
||||
let mut iter2 = source2.iter();
|
||||
let mut iter3 = source3.iter();
|
||||
let t = |i: I| {
|
||||
compute(i, &mut *iter1, &mut *iter2, &mut *iter3)
|
||||
.map(|v| (i, v))
|
||||
.unwrap()
|
||||
};
|
||||
vec.compute_to(max_from, len, version, t, exit)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyVec for ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn version(&self) -> Version {
|
||||
match self {
|
||||
ComputedVec::Eager { vec, .. } => vec.version(),
|
||||
ComputedVec::LazyFrom1(v) => v.version(),
|
||||
ComputedVec::LazyFrom2(v) => v.version(),
|
||||
ComputedVec::LazyFrom3(v) => v.version(),
|
||||
}
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
ComputedVec::Eager { vec, .. } => vec.name(),
|
||||
ComputedVec::LazyFrom1(v) => v.name(),
|
||||
ComputedVec::LazyFrom2(v) => v.name(),
|
||||
ComputedVec::LazyFrom3(v) => v.name(),
|
||||
}
|
||||
}
|
||||
|
||||
fn index_type_to_string(&self) -> &'static str {
|
||||
I::to_string()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
match self {
|
||||
ComputedVec::Eager { vec, .. } => vec.len(),
|
||||
ComputedVec::LazyFrom1(v) => v.len(),
|
||||
ComputedVec::LazyFrom2(v) => v.len(),
|
||||
ComputedVec::LazyFrom3(v) => v.len(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn value_type_to_size_of(&self) -> usize {
|
||||
size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
pub enum ComputedVecIterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
S3T: Clone,
|
||||
{
|
||||
Eager(StoredVecIterator<'a, I, T>),
|
||||
LazyFrom1(LazyVecFrom1Iterator<'a, I, T, S1I, S1T>),
|
||||
LazyFrom2(LazyVecFrom2Iterator<'a, I, T, S1I, S1T, S2I, S2T>),
|
||||
LazyFrom3(LazyVecFrom3Iterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>),
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> Iterator
|
||||
for ComputedVecIterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
match self {
|
||||
Self::Eager(i) => i.next(),
|
||||
Self::LazyFrom1(i) => i.next(),
|
||||
Self::LazyFrom2(i) => i.next(),
|
||||
Self::LazyFrom3(i) => i.next(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> BaseVecIterator
|
||||
for ComputedVecIterator<'_, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
#[inline]
|
||||
fn mut_index(&mut self) -> &mut usize {
|
||||
match self {
|
||||
Self::Eager(i) => i.mut_index(),
|
||||
Self::LazyFrom1(i) => i.mut_index(),
|
||||
Self::LazyFrom2(i) => i.mut_index(),
|
||||
Self::LazyFrom3(i) => i.mut_index(),
|
||||
}
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
match self {
|
||||
Self::Eager(i) => i.len(),
|
||||
Self::LazyFrom1(i) => i.len(),
|
||||
Self::LazyFrom2(i) => i.len(),
|
||||
Self::LazyFrom3(i) => i.len(),
|
||||
}
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
match self {
|
||||
Self::Eager(i) => i.name(),
|
||||
Self::LazyFrom1(i) => i.name(),
|
||||
Self::LazyFrom2(i) => i.name(),
|
||||
Self::LazyFrom3(i) => i.name(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> IntoIterator
|
||||
for &'a ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
type IntoIter = ComputedVecIterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
match self {
|
||||
ComputedVec::Eager { vec, .. } => ComputedVecIterator::Eager(vec.into_iter()),
|
||||
ComputedVec::LazyFrom1(v) => ComputedVecIterator::LazyFrom1(v.into_iter()),
|
||||
ComputedVec::LazyFrom2(v) => ComputedVecIterator::LazyFrom2(v.into_iter()),
|
||||
ComputedVec::LazyFrom3(v) => ComputedVecIterator::LazyFrom3(v.into_iter()),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyIterableVec<I, T>
|
||||
for ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn boxed_iter<'a>(&'a self) -> BoxedVecIterator<'a, I, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
Box::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyCollectableVec
|
||||
for ComputedVec<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn collect_range_serde_json(
|
||||
&self,
|
||||
from: Option<usize>,
|
||||
to: Option<usize>,
|
||||
) -> Result<Vec<serde_json::Value>> {
|
||||
CollectableVec::collect_range_serde_json(self, from, to)
|
||||
}
|
||||
}
|
||||
1316
crates/brk_vecs/src/variants/eager.rs
Normal file
1316
crates/brk_vecs/src/variants/eager.rs
Normal file
File diff suppressed because it is too large
Load Diff
185
crates/brk_vecs/src/variants/lazy/lazy1.rs
Normal file
185
crates/brk_vecs/src/variants/lazy/lazy1.rs
Normal file
@@ -0,0 +1,185 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use brk_core::{Result, Version};
|
||||
|
||||
use crate::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyVec, BaseVecIterator, BoxedAnyIterableVec,
|
||||
BoxedVecIterator, CollectableVec, StoredIndex, StoredType,
|
||||
};
|
||||
|
||||
pub type ComputeFrom1<I, T, S1I, S1T> =
|
||||
for<'a> fn(I, &mut dyn BaseVecIterator<Item = (S1I, Cow<'a, S1T>)>) -> Option<T>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
S1T: Clone,
|
||||
{
|
||||
name: String,
|
||||
version: Version,
|
||||
source: BoxedAnyIterableVec<S1I, S1T>,
|
||||
compute: ComputeFrom1<I, T, S1I, S1T>,
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T> LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
pub fn init(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source: BoxedAnyIterableVec<S1I, S1T>,
|
||||
compute: ComputeFrom1<I, T, S1I, S1T>,
|
||||
) -> Self {
|
||||
if I::to_string() != S1I::to_string() {
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
version,
|
||||
source,
|
||||
compute,
|
||||
}
|
||||
}
|
||||
|
||||
fn version(&self) -> Version {
|
||||
self.version
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LazyVecFrom1Iterator<'a, I, T, S1I, S1T>
|
||||
where
|
||||
S1T: Clone,
|
||||
{
|
||||
lazy: &'a LazyVecFrom1<I, T, S1I, S1T>,
|
||||
source: BoxedVecIterator<'a, S1I, S1T>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T> Iterator for LazyVecFrom1Iterator<'a, I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.index >= self.len() {
|
||||
return None;
|
||||
}
|
||||
let index = I::from(self.index);
|
||||
let opt = (self.lazy.compute)(index, &mut *self.source).map(|v| (index, Cow::Owned(v)));
|
||||
if opt.is_some() {
|
||||
self.index += 1;
|
||||
}
|
||||
opt
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T> BaseVecIterator for LazyVecFrom1Iterator<'_, I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
#[inline]
|
||||
fn mut_index(&mut self) -> &mut usize {
|
||||
&mut self.index
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
self.source.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
self.source.name()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T> IntoIterator for &'a LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
type IntoIter = LazyVecFrom1Iterator<'a, I, T, S1I, S1T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
LazyVecFrom1Iterator {
|
||||
lazy: self,
|
||||
source: self.source.iter(),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T> AnyVec for LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
fn version(&self) -> Version {
|
||||
self.version()
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
fn index_type_to_string(&self) -> &'static str {
|
||||
I::to_string()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
self.source.len()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn value_type_to_size_of(&self) -> usize {
|
||||
size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T> AnyIterableVec<I, T> for LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
fn boxed_iter<'a>(&'a self) -> BoxedVecIterator<'a, I, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
Box::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T> AnyCollectableVec for LazyVecFrom1<I, T, S1I, S1T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
{
|
||||
fn collect_range_serde_json(
|
||||
&self,
|
||||
from: Option<usize>,
|
||||
to: Option<usize>,
|
||||
) -> Result<Vec<serde_json::Value>> {
|
||||
CollectableVec::collect_range_serde_json(self, from, to)
|
||||
}
|
||||
}
|
||||
236
crates/brk_vecs/src/variants/lazy/lazy2.rs
Normal file
236
crates/brk_vecs/src/variants/lazy/lazy2.rs
Normal file
@@ -0,0 +1,236 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use brk_core::{Result, Version};
|
||||
|
||||
use crate::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyVec, BaseVecIterator, BoxedAnyIterableVec,
|
||||
BoxedVecIterator, CollectableVec, StoredIndex, StoredType,
|
||||
};
|
||||
|
||||
pub type ComputeFrom2<I, T, S1I, S1T, S2I, S2T> = for<'a> fn(
|
||||
I,
|
||||
&mut dyn BaseVecIterator<Item = (S1I, Cow<'a, S1T>)>,
|
||||
&mut dyn BaseVecIterator<Item = (S2I, Cow<'a, S2T>)>,
|
||||
) -> Option<T>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
{
|
||||
name: String,
|
||||
version: Version,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
compute: ComputeFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T> LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
pub fn init(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
compute: ComputeFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
) -> Self {
|
||||
if ([
|
||||
source1.index_type_to_string(),
|
||||
source2.index_type_to_string(),
|
||||
])
|
||||
.into_iter()
|
||||
.filter(|t| *t == I::to_string())
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("At least one should have same index");
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
version,
|
||||
source1,
|
||||
source2,
|
||||
compute,
|
||||
}
|
||||
}
|
||||
|
||||
fn version(&self) -> Version {
|
||||
self.version
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LazyVecFrom2Iterator<'a, I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
{
|
||||
lazy: &'a LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>,
|
||||
source1: BoxedVecIterator<'a, S1I, S1T>,
|
||||
source2: BoxedVecIterator<'a, S2I, S2T>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T> Iterator for LazyVecFrom2Iterator<'a, I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let index = I::from(self.index);
|
||||
let opt = (self.lazy.compute)(index, &mut *self.source1, &mut *self.source2)
|
||||
.map(|v| (index, Cow::Owned(v)));
|
||||
if opt.is_some() {
|
||||
self.index += 1;
|
||||
}
|
||||
opt
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T> BaseVecIterator
|
||||
for LazyVecFrom2Iterator<'_, I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
#[inline]
|
||||
fn mut_index(&mut self) -> &mut usize {
|
||||
&mut self.index
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
self.source1.name()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T> IntoIterator for &'a LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
type IntoIter = LazyVecFrom2Iterator<'a, I, T, S1I, S1T, S2I, S2T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
LazyVecFrom2Iterator {
|
||||
lazy: self,
|
||||
source1: self.source1.iter(),
|
||||
source2: self.source2.iter(),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T> AnyVec for LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
fn version(&self) -> Version {
|
||||
self.version()
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
fn index_type_to_string(&self) -> &'static str {
|
||||
I::to_string()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn value_type_to_size_of(&self) -> usize {
|
||||
size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T> AnyIterableVec<I, T> for LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
fn boxed_iter<'a>(&'a self) -> BoxedVecIterator<'a, I, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
Box::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T> AnyCollectableVec for LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
{
|
||||
fn collect_range_serde_json(
|
||||
&self,
|
||||
from: Option<usize>,
|
||||
to: Option<usize>,
|
||||
) -> Result<Vec<serde_json::Value>> {
|
||||
CollectableVec::collect_range_serde_json(self, from, to)
|
||||
}
|
||||
}
|
||||
278
crates/brk_vecs/src/variants/lazy/lazy3.rs
Normal file
278
crates/brk_vecs/src/variants/lazy/lazy3.rs
Normal file
@@ -0,0 +1,278 @@
|
||||
use std::borrow::Cow;
|
||||
|
||||
use brk_core::{Result, Version};
|
||||
|
||||
use crate::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyVec, BaseVecIterator, BoxedAnyIterableVec,
|
||||
BoxedVecIterator, CollectableVec, StoredIndex, StoredType,
|
||||
};
|
||||
|
||||
pub type ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T> = for<'a> fn(
|
||||
I,
|
||||
&mut dyn BaseVecIterator<Item = (S1I, Cow<'a, S1T>)>,
|
||||
&mut dyn BaseVecIterator<Item = (S2I, Cow<'a, S2T>)>,
|
||||
&mut dyn BaseVecIterator<Item = (S3I, Cow<'a, S3T>)>,
|
||||
) -> Option<T>;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
S3T: Clone,
|
||||
{
|
||||
name: String,
|
||||
version: Version,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
source3: BoxedAnyIterableVec<S3I, S3T>,
|
||||
compute: ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
pub fn init(
|
||||
name: &str,
|
||||
version: Version,
|
||||
source1: BoxedAnyIterableVec<S1I, S1T>,
|
||||
source2: BoxedAnyIterableVec<S2I, S2T>,
|
||||
source3: BoxedAnyIterableVec<S3I, S3T>,
|
||||
compute: ComputeFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
) -> Self {
|
||||
if ([
|
||||
source1.index_type_to_string(),
|
||||
source2.index_type_to_string(),
|
||||
source3.index_type_to_string(),
|
||||
])
|
||||
.into_iter()
|
||||
.filter(|t| *t == I::to_string())
|
||||
.count()
|
||||
== 0
|
||||
{
|
||||
panic!("At least one should have same index");
|
||||
}
|
||||
|
||||
Self {
|
||||
name: name.to_string(),
|
||||
version,
|
||||
source1,
|
||||
source2,
|
||||
source3,
|
||||
compute,
|
||||
}
|
||||
}
|
||||
|
||||
fn version(&self) -> Version {
|
||||
self.version
|
||||
}
|
||||
}
|
||||
|
||||
pub struct LazyVecFrom3Iterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
S1T: Clone,
|
||||
S2T: Clone,
|
||||
S3T: Clone,
|
||||
{
|
||||
lazy: &'a LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
|
||||
source1: BoxedVecIterator<'a, S1I, S1T>,
|
||||
source2: BoxedVecIterator<'a, S2I, S2T>,
|
||||
source3: BoxedVecIterator<'a, S3I, S3T>,
|
||||
index: usize,
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> Iterator
|
||||
for LazyVecFrom3Iterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
let index = I::from(self.index);
|
||||
let opt = (self.lazy.compute)(
|
||||
index,
|
||||
&mut *self.source1,
|
||||
&mut *self.source2,
|
||||
&mut *self.source3,
|
||||
)
|
||||
.map(|v| (index, Cow::Owned(v)));
|
||||
if opt.is_some() {
|
||||
self.index += 1;
|
||||
}
|
||||
opt
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> BaseVecIterator
|
||||
for LazyVecFrom3Iterator<'_, I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
#[inline]
|
||||
fn mut_index(&mut self) -> &mut usize {
|
||||
&mut self.index
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn len(&self) -> usize {
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len3 = if self.source3.index_type_to_string() == I::to_string() {
|
||||
self.source3.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2).min(len3)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn name(&self) -> &str {
|
||||
self.source1.name()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> IntoIterator
|
||||
for &'a LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType + 'a,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
type Item = (I, Cow<'a, T>);
|
||||
type IntoIter = LazyVecFrom3Iterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
LazyVecFrom3Iterator {
|
||||
lazy: self,
|
||||
source1: self.source1.iter(),
|
||||
source2: self.source2.iter(),
|
||||
source3: self.source3.iter(),
|
||||
index: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyVec for LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn version(&self) -> Version {
|
||||
self.version()
|
||||
}
|
||||
|
||||
fn name(&self) -> &str {
|
||||
self.name.as_str()
|
||||
}
|
||||
|
||||
fn index_type_to_string(&self) -> &'static str {
|
||||
I::to_string()
|
||||
}
|
||||
|
||||
fn len(&self) -> usize {
|
||||
let len1 = if self.source1.index_type_to_string() == I::to_string() {
|
||||
self.source1.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len2 = if self.source2.index_type_to_string() == I::to_string() {
|
||||
self.source2.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
let len3 = if self.source3.index_type_to_string() == I::to_string() {
|
||||
self.source3.len()
|
||||
} else {
|
||||
usize::MAX
|
||||
};
|
||||
len1.min(len2).min(len3)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn value_type_to_size_of(&self) -> usize {
|
||||
size_of::<T>()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyIterableVec<I, T>
|
||||
for LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn boxed_iter<'a>(&'a self) -> BoxedVecIterator<'a, I, T>
|
||||
where
|
||||
T: 'a,
|
||||
{
|
||||
Box::new(self.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> AnyCollectableVec
|
||||
for LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
S1I: StoredIndex,
|
||||
S1T: StoredType,
|
||||
S2I: StoredIndex,
|
||||
S2T: StoredType,
|
||||
S3I: StoredIndex,
|
||||
S3T: StoredType,
|
||||
{
|
||||
fn collect_range_serde_json(
|
||||
&self,
|
||||
from: Option<usize>,
|
||||
to: Option<usize>,
|
||||
) -> Result<Vec<serde_json::Value>> {
|
||||
CollectableVec::collect_range_serde_json(self, from, to)
|
||||
}
|
||||
}
|
||||
7
crates/brk_vecs/src/variants/lazy/mod.rs
Normal file
7
crates/brk_vecs/src/variants/lazy/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
mod lazy1;
|
||||
mod lazy2;
|
||||
mod lazy3;
|
||||
|
||||
pub use lazy1::*;
|
||||
pub use lazy2::*;
|
||||
pub use lazy3::*;
|
||||
Reference in New Issue
Block a user