global: snapshot

This commit is contained in:
nym21
2025-10-31 21:37:02 +01:00
parent 82e59d409e
commit cf08e470ef
127 changed files with 1059 additions and 450 deletions

View File

@@ -98,7 +98,7 @@ pub struct Vecs {
pub indexes_to_tx_vsize: ComputedVecsFromTxindex<StoredU64>,
pub indexes_to_tx_weight: ComputedVecsFromTxindex<Weight>,
pub indexes_to_unknownoutput_count: ComputedVecsFromHeight<StoredU64>,
pub txinindex_to_value: LazyVecFrom2<TxInIndex, Sats, TxInIndex, TxOutIndex, TxOutIndex, Sats>,
pub txinindex_to_value: EagerVec<TxInIndex, Sats>,
pub indexes_to_input_count: ComputedVecsFromTxindex<StoredU64>,
pub txindex_to_is_coinbase: LazyVecFrom2<TxIndex, StoredBool, TxIndex, Height, Height, TxIndex>,
pub indexes_to_output_count: ComputedVecsFromTxindex<StoredU64>,
@@ -158,29 +158,8 @@ impl Vecs {
let compute_dollars = price.is_some();
let txinindex_to_value = LazyVecFrom2::init(
"value",
version + Version::ZERO,
indexes.txinindex_to_txoutindex.boxed_clone(),
indexer.vecs.txoutindex_to_value.boxed_clone(),
|index: TxInIndex, txinindex_to_txoutindex_iter, txoutindex_to_value_iter| {
txinindex_to_txoutindex_iter.next_at(index.to_usize()).map(
|(txinindex, txoutindex)| {
let txoutindex = txoutindex.into_owned();
if txoutindex == TxOutIndex::COINBASE {
Sats::MAX
} else if let Some((_, value)) =
txoutindex_to_value_iter.next_at(txoutindex.to_usize())
{
value.into_owned()
} else {
dbg!(txinindex, txoutindex);
panic!()
}
},
)
},
);
let txinindex_to_value: EagerVec<TxInIndex, Sats> =
EagerVec::forced_import_compressed(&db, "value", version + Version::ZERO)?;
let txindex_to_weight = LazyVecFrom2::init(
"weight",
@@ -192,12 +171,7 @@ impl Vecs {
txindex_to_base_size_iter
.next_at(index)
.map(|(_, base_size)| {
let base_size = base_size.into_owned();
let total_size = txindex_to_total_size_iter
.next_at(index)
.unwrap()
.1
.into_owned();
let total_size = txindex_to_total_size_iter.next_at(index).unwrap().1;
// This is the exact definition of a weight unit, as defined by BIP-141 (quote above).
let wu = usize::from(base_size) * 3 + usize::from(total_size);
@@ -214,9 +188,7 @@ impl Vecs {
|index: TxIndex, iter| {
let index = index.to_usize();
iter.next_at(index).map(|(_, weight)| {
StoredU64::from(
bitcoin::Weight::from(weight.into_owned()).to_vbytes_ceil() as usize
)
StoredU64::from(bitcoin::Weight::from(weight).to_vbytes_ceil() as usize)
})
},
);
@@ -230,12 +202,10 @@ impl Vecs {
txindex_to_height_iter
.next_at(index.to_usize())
.map(|(_, height)| {
let height = height.into_owned();
let txindex = height_to_first_txindex_iter
.next_at(height.to_usize())
.unwrap()
.1
.into_owned();
.1;
StoredBool::from(index == txindex)
})
},
@@ -255,20 +225,11 @@ impl Vecs {
txindex_to_first_txinindex_iter
.next_at(txindex)
.map(|(_, first_index)| {
let first_index = usize::from(first_index.into_owned());
let count = *txindex_to_input_count_iter
.next_at(txindex)
.unwrap()
.1
.into_owned();
let first_index = usize::from(first_index);
let count = *txindex_to_input_count_iter.next_at(txindex).unwrap().1;
let range = first_index..first_index + count as usize;
range.into_iter().fold(Sats::ZERO, |total, txinindex| {
total
+ txinindex_to_value_iter
.next_at(txinindex)
.unwrap()
.1
.into_owned()
total + txinindex_to_value_iter.next_at(txinindex).unwrap().1
})
})
},
@@ -302,19 +263,11 @@ impl Vecs {
txindex_to_first_txoutindex_iter
.next_at(txindex)
.map(|(_, first_index)| {
let first_index = usize::from(first_index.into_owned());
let count = *txindex_to_output_count_iter
.next_at(txindex)
.unwrap()
.1
.into_owned();
let first_index = usize::from(first_index);
let count = *txindex_to_output_count_iter.next_at(txindex).unwrap().1;
let range = first_index..first_index + count as usize;
range.into_iter().fold(Sats::ZERO, |total, txoutindex| {
let v = txoutindex_to_value_iter
.next_at(txoutindex)
.unwrap()
.1
.into_owned();
let v = txoutindex_to_value_iter.next_at(txoutindex).unwrap().1;
total + v
})
})
@@ -1424,6 +1377,41 @@ impl Vecs {
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v2, TxVersion::TWO)?;
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v3, TxVersion::THREE)?;
let mut txoutindex_to_value_iter = indexer.vecs.txoutindex_to_value.into_iter();
self.txinindex_to_value.compute_transform(
starting_indexes.txinindex,
&indexes.txinindex_to_txoutindex,
|(txinindex, txoutindex, ..)| {
let value = if txoutindex == TxOutIndex::COINBASE {
Sats::MAX
} else {
txoutindex_to_value_iter.unwrap_get_inner(txoutindex)
};
(txinindex, value)
},
exit,
)?;
// indexes.txinindex_to_txoutindex.boxed_clone(),
// indexer.vecs.txoutindex_to_value.boxed_clone(),
// |index: TxInIndex, txinindex_to_txoutindex_iter, txoutindex_to_value_iter| {
// txinindex_to_txoutindex_iter.next_at(index.to_usize()).map(
// |(txinindex, txoutindex)| {
// let txoutindex = txoutindex;
// if txoutindex == TxOutIndex::COINBASE {
// Sats::MAX
// } else if let Some((_, value)) =
// txoutindex_to_value_iter.next_at(txoutindex.to_usize())
// {
// value
// } else {
// dbg!(txinindex, txoutindex);
// panic!()
// }
// },
// )
// },
// self.indexes_to_output_value.compute_all(
// indexer,
// indexes,

View File

@@ -78,7 +78,6 @@ impl Vecs {
height_to_timestamp
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let v = v.into_owned();
self.height_to_price_ohlc_in_cents.forced_push_at(
i,
self.fetcher
@@ -103,8 +102,7 @@ impl Vecs {
indexes
.dateindex_to_date
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let d = v.into_owned();
.try_for_each(|(i, d)| -> Result<()> {
if prev.is_none() {
let i = i.to_usize();
prev.replace(if i > 0 {

View File

@@ -222,7 +222,7 @@ where
cumulative_vec.iter().unwrap_get_inner(index)
});
source.iter_at(index).try_for_each(|(i, v)| -> Result<()> {
cumulative += v.into_owned();
cumulative += v;
cumulative_vec.forced_push_at(i, cumulative, exit)?;
Ok(())
})?;
@@ -263,8 +263,6 @@ where
first_indexes
.iter_at(index)
.try_for_each(|(index, first_index)| -> Result<()> {
let first_index = first_index.into_owned();
let count_index = count_indexes_iter.unwrap_get_inner(index);
if let Some(first) = self.first.as_mut() {
@@ -286,7 +284,7 @@ where
// dbg!(first_index, count_index, last_index);
// })
// .unwrap()
// .into_owned();
// ;
last.forced_push_at(index, v, exit)?;
}
@@ -306,7 +304,7 @@ where
source_iter.set(first_index);
let mut values = (&mut source_iter)
.take(*count_index as usize)
.map(|(_, v)| v.into_owned())
.map(|(_, v)| v)
.collect::<Vec<_>>();
if needs_sorted {
@@ -436,8 +434,6 @@ where
first_indexes
.iter_at(index)
.try_for_each(|(index, first_index, ..)| -> Result<()> {
let first_index = first_index.into_owned();
let count_index = count_indexes_iter.unwrap_get_inner(index);
if let Some(first) = self.first.as_mut() {
@@ -474,7 +470,7 @@ where
source_max_iter.set(first_index);
let mut values = source_max_iter
.take(*count_index as usize)
.map(|(_, v)| v.into_owned())
.map(|(_, v)| v)
.collect::<Vec<_>>();
values.sort_unstable();
max.forced_push_at(index, *values.last().unwrap(), exit)?;
@@ -485,7 +481,7 @@ where
source_min_iter.set(first_index);
let mut values = source_min_iter
.take(*count_index as usize)
.map(|(_, v)| v.into_owned())
.map(|(_, v)| v)
.collect::<Vec<_>>();
values.sort_unstable();
min.forced_push_at(index, *values.first().unwrap(), exit)?;
@@ -498,7 +494,7 @@ where
source_average_iter.set(first_index);
let values = source_average_iter
.take(*count_index as usize)
.map(|(_, v)| v.into_owned())
.map(|(_, v)| v)
.collect::<Vec<_>>();
let len = values.len();
@@ -514,7 +510,7 @@ where
source_sum_iter.set(first_index);
let values = source_sum_iter
.take(*count_index as usize)
.map(|(_, v)| v.into_owned())
.map(|(_, v)| v)
.collect::<Vec<_>>();
let sum = values.into_iter().fold(T::from(0), |a, b| a + b);

View File

@@ -71,9 +71,7 @@ where
if i.to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::min_from(i))
.map(|(_, cow)| cow.into_owned())
source.next_at(S1I::min_from(i)).map(|(_, v)| v)
},
))
}),
@@ -100,7 +98,7 @@ where
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
.map(|(_, v)| v)
},
))
}),
@@ -118,7 +116,7 @@ where
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.flat_map(|i| source.next_at(i).map(|(_, v)| v))
.min()
},
))
@@ -137,7 +135,7 @@ where
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.flat_map(|i| source.next_at(i).map(|(_, v)| v))
.max()
},
))
@@ -156,7 +154,7 @@ where
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.flat_map(|i| source.next_at(i).map(|(_, v)| v))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
@@ -186,7 +184,7 @@ where
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.flat_map(|i| source.next_at(i).map(|(_, v)| v))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
@@ -209,7 +207,7 @@ where
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
.map(|(_, v)| v)
},
))
}),
@@ -259,6 +257,7 @@ pub struct LazyVecBuilderOptions {
}
impl From<VecBuilderOptions> for LazyVecBuilderOptions {
#[inline]
fn from(value: VecBuilderOptions) -> Self {
Self {
average: value.average(),

View File

@@ -440,7 +440,6 @@ impl ComputedRatioVecsFromDateIndex {
.unwrap()
.forced_push_at(index, StoredF32::NAN, exit)?;
} else {
let ratio = ratio.into_owned();
let pos = sorted.binary_search(&ratio).unwrap_or_else(|pos| pos);
sorted.insert(pos, ratio);

View File

@@ -545,7 +545,6 @@ impl ComputedStandardDeviationVecsFromDateIndex {
v.forced_push_at(index, StoredF32::NAN, exit)?
}
} else {
let ratio = ratio.into_owned();
let pos = sorted.binary_search(&ratio).unwrap_or_else(|pos| pos);
sorted.insert(pos, ratio);

View File

@@ -29,18 +29,21 @@ impl<I, T> Source<I, T> {
}
impl<I, T> From<bool> for Source<I, T> {
#[inline]
fn from(value: bool) -> Self {
if value { Self::Compute } else { Self::None }
}
}
impl<I, T> From<AnyBoxedIterableVec<I, T>> for Source<I, T> {
#[inline]
fn from(value: AnyBoxedIterableVec<I, T>) -> Self {
Self::Vec(value)
}
}
impl<I, T> From<Option<AnyBoxedIterableVec<I, T>>> for Source<I, T> {
#[inline]
fn from(value: Option<AnyBoxedIterableVec<I, T>>) -> Self {
if let Some(v) = value {
Self::Vec(v)

View File

@@ -59,10 +59,8 @@ impl ComputedValueVecsFromTxindex {
version + VERSION,
source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|txindex: TxIndex, iter| {
iter.next_at(txindex.to_usize()).map(|(_, value)| {
let sats = value.into_owned();
Bitcoin::from(sats)
})
iter.next_at(txindex.to_usize())
.map(|(_, sats)| Bitcoin::from(sats))
},
);
@@ -87,15 +85,13 @@ impl ComputedValueVecsFromTxindex {
txindex_to_height_iter,
height_to_price_close_iter| {
let txindex = txindex.to_usize();
txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
let btc = value.into_owned();
txindex_to_btc_iter.next_at(txindex).and_then(|(_, btc)| {
txindex_to_height_iter
.next_at(txindex)
.and_then(|(_, value)| {
let height = value.into_owned();
.and_then(|(_, height)| {
height_to_price_close_iter
.next_at(height.to_usize())
.map(|(_, close)| *close.into_owned() * btc)
.map(|(_, close)| *close * btc)
})
})
},

View File

@@ -119,7 +119,6 @@ impl Vecs {
txinindex_to_outpoint_iter
.next_at(index.to_usize())
.map(|(_, outpoint)| {
let outpoint = outpoint.into_owned();
if outpoint.is_coinbase() {
return TxOutIndex::COINBASE;
}
@@ -127,7 +126,6 @@ impl Vecs {
.next_at(outpoint.txindex().to_usize())
.unwrap()
.1
.into_owned()
+ outpoint.vout()
})
},
@@ -164,10 +162,10 @@ impl Vecs {
txindex_to_first_txinindex_iter
.next_at(txindex)
.map(|(_, start)| {
let start = usize::from(start.into_owned());
let start = usize::from(start);
let end = txindex_to_first_txinindex_iter
.next_at(txindex + 1)
.map(|(_, v)| usize::from(v.into_owned()))
.map(|(_, v)| usize::from(v))
.unwrap_or_else(|| txinindex_to_txoutindex_iter.len());
StoredU64::from((start..end).count())
})
@@ -184,10 +182,10 @@ impl Vecs {
txindex_to_first_txoutindex_iter
.next_at(txindex)
.map(|(_, start)| {
let start = usize::from(start.into_owned());
let start = usize::from(start);
let end = txindex_to_first_txoutindex_iter
.next_at(txindex + 1)
.map(|(_, v)| usize::from(v.into_owned()))
.map(|(_, v)| usize::from(v))
.unwrap_or_else(|| txoutindex_to_value_iter.len());
StoredU64::from((start..end).count())
})

View File

@@ -389,11 +389,8 @@ impl Vecs {
.height_to_price_ohlc_in_cents
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
self.height_to_price_ohlc.forced_push_at(
i,
OHLCDollars::from(v.into_owned()),
exit,
)?;
self.height_to_price_ohlc
.forced_push_at(i, OHLCDollars::from(v), exit)?;
Ok(())
})?;
self.height_to_price_ohlc.safe_flush(exit)?;
@@ -433,11 +430,8 @@ impl Vecs {
.dateindex_to_price_ohlc_in_cents
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
self.dateindex_to_price_ohlc.forced_push_at(
i,
OHLCDollars::from(v.into_owned()),
exit,
)?;
self.dateindex_to_price_ohlc
.forced_push_at(i, OHLCDollars::from(v), exit)?;
Ok(())
})?;
self.dateindex_to_price_ohlc.safe_flush(exit)?;
@@ -544,8 +538,7 @@ impl Vecs {
.weekindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = weekindex_first_iter.unwrap_get_inner(i);
let high = weekindex_max_iter.unwrap_get_inner(i);
let low = weekindex_min_iter.unwrap_get_inner(i);
@@ -585,8 +578,7 @@ impl Vecs {
.difficultyepoch
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = difficultyepoch_first_iter.unwrap_get_inner(i);
let high = difficultyepoch_max_iter.unwrap_get_inner(i);
let low = difficultyepoch_min_iter.unwrap_get_inner(i);
@@ -622,8 +614,7 @@ impl Vecs {
.monthindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = monthindex_first_iter.unwrap_get_inner(i);
let high = monthindex_max_iter.unwrap_get_inner(i);
let low = monthindex_min_iter.unwrap_get_inner(i);
@@ -663,8 +654,7 @@ impl Vecs {
.quarterindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = quarterindex_first_iter.unwrap_get_inner(i);
let high = quarterindex_max_iter.unwrap_get_inner(i);
let low = quarterindex_min_iter.unwrap_get_inner(i);
@@ -704,8 +694,7 @@ impl Vecs {
.semesterindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = semesterindex_first_iter.unwrap_get_inner(i);
let high = semesterindex_max_iter.unwrap_get_inner(i);
let low = semesterindex_min_iter.unwrap_get_inner(i);
@@ -737,8 +726,7 @@ impl Vecs {
.yearindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = yearindex_first_iter.unwrap_get_inner(i);
let high = yearindex_max_iter.unwrap_get_inner(i);
let low = yearindex_min_iter.unwrap_get_inner(i);
@@ -781,8 +769,7 @@ impl Vecs {
.decadeindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
let open = decadeindex_first_iter.unwrap_get_inner(i);
let high = decadeindex_max_iter.unwrap_get_inner(i);
let low = decadeindex_min_iter.unwrap_get_inner(i);
@@ -897,8 +884,7 @@ impl Vecs {
self.chainindexes_to_price_close_in_sats
.height
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.height_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -939,8 +925,7 @@ impl Vecs {
.as_ref()
.unwrap()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.dateindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -977,8 +962,7 @@ impl Vecs {
.weekindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.weekindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1015,8 +999,7 @@ impl Vecs {
.difficultyepoch
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.difficultyepoch_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1054,8 +1037,7 @@ impl Vecs {
.monthindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.monthindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1092,8 +1074,7 @@ impl Vecs {
.quarterindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.quarterindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1130,8 +1111,7 @@ impl Vecs {
.semesterindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.semesterindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1168,8 +1148,7 @@ impl Vecs {
.yearindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.yearindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {
@@ -1209,8 +1188,7 @@ impl Vecs {
.decadeindex
.unwrap_last()
.iter_at(index)
.try_for_each(|(i, v)| -> Result<()> {
let close = v.into_owned();
.try_for_each(|(i, close)| -> Result<()> {
self.decadeindex_to_price_ohlc_in_sats.forced_push_at(
i,
OHLCSats {

View File

@@ -9,6 +9,7 @@ use super::AddressTypeToHeightToAddressCount;
pub struct AddressTypeToAddressCount(ByAddressType<u64>);
impl From<(&AddressTypeToHeightToAddressCount, Height)> for AddressTypeToAddressCount {
#[inline]
fn from((groups, starting_height): (&AddressTypeToHeightToAddressCount, Height)) -> Self {
if let Some(prev_height) = starting_height.decremented() {
Self(ByAddressType {

View File

@@ -11,6 +11,7 @@ use super::AddressTypeToAddressCount;
pub struct AddressTypeToHeightToAddressCount(ByAddressType<EagerVec<Height, StoredU64>>);
impl From<ByAddressType<EagerVec<Height, StoredU64>>> for AddressTypeToHeightToAddressCount {
#[inline]
fn from(value: ByAddressType<EagerVec<Height, StoredU64>>) -> Self {
Self(value)
}

View File

@@ -13,6 +13,7 @@ use super::AddressTypeToHeightToAddressCount;
pub struct AddressTypeToIndexesToAddressCount(ByAddressType<ComputedVecsFromHeight<StoredU64>>);
impl From<ByAddressType<ComputedVecsFromHeight<StoredU64>>> for AddressTypeToIndexesToAddressCount {
#[inline]
fn from(value: ByAddressType<ComputedVecsFromHeight<StoredU64>>) -> Self {
Self(value)
}

View File

@@ -66,3 +66,26 @@ impl<T> Default for AddressTypeToTypeIndexMap<T> {
})
}
}
impl<T> AddressTypeToTypeIndexMap<Vec<T>>
where
T: Copy,
{
pub fn merge_vec(mut self, other: Self) -> Self {
for (address_type, other_map) in other.0.into_iter_typed() {
let self_map = self.0.get_mut_unwrap(address_type);
for (typeindex, mut other_vec) in other_map {
self_map
.entry(typeindex)
.and_modify(|self_vec| {
if other_vec.len() > self_vec.len() {
mem::swap(self_vec, &mut other_vec);
}
self_vec.extend(other_vec.iter().copied());
})
.or_insert(other_vec);
}
}
self
}
}

View File

@@ -8,16 +8,17 @@ use brk_types::{
AnyAddressDataIndexEnum, AnyAddressIndex, CheckedSub, DateIndex, Dollars, EmptyAddressData,
EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex, OutputType, P2AAddressIndex,
P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex,
P2WPKHAddressIndex, P2WSHAddressIndex, Sats, StoredU64, Timestamp, TxInIndex, TxOutIndex,
TypeIndex, Version,
P2WPKHAddressIndex, P2WSHAddressIndex, Sats, StoredU64, Timestamp, TxInIndex, TxIndex,
TxOutIndex, TypeIndex, Version,
};
use log::info;
use rayon::prelude::*;
use rustc_hash::FxHashMap;
use smallvec::SmallVec;
use vecdb::{
AnyCloneableIterableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec, Exit,
Format, GenericStoredVec, ImportOptions, LazyVecFrom1, PAGE_SIZE, RawVec, Reader, Stamp,
StoredIndex, VecIterator,
AnyCloneableIterableVec, AnyIterableVec, AnyStoredVec, AnyVec, BoxedVecIterator,
CollectableVec, Database, EagerVec, Exit, Format, GenericStoredVec, ImportOptions,
LazyVecFrom1, PAGE_SIZE, RawVec, Reader, Stamp, StoredIndex, VecIterator,
};
use crate::{
@@ -44,6 +45,8 @@ use range_map::*;
use r#trait::*;
use withaddressdatasource::*;
type TxIndexVec = SmallVec<[TxIndex; 4]>;
const VERSION: Version = Version::new(21);
#[derive(Clone, Traversable)]
@@ -186,12 +189,7 @@ impl Vecs {
.as_ref()
.unwrap()
.boxed_clone(),
|height: Height, iter| {
iter.next_at(height.to_usize()).map(|(_, value)| {
let d: Dollars = value.into_owned();
d
})
},
|height: Height, iter| iter.next_at(height.to_usize()).map(|(_, d)| d),
)
}),
indexes_to_market_cap: compute_dollars.then(|| {
@@ -519,8 +517,12 @@ impl Vecs {
starting_indexes: &mut Indexes,
exit: &Exit,
) -> Result<()> {
let height_to_first_txoutindex = &indexer.vecs.height_to_first_txoutindex;
let height_to_first_txinindex = &indexer.vecs.height_to_first_txinindex;
let dateindex_to_first_height = &indexes.dateindex_to_first_height;
let dateindex_to_height_count = &indexes.dateindex_to_height_count;
let dateindex_to_price_close = price
.as_ref()
.map(|price| price.timeindexes_to_price_close.dateindex.as_ref().unwrap());
let height_to_date_fixed = &indexes.height_to_date_fixed;
let height_to_first_p2aaddressindex = &indexer.vecs.height_to_first_p2aaddressindex;
let height_to_first_p2pk33addressindex = &indexer.vecs.height_to_first_p2pk33addressindex;
let height_to_first_p2pk65addressindex = &indexer.vecs.height_to_first_p2pk65addressindex;
@@ -529,38 +531,42 @@ impl Vecs {
let height_to_first_p2traddressindex = &indexer.vecs.height_to_first_p2traddressindex;
let height_to_first_p2wpkhaddressindex = &indexer.vecs.height_to_first_p2wpkhaddressindex;
let height_to_first_p2wshaddressindex = &indexer.vecs.height_to_first_p2wshaddressindex;
let height_to_output_count = chain.indexes_to_output_count.height.unwrap_sum();
let height_to_first_txindex = &indexer.vecs.height_to_first_txindex;
let height_to_first_txinindex = &indexer.vecs.height_to_first_txinindex;
let height_to_first_txoutindex = &indexer.vecs.height_to_first_txoutindex;
let height_to_input_count = chain.indexes_to_input_count.height.unwrap_sum();
let txinindex_to_outpoint = &indexer.vecs.txinindex_to_outpoint;
let txindex_to_first_txoutindex = &indexer.vecs.txindex_to_first_txoutindex;
let txoutindex_to_value = &indexer.vecs.txoutindex_to_value;
let txindex_to_height = &indexer.vecs.txindex_to_height;
let height_to_output_count = chain.indexes_to_output_count.height.unwrap_sum();
let height_to_price_close = price
.as_ref()
.map(|price| &price.chainindexes_to_price_close.height);
let height_to_timestamp_fixed = &indexes.height_to_timestamp_fixed;
let txoutindex_to_txindex = &indexer.vecs.txoutindex_to_txindex;
let txoutindex_to_outputtype = &indexer.vecs.txoutindex_to_outputtype;
let txoutindex_to_typeindex = &indexer.vecs.txoutindex_to_typeindex;
let height_to_tx_count = chain.indexes_to_tx_count.height.as_ref().unwrap();
let height_to_unclaimed_rewards = chain
.indexes_to_unclaimed_rewards
.sats
.height
.as_ref()
.unwrap();
let height_to_price_close = price
.as_ref()
.map(|price| &price.chainindexes_to_price_close.height);
let dateindex_to_price_close = price
.as_ref()
.map(|price| price.timeindexes_to_price_close.dateindex.as_ref().unwrap());
let height_to_date_fixed = &indexes.height_to_date_fixed;
let dateindex_to_first_height = &indexes.dateindex_to_first_height;
let dateindex_to_height_count = &indexes.dateindex_to_height_count;
let txindex_to_first_txoutindex = &indexer.vecs.txindex_to_first_txoutindex;
let txindex_to_height = &indexer.vecs.txindex_to_height;
let txindex_to_input_count = &indexes.txindex_to_input_count;
let txindex_to_output_count = &indexes.txindex_to_output_count;
let txinindex_to_outpoint = &indexer.vecs.txinindex_to_outpoint;
let txoutindex_to_outputtype = &indexer.vecs.txoutindex_to_outputtype;
let txoutindex_to_txindex = &indexer.vecs.txoutindex_to_txindex;
let txoutindex_to_typeindex = &indexer.vecs.txoutindex_to_typeindex;
let txoutindex_to_value = &indexer.vecs.txoutindex_to_value;
let mut height_to_price_close_iter = height_to_price_close.as_ref().map(|v| v.into_iter());
let mut height_to_timestamp_fixed_iter = height_to_timestamp_fixed.into_iter();
let base_version = Version::ZERO
+ height_to_first_txoutindex.version()
+ height_to_first_txinindex.version()
+ dateindex_to_first_height.version()
+ dateindex_to_height_count.version()
+ dateindex_to_price_close
.as_ref()
.map_or(Version::ZERO, |v| v.version())
+ height_to_date_fixed.version()
+ height_to_first_p2aaddressindex.version()
+ height_to_first_p2pk33addressindex.version()
+ height_to_first_p2pk65addressindex.version()
@@ -569,26 +575,26 @@ impl Vecs {
+ height_to_first_p2traddressindex.version()
+ height_to_first_p2wpkhaddressindex.version()
+ height_to_first_p2wshaddressindex.version()
+ height_to_timestamp_fixed.version()
+ height_to_output_count.version()
+ height_to_first_txindex.version()
+ height_to_first_txinindex.version()
+ height_to_first_txoutindex.version()
+ height_to_input_count.version()
+ txinindex_to_outpoint.version()
+ txoutindex_to_value.version()
+ txindex_to_height.version()
+ txindex_to_first_txoutindex.version()
+ txoutindex_to_txindex.version()
+ txoutindex_to_outputtype.version()
+ txoutindex_to_typeindex.version()
+ height_to_unclaimed_rewards.version()
+ height_to_output_count.version()
+ height_to_price_close
.as_ref()
.map_or(Version::ZERO, |v| v.version())
+ dateindex_to_price_close
.as_ref()
.map_or(Version::ZERO, |v| v.version())
+ height_to_date_fixed.version()
+ dateindex_to_first_height.version()
+ dateindex_to_height_count.version();
+ height_to_timestamp_fixed.version()
+ height_to_tx_count.version()
+ height_to_unclaimed_rewards.version()
+ txindex_to_first_txoutindex.version()
+ txindex_to_height.version()
+ txindex_to_input_count.version()
+ txindex_to_output_count.version()
+ txinindex_to_outpoint.version()
+ txoutindex_to_outputtype.version()
+ txoutindex_to_txindex.version()
+ txoutindex_to_typeindex.version()
+ txoutindex_to_value.version();
let mut separate_utxo_vecs = self.utxo_cohorts.iter_separate_mut().collect::<Vec<_>>();
let mut separate_address_vecs =
@@ -748,8 +754,11 @@ impl Vecs {
let ir = IndexerReaders::new(indexer);
let mut height_to_first_txoutindex_iter = height_to_first_txoutindex.into_iter();
let mut height_to_first_txinindex_iter = height_to_first_txinindex.into_iter();
let mut dateindex_to_first_height_iter = dateindex_to_first_height.into_iter();
let mut dateindex_to_height_count_iter = dateindex_to_height_count.into_iter();
let mut dateindex_to_price_close_iter =
dateindex_to_price_close.as_ref().map(|v| v.into_iter());
let mut height_to_date_fixed_iter = height_to_date_fixed.into_iter();
let mut height_to_first_p2aaddressindex_iter =
height_to_first_p2aaddressindex.into_iter();
let mut height_to_first_p2pk33addressindex_iter =
@@ -766,14 +775,15 @@ impl Vecs {
height_to_first_p2wpkhaddressindex.into_iter();
let mut height_to_first_p2wshaddressindex_iter =
height_to_first_p2wshaddressindex.into_iter();
let mut height_to_output_count_iter = height_to_output_count.into_iter();
let mut height_to_first_txindex_iter = height_to_first_txindex.into_iter();
let mut height_to_first_txinindex_iter = height_to_first_txinindex.into_iter();
let mut height_to_first_txoutindex_iter = height_to_first_txoutindex.into_iter();
let mut height_to_input_count_iter = height_to_input_count.into_iter();
let mut height_to_output_count_iter = height_to_output_count.into_iter();
let mut height_to_tx_count_iter = height_to_tx_count.into_iter();
let mut height_to_unclaimed_rewards_iter = height_to_unclaimed_rewards.into_iter();
let mut dateindex_to_price_close_iter =
dateindex_to_price_close.as_ref().map(|v| v.into_iter());
let mut height_to_date_fixed_iter = height_to_date_fixed.into_iter();
let mut dateindex_to_first_height_iter = dateindex_to_first_height.into_iter();
let mut dateindex_to_height_count_iter = dateindex_to_height_count.into_iter();
let mut txindex_to_input_count_iter = txindex_to_input_count.boxed_iter();
let mut txindex_to_output_count_iter = txindex_to_output_count.boxed_iter();
let height_to_price_close_vec =
height_to_price_close.map(|height_to_price_close| height_to_price_close.collect());
@@ -841,15 +851,29 @@ impl Vecs {
let price = height_to_price_close_iter
.as_mut()
.map(|i| *i.unwrap_get_inner(height));
let first_txindex = height_to_first_txindex_iter.unwrap_get_inner(height);
let first_txoutindex = height_to_first_txoutindex_iter
.unwrap_get_inner(height)
.to_usize();
let first_txinindex = height_to_first_txinindex_iter
.unwrap_get_inner(height)
.to_usize();
let tx_count = height_to_tx_count_iter.unwrap_get_inner(height);
let output_count = height_to_output_count_iter.unwrap_get_inner(height);
let input_count = height_to_input_count_iter.unwrap_get_inner(height);
let txoutindex_to_txindex = build_txoutindex_to_txindex(
first_txindex,
u64::from(tx_count),
&mut txindex_to_output_count_iter,
);
let txinindex_to_txindex = build_txinindex_to_txindex(
first_txindex,
u64::from(tx_count),
&mut txindex_to_input_count_iter,
);
let first_addressindexes: ByAddressType<TypeIndex> = ByAddressType {
p2a: height_to_first_p2aaddressindex_iter
.unwrap_get_inner(height)
@@ -1499,8 +1523,7 @@ impl Vecs {
.loaded
.get_any_or_read(loadedaddressindex, reader)
.unwrap()
.unwrap()
.into_owned();
.unwrap();
WithAddressDataSource::FromLoadedAddressDataVec((
loadedaddressindex,
@@ -1514,8 +1537,7 @@ impl Vecs {
.empty
.get_any_or_read(emtpyaddressindex, reader)
.unwrap()
.unwrap()
.into_owned();
.unwrap();
WithAddressDataSource::FromEmptyAddressDataVec((
emtpyaddressindex,
@@ -1969,7 +1991,7 @@ impl AnyAddressIndexes {
OutputType::P2A => self.p2a.get_any_or_read(typeindex.into(), reader),
_ => unreachable!(),
};
result.unwrap().unwrap().into_owned()
result.unwrap().unwrap()
}
fn update_or_push(
@@ -2104,3 +2126,43 @@ impl VecsReaders {
.get_unwrap(address_type)
}
}
fn build_txoutindex_to_txindex<'a>(
block_first_txindex: TxIndex,
block_tx_count: u64,
txindex_to_output_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>,
) -> Vec<TxIndex> {
let mut vec = Vec::new();
let block_first_txindex = block_first_txindex.to_usize();
for tx_offset in 0..block_tx_count as usize {
let txindex = TxIndex::from(block_first_txindex + tx_offset);
let output_count = u64::from(txindex_to_output_count.unwrap_get_inner(txindex));
for _ in 0..output_count {
vec.push(txindex);
}
}
vec
}
fn build_txinindex_to_txindex<'a>(
block_first_txindex: TxIndex,
block_tx_count: u64,
txindex_to_input_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>,
) -> Vec<TxIndex> {
let mut vec = Vec::new();
let block_first_txindex = block_first_txindex.to_usize();
for tx_offset in 0..block_tx_count as usize {
let txindex = TxIndex::from(block_first_txindex + tx_offset);
let input_count = u64::from(txindex_to_input_count.unwrap_get_inner(txindex));
for _ in 0..input_count {
vec.push(txindex);
}
}
vec
}

View File

@@ -25,10 +25,11 @@ where
I: StoredIndex,
T: StoredIndex + StoredRaw,
{
#[inline]
fn from(vec: &RawVec<I, T>) -> Self {
Self(
vec.into_iter()
.map(|(i, v)| (v.into_owned(), i))
.map(|(i, v)| (v, i))
.collect::<BTreeMap<_, _>>(),
)
}
@@ -39,10 +40,11 @@ where
I: StoredIndex,
T: StoredIndex + StoredCompressed,
{
#[inline]
fn from(vec: &CompressedVec<I, T>) -> Self {
Self(
vec.into_iter()
.map(|(i, v)| (v.into_owned(), i))
.map(|(i, v)| (v, i))
.collect::<BTreeMap<_, _>>(),
)
}

View File

@@ -26,6 +26,7 @@ impl<T> WithAddressDataSource<T> {
}
impl From<WithAddressDataSource<EmptyAddressData>> for WithAddressDataSource<LoadedAddressData> {
#[inline]
fn from(value: WithAddressDataSource<EmptyAddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),
@@ -40,6 +41,7 @@ impl From<WithAddressDataSource<EmptyAddressData>> for WithAddressDataSource<Loa
}
impl From<WithAddressDataSource<LoadedAddressData>> for WithAddressDataSource<EmptyAddressData> {
#[inline]
fn from(value: WithAddressDataSource<LoadedAddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),

View File

@@ -41,6 +41,7 @@ impl SubAssign<&SupplyState> for SupplyState {
}
impl From<&LoadedAddressData> for SupplyState {
#[inline]
fn from(value: &LoadedAddressData) -> Self {
Self {
utxo_count: value.utxo_count() as u64,

View File

@@ -41,7 +41,7 @@ impl ComputeDCAStackViaLen for EagerVec<DateIndex, Sats> {
let index = max_from.min(DateIndex::from(self.len()));
closes.iter_at(index).try_for_each(|(i, closes)| {
let price = *closes.into_owned();
let price = *closes;
let i_usize = i.to_usize();
if prev.is_none() {
if i_usize == 0 {
@@ -91,7 +91,7 @@ impl ComputeDCAStackViaLen for EagerVec<DateIndex, Sats> {
let index = max_from.min(DateIndex::from(self.len()));
closes.iter_at(index).try_for_each(|(i, closes)| {
let price = *closes.into_owned();
let price = *closes;
let i_usize = i.to_usize();
if prev.is_none() {
if i_usize == 0 {
@@ -152,7 +152,6 @@ impl ComputeDCAAveragePriceViaLen for EagerVec<DateIndex, Dollars> {
let first_price_date = DateIndex::try_from(Date::new(2010, 7, 12)).unwrap();
stacks.iter_at(index).try_for_each(|(i, stack)| {
let stack = stack.into_owned();
let mut avg_price = Dollars::from(f64::NAN);
if i > first_price_date {
avg_price = DCA_AMOUNT
@@ -185,7 +184,6 @@ impl ComputeDCAAveragePriceViaLen for EagerVec<DateIndex, Dollars> {
let from_usize = from.to_usize();
stacks.iter_at(index).try_for_each(|(i, stack)| {
let stack = stack.into_owned();
let mut avg_price = Dollars::from(f64::NAN);
if i >= from {
avg_price = DCA_AMOUNT * (i.to_usize() + 1 - from_usize) / Bitcoin::from(stack);
@@ -223,7 +221,7 @@ where
let index = max_from.min(I::from(self.len()));
sats.iter_at(index).try_for_each(|(i, sats)| {
let (i, v) = (i, Bitcoin::from(sats.into_owned()));
let (i, v) = (i, Bitcoin::from(sats));
self.forced_push_at(i, v, exit)
})?;
@@ -261,7 +259,7 @@ where
let index = max_from.min(I::from(self.len()));
bitcoin.iter_at(index).try_for_each(|(i, bitcoin)| {
let dollars = price_iter.unwrap_get_inner(i);
let (i, v) = (i, *dollars * bitcoin.into_owned());
let (i, v) = (i, *dollars * bitcoin);
self.forced_push_at(i, v, exit)
})?;
@@ -298,7 +296,6 @@ where
let index = max_from.min(I::from(self.len()));
let mut close_iter = close.iter();
ath.iter_at(index).try_for_each(|(i, ath)| {
let ath = ath.into_owned();
if ath == Dollars::ZERO {
self.forced_push_at(i, StoredF32::default(), exit)
} else {