From a6f81081659d8ae082959a281b87dbf51a3b6322 Mon Sep 17 00:00:00 2001 From: nym21 Date: Tue, 30 Dec 2025 22:49:47 +0100 Subject: [PATCH] crates: snapshot --- crates/brk/Cargo.toml | 6 +- crates/brk/README.md | 2 +- crates/brk/src/lib.rs | 8 +- crates/brk_binder/Cargo.toml | 2 +- crates/brk_binder/src/javascript.rs | 16 +- crates/brk_binder/src/python.rs | 2 +- crates/brk_binder/src/rust.rs | 2 +- crates/brk_client/Cargo.toml | 2 +- crates/brk_client/src/lib.rs | 258 +++++++++--------- crates/{brk_grouper => brk_cohort}/Cargo.toml | 4 +- crates/{brk_grouper => brk_cohort}/README.md | 2 +- crates/{brk_grouper => brk_cohort}/build.rs | 0 .../src/address.rs | 0 .../src/amount_filter.rs | 0 .../src/by_address_type.rs | 0 .../src/by_age_range.rs | 0 .../src/by_amount_range.rs | 0 .../src/by_any_address.rs | 0 .../src/by_epoch.rs | 0 .../src/by_ge_amount.rs | 0 .../src/by_lt_amount.rs | 0 .../src/by_max_age.rs | 0 .../src/by_min_age.rs | 0 .../src/by_spendable_type.rs | 0 .../src/by_term.rs | 0 .../src/by_type.rs | 0 .../src/by_unspendable_type.rs | 0 .../src/by_value.rs | 0 .../src/by_year.rs | 0 .../src/cohort_context.rs | 0 .../src/cohort_name.rs | 0 .../{brk_grouper => brk_cohort}/src/filter.rs | 0 .../src/filtered.rs | 0 crates/{brk_grouper => brk_cohort}/src/lib.rs | 0 .../src/state_level.rs | 0 .../{brk_grouper => brk_cohort}/src/term.rs | 0 .../src/time_filter.rs | 0 .../{brk_grouper => brk_cohort}/src/utxo.rs | 0 crates/brk_computer/Cargo.toml | 2 +- crates/brk_computer/README.md | 2 +- crates/brk_computer/src/blks.rs | 6 +- .../brk_computer/src/chain/block/compute.rs | 32 ++- crates/brk_computer/src/chain/block/import.rs | 22 +- crates/brk_computer/src/chain/block/vecs.rs | 9 +- .../src/chain/coinbase/compute.rs | 4 +- crates/brk_computer/src/chain/compute.rs | 6 +- .../brk_computer/src/chain/epoch/compute.rs | 94 ++++--- crates/brk_computer/src/chain/epoch/import.rs | 50 +++- crates/brk_computer/src/chain/epoch/vecs.rs | 15 +- .../brk_computer/src/chain/mining/compute.rs | 66 +---- .../brk_computer/src/chain/mining/import.rs | 35 --- crates/brk_computer/src/chain/mining/vecs.rs | 6 +- .../src/chain/output_type/compute.rs | 4 +- .../src/chain/transaction/compute.rs | 4 +- .../brk_computer/src/chain/volume/compute.rs | 4 +- crates/brk_computer/src/cointime.rs | 6 +- crates/brk_computer/src/fetched.rs | 6 +- .../src/grouped/computed/from_dateindex.rs | 6 +- .../grouped/computed/from_height/standard.rs | 6 +- .../grouped/computed/from_height/strict.rs | 4 +- .../src/grouped/computed/from_txindex.rs | 12 +- .../src/grouped/specialized/percentiles.rs | 4 +- .../src/grouped/specialized/ratio.rs | 6 +- .../src/grouped/specialized/stddev.rs | 6 +- .../grouped/value/computed/from_dateindex.rs | 6 +- .../src/grouped/value/computed/from_height.rs | 6 +- .../grouped/value/computed/from_txindex.rs | 4 +- crates/brk_computer/src/indexes/mod.rs | 86 ++---- crates/brk_computer/src/lib.rs | 2 +- crates/brk_computer/src/market/ath/compute.rs | 4 +- crates/brk_computer/src/market/compute.rs | 4 +- crates/brk_computer/src/market/dca/compute.rs | 4 +- .../src/market/history/compute.rs | 4 +- .../src/market/moving_average/compute.rs | 4 +- .../brk_computer/src/market/range/compute.rs | 4 +- .../src/market/volatility/compute.rs | 4 +- crates/brk_computer/src/pools/mod.rs | 8 +- crates/brk_computer/src/pools/vecs.rs | 4 +- crates/brk_computer/src/price.rs | 6 +- .../src/stateful/address/address_count.rs | 6 +- .../stateful/address/type_map/index_map.rs | 3 +- .../src/stateful/address/type_map/vec.rs | 2 +- .../src/stateful/block/cache/address.rs | 8 +- .../src/stateful/block/cohort/received.rs | 2 +- .../src/stateful/block/cohort/sent.rs | 2 +- .../src/stateful/block/utxo/inputs.rs | 2 +- .../src/stateful/block/utxo/outputs.rs | 8 +- .../src/stateful/cohorts/address/groups.rs | 29 +- .../src/stateful/cohorts/address/vecs.rs | 10 +- .../src/stateful/cohorts/traits.rs | 8 +- .../src/stateful/cohorts/utxo/groups.rs | 47 +++- .../src/stateful/cohorts/utxo/tick_tock.rs | 2 +- .../src/stateful/cohorts/utxo/vecs.rs | 10 +- .../src/stateful/compute/aggregates.rs | 8 +- .../src/stateful/compute/block_loop.rs | 13 +- .../src/stateful/compute/readers.rs | 7 +- .../src/stateful/metrics/activity.rs | 6 +- .../src/stateful/metrics/config.rs | 2 +- .../brk_computer/src/stateful/metrics/mod.rs | 10 +- .../src/stateful/metrics/price/paid.rs | 6 +- .../src/stateful/metrics/realized.rs | 8 +- .../src/stateful/metrics/supply.rs | 6 +- .../src/stateful/metrics/unrealized.rs | 6 +- .../src/stateful/state/transacted.rs | 2 +- crates/brk_computer/src/stateful/vecs.rs | 4 +- crates/brk_computer/src/txins.rs | 6 +- crates/brk_computer/src/txouts.rs | 6 +- crates/brk_indexer/BENCH.md | 13 - crates/brk_indexer/Cargo.toml | 2 +- crates/brk_indexer/README.md | 2 +- crates/brk_indexer/src/indexes.rs | 76 +----- crates/brk_indexer/src/lib.rs | 2 +- crates/brk_indexer/src/processor/metadata.rs | 1 + crates/brk_indexer/src/processor/txout.rs | 2 +- crates/brk_indexer/src/readers.rs | 2 +- crates/brk_indexer/src/stores.rs | 6 +- .../src/impl/mining/dateindex_iter.rs | 2 +- .../brk_query/src/impl/mining/difficulty.rs | 2 +- crates/brk_query/src/impl/mining/epochs.rs | 2 +- crates/brk_query/src/impl/mining/hashrate.rs | 2 +- crates/brk_types/src/indexes.rs | 125 +++++++++ crates/brk_types/src/lib.rs | 6 + crates/brk_types/src/option_ext.rs | 19 ++ crates/brk_types/src/percentile.rs | 38 +++ 124 files changed, 761 insertions(+), 641 deletions(-) rename crates/{brk_grouper => brk_cohort}/Cargo.toml (82%) rename crates/{brk_grouper => brk_cohort}/README.md (99%) rename crates/{brk_grouper => brk_cohort}/build.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/address.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/amount_filter.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_address_type.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_age_range.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_amount_range.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_any_address.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_epoch.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_ge_amount.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_lt_amount.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_max_age.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_min_age.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_spendable_type.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_term.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_type.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_unspendable_type.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_value.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/by_year.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/cohort_context.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/cohort_name.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/filter.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/filtered.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/lib.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/state_level.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/term.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/time_filter.rs (100%) rename crates/{brk_grouper => brk_cohort}/src/utxo.rs (100%) delete mode 100644 crates/brk_indexer/BENCH.md create mode 100644 crates/brk_types/src/indexes.rs create mode 100644 crates/brk_types/src/option_ext.rs create mode 100644 crates/brk_types/src/percentile.rs diff --git a/crates/brk/Cargo.toml b/crates/brk/Cargo.toml index bd611a211..b00d20b70 100644 --- a/crates/brk/Cargo.toml +++ b/crates/brk/Cargo.toml @@ -17,7 +17,7 @@ full = [ "computer", "error", "fetcher", - "grouper", + "cohort", "indexer", "iterator", "logger", @@ -38,7 +38,7 @@ client = ["brk_client"] computer = ["brk_computer"] error = ["brk_error"] fetcher = ["brk_fetcher"] -grouper = ["brk_grouper"] +cohort = ["brk_cohort"] indexer = ["brk_indexer"] iterator = ["brk_iterator"] logger = ["brk_logger"] @@ -60,7 +60,7 @@ brk_client = { workspace = true, optional = true } brk_computer = { workspace = true, optional = true } brk_error = { workspace = true, optional = true } brk_fetcher = { workspace = true, optional = true } -brk_grouper = { workspace = true, optional = true } +brk_cohort = { workspace = true, optional = true } brk_indexer = { workspace = true, optional = true } brk_iterator = { workspace = true, optional = true } brk_logger = { workspace = true, optional = true } diff --git a/crates/brk/README.md b/crates/brk/README.md index d57eda458..44d784722 100644 --- a/crates/brk/README.md +++ b/crates/brk/README.md @@ -29,7 +29,7 @@ use brk::types::Height; | `computer` | `brk_computer` | Metric computation | | `error` | `brk_error` | Error types | | `fetcher` | `brk_fetcher` | Price data fetching | -| `grouper` | `brk_grouper` | Cohort filtering | +| `cohort` | `brk_cohort` | Cohort filtering | | `indexer` | `brk_indexer` | Blockchain indexing | | `iterator` | `brk_iterator` | Block iteration | | `logger` | `brk_logger` | Logging setup | diff --git a/crates/brk/src/lib.rs b/crates/brk/src/lib.rs index 9ee2644a2..e22331b90 100644 --- a/crates/brk/src/lib.rs +++ b/crates/brk/src/lib.rs @@ -16,6 +16,10 @@ pub use brk_bundler as bundler; #[doc(inline)] pub use brk_client as client; +#[cfg(feature = "cohort")] +#[doc(inline)] +pub use brk_cohort as cohort; + #[cfg(feature = "computer")] #[doc(inline)] pub use brk_computer as computer; @@ -28,10 +32,6 @@ pub use brk_error as error; #[doc(inline)] pub use brk_fetcher as fetcher; -#[cfg(feature = "grouper")] -#[doc(inline)] -pub use brk_grouper as grouper; - #[cfg(feature = "indexer")] #[doc(inline)] pub use brk_indexer as indexer; diff --git a/crates/brk_binder/Cargo.toml b/crates/brk_binder/Cargo.toml index 2d753d8c7..080d7e6d8 100644 --- a/crates/brk_binder/Cargo.toml +++ b/crates/brk_binder/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true build = "build.rs" [dependencies] -brk_grouper = { workspace = true } +brk_cohort = { workspace = true } brk_query = { workspace = true } brk_types = { workspace = true } oas3 = "0.20" diff --git a/crates/brk_binder/src/javascript.rs b/crates/brk_binder/src/javascript.rs index bc4ab03b9..9030010b9 100644 --- a/crates/brk_binder/src/javascript.rs +++ b/crates/brk_binder/src/javascript.rs @@ -2,7 +2,7 @@ use std::{collections::HashSet, fmt::Write as FmtWrite, fs, io, path::Path}; use serde_json::json; -use brk_grouper::{ +use brk_cohort::{ AGE_RANGE_NAMES, AMOUNT_RANGE_NAMES, EPOCH_NAMES, GE_AMOUNT_NAMES, LT_AMOUNT_NAMES, MAX_AGE_NAMES, MIN_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, YEAR_NAMES, }; @@ -373,6 +373,14 @@ class MetricNode {{ this._path = path; }} + /** + * Get the path for this metric. + * @returns {{string}} + */ + get path() {{ + return this._path; + }} + /** * Fetch all data points for this metric. * @param {{(value: T[]) => void}} [onUpdate] - Called when data is available (may be called twice: cache then fresh) @@ -473,11 +481,12 @@ fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern]) { } writeln!(output, " */\n").unwrap(); - // Outer type with 'by' property + // Outer type with 'by' property and indexes method writeln!(output, "/**").unwrap(); writeln!(output, " * @template T").unwrap(); writeln!(output, " * @typedef {{Object}} {}", pattern.name).unwrap(); writeln!(output, " * @property {{{}}} by", by_type_name).unwrap(); + writeln!(output, " * @property {{() => Index[]}} indexes").unwrap(); writeln!(output, " */\n").unwrap(); // Generate factory function @@ -512,6 +521,9 @@ fn generate_index_accessors(output: &mut String, patterns: &[IndexSetPattern]) { .unwrap(); } + writeln!(output, " }},").unwrap(); + writeln!(output, " indexes() {{").unwrap(); + writeln!(output, " return /** @type {{Index[]}} */ (Object.keys(this.by));").unwrap(); writeln!(output, " }}").unwrap(); writeln!(output, " }};").unwrap(); writeln!(output, "}}\n").unwrap(); diff --git a/crates/brk_binder/src/python.rs b/crates/brk_binder/src/python.rs index 9ebe84a2c..2f6f6af4c 100644 --- a/crates/brk_binder/src/python.rs +++ b/crates/brk_binder/src/python.rs @@ -1,6 +1,6 @@ use std::{collections::HashSet, fmt::Write as FmtWrite, fs, io, path::Path}; -use brk_grouper::{ +use brk_cohort::{ AGE_RANGE_NAMES, AMOUNT_RANGE_NAMES, EPOCH_NAMES, GE_AMOUNT_NAMES, LT_AMOUNT_NAMES, MAX_AGE_NAMES, MIN_AGE_NAMES, SPENDABLE_TYPE_NAMES, TERM_NAMES, YEAR_NAMES, }; diff --git a/crates/brk_binder/src/rust.rs b/crates/brk_binder/src/rust.rs index f5161314d..4a700f3ac 100644 --- a/crates/brk_binder/src/rust.rs +++ b/crates/brk_binder/src/rust.rs @@ -44,7 +44,7 @@ fn generate_imports(output: &mut String) { output, r#"use std::sync::Arc; use serde::de::DeserializeOwned; -pub use brk_grouper::*; +pub use brk_cohort::*; pub use brk_types::*; "# diff --git a/crates/brk_client/Cargo.toml b/crates/brk_client/Cargo.toml index fc8fbc2eb..b2e65abba 100644 --- a/crates/brk_client/Cargo.toml +++ b/crates/brk_client/Cargo.toml @@ -9,7 +9,7 @@ repository.workspace = true build = "build.rs" [dependencies] -brk_grouper = { workspace = true } +brk_cohort = { workspace = true } brk_types = { workspace = true } minreq = { workspace = true } serde = { workspace = true } diff --git a/crates/brk_client/src/lib.rs b/crates/brk_client/src/lib.rs index 8961ee7ca..6c3c491e6 100644 --- a/crates/brk_client/src/lib.rs +++ b/crates/brk_client/src/lib.rs @@ -9,7 +9,7 @@ use std::sync::Arc; use serde::de::DeserializeOwned; -pub use brk_grouper::*; +pub use brk_cohort::*; pub use brk_types::*; @@ -1136,31 +1136,31 @@ impl BitcoinPattern { /// Pattern struct for repeated tree structure. pub struct BlockSizePattern { - pub average: Indexes3, + pub average: Indexes4, pub cumulative: Indexes3, - pub max: Indexes3, - pub median: Indexes2, - pub min: Indexes3, - pub pct10: Indexes2, - pub pct25: Indexes2, - pub pct75: Indexes2, - pub pct90: Indexes2, - pub sum: Indexes3, + pub max: Indexes4, + pub median: Indexes5, + pub min: Indexes4, + pub pct10: Indexes5, + pub pct25: Indexes5, + pub pct75: Indexes5, + pub pct90: Indexes5, + pub sum: Indexes4, } impl BlockSizePattern { pub fn new(client: Arc, base_path: &str) -> Self { Self { - average: Indexes3::new(client.clone(), &format!("{base_path}_average")), + average: Indexes4::new(client.clone(), &format!("{base_path}_average")), cumulative: Indexes3::new(client.clone(), &format!("{base_path}_cumulative")), - max: Indexes3::new(client.clone(), &format!("{base_path}_max")), - median: Indexes2::new(client.clone(), &format!("{base_path}_median")), - min: Indexes3::new(client.clone(), &format!("{base_path}_min")), - pct10: Indexes2::new(client.clone(), &format!("{base_path}_pct10")), - pct25: Indexes2::new(client.clone(), &format!("{base_path}_pct25")), - pct75: Indexes2::new(client.clone(), &format!("{base_path}_pct75")), - pct90: Indexes2::new(client.clone(), &format!("{base_path}_pct90")), - sum: Indexes3::new(client.clone(), &format!("{base_path}_sum")), + max: Indexes4::new(client.clone(), &format!("{base_path}_max")), + median: Indexes5::new(client.clone(), &format!("{base_path}_median")), + min: Indexes4::new(client.clone(), &format!("{base_path}_min")), + pct10: Indexes5::new(client.clone(), &format!("{base_path}_pct10")), + pct25: Indexes5::new(client.clone(), &format!("{base_path}_pct25")), + pct75: Indexes5::new(client.clone(), &format!("{base_path}_pct75")), + pct90: Indexes5::new(client.clone(), &format!("{base_path}_pct90")), + sum: Indexes4::new(client.clone(), &format!("{base_path}_sum")), } } } @@ -1223,29 +1223,57 @@ impl RelativePattern { } } +/// Pattern struct for repeated tree structure. +pub struct BlockIntervalPattern { + pub average: Indexes3, + pub max: Indexes3, + pub median: Indexes2, + pub min: Indexes3, + pub pct10: Indexes2, + pub pct25: Indexes2, + pub pct75: Indexes2, + pub pct90: Indexes2, +} + +impl BlockIntervalPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: &str) -> Self { + Self { + average: Indexes3::new(client.clone(), &format!("{acc}_avg")), + max: Indexes3::new(client.clone(), &format!("{acc}_max")), + median: Indexes2::new(client.clone(), &format!("{acc}_median")), + min: Indexes3::new(client.clone(), &format!("{acc}_min")), + pct10: Indexes2::new(client.clone(), &format!("{acc}_pct10")), + pct25: Indexes2::new(client.clone(), &format!("{acc}_pct25")), + pct75: Indexes2::new(client.clone(), &format!("{acc}_pct75")), + pct90: Indexes2::new(client.clone(), &format!("{acc}_pct90")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct AddresstypeToHeightToAddrCountPattern { - pub p2a: Indexes14, - pub p2pk33: Indexes15, - pub p2pk65: Indexes16, - pub p2pkh: Indexes17, - pub p2sh: Indexes18, - pub p2tr: Indexes19, - pub p2wpkh: Indexes20, - pub p2wsh: Indexes21, + pub p2a: Indexes2, + pub p2pk33: Indexes2, + pub p2pk65: Indexes2, + pub p2pkh: Indexes2, + pub p2sh: Indexes2, + pub p2tr: Indexes2, + pub p2wpkh: Indexes2, + pub p2wsh: Indexes2, } impl AddresstypeToHeightToAddrCountPattern { pub fn new(client: Arc, base_path: &str) -> Self { Self { - p2a: Indexes14::new(client.clone(), &format!("{base_path}_p2a")), - p2pk33: Indexes15::new(client.clone(), &format!("{base_path}_p2pk33")), - p2pk65: Indexes16::new(client.clone(), &format!("{base_path}_p2pk65")), - p2pkh: Indexes17::new(client.clone(), &format!("{base_path}_p2pkh")), - p2sh: Indexes18::new(client.clone(), &format!("{base_path}_p2sh")), - p2tr: Indexes19::new(client.clone(), &format!("{base_path}_p2tr")), - p2wpkh: Indexes20::new(client.clone(), &format!("{base_path}_p2wpkh")), - p2wsh: Indexes21::new(client.clone(), &format!("{base_path}_p2wsh")), + p2a: Indexes2::new(client.clone(), &format!("{base_path}_p2a")), + p2pk33: Indexes2::new(client.clone(), &format!("{base_path}_p2pk33")), + p2pk65: Indexes2::new(client.clone(), &format!("{base_path}_p2pk65")), + p2pkh: Indexes2::new(client.clone(), &format!("{base_path}_p2pkh")), + p2sh: Indexes2::new(client.clone(), &format!("{base_path}_p2sh")), + p2tr: Indexes2::new(client.clone(), &format!("{base_path}_p2tr")), + p2wpkh: Indexes2::new(client.clone(), &format!("{base_path}_p2wpkh")), + p2wsh: Indexes2::new(client.clone(), &format!("{base_path}_p2wsh")), } } } @@ -1278,34 +1306,6 @@ impl Constant0Pattern { } } -/// Pattern struct for repeated tree structure. -pub struct BlockIntervalPattern { - pub average: Indexes3, - pub max: Indexes3, - pub median: Indexes2, - pub min: Indexes3, - pub pct10: Indexes2, - pub pct25: Indexes2, - pub pct75: Indexes2, - pub pct90: Indexes2, -} - -impl BlockIntervalPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: &str) -> Self { - Self { - average: Indexes3::new(client.clone(), &format!("{acc}_avg")), - max: Indexes3::new(client.clone(), &format!("{acc}_max")), - median: Indexes2::new(client.clone(), &format!("{acc}_median")), - min: Indexes3::new(client.clone(), &format!("{acc}_min")), - pct10: Indexes2::new(client.clone(), &format!("{acc}_pct10")), - pct25: Indexes2::new(client.clone(), &format!("{acc}_pct25")), - pct75: Indexes2::new(client.clone(), &format!("{acc}_pct75")), - pct90: Indexes2::new(client.clone(), &format!("{acc}_pct90")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct _0satsPattern { pub activity: ActivityPattern, @@ -1332,21 +1332,21 @@ impl _0satsPattern { } /// Pattern struct for repeated tree structure. -pub struct UpTo1dPattern { +pub struct _10yTo12yPattern { pub activity: ActivityPattern, pub price_paid: PricePaidPattern2, - pub realized: RealizedPattern3, + pub realized: RealizedPattern2, pub relative: RelativePattern2, pub supply: SupplyPattern2, pub unrealized: UnrealizedPattern, } -impl UpTo1dPattern { +impl _10yTo12yPattern { pub fn new(client: Arc, base_path: &str) -> Self { Self { activity: ActivityPattern::new(client.clone(), &format!("{base_path}_activity")), price_paid: PricePaidPattern2::new(client.clone(), &format!("{base_path}_price_paid")), - realized: RealizedPattern3::new(client.clone(), &format!("{base_path}_realized")), + realized: RealizedPattern2::new(client.clone(), &format!("{base_path}_realized")), relative: RelativePattern2::new(client.clone(), &format!("{base_path}_relative")), supply: SupplyPattern2::new(client.clone(), &format!("{base_path}_supply")), unrealized: UnrealizedPattern::new(client.clone(), &format!("{base_path}_unrealized")), @@ -1378,21 +1378,21 @@ impl _0satsPattern2 { } /// Pattern struct for repeated tree structure. -pub struct _10yTo12yPattern { +pub struct UpTo1dPattern { pub activity: ActivityPattern, pub price_paid: PricePaidPattern2, - pub realized: RealizedPattern2, + pub realized: RealizedPattern3, pub relative: RelativePattern2, pub supply: SupplyPattern2, pub unrealized: UnrealizedPattern, } -impl _10yTo12yPattern { +impl UpTo1dPattern { pub fn new(client: Arc, base_path: &str) -> Self { Self { activity: ActivityPattern::new(client.clone(), &format!("{base_path}_activity")), price_paid: PricePaidPattern2::new(client.clone(), &format!("{base_path}_price_paid")), - realized: RealizedPattern2::new(client.clone(), &format!("{base_path}_realized")), + realized: RealizedPattern3::new(client.clone(), &format!("{base_path}_realized")), relative: RelativePattern2::new(client.clone(), &format!("{base_path}_relative")), supply: SupplyPattern2::new(client.clone(), &format!("{base_path}_supply")), unrealized: UnrealizedPattern::new(client.clone(), &format!("{base_path}_unrealized")), @@ -1442,25 +1442,6 @@ impl SupplyPattern2 { } } -/// Pattern struct for repeated tree structure. -pub struct SupplyPattern { - pub base: Indexes2, - pub bitcoin: Indexes, - pub dollars: Indexes, - pub sats: Indexes, -} - -impl SupplyPattern { - pub fn new(client: Arc, base_path: &str) -> Self { - Self { - base: Indexes2::new(client.clone(), &format!("{base_path}_base")), - bitcoin: Indexes::new(client.clone(), &format!("{base_path}_bitcoin")), - dollars: Indexes::new(client.clone(), &format!("{base_path}_dollars")), - sats: Indexes::new(client.clone(), &format!("{base_path}_sats")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct FeePattern2 { pub base: Indexes2, @@ -1481,18 +1462,20 @@ impl FeePattern2 { } /// Pattern struct for repeated tree structure. -pub struct PricePaidPattern2 { - pub max_price_paid: Indexes3, - pub min_price_paid: Indexes3, - pub price_percentiles: PricePercentilesPattern, +pub struct SupplyPattern { + pub base: Indexes2, + pub bitcoin: Indexes, + pub dollars: Indexes, + pub sats: Indexes, } -impl PricePaidPattern2 { +impl SupplyPattern { pub fn new(client: Arc, base_path: &str) -> Self { Self { - max_price_paid: Indexes3::new(client.clone(), &format!("{base_path}_max_price_paid")), - min_price_paid: Indexes3::new(client.clone(), &format!("{base_path}_min_price_paid")), - price_percentiles: PricePercentilesPattern::new(client.clone(), &format!("{base_path}_price_percentiles")), + base: Indexes2::new(client.clone(), &format!("{base_path}_base")), + bitcoin: Indexes::new(client.clone(), &format!("{base_path}_bitcoin")), + dollars: Indexes::new(client.clone(), &format!("{base_path}_dollars")), + sats: Indexes::new(client.clone(), &format!("{base_path}_sats")), } } } @@ -1515,18 +1498,18 @@ impl CoinbasePattern { } /// Pattern struct for repeated tree structure. -pub struct UnclaimedRewardsPattern { - pub bitcoin: BlockCountPattern, - pub dollars: BlockCountPattern, - pub sats: BlockCountPattern, +pub struct PricePaidPattern2 { + pub max_price_paid: Indexes3, + pub min_price_paid: Indexes3, + pub price_percentiles: PricePercentilesPattern, } -impl UnclaimedRewardsPattern { +impl PricePaidPattern2 { pub fn new(client: Arc, base_path: &str) -> Self { Self { - bitcoin: BlockCountPattern::new(client.clone(), &format!("{base_path}_bitcoin")), - dollars: BlockCountPattern::new(client.clone(), &format!("{base_path}_dollars")), - sats: BlockCountPattern::new(client.clone(), &format!("{base_path}_sats")), + max_price_paid: Indexes3::new(client.clone(), &format!("{base_path}_max_price_paid")), + min_price_paid: Indexes3::new(client.clone(), &format!("{base_path}_min_price_paid")), + price_percentiles: PricePercentilesPattern::new(client.clone(), &format!("{base_path}_price_percentiles")), } } } @@ -1548,6 +1531,23 @@ impl ActiveSupplyPattern { } } +/// Pattern struct for repeated tree structure. +pub struct UnclaimedRewardsPattern { + pub bitcoin: BlockCountPattern, + pub dollars: BlockCountPattern, + pub sats: BlockCountPattern, +} + +impl UnclaimedRewardsPattern { + pub fn new(client: Arc, base_path: &str) -> Self { + Self { + bitcoin: BlockCountPattern::new(client.clone(), &format!("{base_path}_bitcoin")), + dollars: BlockCountPattern::new(client.clone(), &format!("{base_path}_dollars")), + sats: BlockCountPattern::new(client.clone(), &format!("{base_path}_sats")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct BlockCountPattern { pub base: Indexes2, @@ -1565,6 +1565,22 @@ impl BlockCountPattern { } } +/// Pattern struct for repeated tree structure. +pub struct _1dReturns1mSdPattern { + pub sd: Indexes, + pub sma: Indexes, +} + +impl _1dReturns1mSdPattern { + /// Create a new pattern node with accumulated metric name. + pub fn new(client: Arc, acc: &str) -> Self { + Self { + sd: Indexes::new(client.clone(), &format!("{acc}_sd")), + sma: Indexes::new(client.clone(), &format!("{acc}_sma")), + } + } +} + /// Pattern struct for repeated tree structure. pub struct SatsPattern { pub cumulative: Indexes3, @@ -1580,21 +1596,6 @@ impl SatsPattern { } } -/// Pattern struct for repeated tree structure. -pub struct SupplyValuePattern { - pub bitcoin: Indexes2, - pub dollars: Indexes2, -} - -impl SupplyValuePattern { - pub fn new(client: Arc, base_path: &str) -> Self { - Self { - bitcoin: Indexes2::new(client.clone(), &format!("{base_path}_bitcoin")), - dollars: Indexes2::new(client.clone(), &format!("{base_path}_dollars")), - } - } -} - /// Pattern struct for repeated tree structure. pub struct PricePaidPattern { pub max_price_paid: Indexes3, @@ -1611,17 +1612,16 @@ impl PricePaidPattern { } /// Pattern struct for repeated tree structure. -pub struct _1dReturns1mSdPattern { - pub sd: Indexes, - pub sma: Indexes, +pub struct SupplyValuePattern { + pub bitcoin: Indexes2, + pub dollars: Indexes2, } -impl _1dReturns1mSdPattern { - /// Create a new pattern node with accumulated metric name. - pub fn new(client: Arc, acc: &str) -> Self { +impl SupplyValuePattern { + pub fn new(client: Arc, base_path: &str) -> Self { Self { - sd: Indexes::new(client.clone(), &format!("{acc}_sd")), - sma: Indexes::new(client.clone(), &format!("{acc}_sma")), + bitcoin: Indexes2::new(client.clone(), &format!("{base_path}_bitcoin")), + dollars: Indexes2::new(client.clone(), &format!("{base_path}_dollars")), } } } diff --git a/crates/brk_grouper/Cargo.toml b/crates/brk_cohort/Cargo.toml similarity index 82% rename from crates/brk_grouper/Cargo.toml rename to crates/brk_cohort/Cargo.toml index 2b0a93b0c..9ccd74961 100644 --- a/crates/brk_grouper/Cargo.toml +++ b/crates/brk_cohort/Cargo.toml @@ -1,6 +1,6 @@ [package] -name = "brk_grouper" -description = "Groups used throughout BRK" +name = "brk_cohort" +description = "Cohort definitions used throughout BRK" version.workspace = true edition.workspace = true license.workspace = true diff --git a/crates/brk_grouper/README.md b/crates/brk_cohort/README.md similarity index 99% rename from crates/brk_grouper/README.md rename to crates/brk_cohort/README.md index 689b434a5..596e4e086 100644 --- a/crates/brk_grouper/README.md +++ b/crates/brk_cohort/README.md @@ -1,4 +1,4 @@ -# brk_grouper +# brk_cohort UTXO and address cohort filtering for on-chain analytics. diff --git a/crates/brk_grouper/build.rs b/crates/brk_cohort/build.rs similarity index 100% rename from crates/brk_grouper/build.rs rename to crates/brk_cohort/build.rs diff --git a/crates/brk_grouper/src/address.rs b/crates/brk_cohort/src/address.rs similarity index 100% rename from crates/brk_grouper/src/address.rs rename to crates/brk_cohort/src/address.rs diff --git a/crates/brk_grouper/src/amount_filter.rs b/crates/brk_cohort/src/amount_filter.rs similarity index 100% rename from crates/brk_grouper/src/amount_filter.rs rename to crates/brk_cohort/src/amount_filter.rs diff --git a/crates/brk_grouper/src/by_address_type.rs b/crates/brk_cohort/src/by_address_type.rs similarity index 100% rename from crates/brk_grouper/src/by_address_type.rs rename to crates/brk_cohort/src/by_address_type.rs diff --git a/crates/brk_grouper/src/by_age_range.rs b/crates/brk_cohort/src/by_age_range.rs similarity index 100% rename from crates/brk_grouper/src/by_age_range.rs rename to crates/brk_cohort/src/by_age_range.rs diff --git a/crates/brk_grouper/src/by_amount_range.rs b/crates/brk_cohort/src/by_amount_range.rs similarity index 100% rename from crates/brk_grouper/src/by_amount_range.rs rename to crates/brk_cohort/src/by_amount_range.rs diff --git a/crates/brk_grouper/src/by_any_address.rs b/crates/brk_cohort/src/by_any_address.rs similarity index 100% rename from crates/brk_grouper/src/by_any_address.rs rename to crates/brk_cohort/src/by_any_address.rs diff --git a/crates/brk_grouper/src/by_epoch.rs b/crates/brk_cohort/src/by_epoch.rs similarity index 100% rename from crates/brk_grouper/src/by_epoch.rs rename to crates/brk_cohort/src/by_epoch.rs diff --git a/crates/brk_grouper/src/by_ge_amount.rs b/crates/brk_cohort/src/by_ge_amount.rs similarity index 100% rename from crates/brk_grouper/src/by_ge_amount.rs rename to crates/brk_cohort/src/by_ge_amount.rs diff --git a/crates/brk_grouper/src/by_lt_amount.rs b/crates/brk_cohort/src/by_lt_amount.rs similarity index 100% rename from crates/brk_grouper/src/by_lt_amount.rs rename to crates/brk_cohort/src/by_lt_amount.rs diff --git a/crates/brk_grouper/src/by_max_age.rs b/crates/brk_cohort/src/by_max_age.rs similarity index 100% rename from crates/brk_grouper/src/by_max_age.rs rename to crates/brk_cohort/src/by_max_age.rs diff --git a/crates/brk_grouper/src/by_min_age.rs b/crates/brk_cohort/src/by_min_age.rs similarity index 100% rename from crates/brk_grouper/src/by_min_age.rs rename to crates/brk_cohort/src/by_min_age.rs diff --git a/crates/brk_grouper/src/by_spendable_type.rs b/crates/brk_cohort/src/by_spendable_type.rs similarity index 100% rename from crates/brk_grouper/src/by_spendable_type.rs rename to crates/brk_cohort/src/by_spendable_type.rs diff --git a/crates/brk_grouper/src/by_term.rs b/crates/brk_cohort/src/by_term.rs similarity index 100% rename from crates/brk_grouper/src/by_term.rs rename to crates/brk_cohort/src/by_term.rs diff --git a/crates/brk_grouper/src/by_type.rs b/crates/brk_cohort/src/by_type.rs similarity index 100% rename from crates/brk_grouper/src/by_type.rs rename to crates/brk_cohort/src/by_type.rs diff --git a/crates/brk_grouper/src/by_unspendable_type.rs b/crates/brk_cohort/src/by_unspendable_type.rs similarity index 100% rename from crates/brk_grouper/src/by_unspendable_type.rs rename to crates/brk_cohort/src/by_unspendable_type.rs diff --git a/crates/brk_grouper/src/by_value.rs b/crates/brk_cohort/src/by_value.rs similarity index 100% rename from crates/brk_grouper/src/by_value.rs rename to crates/brk_cohort/src/by_value.rs diff --git a/crates/brk_grouper/src/by_year.rs b/crates/brk_cohort/src/by_year.rs similarity index 100% rename from crates/brk_grouper/src/by_year.rs rename to crates/brk_cohort/src/by_year.rs diff --git a/crates/brk_grouper/src/cohort_context.rs b/crates/brk_cohort/src/cohort_context.rs similarity index 100% rename from crates/brk_grouper/src/cohort_context.rs rename to crates/brk_cohort/src/cohort_context.rs diff --git a/crates/brk_grouper/src/cohort_name.rs b/crates/brk_cohort/src/cohort_name.rs similarity index 100% rename from crates/brk_grouper/src/cohort_name.rs rename to crates/brk_cohort/src/cohort_name.rs diff --git a/crates/brk_grouper/src/filter.rs b/crates/brk_cohort/src/filter.rs similarity index 100% rename from crates/brk_grouper/src/filter.rs rename to crates/brk_cohort/src/filter.rs diff --git a/crates/brk_grouper/src/filtered.rs b/crates/brk_cohort/src/filtered.rs similarity index 100% rename from crates/brk_grouper/src/filtered.rs rename to crates/brk_cohort/src/filtered.rs diff --git a/crates/brk_grouper/src/lib.rs b/crates/brk_cohort/src/lib.rs similarity index 100% rename from crates/brk_grouper/src/lib.rs rename to crates/brk_cohort/src/lib.rs diff --git a/crates/brk_grouper/src/state_level.rs b/crates/brk_cohort/src/state_level.rs similarity index 100% rename from crates/brk_grouper/src/state_level.rs rename to crates/brk_cohort/src/state_level.rs diff --git a/crates/brk_grouper/src/term.rs b/crates/brk_cohort/src/term.rs similarity index 100% rename from crates/brk_grouper/src/term.rs rename to crates/brk_cohort/src/term.rs diff --git a/crates/brk_grouper/src/time_filter.rs b/crates/brk_cohort/src/time_filter.rs similarity index 100% rename from crates/brk_grouper/src/time_filter.rs rename to crates/brk_cohort/src/time_filter.rs diff --git a/crates/brk_grouper/src/utxo.rs b/crates/brk_cohort/src/utxo.rs similarity index 100% rename from crates/brk_grouper/src/utxo.rs rename to crates/brk_cohort/src/utxo.rs diff --git a/crates/brk_computer/Cargo.toml b/crates/brk_computer/Cargo.toml index 8675cfc27..0a9c3668d 100644 --- a/crates/brk_computer/Cargo.toml +++ b/crates/brk_computer/Cargo.toml @@ -12,7 +12,7 @@ build = "build.rs" bitcoin = { workspace = true } brk_error = { workspace = true } brk_fetcher = { workspace = true } -brk_grouper = { workspace = true } +brk_cohort = { workspace = true } brk_indexer = { workspace = true } brk_iterator = { workspace = true } brk_logger = { workspace = true } diff --git a/crates/brk_computer/README.md b/crates/brk_computer/README.md index 39a44aa64..d6a05e924 100644 --- a/crates/brk_computer/README.md +++ b/crates/brk_computer/README.md @@ -67,7 +67,7 @@ Use [mimalloc v3](https://crates.io/crates/mimalloc) as the global allocator to ## Built On - `brk_indexer` for indexed blockchain data +- `brk_cohort` for cohort filtering - `brk_fetcher` for price data - `brk_reader` for raw block access -- `brk_grouper` for cohort filtering - `brk_traversable` for data export diff --git a/crates/brk_computer/src/blks.rs b/crates/brk_computer/src/blks.rs index 67d905f81..93ef03b80 100644 --- a/crates/brk_computer/src/blks.rs +++ b/crates/brk_computer/src/blks.rs @@ -10,7 +10,7 @@ use vecdb::{ TypedVecIterator, }; -use super::Indexes; +use super::ComputeIndexes; pub const DB_NAME: &str = "blks"; @@ -49,7 +49,7 @@ impl Vecs { pub fn compute( &mut self, indexer: &Indexer, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, reader: &Reader, exit: &Exit, ) -> Result<()> { @@ -62,7 +62,7 @@ impl Vecs { fn compute_( &mut self, indexer: &Indexer, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, parser: &Reader, exit: &Exit, ) -> Result<()> { diff --git a/crates/brk_computer/src/chain/block/compute.rs b/crates/brk_computer/src/chain/block/compute.rs index d144253a8..f523ddd3e 100644 --- a/crates/brk_computer/src/chain/block/compute.rs +++ b/crates/brk_computer/src/chain/block/compute.rs @@ -4,14 +4,14 @@ use brk_types::{CheckedSub, Height, StoredU32, StoredU64, Timestamp}; use vecdb::{Exit, TypedVecIterator}; use super::Vecs; -use crate::{Indexes, indexes}; +use crate::{ComputeIndexes, indexes}; impl Vecs { pub fn compute( &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let mut height_to_timestamp_fixed_iter = @@ -134,6 +134,34 @@ impl Vecs { Some(&self.height_to_vbytes), )?; + // Timestamp metrics (moved from epoch) + self.timeindexes_to_timestamp + .compute_all(starting_indexes, exit, |vec| { + vec.compute_transform( + starting_indexes.dateindex, + &indexes.time.dateindex_to_date, + |(di, d, ..)| (di, Timestamp::from(d)), + exit, + )?; + Ok(()) + })?; + + let mut height_to_timestamp_iter = indexer.vecs.block.height_to_timestamp.iter()?; + + self.difficultyepoch_to_timestamp.compute_transform( + starting_indexes.difficultyepoch, + &indexes.block.difficultyepoch_to_first_height, + |(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)), + exit, + )?; + + self.halvingepoch_to_timestamp.compute_transform( + starting_indexes.halvingepoch, + &indexes.block.halvingepoch_to_first_height, + |(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)), + exit, + )?; + Ok(()) } } diff --git a/crates/brk_computer/src/chain/block/import.rs b/crates/brk_computer/src/chain/block/import.rs index 51337a69c..fbf2f0bbd 100644 --- a/crates/brk_computer/src/chain/block/import.rs +++ b/crates/brk_computer/src/chain/block/import.rs @@ -5,16 +5,15 @@ use vecdb::{Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom use super::Vecs; use crate::{ + chain::{ + TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DECADE, TARGET_BLOCKS_PER_MONTH, + TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK, + TARGET_BLOCKS_PER_YEAR, + }, grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions}, indexes, }; -use crate::chain::{ - TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DECADE, TARGET_BLOCKS_PER_MONTH, - TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK, - TARGET_BLOCKS_PER_YEAR, -}; - impl Vecs { pub fn forced_import( db: &Database, @@ -166,6 +165,17 @@ impl Vecs { indexes, full_stats(), )?, + // Timestamp metrics (moved from epoch) + difficultyepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?, + halvingepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?, + timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import( + db, + "timestamp", + Source::Compute, + version + v0, + indexes, + VecBuilderOptions::default().add_first(), + )?, }) } } diff --git a/crates/brk_computer/src/chain/block/vecs.rs b/crates/brk_computer/src/chain/block/vecs.rs index 54a736e73..bc952dab2 100644 --- a/crates/brk_computer/src/chain/block/vecs.rs +++ b/crates/brk_computer/src/chain/block/vecs.rs @@ -1,13 +1,13 @@ use brk_traversable::Traversable; use brk_types::{ - DateIndex, DecadeIndex, Height, MonthIndex, QuarterIndex, SemesterIndex, StoredU32, StoredU64, - Timestamp, WeekIndex, Weight, YearIndex, + DateIndex, DecadeIndex, DifficultyEpoch, HalvingEpoch, Height, MonthIndex, QuarterIndex, + SemesterIndex, StoredU32, StoredU64, Timestamp, WeekIndex, Weight, YearIndex, }; use vecdb::{EagerVec, LazyVecFrom1, PcoVec}; use crate::grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight}; -/// Block-related metrics: count, interval, size, weight, vbytes +/// Block-related metrics: count, interval, size, weight, vbytes, timestamps #[derive(Clone, Traversable)] pub struct Vecs { pub dateindex_to_block_count_target: LazyVecFrom1, @@ -32,4 +32,7 @@ pub struct Vecs { pub indexes_to_block_size: ComputedVecsFromHeight, pub indexes_to_block_vbytes: ComputedVecsFromHeight, pub indexes_to_block_weight: ComputedVecsFromHeight, + pub difficultyepoch_to_timestamp: EagerVec>, + pub halvingepoch_to_timestamp: EagerVec>, + pub timeindexes_to_timestamp: ComputedVecsFromDateIndex, } diff --git a/crates/brk_computer/src/chain/coinbase/compute.rs b/crates/brk_computer/src/chain/coinbase/compute.rs index 2691d01f4..f0627f616 100644 --- a/crates/brk_computer/src/chain/coinbase/compute.rs +++ b/crates/brk_computer/src/chain/coinbase/compute.rs @@ -5,7 +5,7 @@ use vecdb::{Exit, IterableVec, TypedVecIterator, VecIndex}; use super::Vecs; use crate::{ - Indexes, + ComputeIndexes, chain::{block, transaction}, indexes, price, utils::OptionExt, @@ -19,7 +19,7 @@ impl Vecs { indexes: &indexes::Vecs, block_vecs: &block::Vecs, transaction_vecs: &transaction::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { diff --git a/crates/brk_computer/src/chain/compute.rs b/crates/brk_computer/src/chain/compute.rs index 191b7f893..fcf6f53be 100644 --- a/crates/brk_computer/src/chain/compute.rs +++ b/crates/brk_computer/src/chain/compute.rs @@ -2,7 +2,7 @@ use brk_error::Result; use brk_indexer::Indexer; use vecdb::Exit; -use crate::{indexes, price, txins, Indexes}; +use crate::{indexes, price, txins, ComputeIndexes}; use super::Vecs; @@ -12,13 +12,13 @@ impl Vecs { indexer: &Indexer, indexes: &indexes::Vecs, txins: &txins::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { // Independent computations first self.block.compute(indexer, indexes, starting_indexes, exit)?; - self.epoch.compute(indexer, indexes, starting_indexes, exit)?; + self.epoch.compute(indexes, starting_indexes, exit)?; self.transaction.compute(indexer, indexes, txins, starting_indexes, price, exit)?; // Coinbase depends on block and transaction diff --git a/crates/brk_computer/src/chain/epoch/compute.rs b/crates/brk_computer/src/chain/epoch/compute.rs index 4d2004687..b3bb30719 100644 --- a/crates/brk_computer/src/chain/epoch/compute.rs +++ b/crates/brk_computer/src/chain/epoch/compute.rs @@ -1,46 +1,17 @@ use brk_error::Result; -use brk_indexer::Indexer; -use brk_types::Timestamp; +use brk_types::StoredU32; use vecdb::{Exit, TypedVecIterator}; use super::Vecs; -use crate::{Indexes, indexes}; +use crate::{chain::TARGET_BLOCKS_PER_DAY_F32, indexes, ComputeIndexes}; impl Vecs { pub fn compute( &mut self, - indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { - self.timeindexes_to_timestamp - .compute_all(starting_indexes, exit, |vec| { - vec.compute_transform( - starting_indexes.dateindex, - &indexes.time.dateindex_to_date, - |(di, d, ..)| (di, Timestamp::from(d)), - exit, - )?; - Ok(()) - })?; - - let mut height_to_timestamp_iter = indexer.vecs.block.height_to_timestamp.iter()?; - - self.difficultyepoch_to_timestamp.compute_transform( - starting_indexes.difficultyepoch, - &indexes.block.difficultyepoch_to_first_height, - |(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)), - exit, - )?; - - self.halvingepoch_to_timestamp.compute_transform( - starting_indexes.halvingepoch, - &indexes.block.halvingepoch_to_first_height, - |(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)), - exit, - )?; - let mut height_to_difficultyepoch_iter = indexes.block.height_to_difficultyepoch.into_iter(); self.indexes_to_difficultyepoch @@ -80,6 +51,65 @@ impl Vecs { Ok(()) })?; + // Countdown metrics (moved from mining) + self.indexes_to_blocks_before_next_difficulty_adjustment + .compute_all(indexes, starting_indexes, exit, |v| { + v.compute_transform( + starting_indexes.height, + &indexes.block.height_to_height, + |(h, ..)| (h, StoredU32::from(h.left_before_next_diff_adj())), + exit, + )?; + Ok(()) + })?; + + self.indexes_to_days_before_next_difficulty_adjustment + .compute_all(indexes, starting_indexes, exit, |v| { + v.compute_transform( + starting_indexes.height, + self.indexes_to_blocks_before_next_difficulty_adjustment + .height + .as_ref() + .unwrap(), + |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), + exit, + )?; + Ok(()) + })?; + + self.indexes_to_blocks_before_next_halving.compute_all( + indexes, + starting_indexes, + exit, + |v| { + v.compute_transform( + starting_indexes.height, + &indexes.block.height_to_height, + |(h, ..)| (h, StoredU32::from(h.left_before_next_halving())), + exit, + )?; + Ok(()) + }, + )?; + + self.indexes_to_days_before_next_halving.compute_all( + indexes, + starting_indexes, + exit, + |v| { + v.compute_transform( + starting_indexes.height, + self.indexes_to_blocks_before_next_halving + .height + .as_ref() + .unwrap(), + |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), + exit, + )?; + Ok(()) + }, + )?; + Ok(()) } } diff --git a/crates/brk_computer/src/chain/epoch/import.rs b/crates/brk_computer/src/chain/epoch/import.rs index ee9dcd141..9c3cdac4a 100644 --- a/crates/brk_computer/src/chain/epoch/import.rs +++ b/crates/brk_computer/src/chain/epoch/import.rs @@ -1,29 +1,20 @@ use brk_error::Result; use brk_types::Version; -use vecdb::{Database, EagerVec, ImportableVec}; +use vecdb::Database; use super::Vecs; use crate::{ - grouped::{ComputedVecsFromDateIndex, Source, VecBuilderOptions}, + grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions}, indexes, }; impl Vecs { pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result { let v0 = Version::ZERO; + let v2 = Version::TWO; let last = || VecBuilderOptions::default().add_last(); Ok(Self { - difficultyepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?, - halvingepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?, - timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import( - db, - "timestamp", - Source::Compute, - version + v0, - indexes, - VecBuilderOptions::default().add_first(), - )?, indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import( db, "difficultyepoch", @@ -40,6 +31,41 @@ impl Vecs { indexes, last(), )?, + // Countdown metrics (moved from mining) + indexes_to_blocks_before_next_difficulty_adjustment: + ComputedVecsFromHeight::forced_import( + db, + "blocks_before_next_difficulty_adjustment", + Source::Compute, + version + v2, + indexes, + last(), + )?, + indexes_to_days_before_next_difficulty_adjustment: + ComputedVecsFromHeight::forced_import( + db, + "days_before_next_difficulty_adjustment", + Source::Compute, + version + v2, + indexes, + last(), + )?, + indexes_to_blocks_before_next_halving: ComputedVecsFromHeight::forced_import( + db, + "blocks_before_next_halving", + Source::Compute, + version + v2, + indexes, + last(), + )?, + indexes_to_days_before_next_halving: ComputedVecsFromHeight::forced_import( + db, + "days_before_next_halving", + Source::Compute, + version + v2, + indexes, + last(), + )?, }) } } diff --git a/crates/brk_computer/src/chain/epoch/vecs.rs b/crates/brk_computer/src/chain/epoch/vecs.rs index cf87f4948..507b4364e 100644 --- a/crates/brk_computer/src/chain/epoch/vecs.rs +++ b/crates/brk_computer/src/chain/epoch/vecs.rs @@ -1,15 +1,16 @@ use brk_traversable::Traversable; -use brk_types::{DifficultyEpoch, HalvingEpoch, Timestamp}; -use vecdb::{EagerVec, PcoVec}; +use brk_types::{DifficultyEpoch, HalvingEpoch, StoredF32, StoredU32}; -use crate::grouped::ComputedVecsFromDateIndex; +use crate::grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight}; -/// Epoch and timestamp metrics +/// Epoch metrics: difficulty epochs, halving epochs, and countdown to next epoch #[derive(Clone, Traversable)] pub struct Vecs { - pub difficultyepoch_to_timestamp: EagerVec>, - pub halvingepoch_to_timestamp: EagerVec>, - pub timeindexes_to_timestamp: ComputedVecsFromDateIndex, pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex, pub indexes_to_halvingepoch: ComputedVecsFromDateIndex, + // Countdown metrics (moved from mining) + pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight, + pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight, + pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight, + pub indexes_to_days_before_next_halving: ComputedVecsFromHeight, } diff --git a/crates/brk_computer/src/chain/mining/compute.rs b/crates/brk_computer/src/chain/mining/compute.rs index 2298d97ee..10b1d90ed 100644 --- a/crates/brk_computer/src/chain/mining/compute.rs +++ b/crates/brk_computer/src/chain/mining/compute.rs @@ -1,14 +1,14 @@ use brk_error::Result; use brk_indexer::Indexer; -use brk_types::{StoredF32, StoredF64, StoredU32}; +use brk_types::{StoredF32, StoredF64}; use vecdb::Exit; use super::Vecs; use crate::{ - chain::{block, coinbase, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F32, TARGET_BLOCKS_PER_DAY_F64}, + chain::{block, coinbase, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F64}, indexes, utils::OptionExt, - Indexes, + ComputeIndexes, }; impl Vecs { @@ -18,7 +18,7 @@ impl Vecs { indexes: &indexes::Vecs, block_vecs: &block::Vecs, coinbase_vecs: &coinbase::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_difficulty.compute_rest( @@ -119,64 +119,6 @@ impl Vecs { }, )?; - self.indexes_to_blocks_before_next_difficulty_adjustment - .compute_all(indexes, starting_indexes, exit, |v| { - v.compute_transform( - starting_indexes.height, - &indexes.block.height_to_height, - |(h, ..)| (h, StoredU32::from(h.left_before_next_diff_adj())), - exit, - )?; - Ok(()) - })?; - - self.indexes_to_days_before_next_difficulty_adjustment - .compute_all(indexes, starting_indexes, exit, |v| { - v.compute_transform( - starting_indexes.height, - self.indexes_to_blocks_before_next_difficulty_adjustment - .height - .as_ref() - .unwrap(), - |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), - exit, - )?; - Ok(()) - })?; - - self.indexes_to_blocks_before_next_halving.compute_all( - indexes, - starting_indexes, - exit, - |v| { - v.compute_transform( - starting_indexes.height, - &indexes.block.height_to_height, - |(h, ..)| (h, StoredU32::from(h.left_before_next_halving())), - exit, - )?; - Ok(()) - }, - )?; - - self.indexes_to_days_before_next_halving.compute_all( - indexes, - starting_indexes, - exit, - |v| { - v.compute_transform( - starting_indexes.height, - self.indexes_to_blocks_before_next_halving - .height - .as_ref() - .unwrap(), - |(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()), - exit, - )?; - Ok(()) - }, - )?; - self.indexes_to_hash_price_ths .compute_all(indexes, starting_indexes, exit, |v| { v.compute_transform2( diff --git a/crates/brk_computer/src/chain/mining/import.rs b/crates/brk_computer/src/chain/mining/import.rs index 505ee2241..643be627c 100644 --- a/crates/brk_computer/src/chain/mining/import.rs +++ b/crates/brk_computer/src/chain/mining/import.rs @@ -17,7 +17,6 @@ impl Vecs { indexes: &indexes::Vecs, ) -> Result { let v0 = Version::ZERO; - let v2 = Version::TWO; let v4 = Version::new(4); let v5 = Version::new(5); @@ -169,40 +168,6 @@ impl Vecs { indexes, sum(), )?, - indexes_to_blocks_before_next_difficulty_adjustment: - ComputedVecsFromHeight::forced_import( - db, - "blocks_before_next_difficulty_adjustment", - Source::Compute, - version + v2, - indexes, - last(), - )?, - indexes_to_days_before_next_difficulty_adjustment: - ComputedVecsFromHeight::forced_import( - db, - "days_before_next_difficulty_adjustment", - Source::Compute, - version + v2, - indexes, - last(), - )?, - indexes_to_blocks_before_next_halving: ComputedVecsFromHeight::forced_import( - db, - "blocks_before_next_halving", - Source::Compute, - version + v2, - indexes, - last(), - )?, - indexes_to_days_before_next_halving: ComputedVecsFromHeight::forced_import( - db, - "days_before_next_halving", - Source::Compute, - version + v2, - indexes, - last(), - )?, }) } } diff --git a/crates/brk_computer/src/chain/mining/vecs.rs b/crates/brk_computer/src/chain/mining/vecs.rs index b11ef72ae..825c4f905 100644 --- a/crates/brk_computer/src/chain/mining/vecs.rs +++ b/crates/brk_computer/src/chain/mining/vecs.rs @@ -1,5 +1,5 @@ use brk_traversable::Traversable; -use brk_types::{StoredF32, StoredF64, StoredU32}; +use brk_types::{StoredF32, StoredF64}; use crate::grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight}; @@ -24,8 +24,4 @@ pub struct Vecs { pub indexes_to_difficulty: ComputedVecsFromHeight, pub indexes_to_difficulty_as_hash: ComputedVecsFromHeight, pub indexes_to_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight, - pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight, - pub indexes_to_days_before_next_halving: ComputedVecsFromHeight, } diff --git a/crates/brk_computer/src/chain/output_type/compute.rs b/crates/brk_computer/src/chain/output_type/compute.rs index 0d1402022..1bc3df9d8 100644 --- a/crates/brk_computer/src/chain/output_type/compute.rs +++ b/crates/brk_computer/src/chain/output_type/compute.rs @@ -4,7 +4,7 @@ use brk_types::{Height, StoredU64}; use vecdb::{Exit, TypedVecIterator}; use super::Vecs; -use crate::{chain::transaction, indexes, Indexes}; +use crate::{chain::transaction, indexes, ComputeIndexes}; impl Vecs { pub fn compute( @@ -12,7 +12,7 @@ impl Vecs { indexer: &Indexer, indexes: &indexes::Vecs, transaction_vecs: &transaction::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_p2a_count diff --git a/crates/brk_computer/src/chain/transaction/compute.rs b/crates/brk_computer/src/chain/transaction/compute.rs index 293ee2834..66fe64298 100644 --- a/crates/brk_computer/src/chain/transaction/compute.rs +++ b/crates/brk_computer/src/chain/transaction/compute.rs @@ -4,7 +4,7 @@ use brk_types::{FeeRate, Sats, StoredU64, TxVersion}; use vecdb::{Exit, TypedVecIterator, unlikely}; use super::Vecs; -use crate::{Indexes, grouped::ComputedVecsFromHeight, indexes, price, txins}; +use crate::{ComputeIndexes, grouped::ComputedVecsFromHeight, indexes, price, txins}; impl Vecs { pub fn compute( @@ -12,7 +12,7 @@ impl Vecs { indexer: &Indexer, indexes: &indexes::Vecs, txins: &txins::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { diff --git a/crates/brk_computer/src/chain/volume/compute.rs b/crates/brk_computer/src/chain/volume/compute.rs index 2ee098f15..6c55c3d15 100644 --- a/crates/brk_computer/src/chain/volume/compute.rs +++ b/crates/brk_computer/src/chain/volume/compute.rs @@ -6,7 +6,7 @@ use vecdb::Exit; use super::Vecs; use crate::{ chain::{coinbase, transaction}, - indexes, price, Indexes, + indexes, price, ComputeIndexes, }; impl Vecs { @@ -17,7 +17,7 @@ impl Vecs { indexes: &indexes::Vecs, transaction_vecs: &transaction::Vecs, coinbase_vecs: &coinbase::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { diff --git a/crates/brk_computer/src/cointime.rs b/crates/brk_computer/src/cointime.rs index 1ba396223..07d93fe3a 100644 --- a/crates/brk_computer/src/cointime.rs +++ b/crates/brk_computer/src/cointime.rs @@ -8,7 +8,7 @@ use vecdb::{Database, Exit, PAGE_SIZE, TypedVecIterator}; use crate::{grouped::ComputedVecsFromDateIndex, utils::OptionExt}; use super::{ - Indexes, chain, + ComputeIndexes, chain, grouped::{ ComputedRatioVecsFromDateIndex, ComputedValueVecsFromHeight, ComputedVecsFromHeight, Source, VecBuilderOptions, @@ -198,7 +198,7 @@ impl Vecs { pub fn compute( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, chain: &chain::Vecs, stateful: &stateful::Vecs, @@ -214,7 +214,7 @@ impl Vecs { fn compute_( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, chain: &chain::Vecs, stateful: &stateful::Vecs, diff --git a/crates/brk_computer/src/fetched.rs b/crates/brk_computer/src/fetched.rs index b08bf355a..d30219277 100644 --- a/crates/brk_computer/src/fetched.rs +++ b/crates/brk_computer/src/fetched.rs @@ -10,7 +10,7 @@ use vecdb::{ PAGE_SIZE, TypedVecIterator, VecIndex, }; -use super::{Indexes, indexes, utils::OptionExt}; +use super::{ComputeIndexes, indexes, utils::OptionExt}; pub const DB_NAME: &str = "fetched"; @@ -59,7 +59,7 @@ impl Vecs { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.compute_(indexer, indexes, starting_indexes, exit)?; @@ -72,7 +72,7 @@ impl Vecs { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let height_to_timestamp = &indexer.vecs.block.height_to_timestamp; diff --git a/crates/brk_computer/src/grouped/computed/from_dateindex.rs b/crates/brk_computer/src/grouped/computed/from_dateindex.rs index b7be631a2..d2011c97b 100644 --- a/crates/brk_computer/src/grouped/computed/from_dateindex.rs +++ b/crates/brk_computer/src/grouped/computed/from_dateindex.rs @@ -9,7 +9,7 @@ use vecdb::{ PcoVec, }; -use crate::{Indexes, grouped::LazyVecsBuilder, indexes, utils::OptionExt}; +use crate::{ComputeIndexes, grouped::LazyVecsBuilder, indexes, utils::OptionExt}; use crate::grouped::{ComputedVecValue, EagerVecsBuilder, Source, VecBuilderOptions}; @@ -114,7 +114,7 @@ where pub fn compute_all( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, mut compute: F, ) -> Result<()> @@ -129,7 +129,7 @@ where pub fn compute_rest( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, dateindex: Option<&impl IterableVec>, ) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/computed/from_height/standard.rs b/crates/brk_computer/src/grouped/computed/from_height/standard.rs index 5baef01ce..e64458ece 100644 --- a/crates/brk_computer/src/grouped/computed/from_height/standard.rs +++ b/crates/brk_computer/src/grouped/computed/from_height/standard.rs @@ -12,7 +12,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{LazyVecsBuilder, Source}, indexes, utils::OptionExt, @@ -139,7 +139,7 @@ where pub fn compute_all( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, mut compute: F, ) -> Result<()> @@ -155,7 +155,7 @@ where pub fn compute_rest( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, height_vec: Option<&impl IterableVec>, ) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/computed/from_height/strict.rs b/crates/brk_computer/src/grouped/computed/from_height/strict.rs index e0fe245a4..301edb696 100644 --- a/crates/brk_computer/src/grouped/computed/from_height/strict.rs +++ b/crates/brk_computer/src/grouped/computed/from_height/strict.rs @@ -7,7 +7,7 @@ use vecdb::{ AnyExportableVec, Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, PcoVec, }; -use crate::{Indexes, indexes}; +use crate::{ComputeIndexes, indexes}; use crate::grouped::{ComputedVecValue, EagerVecsBuilder, LazyVecsBuilder, VecBuilderOptions}; @@ -64,7 +64,7 @@ where pub fn compute( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, mut compute: F, ) -> Result<()> diff --git a/crates/brk_computer/src/grouped/computed/from_txindex.rs b/crates/brk_computer/src/grouped/computed/from_txindex.rs index d9bbfbf9d..4a4973a73 100644 --- a/crates/brk_computer/src/grouped/computed/from_txindex.rs +++ b/crates/brk_computer/src/grouped/computed/from_txindex.rs @@ -12,7 +12,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{LazyVecsBuilder, Source}, indexes, price, utils::OptionExt, @@ -135,7 +135,7 @@ where // &mut self, // indexer: &Indexer, // indexes: &indexes::Vecs, - // starting_indexes: &Indexes, + // starting_indexes: &ComputeIndexes, // exit: &Exit, // mut compute: F, // ) -> Result<()> @@ -166,7 +166,7 @@ where &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, txindex: Option<&impl CollectableVec>, ) -> Result<()> { @@ -196,7 +196,7 @@ where fn compute_after_height( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.dateindex.from_aligned( @@ -216,7 +216,7 @@ impl ComputedVecsFromTxindex { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, sats: &ComputedVecsFromTxindex, txindex: Option<&impl CollectableVec>, @@ -314,7 +314,7 @@ impl ComputedVecsFromTxindex { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, bitcoin: &ComputedVecsFromTxindex, txindex: Option<&impl CollectableVec>, diff --git a/crates/brk_computer/src/grouped/specialized/percentiles.rs b/crates/brk_computer/src/grouped/specialized/percentiles.rs index cb247be7a..527c845b6 100644 --- a/crates/brk_computer/src/grouped/specialized/percentiles.rs +++ b/crates/brk_computer/src/grouped/specialized/percentiles.rs @@ -6,7 +6,7 @@ use vecdb::{ AnyExportableVec, AnyStoredVec, Database, EagerVec, Exit, GenericStoredVec, PcoVec, }; -use crate::{Indexes, indexes}; +use crate::{ComputeIndexes, indexes}; use super::super::{ComputedVecsFromDateIndex, Source, VecBuilderOptions}; @@ -65,7 +65,7 @@ impl PricePercentiles { Ok(()) } - pub fn compute_rest(&mut self, starting_indexes: &Indexes, exit: &Exit) -> Result<()> { + pub fn compute_rest(&mut self, starting_indexes: &ComputeIndexes, exit: &Exit) -> Result<()> { for vec in self.vecs.iter_mut().flatten() { vec.compute_rest( starting_indexes, diff --git a/crates/brk_computer/src/grouped/specialized/ratio.rs b/crates/brk_computer/src/grouped/specialized/ratio.rs index 0a4d531b5..4ed4159c7 100644 --- a/crates/brk_computer/src/grouped/specialized/ratio.rs +++ b/crates/brk_computer/src/grouped/specialized/ratio.rs @@ -7,7 +7,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ ComputedStandardDeviationVecsFromDateIndex, LazyVecsFrom2FromDateIndex, PriceTimesRatio, StandardDeviationVecsOptions, source::Source, @@ -157,7 +157,7 @@ impl ComputedRatioVecsFromDateIndex { pub fn compute_all( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, compute: F, ) -> Result<()> @@ -176,7 +176,7 @@ impl ComputedRatioVecsFromDateIndex { pub fn compute_rest( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, price_opt: Option<&impl IterableVec>, ) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/specialized/stddev.rs b/crates/brk_computer/src/grouped/specialized/stddev.rs index cb0cb7a20..0ecf0d3a7 100644 --- a/crates/brk_computer/src/grouped/specialized/stddev.rs +++ b/crates/brk_computer/src/grouped/specialized/stddev.rs @@ -8,7 +8,7 @@ use vecdb::{ PcoVec, VecIndex, }; -use crate::{Indexes, grouped::source::Source, indexes, price, utils::OptionExt}; +use crate::{ComputeIndexes, grouped::source::Source, indexes, price, utils::OptionExt}; use super::super::{ ClosePriceTimesRatio, ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, VecBuilderOptions, @@ -195,7 +195,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { pub fn compute_all( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, source: &impl CollectableVec, ) -> Result<()> { @@ -221,7 +221,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { pub fn compute_rest( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, sma_opt: Option<&impl IterableVec>, source: &impl CollectableVec, diff --git a/crates/brk_computer/src/grouped/value/computed/from_dateindex.rs b/crates/brk_computer/src/grouped/value/computed/from_dateindex.rs index 54a3633e2..27f5955ee 100644 --- a/crates/brk_computer/src/grouped/value/computed/from_dateindex.rs +++ b/crates/brk_computer/src/grouped/value/computed/from_dateindex.rs @@ -4,7 +4,7 @@ use brk_types::{Bitcoin, DateIndex, Dollars, Sats, Version}; use vecdb::{CollectableVec, Database, EagerVec, Exit, IterableCloneableVec, PcoVec}; use crate::{ - Indexes, + ComputeIndexes, grouped::{ComputedVecsFromDateIndex, LazyVecsFromDateIndex, SatsToBitcoin}, indexes, price, traits::ComputeFromBitcoin, @@ -71,7 +71,7 @@ impl ComputedValueVecsFromDateIndex { pub fn compute_all( &mut self, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, mut compute: F, ) -> Result<()> @@ -89,7 +89,7 @@ impl ComputedValueVecsFromDateIndex { pub fn compute_rest( &mut self, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, dateindex: Option<&impl CollectableVec>, ) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/value/computed/from_height.rs b/crates/brk_computer/src/grouped/value/computed/from_height.rs index 52b04663e..a1d112dc6 100644 --- a/crates/brk_computer/src/grouped/value/computed/from_height.rs +++ b/crates/brk_computer/src/grouped/value/computed/from_height.rs @@ -4,7 +4,7 @@ use brk_types::{Bitcoin, Dollars, Height, Sats, Version}; use vecdb::{CollectableVec, Database, EagerVec, Exit, IterableCloneableVec, PcoVec}; use crate::{ - Indexes, + ComputeIndexes, grouped::{LazyVecsFromHeight, SatsToBitcoin, Source}, indexes, price, traits::ComputeFromBitcoin, @@ -74,7 +74,7 @@ impl ComputedValueVecsFromHeight { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, mut compute: F, ) -> Result<()> @@ -93,7 +93,7 @@ impl ComputedValueVecsFromHeight { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, height: Option<&impl CollectableVec>, ) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/value/computed/from_txindex.rs b/crates/brk_computer/src/grouped/value/computed/from_txindex.rs index d5ff34d9b..dea403a97 100644 --- a/crates/brk_computer/src/grouped/value/computed/from_txindex.rs +++ b/crates/brk_computer/src/grouped/value/computed/from_txindex.rs @@ -7,7 +7,7 @@ use vecdb::{ VecIndex, }; -use crate::{Indexes, grouped::Source, indexes, price, utils::OptionExt}; +use crate::{ComputeIndexes, grouped::Source, indexes, price, utils::OptionExt}; use crate::grouped::{ComputedVecsFromTxindex, VecBuilderOptions}; @@ -113,7 +113,7 @@ impl ComputedValueVecsFromTxindex { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, txindex: Option<&impl CollectableVec>, price: Option<&price::Vecs>, diff --git a/crates/brk_computer/src/indexes/mod.rs b/crates/brk_computer/src/indexes/mod.rs index a56de7a27..827d1df8b 100644 --- a/crates/brk_computer/src/indexes/mod.rs +++ b/crates/brk_computer/src/indexes/mod.rs @@ -3,16 +3,15 @@ mod block; mod time; mod transaction; -use std::{ops::Deref, path::Path}; +use std::path::Path; use brk_error::Result; use brk_indexer::Indexer; use brk_traversable::Traversable; -use brk_types::{ - DateIndex, DecadeIndex, DifficultyEpoch, HalvingEpoch, Height, MonthIndex, QuarterIndex, - SemesterIndex, Version, WeekIndex, YearIndex, -}; -use vecdb::{Database, Exit, PAGE_SIZE, TypedVecIterator}; +use brk_types::{Indexes, Version}; + +pub use brk_types::ComputeIndexes; +use vecdb::{Database, Exit, PAGE_SIZE}; pub use address::Vecs as AddressVecs; pub use block::Vecs as BlockVecs; @@ -63,9 +62,9 @@ impl Vecs { pub fn compute( &mut self, indexer: &Indexer, - starting_indexes: brk_indexer::Indexes, + starting_indexes: Indexes, exit: &Exit, - ) -> Result { + ) -> Result { let indexes = self.compute_(indexer, starting_indexes, exit)?; let _lock = exit.lock(); self.db.compact()?; @@ -75,9 +74,9 @@ impl Vecs { fn compute_( &mut self, indexer: &Indexer, - starting_indexes: brk_indexer::Indexes, + starting_indexes: Indexes, exit: &Exit, - ) -> Result { + ) -> Result { // Transaction indexes self.transaction.compute(indexer, &starting_indexes, exit)?; @@ -90,60 +89,17 @@ impl Vecs { .time .compute(indexer, &starting_indexes, starting_dateindex, &self.block, exit)?; - Ok(Indexes { - indexes: starting_indexes, - dateindex: time_indexes.dateindex, - weekindex: time_indexes.weekindex, - monthindex: time_indexes.monthindex, - quarterindex: time_indexes.quarterindex, - semesterindex: time_indexes.semesterindex, - yearindex: time_indexes.yearindex, - decadeindex: time_indexes.decadeindex, - difficultyepoch: starting_difficultyepoch, - halvingepoch: starting_halvingepoch, - }) - } -} - -#[derive(Debug, Clone)] -pub struct Indexes { - indexes: brk_indexer::Indexes, - pub dateindex: DateIndex, - pub weekindex: WeekIndex, - pub monthindex: MonthIndex, - pub quarterindex: QuarterIndex, - pub semesterindex: SemesterIndex, - pub yearindex: YearIndex, - pub decadeindex: DecadeIndex, - pub difficultyepoch: DifficultyEpoch, - pub halvingepoch: HalvingEpoch, -} - -impl Indexes { - pub fn update_from_height(&mut self, height: Height, indexes: &Vecs) { - self.indexes.height = height; - self.dateindex = DateIndex::try_from( - indexes - .block - .height_to_date_fixed - .into_iter() - .get_unwrap(height), - ) - .unwrap(); - self.weekindex = WeekIndex::from(self.dateindex); - self.monthindex = MonthIndex::from(self.dateindex); - self.quarterindex = QuarterIndex::from(self.monthindex); - self.semesterindex = SemesterIndex::from(self.monthindex); - self.yearindex = YearIndex::from(self.monthindex); - self.decadeindex = DecadeIndex::from(self.dateindex); - self.difficultyepoch = DifficultyEpoch::from(self.height); - self.halvingepoch = HalvingEpoch::from(self.height); - } -} - -impl Deref for Indexes { - type Target = brk_indexer::Indexes; - fn deref(&self) -> &Self::Target { - &self.indexes + Ok(ComputeIndexes::new( + starting_indexes, + time_indexes.dateindex, + time_indexes.weekindex, + time_indexes.monthindex, + time_indexes.quarterindex, + time_indexes.semesterindex, + time_indexes.yearindex, + time_indexes.decadeindex, + starting_difficultyepoch, + starting_halvingepoch, + )) } } diff --git a/crates/brk_computer/src/lib.rs b/crates/brk_computer/src/lib.rs index 863bf0b4a..a758bcf4b 100644 --- a/crates/brk_computer/src/lib.rs +++ b/crates/brk_computer/src/lib.rs @@ -27,7 +27,7 @@ mod txins; mod txouts; mod utils; -use indexes::Indexes; +use indexes::ComputeIndexes; use utils::OptionExt; #[derive(Clone, Traversable)] diff --git a/crates/brk_computer/src/market/ath/compute.rs b/crates/brk_computer/src/market/ath/compute.rs index b68b24928..07601a89c 100644 --- a/crates/brk_computer/src/market/ath/compute.rs +++ b/crates/brk_computer/src/market/ath/compute.rs @@ -3,13 +3,13 @@ use brk_types::StoredU16; use vecdb::{Exit, GenericStoredVec, TypedVecIterator, VecIndex}; use super::Vecs; -use crate::{Indexes, price, traits::ComputeDrawdown, utils::OptionExt}; +use crate::{ComputeIndexes, price, traits::ComputeDrawdown, utils::OptionExt}; impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.height_to_price_ath.compute_all_time_high( diff --git a/crates/brk_computer/src/market/compute.rs b/crates/brk_computer/src/market/compute.rs index aa25cc2e8..e98779600 100644 --- a/crates/brk_computer/src/market/compute.rs +++ b/crates/brk_computer/src/market/compute.rs @@ -1,7 +1,7 @@ use brk_error::Result; use vecdb::Exit; -use crate::{price, Indexes}; +use crate::{price, ComputeIndexes}; use crate::utils::OptionExt; use super::Vecs; @@ -10,7 +10,7 @@ impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { // ATH metrics (independent) diff --git a/crates/brk_computer/src/market/dca/compute.rs b/crates/brk_computer/src/market/dca/compute.rs index dc70e8e75..23e983c7f 100644 --- a/crates/brk_computer/src/market/dca/compute.rs +++ b/crates/brk_computer/src/market/dca/compute.rs @@ -7,14 +7,14 @@ use crate::{ price, traits::{ComputeDCAAveragePriceViaLen, ComputeDCAStackViaLen}, utils::OptionExt, - Indexes, + ComputeIndexes, }; impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let close = price.timeindexes_to_price_close.dateindex.u(); diff --git a/crates/brk_computer/src/market/history/compute.rs b/crates/brk_computer/src/market/history/compute.rs index 403fa075e..c7ce2b730 100644 --- a/crates/brk_computer/src/market/history/compute.rs +++ b/crates/brk_computer/src/market/history/compute.rs @@ -2,13 +2,13 @@ use brk_error::Result; use vecdb::Exit; use super::Vecs; -use crate::{price, utils::OptionExt, Indexes}; +use crate::{price, utils::OptionExt, ComputeIndexes}; impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let close = price.timeindexes_to_price_close.dateindex.u(); diff --git a/crates/brk_computer/src/market/moving_average/compute.rs b/crates/brk_computer/src/market/moving_average/compute.rs index f2ddecea6..698c2063c 100644 --- a/crates/brk_computer/src/market/moving_average/compute.rs +++ b/crates/brk_computer/src/market/moving_average/compute.rs @@ -2,13 +2,13 @@ use brk_error::Result; use vecdb::Exit; use super::Vecs; -use crate::{price, utils::OptionExt, Indexes}; +use crate::{price, utils::OptionExt, ComputeIndexes}; impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let close = price.timeindexes_to_price_close.dateindex.u(); diff --git a/crates/brk_computer/src/market/range/compute.rs b/crates/brk_computer/src/market/range/compute.rs index b160f7d3b..d41e2fd1e 100644 --- a/crates/brk_computer/src/market/range/compute.rs +++ b/crates/brk_computer/src/market/range/compute.rs @@ -3,13 +3,13 @@ use brk_types::StoredF32; use vecdb::Exit; use super::Vecs; -use crate::{price, utils::OptionExt, Indexes}; +use crate::{price, utils::OptionExt, ComputeIndexes}; impl Vecs { pub fn compute( &mut self, price: &price::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let open = price.timeindexes_to_price_open.dateindex.u(); diff --git a/crates/brk_computer/src/market/volatility/compute.rs b/crates/brk_computer/src/market/volatility/compute.rs index 3869b4ecb..63120d825 100644 --- a/crates/brk_computer/src/market/volatility/compute.rs +++ b/crates/brk_computer/src/market/volatility/compute.rs @@ -3,12 +3,12 @@ use brk_types::{DateIndex, StoredF32}; use vecdb::{CollectableVec, Exit}; use super::Vecs; -use crate::Indexes; +use crate::ComputeIndexes; impl Vecs { pub fn compute( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, _1d_price_returns_dateindex: &V, ) -> Result<()> diff --git a/crates/brk_computer/src/pools/mod.rs b/crates/brk_computer/src/pools/mod.rs index b31a128ff..13acba37e 100644 --- a/crates/brk_computer/src/pools/mod.rs +++ b/crates/brk_computer/src/pools/mod.rs @@ -15,7 +15,7 @@ mod vecs; use crate::{ chain, - indexes::{self, Indexes}, + indexes::{self, ComputeIndexes}, price, }; @@ -78,7 +78,7 @@ impl Vecs { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { @@ -92,7 +92,7 @@ impl Vecs { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, price: Option<&price::Vecs>, exit: &Exit, ) -> Result<()> { @@ -109,7 +109,7 @@ impl Vecs { &mut self, indexer: &Indexer, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.height_to_pool.validate_computed_version_or_reset( diff --git a/crates/brk_computer/src/pools/vecs.rs b/crates/brk_computer/src/pools/vecs.rs index 56b9b0f33..c6b4c6b56 100644 --- a/crates/brk_computer/src/pools/vecs.rs +++ b/crates/brk_computer/src/pools/vecs.rs @@ -14,7 +14,7 @@ use crate::{ LazyVecsFrom2FromHeight, MaskSats, PercentageU32F32, SatsPlus, SatsPlusToBitcoin, Source, VecBuilderOptions, }, - indexes::{self, Indexes}, + indexes::{self, ComputeIndexes}, price, }; @@ -211,7 +211,7 @@ impl Vecs { pub fn compute( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_pool: &impl IterableVec, price: Option<&price::Vecs>, exit: &Exit, diff --git a/crates/brk_computer/src/price.rs b/crates/brk_computer/src/price.rs index 03f11064e..18c2ba1ff 100644 --- a/crates/brk_computer/src/price.rs +++ b/crates/brk_computer/src/price.rs @@ -11,7 +11,7 @@ use vecdb::{BytesVec, Database, EagerVec, Exit, ImportableVec, PAGE_SIZE, PcoVec use crate::{fetched, grouped::Source, utils::OptionExt}; use super::{ - Indexes, + ComputeIndexes, grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeightStrict, VecBuilderOptions}, indexes, }; @@ -189,7 +189,7 @@ impl Vecs { pub fn compute( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, fetched: &fetched::Vecs, exit: &Exit, ) -> Result<()> { @@ -201,7 +201,7 @@ impl Vecs { fn compute_( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, fetched: &fetched::Vecs, exit: &Exit, ) -> Result<()> { diff --git a/crates/brk_computer/src/stateful/address/address_count.rs b/crates/brk_computer/src/stateful/address/address_count.rs index c6caeb18d..943c020ca 100644 --- a/crates/brk_computer/src/stateful/address/address_count.rs +++ b/crates/brk_computer/src/stateful/address/address_count.rs @@ -1,5 +1,5 @@ +use brk_cohort::ByAddressType; use brk_error::Result; -use brk_grouper::ByAddressType; use brk_traversable::Traversable; use brk_types::{Height, StoredU64, Version}; use derive_deref::{Deref, DerefMut}; @@ -10,7 +10,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ComputedVecsFromHeight, Source, VecBuilderOptions}, indexes, }; @@ -192,7 +192,7 @@ impl AddressTypeToIndexesToAddressCount { pub fn compute( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, addresstype_to_height_to_addresscount: &AddressTypeToHeightToAddressCount, ) -> Result<()> { diff --git a/crates/brk_computer/src/stateful/address/type_map/index_map.rs b/crates/brk_computer/src/stateful/address/type_map/index_map.rs index 2490e7066..ff6a8f32d 100644 --- a/crates/brk_computer/src/stateful/address/type_map/index_map.rs +++ b/crates/brk_computer/src/stateful/address/type_map/index_map.rs @@ -1,6 +1,6 @@ use std::{collections::hash_map::Entry, mem}; -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use brk_types::{OutputType, TypeIndex}; use derive_deref::{Deref, DerefMut}; use rustc_hash::FxHashMap; @@ -124,4 +124,3 @@ where self } } - diff --git a/crates/brk_computer/src/stateful/address/type_map/vec.rs b/crates/brk_computer/src/stateful/address/type_map/vec.rs index 68e7dec2d..44d9632a6 100644 --- a/crates/brk_computer/src/stateful/address/type_map/vec.rs +++ b/crates/brk_computer/src/stateful/address/type_map/vec.rs @@ -1,4 +1,4 @@ -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use derive_deref::{Deref, DerefMut}; /// A vector for each address type. diff --git a/crates/brk_computer/src/stateful/block/cache/address.rs b/crates/brk_computer/src/stateful/block/cache/address.rs index ff3a97a4c..734539fda 100644 --- a/crates/brk_computer/src/stateful/block/cache/address.rs +++ b/crates/brk_computer/src/stateful/block/cache/address.rs @@ -1,4 +1,4 @@ -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use brk_types::{AnyAddressDataIndexEnum, LoadedAddressData, OutputType, TypeIndex}; use vecdb::GenericStoredVec; @@ -7,11 +7,11 @@ use crate::stateful::{ compute::VecsReaders, }; -use super::lookup::AddressLookup; use super::super::cohort::{ - update_tx_counts, EmptyAddressDataWithSource, LoadedAddressDataWithSource, TxIndexVec, - WithAddressDataSource, + EmptyAddressDataWithSource, LoadedAddressDataWithSource, TxIndexVec, WithAddressDataSource, + update_tx_counts, }; +use super::lookup::AddressLookup; /// Cache for address data within a flush interval. pub struct AddressCache { diff --git a/crates/brk_computer/src/stateful/block/cohort/received.rs b/crates/brk_computer/src/stateful/block/cohort/received.rs index baabb5a06..3491c3ed5 100644 --- a/crates/brk_computer/src/stateful/block/cohort/received.rs +++ b/crates/brk_computer/src/stateful/block/cohort/received.rs @@ -1,4 +1,4 @@ -use brk_grouper::{AmountBucket, ByAddressType}; +use brk_cohort::{AmountBucket, ByAddressType}; use brk_types::{Dollars, Sats, TypeIndex}; use rustc_hash::FxHashMap; diff --git a/crates/brk_computer/src/stateful/block/cohort/sent.rs b/crates/brk_computer/src/stateful/block/cohort/sent.rs index 284e83932..f0ed7fd0b 100644 --- a/crates/brk_computer/src/stateful/block/cohort/sent.rs +++ b/crates/brk_computer/src/stateful/block/cohort/sent.rs @@ -1,5 +1,5 @@ +use brk_cohort::{AmountBucket, ByAddressType}; use brk_error::Result; -use brk_grouper::{AmountBucket, ByAddressType}; use brk_types::{CheckedSub, Dollars, Height, Sats, Timestamp, TypeIndex}; use vecdb::{VecIndex, unlikely}; diff --git a/crates/brk_computer/src/stateful/block/utxo/inputs.rs b/crates/brk_computer/src/stateful/block/utxo/inputs.rs index 739e78a52..2aefbaafe 100644 --- a/crates/brk_computer/src/stateful/block/utxo/inputs.rs +++ b/crates/brk_computer/src/stateful/block/utxo/inputs.rs @@ -1,4 +1,4 @@ -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use brk_types::{Height, OutputType, Sats, TxIndex, TypeIndex}; use rayon::prelude::*; use rustc_hash::FxHashMap; diff --git a/crates/brk_computer/src/stateful/block/utxo/outputs.rs b/crates/brk_computer/src/stateful/block/utxo/outputs.rs index d229fc7cd..fe361e183 100644 --- a/crates/brk_computer/src/stateful/block/utxo/outputs.rs +++ b/crates/brk_computer/src/stateful/block/utxo/outputs.rs @@ -1,14 +1,16 @@ -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use brk_types::{Sats, TxIndex, TypeIndex}; use crate::stateful::{ - address::{AddressTypeToTypeIndexMap, AddressTypeToVec, AddressesDataVecs, AnyAddressIndexesVecs}, + address::{ + AddressTypeToTypeIndexMap, AddressTypeToVec, AddressesDataVecs, AnyAddressIndexesVecs, + }, compute::{TxOutData, VecsReaders}, state::Transacted, }; use super::super::{ - cache::{load_uncached_address_data, AddressCache}, + cache::{AddressCache, load_uncached_address_data}, cohort::{LoadedAddressDataWithSource, TxIndexVec}, }; diff --git a/crates/brk_computer/src/stateful/cohorts/address/groups.rs b/crates/brk_computer/src/stateful/cohorts/address/groups.rs index ec6ff6f4d..e051fb3a4 100644 --- a/crates/brk_computer/src/stateful/cohorts/address/groups.rs +++ b/crates/brk_computer/src/stateful/cohorts/address/groups.rs @@ -1,23 +1,20 @@ use std::path::Path; -use brk_error::Result; -use brk_grouper::{ +use brk_cohort::{ AddressGroups, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, Filter, Filtered, }; +use brk_error::Result; use brk_traversable::Traversable; use brk_types::{Bitcoin, DateIndex, Dollars, Height, Version}; use derive_deref::{Deref, DerefMut}; use rayon::prelude::*; use vecdb::{AnyStoredVec, Database, Exit, IterableVec}; -use crate::{Indexes, indexes, price, stateful::DynCohortVecs}; +use crate::{ComputeIndexes, indexes, price, stateful::DynCohortVecs}; use crate::stateful::metrics::SupplyMetrics; -use super::{ - super::traits::CohortVecs, - vecs::AddressCohortVecs, -}; +use super::{super::traits::CohortVecs, vecs::AddressCohortVecs}; const VERSION: Version = Version::new(0); @@ -41,11 +38,13 @@ impl AddressCohorts { let v = version + VERSION + Version::ZERO; // Helper to create a cohort - only amount_range cohorts have state - let create = - |filter: Filter, name: &'static str, has_state: bool| -> Result { - let sp = if has_state { Some(states_path) } else { None }; - AddressCohortVecs::forced_import(db, filter, name, v, indexes, price, sp, all_supply) - }; + let create = |filter: Filter, + name: &'static str, + has_state: bool| + -> Result { + let sp = if has_state { Some(states_path) } else { None }; + AddressCohortVecs::forced_import(db, filter, name, v, indexes, price, sp, all_supply) + }; let full = |f: Filter, name: &'static str| create(f, name, true); let none = |f: Filter, name: &'static str| create(f, name, false); @@ -62,7 +61,7 @@ impl AddressCohorts { /// For example, ">=1 BTC" cohort is computed from sum of amount_range cohorts that match. pub fn compute_overlapping_vecs( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let by_amount_range = &self.0.amount_range; @@ -111,7 +110,7 @@ impl AddressCohorts { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.par_iter_mut() @@ -124,7 +123,7 @@ impl AddressCohorts { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &S, height_to_market_cap: Option<&HM>, dateindex_to_market_cap: Option<&DM>, diff --git a/crates/brk_computer/src/stateful/cohorts/address/vecs.rs b/crates/brk_computer/src/stateful/cohorts/address/vecs.rs index 71da5634e..037331bfd 100644 --- a/crates/brk_computer/src/stateful/cohorts/address/vecs.rs +++ b/crates/brk_computer/src/stateful/cohorts/address/vecs.rs @@ -1,7 +1,7 @@ use std::path::Path; +use brk_cohort::{CohortContext, Filter, Filtered}; use brk_error::Result; -use brk_grouper::{CohortContext, Filter, Filtered}; use brk_traversable::Traversable; use brk_types::{Bitcoin, DateIndex, Dollars, Height, StoredU64, Version}; use rayon::prelude::*; @@ -11,7 +11,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ComputedVecsFromHeight, Source, VecBuilderOptions}, indexes, price, stateful::state::AddressCohortState, @@ -250,7 +250,7 @@ impl DynCohortVecs for AddressCohortVecs { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_addr_count.compute_rest( @@ -268,7 +268,7 @@ impl DynCohortVecs for AddressCohortVecs { impl CohortVecs for AddressCohortVecs { fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -293,7 +293,7 @@ impl CohortVecs for AddressCohortVecs { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &impl IterableVec, height_to_market_cap: Option<&impl IterableVec>, dateindex_to_market_cap: Option<&impl IterableVec>, diff --git a/crates/brk_computer/src/stateful/cohorts/traits.rs b/crates/brk_computer/src/stateful/cohorts/traits.rs index abf8ec86a..282c82b30 100644 --- a/crates/brk_computer/src/stateful/cohorts/traits.rs +++ b/crates/brk_computer/src/stateful/cohorts/traits.rs @@ -2,7 +2,7 @@ use brk_error::Result; use brk_types::{Bitcoin, DateIndex, Dollars, Height, Version}; use vecdb::{Exit, IterableVec}; -use crate::{Indexes, indexes, price}; +use crate::{ComputeIndexes, indexes, price}; /// Dynamic dispatch trait for cohort vectors. /// @@ -38,7 +38,7 @@ pub trait DynCohortVecs: Send + Sync { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()>; } @@ -48,7 +48,7 @@ pub trait CohortVecs: DynCohortVecs { /// Compute aggregate cohort from component cohorts. fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()>; @@ -59,7 +59,7 @@ pub trait CohortVecs: DynCohortVecs { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &impl IterableVec, height_to_market_cap: Option<&impl IterableVec>, dateindex_to_market_cap: Option<&impl IterableVec>, diff --git a/crates/brk_computer/src/stateful/cohorts/utxo/groups.rs b/crates/brk_computer/src/stateful/cohorts/utxo/groups.rs index 51a8871b3..1ec1bc0f8 100644 --- a/crates/brk_computer/src/stateful/cohorts/utxo/groups.rs +++ b/crates/brk_computer/src/stateful/cohorts/utxo/groups.rs @@ -1,10 +1,10 @@ use std::path::Path; -use brk_error::Result; -use brk_grouper::{ +use brk_cohort::{ ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge, ByMinAge, BySpendableType, ByTerm, ByYear, Filter, Filtered, StateLevel, UTXOGroups, }; +use brk_error::Result; use brk_traversable::Traversable; use brk_types::{Bitcoin, DateIndex, Dollars, Height, Sats, Version}; use derive_deref::{Deref, DerefMut}; @@ -12,16 +12,13 @@ use rayon::prelude::*; use vecdb::{AnyStoredVec, Database, Exit, IterableVec}; use crate::{ - Indexes, + ComputeIndexes, grouped::{PERCENTILES, PERCENTILES_LEN}, indexes, price, stateful::DynCohortVecs, }; -use super::{ - super::traits::CohortVecs, - vecs::UTXOCohortVecs, -}; +use super::{super::traits::CohortVecs, vecs::UTXOCohortVecs}; const VERSION: Version = Version::new(0); @@ -59,7 +56,15 @@ impl UTXOCohorts { // Create all cohorts first (while borrowing all_supply), then assemble struct let price_only = |f: Filter, name: &'static str| { UTXOCohortVecs::forced_import( - db, f, name, v, indexes, price, states_path, StateLevel::PriceOnly, all_supply, + db, + f, + name, + v, + indexes, + price, + states_path, + StateLevel::PriceOnly, + all_supply, ) }; @@ -67,12 +72,28 @@ impl UTXOCohorts { let full = |f: Filter, name: &'static str| { UTXOCohortVecs::forced_import( - db, f, name, v, indexes, price, states_path, StateLevel::Full, all_supply, + db, + f, + name, + v, + indexes, + price, + states_path, + StateLevel::Full, + all_supply, ) }; let none = |f: Filter, name: &'static str| { UTXOCohortVecs::forced_import( - db, f, name, v, indexes, price, states_path, StateLevel::None, all_supply, + db, + f, + name, + v, + indexes, + price, + states_path, + StateLevel::None, + all_supply, ) }; @@ -104,7 +125,7 @@ impl UTXOCohorts { /// Compute overlapping cohorts from component age/amount range cohorts. pub fn compute_overlapping_vecs( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let by_age_range = &self.0.age_range; @@ -172,7 +193,7 @@ impl UTXOCohorts { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.par_iter_mut() @@ -185,7 +206,7 @@ impl UTXOCohorts { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &S, height_to_market_cap: Option<&HM>, dateindex_to_market_cap: Option<&DM>, diff --git a/crates/brk_computer/src/stateful/cohorts/utxo/tick_tock.rs b/crates/brk_computer/src/stateful/cohorts/utxo/tick_tock.rs index d73f4a62b..8880ee257 100644 --- a/crates/brk_computer/src/stateful/cohorts/utxo/tick_tock.rs +++ b/crates/brk_computer/src/stateful/cohorts/utxo/tick_tock.rs @@ -1,4 +1,4 @@ -use brk_grouper::AGE_BOUNDARIES; +use brk_cohort::AGE_BOUNDARIES; use brk_types::{ONE_DAY_IN_SEC, Timestamp}; use crate::stateful::state::BlockState; diff --git a/crates/brk_computer/src/stateful/cohorts/utxo/vecs.rs b/crates/brk_computer/src/stateful/cohorts/utxo/vecs.rs index 48992cb1b..81168a838 100644 --- a/crates/brk_computer/src/stateful/cohorts/utxo/vecs.rs +++ b/crates/brk_computer/src/stateful/cohorts/utxo/vecs.rs @@ -1,13 +1,13 @@ use std::path::Path; +use brk_cohort::{CohortContext, Filter, Filtered, StateLevel}; use brk_error::Result; -use brk_grouper::{CohortContext, Filter, Filtered, StateLevel}; use brk_traversable::Traversable; use brk_types::{Bitcoin, DateIndex, Dollars, Height, Version}; use rayon::prelude::*; use vecdb::{AnyStoredVec, Database, Exit, IterableVec}; -use crate::{Indexes, indexes, price, stateful::state::UTXOCohortState}; +use crate::{ComputeIndexes, indexes, price, stateful::state::UTXOCohortState}; use crate::stateful::metrics::{CohortMetrics, ImportConfig, SupplyMetrics}; @@ -211,7 +211,7 @@ impl DynCohortVecs for UTXOCohortVecs { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.metrics @@ -222,7 +222,7 @@ impl DynCohortVecs for UTXOCohortVecs { impl CohortVecs for UTXOCohortVecs { fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -237,7 +237,7 @@ impl CohortVecs for UTXOCohortVecs { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &impl IterableVec, height_to_market_cap: Option<&impl IterableVec>, dateindex_to_market_cap: Option<&impl IterableVec>, diff --git a/crates/brk_computer/src/stateful/compute/aggregates.rs b/crates/brk_computer/src/stateful/compute/aggregates.rs index f7398740b..60a4b9fc8 100644 --- a/crates/brk_computer/src/stateful/compute/aggregates.rs +++ b/crates/brk_computer/src/stateful/compute/aggregates.rs @@ -3,7 +3,7 @@ use brk_types::{Bitcoin, DateIndex, Dollars, Height}; use log::info; use vecdb::{Exit, IterableVec}; -use crate::{Indexes, indexes, price}; +use crate::{ComputeIndexes, indexes, price}; use super::super::cohorts::{AddressCohorts, UTXOCohorts}; @@ -15,7 +15,7 @@ use super::super::cohorts::{AddressCohorts, UTXOCohorts}; pub fn compute_overlapping( utxo_cohorts: &mut UTXOCohorts, address_cohorts: &mut AddressCohorts, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { info!("Computing overlapping cohorts..."); @@ -34,7 +34,7 @@ pub fn compute_rest_part1( address_cohorts: &mut AddressCohorts, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { info!("Computing rest part 1..."); @@ -54,7 +54,7 @@ pub fn compute_rest_part2( address_cohorts: &mut AddressCohorts, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &S, height_to_market_cap: Option<&HM>, dateindex_to_market_cap: Option<&DM>, diff --git a/crates/brk_computer/src/stateful/compute/block_loop.rs b/crates/brk_computer/src/stateful/compute/block_loop.rs index caa801332..a847afab6 100644 --- a/crates/brk_computer/src/stateful/compute/block_loop.rs +++ b/crates/brk_computer/src/stateful/compute/block_loop.rs @@ -1,7 +1,7 @@ use std::thread; +use brk_cohort::ByAddressType; use brk_error::Result; -use brk_grouper::ByAddressType; use brk_indexer::Indexer; use brk_types::{DateIndex, Height, OutputType, Sats, TxIndex, TypeIndex}; use log::info; @@ -12,11 +12,11 @@ use crate::{ chain, indexes, price, stateful::{ address::AddressTypeToAddressCount, - compute::write::{process_address_updates, write}, block::{ AddressCache, InputsResult, process_inputs, process_outputs, process_received, process_sent, }, + compute::write::{process_address_updates, write}, state::{BlockState, Transacted}, }, txins, @@ -63,10 +63,15 @@ pub fn process_blocks( // From chain (via .height.u() or .height.unwrap_sum() patterns): let height_to_tx_count = chain.transaction.indexes_to_tx_count.height.u(); - let height_to_output_count = chain.transaction.indexes_to_output_count.height.unwrap_sum(); + let height_to_output_count = chain + .transaction + .indexes_to_output_count + .height + .unwrap_sum(); let height_to_input_count = chain.transaction.indexes_to_input_count.height.unwrap_sum(); let height_to_unclaimed_rewards = chain - .coinbase.indexes_to_unclaimed_rewards + .coinbase + .indexes_to_unclaimed_rewards .sats .height .as_ref() diff --git a/crates/brk_computer/src/stateful/compute/readers.rs b/crates/brk_computer/src/stateful/compute/readers.rs index bd7e5b4fd..0c2535c6b 100644 --- a/crates/brk_computer/src/stateful/compute/readers.rs +++ b/crates/brk_computer/src/stateful/compute/readers.rs @@ -1,4 +1,4 @@ -use brk_grouper::{ByAddressType, ByAnyAddress}; +use brk_cohort::{ByAddressType, ByAnyAddress}; use brk_indexer::Indexer; use brk_types::{ Height, OutPoint, OutputType, Sats, StoredU64, TxInIndex, TxIndex, TxOutIndex, TypeIndex, @@ -9,7 +9,10 @@ use vecdb::{ }; use crate::{ - stateful::{address::{AddressesDataVecs, AnyAddressIndexesVecs}, RangeMap}, + stateful::{ + RangeMap, + address::{AddressesDataVecs, AnyAddressIndexesVecs}, + }, txins, }; diff --git a/crates/brk_computer/src/stateful/metrics/activity.rs b/crates/brk_computer/src/stateful/metrics/activity.rs index d55e8caee..202abf7af 100644 --- a/crates/brk_computer/src/stateful/metrics/activity.rs +++ b/crates/brk_computer/src/stateful/metrics/activity.rs @@ -8,7 +8,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ComputedValueVecsFromHeight, ComputedVecsFromHeight, Source, VecBuilderOptions}, indexes, price, }; @@ -143,7 +143,7 @@ impl ActivityMetrics { /// Compute aggregate values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -176,7 +176,7 @@ impl ActivityMetrics { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_sent.compute_rest( diff --git a/crates/brk_computer/src/stateful/metrics/config.rs b/crates/brk_computer/src/stateful/metrics/config.rs index 9c5179cd2..603f8fbd5 100644 --- a/crates/brk_computer/src/stateful/metrics/config.rs +++ b/crates/brk_computer/src/stateful/metrics/config.rs @@ -1,4 +1,4 @@ -use brk_grouper::{CohortContext, Filter}; +use brk_cohort::{CohortContext, Filter}; use brk_types::Version; use vecdb::Database; diff --git a/crates/brk_computer/src/stateful/metrics/mod.rs b/crates/brk_computer/src/stateful/metrics/mod.rs index df4539c2d..8503fcd4a 100644 --- a/crates/brk_computer/src/stateful/metrics/mod.rs +++ b/crates/brk_computer/src/stateful/metrics/mod.rs @@ -12,14 +12,14 @@ pub use realized::RealizedMetrics; pub use supply::SupplyMetrics; pub use unrealized::UnrealizedMetrics; +use brk_cohort::Filter; use brk_error::Result; -use brk_grouper::Filter; use brk_traversable::Traversable; use brk_types::{Bitcoin, DateIndex, Dollars, Height, Version}; use rayon::prelude::*; use vecdb::{AnyStoredVec, Exit, IterableVec}; -use crate::{Indexes, indexes, price as price_vecs, stateful::state::CohortState}; +use crate::{ComputeIndexes, indexes, price as price_vecs, stateful::state::CohortState}; /// All metrics for a cohort, organized by category. #[derive(Clone, Traversable)] @@ -205,7 +205,7 @@ impl CohortMetrics { /// Compute aggregate cohort values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -261,7 +261,7 @@ impl CohortMetrics { &mut self, indexes: &indexes::Vecs, price: Option<&price_vecs::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.supply @@ -290,7 +290,7 @@ impl CohortMetrics { &mut self, indexes: &indexes::Vecs, price: Option<&price_vecs::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &impl IterableVec, height_to_market_cap: Option<&impl IterableVec>, dateindex_to_market_cap: Option<&impl IterableVec>, diff --git a/crates/brk_computer/src/stateful/metrics/price/paid.rs b/crates/brk_computer/src/stateful/metrics/price/paid.rs index bdeb53d95..31a3000ba 100644 --- a/crates/brk_computer/src/stateful/metrics/price/paid.rs +++ b/crates/brk_computer/src/stateful/metrics/price/paid.rs @@ -7,7 +7,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ComputedVecsFromHeight, PricePercentiles, Source, VecBuilderOptions}, stateful::state::CohortState, }; @@ -147,7 +147,7 @@ impl PricePaidMetrics { /// Compute aggregate values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -174,7 +174,7 @@ impl PricePaidMetrics { pub fn compute_rest_part1( &mut self, indexes: &crate::indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_min_price_paid.compute_rest( diff --git a/crates/brk_computer/src/stateful/metrics/realized.rs b/crates/brk_computer/src/stateful/metrics/realized.rs index c8e2e7d4b..747f0d32a 100644 --- a/crates/brk_computer/src/stateful/metrics/realized.rs +++ b/crates/brk_computer/src/stateful/metrics/realized.rs @@ -8,7 +8,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ ComputedRatioVecsFromDateIndex, ComputedVecsFromDateIndex, ComputedVecsFromHeight, LazyVecsFrom2FromHeight, LazyVecsFromHeight, PercentageDollarsF32, Source, @@ -515,7 +515,7 @@ impl RealizedMetrics { /// Compute aggregate values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -598,7 +598,7 @@ impl RealizedMetrics { pub fn compute_rest_part1( &mut self, indexes: &indexes::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_realized_cap.compute_rest( @@ -690,7 +690,7 @@ impl RealizedMetrics { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, height_to_supply: &impl IterableVec, height_to_market_cap: Option<&impl IterableVec>, dateindex_to_market_cap: Option<&impl IterableVec>, diff --git a/crates/brk_computer/src/stateful/metrics/supply.rs b/crates/brk_computer/src/stateful/metrics/supply.rs index 444ce7945..8c6b6ba11 100644 --- a/crates/brk_computer/src/stateful/metrics/supply.rs +++ b/crates/brk_computer/src/stateful/metrics/supply.rs @@ -8,7 +8,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ ComputedHeightValueVecs, ComputedValueVecsFromDateIndex, ComputedVecsFromHeight, HalfClosePriceTimesSats, HalveDollars, HalveSats, HalveSatsToBitcoin, LazyHeightValueVecs, @@ -157,7 +157,7 @@ impl SupplyMetrics { /// Compute aggregate values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -185,7 +185,7 @@ impl SupplyMetrics { &mut self, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_supply diff --git a/crates/brk_computer/src/stateful/metrics/unrealized.rs b/crates/brk_computer/src/stateful/metrics/unrealized.rs index ca953d442..013b9a031 100644 --- a/crates/brk_computer/src/stateful/metrics/unrealized.rs +++ b/crates/brk_computer/src/stateful/metrics/unrealized.rs @@ -8,7 +8,7 @@ use vecdb::{ }; use crate::{ - Indexes, + ComputeIndexes, grouped::{ ComputedHeightValueVecs, ComputedValueVecsFromDateIndex, ComputedVecsFromDateIndex, DollarsMinus, DollarsPlus, LazyVecsFromDateIndex, Source, VecBuilderOptions, @@ -267,7 +267,7 @@ impl UnrealizedMetrics { /// Compute aggregate values from separate cohorts. pub fn compute_from_stateful( &mut self, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, others: &[&Self], exit: &Exit, ) -> Result<()> { @@ -342,7 +342,7 @@ impl UnrealizedMetrics { pub fn compute_rest_part1( &mut self, price: Option<&crate::price::Vecs>, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.indexes_to_supply_in_profit.compute_rest( diff --git a/crates/brk_computer/src/stateful/state/transacted.rs b/crates/brk_computer/src/stateful/state/transacted.rs index 9f4d7a184..3f567bfee 100644 --- a/crates/brk_computer/src/stateful/state/transacted.rs +++ b/crates/brk_computer/src/stateful/state/transacted.rs @@ -1,6 +1,6 @@ use std::ops::{Add, AddAssign}; -use brk_grouper::{ByAmountRange, GroupedByType}; +use brk_cohort::{ByAmountRange, GroupedByType}; use brk_types::{OutputType, Sats, SupplyState}; #[derive(Default, Debug)] diff --git a/crates/brk_computer/src/stateful/vecs.rs b/crates/brk_computer/src/stateful/vecs.rs index 30bec6365..bb87df3a0 100644 --- a/crates/brk_computer/src/stateful/vecs.rs +++ b/crates/brk_computer/src/stateful/vecs.rs @@ -14,7 +14,7 @@ use vecdb::{ }; use crate::{ - Indexes, chain, + ComputeIndexes, chain, grouped::{ ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions, @@ -268,7 +268,7 @@ impl Vecs { txins: &txins::Vecs, chain: &chain::Vecs, price: Option<&price::Vecs>, - starting_indexes: &mut Indexes, + starting_indexes: &mut ComputeIndexes, exit: &Exit, ) -> Result<()> { // 1. Find minimum computed height for recovery diff --git a/crates/brk_computer/src/txins.rs b/crates/brk_computer/src/txins.rs index de3627baf..01593828c 100644 --- a/crates/brk_computer/src/txins.rs +++ b/crates/brk_computer/src/txins.rs @@ -10,7 +10,7 @@ use vecdb::{ TypedVecIterator, VecIndex, }; -use super::Indexes; +use super::ComputeIndexes; const BATCH_SIZE: usize = 2 * 1024 * 1024 * 1024 / size_of::(); pub const DB_NAME: &str = "txins"; @@ -48,7 +48,7 @@ impl Vecs { pub fn compute( &mut self, indexer: &Indexer, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.compute_(indexer, starting_indexes, exit)?; @@ -60,7 +60,7 @@ impl Vecs { fn compute_( &mut self, indexer: &Indexer, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let target = indexer.vecs.txin.txinindex_to_outpoint.len(); diff --git a/crates/brk_computer/src/txouts.rs b/crates/brk_computer/src/txouts.rs index fed09e18d..7784c394f 100644 --- a/crates/brk_computer/src/txouts.rs +++ b/crates/brk_computer/src/txouts.rs @@ -10,7 +10,7 @@ use vecdb::{ Stamp, TypedVecIterator, VecIndex, }; -use super::{Indexes, txins}; +use super::{ComputeIndexes, txins}; pub const DB_NAME: &str = "txouts"; const HEIGHT_BATCH: u32 = 10_000; @@ -47,7 +47,7 @@ impl Vecs { &mut self, indexer: &Indexer, txins: &txins::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { self.compute_(indexer, txins, starting_indexes, exit)?; @@ -60,7 +60,7 @@ impl Vecs { &mut self, indexer: &Indexer, txins: &txins::Vecs, - starting_indexes: &Indexes, + starting_indexes: &ComputeIndexes, exit: &Exit, ) -> Result<()> { let target_height = indexer.vecs.block.height_to_blockhash.len(); diff --git a/crates/brk_indexer/BENCH.md b/crates/brk_indexer/BENCH.md deleted file mode 100644 index 7e249a03b..000000000 --- a/crates/brk_indexer/BENCH.md +++ /dev/null @@ -1,13 +0,0 @@ -## Bench - -MBP M3 Pro - -Range: ~0..920_000 - -Time: ~10h30mn - -RAM: -Peak: ~11GB -At the end: ~6.5GB - -storage: 223GB diff --git a/crates/brk_indexer/Cargo.toml b/crates/brk_indexer/Cargo.toml index 250d0b68d..601c45024 100644 --- a/crates/brk_indexer/Cargo.toml +++ b/crates/brk_indexer/Cargo.toml @@ -11,7 +11,7 @@ build = "build.rs" [dependencies] bitcoin = { workspace = true } brk_error = { workspace = true } -brk_grouper = { workspace = true } +brk_cohort = { workspace = true } brk_iterator = { workspace = true } brk_logger = { workspace = true } brk_reader = { workspace = true } diff --git a/crates/brk_indexer/README.md b/crates/brk_indexer/README.md index 073ef6735..65cfc9b3f 100644 --- a/crates/brk_indexer/README.md +++ b/crates/brk_indexer/README.md @@ -66,7 +66,7 @@ Use [mimalloc v3](https://crates.io/crates/mimalloc) as the global allocator to ## Built On +- `brk_cohort` for address type handling - `brk_iterator` for block iteration - `brk_store` for key-value storage -- `brk_grouper` for address type handling - `brk_types` for domain types diff --git a/crates/brk_indexer/src/indexes.rs b/crates/brk_indexer/src/indexes.rs index b596180ee..8288978bf 100644 --- a/crates/brk_indexer/src/indexes.rs +++ b/crates/brk_indexer/src/indexes.rs @@ -1,71 +1,20 @@ use brk_error::Result; -use brk_types::{ - EmptyOutputIndex, Height, OpReturnIndex, OutputType, P2AAddressIndex, P2MSOutputIndex, - P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex, - P2WPKHAddressIndex, P2WSHAddressIndex, TxInIndex, TxIndex, TxOutIndex, TypeIndex, - UnknownOutputIndex, -}; +use brk_types::Height; use log::debug; use vecdb::{GenericStoredVec, IterableStoredVec, IterableVec, VecIndex, VecValue}; use crate::{Stores, Vecs}; -#[derive(Debug, Default, Clone)] -pub struct Indexes { - pub emptyoutputindex: EmptyOutputIndex, - pub height: Height, - pub opreturnindex: OpReturnIndex, - pub p2msoutputindex: P2MSOutputIndex, - pub p2pk33addressindex: P2PK33AddressIndex, - pub p2pk65addressindex: P2PK65AddressIndex, - pub p2pkhaddressindex: P2PKHAddressIndex, - pub p2shaddressindex: P2SHAddressIndex, - pub p2traddressindex: P2TRAddressIndex, - pub p2wpkhaddressindex: P2WPKHAddressIndex, - pub p2wshaddressindex: P2WSHAddressIndex, - pub p2aaddressindex: P2AAddressIndex, - pub txindex: TxIndex, - pub txinindex: TxInIndex, - pub txoutindex: TxOutIndex, - pub unknownoutputindex: UnknownOutputIndex, +pub use brk_types::Indexes; + +/// Extension trait for Indexes with brk_indexer-specific functionality. +pub trait IndexesExt { + fn checked_push(&self, vecs: &mut Vecs) -> Result<()>; + fn from_vecs_and_stores(min_height: Height, vecs: &mut Vecs, stores: &Stores) -> Self; } -impl Indexes { - pub fn to_typeindex(&self, outputtype: OutputType) -> TypeIndex { - match outputtype { - OutputType::Empty => *self.emptyoutputindex, - OutputType::OpReturn => *self.opreturnindex, - OutputType::P2A => *self.p2aaddressindex, - OutputType::P2MS => *self.p2msoutputindex, - OutputType::P2PK33 => *self.p2pk33addressindex, - OutputType::P2PK65 => *self.p2pk65addressindex, - OutputType::P2PKH => *self.p2pkhaddressindex, - OutputType::P2SH => *self.p2shaddressindex, - OutputType::P2TR => *self.p2traddressindex, - OutputType::P2WPKH => *self.p2wpkhaddressindex, - OutputType::P2WSH => *self.p2wshaddressindex, - OutputType::Unknown => *self.unknownoutputindex, - } - } - - /// Increments the address index for the given address type and returns the previous value. - /// Only call this for address types (P2PK65, P2PK33, P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2A). - #[inline] - pub fn increment_address_index(&mut self, addresstype: OutputType) -> TypeIndex { - match addresstype { - OutputType::P2PK65 => self.p2pk65addressindex.copy_then_increment(), - OutputType::P2PK33 => self.p2pk33addressindex.copy_then_increment(), - OutputType::P2PKH => self.p2pkhaddressindex.copy_then_increment(), - OutputType::P2SH => self.p2shaddressindex.copy_then_increment(), - OutputType::P2WPKH => self.p2wpkhaddressindex.copy_then_increment(), - OutputType::P2WSH => self.p2wshaddressindex.copy_then_increment(), - OutputType::P2TR => self.p2traddressindex.copy_then_increment(), - OutputType::P2A => self.p2aaddressindex.copy_then_increment(), - _ => unreachable!(), - } - } - - pub fn checked_push(&self, vecs: &mut Vecs) -> Result<()> { +impl IndexesExt for Indexes { + fn checked_push(&self, vecs: &mut Vecs) -> Result<()> { let height = self.height; vecs.tx .height_to_first_txindex @@ -115,11 +64,8 @@ impl Indexes { Ok(()) } -} -impl From<(Height, &mut Vecs, &Stores)> for Indexes { - #[inline] - fn from((min_height, vecs, stores): (Height, &mut Vecs, &Stores)) -> Self { + fn from_vecs_and_stores(min_height: Height, vecs: &mut Vecs, stores: &Stores) -> Indexes { debug!("Creating indexes from vecs and stores..."); // Height at which we want to start: min last saved + 1 or 0 @@ -236,7 +182,7 @@ impl From<(Height, &mut Vecs, &Stores)> for Indexes { ) .unwrap(); - Self { + Indexes { emptyoutputindex, height, p2msoutputindex, diff --git a/crates/brk_indexer/src/lib.rs b/crates/brk_indexer/src/lib.rs index e10ccfcf5..8473a1f07 100644 --- a/crates/brk_indexer/src/lib.rs +++ b/crates/brk_indexer/src/lib.rs @@ -104,7 +104,7 @@ impl Indexer { let (starting_indexes, prev_hash) = if let Some(hash) = last_blockhash { let (height, hash) = client.get_closest_valid_height(hash)?; let starting_indexes = - Indexes::from((height.incremented(), &mut self.vecs, &self.stores)); + Indexes::from_vecs_and_stores(height.incremented(), &mut self.vecs, &self.stores); if starting_indexes.height > client.get_last_height()? { info!("Up to date, nothing to index."); return Ok(starting_indexes); diff --git a/crates/brk_indexer/src/processor/metadata.rs b/crates/brk_indexer/src/processor/metadata.rs index c8401dc3b..98144e9c5 100644 --- a/crates/brk_indexer/src/processor/metadata.rs +++ b/crates/brk_indexer/src/processor/metadata.rs @@ -4,6 +4,7 @@ use log::error; use vecdb::GenericStoredVec; use super::BlockProcessor; +use crate::IndexesExt; impl BlockProcessor<'_> { pub fn process_block_metadata(&mut self) -> Result<()> { diff --git a/crates/brk_indexer/src/processor/txout.rs b/crates/brk_indexer/src/processor/txout.rs index be8236025..12fa788c7 100644 --- a/crates/brk_indexer/src/processor/txout.rs +++ b/crates/brk_indexer/src/processor/txout.rs @@ -1,5 +1,5 @@ +use brk_cohort::ByAddressType; use brk_error::{Error, Result}; -use brk_grouper::ByAddressType; use brk_types::{ AddressBytes, AddressHash, AddressIndexOutPoint, AddressIndexTxIndex, OutPoint, OutputType, Sats, TxIndex, TxOutIndex, TypeIndex, Unit, Vout, diff --git a/crates/brk_indexer/src/readers.rs b/crates/brk_indexer/src/readers.rs index e25a2affd..7cafc0e46 100644 --- a/crates/brk_indexer/src/readers.rs +++ b/crates/brk_indexer/src/readers.rs @@ -1,4 +1,4 @@ -use brk_grouper::ByAddressType; +use brk_cohort::ByAddressType; use vecdb::{GenericStoredVec, Reader}; use crate::Vecs; diff --git a/crates/brk_indexer/src/stores.rs b/crates/brk_indexer/src/stores.rs index bad13816b..08efd3010 100644 --- a/crates/brk_indexer/src/stores.rs +++ b/crates/brk_indexer/src/stores.rs @@ -1,7 +1,7 @@ use std::{fs, path::Path, time::Instant}; +use brk_cohort::ByAddressType; use brk_error::Result; -use brk_grouper::ByAddressType; use brk_store::{AnyStore, Kind, Mode, Store}; use brk_types::{ AddressHash, AddressIndexOutPoint, AddressIndexTxIndex, BlockHashPrefix, Height, OutPoint, @@ -272,8 +272,8 @@ impl Stores { let mut txoutindex_to_outputtype_iter = vecs.txout.txoutindex_to_outputtype.iter()?; let mut txoutindex_to_typeindex_iter = vecs.txout.txoutindex_to_typeindex.iter()?; - for txoutindex in starting_indexes.txoutindex.to_usize() - ..vecs.txout.txoutindex_to_outputtype.len() + for txoutindex in + starting_indexes.txoutindex.to_usize()..vecs.txout.txoutindex_to_outputtype.len() { let outputtype = txoutindex_to_outputtype_iter.get_at_unwrap(txoutindex); if !outputtype.is_address() { diff --git a/crates/brk_query/src/impl/mining/dateindex_iter.rs b/crates/brk_query/src/impl/mining/dateindex_iter.rs index 68fb96b10..5147bea8c 100644 --- a/crates/brk_query/src/impl/mining/dateindex_iter.rs +++ b/crates/brk_query/src/impl/mining/dateindex_iter.rs @@ -49,7 +49,7 @@ impl<'a> DateIndexIter<'a> { let mut timestamps = self .computer .chain - .epoch + .block .timeindexes_to_timestamp .dateindex .as_ref() diff --git a/crates/brk_query/src/impl/mining/difficulty.rs b/crates/brk_query/src/impl/mining/difficulty.rs index b92b4e9de..9052765c6 100644 --- a/crates/brk_query/src/impl/mining/difficulty.rs +++ b/crates/brk_query/src/impl/mining/difficulty.rs @@ -44,7 +44,7 @@ impl Query { // Get timestamps using difficultyepoch_to_timestamp for epoch start let epoch_start_timestamp = computer .chain - .epoch + .block .difficultyepoch_to_timestamp .read_once(current_epoch)?; let current_timestamp = indexer diff --git a/crates/brk_query/src/impl/mining/epochs.rs b/crates/brk_query/src/impl/mining/epochs.rs index ea41f4ba8..f88b8f8f1 100644 --- a/crates/brk_query/src/impl/mining/epochs.rs +++ b/crates/brk_query/src/impl/mining/epochs.rs @@ -22,7 +22,7 @@ pub fn iter_difficulty_epochs( .unwrap_or_default(); let mut epoch_to_height_iter = computer.indexes.block.difficultyepoch_to_first_height.iter(); - let mut epoch_to_timestamp_iter = computer.chain.epoch.difficultyepoch_to_timestamp.iter(); + let mut epoch_to_timestamp_iter = computer.chain.block.difficultyepoch_to_timestamp.iter(); let mut epoch_to_difficulty_iter = computer .chain .mining diff --git a/crates/brk_query/src/impl/mining/hashrate.rs b/crates/brk_query/src/impl/mining/hashrate.rs index 31372ea1c..665393225 100644 --- a/crates/brk_query/src/impl/mining/hashrate.rs +++ b/crates/brk_query/src/impl/mining/hashrate.rs @@ -66,7 +66,7 @@ impl Query { let mut timestamp_iter = computer .chain - .epoch + .block .timeindexes_to_timestamp .dateindex .as_ref() diff --git a/crates/brk_types/src/indexes.rs b/crates/brk_types/src/indexes.rs new file mode 100644 index 000000000..3d4ad1670 --- /dev/null +++ b/crates/brk_types/src/indexes.rs @@ -0,0 +1,125 @@ +use std::ops::{Deref, DerefMut}; + +use crate::{ + DateIndex, DecadeIndex, DifficultyEpoch, EmptyOutputIndex, HalvingEpoch, Height, MonthIndex, + OpReturnIndex, OutputType, P2AAddressIndex, P2MSOutputIndex, P2PK33AddressIndex, + P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, + P2WSHAddressIndex, QuarterIndex, SemesterIndex, TxInIndex, TxIndex, TxOutIndex, TypeIndex, + UnknownOutputIndex, WeekIndex, YearIndex, +}; + +/// Blockchain-level indexes tracking current positions for various entity types. +/// Used by brk_indexer during block processing. +#[derive(Debug, Default, Clone)] +pub struct Indexes { + pub emptyoutputindex: EmptyOutputIndex, + pub height: Height, + pub opreturnindex: OpReturnIndex, + pub p2msoutputindex: P2MSOutputIndex, + pub p2pk33addressindex: P2PK33AddressIndex, + pub p2pk65addressindex: P2PK65AddressIndex, + pub p2pkhaddressindex: P2PKHAddressIndex, + pub p2shaddressindex: P2SHAddressIndex, + pub p2traddressindex: P2TRAddressIndex, + pub p2wpkhaddressindex: P2WPKHAddressIndex, + pub p2wshaddressindex: P2WSHAddressIndex, + pub p2aaddressindex: P2AAddressIndex, + pub txindex: TxIndex, + pub txinindex: TxInIndex, + pub txoutindex: TxOutIndex, + pub unknownoutputindex: UnknownOutputIndex, +} + +impl Indexes { + pub fn to_typeindex(&self, outputtype: OutputType) -> TypeIndex { + match outputtype { + OutputType::Empty => *self.emptyoutputindex, + OutputType::OpReturn => *self.opreturnindex, + OutputType::P2A => *self.p2aaddressindex, + OutputType::P2MS => *self.p2msoutputindex, + OutputType::P2PK33 => *self.p2pk33addressindex, + OutputType::P2PK65 => *self.p2pk65addressindex, + OutputType::P2PKH => *self.p2pkhaddressindex, + OutputType::P2SH => *self.p2shaddressindex, + OutputType::P2TR => *self.p2traddressindex, + OutputType::P2WPKH => *self.p2wpkhaddressindex, + OutputType::P2WSH => *self.p2wshaddressindex, + OutputType::Unknown => *self.unknownoutputindex, + } + } + + /// Increments the address index for the given address type and returns the previous value. + /// Only call this for address types (P2PK65, P2PK33, P2PKH, P2SH, P2WPKH, P2WSH, P2TR, P2A). + #[inline] + pub fn increment_address_index(&mut self, addresstype: OutputType) -> TypeIndex { + match addresstype { + OutputType::P2PK65 => self.p2pk65addressindex.copy_then_increment(), + OutputType::P2PK33 => self.p2pk33addressindex.copy_then_increment(), + OutputType::P2PKH => self.p2pkhaddressindex.copy_then_increment(), + OutputType::P2SH => self.p2shaddressindex.copy_then_increment(), + OutputType::P2WPKH => self.p2wpkhaddressindex.copy_then_increment(), + OutputType::P2WSH => self.p2wshaddressindex.copy_then_increment(), + OutputType::P2TR => self.p2traddressindex.copy_then_increment(), + OutputType::P2A => self.p2aaddressindex.copy_then_increment(), + _ => unreachable!(), + } + } +} + +/// Extended indexes with time-based granularities. +/// Used by brk_computer for time-series aggregation. +#[derive(Debug, Clone)] +pub struct ComputeIndexes { + indexes: Indexes, + pub dateindex: DateIndex, + pub weekindex: WeekIndex, + pub monthindex: MonthIndex, + pub quarterindex: QuarterIndex, + pub semesterindex: SemesterIndex, + pub yearindex: YearIndex, + pub decadeindex: DecadeIndex, + pub difficultyepoch: DifficultyEpoch, + pub halvingepoch: HalvingEpoch, +} + +impl ComputeIndexes { + #[allow(clippy::too_many_arguments)] + pub fn new( + indexes: Indexes, + dateindex: DateIndex, + weekindex: WeekIndex, + monthindex: MonthIndex, + quarterindex: QuarterIndex, + semesterindex: SemesterIndex, + yearindex: YearIndex, + decadeindex: DecadeIndex, + difficultyepoch: DifficultyEpoch, + halvingepoch: HalvingEpoch, + ) -> Self { + Self { + indexes, + dateindex, + weekindex, + monthindex, + quarterindex, + semesterindex, + yearindex, + decadeindex, + difficultyepoch, + halvingepoch, + } + } +} + +impl Deref for ComputeIndexes { + type Target = Indexes; + fn deref(&self) -> &Self::Target { + &self.indexes + } +} + +impl DerefMut for ComputeIndexes { + fn deref_mut(&mut self) -> &mut Self::Target { + &mut self.indexes + } +} diff --git a/crates/brk_types/src/lib.rs b/crates/brk_types/src/lib.rs index ea6f1176b..0a657f0b5 100644 --- a/crates/brk_types/src/lib.rs +++ b/crates/brk_types/src/lib.rs @@ -61,6 +61,7 @@ mod height; mod heightparam; mod hex; mod index; +mod indexes; mod indexinfo; mod limit; mod limitparam; @@ -81,6 +82,7 @@ mod metricwithindex; mod monthindex; mod ohlc; mod opreturnindex; +mod option_ext; mod outpoint; mod outputtype; mod p2aaddressindex; @@ -102,6 +104,7 @@ mod p2wshaddressindex; mod p2wshbytes; mod pagination; mod paginationindex; +mod percentile; mod pool; mod pooldetail; mod poolinfo; @@ -217,6 +220,7 @@ pub use height::*; pub use heightparam::*; pub use hex::*; pub use index::*; +pub use indexes::*; pub use indexinfo::*; pub use limit::*; pub use limitparam::*; @@ -237,6 +241,7 @@ pub use metricwithindex::*; pub use monthindex::*; pub use ohlc::*; pub use opreturnindex::*; +pub use option_ext::*; pub use outpoint::*; pub use outputtype::*; pub use p2aaddressindex::*; @@ -258,6 +263,7 @@ pub use p2wshaddressindex::*; pub use p2wshbytes::*; pub use pagination::*; pub use paginationindex::*; +pub use percentile::*; pub use pool::*; pub use pooldetail::*; pub use poolinfo::*; diff --git a/crates/brk_types/src/option_ext.rs b/crates/brk_types/src/option_ext.rs new file mode 100644 index 000000000..ae50c3024 --- /dev/null +++ b/crates/brk_types/src/option_ext.rs @@ -0,0 +1,19 @@ +/// Extension trait for Option to provide shorter unwrap methods +pub trait OptionExt { + /// Shorthand for `.as_ref().unwrap()` + fn u(&self) -> &T; + /// Shorthand for `.as_mut().unwrap()` + fn um(&mut self) -> &mut T; +} + +impl OptionExt for Option { + #[inline] + fn u(&self) -> &T { + self.as_ref().unwrap() + } + + #[inline] + fn um(&mut self) -> &mut T { + self.as_mut().unwrap() + } +} diff --git a/crates/brk_types/src/percentile.rs b/crates/brk_types/src/percentile.rs new file mode 100644 index 000000000..3f4f77929 --- /dev/null +++ b/crates/brk_types/src/percentile.rs @@ -0,0 +1,38 @@ +use std::ops::{Add, Div}; + +/// Standard percentile values used throughout BRK. +pub const PERCENTILES: [u8; 19] = [ + 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95, +]; + +/// Length of the PERCENTILES array. +pub const PERCENTILES_LEN: usize = PERCENTILES.len(); + +/// Get a percentile value from a sorted slice. +/// +/// # Panics +/// Panics if the slice is empty. +pub fn get_percentile(sorted: &[T], percentile: f64) -> T +where + T: Clone + Div + Add, +{ + let len = sorted.len(); + + if len == 0 { + panic!("Cannot get percentile from empty slice"); + } else if len == 1 { + sorted[0].clone() + } else { + let index = (len - 1) as f64 * percentile; + + let fract = index.fract(); + + if fract != 0.0 { + let left = sorted.get(index as usize).unwrap().clone(); + let right = sorted.get(index.ceil() as usize).unwrap().clone(); + left / 2 + right / 2 + } else { + sorted.get(index as usize).unwrap().clone() + } + } +}