mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-08-12 02:03:09 -07:00
global: massive columnar rework part 4
This commit is contained in:
+4709
-19067
File diff suppressed because it is too large
Load Diff
@@ -9,12 +9,12 @@ pub struct BlockActivityCounts {
|
||||
|
||||
impl BlockActivityCounts {
|
||||
#[inline]
|
||||
pub(crate) fn reset(&mut self) {
|
||||
pub fn reset(&mut self) {
|
||||
*self = Self::default();
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn active(&self) -> u32 {
|
||||
pub fn active(&self) -> u32 {
|
||||
debug_assert!(self.bidirectional <= self.sending.min(self.receiving));
|
||||
self.sending + self.receiving - self.bidirectional
|
||||
}
|
||||
|
||||
@@ -10,16 +10,16 @@ use super::BlockActivityCounts;
|
||||
pub struct AddrTypeToActivityCounts(pub ByAddrType<BlockActivityCounts>);
|
||||
|
||||
impl AddrTypeToActivityCounts {
|
||||
pub(crate) fn reset(&mut self) {
|
||||
pub fn reset(&mut self) {
|
||||
self.0.values_mut().for_each(BlockActivityCounts::reset);
|
||||
}
|
||||
|
||||
pub(crate) fn active(&self) -> u32 {
|
||||
pub fn active(&self) -> u32 {
|
||||
self.0.values().map(BlockActivityCounts::active).sum()
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn row(
|
||||
pub fn row(
|
||||
&self,
|
||||
value: impl Fn(&BlockActivityCounts) -> u32,
|
||||
) -> <AddrTypeId as ColumnId>::Row<StoredU64> {
|
||||
|
||||
@@ -41,7 +41,7 @@ pub struct AddrActivityVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AddrActivityVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -129,7 +129,7 @@ impl AddrActivityVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
[
|
||||
self.cumulative_reactivated.cumulative.len(),
|
||||
self.cumulative_sending.cumulative.len(),
|
||||
@@ -142,9 +142,7 @@ impl AddrActivityVecs {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
[
|
||||
self.cumulative_reactivated.stored_mut(),
|
||||
self.cumulative_sending.stored_mut(),
|
||||
@@ -155,7 +153,7 @@ impl AddrActivityVecs {
|
||||
.into_par_iter()
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.cumulative_reactivated.reset()?;
|
||||
self.cumulative_sending.reset()?;
|
||||
self.cumulative_receiving.reset()?;
|
||||
@@ -165,7 +163,7 @@ impl AddrActivityVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_height(&mut self, counts: &AddrTypeToActivityCounts) {
|
||||
pub fn push_height(&mut self, counts: &AddrTypeToActivityCounts) {
|
||||
self.cumulative_reactivated
|
||||
.push_block(counts.row(|counts| counts.reactivated));
|
||||
self.cumulative_sending
|
||||
|
||||
@@ -9,7 +9,7 @@ use vecdb::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
distribution::AllChainCache,
|
||||
distribution::AllChainSources,
|
||||
indexes,
|
||||
internal::{
|
||||
ColumnarPerBlock, LazyColumnSpotValuePerBlock, LazySpotValuePerBlock, WithAddrTypes,
|
||||
@@ -27,12 +27,12 @@ pub struct AvgAmountVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AvgAmountVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
spot_price: &CachedBoxedVec<Height, Cents>,
|
||||
all_chain: &AllChainCache,
|
||||
all_chain: &AllChainSources,
|
||||
utxo_count: &(impl ReadableCloneableVec<Height, StoredU64> + 'static),
|
||||
funded_addr_count: &(impl ReadableCloneableVec<Height, StoredU64> + 'static),
|
||||
) -> Result<Self> {
|
||||
@@ -101,20 +101,18 @@ impl AvgAmountVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
rayon::iter::once(self.utxo_source.stored_mut())
|
||||
.chain(rayon::iter::once(self.addr_source.stored_mut()))
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.utxo_source.height.reset()?;
|
||||
self.addr_source.height.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn compute(
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
supply_sats: &ByAddrType<&impl ReadableVec<Height, Sats>>,
|
||||
utxo_count: &ByAddrType<&impl ReadableVec<Height, StoredU64>>,
|
||||
|
||||
@@ -28,7 +28,7 @@ pub struct AddrCountsVecs<M: StorageMode = Rw>(
|
||||
);
|
||||
|
||||
impl AddrCountsVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -42,23 +42,21 @@ impl AddrCountsVecs {
|
||||
)?))
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.height.len()
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
rayon::iter::once(&mut self.height as &mut dyn AnyStoredVec)
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.height.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_counts(&mut self, counts: &AddrTypeToAddrCount) {
|
||||
pub fn push_counts(&mut self, counts: &AddrTypeToAddrCount) {
|
||||
self.push(counts.row());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct DeltaVecs(
|
||||
);
|
||||
|
||||
impl DeltaVecs {
|
||||
pub(crate) fn new(
|
||||
pub fn new(
|
||||
version: Version,
|
||||
addr_count: &AddrCountsVecs,
|
||||
cached_starts: &Windows<&CachedWindowStartVec>,
|
||||
|
||||
@@ -18,7 +18,7 @@ pub struct AddrCountFundedTotalVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AddrCountFundedTotalVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -40,32 +40,26 @@ impl AddrCountFundedTotalVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.funded
|
||||
.min_stateful_len()
|
||||
.min(self.total.min_stateful_len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.funded
|
||||
.par_iter_height_mut()
|
||||
.chain(self.total.par_iter_height_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.funded.reset_height()?;
|
||||
self.total.reset_height()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_counts(
|
||||
&mut self,
|
||||
funded: &AddrTypeToAddrCount,
|
||||
total: &AddrTypeToAddrCount,
|
||||
) {
|
||||
pub fn push_counts(&mut self, funded: &AddrTypeToAddrCount, total: &AddrTypeToAddrCount) {
|
||||
self.funded.push_counts(funded);
|
||||
self.total.push_counts(total);
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ pub struct FundedAddrCountsVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl FundedAddrCountsVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -53,31 +53,29 @@ impl FundedAddrCountsVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.counts.min_stateful_len().min(self.balance.len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.counts
|
||||
.par_iter_height_mut()
|
||||
.chain(rayon::iter::once(self.balance.stored_mut()))
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.counts.reset_height()?;
|
||||
self.balance.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_counts(&mut self, counts: &AddrTypeToAddrCount) {
|
||||
pub fn push_counts(&mut self, counts: &AddrTypeToAddrCount) {
|
||||
self.counts.push_counts(counts);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_balance(&mut self, counts: AmountRange<StoredU64>) {
|
||||
pub fn push_balance(&mut self, counts: AmountRange<StoredU64>) {
|
||||
self.balance.push(counts);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ pub struct NewAddrCountVecs(
|
||||
);
|
||||
|
||||
impl NewAddrCountVecs {
|
||||
pub(crate) fn new(
|
||||
pub fn new(
|
||||
version: Version,
|
||||
total: &TotalAddrCountVecs,
|
||||
indexes: &indexes::Vecs,
|
||||
|
||||
@@ -12,7 +12,7 @@ use super::AddrCountsVecs;
|
||||
pub struct AddrTypeToAddrCount(ByAddrType<u64>);
|
||||
|
||||
impl AddrTypeToAddrCount {
|
||||
pub(crate) fn row(&self) -> <AddrTypeId as ColumnId>::Row<StoredU64> {
|
||||
pub fn row(&self) -> <AddrTypeId as ColumnId>::Row<StoredU64> {
|
||||
AddrTypeId::from_fn(|id| StoredU64::from(*id.select(&self.0)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,11 +14,7 @@ use super::AddrCountsVecs;
|
||||
pub struct TotalAddrCountVecs<M: StorageMode = Rw>(#[traversable(flatten)] pub AddrCountsVecs<M>);
|
||||
|
||||
impl TotalAddrCountVecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
Ok(Self(AddrCountsVecs::forced_import(
|
||||
db,
|
||||
"total_addr_count",
|
||||
@@ -28,7 +24,7 @@ impl TotalAddrCountVecs {
|
||||
}
|
||||
|
||||
/// Eagerly compute total = addr_count + empty_addr_count.
|
||||
pub(crate) fn compute(
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
addr_count: &AddrCountsVecs,
|
||||
|
||||
@@ -13,14 +13,14 @@ pub struct AddrsDataVecs<M: StorageMode = Rw> {
|
||||
|
||||
impl AddrsDataVecs {
|
||||
/// Get minimum stamped height across funded and empty data.
|
||||
pub(crate) fn min_stamped_len(&self) -> Height {
|
||||
pub fn min_stamped_len(&self) -> Height {
|
||||
Height::from(self.funded.stamp())
|
||||
.incremented()
|
||||
.min(Height::from(self.empty.stamp()).incremented())
|
||||
}
|
||||
|
||||
/// Rollback both funded and empty data to before the given stamp.
|
||||
pub(crate) fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 2]> {
|
||||
pub fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 2]> {
|
||||
Ok([
|
||||
self.funded.rollback_before(stamp)?,
|
||||
self.empty.rollback_before(stamp)?,
|
||||
@@ -28,14 +28,14 @@ impl AddrsDataVecs {
|
||||
}
|
||||
|
||||
/// Reset both funded and empty data.
|
||||
pub(crate) fn reset(&mut self) -> Result<()> {
|
||||
pub fn reset(&mut self) -> Result<()> {
|
||||
self.funded.reset()?;
|
||||
self.empty.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a parallel iterator over all vecs for parallel writing.
|
||||
pub(crate) fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.funded as &mut dyn AnyStoredVec,
|
||||
&mut self.empty as &mut dyn AnyStoredVec,
|
||||
|
||||
@@ -45,7 +45,7 @@ use super::{
|
||||
count::AddrCountFundedTotalVecs,
|
||||
supply::{AddrSupplyShareVecs, AddrSupplyVecs},
|
||||
};
|
||||
use crate::{distribution::metrics::AllSupplyCache, indexes};
|
||||
use crate::indexes;
|
||||
|
||||
mod state;
|
||||
|
||||
@@ -62,12 +62,12 @@ pub struct ExposedAddrVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl ExposedAddrVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
spot_price: &CachedBoxedVec<Height, Cents>,
|
||||
all_supply: &AllSupplyCache,
|
||||
all_supply: &CachedBoxedVec<Height, Sats>,
|
||||
) -> Result<Self> {
|
||||
let count = AddrCountFundedTotalVecs::forced_import(db, "exposed", version, indexes)?;
|
||||
let supply = AddrSupplyVecs::forced_import(db, "exposed", version, indexes, spot_price)?;
|
||||
@@ -82,13 +82,13 @@ impl ExposedAddrVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.count
|
||||
.min_stateful_len()
|
||||
.min(self.supply.min_stateful_len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_stateful_height_mut(
|
||||
pub fn par_iter_stateful_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.count
|
||||
@@ -96,16 +96,14 @@ impl ExposedAddrVecs {
|
||||
.chain(self.supply.par_iter_height_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.count
|
||||
.par_iter_height_mut()
|
||||
.chain(self.supply.par_iter_height_mut())
|
||||
.chain(rayon::iter::once(self.supply_share.stored_mut()))
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.count.reset_height()?;
|
||||
self.supply.reset_height()?;
|
||||
self.supply_share.reset_height()?;
|
||||
@@ -113,12 +111,12 @@ impl ExposedAddrVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_height(&mut self, state: &ExposedAddrState) {
|
||||
pub fn push_height(&mut self, state: &ExposedAddrState) {
|
||||
self.count.push_counts(&state.funded, &state.total);
|
||||
self.supply.push_supply(&state.supply);
|
||||
}
|
||||
|
||||
pub(crate) fn compute_rest(
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
starting_lengths: &Lengths,
|
||||
type_supply_sats: &ByAddrType<&impl ReadableVec<Height, Sats>>,
|
||||
|
||||
@@ -21,7 +21,7 @@ impl ExposedAddrState {
|
||||
/// Apply exposed-addr updates for a received output, AFTER the receive
|
||||
/// has mutated `addr_data`. `pre` is the snapshot taken before the mutation.
|
||||
#[inline]
|
||||
pub(crate) fn on_receive(
|
||||
pub fn on_receive(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
@@ -46,7 +46,7 @@ impl ExposedAddrState {
|
||||
/// Apply exposed-addr updates for a spent UTXO, AFTER the send has mutated
|
||||
/// `addr_data`. `pre` is the snapshot taken before the mutation.
|
||||
#[inline]
|
||||
pub(crate) fn on_send(
|
||||
pub fn on_send(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
|
||||
@@ -29,7 +29,7 @@ macro_rules! define_any_addr_indexes_vecs {
|
||||
|
||||
impl AnyAddrIndexesVecs {
|
||||
/// Import from database.
|
||||
pub(crate) fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
$($field: BytesVec::forced_import_with(
|
||||
ImportOptions::new(db, "any_addr_index", version)
|
||||
@@ -39,7 +39,7 @@ macro_rules! define_any_addr_indexes_vecs {
|
||||
}
|
||||
|
||||
/// Get minimum stamped height across all address types.
|
||||
pub(crate) fn min_stamped_len(&self) -> Height {
|
||||
pub fn min_stamped_len(&self) -> Height {
|
||||
[$(Height::from(self.$field.stamp()).incremented()),*]
|
||||
.into_iter()
|
||||
.min()
|
||||
@@ -47,18 +47,18 @@ macro_rules! define_any_addr_indexes_vecs {
|
||||
}
|
||||
|
||||
/// Rollback all address types to before the given stamp.
|
||||
pub(crate) fn rollback_before(&mut self, stamp: Stamp) -> Result<Vec<Stamp>> {
|
||||
pub fn rollback_before(&mut self, stamp: Stamp) -> Result<Vec<Stamp>> {
|
||||
Ok(vec![$(self.$field.rollback_before(stamp)?),*])
|
||||
}
|
||||
|
||||
/// Reset all address types.
|
||||
pub(crate) fn reset(&mut self) -> Result<()> {
|
||||
pub fn reset(&mut self) -> Result<()> {
|
||||
$(self.$field.reset()?;)*
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns a parallel iterator over all vecs for parallel writing.
|
||||
pub(crate) fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
vec![$(&mut self.$field as &mut dyn AnyStoredVec),*].into_par_iter()
|
||||
}
|
||||
}
|
||||
@@ -94,7 +94,7 @@ impl AnyAddrIndexesVecs {
|
||||
/// Accepts two maps (e.g. from empty and funded processing) and merges per-thread.
|
||||
/// Updates existing entries and pushes new ones (sorted).
|
||||
/// Returns (update_count, push_count).
|
||||
pub(crate) fn par_batch_update(
|
||||
pub fn par_batch_update(
|
||||
&mut self,
|
||||
updates1: AddrTypeToTypeIndexMap<AnyAddrIndex>,
|
||||
updates2: AddrTypeToTypeIndexMap<AnyAddrIndex>,
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
mod any;
|
||||
|
||||
pub use any::*;
|
||||
pub use any::AnyAddrIndexesVecs;
|
||||
|
||||
@@ -16,17 +16,17 @@ pub struct AddrTypeToAddrEventCount(ByAddrType<u64>);
|
||||
|
||||
impl AddrTypeToAddrEventCount {
|
||||
#[inline]
|
||||
pub(crate) fn sum(&self) -> u64 {
|
||||
pub fn sum(&self) -> u64 {
|
||||
self.0.values().sum()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn row(&self) -> <AddrTypeId as ColumnId>::Row<StoredU64> {
|
||||
pub fn row(&self) -> <AddrTypeId as ColumnId>::Row<StoredU64> {
|
||||
AddrTypeId::from_fn(|column| StoredU64::from(*column.select(&self.0)))
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn reset(&mut self) {
|
||||
pub fn reset(&mut self) {
|
||||
for v in self.0.values_mut() {
|
||||
*v = 0;
|
||||
}
|
||||
|
||||
@@ -115,7 +115,7 @@ impl AddrEventsVecs {
|
||||
});
|
||||
WithAddrTypes { all, by_addr_type }
|
||||
}
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -218,7 +218,7 @@ impl AddrEventsVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.output_to_reused_addr_count
|
||||
.cumulative
|
||||
.len()
|
||||
@@ -227,9 +227,7 @@ impl AddrEventsVecs {
|
||||
.min(self.active_reused_addr_share.block.len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
rayon::iter::once(self.output_to_reused_addr_count.stored_mut())
|
||||
.chain(rayon::iter::once(
|
||||
self.input_from_reused_addr_count.stored_mut(),
|
||||
@@ -240,7 +238,7 @@ impl AddrEventsVecs {
|
||||
])
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.output_to_reused_addr_count.reset()?;
|
||||
self.input_from_reused_addr_count.reset()?;
|
||||
self.active_reused_addr_count.reset()?;
|
||||
@@ -249,7 +247,7 @@ impl AddrEventsVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_height(
|
||||
pub fn push_height(
|
||||
&mut self,
|
||||
uses: &AddrTypeToAddrEventCount,
|
||||
spends: &AddrTypeToAddrEventCount,
|
||||
@@ -275,7 +273,7 @@ impl AddrEventsVecs {
|
||||
.push(StoredF32::from(share));
|
||||
}
|
||||
|
||||
pub(crate) fn compute_rest(&mut self, starting_lengths: &Lengths, exit: &Exit) -> Result<()> {
|
||||
pub fn compute_rest(&mut self, starting_lengths: &Lengths, exit: &Exit) -> Result<()> {
|
||||
self.active_reused_addr_share
|
||||
.compute_rest(starting_lengths.height, exit)?;
|
||||
Ok(())
|
||||
|
||||
@@ -33,7 +33,6 @@ use super::{
|
||||
supply::{AddrSupplyShareVecs, AddrSupplyVecs},
|
||||
};
|
||||
use crate::{
|
||||
distribution::metrics::AllSupplyCache,
|
||||
indexes, inputs,
|
||||
internal::{CachedWindowStartVec, Windows},
|
||||
outputs,
|
||||
@@ -57,7 +56,7 @@ pub struct ReusedAddrVecs<M: StorageMode = Rw> {
|
||||
|
||||
impl ReusedAddrVecs {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -66,7 +65,7 @@ impl ReusedAddrVecs {
|
||||
spot_price: &CachedBoxedVec<Height, Cents>,
|
||||
outputs_by_type: &outputs::ByTypeVecs,
|
||||
inputs_by_type: &inputs::ByTypeVecs,
|
||||
all_supply: &AllSupplyCache,
|
||||
all_supply: &CachedBoxedVec<Height, Sats>,
|
||||
) -> Result<Self> {
|
||||
let count = AddrCountFundedTotalVecs::forced_import(db, name, version, indexes)?;
|
||||
let events = AddrEventsVecs::forced_import(
|
||||
@@ -90,14 +89,14 @@ impl ReusedAddrVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.count
|
||||
.min_stateful_len()
|
||||
.min(self.events.min_stateful_len())
|
||||
.min(self.supply.min_stateful_len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_stateful_height_mut(
|
||||
pub fn par_iter_stateful_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.count
|
||||
@@ -106,9 +105,7 @@ impl ReusedAddrVecs {
|
||||
.chain(self.supply.par_iter_height_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.count
|
||||
.par_iter_height_mut()
|
||||
.chain(self.events.par_iter_height_mut())
|
||||
@@ -116,7 +113,7 @@ impl ReusedAddrVecs {
|
||||
.chain(rayon::iter::once(self.supply_share.stored_mut()))
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.count.reset_height()?;
|
||||
self.events.reset_height()?;
|
||||
self.supply.reset_height()?;
|
||||
@@ -125,7 +122,7 @@ impl ReusedAddrVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_height(&mut self, state: &ReusedAddrState, active_addr_count: u32) {
|
||||
pub fn push_height(&mut self, state: &ReusedAddrState, active_addr_count: u32) {
|
||||
let active_reused_addr_count = state.active.sum();
|
||||
debug_assert!(u32::try_from(active_reused_addr_count).is_ok());
|
||||
|
||||
@@ -140,7 +137,7 @@ impl ReusedAddrVecs {
|
||||
}
|
||||
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn compute_rest(
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
starting_lengths: &Lengths,
|
||||
type_supply_sats: &ByAddrType<&impl ReadableVec<Height, Sats>>,
|
||||
|
||||
@@ -27,7 +27,7 @@ pub struct ReusedAddrState {
|
||||
|
||||
impl ReusedAddrState {
|
||||
#[inline]
|
||||
pub(crate) fn reset_per_block(&mut self) {
|
||||
pub fn reset_per_block(&mut self) {
|
||||
self.output_events.reset();
|
||||
self.input_events.reset();
|
||||
self.active.reset();
|
||||
@@ -36,7 +36,7 @@ impl ReusedAddrState {
|
||||
/// Apply reused-flavor (receive-based: `funded_txo_count > 1`) updates
|
||||
/// for a received output, AFTER the receive has mutated `addr_data`.
|
||||
#[inline]
|
||||
pub(crate) fn on_receive_as_reused(
|
||||
pub fn on_receive_as_reused(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
@@ -79,7 +79,7 @@ impl ReusedAddrState {
|
||||
/// don't cross the respent threshold. The only transition is an
|
||||
/// already-respent empty address reactivating into the funded set.
|
||||
#[inline]
|
||||
pub(crate) fn on_receive_as_respent(
|
||||
pub fn on_receive_as_respent(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
@@ -104,7 +104,7 @@ impl ReusedAddrState {
|
||||
/// mutated `addr_data`. Sends don't change the reused predicate, so
|
||||
/// `pre.was_reused == is_reused` post-spend.
|
||||
#[inline]
|
||||
pub(crate) fn on_send_as_reused(
|
||||
pub fn on_send_as_reused(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
@@ -133,7 +133,7 @@ impl ReusedAddrState {
|
||||
/// mutated `addr_data`. Sends CAN cross the respent threshold on the
|
||||
/// 2nd lifetime spend.
|
||||
#[inline]
|
||||
pub(crate) fn on_send_as_respent(
|
||||
pub fn on_send_as_respent(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
|
||||
@@ -20,14 +20,14 @@ pub struct AddrMetricsState {
|
||||
|
||||
impl AddrMetricsState {
|
||||
#[inline]
|
||||
pub(crate) fn reset_per_block(&mut self) {
|
||||
pub fn reset_per_block(&mut self) {
|
||||
self.activity.reset();
|
||||
self.reused.reset_per_block();
|
||||
self.respent.reset_per_block();
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn on_receive_applied(
|
||||
pub fn on_receive_applied(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
status: TrackingStatus,
|
||||
@@ -56,7 +56,7 @@ impl AddrMetricsState {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn on_send_applied(
|
||||
pub fn on_send_applied(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
addr_data: &FundedAddrData,
|
||||
|
||||
@@ -3,12 +3,11 @@ use brk_error::Result;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Height, PartsPerMillion32, Sats, Version};
|
||||
use vecdb::{
|
||||
AnyStoredVec, BinaryTransform, Database, Exit, ReadOnlyClone, ReadableVec, Rw, StorageMode,
|
||||
WritableVec,
|
||||
AnyStoredVec, BinaryTransform, CachedBoxedVec, Database, Exit, ReadOnlyClone, ReadableVec, Rw,
|
||||
StorageMode, WritableVec,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
distribution::metrics::AllSupplyCache,
|
||||
indexes,
|
||||
internal::{ColumnarPerBlock, LazyColumnPercentPerBlock, LazyPercentPerBlock, RatioSats},
|
||||
};
|
||||
@@ -29,20 +28,20 @@ pub struct AddrSupplyShareVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AddrSupplyShareVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
supply: &AddrSupplyVecs,
|
||||
all_supply: &AllSupplyCache,
|
||||
all_supply: &CachedBoxedVec<Height, Sats>,
|
||||
) -> Result<Self> {
|
||||
let name = format!("{name}_addr_supply_share");
|
||||
let all = LazyPercentPerBlock::from_cached_ratio::<Sats, Sats, RatioSats<PartsPerMillion32>>(
|
||||
&name,
|
||||
version,
|
||||
&supply.all.sats.height,
|
||||
all_supply.cached_boxed_clone(),
|
||||
all_supply.clone(),
|
||||
indexes,
|
||||
);
|
||||
let ppm =
|
||||
@@ -65,16 +64,16 @@ impl AddrSupplyShareVecs {
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.ppm.height.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.ppm.stored_mut()
|
||||
}
|
||||
|
||||
pub(crate) fn compute_rest(
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
supply: &AddrSupplyVecs,
|
||||
|
||||
@@ -12,14 +12,14 @@ pub struct AddrTypeToSupply(ByAddrType<Sats>);
|
||||
|
||||
impl AddrTypeToSupply {
|
||||
#[inline]
|
||||
pub(crate) fn row(&self) -> <AddrTypeId as ColumnId>::Row<Sats> {
|
||||
pub fn row(&self) -> <AddrTypeId as ColumnId>::Row<Sats> {
|
||||
AddrTypeId::from_fn(|column| *column.select(&self.0))
|
||||
}
|
||||
|
||||
/// Apply a signed `after - before` delta to the slot for `output_type`.
|
||||
/// Sats is unsigned, so branch on sign.
|
||||
#[inline]
|
||||
pub(crate) fn apply_delta(&mut self, output_type: OutputType, before: Sats, after: Sats) {
|
||||
pub fn apply_delta(&mut self, output_type: OutputType, before: Sats, after: Sats) {
|
||||
let slot = self.get_mut_unwrap(output_type);
|
||||
if after >= before {
|
||||
*slot += after - before;
|
||||
|
||||
@@ -31,7 +31,7 @@ pub struct AddrSupplyVecs<M: StorageMode = Rw>(
|
||||
);
|
||||
|
||||
impl AddrSupplyVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -51,23 +51,21 @@ impl AddrSupplyVecs {
|
||||
)?))
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.height.len()
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
rayon::iter::once(self.stored_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.height.reset()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_supply(&mut self, supply: &AddrTypeToSupply) {
|
||||
pub fn push_supply(&mut self, supply: &AddrTypeToSupply) {
|
||||
self.push(supply.row());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ pub struct HeightToAddrTypeToVec<T>(FxHashMap<Height, AddrTypeToVec<T>>);
|
||||
|
||||
impl<T> HeightToAddrTypeToVec<T> {
|
||||
/// Create with pre-allocated capacity for unique heights.
|
||||
pub(crate) fn with_capacity(capacity: usize) -> Self {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self(FxHashMap::with_capacity_and_hasher(
|
||||
capacity,
|
||||
Default::default(),
|
||||
@@ -20,7 +20,7 @@ impl<T> HeightToAddrTypeToVec<T> {
|
||||
|
||||
impl<T> HeightToAddrTypeToVec<T> {
|
||||
/// Consume and iterate over (Height, AddrTypeToVec) pairs.
|
||||
pub(crate) fn into_iter(self) -> impl Iterator<Item = (Height, AddrTypeToVec<T>)> {
|
||||
pub fn into_iter(self) -> impl Iterator<Item = (Height, AddrTypeToVec<T>)> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,7 @@ impl<T> Default for AddrTypeToTypeIndexMap<T> {
|
||||
|
||||
impl<T> AddrTypeToTypeIndexMap<T> {
|
||||
/// Create with pre-allocated capacity per address type.
|
||||
pub(crate) fn with_capacity(capacity: usize) -> Self {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self(ByAddrType {
|
||||
p2a: FxHashMap::with_capacity_and_hasher(capacity, Default::default()),
|
||||
p2pk33: FxHashMap::with_capacity_and_hasher(capacity, Default::default()),
|
||||
@@ -41,30 +41,23 @@ impl<T> AddrTypeToTypeIndexMap<T> {
|
||||
}
|
||||
|
||||
/// Insert a value for a specific address type and type_index.
|
||||
pub(crate) fn insert_for_type(
|
||||
&mut self,
|
||||
addr_type: OutputType,
|
||||
type_index: TypeIndex,
|
||||
value: T,
|
||||
) {
|
||||
pub fn insert_for_type(&mut self, addr_type: OutputType, type_index: TypeIndex, value: T) {
|
||||
self.get_mut(addr_type).unwrap().insert(type_index, value);
|
||||
}
|
||||
|
||||
/// Consume and iterate over entries by address type.
|
||||
#[allow(clippy::should_implement_trait)]
|
||||
pub(crate) fn into_iter(self) -> impl Iterator<Item = (OutputType, FxHashMap<TypeIndex, T>)> {
|
||||
pub fn into_iter(self) -> impl Iterator<Item = (OutputType, FxHashMap<TypeIndex, T>)> {
|
||||
self.0.into_iter()
|
||||
}
|
||||
|
||||
/// Consume and return the inner ByAddrType.
|
||||
pub(crate) fn into_inner(self) -> ByAddrType<FxHashMap<TypeIndex, T>> {
|
||||
pub fn into_inner(self) -> ByAddrType<FxHashMap<TypeIndex, T>> {
|
||||
self.0
|
||||
}
|
||||
|
||||
/// Iterate mutably over entries by address type.
|
||||
pub(crate) fn iter_mut(
|
||||
&mut self,
|
||||
) -> impl Iterator<Item = (OutputType, &mut FxHashMap<TypeIndex, T>)> {
|
||||
pub fn iter_mut(&mut self) -> impl Iterator<Item = (OutputType, &mut FxHashMap<TypeIndex, T>)> {
|
||||
self.0.iter_mut()
|
||||
}
|
||||
}
|
||||
@@ -74,7 +67,7 @@ where
|
||||
T: Array,
|
||||
{
|
||||
/// Merge two maps of SmallVec values, concatenating vectors.
|
||||
pub(crate) fn merge_vec(mut self, other: Self) -> Self {
|
||||
pub fn merge_vec(mut self, other: Self) -> Self {
|
||||
for (addr_type, other_map) in other.0.into_iter() {
|
||||
let self_map = self.0.get_mut_unwrap(addr_type);
|
||||
for (type_index, mut other_vec) in other_map {
|
||||
|
||||
@@ -2,6 +2,6 @@ mod height_vec;
|
||||
mod index_map;
|
||||
mod vec;
|
||||
|
||||
pub use height_vec::*;
|
||||
pub use index_map::*;
|
||||
pub use vec::*;
|
||||
pub use height_vec::HeightToAddrTypeToVec;
|
||||
pub use index_map::AddrTypeToTypeIndexMap;
|
||||
pub use vec::AddrTypeToVec;
|
||||
|
||||
@@ -22,7 +22,7 @@ impl<T> Default for AddrTypeToVec<T> {
|
||||
|
||||
impl<T> AddrTypeToVec<T> {
|
||||
/// Create with pre-allocated capacity per address type.
|
||||
pub(crate) fn with_capacity(capacity: usize) -> Self {
|
||||
pub fn with_capacity(capacity: usize) -> Self {
|
||||
Self(ByAddrType {
|
||||
p2a: Vec::with_capacity(capacity),
|
||||
p2pk33: Vec::with_capacity(capacity),
|
||||
@@ -38,7 +38,7 @@ impl<T> AddrTypeToVec<T> {
|
||||
|
||||
impl<T> AddrTypeToVec<T> {
|
||||
/// Unwrap the inner ByAddrType.
|
||||
pub(crate) fn unwrap(self) -> ByAddrType<Vec<T>> {
|
||||
pub fn unwrap(self) -> ByAddrType<Vec<T>> {
|
||||
self.0
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@ pub struct AddrVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AddrVecs {
|
||||
pub(crate) fn reset_height(&mut self) -> Result<()> {
|
||||
pub fn reset_height(&mut self) -> Result<()> {
|
||||
self.funded.reset_height()?;
|
||||
self.empty.reset_height()?;
|
||||
self.activity.reset_height()?;
|
||||
@@ -40,7 +40,7 @@ impl AddrVecs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.funded
|
||||
.min_stateful_len()
|
||||
.min(self.empty.min_stateful_len())
|
||||
@@ -50,7 +50,7 @@ impl AddrVecs {
|
||||
.min(self.exposed.min_stateful_len())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_stateful_height_mut(
|
||||
pub fn par_iter_stateful_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.funded
|
||||
@@ -62,9 +62,7 @@ impl AddrVecs {
|
||||
.chain(self.exposed.par_iter_stateful_height_mut())
|
||||
}
|
||||
|
||||
pub(crate) fn par_iter_height_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_height_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
self.funded
|
||||
.par_iter_height_mut()
|
||||
.chain(self.empty.par_iter_height_mut())
|
||||
@@ -77,7 +75,7 @@ impl AddrVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_height(&mut self, state: &AddrMetricsState, active_addr_count: u32) {
|
||||
pub fn push_height(&mut self, state: &AddrMetricsState, active_addr_count: u32) {
|
||||
self.funded.push_counts(&state.funded);
|
||||
self.empty.push_counts(&state.empty);
|
||||
self.activity.push_height(&state.activity);
|
||||
|
||||
+20
-91
@@ -1,17 +1,15 @@
|
||||
use brk_types::{Cents, Height, PartsPerMillionSigned64, Sats, Version};
|
||||
use brk_types::{Cents, Height, Sats, Version};
|
||||
use vecdb::{
|
||||
BinaryTransform, CachedBoxedVec, ReadableCloneableVec, ReadableVec, TypedVec, VecValue,
|
||||
};
|
||||
|
||||
use crate::internal::{LazyIndexedVec, LazyWindowVec, SatsToCents};
|
||||
|
||||
use super::metrics::AllSupplyCache;
|
||||
use crate::internal::{LazyIndexedVec, SatsToCents};
|
||||
|
||||
/// Shared handles to the pinned all-chain inputs.
|
||||
///
|
||||
/// Cloning these handles does not duplicate either cached array.
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct AllChainCache {
|
||||
pub struct AllChainSources {
|
||||
supply: CachedBoxedVec<Height, Sats>,
|
||||
price: CachedBoxedVec<Height, Cents>,
|
||||
}
|
||||
@@ -22,22 +20,19 @@ struct WithSupply<S> {
|
||||
supply: Sats,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, Default)]
|
||||
struct MarketAndRealizedCap {
|
||||
market: Cents,
|
||||
realized: Cents,
|
||||
}
|
||||
|
||||
impl AllChainCache {
|
||||
pub(crate) fn new(supply: &AllSupplyCache, price: &CachedBoxedVec<Height, Cents>) -> Self {
|
||||
impl AllChainSources {
|
||||
pub fn new(
|
||||
supply: &CachedBoxedVec<Height, Sats>,
|
||||
price: &CachedBoxedVec<Height, Cents>,
|
||||
) -> Self {
|
||||
Self {
|
||||
supply: supply.cached_boxed_clone(),
|
||||
supply: supply.clone(),
|
||||
price: price.clone(),
|
||||
}
|
||||
}
|
||||
|
||||
/// Lazily combines one ordinary source with the pinned all-supply cache.
|
||||
pub(crate) fn with_supply<S, T>(
|
||||
pub fn with_supply<S, T>(
|
||||
&self,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -59,7 +54,7 @@ impl AllChainCache {
|
||||
|
||||
/// Lazily combines one ordinary source with market cap derived from the
|
||||
/// pinned all-supply and spot-price caches.
|
||||
pub(crate) fn with_market_cap<S, T>(
|
||||
pub fn with_market_cap<S, T>(
|
||||
&self,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -91,67 +86,25 @@ impl AllChainCache {
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Computes market-cap growth minus realized-cap growth from one realized
|
||||
/// cap source and cached window starts.
|
||||
pub(crate) fn market_minus_realized_cap_growth(
|
||||
&self,
|
||||
name: &str,
|
||||
version: Version,
|
||||
realized_cap: &(impl ReadableCloneableVec<Height, Cents> + 'static),
|
||||
window_starts: CachedBoxedVec<Height, Height>,
|
||||
) -> impl TypedVec<I = Height, T = PartsPerMillionSigned64>
|
||||
+ ReadableVec<Height, PartsPerMillionSigned64>
|
||||
+ Clone
|
||||
+ 'static {
|
||||
let caps = self.with_market_cap(
|
||||
&format!("{name}_caps"),
|
||||
Version::ZERO,
|
||||
realized_cap,
|
||||
|_, realized, market| MarketAndRealizedCap { market, realized },
|
||||
);
|
||||
|
||||
LazyWindowVec::new(
|
||||
name,
|
||||
version,
|
||||
caps.read_only_boxed_clone(),
|
||||
window_starts,
|
||||
false,
|
||||
|current, previous, _| {
|
||||
let growth = |current: Cents, previous: Cents| {
|
||||
if previous == Cents::ZERO {
|
||||
0.0
|
||||
} else {
|
||||
(f64::from(current) - f64::from(previous)) / f64::from(previous)
|
||||
}
|
||||
};
|
||||
PartsPerMillionSigned64::from(
|
||||
growth(current.market, previous.market)
|
||||
- growth(current.realized, previous.realized),
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use brk_types::PartsPerMillionSigned64;
|
||||
use vecdb::{
|
||||
AnyStoredVec, CachedVec, Database, EagerVec, ImportableVec, PcoVec, ReadOnlyClone,
|
||||
WritableVec,
|
||||
AnyStoredVec, CachedReadableVec, CachedVec, Database, EagerVec, ImportableVec, PcoVec,
|
||||
ReadOnlyClone, WritableVec,
|
||||
};
|
||||
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn derives_from_one_source_and_shared_chain_caches() {
|
||||
fn derives_from_shared_chain_sources() {
|
||||
let suffix = std::time::SystemTime::now()
|
||||
.duration_since(std::time::UNIX_EPOCH)
|
||||
.unwrap()
|
||||
.as_nanos();
|
||||
let path = std::env::temp_dir().join(format!(
|
||||
"brk-all-chain-cache-{}-{suffix}",
|
||||
"brk-all-chain-sources-{}-{suffix}",
|
||||
std::process::id()
|
||||
));
|
||||
let db = Database::open(&path).unwrap();
|
||||
@@ -162,8 +115,6 @@ mod tests {
|
||||
EagerVec::forced_import(&db, "price", Version::ONE).unwrap();
|
||||
let mut realized: EagerVec<PcoVec<Height, Cents>> =
|
||||
EagerVec::forced_import(&db, "realized", Version::ONE).unwrap();
|
||||
let mut starts: EagerVec<PcoVec<Height, Height>> =
|
||||
EagerVec::forced_import(&db, "starts", Version::ONE).unwrap();
|
||||
|
||||
for value in [100_000_000, 100_000_000, 200_000_000] {
|
||||
supply.push(Sats::new(value));
|
||||
@@ -174,20 +125,17 @@ mod tests {
|
||||
for value in [50, 100, 100] {
|
||||
realized.push(Cents::new(value));
|
||||
}
|
||||
for value in [0, 0, 1] {
|
||||
starts.push(Height::new(value));
|
||||
}
|
||||
supply.write().unwrap();
|
||||
price.write().unwrap();
|
||||
realized.write().unwrap();
|
||||
starts.write().unwrap();
|
||||
|
||||
let supply_cache = AllSupplyCache::new(supply.read_only_clone());
|
||||
let supply_cache = CachedVec::wrap(supply.read_only_clone()).cached_boxed_clone();
|
||||
let price_cache = CachedVec::wrap(price);
|
||||
let cache = AllChainCache::new(&supply_cache, &price_cache.read_only_cached_boxed_clone());
|
||||
let sources =
|
||||
AllChainSources::new(&supply_cache, &price_cache.read_only_cached_boxed_clone());
|
||||
|
||||
let cached_supply =
|
||||
cache.with_supply("cached_supply", Version::ONE, &realized, |_, _, supply| {
|
||||
sources.with_supply("cached_supply", Version::ONE, &realized, |_, _, supply| {
|
||||
supply
|
||||
});
|
||||
assert_eq!(
|
||||
@@ -199,7 +147,7 @@ mod tests {
|
||||
],
|
||||
);
|
||||
|
||||
let market_cap = cache.with_market_cap(
|
||||
let market_cap = sources.with_market_cap(
|
||||
"market_cap",
|
||||
Version::ONE,
|
||||
&realized,
|
||||
@@ -214,27 +162,8 @@ mod tests {
|
||||
],
|
||||
);
|
||||
|
||||
let starts_cache = CachedVec::wrap(starts);
|
||||
let growth = cache.market_minus_realized_cap_growth(
|
||||
"growth",
|
||||
Version::ONE,
|
||||
&realized,
|
||||
starts_cache.read_only_cached_boxed_clone(),
|
||||
);
|
||||
assert_eq!(
|
||||
growth.collect_range(Height::ZERO, Height::new(3)),
|
||||
[
|
||||
PartsPerMillionSigned64::ZERO,
|
||||
PartsPerMillionSigned64::ZERO,
|
||||
PartsPerMillionSigned64::ONE,
|
||||
],
|
||||
);
|
||||
|
||||
drop(growth);
|
||||
drop(starts_cache);
|
||||
drop(market_cap);
|
||||
drop(cached_supply);
|
||||
drop(cache);
|
||||
drop(price_cache);
|
||||
drop(supply_cache);
|
||||
drop(realized);
|
||||
@@ -98,7 +98,7 @@ impl Default for AddrCache {
|
||||
}
|
||||
|
||||
impl AddrCache {
|
||||
pub(crate) fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
funded: AddrTypeToTypeIndexMap::default(),
|
||||
empty: AddrTypeToTypeIndexMap::default(),
|
||||
@@ -109,7 +109,7 @@ impl AddrCache {
|
||||
|
||||
/// Check if address is in cache (either funded or empty).
|
||||
#[inline]
|
||||
pub(crate) fn contains(&self, addr_type: OutputType, type_index: TypeIndex) -> bool {
|
||||
pub fn contains(&self, addr_type: OutputType, type_index: TypeIndex) -> bool {
|
||||
self.funded
|
||||
.get(addr_type)
|
||||
.is_some_and(|m| m.contains_key(&type_index))
|
||||
@@ -120,7 +120,7 @@ impl AddrCache {
|
||||
}
|
||||
|
||||
/// Load each address touched by the block once.
|
||||
pub(crate) fn load_block_addresses(
|
||||
pub fn load_block_addresses(
|
||||
&mut self,
|
||||
addresses: impl Iterator<Item = (OutputType, TypeIndex)>,
|
||||
first_addr_indexes: &ByAddrType<TypeIndex>,
|
||||
@@ -171,7 +171,7 @@ impl AddrCache {
|
||||
|
||||
/// Create an AddrLookup view into this cache.
|
||||
#[inline]
|
||||
pub(crate) fn as_lookup(&mut self) -> AddrLookup<'_> {
|
||||
pub fn as_lookup(&mut self) -> AddrLookup<'_> {
|
||||
AddrLookup {
|
||||
funded: &mut self.funded,
|
||||
empty: &mut self.empty,
|
||||
@@ -179,7 +179,7 @@ impl AddrCache {
|
||||
}
|
||||
|
||||
/// Update transaction counts for addresses.
|
||||
pub(crate) fn update_tx_counts(
|
||||
pub fn update_tx_counts(
|
||||
&mut self,
|
||||
tx_index_vecs: AddrTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
) {
|
||||
@@ -187,7 +187,7 @@ impl AddrCache {
|
||||
}
|
||||
|
||||
/// Take the cache contents for flushing, leaving empty caches.
|
||||
pub(crate) fn take(
|
||||
pub fn take(
|
||||
&mut self,
|
||||
) -> (
|
||||
AddrTypeToTypeIndexMap<WithAddrDataSource<EmptyAddrData>>,
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct AddrLookup<'a> {
|
||||
}
|
||||
|
||||
impl<'a> AddrLookup<'a> {
|
||||
pub(crate) fn get_or_create_for_receive(
|
||||
pub fn get_or_create_for_receive(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
type_index: TypeIndex,
|
||||
@@ -77,7 +77,7 @@ impl<'a> AddrLookup<'a> {
|
||||
}
|
||||
|
||||
/// Get address data for a send operation (must exist in cache).
|
||||
pub(crate) fn get_for_send(
|
||||
pub fn get_for_send(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
type_index: TypeIndex,
|
||||
@@ -90,7 +90,7 @@ impl<'a> AddrLookup<'a> {
|
||||
}
|
||||
|
||||
/// Move address from funded to empty set.
|
||||
pub(crate) fn move_to_empty(&mut self, output_type: OutputType, type_index: TypeIndex) {
|
||||
pub fn move_to_empty(&mut self, output_type: OutputType, type_index: TypeIndex) {
|
||||
let data = self
|
||||
.funded
|
||||
.get_mut(output_type)
|
||||
|
||||
+2
-2
@@ -1,5 +1,5 @@
|
||||
mod addr;
|
||||
mod lookup;
|
||||
|
||||
pub use addr::*;
|
||||
pub use lookup::*;
|
||||
pub use addr::AddrCache;
|
||||
pub use lookup::{AddrLookup, TrackingStatus};
|
||||
|
||||
@@ -5,7 +5,7 @@ use brk_types::{
|
||||
};
|
||||
use vecdb::AnyVec;
|
||||
|
||||
use crate::distribution::{AddrTypeToTypeIndexMap, AddrsDataVecs};
|
||||
use crate::distribution::addr::{AddrTypeToTypeIndexMap, AddrsDataVecs};
|
||||
|
||||
use super::with_source::WithAddrDataSource;
|
||||
|
||||
@@ -15,7 +15,7 @@ use super::with_source::WithAddrDataSource;
|
||||
/// - New funded address: push to funded storage
|
||||
/// - Updated funded address (was funded): update in place
|
||||
/// - Transition empty -> funded: delete from empty, push to funded
|
||||
pub(crate) fn process_funded_addrs(
|
||||
pub fn process_funded_addrs(
|
||||
addrs_data: &mut AddrsDataVecs,
|
||||
funded_updates: AddrTypeToTypeIndexMap<WithAddrDataSource<FundedAddrData>>,
|
||||
) -> Result<AddrTypeToTypeIndexMap<AnyAddrIndex>> {
|
||||
@@ -85,7 +85,7 @@ pub(crate) fn process_funded_addrs(
|
||||
/// - New empty address: push to empty storage
|
||||
/// - Updated empty address (was empty): update in place
|
||||
/// - Transition funded -> empty: delete from funded, push to empty
|
||||
pub(crate) fn process_empty_addrs(
|
||||
pub fn process_empty_addrs(
|
||||
addrs_data: &mut AddrsDataVecs,
|
||||
empty_updates: AddrTypeToTypeIndexMap<WithAddrDataSource<EmptyAddrData>>,
|
||||
) -> Result<AddrTypeToTypeIndexMap<AnyAddrIndex>> {
|
||||
|
||||
@@ -5,9 +5,9 @@ mod transfer_address_cache;
|
||||
mod tx_counts;
|
||||
mod with_source;
|
||||
|
||||
pub(crate) use addr_updates::*;
|
||||
pub(crate) use received::*;
|
||||
pub(crate) use sent::*;
|
||||
pub(crate) use transfer_address_cache::*;
|
||||
pub(crate) use tx_counts::*;
|
||||
pub(crate) use with_source::*;
|
||||
pub use addr_updates::{process_empty_addrs, process_funded_addrs};
|
||||
pub use received::process_received;
|
||||
pub use sent::process_sent;
|
||||
pub use transfer_address_cache::TransferAddressCache;
|
||||
pub use tx_counts::update_tx_counts;
|
||||
pub use with_source::WithAddrDataSource;
|
||||
|
||||
@@ -3,8 +3,8 @@ use brk_types::{Cents, Sats, TypeIndex};
|
||||
use rustc_hash::FxHashMap;
|
||||
|
||||
use crate::distribution::{
|
||||
AddrStates,
|
||||
addr::{AddrMetricsState, AddrReceivePreState, AddrTypeToVec},
|
||||
state::AddrStates,
|
||||
};
|
||||
|
||||
use super::super::cache::{AddrLookup, TrackingStatus};
|
||||
@@ -16,7 +16,7 @@ struct AggregatedReceive {
|
||||
output_count: u32,
|
||||
}
|
||||
|
||||
pub(crate) fn process_received(
|
||||
pub fn process_received(
|
||||
received_data: AddrTypeToVec<(TypeIndex, Sats)>,
|
||||
cohorts: &mut AddrStates,
|
||||
lookup: &mut AddrLookup<'_>,
|
||||
|
||||
@@ -4,14 +4,14 @@ use brk_types::{Cents, Sats, TypeIndex};
|
||||
use vecdb::VecIndex;
|
||||
|
||||
use crate::distribution::{
|
||||
AddrStates,
|
||||
addr::{AddrMetricsState, AddrSendPreState, HeightToAddrTypeToVec},
|
||||
state::AddrStates,
|
||||
};
|
||||
|
||||
use super::{super::cache::AddrLookup, transfer_address_cache::TransferAddressCache};
|
||||
|
||||
/// Process sent UTXOs for address cohort membership and empty-address transitions.
|
||||
pub(crate) fn process_sent(
|
||||
pub fn process_sent(
|
||||
sent_data: HeightToAddrTypeToVec<(TypeIndex, Sats)>,
|
||||
cohorts: &mut AddrStates,
|
||||
lookup: &mut AddrLookup<'_>,
|
||||
|
||||
@@ -5,13 +5,13 @@ use rustc_hash::FxHashSet;
|
||||
use crate::distribution::addr::AddrTypeToVec;
|
||||
|
||||
#[derive(Default)]
|
||||
pub(crate) struct TransferAddressCache {
|
||||
pub struct TransferAddressCache {
|
||||
received: ByAddrType<FxHashSet<TypeIndex>>,
|
||||
seen_senders: ByAddrType<FxHashSet<TypeIndex>>,
|
||||
}
|
||||
|
||||
impl TransferAddressCache {
|
||||
pub(crate) fn prepare(&mut self, received_data: &AddrTypeToVec<(TypeIndex, Sats)>) {
|
||||
pub fn prepare(&mut self, received_data: &AddrTypeToVec<(TypeIndex, Sats)>) {
|
||||
self.received.values_mut().for_each(FxHashSet::clear);
|
||||
self.seen_senders.values_mut().for_each(FxHashSet::clear);
|
||||
|
||||
@@ -22,7 +22,7 @@ impl TransferAddressCache {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn sets_for(
|
||||
pub fn sets_for(
|
||||
&mut self,
|
||||
output_type: OutputType,
|
||||
) -> (Option<&FxHashSet<TypeIndex>>, &mut FxHashSet<TypeIndex>) {
|
||||
|
||||
@@ -13,7 +13,7 @@ use super::with_source::WithAddrDataSource;
|
||||
///
|
||||
/// Addresses are looked up in funded_cache first, then empty_cache.
|
||||
/// NOTE: This should be called AFTER merging parallel-fetched address data into funded_cache.
|
||||
pub(crate) fn update_tx_counts(
|
||||
pub fn update_tx_counts(
|
||||
funded_cache: &mut AddrTypeToTypeIndexMap<WithAddrDataSource<FundedAddrData>>,
|
||||
empty_cache: &mut AddrTypeToTypeIndexMap<WithAddrDataSource<EmptyAddrData>>,
|
||||
mut tx_index_vecs: AddrTypeToTypeIndexMap<SmallVec<[TxIndex; 4]>>,
|
||||
|
||||
@@ -2,6 +2,9 @@ mod cache;
|
||||
mod cohort;
|
||||
mod utxo;
|
||||
|
||||
pub(crate) use cache::*;
|
||||
pub(crate) use cohort::*;
|
||||
pub(crate) use utxo::*;
|
||||
pub use cache::{AddrCache, TrackingStatus};
|
||||
pub use cohort::{
|
||||
TransferAddressCache, WithAddrDataSource, process_empty_addrs, process_funded_addrs,
|
||||
process_received, process_sent,
|
||||
};
|
||||
pub use utxo::{process_inputs, process_outputs};
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct InputsResult {
|
||||
/// 4. Read value and type from the referenced output (random access via mmap)
|
||||
/// 5. Accumulate into height_to_sent map
|
||||
/// 6. Track address-specific data for address cohort processing
|
||||
pub(crate) fn process_inputs(
|
||||
pub fn process_inputs(
|
||||
txin_index_to_tx_index: &[TxIndex],
|
||||
txin_index_to_value: &[Sats],
|
||||
txin_index_to_output_type: &[OutputType],
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mod inputs;
|
||||
mod outputs;
|
||||
|
||||
pub use inputs::*;
|
||||
pub use outputs::*;
|
||||
pub use inputs::process_inputs;
|
||||
pub use outputs::process_outputs;
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct OutputsResult {
|
||||
/// 1. Read pre-collected value, output type, and type_index
|
||||
/// 2. Accumulate into Transacted by type and amount
|
||||
/// 3. Track address-specific data for address cohort processing
|
||||
pub(crate) fn process_outputs(
|
||||
pub fn process_outputs(
|
||||
txout_index_to_tx_index: &[TxIndex],
|
||||
txout_data_vec: &[TxOutData],
|
||||
) -> OutputsResult {
|
||||
|
||||
@@ -2,7 +2,8 @@ use brk_cohort::{ByAddrType, EntryPrice, Filter, Term};
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{
|
||||
Cents, Date, Height, ONE_DAY_IN_SEC, OutputType, Sats, StoredF64, Timestamp, TxIndex, TypeIndex,
|
||||
Cents, Date, Height, ONE_DAY_IN_SEC, OutputType, RangeMap, Sats, StoredF64, Timestamp, TxIndex,
|
||||
TypeIndex,
|
||||
};
|
||||
use rayon::prelude::*;
|
||||
use tracing::{debug, info};
|
||||
@@ -23,7 +24,6 @@ use crate::{
|
||||
|
||||
use super::{
|
||||
super::{
|
||||
RangeMap,
|
||||
metrics::CohortMetrics,
|
||||
state::{AddrStates, UTXOStates},
|
||||
vecs::Vecs,
|
||||
@@ -35,7 +35,7 @@ use super::{
|
||||
|
||||
/// Process all blocks from starting_height to last_height.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub(crate) fn process_blocks(
|
||||
pub fn process_blocks(
|
||||
vecs: &mut Vecs,
|
||||
utxo_states: &mut UTXOStates,
|
||||
addr_states: &mut AddrStates,
|
||||
|
||||
@@ -12,11 +12,11 @@ pub struct ComputeContext<'a> {
|
||||
}
|
||||
|
||||
impl<'a> ComputeContext<'a> {
|
||||
pub(crate) fn price_at(&self, height: Height) -> Cents {
|
||||
pub fn price_at(&self, height: Height) -> Cents {
|
||||
self.height_to_price[height.to_usize()]
|
||||
}
|
||||
|
||||
pub(crate) fn timestamp_at(&self, height: Height) -> Timestamp {
|
||||
pub fn timestamp_at(&self, height: Height) -> Timestamp {
|
||||
self.height_to_timestamp[height.to_usize()]
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ mod readers;
|
||||
mod recover;
|
||||
mod write;
|
||||
|
||||
pub(crate) use block_loop::process_blocks;
|
||||
pub(crate) use context::ComputeContext;
|
||||
pub(crate) use price_range_max::PriceRangeMax;
|
||||
pub(crate) use readers::{AddrReaders, IndexToTxIndexBuf, TxInReaders, TxOutData, TxOutReaders};
|
||||
pub(crate) use recover::{StartMode, determine_start_mode, reset_state};
|
||||
pub use block_loop::process_blocks;
|
||||
pub use context::ComputeContext;
|
||||
pub use price_range_max::PriceRangeMax;
|
||||
pub use readers::{AddrReaders, IndexToTxIndexBuf, TxInReaders, TxOutData, TxOutReaders};
|
||||
pub use recover::{StartMode, determine_start_mode, reset_state};
|
||||
|
||||
/// Flush checkpoint interval (every N blocks).
|
||||
pub const FLUSH_INTERVAL: usize = 10_000;
|
||||
|
||||
@@ -11,7 +11,7 @@ pub struct PriceRangeMax {
|
||||
}
|
||||
|
||||
impl PriceRangeMax {
|
||||
pub(crate) fn extend(&mut self, prices: &[Cents]) {
|
||||
pub fn extend(&mut self, prices: &[Cents]) {
|
||||
let new_n = prices.len();
|
||||
if new_n <= self.n || new_n == 0 {
|
||||
return;
|
||||
@@ -53,7 +53,7 @@ impl PriceRangeMax {
|
||||
);
|
||||
}
|
||||
|
||||
pub(crate) fn truncate(&mut self, new_n: usize) {
|
||||
pub fn truncate(&mut self, new_n: usize) {
|
||||
if new_n >= self.n {
|
||||
return;
|
||||
}
|
||||
@@ -73,7 +73,7 @@ impl PriceRangeMax {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn range_max(&self, start: usize, end: usize) -> Cents {
|
||||
pub fn range_max(&self, start: usize, end: usize) -> Cents {
|
||||
debug_assert!(start <= end && end < self.n);
|
||||
let len = end - start + 1;
|
||||
let level = (usize::BITS - len.leading_zeros() - 1) as usize;
|
||||
@@ -87,7 +87,7 @@ impl PriceRangeMax {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn max_between(&self, from: Height, to: Height) -> Cents {
|
||||
pub fn max_between(&self, from: Height, to: Height) -> Cents {
|
||||
self.range_max(from.to_usize(), to.to_usize())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ pub struct AddrReaders {
|
||||
}
|
||||
|
||||
impl AddrReaders {
|
||||
pub(crate) fn new(any_addr_indexes: &AnyAddrIndexesVecs, addrs_data: &AddrsDataVecs) -> Self {
|
||||
pub fn new(any_addr_indexes: &AnyAddrIndexesVecs, addrs_data: &AddrsDataVecs) -> Self {
|
||||
Self {
|
||||
p2a: any_addr_indexes.p2a.reader(),
|
||||
p2pk33: any_addr_indexes.p2pk33.reader(),
|
||||
@@ -37,7 +37,7 @@ impl AddrReaders {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn any_addr_index(
|
||||
pub fn any_addr_index(
|
||||
&self,
|
||||
vecs: &AnyAddrIndexesVecs,
|
||||
addr_type: OutputType,
|
||||
@@ -58,16 +58,12 @@ impl AddrReaders {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn funded_data(
|
||||
&self,
|
||||
vecs: &AddrsDataVecs,
|
||||
index: FundedAddrIndex,
|
||||
) -> FundedAddrData {
|
||||
pub fn funded_data(&self, vecs: &AddrsDataVecs, index: FundedAddrIndex) -> FundedAddrData {
|
||||
vecs.funded.get_with_reader(index, &self.funded).unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub(crate) fn empty_data(&self, vecs: &AddrsDataVecs, index: EmptyAddrIndex) -> EmptyAddrData {
|
||||
pub fn empty_data(&self, vecs: &AddrsDataVecs, index: EmptyAddrIndex) -> EmptyAddrData {
|
||||
vecs.empty.get_with_reader(index, &self.empty).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,20 @@ use brk_types::{StoredU64, TxIndex};
|
||||
use vecdb::{ReadableVec, VecIndex};
|
||||
|
||||
/// Reusable buffers for a block's index-to-transaction-index mapping.
|
||||
pub(crate) struct IndexToTxIndexBuf {
|
||||
pub struct IndexToTxIndexBuf {
|
||||
counts: Vec<StoredU64>,
|
||||
result: Vec<TxIndex>,
|
||||
}
|
||||
|
||||
impl IndexToTxIndexBuf {
|
||||
pub(crate) fn new() -> Self {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
counts: Vec::new(),
|
||||
result: Vec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn build(
|
||||
pub fn build(
|
||||
&mut self,
|
||||
block_first_tx_index: TxIndex,
|
||||
block_tx_count: u64,
|
||||
|
||||
@@ -4,8 +4,8 @@ mod tx_in;
|
||||
mod tx_out;
|
||||
mod tx_out_data;
|
||||
|
||||
pub(crate) use addr::AddrReaders;
|
||||
pub(crate) use index_to_tx_index::IndexToTxIndexBuf;
|
||||
pub(crate) use tx_in::TxInReaders;
|
||||
pub(crate) use tx_out::TxOutReaders;
|
||||
pub(crate) use tx_out_data::TxOutData;
|
||||
pub use addr::AddrReaders;
|
||||
pub use index_to_tx_index::IndexToTxIndexBuf;
|
||||
pub use tx_in::TxInReaders;
|
||||
pub use tx_out::TxOutReaders;
|
||||
pub use tx_out_data::TxOutData;
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{Height, OutPoint, OutputType, Sats, TxInIndex, TxIndex, TypeIndex};
|
||||
use brk_types::{Height, OutPoint, OutputType, RangeMap, Sats, TxInIndex, TxIndex, TypeIndex};
|
||||
use vecdb::{PcoVec, ReadableVec};
|
||||
|
||||
use crate::distribution::RangeMap;
|
||||
|
||||
/// Bulk txin reader with reusable buffers.
|
||||
pub struct TxInReaders<'a> {
|
||||
indexer: &'a Indexer,
|
||||
@@ -17,7 +15,7 @@ pub struct TxInReaders<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TxInReaders<'a> {
|
||||
pub(crate) fn new(
|
||||
pub fn new(
|
||||
indexer: &'a Indexer,
|
||||
input_values: &'a PcoVec<TxInIndex, Sats>,
|
||||
tx_index_to_height: &'a mut RangeMap<TxIndex, Height>,
|
||||
@@ -34,7 +32,7 @@ impl<'a> TxInReaders<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn collect_block_inputs(
|
||||
pub fn collect_block_inputs(
|
||||
&mut self,
|
||||
first_txin_index: usize,
|
||||
input_count: usize,
|
||||
|
||||
@@ -14,7 +14,7 @@ pub struct TxOutReaders<'a> {
|
||||
}
|
||||
|
||||
impl<'a> TxOutReaders<'a> {
|
||||
pub(crate) fn new(indexer: &'a Indexer) -> Self {
|
||||
pub fn new(indexer: &'a Indexer) -> Self {
|
||||
Self {
|
||||
indexer,
|
||||
values_buf: Vec::new(),
|
||||
@@ -24,7 +24,7 @@ impl<'a> TxOutReaders<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn collect_block_outputs(
|
||||
pub fn collect_block_outputs(
|
||||
&mut self,
|
||||
first_txout_index: usize,
|
||||
output_count: usize,
|
||||
|
||||
@@ -11,9 +11,9 @@ use super::super::{
|
||||
};
|
||||
|
||||
/// Result of state recovery.
|
||||
pub(crate) struct RecoveredState {
|
||||
pub struct RecoveredState {
|
||||
/// Height to start processing from. Zero means fresh start.
|
||||
pub(crate) starting_height: Height,
|
||||
pub starting_height: Height,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
@@ -22,7 +22,7 @@ impl Vecs {
|
||||
/// Rolls back state vectors and imports cohort states.
|
||||
/// Validates that all rollbacks and imports are consistent.
|
||||
/// Returns Height::ZERO if any validation fails (triggers fresh start).
|
||||
pub(crate) fn recover_state(
|
||||
pub fn recover_state(
|
||||
&mut self,
|
||||
height: Height,
|
||||
chain_state_rollback: Option<VecdbResult<Stamp>>,
|
||||
@@ -119,7 +119,7 @@ impl Vecs {
|
||||
/// Reset all state for fresh start.
|
||||
///
|
||||
/// Resets all state vectors and cohort states.
|
||||
pub(crate) fn reset_state(
|
||||
pub fn reset_state(
|
||||
any_addr_indexes: &mut AnyAddrIndexesVecs,
|
||||
addrs_data: &mut AddrsDataVecs,
|
||||
utxo_states: &mut UTXOStates,
|
||||
@@ -142,7 +142,7 @@ pub(crate) fn reset_state(
|
||||
///
|
||||
/// - `min_available`: minimum height we have data for across all stateful vecs
|
||||
/// - `resume_target`: the height we want to resume processing from
|
||||
pub(crate) fn determine_start_mode(min_available: Height, resume_target: Height) -> StartMode {
|
||||
pub fn determine_start_mode(min_available: Height, resume_target: Height) -> StartMode {
|
||||
// No data to resume from
|
||||
if resume_target.is_zero() {
|
||||
return StartMode::Fresh;
|
||||
|
||||
@@ -22,7 +22,7 @@ use super::super::addr::{AddrTypeToTypeIndexMap, AddrsDataVecs, AnyAddrIndexesVe
|
||||
/// - Updates address indexes
|
||||
///
|
||||
/// Call this before `flush()` to prepare data for writing.
|
||||
pub(crate) fn process_addr_updates(
|
||||
pub fn process_addr_updates(
|
||||
addrs_data: &mut AddrsDataVecs,
|
||||
addr_indexes: &mut AnyAddrIndexesVecs,
|
||||
empty_updates: AddrTypeToTypeIndexMap<WithAddrDataSource<EmptyAddrData>>,
|
||||
@@ -50,7 +50,7 @@ pub(crate) fn process_addr_updates(
|
||||
/// - Chain state
|
||||
///
|
||||
/// Set `with_changes=true` near chain tip to enable rollback support.
|
||||
pub(crate) fn write(
|
||||
pub fn write(
|
||||
vecs: &mut Vecs,
|
||||
utxo_states: &mut UTXOStates,
|
||||
addr_states: &mut AddrStates,
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
use brk_types::{Cents, Height, RangeMap, Timestamp, TxIndex};
|
||||
use vecdb::Database;
|
||||
|
||||
use super::{compute::PriceRangeMax, state::BlockState};
|
||||
|
||||
/// Private storage and transient computation state for distribution.
|
||||
#[derive(Clone)]
|
||||
pub struct Inner {
|
||||
pub db: Database,
|
||||
pub chain_state: Vec<BlockState>,
|
||||
pub tx_index_to_height: RangeMap<TxIndex, Height>,
|
||||
pub prices: Vec<Cents>,
|
||||
pub timestamps: Vec<Timestamp>,
|
||||
pub price_range_max: PriceRangeMax,
|
||||
}
|
||||
|
||||
impl Inner {
|
||||
pub fn new(db: Database) -> Self {
|
||||
Self {
|
||||
db,
|
||||
chain_state: Vec::new(),
|
||||
tx_index_to_height: RangeMap::default(),
|
||||
prices: Vec::new(),
|
||||
timestamps: Vec::new(),
|
||||
price_range_max: PriceRangeMax::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn reset(&mut self) {
|
||||
self.chain_state = Vec::new();
|
||||
self.tx_index_to_height = RangeMap::default();
|
||||
self.prices = Vec::new();
|
||||
self.timestamps = Vec::new();
|
||||
self.price_range_max = PriceRangeMax::default();
|
||||
}
|
||||
}
|
||||
@@ -19,7 +19,7 @@ pub struct CoindaysDestroyedByCohort<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl CoindaysDestroyedByCohort {
|
||||
pub(super) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
|
||||
@@ -33,7 +33,7 @@ pub struct ActivityVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl ActivityVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -117,14 +117,14 @@ impl ActivityVecs {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn sources(&self, filter: &Filter) -> Option<ActivitySources> {
|
||||
pub fn sources(&self, filter: &Filter) -> Option<ActivitySources> {
|
||||
Some(ActivitySources {
|
||||
transfer_volume: self.transfer_volume.cohorts.get(filter)?.clone(),
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(
|
||||
pub fn push(
|
||||
&mut self,
|
||||
height_price: Cents,
|
||||
transfer_volume: UTXORows<Sats>,
|
||||
@@ -150,11 +150,7 @@ impl ActivityVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_addr_balance(
|
||||
&mut self,
|
||||
height_price: Cents,
|
||||
transfer_volume: &AmountRange<Sats>,
|
||||
) {
|
||||
pub fn push_addr_balance(&mut self, height_price: Cents, transfer_volume: &AmountRange<Sats>) {
|
||||
let cents = AmountRange::from_fn(|amount| {
|
||||
SatsToCents::apply(*amount.select(transfer_volume), height_price)
|
||||
});
|
||||
@@ -162,7 +158,7 @@ impl ActivityVecs {
|
||||
.push_addr_balance(transfer_volume, ¢s);
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.transfer_volume
|
||||
.min_len()
|
||||
.min(self.coindays_destroyed.cumulative.min_len())
|
||||
@@ -177,7 +173,7 @@ impl ActivityVecs {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = self.transfer_volume.collect_vecs_mut();
|
||||
vecs.extend(self.coindays_destroyed.cumulative.collect_vecs_mut());
|
||||
vecs.extend(self.transfer_volume_in_profit.collect_vecs_mut());
|
||||
@@ -186,7 +182,7 @@ impl ActivityVecs {
|
||||
vecs
|
||||
}
|
||||
|
||||
pub(crate) fn compute_dormancy(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
|
||||
pub fn compute_dormancy(&mut self, max_from: Height, exit: &Exit) -> Result<()> {
|
||||
for id in UTXOAggregateId::ALL {
|
||||
let filter = id.select(&UTXO_AGGREGATE_FILTERS);
|
||||
let coindays_destroyed = &self
|
||||
|
||||
@@ -18,7 +18,7 @@ pub struct CoreCumulativeValueByCohort<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl CoreCumulativeValueByCohort {
|
||||
pub(super) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -51,15 +51,15 @@ impl CoreCumulativeValueByCohort {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
pub fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
self.cumulative.push_block(sats, cents);
|
||||
}
|
||||
|
||||
pub(super) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.cumulative.min_len()
|
||||
}
|
||||
|
||||
pub(super) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
self.cumulative.collect_vecs_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct CumulativeValueByCohort<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl CumulativeValueByCohort {
|
||||
pub(super) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -71,24 +71,20 @@ impl CumulativeValueByCohort {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
pub fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
self.cumulative.push_block(sats, cents);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(super) fn push_addr_balance(
|
||||
&mut self,
|
||||
sats: &AmountRange<Sats>,
|
||||
cents: &AmountRange<Cents>,
|
||||
) {
|
||||
pub fn push_addr_balance(&mut self, sats: &AmountRange<Sats>, cents: &AmountRange<Cents>) {
|
||||
self.addr_balance.push_cumulative(sats, cents);
|
||||
}
|
||||
|
||||
pub(super) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.cumulative.min_len().min(self.addr_balance.len())
|
||||
}
|
||||
|
||||
pub(super) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = self.cumulative.collect_vecs_mut();
|
||||
vecs.extend(self.addr_balance.collect_vecs_mut());
|
||||
vecs
|
||||
|
||||
@@ -4,8 +4,8 @@ mod core_cumulative_value;
|
||||
mod cumulative_value;
|
||||
mod sources;
|
||||
|
||||
pub(super) use coindays_destroyed::CoindaysDestroyedByCohort;
|
||||
pub use coindays_destroyed::CoindaysDestroyedByCohort;
|
||||
pub use collection::ActivityVecs;
|
||||
pub(super) use core_cumulative_value::CoreCumulativeValueByCohort;
|
||||
pub(super) use cumulative_value::CumulativeValueByCohort;
|
||||
pub use core_cumulative_value::CoreCumulativeValueByCohort;
|
||||
pub use cumulative_value::CumulativeValueByCohort;
|
||||
pub use sources::ActivitySources;
|
||||
|
||||
@@ -13,7 +13,7 @@ use vecdb::{
|
||||
|
||||
use crate::{
|
||||
indexes,
|
||||
internal::{ColumnarPerBlock, FiatType, LazyFiatPerBlock},
|
||||
internal::{ColumnarPerBlock, FiatType, LazyFiatPerBlock, cache_wrap},
|
||||
};
|
||||
|
||||
#[derive(Deref, DerefMut, Traversable)]
|
||||
@@ -25,7 +25,7 @@ pub struct AdditiveAggregateFiatPerBlock<C: FiatType, M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl<C: FiatType> AdditiveAggregateFiatPerBlock<C> {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -44,13 +44,12 @@ impl<C: FiatType> AdditiveAggregateFiatPerBlock<C> {
|
||||
metric,
|
||||
);
|
||||
let cents = match aggregate {
|
||||
UTXOAggregateId::All => source
|
||||
.sum_columns(
|
||||
&format!("{name}_cents"),
|
||||
version,
|
||||
TermId::ALL.iter().copied(),
|
||||
)
|
||||
.read_only_boxed_clone(),
|
||||
UTXOAggregateId::All => cache_wrap(source.sum_columns(
|
||||
&format!("{name}_cents"),
|
||||
version,
|
||||
TermId::ALL.iter().copied(),
|
||||
))
|
||||
.read_only_boxed_clone(),
|
||||
UTXOAggregateId::Sth => source
|
||||
.column(&format!("{name}_cents"), version, TermId::Short)
|
||||
.read_only_boxed_clone(),
|
||||
@@ -66,18 +65,18 @@ impl<C: FiatType> AdditiveAggregateFiatPerBlock<C> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, row: UTXOAggregate<C>) {
|
||||
pub fn push(&mut self, row: UTXOAggregate<C>) {
|
||||
self.values.push(ByTerm {
|
||||
short: row.sth,
|
||||
long: row.lth,
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.height.len()
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.values.stored_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,4 +2,4 @@ mod aggregate;
|
||||
mod utxo_raw;
|
||||
|
||||
pub use aggregate::AdditiveAggregateFiatPerBlock;
|
||||
pub(crate) use utxo_raw::AdditiveUTXORawVec;
|
||||
pub use utxo_raw::AdditiveUTXORawVec;
|
||||
|
||||
@@ -21,25 +21,25 @@ impl<T> AdditiveUTXORawVec<T>
|
||||
where
|
||||
T: BytesVecValue + AddAssign + Copy,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
matrix: ImportableVec::forced_import(db, &format!("{name}_by_term"), version)?,
|
||||
})
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, row: &UTXOAggregate<T>) {
|
||||
pub fn push(&mut self, row: &UTXOAggregate<T>) {
|
||||
self.matrix.push(ByTerm {
|
||||
short: row.sth,
|
||||
long: row.lth,
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.matrix.len()
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
&mut self.matrix
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,7 +15,7 @@ use crate::{
|
||||
indexes,
|
||||
internal::{
|
||||
CachedWindowStartVec, ColumnarPerBlockCumulativeRolling, FiatType,
|
||||
LazyFiatPerBlockCumulativeWithSums, Windows,
|
||||
LazyFiatPerBlockCumulativeWithSums, Windows, cache_wrap,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -33,7 +33,7 @@ pub struct AdditiveAggregateFiatPerBlockCumulativeWithSums<C: FiatType, M: Stora
|
||||
}
|
||||
|
||||
impl<C: FiatType> AdditiveAggregateFiatPerBlockCumulativeWithSums<C> {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -53,13 +53,12 @@ impl<C: FiatType> AdditiveAggregateFiatPerBlockCumulativeWithSums<C> {
|
||||
metric,
|
||||
);
|
||||
let cumulative = match id {
|
||||
UTXOAggregateId::All => source
|
||||
.sum_columns(
|
||||
&format!("{name}_cumulative_cents"),
|
||||
version,
|
||||
TermId::ALL.iter().copied(),
|
||||
)
|
||||
.read_only_boxed_clone(),
|
||||
UTXOAggregateId::All => cache_wrap(source.sum_columns(
|
||||
&format!("{name}_cumulative_cents"),
|
||||
version,
|
||||
TermId::ALL.iter().copied(),
|
||||
))
|
||||
.read_only_boxed_clone(),
|
||||
UTXOAggregateId::Sth => source
|
||||
.column(&format!("{name}_cumulative_cents"), version, TermId::Short)
|
||||
.read_only_boxed_clone(),
|
||||
@@ -81,18 +80,18 @@ impl<C: FiatType> AdditiveAggregateFiatPerBlockCumulativeWithSums<C> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_block(&mut self, row: UTXOAggregate<C>) {
|
||||
pub fn push_block(&mut self, row: UTXOAggregate<C>) {
|
||||
self.values.push_block(ByTerm {
|
||||
short: row.sth,
|
||||
long: row.lth,
|
||||
});
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.cumulative.len()
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.values.stored_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ pub struct AggregateFiatPerBlock<C: FiatType, M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl<C: FiatType> AggregateFiatPerBlock<C> {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -55,15 +55,15 @@ impl<C: FiatType> AggregateFiatPerBlock<C> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, row: UTXOAggregate<C>) {
|
||||
pub fn push(&mut self, row: UTXOAggregate<C>) {
|
||||
self.values.push(row);
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.height.len()
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.values.stored_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct AggregatePercentPerBlock<B: FixedRatio, M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl<B: FixedRatio> AggregatePercentPerBlock<B> {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -50,7 +50,7 @@ impl<B: FixedRatio> AggregatePercentPerBlock<B> {
|
||||
Ok(Self { values })
|
||||
}
|
||||
|
||||
pub(crate) fn compute_columns2<'a, A, C, V1, V2>(
|
||||
pub fn compute_columns2<'a, A, C, V1, V2>(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
source1: impl Fn(UTXOAggregateId) -> &'a V1,
|
||||
@@ -68,7 +68,7 @@ impl<B: FixedRatio> AggregatePercentPerBlock<B> {
|
||||
.compute_columns2(max_from, source1, source2, transform, exit)
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.values.stored_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,7 +26,7 @@ pub struct AggregatePriceWithRatioPerBlock<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AggregatePriceWithRatioPerBlock {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
metric: &str,
|
||||
version: Version,
|
||||
@@ -54,15 +54,15 @@ impl AggregatePriceWithRatioPerBlock {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, row: UTXOAggregate<Cents>) {
|
||||
pub fn push(&mut self, row: UTXOAggregate<Cents>) {
|
||||
self.values.push(row);
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.height.len()
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.values.stored_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ use brk_cohort::{
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Lengths;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Cents, Height, StoredU64, Version};
|
||||
use brk_types::{Cents, Height, Sats, StoredU64, Version};
|
||||
use rayon::prelude::*;
|
||||
use vecdb::{
|
||||
AnyStoredVec, CachedBoxedVec, ColumnId, Database, Exit, ReadOnlyClone, Rw, StorageMode,
|
||||
@@ -13,11 +13,11 @@ use vecdb::{
|
||||
|
||||
use crate::{
|
||||
distribution::{
|
||||
AllChainCache,
|
||||
AllChainSources,
|
||||
metrics::{
|
||||
ActivityVecs, AdjustedSoprComputeSource, AllSupplyCache, CostBasisVecs, OutputsVecs,
|
||||
ProfitabilityVecs, RealizedAggregateSources, RealizedAggregateState, RealizedVecs,
|
||||
RelativeSource, RelativeVecs, Sopr24hInput, SupplyVecs, UTXORows, UnrealizedVecs,
|
||||
ActivityVecs, AdjustedSoprComputeSource, CostBasisVecs, OutputsVecs, ProfitabilityVecs,
|
||||
RealizedAggregateSources, RealizedAggregateState, RealizedVecs, RelativeSource,
|
||||
RelativeVecs, Sopr24hInput, SupplyVecs, UTXORows, UnrealizedVecs,
|
||||
},
|
||||
state::{AddrCohortState, RealizedOps, UTXOStates, UnrealizedState},
|
||||
},
|
||||
@@ -38,13 +38,11 @@ pub struct CohortMetrics<M: StorageMode = Rw> {
|
||||
pub cost_basis: Box<CostBasisVecs<M>>,
|
||||
pub relative: Box<RelativeVecs<M>>,
|
||||
pub profitability: Box<ProfitabilityVecs<M>>,
|
||||
#[traversable(skip)]
|
||||
all_supply_cache: AllSupplyCache,
|
||||
}
|
||||
|
||||
impl CohortMetrics<Rw> {
|
||||
/// Import all cohort metrics from the database.
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -54,10 +52,14 @@ impl CohortMetrics<Rw> {
|
||||
let v = version + VERSION;
|
||||
|
||||
// Phase 1: Import supply first so its shared sources can back every cohort view.
|
||||
let (supply, all_supply_cache) =
|
||||
SupplyVecs::forced_import(db, v, indexes, cached_starts, spot_price)?;
|
||||
let supply = Box::new(supply);
|
||||
let all_chain_cache = AllChainCache::new(&all_supply_cache, spot_price);
|
||||
let supply = Box::new(SupplyVecs::forced_import(
|
||||
db,
|
||||
v,
|
||||
indexes,
|
||||
cached_starts,
|
||||
spot_price,
|
||||
)?);
|
||||
let all_chain_sources = AllChainSources::new(supply.total.all_supply(), spot_price);
|
||||
let outputs = Box::new(OutputsVecs::forced_import(db, v, indexes, cached_starts)?);
|
||||
let activity = Box::new(ActivityVecs::forced_import(db, v, indexes, cached_starts)?);
|
||||
let realized = Box::new(RealizedVecs::forced_import(
|
||||
@@ -66,7 +68,7 @@ impl CohortMetrics<Rw> {
|
||||
indexes,
|
||||
cached_starts,
|
||||
spot_price,
|
||||
&all_chain_cache,
|
||||
&all_chain_sources,
|
||||
)?);
|
||||
let unrealized = Box::new(UnrealizedVecs::forced_import(
|
||||
db,
|
||||
@@ -103,7 +105,7 @@ impl CohortMetrics<Rw> {
|
||||
db,
|
||||
v,
|
||||
indexes,
|
||||
&all_chain_cache,
|
||||
&all_chain_sources,
|
||||
&relative_sources,
|
||||
)?);
|
||||
|
||||
@@ -116,17 +118,16 @@ impl CohortMetrics<Rw> {
|
||||
cost_basis,
|
||||
relative,
|
||||
profitability,
|
||||
all_supply_cache,
|
||||
})
|
||||
}
|
||||
|
||||
/// Reset in-memory caches that become stale after rollback.
|
||||
pub(crate) fn reset_caches(&mut self) {
|
||||
self.all_supply_cache.clear();
|
||||
pub fn reset_caches(&mut self) {
|
||||
self.supply.total.all_supply().clear();
|
||||
}
|
||||
|
||||
pub(crate) fn all_supply_cache(&self) -> &AllSupplyCache {
|
||||
&self.all_supply_cache
|
||||
pub fn all_supply(&self) -> &CachedBoxedVec<Height, Sats> {
|
||||
self.supply.total.all_supply()
|
||||
}
|
||||
|
||||
fn sopr_24h_inputs(&self) -> UTXOGroupsWithoutAmountOrType<Sopr24hInput> {
|
||||
@@ -147,7 +148,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_supply_and_unrealized(
|
||||
pub fn push_supply_and_unrealized(
|
||||
&mut self,
|
||||
states: &mut UTXOStates,
|
||||
height_price: Cents,
|
||||
@@ -209,7 +210,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_outputs(&mut self, states: &UTXOStates) {
|
||||
pub fn push_outputs(&mut self, states: &UTXOStates) {
|
||||
let outputs = &mut self.outputs;
|
||||
let UTXOStates {
|
||||
age_range,
|
||||
@@ -235,7 +236,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_activity(&mut self, states: &UTXOStates, height_price: Cents) {
|
||||
pub fn push_activity(&mut self, states: &UTXOStates, height_price: Cents) {
|
||||
let activity = &mut self.activity;
|
||||
let UTXOStates {
|
||||
age_range,
|
||||
@@ -277,7 +278,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_realized(&mut self, states: &UTXOStates) {
|
||||
pub fn push_realized(&mut self, states: &UTXOStates) {
|
||||
let realized = &mut self.realized;
|
||||
let UTXOStates {
|
||||
age_range,
|
||||
@@ -301,7 +302,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_addr_balance(
|
||||
pub fn push_addr_balance(
|
||||
&mut self,
|
||||
states: &AmountRange<AddrCohortState>,
|
||||
height_price: Cents,
|
||||
@@ -327,11 +328,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
/// First phase of post-processing: compute index transforms.
|
||||
pub(crate) fn compute_rest_part1(
|
||||
&mut self,
|
||||
starting_lengths: &Lengths,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
pub fn compute_rest_part1(&mut self, starting_lengths: &Lengths, exit: &Exit) -> Result<()> {
|
||||
self.activity
|
||||
.compute_dormancy(starting_lengths.height, exit)?;
|
||||
|
||||
@@ -339,11 +336,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
/// Second phase of post-processing: compute derived ratios and relative metrics.
|
||||
pub(crate) fn compute_rest_part2(
|
||||
&mut self,
|
||||
starting_lengths: &Lengths,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
pub fn compute_rest_part2(&mut self, starting_lengths: &Lengths, exit: &Exit) -> Result<()> {
|
||||
// Get under_1h value sources for adjusted computation (cloned to avoid borrow conflicts).
|
||||
let under_1h_value_created = self
|
||||
.activity
|
||||
@@ -456,9 +449,7 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
/// Returns a parallel iterator over all vecs for parallel writing.
|
||||
pub(crate) fn par_iter_vecs_mut(
|
||||
&mut self,
|
||||
) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
pub fn par_iter_vecs_mut(&mut self) -> impl ParallelIterator<Item = &mut dyn AnyStoredVec> {
|
||||
let mut vecs: Vec<&mut dyn AnyStoredVec> = Vec::with_capacity(128);
|
||||
vecs.extend(self.supply.collect_vecs_mut());
|
||||
vecs.extend(self.outputs.collect_vecs_mut());
|
||||
@@ -471,7 +462,7 @@ impl CohortMetrics<Rw> {
|
||||
vecs.into_par_iter()
|
||||
}
|
||||
|
||||
pub(crate) fn min_stateful_len(&self) -> Height {
|
||||
pub fn min_stateful_len(&self) -> Height {
|
||||
Height::from(self.supply.min_len())
|
||||
.min(Height::from(self.outputs.min_len()))
|
||||
.min(Height::from(self.activity.min_len()))
|
||||
@@ -482,13 +473,13 @@ impl CohortMetrics<Rw> {
|
||||
}
|
||||
|
||||
/// Validate computed versions for all cohorts.
|
||||
pub(crate) fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
|
||||
pub fn validate_computed_versions(&mut self, base_version: Version) -> Result<()> {
|
||||
self.cost_basis.validate_computed_versions(base_version)
|
||||
}
|
||||
|
||||
/// Aggregate realized fields from age-range states and push all/STH/LTH.
|
||||
/// Called during the block loop after separate cohorts' push_state but before reset.
|
||||
pub(crate) fn push_overlapping(
|
||||
pub fn push_overlapping(
|
||||
&mut self,
|
||||
states: &UTXOStates,
|
||||
height_price: Cents,
|
||||
|
||||
@@ -2,6 +2,6 @@ mod with_amount_and_type;
|
||||
mod without_amount;
|
||||
mod without_amount_or_type;
|
||||
|
||||
pub(crate) use with_amount_and_type::UTXOColumnarMetric;
|
||||
pub(crate) use without_amount::UTXOColumnarMetricWithoutAmount;
|
||||
pub(crate) use without_amount_or_type::UTXOColumnarMetricWithoutAmountOrType;
|
||||
pub use with_amount_and_type::UTXOColumnarMetric;
|
||||
pub use without_amount::UTXOColumnarMetricWithoutAmount;
|
||||
pub use without_amount_or_type::UTXOColumnarMetricWithoutAmountOrType;
|
||||
|
||||
+7
-7
@@ -32,7 +32,7 @@ impl<T> UTXOColumnarMetric<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let version = version + Version::ONE;
|
||||
Ok(Self {
|
||||
age_range_matrix: EagerVec::forced_import(
|
||||
@@ -52,7 +52,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn additive_source(
|
||||
pub fn additive_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -70,7 +70,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn direct_source(
|
||||
pub fn direct_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -131,7 +131,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.age_range_matrix
|
||||
.len()
|
||||
.min(self.epoch_matrix.len())
|
||||
@@ -142,7 +142,7 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, rows: UTXORows<T>) {
|
||||
pub fn push(&mut self, rows: UTXORows<T>) {
|
||||
let UTXORows {
|
||||
age_range,
|
||||
epoch,
|
||||
@@ -159,7 +159,7 @@ where
|
||||
self.amount_range_matrix.push(amount_range);
|
||||
}
|
||||
|
||||
pub(crate) fn collect_last(&self) -> Option<UTXORows<T>>
|
||||
pub fn collect_last(&self) -> Option<UTXORows<T>>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
@@ -173,7 +173,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.age_range_matrix,
|
||||
&mut self.epoch_matrix,
|
||||
|
||||
@@ -30,7 +30,7 @@ impl<T> UTXOColumnarMetricWithoutAmount<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let version = version + Version::ONE;
|
||||
Ok(Self {
|
||||
age_range_matrix: EagerVec::forced_import(
|
||||
@@ -45,7 +45,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn additive_source(
|
||||
pub fn additive_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -61,7 +61,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn direct_source(
|
||||
pub fn direct_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -91,7 +91,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.age_range_matrix
|
||||
.len()
|
||||
.min(self.epoch_matrix.len())
|
||||
@@ -101,7 +101,7 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, rows: UTXORows<T>) {
|
||||
pub fn push(&mut self, rows: UTXORows<T>) {
|
||||
let UTXORows {
|
||||
age_range,
|
||||
epoch,
|
||||
@@ -117,7 +117,7 @@ where
|
||||
self.type_matrix.push(type_);
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.age_range_matrix,
|
||||
&mut self.epoch_matrix,
|
||||
|
||||
+27
-14
@@ -15,6 +15,7 @@ use vecdb::{
|
||||
};
|
||||
|
||||
use super::super::UTXORows;
|
||||
use crate::internal::cache_wrap;
|
||||
|
||||
#[derive(Traversable)]
|
||||
pub struct UTXOColumnarMetricWithoutAmountOrType<T, M: StorageMode = Rw>
|
||||
@@ -31,7 +32,7 @@ impl<T> UTXOColumnarMetricWithoutAmountOrType<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let version = version + Version::ONE;
|
||||
Ok(Self {
|
||||
age_range_matrix: EagerVec::forced_import(
|
||||
@@ -45,7 +46,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn additive_source(
|
||||
pub fn additive_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -55,7 +56,7 @@ where
|
||||
.or_else(|| self.aggregate_source(filter, name, version))
|
||||
}
|
||||
|
||||
pub(super) fn direct_source(
|
||||
pub fn direct_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -72,7 +73,7 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn direct_source_from(
|
||||
pub fn direct_source_from(
|
||||
age_range_matrix: &ReadOnlyColumnarVec<PcoVec<Height, T>, AgeRangeId>,
|
||||
epoch_matrix: &ReadOnlyColumnarVec<PcoVec<Height, T>, EpochId>,
|
||||
class_matrix: &ReadOnlyColumnarVec<PcoVec<Height, T>, ClassId>,
|
||||
@@ -103,7 +104,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn aggregate_source(
|
||||
pub fn aggregate_source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -117,14 +118,14 @@ where
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn aggregate_source_from(
|
||||
pub fn aggregate_source_from(
|
||||
age_range_matrix: &ReadOnlyColumnarVec<PcoVec<Height, T>, AgeRangeId>,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
version: Version,
|
||||
) -> Option<ReadableBoxedVec<Height, T>> {
|
||||
match filter {
|
||||
Filter::All => Some(Self::sum(
|
||||
Filter::All => Some(Self::budgeted_sum(
|
||||
age_range_matrix,
|
||||
name,
|
||||
version,
|
||||
@@ -165,7 +166,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn column<C>(
|
||||
pub fn column<C>(
|
||||
source: &ReadOnlyColumnarVec<PcoVec<Height, T>, C>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -177,7 +178,7 @@ where
|
||||
source.column(name, version, column).read_only_boxed_clone()
|
||||
}
|
||||
|
||||
pub(super) fn sum<C>(
|
||||
pub fn sum<C>(
|
||||
source: &ReadOnlyColumnarVec<PcoVec<Height, T>, C>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -191,7 +192,19 @@ where
|
||||
.read_only_boxed_clone()
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
fn budgeted_sum<C>(
|
||||
source: &ReadOnlyColumnarVec<PcoVec<Height, T>, C>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
columns: impl IntoIterator<Item = C>,
|
||||
) -> ReadableBoxedVec<Height, T>
|
||||
where
|
||||
C: ColumnId,
|
||||
{
|
||||
cache_wrap(source.sum_columns(name, version, columns)).read_only_boxed_clone()
|
||||
}
|
||||
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.age_range_matrix
|
||||
.len()
|
||||
.min(self.epoch_matrix.len())
|
||||
@@ -199,7 +212,7 @@ where
|
||||
.min(self.entry_matrix.len())
|
||||
}
|
||||
|
||||
pub(super) fn push_parts(
|
||||
pub fn push_parts(
|
||||
&mut self,
|
||||
age_range: AgeRange<T>,
|
||||
epoch: ByEpoch<T>,
|
||||
@@ -213,11 +226,11 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, rows: UTXORows<T>) {
|
||||
pub fn push(&mut self, rows: UTXORows<T>) {
|
||||
self.push_parts(rows.age_range, rows.epoch, rows.class, rows.entry);
|
||||
}
|
||||
|
||||
pub(crate) fn collect_last(&self) -> Option<UTXORows<T>>
|
||||
pub fn collect_last(&self) -> Option<UTXORows<T>>
|
||||
where
|
||||
T: Default,
|
||||
{
|
||||
@@ -231,7 +244,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
vec![
|
||||
&mut self.age_range_matrix,
|
||||
&mut self.epoch_matrix,
|
||||
|
||||
@@ -29,7 +29,7 @@ impl<T, S: Clone> ColumnarAmount<T, S>
|
||||
where
|
||||
T: PcoVecValue + AddAssign,
|
||||
{
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
matrix_name: &str,
|
||||
context: CohortContext,
|
||||
@@ -71,12 +71,12 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, row: AmountRange<T>) {
|
||||
pub fn push(&mut self, row: AmountRange<T>) {
|
||||
self.matrix.push(row);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_cumulative(&mut self, delta: &AmountRange<T>)
|
||||
pub fn push_cumulative(&mut self, delta: &AmountRange<T>)
|
||||
where
|
||||
T: AddAssign + Default,
|
||||
{
|
||||
@@ -92,16 +92,16 @@ where
|
||||
self.last = Some((len + 1, cumulative));
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.matrix.len()
|
||||
}
|
||||
|
||||
pub(crate) fn reset(&mut self) -> Result<()> {
|
||||
pub fn reset(&mut self) -> Result<()> {
|
||||
self.last = None;
|
||||
self.matrix.reset().map_err(Into::into)
|
||||
}
|
||||
|
||||
pub(crate) fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
pub fn stored_mut(&mut self) -> &mut dyn AnyStoredVec {
|
||||
self.last = None;
|
||||
&mut self.matrix
|
||||
}
|
||||
|
||||
@@ -17,7 +17,7 @@ pub struct ColumnarAmountValue<S: Clone, M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl<S: Clone> ColumnarAmountValue<S> {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
matrix_name: &str,
|
||||
context: CohortContext,
|
||||
@@ -63,15 +63,15 @@ impl<S: Clone> ColumnarAmountValue<S> {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_cumulative(&mut self, sats: &AmountRange<Sats>, cents: &AmountRange<Cents>) {
|
||||
pub fn push_cumulative(&mut self, sats: &AmountRange<Sats>, cents: &AmountRange<Cents>) {
|
||||
self.values.push_block(sats.clone(), cents.clone());
|
||||
}
|
||||
|
||||
pub(crate) fn len(&self) -> usize {
|
||||
pub fn len(&self) -> usize {
|
||||
self.values.len()
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
self.values.collect_vecs_mut()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@ mod value_without_amount_or_type;
|
||||
mod with_amount_and_type;
|
||||
mod without_amount_or_type;
|
||||
|
||||
pub(crate) use value_with_amount_and_type::CumulativeUTXOValueColumnarMetric;
|
||||
pub(crate) use value_without_amount_or_type::CumulativeUTXOValueColumnarMetricWithoutAmountOrType;
|
||||
pub(crate) use with_amount_and_type::CumulativeUTXOColumnarMetric;
|
||||
pub(crate) use without_amount_or_type::CumulativeUTXOColumnarMetricWithoutAmountOrType;
|
||||
pub use value_with_amount_and_type::CumulativeUTXOValueColumnarMetric;
|
||||
pub use value_without_amount_or_type::CumulativeUTXOValueColumnarMetricWithoutAmountOrType;
|
||||
pub use with_amount_and_type::CumulativeUTXOColumnarMetric;
|
||||
pub use without_amount_or_type::CumulativeUTXOColumnarMetricWithoutAmountOrType;
|
||||
|
||||
+11
-11
@@ -23,7 +23,7 @@ pub struct CumulativeUTXOValueColumnarMetric<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl CumulativeUTXOValueColumnarMetric {
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let version = version + Version::ONE;
|
||||
Ok(Self {
|
||||
age_range: Self::import(db, &format!("utxos_{name}_by_age_range"), version)?,
|
||||
@@ -46,7 +46,7 @@ impl CumulativeUTXOValueColumnarMetric {
|
||||
ColumnarValuePerBlockCumulativeRolling::forced_import(db, name, version, |_, _| ())
|
||||
}
|
||||
|
||||
pub(crate) fn sources(
|
||||
pub fn sources(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -120,12 +120,12 @@ impl CumulativeUTXOValueColumnarMetric {
|
||||
ReadableBoxedVec<Height, Cents>,
|
||||
)> {
|
||||
let columns = CumulativeUTXOValueColumnarMetricWithoutAmountOrType::age_columns(filter)?;
|
||||
Some(Self::matrix_sources(
|
||||
&self.age_range,
|
||||
name,
|
||||
version,
|
||||
columns,
|
||||
))
|
||||
Some(if matches!(filter, Filter::All) {
|
||||
self.age_range
|
||||
.budgeted_sources(&format!("{name}_cumulative"), version, columns)
|
||||
} else {
|
||||
Self::matrix_sources(&self.age_range, name, version, columns)
|
||||
})
|
||||
}
|
||||
|
||||
fn matrix_sources<C>(
|
||||
@@ -146,7 +146,7 @@ impl CumulativeUTXOValueColumnarMetric {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
pub fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
self.age_range.push_block(sats.age_range, cents.age_range);
|
||||
self.epoch.push_block(sats.epoch, cents.epoch);
|
||||
self.class.push_block(sats.class, cents.class);
|
||||
@@ -156,7 +156,7 @@ impl CumulativeUTXOValueColumnarMetric {
|
||||
self.type_.push_block(sats.type_, cents.type_);
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.age_range
|
||||
.len()
|
||||
.min(self.epoch.len())
|
||||
@@ -166,7 +166,7 @@ impl CumulativeUTXOValueColumnarMetric {
|
||||
.min(self.type_.len())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let Self {
|
||||
age_range,
|
||||
epoch,
|
||||
|
||||
+16
-16
@@ -20,7 +20,7 @@ pub struct CumulativeUTXOValueColumnarMetricWithoutAmountOrType<M: StorageMode =
|
||||
}
|
||||
|
||||
impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let version = version + Version::ONE;
|
||||
Ok(Self {
|
||||
age_range: Self::import(db, &format!("utxos_{name}_by_age_range"), version)?,
|
||||
@@ -41,7 +41,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
ColumnarValuePerBlockCumulativeRolling::forced_import(db, name, version, |_, _| ())
|
||||
}
|
||||
|
||||
pub(crate) fn sources(
|
||||
pub fn sources(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -54,7 +54,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
.or_else(|| self.aggregate_sources(filter, name, version))
|
||||
}
|
||||
|
||||
pub(super) fn direct_sources(
|
||||
pub fn direct_sources(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -74,7 +74,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
)
|
||||
}
|
||||
|
||||
pub(super) fn direct_sources_from(
|
||||
pub fn direct_sources_from(
|
||||
age_range: &ColumnarValuePerBlockCumulativeRolling<AgeRangeId, ()>,
|
||||
epoch: &ColumnarValuePerBlockCumulativeRolling<EpochId, ()>,
|
||||
class: &ColumnarValuePerBlockCumulativeRolling<ClassId, ()>,
|
||||
@@ -108,7 +108,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn aggregate_sources(
|
||||
pub fn aggregate_sources(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -118,15 +118,15 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
ReadableBoxedVec<Height, Cents>,
|
||||
)> {
|
||||
let columns = Self::age_columns(filter)?;
|
||||
Some(Self::matrix_sources(
|
||||
&self.age_range,
|
||||
name,
|
||||
version,
|
||||
columns,
|
||||
))
|
||||
Some(if matches!(filter, Filter::All) {
|
||||
self.age_range
|
||||
.budgeted_sources(&format!("{name}_cumulative"), version, columns)
|
||||
} else {
|
||||
Self::matrix_sources(&self.age_range, name, version, columns)
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn age_columns(filter: &Filter) -> Option<Vec<AgeRangeId>> {
|
||||
pub fn age_columns(filter: &Filter) -> Option<Vec<AgeRangeId>> {
|
||||
Some(match filter {
|
||||
Filter::All => AgeRangeId::ALL.to_vec(),
|
||||
Filter::Term(term) => {
|
||||
@@ -149,7 +149,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
})
|
||||
}
|
||||
|
||||
pub(super) fn matrix_sources<C>(
|
||||
pub fn matrix_sources<C>(
|
||||
matrix: &ColumnarValuePerBlockCumulativeRolling<C, ()>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -165,14 +165,14 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
pub fn push_block(&mut self, sats: UTXORows<Sats>, cents: UTXORows<Cents>) {
|
||||
self.age_range.push_block(sats.age_range, cents.age_range);
|
||||
self.epoch.push_block(sats.epoch, cents.epoch);
|
||||
self.class.push_block(sats.class, cents.class);
|
||||
self.entry.push_block(sats.entry, cents.entry);
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.age_range
|
||||
.len()
|
||||
.min(self.epoch.len())
|
||||
@@ -180,7 +180,7 @@ impl CumulativeUTXOValueColumnarMetricWithoutAmountOrType {
|
||||
.min(self.entry.len())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let Self {
|
||||
age_range,
|
||||
epoch,
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ impl<T> CumulativeUTXOColumnarMetric<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign + Copy + Default,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
matrices: UTXOColumnarMetric::forced_import(db, name, version)?,
|
||||
last: None,
|
||||
@@ -30,7 +30,7 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_block(&mut self, rows: UTXORows<T>) {
|
||||
pub fn push_block(&mut self, rows: UTXORows<T>) {
|
||||
let len = self.matrices.min_len();
|
||||
let mut cumulative = match self.last.take() {
|
||||
Some((cached_len, row)) if cached_len == len => row,
|
||||
@@ -41,11 +41,11 @@ where
|
||||
self.last = Some((len + 1, cumulative));
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.matrices.min_len()
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
self.last = None;
|
||||
self.matrices.collect_vecs_mut()
|
||||
}
|
||||
|
||||
+4
-4
@@ -22,7 +22,7 @@ impl<T> CumulativeUTXOColumnarMetricWithoutAmountOrType<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign + Copy + Default,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
matrices: UTXOColumnarMetricWithoutAmountOrType::forced_import(db, name, version)?,
|
||||
last: None,
|
||||
@@ -30,7 +30,7 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_block(&mut self, rows: UTXORows<T>) {
|
||||
pub fn push_block(&mut self, rows: UTXORows<T>) {
|
||||
let len = self.matrices.min_len();
|
||||
let mut cumulative = match self.last.take() {
|
||||
Some((cached_len, row)) if cached_len == len => row,
|
||||
@@ -41,11 +41,11 @@ where
|
||||
self.last = Some((len + 1, cumulative));
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.matrices.min_len()
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
self.last = None;
|
||||
self.matrices.collect_vecs_mut()
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ impl<T> ExactUTXOColumnarMetric<T>
|
||||
where
|
||||
T: PcoVecValue + AddAssign,
|
||||
{
|
||||
pub(crate) fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, name: &str, version: Version) -> Result<Self> {
|
||||
let direct = UTXOColumnarMetric::forced_import(db, name, version)?;
|
||||
let version = version + Version::ONE;
|
||||
|
||||
@@ -67,7 +67,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn source(
|
||||
pub fn source(
|
||||
&self,
|
||||
filter: &Filter,
|
||||
name: &str,
|
||||
@@ -127,7 +127,7 @@ where
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, direct: UTXORows<T>, aggregates: UTXOAggregateRows<T>) {
|
||||
pub fn push(&mut self, direct: UTXORows<T>, aggregates: UTXOAggregateRows<T>) {
|
||||
self.direct.push(direct);
|
||||
self.aggregate_matrix.push(aggregates.aggregate);
|
||||
self.under_age_matrix.push(aggregates.under_age);
|
||||
@@ -136,7 +136,7 @@ where
|
||||
self.over_amount_matrix.push(aggregates.over_amount);
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.direct
|
||||
.min_len()
|
||||
.min(self.aggregate_matrix.len())
|
||||
@@ -146,7 +146,7 @@ where
|
||||
.min(self.over_amount_matrix.len())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let Self {
|
||||
direct,
|
||||
aggregate_matrix,
|
||||
|
||||
@@ -5,14 +5,14 @@ mod cumulative;
|
||||
mod exact;
|
||||
mod rows;
|
||||
|
||||
pub(crate) use additive::{
|
||||
pub use additive::{
|
||||
UTXOColumnarMetric, UTXOColumnarMetricWithoutAmount, UTXOColumnarMetricWithoutAmountOrType,
|
||||
};
|
||||
pub use amount::ColumnarAmount;
|
||||
pub use amount_value::ColumnarAmountValue;
|
||||
pub(crate) use cumulative::{
|
||||
pub use cumulative::{
|
||||
CumulativeUTXOColumnarMetric, CumulativeUTXOColumnarMetricWithoutAmountOrType,
|
||||
CumulativeUTXOValueColumnarMetric, CumulativeUTXOValueColumnarMetricWithoutAmountOrType,
|
||||
};
|
||||
pub(crate) use exact::ExactUTXOColumnarMetric;
|
||||
pub(crate) use rows::{UTXOAggregateRows, UTXORows};
|
||||
pub use exact::ExactUTXOColumnarMetric;
|
||||
pub use rows::{UTXOAggregateRows, UTXORows};
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_cohort::{OverAge, OverAmount, UTXOAggregate, UnderAge, UnderAmount};
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct UTXOAggregateRows<T> {
|
||||
pub struct UTXOAggregateRows<T> {
|
||||
pub aggregate: UTXOAggregate<T>,
|
||||
pub under_age: UnderAge<T>,
|
||||
pub over_age: OverAge<T>,
|
||||
@@ -10,7 +10,7 @@ pub(crate) struct UTXOAggregateRows<T> {
|
||||
}
|
||||
|
||||
impl<T> UTXOAggregateRows<T> {
|
||||
pub(crate) fn map<U>(&self, mut map: impl FnMut(&T) -> U) -> UTXOAggregateRows<U> {
|
||||
pub fn map<U>(&self, mut map: impl FnMut(&T) -> U) -> UTXOAggregateRows<U> {
|
||||
UTXOAggregateRows {
|
||||
aggregate: self.aggregate.map(&mut map),
|
||||
under_age: UnderAge::from_fn(|id| map(id.select(&self.under_age))),
|
||||
|
||||
@@ -11,7 +11,7 @@ use vecdb::{ColumnId, VecValue};
|
||||
use super::UTXOAggregateRows;
|
||||
|
||||
#[derive(Clone, Default)]
|
||||
pub(crate) struct UTXORows<T> {
|
||||
pub struct UTXORows<T> {
|
||||
pub age_range: AgeRange<T>,
|
||||
pub epoch: ByEpoch<T>,
|
||||
pub class: Class<T>,
|
||||
@@ -21,7 +21,7 @@ pub(crate) struct UTXORows<T> {
|
||||
}
|
||||
|
||||
impl<T> UTXORows<T> {
|
||||
pub(crate) fn map<U>(&self, mut map: impl FnMut(&T) -> U) -> UTXORows<U> {
|
||||
pub fn map<U>(&self, mut map: impl FnMut(&T) -> U) -> UTXORows<U> {
|
||||
UTXORows {
|
||||
age_range: AgeRange::from_fn(|id| map(id.select(&self.age_range))),
|
||||
epoch: ByEpoch::from_fn(|id| map(id.select(&self.epoch))),
|
||||
@@ -32,7 +32,7 @@ impl<T> UTXORows<T> {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn aggregate(&self) -> UTXOAggregateRows<T>
|
||||
pub fn aggregate(&self) -> UTXOAggregateRows<T>
|
||||
where
|
||||
T: AddAssign + Clone + Default,
|
||||
{
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
mod aggregate;
|
||||
mod direct;
|
||||
|
||||
pub(crate) use aggregate::UTXOAggregateRows;
|
||||
pub(crate) use direct::UTXORows;
|
||||
pub use aggregate::UTXOAggregateRows;
|
||||
pub use direct::UTXORows;
|
||||
|
||||
@@ -4,7 +4,7 @@ use crate::distribution::state::PercentileResult;
|
||||
use crate::internal::PERCENTILES_LEN;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct CostBasisBlockData {
|
||||
pub struct CostBasisBlockData {
|
||||
pub min: Cents,
|
||||
pub max: Cents,
|
||||
pub per_coin: [Cents; PERCENTILES_LEN],
|
||||
@@ -14,7 +14,7 @@ pub(crate) struct CostBasisBlockData {
|
||||
|
||||
impl CostBasisBlockData {
|
||||
#[inline(always)]
|
||||
pub(crate) fn from_percentiles(
|
||||
pub fn from_percentiles(
|
||||
percentiles: PercentileResult,
|
||||
supply_density: PartsPerMillion32,
|
||||
) -> Self {
|
||||
|
||||
@@ -4,6 +4,6 @@ mod side;
|
||||
mod vecs;
|
||||
|
||||
pub use base::CostBasis;
|
||||
pub(crate) use block_data::CostBasisBlockData;
|
||||
pub use block_data::CostBasisBlockData;
|
||||
pub use side::CostBasisSide;
|
||||
pub use vecs::CostBasisVecs;
|
||||
|
||||
@@ -76,11 +76,7 @@ pub struct CostBasisVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl CostBasisVecs {
|
||||
pub(crate) fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
let aggregate_version = version + Version::ONE;
|
||||
let in_profit_per_coin_source = Self::import_prices(
|
||||
db,
|
||||
@@ -218,7 +214,7 @@ impl CostBasisVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_prices(&mut self, spot: Cents, states: &UTXOAggregate<UnrealizedState>) {
|
||||
pub fn push_prices(&mut self, spot: Cents, states: &UTXOAggregate<UnrealizedState>) {
|
||||
self.in_profit_per_coin_source
|
||||
.push(UTXOAggregate::from_fn(|id| {
|
||||
Self::per_coin_price(spot, id.select(states), true)
|
||||
@@ -286,7 +282,7 @@ impl CostBasisVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(&mut self, rows: UTXOAggregate<CostBasisBlockData>) {
|
||||
pub fn push(&mut self, rows: UTXOAggregate<CostBasisBlockData>) {
|
||||
self.min_source
|
||||
.push(UTXOAggregate::from_fn(|id| id.select(&rows).min));
|
||||
self.max_source
|
||||
@@ -301,7 +297,7 @@ impl CostBasisVecs {
|
||||
self.per_dollar_sources.lth.push(&rows.lth.per_dollar);
|
||||
}
|
||||
|
||||
pub(crate) fn validate_computed_versions(&mut self, version: Version) -> Result<()> {
|
||||
pub fn validate_computed_versions(&mut self, version: Version) -> Result<()> {
|
||||
for percentiles in self
|
||||
.per_coin_sources
|
||||
.iter_mut()
|
||||
@@ -312,7 +308,7 @@ impl CostBasisVecs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.in_profit_per_coin_source
|
||||
.height
|
||||
.len()
|
||||
@@ -332,7 +328,7 @@ impl CostBasisVecs {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = vec![
|
||||
self.in_profit_per_coin_source.stored_mut(),
|
||||
self.in_profit_per_dollar_source.stored_mut(),
|
||||
|
||||
@@ -15,28 +15,27 @@ mod unrealized;
|
||||
|
||||
pub use activity::{ActivitySources, ActivityVecs};
|
||||
pub use additive::AdditiveAggregateFiatPerBlock;
|
||||
pub(crate) use additive::AdditiveUTXORawVec;
|
||||
pub use additive::AdditiveUTXORawVec;
|
||||
pub use aggregate::{
|
||||
AdditiveAggregateFiatPerBlockCumulativeWithSums, AggregateFiatPerBlock,
|
||||
AggregatePercentPerBlock, AggregatePriceWithRatioPerBlock,
|
||||
};
|
||||
pub use cohorts::CohortMetrics;
|
||||
pub use columnar::{ColumnarAmount, ColumnarAmountValue};
|
||||
pub(crate) use columnar::{
|
||||
pub use columnar::{
|
||||
CumulativeUTXOColumnarMetric, CumulativeUTXOColumnarMetricWithoutAmountOrType,
|
||||
CumulativeUTXOValueColumnarMetric, CumulativeUTXOValueColumnarMetricWithoutAmountOrType,
|
||||
ExactUTXOColumnarMetric, UTXOColumnarMetric, UTXOColumnarMetricWithoutAmount,
|
||||
UTXOColumnarMetricWithoutAmountOrType, UTXORows,
|
||||
};
|
||||
pub(crate) use cost_basis::CostBasisBlockData;
|
||||
pub use cost_basis::CostBasisBlockData;
|
||||
pub use cost_basis::CostBasisVecs;
|
||||
pub use outputs::OutputsVecs;
|
||||
pub use profitability::ProfitabilityVecs;
|
||||
pub(crate) use realized::{AdjustedSoprComputeSource, RealizedAggregateSources};
|
||||
pub use realized::{AdjustedSoprComputeSource, RealizedAggregateSources};
|
||||
pub use realized::{RealizedAggregateState, RealizedSources, RealizedVecs};
|
||||
pub(crate) use realized::{RealizedBlockData, RealizedTotals, Sopr24hInput};
|
||||
pub(crate) use relative::RelativeSource;
|
||||
pub use realized::{RealizedBlockData, RealizedTotals, Sopr24hInput};
|
||||
pub use relative::RelativeSource;
|
||||
pub use relative::RelativeVecs;
|
||||
pub(crate) use supply::AllSupplyCache;
|
||||
pub use supply::{SupplySources, SupplyVecs};
|
||||
pub use unrealized::{UnrealizedAggregateSources, UnrealizedSources, UnrealizedVecs};
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct OutputsVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl OutputsVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -32,21 +32,17 @@ impl OutputsVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(
|
||||
&mut self,
|
||||
unspent_count: UTXORows<StoredU64>,
|
||||
spent_count: UTXORows<StoredU64>,
|
||||
) {
|
||||
pub fn push(&mut self, unspent_count: UTXORows<StoredU64>, spent_count: UTXORows<StoredU64>) {
|
||||
self.unspent_count.matrices.push(unspent_count);
|
||||
self.spent_count.cumulative.push_block(spent_count);
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_addr_balance(&mut self, row: AmountRange<StoredU64>) {
|
||||
pub fn push_addr_balance(&mut self, row: AmountRange<StoredU64>) {
|
||||
self.unspent_count.push_addr_balance(row);
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.unspent_count
|
||||
.matrices
|
||||
.min_len()
|
||||
@@ -54,7 +50,7 @@ impl OutputsVecs {
|
||||
.min(self.spent_count.cumulative.min_len())
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = self.unspent_count.matrices.collect_vecs_mut();
|
||||
vecs.push(self.unspent_count.addr_balance.stored_mut());
|
||||
vecs.extend(self.spent_count.cumulative.collect_vecs_mut());
|
||||
|
||||
@@ -3,5 +3,5 @@ mod spent;
|
||||
mod unspent;
|
||||
|
||||
pub use collection::OutputsVecs;
|
||||
pub(super) use spent::SpentOutputCount;
|
||||
pub(super) use unspent::UnspentOutputCount;
|
||||
pub use spent::SpentOutputCount;
|
||||
pub use unspent::UnspentOutputCount;
|
||||
|
||||
@@ -19,7 +19,7 @@ pub struct SpentOutputCount<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl SpentOutputCount {
|
||||
pub(super) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
|
||||
@@ -24,7 +24,7 @@ pub struct UnspentOutputCount<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl UnspentOutputCount {
|
||||
pub(super) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -69,7 +69,7 @@ impl UnspentOutputCount {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push_addr_balance(&mut self, row: AmountRange<StoredU64>) {
|
||||
pub fn push_addr_balance(&mut self, row: AmountRange<StoredU64>) {
|
||||
self.addr_balance.push(row);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::distribution::{
|
||||
};
|
||||
|
||||
impl CohortMetrics {
|
||||
pub(crate) fn push_aggregate_percentiles(
|
||||
pub fn push_aggregate_percentiles(
|
||||
&mut self,
|
||||
states: &UTXOStates,
|
||||
spot_price: Cents,
|
||||
|
||||
@@ -7,6 +7,8 @@ use vecdb::{
|
||||
ReadableColumnarVec, VecValue,
|
||||
};
|
||||
|
||||
use crate::internal::cache_wrap;
|
||||
|
||||
const RANGE_COUNT: usize = ProfitabilityRangeId::ALL.len();
|
||||
const COLUMN_COUNT: usize = TermId::ALL.len() * RANGE_COUNT;
|
||||
|
||||
@@ -38,7 +40,7 @@ pub struct TermProfitabilityRangeId {
|
||||
}
|
||||
|
||||
impl TermProfitabilityRangeId {
|
||||
pub(super) fn source<T>(
|
||||
pub fn source<T>(
|
||||
source: &ReadOnlyColumnarVec<PcoVec<Height, T>, Self>,
|
||||
name: &str,
|
||||
version: Version,
|
||||
@@ -62,22 +64,25 @@ impl TermProfitabilityRangeId {
|
||||
}
|
||||
|
||||
let selected_term = aggregate.term();
|
||||
source
|
||||
.sum_columns(
|
||||
name,
|
||||
version,
|
||||
TermId::ALL
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |&term| selected_term.is_none_or(|selected| selected == term))
|
||||
.flat_map(|term| {
|
||||
ranges
|
||||
.iter()
|
||||
.copied()
|
||||
.map(move |range| Self { term, range })
|
||||
}),
|
||||
)
|
||||
.read_only_boxed_clone()
|
||||
let source = source.sum_columns(
|
||||
name,
|
||||
version,
|
||||
TermId::ALL
|
||||
.iter()
|
||||
.copied()
|
||||
.filter(move |&term| selected_term.is_none_or(|selected| selected == term))
|
||||
.flat_map(|term| {
|
||||
ranges
|
||||
.iter()
|
||||
.copied()
|
||||
.map(move |range| Self { term, range })
|
||||
}),
|
||||
);
|
||||
if aggregate == UTXOAggregateId::All {
|
||||
cache_wrap(source).read_only_boxed_clone()
|
||||
} else {
|
||||
source.read_only_boxed_clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -53,7 +53,7 @@ pub struct ProfitabilityVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl<M: StorageMode> ProfitabilityVecs<M> {
|
||||
pub(crate) fn min_stateful_len(&self) -> usize {
|
||||
pub fn min_stateful_len(&self) -> usize {
|
||||
self.supply
|
||||
.height
|
||||
.len()
|
||||
@@ -64,7 +64,7 @@ impl<M: StorageMode> ProfitabilityVecs<M> {
|
||||
}
|
||||
|
||||
impl ProfitabilityVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -168,7 +168,7 @@ impl ProfitabilityVecs {
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub(crate) fn push(
|
||||
pub fn push(
|
||||
&mut self,
|
||||
spot: Cents,
|
||||
supply: ByTerm<ProfitabilityRange<Sats>>,
|
||||
@@ -185,7 +185,7 @@ impl ProfitabilityVecs {
|
||||
self.nupl.push(nupl);
|
||||
}
|
||||
|
||||
pub(crate) fn collect_all_vecs_mut(&mut self) -> [&mut dyn AnyStoredVec; 4] {
|
||||
pub fn collect_all_vecs_mut(&mut self) -> [&mut dyn AnyStoredVec; 4] {
|
||||
[
|
||||
self.supply.stored_mut(),
|
||||
self.realized_cap.stored_mut(),
|
||||
|
||||
@@ -36,7 +36,7 @@ pub struct AdjustedSoprVecs<M: StorageMode = Rw> {
|
||||
}
|
||||
|
||||
impl AdjustedSoprVecs {
|
||||
pub(crate) fn forced_import(
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
@@ -141,7 +141,7 @@ impl AdjustedSoprVecs {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn compute<V1, V2>(
|
||||
pub fn compute<V1, V2>(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
sources: &UTXOAllAndSth<AdjustedSoprComputeSource>,
|
||||
@@ -210,7 +210,7 @@ impl AdjustedSoprVecs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub(crate) fn min_len(&self) -> usize {
|
||||
pub fn min_len(&self) -> usize {
|
||||
self.transfer_volume
|
||||
.cumulative
|
||||
.len()
|
||||
@@ -224,7 +224,7 @@ impl AdjustedSoprVecs {
|
||||
)
|
||||
}
|
||||
|
||||
pub(crate) fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
pub fn collect_vecs_mut(&mut self) -> Vec<&mut dyn AnyStoredVec> {
|
||||
let mut vecs = vec![
|
||||
self.transfer_volume.stored_mut(),
|
||||
self.value_destroyed.stored_mut(),
|
||||
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
use crate::distribution::metrics::{ActivitySources, RealizedSources};
|
||||
|
||||
pub(crate) struct AdjustedSoprComputeSource {
|
||||
pub struct AdjustedSoprComputeSource {
|
||||
pub activity: ActivitySources,
|
||||
pub realized: RealizedSources,
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use crate::distribution::metrics::{ActivitySources, RealizedSources};
|
||||
|
||||
pub(crate) struct RealizedAggregateSources {
|
||||
pub struct RealizedAggregateSources {
|
||||
pub activity: ActivitySources,
|
||||
pub realized: RealizedSources,
|
||||
}
|
||||
|
||||
@@ -4,25 +4,25 @@ use crate::distribution::state::{RealizedOps, RealizedState};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct RealizedAggregateState {
|
||||
pub(crate) cap_raw: CentsSats,
|
||||
pub(crate) capitalized_cap_raw: CentsSquaredSats,
|
||||
pub cap_raw: CentsSats,
|
||||
pub capitalized_cap_raw: CentsSquaredSats,
|
||||
peak_regret: CentsSats,
|
||||
gross_pnl: Cents,
|
||||
}
|
||||
|
||||
impl RealizedAggregateState {
|
||||
pub(crate) fn add(&mut self, state: &RealizedState) {
|
||||
pub fn add(&mut self, state: &RealizedState) {
|
||||
self.cap_raw += state.cap_raw();
|
||||
self.capitalized_cap_raw += state.capitalized_cap_raw();
|
||||
self.peak_regret += CentsSats::new(state.peak_regret_raw());
|
||||
self.gross_pnl += state.profit() + state.loss();
|
||||
}
|
||||
|
||||
pub(crate) fn peak_regret(&self) -> Cents {
|
||||
pub fn peak_regret(&self) -> Cents {
|
||||
self.peak_regret.to_cents()
|
||||
}
|
||||
|
||||
pub(crate) fn capitalized_price(&self) -> Cents {
|
||||
pub fn capitalized_price(&self) -> Cents {
|
||||
let cap = self.cap_raw.as_u128();
|
||||
self.capitalized_cap_raw
|
||||
.inner()
|
||||
@@ -31,7 +31,7 @@ impl RealizedAggregateState {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub(crate) fn gross_pnl(&self) -> Cents {
|
||||
pub fn gross_pnl(&self) -> Cents {
|
||||
self.gross_pnl
|
||||
}
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user