global: massive columnar rework part 4

This commit is contained in:
nym21
2026-08-12 00:24:49 +02:00
parent 30ebe4e1ff
commit 0628ccd2d9
176 changed files with 6062 additions and 20190 deletions
+4709 -19067
View File
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);
@@ -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);
+6 -6
View File
@@ -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>>,
+3 -3
View File
@@ -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
View File
@@ -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, &cents);
}
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;
@@ -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,
@@ -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;
@@ -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,
@@ -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,
@@ -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()
}
@@ -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,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