computer: lazy part 3

This commit is contained in:
nym21
2025-05-03 11:44:33 +02:00
parent ae0e092935
commit efa7294f59
79 changed files with 707 additions and 311 deletions

View File

@@ -14,6 +14,7 @@ mod storage;
use brk_vec::Compressed;
use log::info;
pub use storage::Computation;
use storage::{Stores, Vecs};
#[derive(Clone)]
@@ -36,11 +37,16 @@ impl Computer {
}
}
pub fn import_vecs(&mut self, indexer: &Indexer) -> color_eyre::Result<()> {
pub fn import_vecs(
&mut self,
indexer: &Indexer,
computation: Computation,
) -> color_eyre::Result<()> {
self.vecs = Some(Vecs::import(
&self.path.join("vecs/computed"),
indexer,
self.fetcher.is_some(),
computation,
self.compressed,
)?);
Ok(())

View File

@@ -223,7 +223,7 @@ impl Vecs {
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
[
vec![
self.height_to_interval.any_vec(),

View File

@@ -190,7 +190,7 @@ where
self.monthindex.any_vecs(),
self.quarterindex.any_vecs(),
self.yearindex.any_vecs(),
// self.halvingepoch.as_any_vecs(),
// self.halvingepoch.any_vecs(),
self.decadeindex.any_vecs(),
]
.concat()

View File

@@ -91,7 +91,7 @@ where
vec![self.height.any_vec()],
self.height_extra.any_vecs(),
self.difficultyepoch.any_vecs(),
// self.halvingepoch.as_any_vecs(),
// self.halvingepoch.any_vecs(),
]
.concat()
}

View File

@@ -198,7 +198,7 @@ where
self.monthindex.any_vecs(),
self.quarterindex.any_vecs(),
self.yearindex.any_vecs(),
// self.halvingepoch.as_any_vecs(),
// self.halvingepoch.any_vecs(),
self.decadeindex.any_vecs(),
]
.concat()

View File

@@ -865,7 +865,7 @@ impl Vecs {
})
}
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
vec![
self.dateindex_to_date.any_vec(),
self.dateindex_to_dateindex.any_vec(),

View File

@@ -1063,7 +1063,7 @@ impl Vecs {
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
vec![
vec![
self.dateindex_to_close_in_cents.any_vec(),

View File

@@ -113,7 +113,7 @@ impl Vecs {
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
[
self.indexes_to_difficulty.any_vecs(),
self.indexes_to_difficultyepoch.any_vecs(),

View File

@@ -30,6 +30,7 @@ impl Vecs {
path: &Path,
indexer: &Indexer,
fetch: bool,
computation: Computation,
compressed: Compressed,
) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
@@ -38,7 +39,13 @@ impl Vecs {
blocks: blocks::Vecs::forced_import(path, compressed)?,
indexes: indexes::Vecs::forced_import(path, compressed)?,
mining: mining::Vecs::forced_import(path, compressed)?,
transactions: transactions::Vecs::forced_import(path, indexer, compressed, fetch)?,
transactions: transactions::Vecs::forced_import(
path,
indexer,
computation,
compressed,
fetch,
)?,
marketprice: fetch.then(|| marketprice::Vecs::forced_import(path, compressed).unwrap()),
})
}
@@ -79,15 +86,13 @@ impl Vecs {
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
[
self.indexes.as_any_vecs(),
self.blocks.as_any_vecs(),
self.mining.as_any_vecs(),
self.transactions.as_any_vecs(),
self.marketprice
.as_ref()
.map_or(vec![], |v| v.as_any_vecs()),
self.indexes.any_vecs(),
self.blocks.any_vecs(),
self.mining.any_vecs(),
self.transactions.any_vecs(),
self.marketprice.as_ref().map_or(vec![], |v| v.any_vecs()),
]
.concat()
}

View File

@@ -9,7 +9,7 @@ use brk_parser::bitcoin;
use brk_vec::{Compressed, StoredIndex, VecIterator, Version};
use super::{
EagerVec, Indexes, LazyVec,
Computation, ComputedVec, ComputedVecFrom2, EagerVec, Indexes,
grouped::{
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromHeight,
ComputedVecsFromTxindex, StorableVecGeneatorOptions,
@@ -47,7 +47,8 @@ pub struct Vecs {
pub indexes_to_tx_vsize: ComputedVecsFromTxindex<StoredUsize>,
pub indexes_to_tx_weight: ComputedVecsFromTxindex<Weight>,
pub indexes_to_unknownoutput_count: ComputedVecsFromHeight<StoredUsize>,
pub inputindex_to_value: LazyVec<InputIndex, Sats, OutputIndex, Sats, InputIndex, OutputIndex>,
pub inputindex_to_value:
ComputedVecFrom2<InputIndex, Sats, OutputIndex, Sats, InputIndex, OutputIndex>,
pub indexes_to_input_count: ComputedVecsFromTxindex<StoredUsize>,
pub txindex_to_is_coinbase: EagerVec<TxIndex, bool>,
pub indexes_to_output_count: ComputedVecsFromTxindex<StoredUsize>,
@@ -59,6 +60,7 @@ impl Vecs {
pub fn forced_import(
path: &Path,
indexer: &Indexer,
computation: Computation,
compressed: Compressed,
compute_dollars: bool,
) -> color_eyre::Result<Self> {
@@ -110,8 +112,11 @@ impl Vecs {
.add_sum()
.add_total(),
)?,
inputindex_to_value: LazyVec::init(
inputindex_to_value: ComputedVec::forced_import_or_init_from_2(
computation,
&path.join("inputindex_to_value"),
Version::ZERO,
compressed,
indexer.vecs().outputindex_to_value.vec().clone(),
indexer.vecs().inputindex_to_outputindex.vec().clone(),
|index, outputindex_to_value_iter, inputindex_to_outputindex_iter| {
@@ -131,7 +136,7 @@ impl Vecs {
},
)
},
),
)?,
indexes_to_tx_v1: ComputedVecsFromHeight::forced_import(
path,
"tx_v1",
@@ -536,22 +541,22 @@ impl Vecs {
)?;
// let mut outputindex_to_value_iter = indexer.vecs().outputindex_to_value.iter();
// self.inputindex_to_value.compute_transform(
// starting_indexes.inputindex,
// indexer.vecs().inputindex_to_outputindex.vec(),
// |(inputindex, outputindex, ..)| {
// let value = if outputindex == OutputIndex::COINBASE {
// Sats::ZERO
// } else if let Some(value) = outputindex_to_value_iter.get(outputindex) {
// value.into_inner()
// } else {
// dbg!(inputindex, outputindex);
// panic!()
// };
// (inputindex, value)
// },
// exit,
// )?;
self.inputindex_to_value.compute_if_necessary(
starting_indexes.inputindex,
// indexer.vecs().inputindex_to_outputindex.vec(),
// |(inputindex, outputindex, ..)| {
// let value = if outputindex == OutputIndex::COINBASE {
// Sats::ZERO
// } else if let Some(value) = outputindex_to_value_iter.get(outputindex) {
// value.into_inner()
// } else {
// dbg!(inputindex, outputindex);
// panic!()
// };
// (inputindex, value)
// },
exit,
)?;
self.indexes_to_output_value.compute_all(
indexer,
@@ -881,7 +886,7 @@ impl Vecs {
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
[
vec![
self.txindex_to_is_coinbase.any_vec(),

View File

@@ -18,12 +18,8 @@ const ONE_KIB: usize = 1024;
const ONE_MIB: usize = ONE_KIB * ONE_KIB;
const MAX_CACHE_SIZE: usize = 210 * ONE_MIB;
#[derive(Debug)]
pub struct EagerVec<I, T>
where
I: StoredIndex,
T: StoredType,
{
#[derive(Debug, Clone)]
pub struct EagerVec<I, T> {
computed_version: Option<Version>,
inner: StoredVec<I, T>,
}
@@ -89,8 +85,8 @@ where
Ok(())
}
fn version(&self) -> Version {
self.inner.version()
pub fn version(&self) -> Version {
self.computed_version.unwrap()
}
pub fn len(&self) -> usize {
@@ -147,28 +143,42 @@ where
self.into_iter()
}
pub fn compute_to<F>(
&mut self,
max_from: I,
to: usize,
version: Version,
mut t: F,
exit: &Exit,
) -> Result<()>
where
F: FnMut(I) -> (I, T),
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.inner.version() + version,
)?;
let index = max_from.min(I::from(self.len()));
(index.to_usize()?..to).try_for_each(|i| {
let (i, v) = t(I::from(i));
self.forced_push_at(i, v, exit)
})?;
self.safe_flush(exit)
}
pub fn compute_range<A, F>(
&mut self,
max_from: I,
other: &StoredVec<I, A>,
mut t: F,
t: F,
exit: &Exit,
) -> Result<()>
where
A: StoredType,
F: FnMut(I) -> (I, T),
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + other.version(),
)?;
let index = max_from.min(I::from(self.len()));
(index.to_usize()?..other.len()).try_for_each(|i| {
let (i, v) = t(I::from(i));
self.forced_push_at(i, v, exit)
})?;
self.safe_flush(exit)
self.compute_to(max_from, other.len(), other.version(), t, exit)
}
pub fn compute_transform<A, B, F>(
@@ -184,7 +194,7 @@ where
F: FnMut((A, B, &Self)) -> (I, T),
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + other.version(),
Version::ZERO + self.inner.version() + other.version(),
)?;
let index = max_from.min(A::from(self.len()));
@@ -207,7 +217,7 @@ where
T: StoredIndex,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + other.version(),
Version::ZERO + self.inner.version() + other.version(),
)?;
let index = max_from.min(
@@ -241,7 +251,10 @@ where
T: StoredIndex,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + first_indexes.version() + indexes_count.version(),
Version::ZERO
+ self.inner.version()
+ first_indexes.version()
+ indexes_count.version(),
)?;
let mut indexes_count_iter = indexes_count.iter();
@@ -333,7 +346,7 @@ where
<T2 as TryInto<T>>::Error: error::Error + 'static,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + first_indexes.version(), // + last_indexes.version(),
Version::ZERO + self.inner.version() + first_indexes.version(), // + last_indexes.version(),
)?;
let mut other_iter = first_indexes.iter();
@@ -371,7 +384,10 @@ where
A: StoredIndex + StoredType,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + self_to_other.version() + other_to_self.version(),
Version::ZERO
+ self.inner.version()
+ self_to_other.version()
+ other_to_self.version(),
)?;
let mut other_to_self_iter = other_to_self.iter();
@@ -400,7 +416,10 @@ where
T2: StoredIndex + StoredType,
{
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + first_indexes.version() + indexes_count.version(),
Version::ZERO
+ self.inner.version()
+ first_indexes.version()
+ indexes_count.version(),
)?;
let mut indexes_count_iter = indexes_count.iter();
@@ -434,7 +453,7 @@ where
exit: &Exit,
) -> Result<()> {
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + sats.version(),
Version::ZERO + self.inner.version() + sats.version(),
)?;
let index = max_from.min(I::from(self.len()));
@@ -456,7 +475,7 @@ impl EagerVec<Height, Dollars> {
exit: &Exit,
) -> Result<()> {
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + bitcoin.version(),
Version::ZERO + self.inner.version() + bitcoin.version(),
)?;
let mut price_iter = price.iter();
@@ -481,7 +500,7 @@ impl EagerVec<TxIndex, Dollars> {
exit: &Exit,
) -> Result<()> {
self.validate_computed_version_or_reset_file(
Version::ZERO + self.version() + bitcoin.version(),
Version::ZERO + self.inner.version() + bitcoin.version(),
)?;
let mut i_to_height_iter = i_to_height.iter();
@@ -498,19 +517,6 @@ impl EagerVec<TxIndex, Dollars> {
}
}
impl<I, T> Clone for EagerVec<I, T>
where
I: StoredIndex,
T: StoredType,
{
fn clone(&self) -> Self {
Self {
computed_version: self.computed_version,
inner: self.inner.clone(),
}
}
}
impl<'a, I, T> IntoIterator for &'a EagerVec<I, T>
where
I: StoredIndex,

View File

@@ -0,0 +1,103 @@
use std::marker::PhantomData;
use brk_vec::{
BaseVecIterator, StoredIndex, StoredType, StoredVec, StoredVecIterator, Value, Version,
};
pub type ComputeFrom1<T, S1I, S1T> =
for<'a> fn(usize, &mut dyn BaseVecIterator<Item = (S1I, Value<'a, S1T>)>) -> Option<T>;
#[derive(Clone)]
pub struct LazyVecFrom1<I, T, S1I, S1T> {
version: Version,
source: StoredVec<S1I, S1T>,
compute: ComputeFrom1<T, S1I, S1T>,
phantom: PhantomData<I>,
}
impl<I, T, S1I, S1T> LazyVecFrom1<I, T, S1I, S1T>
where
I: StoredIndex,
T: StoredType,
S1I: StoredIndex,
S1T: StoredType,
{
pub fn init(
version: Version,
source: StoredVec<S1I, S1T>,
compute: ComputeFrom1<T, S1I, S1T>,
) -> Self {
Self {
version,
source,
compute,
phantom: PhantomData,
}
}
fn version(&self) -> Version {
self.version
}
}
pub struct LazyVecIterator<'a, I, T, S1I, S1T> {
lazy: &'a LazyVecFrom1<I, T, S1I, S1T>,
source: StoredVecIterator<'a, S1I, S1T>,
index: usize,
}
impl<'a, I, T, S1I, S1T> Iterator for LazyVecIterator<'a, I, T, S1I, S1T>
where
I: StoredIndex,
T: StoredType + 'a,
S1I: StoredIndex,
S1T: StoredType,
{
type Item = (I, Value<'a, T>);
fn next(&mut self) -> Option<Self::Item> {
let opt = (self.lazy.compute)(self.index, &mut self.lazy.source.iter())
.map(|v| (I::from(self.index), Value::Owned(v)));
if opt.is_some() {
self.index += 1;
}
opt
}
}
impl<I, T, S1I, S1T> BaseVecIterator for LazyVecIterator<'_, 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 {
todo!();
}
}
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, Value<'a, T>);
type IntoIter = LazyVecIterator<'a, I, T, S1I, S1T>;
fn into_iter(self) -> Self::IntoIter {
LazyVecIterator {
lazy: self,
source: self.source.iter(),
index: 0,
}
}
}

View File

@@ -4,40 +4,22 @@ use brk_vec::{
BaseVecIterator, StoredIndex, StoredType, StoredVec, StoredVecIterator, Value, Version,
};
// LazyVec owns SourceVecs
//
// Functions:
// init()
// version()
// iter()
// len() ?
//
// When .iter() called convert SourcesVecs into iterators
// iter owns source iters
// call compute function to convert index and source iters to T
pub type ComputeFrom2<T, S1I, S1T, S2I, S2T> = for<'a> fn(
usize,
&mut dyn BaseVecIterator<Item = (S1I, Value<'a, S1T>)>,
&mut dyn BaseVecIterator<Item = (S2I, Value<'a, S2T>)>,
) -> Option<T>;
#[derive(Clone)]
pub struct LazyVec<I, T, S1I, S1T, S2I, S2T>
where
I: StoredIndex,
T: StoredType,
S1I: StoredIndex,
S1T: StoredType,
S2I: StoredIndex,
S2T: StoredType,
{
pub struct LazyVecFrom2<I, T, S1I, S1T, S2I, S2T> {
version: Version,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
compute: for<'a> fn(
usize,
&mut dyn BaseVecIterator<Item = (S1I, Value<'a, S1T>)>,
&mut dyn BaseVecIterator<Item = (S2I, Value<'a, S2T>)>,
) -> Option<T>,
compute: ComputeFrom2<T, S1I, S1T, S2I, S2T>,
phantom: PhantomData<I>,
}
impl<I, T, S1I, S1T, S2I, S2T> LazyVec<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,
@@ -50,11 +32,7 @@ where
version: Version,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
compute: for<'a> fn(
usize,
&mut dyn BaseVecIterator<Item = (S1I, Value<'a, S1T>)>,
&mut dyn BaseVecIterator<Item = (S2I, Value<'a, S2T>)>,
) -> Option<T>,
compute: ComputeFrom2<T, S1I, S1T, S2I, S2T>,
) -> Self {
Self {
version,
@@ -68,59 +46,15 @@ where
fn version(&self) -> Version {
self.version
}
fn len(&self) -> usize {
todo!()
}
}
pub struct LazyVecIterator<'a, I, T, S1I, S1T, S2I, S2T>
where
I: StoredIndex,
T: StoredType,
S1I: StoredIndex,
S1T: StoredType,
S2I: StoredIndex,
S2T: StoredType,
{
lazy: &'a LazyVec<I, T, S1I, S1T, S2I, S2T>,
pub struct LazyVecIterator<'a, I, T, S1I, S1T, S2I, S2T> {
lazy: &'a LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>,
source1: StoredVecIterator<'a, S1I, S1T>,
source2: StoredVecIterator<'a, S2I, S2T>,
index: usize,
}
impl<I, T, S1I, S1T, S2I, S2T> LazyVecIterator<'_, I, T, S1I, S1T, S2I, S2T>
where
I: StoredIndex,
T: StoredType,
S1I: StoredIndex,
S1T: StoredType,
S2I: StoredIndex,
S2T: StoredType,
{
#[inline]
pub fn set(&mut self, i: I) -> &mut Self {
self.index = i.unwrap_to_usize();
self
}
#[inline]
pub fn set_(&mut self, i: usize) {
self.index = i;
}
#[inline]
pub fn get(&mut self, i: I) -> Option<Value<'_, T>> {
self.set(i).next().map(|(_, v)| v)
}
#[inline]
pub fn get_(&mut self, i: usize) -> Option<Value<'_, T>> {
self.set_(i);
self.next().map(|(_, v)| v)
}
}
impl<'a, I, T, S1I, S1T, S2I, S2T> Iterator for LazyVecIterator<'a, I, T, S1I, S1T, S2I, S2T>
where
I: StoredIndex,
@@ -163,11 +97,10 @@ where
#[inline]
fn len(&self) -> usize {
todo!();
// self.vec.len()
}
}
impl<'a, I, T, S1I, S1T, S2I, S2T> IntoIterator for &'a LazyVec<I, T, S1I, S1T, S2I, S2T>
impl<'a, I, T, S1I, S1T, S2I, S2T> IntoIterator for &'a LazyVecFrom2<I, T, S1I, S1T, S2I, S2T>
where
I: StoredIndex,
T: StoredType + 'a,

View File

@@ -0,0 +1,141 @@
use std::marker::PhantomData;
use brk_vec::{
BaseVecIterator, StoredIndex, StoredType, StoredVec, StoredVecIterator, Value, Version,
};
pub type ComputeFrom3<T, S1I, S1T, S2I, S2T, S3I, S3T> = for<'a> fn(
usize,
&mut dyn BaseVecIterator<Item = (S1I, Value<'a, S1T>)>,
&mut dyn BaseVecIterator<Item = (S2I, Value<'a, S2T>)>,
&mut dyn BaseVecIterator<Item = (S3I, Value<'a, S3T>)>,
) -> Option<T>;
#[derive(Clone)]
pub struct LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T> {
version: Version,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
source3: StoredVec<S3I, S3T>,
compute: ComputeFrom3<T, S1I, S1T, S2I, S2T, S3I, S3T>,
phantom: PhantomData<I>,
}
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(
version: Version,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
source3: StoredVec<S3I, S3T>,
compute: ComputeFrom3<T, S1I, S1T, S2I, S2T, S3I, S3T>,
) -> Self {
Self {
version,
source1,
source2,
source3,
compute,
phantom: PhantomData,
}
}
fn version(&self) -> Version {
self.version
}
}
pub struct LazyVecIterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> {
lazy: &'a LazyVecFrom3<I, T, S1I, S1T, S2I, S2T, S3I, S3T>,
source1: StoredVecIterator<'a, S1I, S1T>,
source2: StoredVecIterator<'a, S2I, S2T>,
source3: StoredVecIterator<'a, S3I, S3T>,
index: usize,
}
impl<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T> Iterator
for LazyVecIterator<'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, Value<'a, T>);
fn next(&mut self) -> Option<Self::Item> {
let opt = (self.lazy.compute)(
self.index,
&mut self.lazy.source1.iter(),
&mut self.lazy.source2.iter(),
&mut self.lazy.source3.iter(),
)
.map(|v| (I::from(self.index), Value::Owned(v)));
if opt.is_some() {
self.index += 1;
}
opt
}
}
impl<I, T, S1I, S1T, S2I, S2T, S3I, S3T> BaseVecIterator
for LazyVecIterator<'_, 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 {
todo!();
}
}
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, Value<'a, T>);
type IntoIter = LazyVecIterator<'a, I, T, S1I, S1T, S2I, S2T, S3I, S3T>;
fn into_iter(self) -> Self::IntoIter {
LazyVecIterator {
lazy: self,
source1: self.source1.iter(),
source2: self.source2.iter(),
source3: self.source3.iter(),
index: 0,
}
}
}

View File

@@ -1,13 +1,193 @@
use std::path::Path;
use brk_exit::Exit;
use clap_derive::ValueEnum;
use serde::{Deserialize, Serialize};
mod _type;
mod eager;
mod lazy;
mod lazy1;
mod lazy2;
mod lazy3;
pub use _type::*;
use brk_core::StoredPhantom;
use brk_vec::{Compressed, GenericVec, Result, StoredIndex, StoredType, StoredVec, Version};
pub use eager::*;
pub use lazy::*;
pub use lazy1::*;
pub use lazy2::*;
pub use lazy3::*;
#[derive(Debug, Clone, Copy)]
enum Mode {
Lazy,
#[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
}
}
#[derive(Clone)]
enum Dependencies<T, S1I, S1T, S2I, S2T, S3I, S3T> {
From1(StoredVec<S1I, S1T>, ComputeFrom1<T, S1I, S1T>),
From2(
(StoredVec<S1I, S1T>, StoredVec<S2I, S2T>),
ComputeFrom2<T, S1I, S1T, S2I, S2T>,
),
From3(
(
StoredVec<S1I, S1T>,
StoredVec<S2I, S2T>,
StoredVec<S3I, S3T>,
),
ComputeFrom3<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> {
Eager {
vec: EagerVec<I, T>,
deps: Dependencies<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>),
// Lazy4
}
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(
mode: Computation,
path: &Path,
version: Version,
compressed: Compressed,
source: StoredVec<S1I, S1T>,
compute: ComputeFrom1<T, S1I, S1T>,
) -> brk_vec::Result<Self> {
Ok(match mode {
Computation::Eager => Self::Eager {
vec: EagerVec::forced_import(path, version, compressed)?,
deps: Dependencies::From1(source, compute),
},
Computation::Lazy => Self::LazyFrom1(LazyVecFrom1::init(version, source, compute)),
})
}
pub fn forced_import_or_init_from_2(
mode: Computation,
path: &Path,
version: Version,
compressed: Compressed,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
compute: ComputeFrom2<T, S1I, S1T, S2I, S2T>,
) -> brk_vec::Result<Self> {
Ok(match mode {
Computation::Eager => Self::Eager {
vec: EagerVec::forced_import(path, version, compressed)?,
deps: Dependencies::From2((source1, source2), compute),
},
Computation::Lazy => {
Self::LazyFrom2(LazyVecFrom2::init(version, source1, source2, compute))
}
})
}
#[allow(clippy::too_many_arguments)]
pub fn forced_import_or_init_from_3(
mode: Computation,
path: &Path,
version: Version,
compressed: Compressed,
source1: StoredVec<S1I, S1T>,
source2: StoredVec<S2I, S2T>,
source3: StoredVec<S3I, S3T>,
compute: ComputeFrom3<T, S1I, S1T, S2I, S2T, S3I, S3T>,
) -> brk_vec::Result<Self> {
Ok(match mode {
Computation::Eager => Self::Eager {
vec: EagerVec::forced_import(path, version, compressed)?,
deps: Dependencies::From3((source1, source2, source3), compute),
},
Computation::Lazy => Self::LazyFrom3(LazyVecFrom3::init(
version, source1, source2, source3, compute,
)),
})
}
pub fn compute_if_necessary(&mut self, max_from: I, exit: &Exit) -> Result<()> {
let (vec, dependencies) = if let ComputedVec::Eager {
vec,
deps: dependencies,
} = self
{
(vec, dependencies)
} else {
return Ok(());
};
match dependencies {
Dependencies::From1(source, compute) => {
let version = source.version();
let mut iter = source.iter();
let t = |i: I| {
compute(i.unwrap_to_usize(), &mut iter)
.map(|v| (i, v))
.unwrap()
};
vec.compute_to(max_from, 1, 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.unwrap_to_usize(), &mut iter1, &mut iter2)
.map(|v| (i, v))
.unwrap()
};
vec.compute_to(max_from, 1, 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.unwrap_to_usize(), &mut iter1, &mut iter2, &mut iter3)
.map(|v| (i, v))
.unwrap()
};
vec.compute_to(max_from, 1, version, t, exit)
}
}
}
}