mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-26 07:39:59 -07:00
computer: lazy part 3
This commit is contained in:
@@ -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(())
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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()
|
||||
}
|
||||
|
||||
@@ -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(),
|
||||
|
||||
@@ -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,
|
||||
|
||||
103
crates/brk_computer/src/storage/vecs/vec/lazy1.rs
Normal file
103
crates/brk_computer/src/storage/vecs/vec/lazy1.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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,
|
||||
141
crates/brk_computer/src/storage/vecs/vec/lazy3.rs
Normal file
141
crates/brk_computer/src/storage/vecs/vec/lazy3.rs
Normal 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,
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user