diff --git a/Cargo.lock b/Cargo.lock index c7066f8e4..962c8b844 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -333,9 +333,9 @@ dependencies = [ [[package]] name = "bech32" -version = "0.11.0" +version = "0.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d965446196e3b7decd44aa7ee49e31d630118f90ef12f97900f262eb915c951d" +checksum = "32637268377fc7b10a8c6d51de3e7fba1ce5dd371a96e342b34e6078db558e7f" [[package]] name = "better_io" @@ -1591,6 +1591,15 @@ version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7c74b8349d32d297c9134b8c88677813a227df8f779daa29bfc29c183fe3dca6" +[[package]] +name = "convert_case" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "633458d4ef8c78b72454de2d54fd6ab2e60f9e02be22f3c6104cdc8a4e0fceb9" +dependencies = [ + "unicode-segmentation", +] + [[package]] name = "core-foundation" version = "0.9.4" @@ -1851,21 +1860,23 @@ dependencies = [ [[package]] name = "derive_more" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "093242cf7570c207c83073cf82f79706fe7b8317e98620a47d5be7c3d8497678" +checksum = "10b768e943bed7bf2cab53df09f4bc34bfd217cdb57d971e769874c9a6710618" dependencies = [ "derive_more-impl", ] [[package]] name = "derive_more-impl" -version = "2.0.1" +version = "2.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda628edc44c4bb645fbe0f758797143e4e07926f7ebf4e9bdfbd3d2ce621df3" +checksum = "6d286bfdaf75e988b4a78e013ecd79c581e06399ab53fbacd2d916c2f904f30b" dependencies = [ + "convert_case", "proc-macro2", "quote", + "rustc_version", "syn 2.0.111", "unicode-xid", ] @@ -2118,7 +2129,7 @@ dependencies = [ "dashmap", "flume", "log", - "lsm-tree 3.0.0-rc.4", + "lsm-tree 3.0.0-rc.5", "lz4_flex 0.11.5", "tempfile", "xxhash-rust", @@ -2543,9 +2554,9 @@ dependencies = [ [[package]] name = "hyper-util" -version = "0.1.18" +version = "0.1.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52e9a2a24dc5c6821e71a7030e1e14b7b632acac55c40e9d2e082c621261bb56" +checksum = "727805d60e7938b76b826a6ef209eb70eaa1812794f9424d4a4e2d740662df5f" dependencies = [ "bytes", "futures-core", @@ -2911,9 +2922,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.177" +version = "0.2.178" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976" +checksum = "37c93d8daa9d8a012fd8ab92f088405fb202ea0b6ab73ee2482ae66af4f42091" [[package]] name = "libloading" @@ -2949,9 +2960,9 @@ dependencies = [ [[package]] name = "libz-rs-sys" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "840db8cf39d9ec4dd794376f38acc40d0fc65eec2a8f484f7fd375b84602becd" +checksum = "8b484ba8d4f775eeca644c452a56650e544bf7e617f1d170fe7298122ead5222" dependencies = [ "zlib-rs", ] @@ -2979,9 +2990,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.28" +version = "0.4.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34080505efa8e45a4b816c349525ebe327ceaa8559756f0356cba97ef3bf7432" +checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897" [[package]] name = "lsm-tree" @@ -3009,9 +3020,9 @@ dependencies = [ [[package]] name = "lsm-tree" -version = "3.0.0-rc.4" +version = "3.0.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "063c691d381ad78609b8bc6e83ba58cef11b9347f5e26ff9b5e3eba921dc8d77" +checksum = "b4e32220e039b7e8e1474a5206eb32c002c9d18fe0770d87c693e00b782f15ff" dependencies = [ "byteorder-lite", "byteview 0.9.1", @@ -3020,7 +3031,6 @@ dependencies = [ "interval-heap", "log", "lz4_flex 0.11.5", - "mutants", "quick_cache", "rustc-hash", "self_cell", @@ -3113,12 +3123,6 @@ dependencies = [ "windows-sys 0.61.2", ] -[[package]] -name = "mutants" -version = "0.0.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc0287524726960e07b119cebd01678f852f147742ae0d925e6a520dca956126" - [[package]] name = "nibble_vec" version = "0.1.0" @@ -3635,9 +3639,9 @@ dependencies = [ [[package]] name = "oxc_resolver" -version = "11.14.1" +version = "11.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c47417853c7239c336e0543e0c1857f298461d04677ee10a43b115478d03b255" +checksum = "a22ff4e8307f0392031c2221a3c14f448c446f7ca6312eac62e3181d01e93fe5" dependencies = [ "cfg-if", "fast-glob", @@ -5395,9 +5399,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.18.1" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f87b8aa10b915a06587d0dec516c282ff295b475d94abf425d62b57710070a2" +checksum = "e2e054861b4bd027cd373e18e8d8d8e6548085000e41290d95ce0c373a654b4a" dependencies = [ "getrandom 0.3.4", "js-sys", @@ -6053,9 +6057,9 @@ dependencies = [ [[package]] name = "zlib-rs" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2f06ae92f42f5e5c42443fd094f245eb656abf56dd7cce9b8b263236565e00f2" +checksum = "36134c44663532e6519d7a6dfdbbe06f6f8192bde8ae9ed076e9b213f0e31df7" [[package]] name = "zopfli" diff --git a/Cargo.toml b/Cargo.toml index 688514b54..19534e352 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -67,7 +67,7 @@ fjall3 = { version = "3.0.0-rc.4", package = "fjall" } # fjall3 = { path = "../fjall3", package = "fjall" } # fjall3 = { git = "https://github.com/fjall-rs/fjall.git", rev = "f0bf96c2017b3543eb176012b8eff69c639dff1d", package = "fjall" } jiff = "0.2.16" -log = "0.4.28" +log = "0.4.29" minreq = { version = "2.14.1", features = ["https", "serde_json"] } parking_lot = "0.12.5" rayon = "1.11.0" diff --git a/crates/brk_computer/src/chain.rs b/crates/brk_computer/src/chain.rs index 1cb9b4d6c..4c9951b1d 100644 --- a/crates/brk_computer/src/chain.rs +++ b/crates/brk_computer/src/chain.rs @@ -14,9 +14,12 @@ use vecdb::{ LazyVecFrom1, LazyVecFrom2, PAGE_SIZE, PcoVec, TypedVecIterator, VecIndex, unlikely, }; -use crate::grouped::{ - ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex, - ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions, +use crate::{ + grouped::{ + ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex, + ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions, + }, + utils::OptionExt, }; use super::{Indexes, indexes, price}; @@ -154,9 +157,48 @@ impl Vecs { let version = parent_version + Version::ZERO; let compute_dollars = price.is_some(); + let v0 = Version::ZERO; + let v2 = Version::TWO; + let v4 = Version::new(4); + let v5 = Version::new(5); - let txinindex_to_value: EagerVec> = - EagerVec::forced_import(&db, "value", version + Version::ZERO)?; + // Helper macros for common patterns + macro_rules! eager { + ($name:expr) => { + EagerVec::forced_import(&db, $name, version + v0)? + }; + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } + macro_rules! computed_h { + ($name:expr, $source:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import(&db, $name, $source, version + v0, indexes, $opts)? + }; + ($name:expr, $source:expr, $v:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import(&db, $name, $source, version + $v, indexes, $opts)? + }; + } + macro_rules! computed_di { + ($name:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, $opts)? + }; + ($name:expr, $v:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + $v, indexes, $opts)? + }; + } + macro_rules! computed_tx { + ($name:expr, $source:expr, $opts:expr) => { + ComputedVecsFromTxindex::forced_import(&db, $name, $source, version + v0, indexes, $opts)? + }; + } + let last = || VecBuilderOptions::default().add_last(); + let sum = || VecBuilderOptions::default().add_sum(); + let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative(); + let stats = || VecBuilderOptions::default().add_average().add_minmax().add_percentiles(); + let full_stats = || VecBuilderOptions::default().add_average().add_minmax().add_percentiles().add_sum().add_cumulative(); + + let txinindex_to_value: EagerVec> = eager!("value"); let txindex_to_weight = LazyVecFrom2::init( "weight", @@ -200,16 +242,10 @@ impl Vecs { }, ); - let txindex_to_input_value = - EagerVec::forced_import(&db, "input_value", version + Version::ZERO)?; - - let txindex_to_output_value = - EagerVec::forced_import(&db, "output_value", version + Version::ZERO)?; - - let txindex_to_fee = EagerVec::forced_import(&db, "fee", version + Version::ZERO)?; - - let txindex_to_fee_rate = - EagerVec::forced_import(&db, "fee_rate", version + Version::ZERO)?; + let txindex_to_input_value = eager!("input_value"); + let txindex_to_output_value = eager!("output_value"); + let txindex_to_fee = eager!("fee"); + let txindex_to_fee_rate = eager!("fee_rate"); let dateindex_to_block_count_target = LazyVecFrom1::init( "block_count_target", @@ -262,221 +298,34 @@ impl Vecs { semesterindex_to_block_count_target, yearindex_to_block_count_target, decadeindex_to_block_count_target, - height_to_interval: EagerVec::forced_import(&db, "interval", version + Version::ZERO)?, - timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import( - &db, - "timestamp", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_first(), - )?, - indexes_to_block_interval: ComputedVecsFromHeight::forced_import( - &db, - "block_interval", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_percentiles() - .add_minmax() - .add_average(), - )?, - indexes_to_block_count: ComputedVecsFromHeight::forced_import( - &db, - "block_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_1w_block_count: ComputedVecsFromDateIndex::forced_import( - &db, - "1w_block_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1m_block_count: ComputedVecsFromDateIndex::forced_import( - &db, - "1m_block_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1y_block_count: ComputedVecsFromDateIndex::forced_import( - &db, - "1y_block_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_block_weight: ComputedVecsFromHeight::forced_import( - &db, - "block_weight", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_sum() - .add_minmax() - .add_average() - .add_percentiles() - .add_cumulative(), - )?, - indexes_to_block_size: ComputedVecsFromHeight::forced_import( - &db, - "block_size", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_sum() - .add_minmax() - .add_average() - .add_percentiles() - .add_cumulative(), - )?, - height_to_vbytes: EagerVec::forced_import(&db, "vbytes", version + Version::ZERO)?, - height_to_24h_block_count: EagerVec::forced_import( - &db, - "24h_block_count", - version + Version::ZERO, - )?, - height_to_24h_coinbase_sum: EagerVec::forced_import( - &db, - "24h_coinbase_sum", - version + Version::ZERO, - )?, - height_to_24h_coinbase_usd_sum: EagerVec::forced_import( - &db, - "24h_coinbase_usd_sum", - version + Version::ZERO, - )?, - indexes_to_block_vbytes: ComputedVecsFromHeight::forced_import( - &db, - "block_vbytes", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_sum() - .add_minmax() - .add_average() - .add_percentiles() - .add_cumulative(), - )?, - difficultyepoch_to_timestamp: EagerVec::forced_import( - &db, - "timestamp", - version + Version::ZERO, - )?, - halvingepoch_to_timestamp: EagerVec::forced_import( - &db, - "timestamp", - version + Version::ZERO, - )?, + height_to_interval: eager!("interval"), + timeindexes_to_timestamp: computed_di!("timestamp", VecBuilderOptions::default().add_first()), + indexes_to_block_interval: computed_h!("block_interval", Source::None, stats()), + indexes_to_block_count: computed_h!("block_count", Source::Compute, sum_cum()), + indexes_to_1w_block_count: computed_di!("1w_block_count", last()), + indexes_to_1m_block_count: computed_di!("1m_block_count", last()), + indexes_to_1y_block_count: computed_di!("1y_block_count", last()), + indexes_to_block_weight: computed_h!("block_weight", Source::None, full_stats()), + indexes_to_block_size: computed_h!("block_size", Source::None, full_stats()), + height_to_vbytes: eager!("vbytes"), + height_to_24h_block_count: eager!("24h_block_count"), + height_to_24h_coinbase_sum: eager!("24h_coinbase_sum"), + height_to_24h_coinbase_usd_sum: eager!("24h_coinbase_usd_sum"), + indexes_to_block_vbytes: computed_h!("block_vbytes", Source::None, full_stats()), + difficultyepoch_to_timestamp: eager!("timestamp"), + halvingepoch_to_timestamp: eager!("timestamp"), - dateindex_to_fee_dominance: EagerVec::forced_import( - &db, - "fee_dominance", - version + Version::ZERO, - )?, - dateindex_to_subsidy_dominance: EagerVec::forced_import( - &db, - "subsidy_dominance", - version + Version::ZERO, - )?, - indexes_to_difficulty: ComputedVecsFromHeight::forced_import( - &db, - "difficulty", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import( - &db, - "difficultyepoch", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import( - &db, - "halvingepoch", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_tx_count: ComputedVecsFromHeight::forced_import( - &db, - "tx_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_input_count: ComputedVecsFromTxindex::forced_import( - &db, - "input_count", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_output_count: ComputedVecsFromTxindex::forced_import( - &db, - "output_count", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_tx_v1: ComputedVecsFromHeight::forced_import( - &db, - "tx_v1", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_tx_v2: ComputedVecsFromHeight::forced_import( - &db, - "tx_v2", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_tx_v3: ComputedVecsFromHeight::forced_import( - &db, - "tx_v3", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, + dateindex_to_fee_dominance: eager!("fee_dominance"), + dateindex_to_subsidy_dominance: eager!("subsidy_dominance"), + indexes_to_difficulty: computed_h!("difficulty", Source::None, last()), + indexes_to_difficultyepoch: computed_di!("difficultyepoch", last()), + indexes_to_halvingepoch: computed_di!("halvingepoch", last()), + indexes_to_tx_count: computed_h!("tx_count", Source::Compute, full_stats()), + indexes_to_input_count: computed_tx!("input_count", Source::None, full_stats()), + indexes_to_output_count: computed_tx!("output_count", Source::None, full_stats()), + indexes_to_tx_v1: computed_h!("tx_v1", Source::Compute, sum_cum()), + indexes_to_tx_v2: computed_h!("tx_v2", Source::Compute, sum_cum()), + indexes_to_tx_v3: computed_h!("tx_v3", Source::Compute, sum_cum()), indexes_to_sent: ComputedValueVecsFromHeight::forced_import( &db, "sent", @@ -501,39 +350,9 @@ impl Vecs { .add_minmax() .add_average(), )?, - indexes_to_fee_rate: ComputedVecsFromTxindex::forced_import( - &db, - "fee_rate", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_percentiles() - .add_minmax() - .add_average(), - )?, - indexes_to_tx_vsize: ComputedVecsFromTxindex::forced_import( - &db, - "tx_vsize", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_percentiles() - .add_minmax() - .add_average(), - )?, - indexes_to_tx_weight: ComputedVecsFromTxindex::forced_import( - &db, - "tx_weight", - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_percentiles() - .add_minmax() - .add_average(), - )?, + indexes_to_fee_rate: computed_tx!("fee_rate", Source::None, stats()), + indexes_to_tx_vsize: computed_tx!("tx_vsize", Source::None, stats()), + indexes_to_tx_weight: computed_tx!("tx_weight", Source::None, stats()), indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import( &db, "subsidy", @@ -571,434 +390,55 @@ impl Vecs { compute_dollars, indexes, )?, - indexes_to_p2a_count: ComputedVecsFromHeight::forced_import( - &db, - "p2a_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2ms_count: ComputedVecsFromHeight::forced_import( - &db, - "p2ms_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2pk33_count: ComputedVecsFromHeight::forced_import( - &db, - "p2pk33_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2pk65_count: ComputedVecsFromHeight::forced_import( - &db, - "p2pk65_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2pkh_count: ComputedVecsFromHeight::forced_import( - &db, - "p2pkh_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2sh_count: ComputedVecsFromHeight::forced_import( - &db, - "p2sh_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2tr_count: ComputedVecsFromHeight::forced_import( - &db, - "p2tr_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2wpkh_count: ComputedVecsFromHeight::forced_import( - &db, - "p2wpkh_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_p2wsh_count: ComputedVecsFromHeight::forced_import( - &db, - "p2wsh_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_opreturn_count: ComputedVecsFromHeight::forced_import( - &db, - "opreturn_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_unknownoutput_count: ComputedVecsFromHeight::forced_import( - &db, - "unknownoutput_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_emptyoutput_count: ComputedVecsFromHeight::forced_import( - &db, - "emptyoutput_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default() - .add_average() - .add_minmax() - .add_percentiles() - .add_sum() - .add_cumulative(), - )?, - indexes_to_exact_utxo_count: ComputedVecsFromHeight::forced_import( - &db, - "exact_utxo_count", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_subsidy_usd_1y_sma: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - &db, - "subsidy_usd_1y_sma", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_puell_multiple: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - &db, - "puell_multiple", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_hash_rate: ComputedVecsFromHeight::forced_import( - &db, - "hash_rate", - Source::Compute, - version + Version::new(5), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex::forced_import( - &db, - "hash_rate_1w_sma", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex::forced_import( - &db, - "hash_rate_1m_sma", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex::forced_import( - &db, - "hash_rate_2m_sma", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex::forced_import( - &db, - "hash_rate_1y_sma", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_difficulty_as_hash: ComputedVecsFromHeight::forced_import( - &db, - "difficulty_as_hash", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_difficulty_adjustment: ComputedVecsFromHeight::forced_import( - &db, - "difficulty_adjustment", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - )?, - indexes_to_blocks_before_next_difficulty_adjustment: - ComputedVecsFromHeight::forced_import( - &db, - "blocks_before_next_difficulty_adjustment", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_days_before_next_difficulty_adjustment: - ComputedVecsFromHeight::forced_import( - &db, - "days_before_next_difficulty_adjustment", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_blocks_before_next_halving: ComputedVecsFromHeight::forced_import( - &db, - "blocks_before_next_halving", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_days_before_next_halving: ComputedVecsFromHeight::forced_import( - &db, - "days_before_next_halving", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_price_ths: ComputedVecsFromHeight::forced_import( - &db, - "hash_price_ths", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_price_phs: ComputedVecsFromHeight::forced_import( - &db, - "hash_price_phs", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_value_ths: ComputedVecsFromHeight::forced_import( - &db, - "hash_value_ths", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_value_phs: ComputedVecsFromHeight::forced_import( - &db, - "hash_value_phs", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_price_ths_min: ComputedVecsFromHeight::forced_import( - &db, - "hash_price_ths_min", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_price_phs_min: ComputedVecsFromHeight::forced_import( - &db, - "hash_price_phs_min", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_price_rebound: ComputedVecsFromHeight::forced_import( - &db, - "hash_price_rebound", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_value_ths_min: ComputedVecsFromHeight::forced_import( - &db, - "hash_value_ths_min", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_value_phs_min: ComputedVecsFromHeight::forced_import( - &db, - "hash_value_phs_min", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_hash_value_rebound: ComputedVecsFromHeight::forced_import( - &db, - "hash_value_rebound", - Source::Compute, - version + Version::new(4), - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_inflation_rate: ComputedVecsFromDateIndex::forced_import( - &db, - "inflation_rate", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_annualized_volume: ComputedVecsFromDateIndex::forced_import( - &db, - "annualized_volume", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex::forced_import( - &db, - "annualized_volume_btc", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex::forced_import( - &db, - "annualized_volume_usd", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex::forced_import( - &db, - "tx_btc_velocity", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex::forced_import( - &db, - "tx_usd_velocity", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_tx_per_sec: ComputedVecsFromDateIndex::forced_import( - &db, - "tx_per_sec", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_outputs_per_sec: ComputedVecsFromDateIndex::forced_import( - &db, - "outputs_per_sec", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_inputs_per_sec: ComputedVecsFromDateIndex::forced_import( - &db, - "inputs_per_sec", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + indexes_to_p2a_count: computed_h!("p2a_count", Source::Compute, full_stats()), + indexes_to_p2ms_count: computed_h!("p2ms_count", Source::Compute, full_stats()), + indexes_to_p2pk33_count: computed_h!("p2pk33_count", Source::Compute, full_stats()), + indexes_to_p2pk65_count: computed_h!("p2pk65_count", Source::Compute, full_stats()), + indexes_to_p2pkh_count: computed_h!("p2pkh_count", Source::Compute, full_stats()), + indexes_to_p2sh_count: computed_h!("p2sh_count", Source::Compute, full_stats()), + indexes_to_p2tr_count: computed_h!("p2tr_count", Source::Compute, full_stats()), + indexes_to_p2wpkh_count: computed_h!("p2wpkh_count", Source::Compute, full_stats()), + indexes_to_p2wsh_count: computed_h!("p2wsh_count", Source::Compute, full_stats()), + indexes_to_opreturn_count: computed_h!("opreturn_count", Source::Compute, full_stats()), + indexes_to_unknownoutput_count: computed_h!("unknownoutput_count", Source::Compute, full_stats()), + indexes_to_emptyoutput_count: computed_h!("emptyoutput_count", Source::Compute, full_stats()), + indexes_to_exact_utxo_count: computed_h!("exact_utxo_count", Source::Compute, last()), + indexes_to_subsidy_usd_1y_sma: compute_dollars + .then(|| ComputedVecsFromDateIndex::forced_import(&db, "subsidy_usd_1y_sma", Source::Compute, version + v0, indexes, last())) + .transpose()?, + indexes_to_puell_multiple: compute_dollars + .then(|| ComputedVecsFromDateIndex::forced_import(&db, "puell_multiple", Source::Compute, version + v0, indexes, last())) + .transpose()?, + indexes_to_hash_rate: computed_h!("hash_rate", Source::Compute, v5, last()), + indexes_to_hash_rate_1w_sma: computed_di!("hash_rate_1w_sma", last()), + indexes_to_hash_rate_1m_sma: computed_di!("hash_rate_1m_sma", last()), + indexes_to_hash_rate_2m_sma: computed_di!("hash_rate_2m_sma", last()), + indexes_to_hash_rate_1y_sma: computed_di!("hash_rate_1y_sma", last()), + indexes_to_difficulty_as_hash: computed_h!("difficulty_as_hash", Source::Compute, last()), + indexes_to_difficulty_adjustment: computed_h!("difficulty_adjustment", Source::Compute, sum()), + indexes_to_blocks_before_next_difficulty_adjustment: computed_h!("blocks_before_next_difficulty_adjustment", Source::Compute, v2, last()), + indexes_to_days_before_next_difficulty_adjustment: computed_h!("days_before_next_difficulty_adjustment", Source::Compute, v2, last()), + indexes_to_blocks_before_next_halving: computed_h!("blocks_before_next_halving", Source::Compute, v2, last()), + indexes_to_days_before_next_halving: computed_h!("days_before_next_halving", Source::Compute, v2, last()), + indexes_to_hash_price_ths: computed_h!("hash_price_ths", Source::Compute, v4, last()), + indexes_to_hash_price_phs: computed_h!("hash_price_phs", Source::Compute, v4, last()), + indexes_to_hash_value_ths: computed_h!("hash_value_ths", Source::Compute, v4, last()), + indexes_to_hash_value_phs: computed_h!("hash_value_phs", Source::Compute, v4, last()), + indexes_to_hash_price_ths_min: computed_h!("hash_price_ths_min", Source::Compute, v4, last()), + indexes_to_hash_price_phs_min: computed_h!("hash_price_phs_min", Source::Compute, v4, last()), + indexes_to_hash_price_rebound: computed_h!("hash_price_rebound", Source::Compute, v4, last()), + indexes_to_hash_value_ths_min: computed_h!("hash_value_ths_min", Source::Compute, v4, last()), + indexes_to_hash_value_phs_min: computed_h!("hash_value_phs_min", Source::Compute, v4, last()), + indexes_to_hash_value_rebound: computed_h!("hash_value_rebound", Source::Compute, v4, last()), + indexes_to_inflation_rate: computed_di!("inflation_rate", last()), + indexes_to_annualized_volume: computed_di!("annualized_volume", last()), + indexes_to_annualized_volume_btc: computed_di!("annualized_volume_btc", last()), + indexes_to_annualized_volume_usd: computed_di!("annualized_volume_usd", last()), + indexes_to_tx_btc_velocity: computed_di!("tx_btc_velocity", last()), + indexes_to_tx_usd_velocity: computed_di!("tx_usd_velocity", last()), + indexes_to_tx_per_sec: computed_di!("tx_per_sec", v2, last()), + indexes_to_outputs_per_sec: computed_di!("outputs_per_sec", v2, last()), + indexes_to_inputs_per_sec: computed_di!("inputs_per_sec", v2, last()), txindex_to_is_coinbase, txinindex_to_value, @@ -1441,7 +881,7 @@ impl Vecs { .indexes_to_coinbase .dollars .as_ref() - .map(|c| c.height.as_ref().unwrap().into_iter()) + .map(|c| c.height.u().into_iter()) { self.height_to_24h_coinbase_usd_sum.compute_transform( starting_indexes.height, @@ -1462,7 +902,7 @@ impl Vecs { .compute_all(indexes, price, starting_indexes, exit, |vec| { vec.compute_transform2( starting_indexes.height, - self.indexes_to_coinbase.sats.height.as_ref().unwrap(), + self.indexes_to_coinbase.sats.height.u(), self.indexes_to_fee.sats.height.unwrap_sum(), |(height, coinbase, fees, ..)| { ( @@ -1486,7 +926,7 @@ impl Vecs { |vec| { vec.compute_transform( starting_indexes.height, - self.indexes_to_subsidy.sats.height.as_ref().unwrap(), + self.indexes_to_subsidy.sats.height.u(), |(height, subsidy, ..)| { let halving = HalvingEpoch::from(height); let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32); @@ -1738,7 +1178,7 @@ impl Vecs { v.compute_transform2( starting_indexes.height, &self.height_to_24h_block_count, - self.indexes_to_difficulty_as_hash.height.as_ref().unwrap(), + self.indexes_to_difficulty_as_hash.height.u(), |(i, block_count_sum, difficulty_as_hash, ..)| { ( i, @@ -1916,7 +1356,7 @@ impl Vecs { v.compute_transform2( starting_indexes.height, &self.height_to_24h_coinbase_usd_sum, - self.indexes_to_hash_rate.height.as_ref().unwrap(), + self.indexes_to_hash_rate.height.u(), |(i, coinbase_sum, hashrate, ..)| { (i, (*coinbase_sum / (*hashrate / ONE_TERA_HASH)).into()) }, @@ -1929,7 +1369,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_transform( starting_indexes.height, - self.indexes_to_hash_price_ths.height.as_ref().unwrap(), + self.indexes_to_hash_price_ths.height.u(), |(i, price, ..)| (i, (*price * 1000.0).into()), exit, )?; @@ -1941,7 +1381,7 @@ impl Vecs { v.compute_transform2( starting_indexes.height, &self.height_to_24h_coinbase_sum, - self.indexes_to_hash_rate.height.as_ref().unwrap(), + self.indexes_to_hash_rate.height.u(), |(i, coinbase_sum, hashrate, ..)| { ( i, @@ -1957,7 +1397,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_transform( starting_indexes.height, - self.indexes_to_hash_value_ths.height.as_ref().unwrap(), + self.indexes_to_hash_value_ths.height.u(), |(i, value, ..)| (i, (*value * 1000.0).into()), exit, )?; @@ -1968,7 +1408,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_all_time_low_( starting_indexes.height, - self.indexes_to_hash_price_ths.height.as_ref().unwrap(), + self.indexes_to_hash_price_ths.height.u(), exit, true, )?; @@ -1979,7 +1419,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_all_time_low_( starting_indexes.height, - self.indexes_to_hash_price_phs.height.as_ref().unwrap(), + self.indexes_to_hash_price_phs.height.u(), exit, true, )?; @@ -1990,7 +1430,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_all_time_low_( starting_indexes.height, - self.indexes_to_hash_value_ths.height.as_ref().unwrap(), + self.indexes_to_hash_value_ths.height.u(), exit, true, )?; @@ -2001,7 +1441,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_all_time_low_( starting_indexes.height, - self.indexes_to_hash_value_phs.height.as_ref().unwrap(), + self.indexes_to_hash_value_phs.height.u(), exit, true, )?; @@ -2012,8 +1452,8 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_percentage_difference( starting_indexes.height, - self.indexes_to_hash_price_phs.height.as_ref().unwrap(), - self.indexes_to_hash_price_phs_min.height.as_ref().unwrap(), + self.indexes_to_hash_price_phs.height.u(), + self.indexes_to_hash_price_phs_min.height.u(), exit, )?; Ok(()) @@ -2023,8 +1463,8 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_percentage_difference( starting_indexes.height, - self.indexes_to_hash_value_phs.height.as_ref().unwrap(), - self.indexes_to_hash_value_phs_min.height.as_ref().unwrap(), + self.indexes_to_hash_value_phs.height.u(), + self.indexes_to_hash_value_phs_min.height.u(), exit, )?; Ok(()) diff --git a/crates/brk_computer/src/cointime.rs b/crates/brk_computer/src/cointime.rs index 56185972b..8d954294a 100644 --- a/crates/brk_computer/src/cointime.rs +++ b/crates/brk_computer/src/cointime.rs @@ -5,7 +5,7 @@ use brk_traversable::Traversable; use brk_types::{Bitcoin, CheckedSub, Dollars, StoredF32, StoredF64, Version}; use vecdb::{Database, Exit, PAGE_SIZE, TypedVecIterator}; -use crate::grouped::ComputedVecsFromDateIndex; +use crate::{grouped::ComputedVecsFromDateIndex, utils::OptionExt}; use super::{ Indexes, chain, @@ -60,220 +60,63 @@ impl Vecs { db.set_min_len(PAGE_SIZE * 1_000_000)?; let compute_dollars = price.is_some(); + let v0 = parent_version; + let v1 = parent_version + Version::ONE; - let version = parent_version + Version::ZERO; + let last = || VecBuilderOptions::default().add_last(); + let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative(); + + macro_rules! computed_h { + ($name:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import(&db, $name, Source::Compute, v0, indexes, $opts)? + }; + ($name:expr, $v:expr, $opts:expr) => { + ComputedVecsFromHeight::forced_import(&db, $name, Source::Compute, $v, indexes, $opts)? + }; + } + macro_rules! computed_di { + ($name:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, v0, indexes, $opts)? + }; + } + macro_rules! ratio_di { + ($name:expr) => { + ComputedRatioVecsFromDateIndex::forced_import(&db, $name, Source::None, v0, indexes, true)? + }; + } + macro_rules! value_h { + ($name:expr) => { + ComputedValueVecsFromHeight::forced_import(&db, $name, Source::Compute, v1, last(), compute_dollars, indexes)? + }; + } let this = Self { - indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import( - &db, - "coinblocks_created", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_coinblocks_stored: ComputedVecsFromHeight::forced_import( - &db, - "coinblocks_stored", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_liveliness: ComputedVecsFromHeight::forced_import( - &db, - "liveliness", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_vaultedness: ComputedVecsFromHeight::forced_import( - &db, - "vaultedness", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_activity_to_vaultedness_ratio: ComputedVecsFromHeight::forced_import( - &db, - "activity_to_vaultedness_ratio", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_vaulted_supply: ComputedValueVecsFromHeight::forced_import( - &db, - "vaulted_supply", - Source::Compute, - version + Version::ONE, - VecBuilderOptions::default().add_last(), - compute_dollars, - indexes, - )?, - indexes_to_active_supply: ComputedValueVecsFromHeight::forced_import( - &db, - "active_supply", - Source::Compute, - version + Version::ONE, - VecBuilderOptions::default().add_last(), - compute_dollars, - indexes, - )?, - indexes_to_thermo_cap: ComputedVecsFromHeight::forced_import( - &db, - "thermo_cap", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_investor_cap: ComputedVecsFromHeight::forced_import( - &db, - "investor_cap", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_vaulted_cap: ComputedVecsFromHeight::forced_import( - &db, - "vaulted_cap", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_active_cap: ComputedVecsFromHeight::forced_import( - &db, - "active_cap", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_vaulted_price: ComputedVecsFromHeight::forced_import( - &db, - "vaulted_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_vaulted_price_ratio: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "vaulted_price", - Source::None, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_active_price: ComputedVecsFromHeight::forced_import( - &db, - "active_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_active_price_ratio: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "active_price", - Source::None, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_true_market_mean: ComputedVecsFromHeight::forced_import( - &db, - "true_market_mean", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_true_market_mean_ratio: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "true_market_mean", - Source::None, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_cointime_value_destroyed: ComputedVecsFromHeight::forced_import( - &db, - "cointime_value_destroyed", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_cointime_value_created: ComputedVecsFromHeight::forced_import( - &db, - "cointime_value_created", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_cointime_value_stored: ComputedVecsFromHeight::forced_import( - &db, - "cointime_value_stored", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_cointime_price: ComputedVecsFromHeight::forced_import( - &db, - "cointime_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_cointime_cap: ComputedVecsFromHeight::forced_import( - &db, - "cointime_cap", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_cointime_price_ratio: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "cointime_price", - Source::None, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_cointime_adj_inflation_rate: ComputedVecsFromDateIndex::forced_import( - &db, - "cointime_adj_inflation_rate", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_cointime_adj_tx_btc_velocity: ComputedVecsFromDateIndex::forced_import( - &db, - "cointime_adj_tx_btc_velocity", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_cointime_adj_tx_usd_velocity: ComputedVecsFromDateIndex::forced_import( - &db, - "cointime_adj_tx_usd_velocity", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + indexes_to_coinblocks_created: computed_h!("coinblocks_created", sum_cum()), + indexes_to_coinblocks_stored: computed_h!("coinblocks_stored", sum_cum()), + indexes_to_liveliness: computed_h!("liveliness", last()), + indexes_to_vaultedness: computed_h!("vaultedness", last()), + indexes_to_activity_to_vaultedness_ratio: computed_h!("activity_to_vaultedness_ratio", last()), + indexes_to_vaulted_supply: value_h!("vaulted_supply"), + indexes_to_active_supply: value_h!("active_supply"), + indexes_to_thermo_cap: computed_h!("thermo_cap", v1, last()), + indexes_to_investor_cap: computed_h!("investor_cap", v1, last()), + indexes_to_vaulted_cap: computed_h!("vaulted_cap", v1, last()), + indexes_to_active_cap: computed_h!("active_cap", v1, last()), + indexes_to_vaulted_price: computed_h!("vaulted_price", last()), + indexes_to_vaulted_price_ratio: ratio_di!("vaulted_price"), + indexes_to_active_price: computed_h!("active_price", last()), + indexes_to_active_price_ratio: ratio_di!("active_price"), + indexes_to_true_market_mean: computed_h!("true_market_mean", last()), + indexes_to_true_market_mean_ratio: ratio_di!("true_market_mean"), + indexes_to_cointime_value_destroyed: computed_h!("cointime_value_destroyed", sum_cum()), + indexes_to_cointime_value_created: computed_h!("cointime_value_created", sum_cum()), + indexes_to_cointime_value_stored: computed_h!("cointime_value_stored", sum_cum()), + indexes_to_cointime_price: computed_h!("cointime_price", last()), + indexes_to_cointime_cap: computed_h!("cointime_cap", last()), + indexes_to_cointime_price_ratio: ratio_di!("cointime_price"), + indexes_to_cointime_adj_inflation_rate: computed_di!("cointime_adj_inflation_rate", last()), + indexes_to_cointime_adj_tx_btc_velocity: computed_di!("cointime_adj_tx_btc_velocity", last()), + indexes_to_cointime_adj_tx_usd_velocity: computed_di!("cointime_adj_tx_usd_velocity", last()), db, }; @@ -339,7 +182,7 @@ impl Vecs { .into_iter(); vec.compute_transform( starting_indexes.height, - self.indexes_to_coinblocks_created.height.as_ref().unwrap(), + self.indexes_to_coinblocks_created.height.u(), |(i, created, ..)| { let destroyed = coinblocks_destroyed_iter.get_unwrap(i); (i, created.checked_sub(destroyed).unwrap()) @@ -369,7 +212,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_transform( starting_indexes.height, - liveliness.height.as_ref().unwrap(), + liveliness.height.u(), |(i, v, ..)| (i, StoredF64::from(1.0).checked_sub(v).unwrap()), exit, )?; @@ -384,8 +227,8 @@ impl Vecs { |vec| { vec.compute_divide( starting_indexes.height, - liveliness.height.as_ref().unwrap(), - vaultedness.height.as_ref().unwrap(), + liveliness.height.u(), + vaultedness.height.u(), exit, )?; Ok(()) @@ -401,7 +244,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, circulating_supply, - vaultedness.height.as_ref().unwrap(), + vaultedness.height.u(), exit, )?; Ok(()) @@ -417,7 +260,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, circulating_supply, - liveliness.height.as_ref().unwrap(), + liveliness.height.u(), exit, )?; Ok(()) @@ -431,7 +274,7 @@ impl Vecs { self.indexes_to_activity_to_vaultedness_ratio .dateindex .unwrap_last(), - chain.indexes_to_inflation_rate.dateindex.as_ref().unwrap(), + chain.indexes_to_inflation_rate.dateindex.u(), exit, )?; Ok(()) @@ -444,7 +287,7 @@ impl Vecs { self.indexes_to_activity_to_vaultedness_ratio .dateindex .unwrap_last(), - chain.indexes_to_tx_btc_velocity.dateindex.as_ref().unwrap(), + chain.indexes_to_tx_btc_velocity.dateindex.u(), exit, )?; Ok(()) @@ -492,7 +335,7 @@ impl Vecs { vec.compute_subtract( starting_indexes.height, realized_cap, - self.indexes_to_thermo_cap.height.as_ref().unwrap(), + self.indexes_to_thermo_cap.height.u(), exit, )?; Ok(()) @@ -503,7 +346,7 @@ impl Vecs { vec.compute_divide( starting_indexes.height, realized_cap, - self.indexes_to_vaultedness.height.as_ref().unwrap(), + self.indexes_to_vaultedness.height.u(), exit, )?; Ok(()) @@ -514,7 +357,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, realized_cap, - self.indexes_to_liveliness.height.as_ref().unwrap(), + self.indexes_to_liveliness.height.u(), exit, )?; Ok(()) @@ -525,7 +368,7 @@ impl Vecs { vec.compute_divide( starting_indexes.height, realized_price, - self.indexes_to_vaultedness.height.as_ref().unwrap(), + self.indexes_to_vaultedness.height.u(), exit, )?; Ok(()) @@ -543,7 +386,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, realized_price, - self.indexes_to_liveliness.height.as_ref().unwrap(), + self.indexes_to_liveliness.height.u(), exit, )?; Ok(()) @@ -563,7 +406,7 @@ impl Vecs { |vec| { vec.compute_divide( starting_indexes.height, - self.indexes_to_investor_cap.height.as_ref().unwrap(), + self.indexes_to_investor_cap.height.u(), self.indexes_to_active_supply .bitcoin .height @@ -592,7 +435,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, &price.chainindexes_to_price_close.height, - indexes_to_coinblocks_destroyed.height.as_ref().unwrap(), + indexes_to_coinblocks_destroyed.height.u(), exit, )?; Ok(()) @@ -607,7 +450,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, &price.chainindexes_to_price_close.height, - self.indexes_to_coinblocks_created.height.as_ref().unwrap(), + self.indexes_to_coinblocks_created.height.u(), exit, )?; Ok(()) @@ -622,7 +465,7 @@ impl Vecs { vec.compute_multiply( starting_indexes.height, &price.chainindexes_to_price_close.height, - self.indexes_to_coinblocks_stored.height.as_ref().unwrap(), + self.indexes_to_coinblocks_stored.height.u(), exit, )?; Ok(()) @@ -648,7 +491,7 @@ impl Vecs { .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_multiply( starting_indexes.height, - self.indexes_to_cointime_price.height.as_ref().unwrap(), + self.indexes_to_cointime_price.height.u(), circulating_supply, exit, )?; @@ -671,7 +514,7 @@ impl Vecs { self.indexes_to_activity_to_vaultedness_ratio .dateindex .unwrap_last(), - chain.indexes_to_tx_usd_velocity.dateindex.as_ref().unwrap(), + chain.indexes_to_tx_usd_velocity.dateindex.u(), exit, )?; Ok(()) diff --git a/crates/brk_computer/src/fetched.rs b/crates/brk_computer/src/fetched.rs index 2c95e4ed4..003dccf77 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}; +use super::{Indexes, indexes, utils::OptionExt}; #[derive(Clone, Traversable)] pub struct Vecs { @@ -114,7 +114,7 @@ impl Vecs { let ohlc = if i.to_usize() + 100 >= self.dateindex_to_price_ohlc_in_cents.len() && let Ok(mut ohlc) = self.fetcher.get_date(d) { - let prev_open = *prev.as_ref().unwrap().close; + let prev_open = *prev.u().close; *ohlc.open = prev_open; *ohlc.high = (*ohlc.high).max(prev_open); *ohlc.low = (*ohlc.low).min(prev_open); diff --git a/crates/brk_computer/src/grouped/builder_eager.rs b/crates/brk_computer/src/grouped/builder_eager.rs index d9da570b9..1126a2a8e 100644 --- a/crates/brk_computer/src/grouped/builder_eager.rs +++ b/crates/brk_computer/src/grouped/builder_eager.rs @@ -6,7 +6,7 @@ use vecdb::{ PcoVec, VecIndex, VecValue, }; -use crate::utils::get_percentile; +use crate::utils::{get_percentile, OptionExt}; use super::ComputedVecValue; @@ -44,135 +44,34 @@ where options: VecBuilderOptions, ) -> Result { let only_one_active = options.is_only_one_active(); - let suffix = |s: &str| format!("{name}_{s}"); + let maybe_suffix = |s: &str| if only_one_active { name.to_string() } else { suffix(s) }; + let v = version + VERSION; - let maybe_suffix = |s: &str| { - if only_one_active { - name.to_string() - } else { - suffix(s) - } - }; + macro_rules! import { + ($s:expr) => { Box::new(EagerVec::forced_import(db, &maybe_suffix($s), v).unwrap()) }; + } let s = Self { - first: options.first.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("first"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - last: options.last.then(|| { - Box::new(EagerVec::forced_import(db, name, version + Version::ZERO).unwrap()) - }), - min: options.min.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("min"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - max: options.max.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("max"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - median: options.median.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("median"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - average: options.average.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("avg"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), + first: options.first.then(|| import!("first")), + last: options.last.then(|| Box::new(EagerVec::forced_import(db, name, v).unwrap())), + min: options.min.then(|| import!("min")), + max: options.max.then(|| import!("max")), + median: options.median.then(|| import!("median")), + average: options.average.then(|| import!("avg")), sum: options.sum.then(|| { - Box::new( - EagerVec::forced_import( - db, - &(if !options.last && !options.average && !options.min && !options.max { - name.to_string() - } else { - maybe_suffix("sum") - }), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - cumulative: options.cumulative.then(|| { - Box::new( - EagerVec::forced_import( - db, - &suffix("cumulative"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - pct90: options.pct90.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("pct90"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - pct75: options.pct75.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("pct75"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - pct25: options.pct25.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("pct25"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) - }), - pct10: options.pct10.then(|| { - Box::new( - EagerVec::forced_import( - db, - &maybe_suffix("pct10"), - version + VERSION + Version::ZERO, - ) - .unwrap(), - ) + let sum_name = if !options.last && !options.average && !options.min && !options.max { + name.to_string() + } else { + maybe_suffix("sum") + }; + Box::new(EagerVec::forced_import(db, &sum_name, v).unwrap()) }), + cumulative: options.cumulative.then(|| Box::new(EagerVec::forced_import(db, &suffix("cumulative"), v).unwrap())), + pct90: options.pct90.then(|| import!("pct90")), + pct75: options.pct75.then(|| import!("pct75")), + pct25: options.pct25.then(|| import!("pct25")), + pct10: options.pct10.then(|| import!("pct10")), }; Ok(s) @@ -192,7 +91,7 @@ where let index = self.starting_index(max_from); - let cumulative_vec = self.cumulative.as_mut().unwrap(); + let cumulative_vec = self.cumulative.um(); let mut cumulative = index.decremented().map_or(T::from(0_usize), |index| { cumulative_vec.iter().get_unwrap(index) @@ -421,7 +320,7 @@ where let count_index = count_indexes_iter.next().unwrap(); if let Some(first) = self.first.as_mut() { - let v = source_first_iter.as_mut().unwrap().get_unwrap(first_index); + let v = source_first_iter.um().get_unwrap(first_index); first.truncate_push_at(index, v)?; } @@ -431,7 +330,7 @@ where panic!("should compute last if count can be 0") } let last_index = first_index + (count_index - 1); - let v = source_last_iter.as_mut().unwrap().get_unwrap(last_index); + let v = source_last_iter.um().get_unwrap(last_index); last.truncate_push_at(index, v)?; } @@ -444,7 +343,7 @@ where if needs_values { if needs_sorted { if let Some(max) = self.max.as_mut() { - let source_max_iter = source_max_iter.as_mut().unwrap(); + let source_max_iter = source_max_iter.um(); source_max_iter.set_position(first_index); let mut values = source_max_iter .take(*count_index as usize) @@ -454,7 +353,7 @@ where } if let Some(min) = self.min.as_mut() { - let source_min_iter = source_min_iter.as_mut().unwrap(); + let source_min_iter = source_min_iter.um(); source_min_iter.set_position(first_index); let mut values = source_min_iter .take(*count_index as usize) @@ -466,7 +365,7 @@ where if needs_average_sum_or_cumulative { if let Some(average) = self.average.as_mut() { - let source_average_iter = source_average_iter.as_mut().unwrap(); + let source_average_iter = source_average_iter.um(); source_average_iter.set_position(first_index); let values = source_average_iter .take(*count_index as usize) @@ -481,7 +380,7 @@ where } if needs_sum_or_cumulative { - let source_sum_iter = source_sum_iter.as_mut().unwrap(); + let source_sum_iter = source_sum_iter.um(); source_sum_iter.set_position(first_index); let values = source_sum_iter .take(*count_index as usize) @@ -517,47 +416,47 @@ where } pub fn unwrap_first(&self) -> &EagerVec> { - self.first.as_ref().unwrap() + self.first.u() } #[allow(unused)] pub fn unwrap_average(&self) -> &EagerVec> { - self.average.as_ref().unwrap() + self.average.u() } pub fn unwrap_sum(&self) -> &EagerVec> { - self.sum.as_ref().unwrap() + self.sum.u() } pub fn unwrap_max(&self) -> &EagerVec> { - self.max.as_ref().unwrap() + self.max.u() } #[allow(unused)] pub fn unwrap_pct90(&self) -> &EagerVec> { - self.pct90.as_ref().unwrap() + self.pct90.u() } #[allow(unused)] pub fn unwrap_pct75(&self) -> &EagerVec> { - self.pct75.as_ref().unwrap() + self.pct75.u() } #[allow(unused)] pub fn unwrap_median(&self) -> &EagerVec> { - self.median.as_ref().unwrap() + self.median.u() } #[allow(unused)] pub fn unwrap_pct25(&self) -> &EagerVec> { - self.pct25.as_ref().unwrap() + self.pct25.u() } #[allow(unused)] pub fn unwrap_pct10(&self) -> &EagerVec> { - self.pct10.as_ref().unwrap() + self.pct10.u() } pub fn unwrap_min(&self) -> &EagerVec> { - self.min.as_ref().unwrap() + self.min.u() } pub fn unwrap_last(&self) -> &EagerVec> { - self.last.as_ref().unwrap() + self.last.u() } #[allow(unused)] pub fn unwrap_cumulative(&self) -> &EagerVec> { - self.cumulative.as_ref().unwrap() + self.cumulative.u() } pub fn safe_flush(&mut self, exit: &Exit) -> Result<()> { diff --git a/crates/brk_computer/src/grouped/builder_lazy.rs b/crates/brk_computer/src/grouped/builder_lazy.rs index 27dbf793e..97a886fe5 100644 --- a/crates/brk_computer/src/grouped/builder_lazy.rs +++ b/crates/brk_computer/src/grouped/builder_lazy.rs @@ -3,6 +3,7 @@ use brk_types::Version; use vecdb::{FromCoarserIndex, IterableBoxedVec, IterableCloneableVec, LazyVecFrom2, VecIndex}; use crate::grouped::{EagerVecsBuilder, VecBuilderOptions}; +use crate::utils::OptionExt; use super::ComputedVecValue; @@ -62,7 +63,7 @@ where source_extra .first .as_ref() - .map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()), + .map_or_else(|| source.u().clone(), |v| v.clone()), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -104,7 +105,7 @@ where source_extra .min .as_ref() - .map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()), + .map_or_else(|| source.u().clone(), |v| v.clone()), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -123,7 +124,7 @@ where source_extra .max .as_ref() - .map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()), + .map_or_else(|| source.u().clone(), |v| v.clone()), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -142,7 +143,7 @@ where source_extra .average .as_ref() - .map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()), + .map_or_else(|| source.u().clone(), |v| v.clone()), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -172,7 +173,7 @@ where source_extra .sum .as_ref() - .map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()), + .map_or_else(|| source.u().clone(), |v| v.clone()), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -194,7 +195,7 @@ where Box::new(LazyVecFrom2::init( &suffix("cumulative"), version + VERSION + Version::ZERO, - source_extra.cumulative.as_ref().unwrap().boxed_clone(), + source_extra.cumulative.u().boxed_clone(), len_source.clone(), |i: I, source, len_source| { if i.to_usize() >= len_source.vec_len() { @@ -214,27 +215,27 @@ where } pub fn unwrap_first(&self) -> &LazyVecFrom2 { - self.first.as_ref().unwrap() + self.first.u() } #[allow(unused)] pub fn unwrap_average(&self) -> &LazyVecFrom2 { - self.average.as_ref().unwrap() + self.average.u() } pub fn unwrap_sum(&self) -> &LazyVecFrom2 { - self.sum.as_ref().unwrap() + self.sum.u() } pub fn unwrap_max(&self) -> &LazyVecFrom2 { - self.max.as_ref().unwrap() + self.max.u() } pub fn unwrap_min(&self) -> &LazyVecFrom2 { - self.min.as_ref().unwrap() + self.min.u() } pub fn unwrap_last(&self) -> &LazyVecFrom2 { - self.last.as_ref().unwrap() + self.last.u() } #[allow(unused)] pub fn unwrap_cumulative(&self) -> &LazyVecFrom2 { - self.cumulative.as_ref().unwrap() + self.cumulative.u() } } diff --git a/crates/brk_computer/src/grouped/from_dateindex.rs b/crates/brk_computer/src/grouped/from_dateindex.rs index da6bf94c9..4466a660e 100644 --- a/crates/brk_computer/src/grouped/from_dateindex.rs +++ b/crates/brk_computer/src/grouped/from_dateindex.rs @@ -9,7 +9,7 @@ use vecdb::{ PcoVec, }; -use crate::{Indexes, grouped::LazyVecsBuilder, indexes}; +use crate::{Indexes, grouped::LazyVecsBuilder, indexes, utils::OptionExt}; use super::{ComputedVecValue, EagerVecsBuilder, Source, VecBuilderOptions}; @@ -121,7 +121,7 @@ where where F: FnMut(&mut EagerVec>) -> Result<()>, { - compute(self.dateindex.as_mut().unwrap())?; + compute(self.dateindex.um())?; let dateindex: Option<&EagerVec>> = None; self.compute_rest(starting_indexes, exit, dateindex) @@ -137,7 +137,7 @@ where self.dateindex_extra .extend(starting_indexes.dateindex, dateindex, exit)?; } else { - let dateindex = self.dateindex.as_ref().unwrap(); + let dateindex = self.dateindex.u(); self.dateindex_extra .extend(starting_indexes.dateindex, dateindex, exit)?; diff --git a/crates/brk_computer/src/grouped/from_height.rs b/crates/brk_computer/src/grouped/from_height.rs index 2e48b1b78..e8e20506d 100644 --- a/crates/brk_computer/src/grouped/from_height.rs +++ b/crates/brk_computer/src/grouped/from_height.rs @@ -14,6 +14,7 @@ use crate::{ Indexes, grouped::{LazyVecsBuilder, Source}, indexes, + utils::OptionExt, }; use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions}; @@ -140,7 +141,7 @@ where where F: FnMut(&mut EagerVec>) -> Result<()>, { - compute(self.height.as_mut().unwrap())?; + compute(self.height.um())?; let height: Option<&EagerVec>> = None; self.compute_rest(indexes, starting_indexes, exit, height) @@ -173,7 +174,7 @@ where exit, )?; } else { - let height = self.height.as_ref().unwrap(); + let height = self.height.u(); self.height_extra .extend(starting_indexes.height, height, exit)?; diff --git a/crates/brk_computer/src/grouped/from_txindex.rs b/crates/brk_computer/src/grouped/from_txindex.rs index 961c6ad26..546056cb6 100644 --- a/crates/brk_computer/src/grouped/from_txindex.rs +++ b/crates/brk_computer/src/grouped/from_txindex.rs @@ -14,6 +14,7 @@ use crate::{ Indexes, grouped::{LazyVecsBuilder, Source}, indexes, price, + utils::OptionExt, }; use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions}; @@ -146,7 +147,7 @@ where // ) -> Result<()>, // { // compute( - // self.txindex.as_mut().unwrap(), + // self.txindex.um(), // indexer, // indexes, // starting_indexes, @@ -176,7 +177,7 @@ where exit, )?; } else { - let txindex = self.txindex.as_ref().unwrap().as_ref(); + let txindex = self.txindex.u().as_ref(); self.height.compute( starting_indexes.height, @@ -229,7 +230,7 @@ impl ComputedVecsFromTxindex { let txindex_version = if let Some(txindex) = txindex { txindex.version() } else { - self.txindex.as_ref().unwrap().as_ref().version() + self.txindex.u().as_ref().version() }; self.height @@ -237,84 +238,93 @@ impl ComputedVecsFromTxindex { let starting_index = self.height.starting_index(starting_indexes.height); + // Create iterators once before the loop to avoid repeated iterator creation + let mut first_iter = sats.height.first.as_ref().map(|v| v.into_iter()); + let mut average_iter = sats.height.average.as_ref().map(|v| v.into_iter()); + let mut sum_iter = sats.height.sum.as_ref().map(|v| v.into_iter()); + let mut max_iter = sats.height.max.as_ref().map(|v| v.into_iter()); + let mut pct90_iter = sats.height.pct90.as_ref().map(|v| v.into_iter()); + let mut pct75_iter = sats.height.pct75.as_ref().map(|v| v.into_iter()); + let mut median_iter = sats.height.median.as_ref().map(|v| v.into_iter()); + let mut pct25_iter = sats.height.pct25.as_ref().map(|v| v.into_iter()); + let mut pct10_iter = sats.height.pct10.as_ref().map(|v| v.into_iter()); + let mut min_iter = sats.height.min.as_ref().map(|v| v.into_iter()); + let mut last_iter = sats.height.last.as_ref().map(|v| v.into_iter()); + let mut cumulative_iter = sats.height.cumulative.as_ref().map(|v| v.into_iter()); + (starting_index.to_usize()..indexer.vecs.height_to_weight.len()) .map(Height::from) .try_for_each(|height| -> Result<()> { if let Some(first) = self.height.first.as_mut() { first.truncate_push( height, - Bitcoin::from(sats.height.unwrap_first().into_iter().get_unwrap(height)), + Bitcoin::from(first_iter.um().get_unwrap(height)), )?; } if let Some(average) = self.height.average.as_mut() { average.truncate_push( height, - Bitcoin::from(sats.height.unwrap_average().into_iter().get_unwrap(height)), + Bitcoin::from(average_iter.um().get_unwrap(height)), )?; } if let Some(sum) = self.height.sum.as_mut() { sum.truncate_push( height, - Bitcoin::from(sats.height.unwrap_sum().into_iter().get_unwrap(height)), + Bitcoin::from(sum_iter.um().get_unwrap(height)), )?; } if let Some(max) = self.height.max.as_mut() { max.truncate_push( height, - Bitcoin::from(sats.height.unwrap_max().into_iter().get_unwrap(height)), + Bitcoin::from(max_iter.um().get_unwrap(height)), )?; } if let Some(pct90) = self.height.pct90.as_mut() { pct90.truncate_push( height, - Bitcoin::from(sats.height.unwrap_pct90().into_iter().get_unwrap(height)), + Bitcoin::from(pct90_iter.um().get_unwrap(height)), )?; } if let Some(pct75) = self.height.pct75.as_mut() { pct75.truncate_push( height, - Bitcoin::from(sats.height.unwrap_pct75().into_iter().get_unwrap(height)), + Bitcoin::from(pct75_iter.um().get_unwrap(height)), )?; } if let Some(median) = self.height.median.as_mut() { median.truncate_push( height, - Bitcoin::from(sats.height.unwrap_median().into_iter().get_unwrap(height)), + Bitcoin::from(median_iter.um().get_unwrap(height)), )?; } if let Some(pct25) = self.height.pct25.as_mut() { pct25.truncate_push( height, - Bitcoin::from(sats.height.unwrap_pct25().into_iter().get_unwrap(height)), + Bitcoin::from(pct25_iter.um().get_unwrap(height)), )?; } if let Some(pct10) = self.height.pct10.as_mut() { pct10.truncate_push( height, - Bitcoin::from(sats.height.unwrap_pct10().into_iter().get_unwrap(height)), + Bitcoin::from(pct10_iter.um().get_unwrap(height)), )?; } if let Some(min) = self.height.min.as_mut() { min.truncate_push( height, - Bitcoin::from(sats.height.unwrap_min().into_iter().get_unwrap(height)), + Bitcoin::from(min_iter.um().get_unwrap(height)), )?; } if let Some(last) = self.height.last.as_mut() { last.truncate_push( height, - Bitcoin::from(sats.height.unwrap_last().into_iter().get_unwrap(height)), + Bitcoin::from(last_iter.um().get_unwrap(height)), )?; } if let Some(cumulative) = self.height.cumulative.as_mut() { cumulative.truncate_push( height, - Bitcoin::from( - sats.height - .unwrap_cumulative() - .into_iter() - .get_unwrap(height), - ), + Bitcoin::from(cumulative_iter.um().get_unwrap(height)), )?; } Ok(()) @@ -341,7 +351,7 @@ impl ComputedVecsFromTxindex { let txindex_version = if let Some(txindex) = txindex { txindex.version() } else { - self.txindex.as_ref().unwrap().as_ref().version() + self.txindex.u().as_ref().version() }; self.height @@ -351,6 +361,20 @@ impl ComputedVecsFromTxindex { let mut close_iter = price.chainindexes_to_price_close.height.into_iter(); + // Create iterators once before the loop to avoid repeated iterator creation + let mut first_iter = bitcoin.height.first.as_ref().map(|v| v.into_iter()); + let mut average_iter = bitcoin.height.average.as_ref().map(|v| v.into_iter()); + let mut sum_iter = bitcoin.height.sum.as_ref().map(|v| v.into_iter()); + let mut max_iter = bitcoin.height.max.as_ref().map(|v| v.into_iter()); + let mut pct90_iter = bitcoin.height.pct90.as_ref().map(|v| v.into_iter()); + let mut pct75_iter = bitcoin.height.pct75.as_ref().map(|v| v.into_iter()); + let mut median_iter = bitcoin.height.median.as_ref().map(|v| v.into_iter()); + let mut pct25_iter = bitcoin.height.pct25.as_ref().map(|v| v.into_iter()); + let mut pct10_iter = bitcoin.height.pct10.as_ref().map(|v| v.into_iter()); + let mut min_iter = bitcoin.height.min.as_ref().map(|v| v.into_iter()); + let mut last_iter = bitcoin.height.last.as_ref().map(|v| v.into_iter()); + let mut cumulative_iter = bitcoin.height.cumulative.as_ref().map(|v| v.into_iter()); + (starting_index.to_usize()..indexer.vecs.height_to_weight.len()) .map(Height::from) .try_for_each(|height| -> Result<()> { @@ -359,88 +383,73 @@ impl ComputedVecsFromTxindex { if let Some(first) = self.height.first.as_mut() { first.truncate_push( height, - price * bitcoin.height.unwrap_first().into_iter().get_unwrap(height), + price * first_iter.um().get_unwrap(height), )?; } if let Some(average) = self.height.average.as_mut() { average.truncate_push( height, - price - * bitcoin - .height - .unwrap_average() - .into_iter() - .get_unwrap(height), + price * average_iter.um().get_unwrap(height), )?; } if let Some(sum) = self.height.sum.as_mut() { sum.truncate_push( height, - price * bitcoin.height.unwrap_sum().into_iter().get_unwrap(height), + price * sum_iter.um().get_unwrap(height), )?; } if let Some(max) = self.height.max.as_mut() { max.truncate_push( height, - price * bitcoin.height.unwrap_max().into_iter().get_unwrap(height), + price * max_iter.um().get_unwrap(height), )?; } if let Some(pct90) = self.height.pct90.as_mut() { pct90.truncate_push( height, - price * bitcoin.height.unwrap_pct90().into_iter().get_unwrap(height), + price * pct90_iter.um().get_unwrap(height), )?; } if let Some(pct75) = self.height.pct75.as_mut() { pct75.truncate_push( height, - price * bitcoin.height.unwrap_pct75().into_iter().get_unwrap(height), + price * pct75_iter.um().get_unwrap(height), )?; } if let Some(median) = self.height.median.as_mut() { median.truncate_push( height, - price - * bitcoin - .height - .unwrap_median() - .into_iter() - .get_unwrap(height), + price * median_iter.um().get_unwrap(height), )?; } if let Some(pct25) = self.height.pct25.as_mut() { pct25.truncate_push( height, - price * bitcoin.height.unwrap_pct25().into_iter().get_unwrap(height), + price * pct25_iter.um().get_unwrap(height), )?; } if let Some(pct10) = self.height.pct10.as_mut() { pct10.truncate_push( height, - price * bitcoin.height.unwrap_pct10().into_iter().get_unwrap(height), + price * pct10_iter.um().get_unwrap(height), )?; } if let Some(min) = self.height.min.as_mut() { min.truncate_push( height, - price * bitcoin.height.unwrap_min().into_iter().get_unwrap(height), + price * min_iter.um().get_unwrap(height), )?; } if let Some(last) = self.height.last.as_mut() { last.truncate_push( height, - price * bitcoin.height.unwrap_last().into_iter().get_unwrap(height), + price * last_iter.um().get_unwrap(height), )?; } if let Some(cumulative) = self.height.cumulative.as_mut() { cumulative.truncate_push( height, - price - * bitcoin - .height - .unwrap_cumulative() - .into_iter() - .get_unwrap(height), + price * cumulative_iter.um().get_unwrap(height), )?; } Ok(()) diff --git a/crates/brk_computer/src/grouped/ratio_from_dateindex.rs b/crates/brk_computer/src/grouped/ratio_from_dateindex.rs index 37db62389..33e9d10f6 100644 --- a/crates/brk_computer/src/grouped/ratio_from_dateindex.rs +++ b/crates/brk_computer/src/grouped/ratio_from_dateindex.rs @@ -12,7 +12,7 @@ use crate::{ ComputedStandardDeviationVecsFromDateIndex, StandardDeviationVecsOptions, source::Source, }, indexes, price, - utils::get_percentile, + utils::{get_percentile, OptionExt}, }; use super::{ComputedVecsFromDateIndex, VecBuilderOptions}; @@ -55,230 +55,48 @@ impl ComputedRatioVecsFromDateIndex { indexes: &indexes::Vecs, extended: bool, ) -> Result { - let options = VecBuilderOptions::default().add_last(); + let opts = VecBuilderOptions::default().add_last(); + let v = version + VERSION; + + macro_rules! import { + ($suffix:expr) => { + ComputedVecsFromDateIndex::forced_import( + db, &format!("{name}_{}", $suffix), Source::Compute, v, indexes, opts, + ).unwrap() + }; + } + macro_rules! import_sd { + ($suffix:expr, $days:expr) => { + ComputedStandardDeviationVecsFromDateIndex::forced_import( + db, &format!("{name}_{}", $suffix), $days, Source::Compute, v, indexes, + StandardDeviationVecsOptions::default().add_all(), + ).unwrap() + }; + } Ok(Self { price: source.is_compute().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - name, - Source::Compute, - version + VERSION, - indexes, - options, - ) - .unwrap() - }), - ratio: ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - )?, - ratio_1w_sma: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_1w_sma"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_1m_sma: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_1m_sma"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_sd: extended.then(|| { - ComputedStandardDeviationVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio"), - usize::MAX, - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - StandardDeviationVecsOptions::default().add_all(), - ) - .unwrap() - }), - ratio_1y_sd: extended.then(|| { - ComputedStandardDeviationVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_1y"), - 365, - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - StandardDeviationVecsOptions::default().add_all(), - ) - .unwrap() - }), - ratio_2y_sd: extended.then(|| { - ComputedStandardDeviationVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_2y"), - 2 * 365, - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - StandardDeviationVecsOptions::default().add_all(), - ) - .unwrap() - }), - ratio_4y_sd: extended.then(|| { - ComputedStandardDeviationVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_4y"), - 4 * 365, - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - StandardDeviationVecsOptions::default().add_all(), - ) - .unwrap() - }), - ratio_pct99: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct99"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct98: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct98"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct95: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct95"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct5: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct5"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct2: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct2"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct1: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct1"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct99_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct99_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct98_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct98_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct95_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct95_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct5_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct5_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct2_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct2_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() - }), - ratio_pct1_usd: extended.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_ratio_pct1_usd"), - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - options, - ) - .unwrap() + ComputedVecsFromDateIndex::forced_import(db, name, Source::Compute, v, indexes, opts).unwrap() }), + ratio: import!("ratio"), + ratio_1w_sma: extended.then(|| import!("ratio_1w_sma")), + ratio_1m_sma: extended.then(|| import!("ratio_1m_sma")), + ratio_sd: extended.then(|| import_sd!("ratio", usize::MAX)), + ratio_1y_sd: extended.then(|| import_sd!("ratio_1y", 365)), + ratio_2y_sd: extended.then(|| import_sd!("ratio_2y", 2 * 365)), + ratio_4y_sd: extended.then(|| import_sd!("ratio_4y", 4 * 365)), + ratio_pct99: extended.then(|| import!("ratio_pct99")), + ratio_pct98: extended.then(|| import!("ratio_pct98")), + ratio_pct95: extended.then(|| import!("ratio_pct95")), + ratio_pct5: extended.then(|| import!("ratio_pct5")), + ratio_pct2: extended.then(|| import!("ratio_pct2")), + ratio_pct1: extended.then(|| import!("ratio_pct1")), + ratio_pct99_usd: extended.then(|| import!("ratio_pct99_usd")), + ratio_pct98_usd: extended.then(|| import!("ratio_pct98_usd")), + ratio_pct95_usd: extended.then(|| import!("ratio_pct95_usd")), + ratio_pct5_usd: extended.then(|| import!("ratio_pct5_usd")), + ratio_pct2_usd: extended.then(|| import!("ratio_pct2_usd")), + ratio_pct1_usd: extended.then(|| import!("ratio_pct1_usd")), }) } @@ -308,10 +126,10 @@ impl ComputedRatioVecsFromDateIndex { exit: &Exit, price_opt: Option<&impl IterableVec>, ) -> Result<()> { - let closes = price.timeindexes_to_price_close.dateindex.as_ref().unwrap(); + let closes = price.timeindexes_to_price_close.dateindex.u(); let price = price_opt.unwrap_or_else(|| unsafe { - std::mem::transmute(&self.price.as_ref().unwrap().dateindex) + std::mem::transmute(&self.price.u().dateindex) }); self.ratio.compute_all(starting_indexes, exit, |v| { @@ -343,7 +161,7 @@ impl ComputedRatioVecsFromDateIndex { .compute_all(starting_indexes, exit, |v| { v.compute_sma_( starting_indexes.dateindex, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), 7, exit, Some(min_ratio_date), @@ -357,7 +175,7 @@ impl ComputedRatioVecsFromDateIndex { .compute_all(starting_indexes, exit, |v| { v.compute_sma_( starting_indexes.dateindex, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), 30, exit, Some(min_ratio_date), @@ -365,7 +183,7 @@ impl ComputedRatioVecsFromDateIndex { Ok(()) })?; - let ratio_version = self.ratio.dateindex.as_ref().unwrap().version(); + let ratio_version = self.ratio.dateindex.u().version(); self.mut_ratio_vecs() .iter_mut() .try_for_each(|v| -> Result<()> { @@ -385,7 +203,7 @@ impl ComputedRatioVecsFromDateIndex { let min_ratio_date_usize = min_ratio_date.to_usize(); - let mut sorted = self.ratio.dateindex.as_ref().unwrap().collect_range( + let mut sorted = self.ratio.dateindex.u().collect_range( Some(min_ratio_date_usize), Some(starting_dateindex.to_usize()), ); @@ -498,39 +316,39 @@ impl ComputedRatioVecsFromDateIndex { .into_iter() .try_for_each(|v| v.safe_flush(exit))?; - self.ratio_pct1.as_mut().unwrap().compute_rest( + self.ratio_pct1.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; - self.ratio_pct2.as_mut().unwrap().compute_rest( + self.ratio_pct2.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; - self.ratio_pct5.as_mut().unwrap().compute_rest( + self.ratio_pct5.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; - self.ratio_pct95.as_mut().unwrap().compute_rest( + self.ratio_pct95.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; - self.ratio_pct98.as_mut().unwrap().compute_rest( + self.ratio_pct98.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; - self.ratio_pct99.as_mut().unwrap().compute_rest( + self.ratio_pct99.um().compute_rest( starting_indexes, exit, None as Option<&EagerVec>>, )?; let date_to_price = price_opt.unwrap_or_else(|| unsafe { - std::mem::transmute(&self.price.as_ref().unwrap().dateindex) + std::mem::transmute(&self.price.u().dateindex) }); self.ratio_pct99_usd @@ -561,7 +379,7 @@ impl ComputedRatioVecsFromDateIndex { |usd: Option<&mut ComputedVecsFromDateIndex>, source: Option<&ComputedVecsFromDateIndex>| { usd.unwrap().compute_all(starting_indexes, exit, |vec| { - let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter(); + let mut iter = source.unwrap().dateindex.u().into_iter(); vec.compute_transform( starting_indexes.dateindex, date_to_price, @@ -582,28 +400,28 @@ impl ComputedRatioVecsFromDateIndex { compute_usd(self.ratio_pct98_usd.as_mut(), self.ratio_pct98.as_ref())?; compute_usd(self.ratio_pct99_usd.as_mut(), self.ratio_pct99.as_ref())?; - self.ratio_sd.as_mut().unwrap().compute_all( + self.ratio_sd.um().compute_all( starting_indexes, exit, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), Some(date_to_price), )?; - self.ratio_4y_sd.as_mut().unwrap().compute_all( + self.ratio_4y_sd.um().compute_all( starting_indexes, exit, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), Some(date_to_price), )?; - self.ratio_2y_sd.as_mut().unwrap().compute_all( + self.ratio_2y_sd.um().compute_all( starting_indexes, exit, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), Some(date_to_price), )?; - self.ratio_1y_sd.as_mut().unwrap().compute_all( + self.ratio_1y_sd.um().compute_all( starting_indexes, exit, - self.ratio.dateindex.as_ref().unwrap(), + self.ratio.dateindex.u(), Some(date_to_price), )?; @@ -613,22 +431,22 @@ impl ComputedRatioVecsFromDateIndex { fn mut_ratio_vecs(&mut self) -> Vec<&mut EagerVec>> { let mut vecs = Vec::with_capacity(6); if let Some(v) = self.ratio_pct1.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } if let Some(v) = self.ratio_pct2.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } if let Some(v) = self.ratio_pct5.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } if let Some(v) = self.ratio_pct95.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } if let Some(v) = self.ratio_pct98.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } if let Some(v) = self.ratio_pct99.as_mut() { - vecs.push(v.dateindex.as_mut().unwrap()); + vecs.push(v.dateindex.um()); } vecs } diff --git a/crates/brk_computer/src/grouped/sd_from_dateindex.rs b/crates/brk_computer/src/grouped/sd_from_dateindex.rs index 01b734d76..8426e5deb 100644 --- a/crates/brk_computer/src/grouped/sd_from_dateindex.rs +++ b/crates/brk_computer/src/grouped/sd_from_dateindex.rs @@ -6,7 +6,7 @@ use vecdb::{PcoVec, GenericStoredVec, IterableVec, VecIndex, }; -use crate::{Indexes, grouped::source::Source, indexes}; +use crate::{Indexes, grouped::source::Source, indexes, utils::OptionExt}; use super::{ComputedVecsFromDateIndex, VecBuilderOptions}; @@ -103,317 +103,47 @@ impl ComputedStandardDeviationVecsFromDateIndex { indexes: &indexes::Vecs, options: StandardDeviationVecsOptions, ) -> Result { - let builder_options = VecBuilderOptions::default().add_last(); - + let opts = VecBuilderOptions::default().add_last(); let version = parent_version + Version::ONE; + macro_rules! import { + ($suffix:expr) => { + ComputedVecsFromDateIndex::forced_import( + db, &format!("{name}_{}", $suffix), Source::Compute, version, indexes, opts, + ).unwrap() + }; + } + Ok(Self { days, - sma: sma.is_compute().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_sma"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - sd: ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - )?, - p0_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p0_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p1sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p1sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p1_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p1_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p2sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p2sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p2_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p2_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p3sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p3sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m0_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m0_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m1sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m1sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m1_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m1_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m2sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m2sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m2_5sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m2_5sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m3sd: options.bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m3sd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - _0sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_0sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p0_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p0_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p1sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p1sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p1_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p1_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p2sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p2sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p2_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p2_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - p3sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_p3sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m0_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m0_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m1sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m1sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m1_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m1_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m2sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m2sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m2_5sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m2_5sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - m3sd_usd: options.price_bands().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_m3sd_usd"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), - zscore: options.zscore().then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &format!("{name}_zscore"), - Source::Compute, - version + Version::ZERO, - indexes, - builder_options, - ) - .unwrap() - }), + sma: sma.is_compute().then(|| import!("sma")), + sd: import!("sd"), + p0_5sd: options.bands().then(|| import!("p0_5sd")), + p1sd: options.bands().then(|| import!("p1sd")), + p1_5sd: options.bands().then(|| import!("p1_5sd")), + p2sd: options.bands().then(|| import!("p2sd")), + p2_5sd: options.bands().then(|| import!("p2_5sd")), + p3sd: options.bands().then(|| import!("p3sd")), + m0_5sd: options.bands().then(|| import!("m0_5sd")), + m1sd: options.bands().then(|| import!("m1sd")), + m1_5sd: options.bands().then(|| import!("m1_5sd")), + m2sd: options.bands().then(|| import!("m2sd")), + m2_5sd: options.bands().then(|| import!("m2_5sd")), + m3sd: options.bands().then(|| import!("m3sd")), + _0sd_usd: options.price_bands().then(|| import!("0sd_usd")), + p0_5sd_usd: options.price_bands().then(|| import!("p0_5sd_usd")), + p1sd_usd: options.price_bands().then(|| import!("p1sd_usd")), + p1_5sd_usd: options.price_bands().then(|| import!("p1_5sd_usd")), + p2sd_usd: options.price_bands().then(|| import!("p2sd_usd")), + p2_5sd_usd: options.price_bands().then(|| import!("p2_5sd_usd")), + p3sd_usd: options.price_bands().then(|| import!("p3sd_usd")), + m0_5sd_usd: options.price_bands().then(|| import!("m0_5sd_usd")), + m1sd_usd: options.price_bands().then(|| import!("m1sd_usd")), + m1_5sd_usd: options.price_bands().then(|| import!("m1_5sd_usd")), + m2sd_usd: options.price_bands().then(|| import!("m2sd_usd")), + m2_5sd_usd: options.price_bands().then(|| import!("m2_5sd_usd")), + m3sd_usd: options.price_bands().then(|| import!("m3sd_usd")), + zscore: options.zscore().then(|| import!("zscore")), }) } @@ -454,7 +184,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { price_opt: Option<&impl IterableVec>, ) -> Result<()> { let sma = sma_opt.unwrap_or_else(|| unsafe { - std::mem::transmute(&self.sma.as_ref().unwrap().dateindex) + std::mem::transmute(&self.sma.u().dateindex) }); let min_date = DateIndex::try_from(Date::MIN_RATIO).unwrap(); @@ -483,18 +213,18 @@ impl ComputedStandardDeviationVecsFromDateIndex { sorted.sort_unstable(); - let mut p0_5sd = self.p0_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut p1sd = self.p1sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut p1_5sd = self.p1_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut p2sd = self.p2sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut p2_5sd = self.p2_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut p3sd = self.p3sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m0_5sd = self.m0_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m1sd = self.m1sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m1_5sd = self.m1_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m2sd = self.m2sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m2_5sd = self.m2_5sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); - let mut m3sd = self.m3sd.as_mut().map(|c| c.dateindex.as_mut().unwrap()); + let mut p0_5sd = self.p0_5sd.as_mut().map(|c| c.dateindex.um()); + let mut p1sd = self.p1sd.as_mut().map(|c| c.dateindex.um()); + let mut p1_5sd = self.p1_5sd.as_mut().map(|c| c.dateindex.um()); + let mut p2sd = self.p2sd.as_mut().map(|c| c.dateindex.um()); + let mut p2_5sd = self.p2_5sd.as_mut().map(|c| c.dateindex.um()); + let mut p3sd = self.p3sd.as_mut().map(|c| c.dateindex.um()); + let mut m0_5sd = self.m0_5sd.as_mut().map(|c| c.dateindex.um()); + let mut m1sd = self.m1sd.as_mut().map(|c| c.dateindex.um()); + let mut m1_5sd = self.m1_5sd.as_mut().map(|c| c.dateindex.um()); + let mut m2sd = self.m2sd.as_mut().map(|c| c.dateindex.um()); + let mut m2_5sd = self.m2_5sd.as_mut().map(|c| c.dateindex.um()); + let mut m3sd = self.m3sd.as_mut().map(|c| c.dateindex.um()); let min_date_usize = min_date.to_usize(); let mut sma_iter = sma.iter().skip(starting_dateindex.to_usize()); @@ -624,7 +354,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { starting_indexes.dateindex, source, sma, - self.sd.dateindex.as_ref().unwrap(), + self.sd.dateindex.u(), exit, )?; Ok(()) @@ -656,9 +386,9 @@ impl ComputedStandardDeviationVecsFromDateIndex { return Ok(()); } - compute_usd(self._0sd_usd.as_mut().unwrap(), sma.iter())?; + compute_usd(self._0sd_usd.um(), sma.iter())?; compute_usd( - self.p0_5sd_usd.as_mut().unwrap(), + self.p0_5sd_usd.um(), self.p0_5sd .as_ref() .unwrap() @@ -668,7 +398,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.p1sd_usd.as_mut().unwrap(), + self.p1sd_usd.um(), self.p1sd .as_ref() .unwrap() @@ -678,7 +408,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.p1_5sd_usd.as_mut().unwrap(), + self.p1_5sd_usd.um(), self.p1_5sd .as_ref() .unwrap() @@ -688,7 +418,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.p2sd_usd.as_mut().unwrap(), + self.p2sd_usd.um(), self.p2sd .as_ref() .unwrap() @@ -698,7 +428,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.p2_5sd_usd.as_mut().unwrap(), + self.p2_5sd_usd.um(), self.p2_5sd .as_ref() .unwrap() @@ -708,7 +438,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.p3sd_usd.as_mut().unwrap(), + self.p3sd_usd.um(), self.p3sd .as_ref() .unwrap() @@ -718,7 +448,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m0_5sd_usd.as_mut().unwrap(), + self.m0_5sd_usd.um(), self.m0_5sd .as_ref() .unwrap() @@ -728,7 +458,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m1sd_usd.as_mut().unwrap(), + self.m1sd_usd.um(), self.m1sd .as_ref() .unwrap() @@ -738,7 +468,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m1_5sd_usd.as_mut().unwrap(), + self.m1_5sd_usd.um(), self.m1_5sd .as_ref() .unwrap() @@ -748,7 +478,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m2sd_usd.as_mut().unwrap(), + self.m2sd_usd.um(), self.m2sd .as_ref() .unwrap() @@ -758,7 +488,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m2_5sd_usd.as_mut().unwrap(), + self.m2_5sd_usd.um(), self.m2_5sd .as_ref() .unwrap() @@ -768,7 +498,7 @@ impl ComputedStandardDeviationVecsFromDateIndex { .iter(), )?; compute_usd( - self.m3sd_usd.as_mut().unwrap(), + self.m3sd_usd.um(), self.m3sd .as_ref() .unwrap() @@ -807,6 +537,6 @@ impl ComputedStandardDeviationVecsFromDateIndex { &mut self, ) -> impl Iterator>> { self.mut_stateful_computed() - .map(|c| c.dateindex.as_mut().unwrap()) + .map(|c| c.dateindex.um()) } } diff --git a/crates/brk_computer/src/grouped/value_from_dateindex.rs b/crates/brk_computer/src/grouped/value_from_dateindex.rs index d882fa14f..78f80a7de 100644 --- a/crates/brk_computer/src/grouped/value_from_dateindex.rs +++ b/crates/brk_computer/src/grouped/value_from_dateindex.rs @@ -8,6 +8,7 @@ use crate::{ grouped::ComputedVecsFromDateIndex, indexes, price, traits::{ComputeFromBitcoin, ComputeFromSats}, + utils::OptionExt, }; use super::{Source, VecBuilderOptions}; @@ -73,7 +74,7 @@ impl ComputedValueVecsFromDateIndex { where F: FnMut(&mut EagerVec>) -> Result<()>, { - compute(self.sats.dateindex.as_mut().unwrap())?; + compute(self.sats.dateindex.um())?; let dateindex: Option<&PcoVec> = None; self.compute_rest(price, starting_indexes, exit, dateindex)?; @@ -103,13 +104,13 @@ impl ComputedValueVecsFromDateIndex { self.bitcoin.compute_all(starting_indexes, exit, |v| { v.compute_from_sats( starting_indexes.dateindex, - self.sats.dateindex.as_ref().unwrap(), + self.sats.dateindex.u(), exit, ) })?; } - let dateindex_to_bitcoin = self.bitcoin.dateindex.as_ref().unwrap(); + let dateindex_to_bitcoin = self.bitcoin.dateindex.u(); let dateindex_to_price_close = price .as_ref() .unwrap() diff --git a/crates/brk_computer/src/grouped/value_from_height.rs b/crates/brk_computer/src/grouped/value_from_height.rs index c13b02c9f..1fedc3575 100644 --- a/crates/brk_computer/src/grouped/value_from_height.rs +++ b/crates/brk_computer/src/grouped/value_from_height.rs @@ -8,6 +8,7 @@ use crate::{ grouped::Source, indexes, price, traits::{ComputeFromBitcoin, ComputeFromSats}, + utils::OptionExt, }; use super::{ComputedVecsFromHeight, VecBuilderOptions}; @@ -74,7 +75,7 @@ impl ComputedValueVecsFromHeight { where F: FnMut(&mut EagerVec>) -> Result<()>, { - compute(self.sats.height.as_mut().unwrap())?; + compute(self.sats.height.um())?; let height: Option<&PcoVec> = None; self.compute_rest(indexes, price, starting_indexes, exit, height)?; @@ -108,14 +109,14 @@ impl ComputedValueVecsFromHeight { .compute_all(indexes, starting_indexes, exit, |v| { v.compute_from_sats( starting_indexes.height, - self.sats.height.as_ref().unwrap(), + self.sats.height.u(), exit, ) })?; } - let height_to_bitcoin = self.bitcoin.height.as_ref().unwrap(); - let height_to_price_close = &price.as_ref().unwrap().chainindexes_to_price_close.height; + let height_to_bitcoin = self.bitcoin.height.u(); + let height_to_price_close = &price.u().chainindexes_to_price_close.height; if let Some(dollars) = self.dollars.as_mut() { dollars.compute_all(indexes, starting_indexes, exit, |v| { diff --git a/crates/brk_computer/src/grouped/value_from_txindex.rs b/crates/brk_computer/src/grouped/value_from_txindex.rs index b949428c5..e04d8a03a 100644 --- a/crates/brk_computer/src/grouped/value_from_txindex.rs +++ b/crates/brk_computer/src/grouped/value_from_txindex.rs @@ -7,7 +7,7 @@ use vecdb::{ VecIndex, }; -use crate::{Indexes, grouped::Source, indexes, price}; +use crate::{Indexes, grouped::Source, indexes, price, utils::OptionExt}; use super::{ComputedVecsFromTxindex, VecBuilderOptions}; @@ -56,7 +56,7 @@ impl ComputedValueVecsFromTxindex { let bitcoin_txindex = LazyVecFrom1::init( &name_btc, version + VERSION, - source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s), + source_vec.map_or_else(|| sats.txindex.u().boxed_clone(), |s| s), |txindex: TxIndex, iter| iter.get_at(txindex.to_usize()).map(Bitcoin::from), ); @@ -130,7 +130,7 @@ impl ComputedValueVecsFromTxindex { // ) -> Result<()>, // { // compute( - // self.sats.txindex.as_mut().unwrap(), + // self.sats.txindex.um(), // indexer, // indexes, // starting_indexes, @@ -178,7 +178,7 @@ impl ComputedValueVecsFromTxindex { )?; if let Some(dollars) = self.dollars.as_mut() { - let dollars_txindex = self.dollars_txindex.as_mut().unwrap(); + let dollars_txindex = self.dollars_txindex.um(); dollars.compute_rest_from_bitcoin( indexer, @@ -187,7 +187,7 @@ impl ComputedValueVecsFromTxindex { exit, &self.bitcoin, Some(dollars_txindex), - price.as_ref().unwrap(), + price.u(), )?; } diff --git a/crates/brk_computer/src/grouped/value_height.rs b/crates/brk_computer/src/grouped/value_height.rs index 5fd6322cb..ab9221e0d 100644 --- a/crates/brk_computer/src/grouped/value_height.rs +++ b/crates/brk_computer/src/grouped/value_height.rs @@ -8,6 +8,7 @@ use crate::{ grouped::Source, price, traits::{ComputeFromBitcoin, ComputeFromSats}, + utils::OptionExt, }; #[derive(Clone, Traversable)] @@ -57,7 +58,7 @@ impl ComputedHeightValueVecs { where F: FnMut(&mut EagerVec>) -> Result<()>, { - compute(self.sats.as_mut().unwrap())?; + compute(self.sats.um())?; let height: Option<&PcoVec> = None; self.compute_rest(price, starting_indexes, exit, height)?; @@ -78,13 +79,13 @@ impl ComputedHeightValueVecs { } else { self.bitcoin.compute_from_sats( starting_indexes.height, - self.sats.as_ref().unwrap(), + self.sats.u(), exit, )?; } let height_to_bitcoin = &self.bitcoin; - let height_to_price_close = &price.as_ref().unwrap().chainindexes_to_price_close.height; + let height_to_price_close = &price.u().chainindexes_to_price_close.height; if let Some(dollars) = self.dollars.as_mut() { dollars.compute_from_bitcoin( diff --git a/crates/brk_computer/src/indexes.rs b/crates/brk_computer/src/indexes.rs index 176ea2d0e..6e299e60b 100644 --- a/crates/brk_computer/src/indexes.rs +++ b/crates/brk_computer/src/indexes.rs @@ -107,301 +107,75 @@ impl Vecs { let version = parent_version + VERSION; + macro_rules! eager { + ($name:expr) => { EagerVec::forced_import(&db, $name, version)? }; + } + macro_rules! lazy { + ($name:expr, $source:expr) => { + LazyVecFrom1::init($name, version, $source.boxed_clone(), |index, _| Some(index)) + }; + } + let this = Self { - txinindex_to_txoutindex: EagerVec::forced_import(&db, "txoutindex", version)?, - txoutindex_to_txoutindex: LazyVecFrom1::init( - "txoutindex", - version + Version::ZERO, - indexer.vecs.txoutindex_to_value.boxed_clone(), - |index, _| Some(index), - ), - txinindex_to_txinindex: LazyVecFrom1::init( - "txinindex", - version + Version::ZERO, - indexer.vecs.txinindex_to_outpoint.boxed_clone(), - |index, _| Some(index), - ), - p2pk33addressindex_to_p2pk33addressindex: LazyVecFrom1::init( - "p2pk33addressindex", - version + Version::ZERO, - indexer.vecs.p2pk33addressindex_to_p2pk33bytes.boxed_clone(), - |index, _| Some(index), - ), - p2pk65addressindex_to_p2pk65addressindex: LazyVecFrom1::init( - "p2pk65addressindex", - version + Version::ZERO, - indexer.vecs.p2pk65addressindex_to_p2pk65bytes.boxed_clone(), - |index, _| Some(index), - ), - p2pkhaddressindex_to_p2pkhaddressindex: LazyVecFrom1::init( - "p2pkhaddressindex", - version + Version::ZERO, - indexer.vecs.p2pkhaddressindex_to_p2pkhbytes.boxed_clone(), - |index, _| Some(index), - ), - p2shaddressindex_to_p2shaddressindex: LazyVecFrom1::init( - "p2shaddressindex", - version + Version::ZERO, - indexer.vecs.p2shaddressindex_to_p2shbytes.boxed_clone(), - |index, _| Some(index), - ), - p2traddressindex_to_p2traddressindex: LazyVecFrom1::init( - "p2traddressindex", - version + Version::ZERO, - indexer.vecs.p2traddressindex_to_p2trbytes.boxed_clone(), - |index, _| Some(index), - ), - p2wpkhaddressindex_to_p2wpkhaddressindex: LazyVecFrom1::init( - "p2wpkhaddressindex", - version + Version::ZERO, - indexer.vecs.p2wpkhaddressindex_to_p2wpkhbytes.boxed_clone(), - |index, _| Some(index), - ), - p2wshaddressindex_to_p2wshaddressindex: LazyVecFrom1::init( - "p2wshaddressindex", - version + Version::ZERO, - indexer.vecs.p2wshaddressindex_to_p2wshbytes.boxed_clone(), - |index, _| Some(index), - ), - p2aaddressindex_to_p2aaddressindex: LazyVecFrom1::init( - "p2aaddressindex", - version + Version::ZERO, - indexer.vecs.p2aaddressindex_to_p2abytes.boxed_clone(), - |index, _| Some(index), - ), - p2msoutputindex_to_p2msoutputindex: LazyVecFrom1::init( - "p2msoutputindex", - version + Version::ZERO, - indexer.vecs.p2msoutputindex_to_txindex.boxed_clone(), - |index, _| Some(index), - ), - emptyoutputindex_to_emptyoutputindex: LazyVecFrom1::init( - "emptyoutputindex", - version + Version::ZERO, - indexer.vecs.emptyoutputindex_to_txindex.boxed_clone(), - |index, _| Some(index), - ), - unknownoutputindex_to_unknownoutputindex: LazyVecFrom1::init( - "unknownoutputindex", - version + Version::ZERO, - indexer.vecs.unknownoutputindex_to_txindex.boxed_clone(), - |index, _| Some(index), - ), - opreturnindex_to_opreturnindex: LazyVecFrom1::init( - "opreturnindex", - version + Version::ZERO, - indexer.vecs.opreturnindex_to_txindex.boxed_clone(), - |index, _| Some(index), - ), - txindex_to_txindex: LazyVecFrom1::init( - "txindex", - version + Version::ZERO, - indexer.vecs.txindex_to_txid.boxed_clone(), - |index, _| Some(index), - ), - txindex_to_input_count: EagerVec::forced_import( - &db, - "input_count", - version + Version::ZERO, - )?, - txindex_to_output_count: EagerVec::forced_import( - &db, - "output_count", - version + Version::ZERO, - )?, - dateindex_to_date: EagerVec::forced_import(&db, "date", version + Version::ZERO)?, - dateindex_to_dateindex: EagerVec::forced_import( - &db, - "dateindex", - version + Version::ZERO, - )?, - dateindex_to_first_height: EagerVec::forced_import( - &db, - "first_height", - version + Version::ZERO, - )?, - dateindex_to_monthindex: EagerVec::forced_import( - &db, - "monthindex", - version + Version::ZERO, - )?, - dateindex_to_weekindex: EagerVec::forced_import( - &db, - "weekindex", - version + Version::ZERO, - )?, - decadeindex_to_decadeindex: EagerVec::forced_import( - &db, - "decadeindex", - version + Version::ZERO, - )?, - decadeindex_to_first_yearindex: EagerVec::forced_import( - &db, - "first_yearindex", - version + Version::ZERO, - )?, - difficultyepoch_to_difficultyepoch: EagerVec::forced_import( - &db, - "difficultyepoch", - version + Version::ZERO, - )?, - difficultyepoch_to_first_height: EagerVec::forced_import( - &db, - "first_height", - version + Version::ZERO, - )?, - halvingepoch_to_first_height: EagerVec::forced_import( - &db, - "first_height", - version + Version::ZERO, - )?, - halvingepoch_to_halvingepoch: EagerVec::forced_import( - &db, - "halvingepoch", - version + Version::ZERO, - )?, - height_to_date: EagerVec::forced_import(&db, "date", version + Version::ZERO)?, - height_to_difficultyepoch: EagerVec::forced_import( - &db, - "difficultyepoch", - version + Version::ZERO, - )?, - height_to_halvingepoch: EagerVec::forced_import( - &db, - "halvingepoch", - version + Version::ZERO, - )?, - height_to_height: EagerVec::forced_import(&db, "height", version + Version::ZERO)?, - monthindex_to_first_dateindex: EagerVec::forced_import( - &db, - "first_dateindex", - version + Version::ZERO, - )?, - monthindex_to_monthindex: EagerVec::forced_import( - &db, - "monthindex", - version + Version::ZERO, - )?, - monthindex_to_quarterindex: EagerVec::forced_import( - &db, - "quarterindex", - version + Version::ZERO, - )?, - monthindex_to_semesterindex: EagerVec::forced_import( - &db, - "semesterindex", - version + Version::ZERO, - )?, - monthindex_to_yearindex: EagerVec::forced_import( - &db, - "yearindex", - version + Version::ZERO, - )?, - quarterindex_to_first_monthindex: EagerVec::forced_import( - &db, - "first_monthindex", - version + Version::ZERO, - )?, - semesterindex_to_first_monthindex: EagerVec::forced_import( - &db, - "first_monthindex", - version + Version::ZERO, - )?, - weekindex_to_first_dateindex: EagerVec::forced_import( - &db, - "first_dateindex", - version + Version::ZERO, - )?, - yearindex_to_first_monthindex: EagerVec::forced_import( - &db, - "first_monthindex", - version + Version::ZERO, - )?, - quarterindex_to_quarterindex: EagerVec::forced_import( - &db, - "quarterindex", - version + Version::ZERO, - )?, - semesterindex_to_semesterindex: EagerVec::forced_import( - &db, - "semesterindex", - version + Version::ZERO, - )?, - weekindex_to_weekindex: EagerVec::forced_import( - &db, - "weekindex", - version + Version::ZERO, - )?, - yearindex_to_decadeindex: EagerVec::forced_import( - &db, - "decadeindex", - version + Version::ZERO, - )?, - yearindex_to_yearindex: EagerVec::forced_import( - &db, - "yearindex", - version + Version::ZERO, - )?, - height_to_date_fixed: EagerVec::forced_import( - &db, - "date_fixed", - version + Version::ZERO, - )?, - height_to_dateindex: EagerVec::forced_import( - &db, - "dateindex", - version + Version::ZERO, - )?, - height_to_timestamp_fixed: EagerVec::forced_import( - &db, - "timestamp_fixed", - version + Version::ZERO, - )?, - height_to_txindex_count: EagerVec::forced_import( - &db, - "txindex_count", - version + Version::ZERO, - )?, - dateindex_to_height_count: EagerVec::forced_import( - &db, - "height_count", - version + Version::ZERO, - )?, - weekindex_to_dateindex_count: EagerVec::forced_import( - &db, - "dateindex_count", - version + Version::ZERO, - )?, - difficultyepoch_to_height_count: EagerVec::forced_import( - &db, - "height_count", - version + Version::ZERO, - )?, - monthindex_to_dateindex_count: EagerVec::forced_import( - &db, - "dateindex_count", - version + Version::ZERO, - )?, - quarterindex_to_monthindex_count: EagerVec::forced_import( - &db, - "monthindex_count", - version + Version::ZERO, - )?, - semesterindex_to_monthindex_count: EagerVec::forced_import( - &db, - "monthindex_count", - version + Version::ZERO, - )?, - yearindex_to_monthindex_count: EagerVec::forced_import( - &db, - "monthindex_count", - version + Version::ZERO, - )?, - decadeindex_to_yearindex_count: EagerVec::forced_import( - &db, - "yearindex_count", - version + Version::ZERO, - )?, + txinindex_to_txoutindex: eager!("txoutindex"), + txoutindex_to_txoutindex: lazy!("txoutindex", indexer.vecs.txoutindex_to_value), + txinindex_to_txinindex: lazy!("txinindex", indexer.vecs.txinindex_to_outpoint), + p2pk33addressindex_to_p2pk33addressindex: lazy!("p2pk33addressindex", indexer.vecs.p2pk33addressindex_to_p2pk33bytes), + p2pk65addressindex_to_p2pk65addressindex: lazy!("p2pk65addressindex", indexer.vecs.p2pk65addressindex_to_p2pk65bytes), + p2pkhaddressindex_to_p2pkhaddressindex: lazy!("p2pkhaddressindex", indexer.vecs.p2pkhaddressindex_to_p2pkhbytes), + p2shaddressindex_to_p2shaddressindex: lazy!("p2shaddressindex", indexer.vecs.p2shaddressindex_to_p2shbytes), + p2traddressindex_to_p2traddressindex: lazy!("p2traddressindex", indexer.vecs.p2traddressindex_to_p2trbytes), + p2wpkhaddressindex_to_p2wpkhaddressindex: lazy!("p2wpkhaddressindex", indexer.vecs.p2wpkhaddressindex_to_p2wpkhbytes), + p2wshaddressindex_to_p2wshaddressindex: lazy!("p2wshaddressindex", indexer.vecs.p2wshaddressindex_to_p2wshbytes), + p2aaddressindex_to_p2aaddressindex: lazy!("p2aaddressindex", indexer.vecs.p2aaddressindex_to_p2abytes), + p2msoutputindex_to_p2msoutputindex: lazy!("p2msoutputindex", indexer.vecs.p2msoutputindex_to_txindex), + emptyoutputindex_to_emptyoutputindex: lazy!("emptyoutputindex", indexer.vecs.emptyoutputindex_to_txindex), + unknownoutputindex_to_unknownoutputindex: lazy!("unknownoutputindex", indexer.vecs.unknownoutputindex_to_txindex), + opreturnindex_to_opreturnindex: lazy!("opreturnindex", indexer.vecs.opreturnindex_to_txindex), + txindex_to_txindex: lazy!("txindex", indexer.vecs.txindex_to_txid), + txindex_to_input_count: eager!("input_count"), + txindex_to_output_count: eager!("output_count"), + dateindex_to_date: eager!("date"), + dateindex_to_dateindex: eager!("dateindex"), + dateindex_to_first_height: eager!("first_height"), + dateindex_to_monthindex: eager!("monthindex"), + dateindex_to_weekindex: eager!("weekindex"), + decadeindex_to_decadeindex: eager!("decadeindex"), + decadeindex_to_first_yearindex: eager!("first_yearindex"), + difficultyepoch_to_difficultyepoch: eager!("difficultyepoch"), + difficultyepoch_to_first_height: eager!("first_height"), + halvingepoch_to_first_height: eager!("first_height"), + halvingepoch_to_halvingepoch: eager!("halvingepoch"), + height_to_date: eager!("date"), + height_to_difficultyepoch: eager!("difficultyepoch"), + height_to_halvingepoch: eager!("halvingepoch"), + height_to_height: eager!("height"), + monthindex_to_first_dateindex: eager!("first_dateindex"), + monthindex_to_monthindex: eager!("monthindex"), + monthindex_to_quarterindex: eager!("quarterindex"), + monthindex_to_semesterindex: eager!("semesterindex"), + monthindex_to_yearindex: eager!("yearindex"), + quarterindex_to_first_monthindex: eager!("first_monthindex"), + semesterindex_to_first_monthindex: eager!("first_monthindex"), + weekindex_to_first_dateindex: eager!("first_dateindex"), + yearindex_to_first_monthindex: eager!("first_monthindex"), + quarterindex_to_quarterindex: eager!("quarterindex"), + semesterindex_to_semesterindex: eager!("semesterindex"), + weekindex_to_weekindex: eager!("weekindex"), + yearindex_to_decadeindex: eager!("decadeindex"), + yearindex_to_yearindex: eager!("yearindex"), + height_to_date_fixed: eager!("date_fixed"), + height_to_dateindex: eager!("dateindex"), + height_to_timestamp_fixed: eager!("timestamp_fixed"), + height_to_txindex_count: eager!("txindex_count"), + dateindex_to_height_count: eager!("height_count"), + weekindex_to_dateindex_count: eager!("dateindex_count"), + difficultyepoch_to_height_count: eager!("height_count"), + monthindex_to_dateindex_count: eager!("dateindex_count"), + quarterindex_to_monthindex_count: eager!("monthindex_count"), + semesterindex_to_monthindex_count: eager!("monthindex_count"), + yearindex_to_monthindex_count: eager!("monthindex_count"), + decadeindex_to_yearindex_count: eager!("yearindex_count"), db, }; diff --git a/crates/brk_computer/src/lib.rs b/crates/brk_computer/src/lib.rs index 4afc9a791..36613e0f0 100644 --- a/crates/brk_computer/src/lib.rs +++ b/crates/brk_computer/src/lib.rs @@ -27,6 +27,7 @@ mod traits; mod utils; use indexes::Indexes; +use utils::OptionExt; // pub use pools::*; pub use states::PriceToAmount; @@ -162,7 +163,7 @@ impl Computer { info!("Computing prices..."); let i = Instant::now(); - self.price.as_mut().unwrap().compute( + self.price.um().compute( &self.indexes, &starting_indexes, fetched, diff --git a/crates/brk_computer/src/market.rs b/crates/brk_computer/src/market.rs index 858fd3cd1..ffbf9ba22 100644 --- a/crates/brk_computer/src/market.rs +++ b/crates/brk_computer/src/market.rs @@ -12,6 +12,7 @@ use crate::{ grouped::{ComputedStandardDeviationVecsFromDateIndex, Source, StandardDeviationVecsOptions}, price, traits::{ComputeDCAAveragePriceViaLen, ComputeDCAStackViaLen, ComputeDrawdown}, + utils::OptionExt, }; use super::{ @@ -211,1311 +212,213 @@ impl Vecs { db.set_min_len(PAGE_SIZE * 1_000_000)?; let version = parent_version + Version::ZERO; + let v0 = Version::ZERO; + let v1 = Version::ONE; + let v2 = Version::TWO; + let last = VecBuilderOptions::default().add_last(); + + // Helper macros for computed vecs + macro_rules! computed_di { + ($name:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, last.clone())? + }; + ($name:expr, $v:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + $v, indexes, last.clone())? + }; + } + macro_rules! ratio_di { + ($name:expr) => { + ComputedRatioVecsFromDateIndex::forced_import(&db, $name, Source::Compute, version + v0, indexes, true)? + }; + } + macro_rules! sd_di { + ($name:expr, $window:expr, $v:expr) => { + ComputedStandardDeviationVecsFromDateIndex::forced_import(&db, $name, $window, Source::Compute, version + $v, indexes, StandardDeviationVecsOptions::default())? + }; + } + macro_rules! eager_h { + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } + macro_rules! eager_di { + ($name:expr, $v:expr) => { + EagerVec::forced_import(&db, $name, version + $v)? + }; + } let this = Self { - height_to_price_ath: EagerVec::forced_import( - &db, - "price_ath", - version + Version::ZERO, - )?, - height_to_price_drawdown: EagerVec::forced_import( - &db, - "price_drawdown", - version + Version::ZERO, - )?, - indexes_to_price_ath: ComputedVecsFromDateIndex::forced_import( - &db, - "price_ath", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_drawdown: ComputedVecsFromDateIndex::forced_import( - &db, - "price_drawdown", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1d_returns_1w_sd: ComputedStandardDeviationVecsFromDateIndex::forced_import( - &db, - "1d_returns_1w_sd", - 7, - Source::Compute, - version + Version::ONE, - indexes, - StandardDeviationVecsOptions::default(), - )?, - indexes_to_1d_returns_1m_sd: ComputedStandardDeviationVecsFromDateIndex::forced_import( - &db, - "1d_returns_1m_sd", - 30, - Source::Compute, - version + Version::ONE, - indexes, - StandardDeviationVecsOptions::default(), - )?, - indexes_to_1d_returns_1y_sd: ComputedStandardDeviationVecsFromDateIndex::forced_import( - &db, - "1d_returns_1y_sd", - 365, - Source::Compute, - version + Version::ONE, - indexes, - StandardDeviationVecsOptions::default(), - )?, - indexes_to_price_1w_volatility: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1w_volatility", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1m_volatility: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1m_volatility", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1y_volatility: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1y_volatility", - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_days_since_price_ath: ComputedVecsFromDateIndex::forced_import( - &db, - "days_since_price_ath", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_max_days_between_price_aths: ComputedVecsFromDateIndex::forced_import( - &db, - "max_days_between_price_aths", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_max_years_between_price_aths: ComputedVecsFromDateIndex::forced_import( - &db, - "max_years_between_price_aths", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + height_to_price_ath: eager_h!("price_ath", v0), + height_to_price_drawdown: eager_h!("price_drawdown", v0), + indexes_to_price_ath: computed_di!("price_ath"), + indexes_to_price_drawdown: computed_di!("price_drawdown"), + indexes_to_1d_returns_1w_sd: sd_di!("1d_returns_1w_sd", 7, v1), + indexes_to_1d_returns_1m_sd: sd_di!("1d_returns_1m_sd", 30, v1), + indexes_to_1d_returns_1y_sd: sd_di!("1d_returns_1y_sd", 365, v1), + indexes_to_price_1w_volatility: computed_di!("price_1w_volatility", v2), + indexes_to_price_1m_volatility: computed_di!("price_1m_volatility", v2), + indexes_to_price_1y_volatility: computed_di!("price_1y_volatility", v2), + indexes_to_days_since_price_ath: computed_di!("days_since_price_ath"), + indexes_to_max_days_between_price_aths: computed_di!("max_days_between_price_aths"), + indexes_to_max_years_between_price_aths: computed_di!("max_years_between_price_aths"), - indexes_to_price_1w_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1w_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_8d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_8d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_13d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_13d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_21d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_21d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_1m_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1m_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_34d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_34d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_55d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_55d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_89d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_89d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_144d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_144d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_200d_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_200d_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_1y_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1y_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_2y_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_2y_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_200w_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_200w_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_4y_sma: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_4y_sma", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, + indexes_to_price_1w_sma: ratio_di!("price_1w_sma"), + indexes_to_price_8d_sma: ratio_di!("price_8d_sma"), + indexes_to_price_13d_sma: ratio_di!("price_13d_sma"), + indexes_to_price_21d_sma: ratio_di!("price_21d_sma"), + indexes_to_price_1m_sma: ratio_di!("price_1m_sma"), + indexes_to_price_34d_sma: ratio_di!("price_34d_sma"), + indexes_to_price_55d_sma: ratio_di!("price_55d_sma"), + indexes_to_price_89d_sma: ratio_di!("price_89d_sma"), + indexes_to_price_144d_sma: ratio_di!("price_144d_sma"), + indexes_to_price_200d_sma: ratio_di!("price_200d_sma"), + indexes_to_price_1y_sma: ratio_di!("price_1y_sma"), + indexes_to_price_2y_sma: ratio_di!("price_2y_sma"), + indexes_to_price_200w_sma: ratio_di!("price_200w_sma"), + indexes_to_price_4y_sma: ratio_di!("price_4y_sma"), - indexes_to_price_1w_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1w_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_8d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_8d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_13d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_13d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_21d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_21d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_1m_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1m_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_34d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_34d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_55d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_55d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_89d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_89d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_144d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_144d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_200d_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_200d_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_1y_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_1y_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_2y_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_2y_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_200w_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_200w_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, - indexes_to_price_4y_ema: ComputedRatioVecsFromDateIndex::forced_import( - &db, - "price_4y_ema", - Source::Compute, - version + Version::ZERO, - indexes, - true, - )?, + indexes_to_price_1w_ema: ratio_di!("price_1w_ema"), + indexes_to_price_8d_ema: ratio_di!("price_8d_ema"), + indexes_to_price_13d_ema: ratio_di!("price_13d_ema"), + indexes_to_price_21d_ema: ratio_di!("price_21d_ema"), + indexes_to_price_1m_ema: ratio_di!("price_1m_ema"), + indexes_to_price_34d_ema: ratio_di!("price_34d_ema"), + indexes_to_price_55d_ema: ratio_di!("price_55d_ema"), + indexes_to_price_89d_ema: ratio_di!("price_89d_ema"), + indexes_to_price_144d_ema: ratio_di!("price_144d_ema"), + indexes_to_price_200d_ema: ratio_di!("price_200d_ema"), + indexes_to_price_1y_ema: ratio_di!("price_1y_ema"), + indexes_to_price_2y_ema: ratio_di!("price_2y_ema"), + indexes_to_price_200w_ema: ratio_di!("price_200w_ema"), + indexes_to_price_4y_ema: ratio_di!("price_4y_ema"), - _1d_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1d_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1w_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1w_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1m_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1m_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3m_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "3m_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6m_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "6m_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_price_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_price_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + _1d_price_returns: computed_di!("1d_price_returns"), + _1w_price_returns: computed_di!("1w_price_returns"), + _1m_price_returns: computed_di!("1m_price_returns"), + _3m_price_returns: computed_di!("3m_price_returns"), + _6m_price_returns: computed_di!("6m_price_returns"), + _1y_price_returns: computed_di!("1y_price_returns"), + _2y_price_returns: computed_di!("2y_price_returns"), + _3y_price_returns: computed_di!("3y_price_returns"), + _4y_price_returns: computed_di!("4y_price_returns"), + _5y_price_returns: computed_di!("5y_price_returns"), + _6y_price_returns: computed_di!("6y_price_returns"), + _8y_price_returns: computed_di!("8y_price_returns"), + _10y_price_returns: computed_di!("10y_price_returns"), + _2y_cagr: computed_di!("2y_cagr"), + _3y_cagr: computed_di!("3y_cagr"), + _4y_cagr: computed_di!("4y_cagr"), + _5y_cagr: computed_di!("5y_cagr"), + _6y_cagr: computed_di!("6y_cagr"), + _8y_cagr: computed_di!("8y_cagr"), + _10y_cagr: computed_di!("10y_cagr"), - _1w_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1w_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1m_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1m_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3m_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "3m_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6m_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "6m_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "1y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_dca_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_dca_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_dca_cagr: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_dca_cagr", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1w_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "1w_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1m_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "1m_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3m_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "3m_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6m_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "6m_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "1y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_dca_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_dca_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_1d_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1d_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_1w_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1w_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_1m_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1m_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_3m_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_3m_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_6m_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_6m_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_1y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_2y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_2y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_3y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_3y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_4y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_4y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_5y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_5y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_6y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_6y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_8y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_8y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - price_10y_ago: ComputedVecsFromDateIndex::forced_import( - &db, - "price_10y_ago", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1w_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "1w_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1m_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "1m_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3m_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "3m_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6m_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "6m_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _1y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "1y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _2y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "2y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _3y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "3y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _4y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "4y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _5y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "5y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _6y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "6y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _8y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "8y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - _10y_dca_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "10y_dca_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + _1w_dca_returns: computed_di!("1w_dca_returns"), + _1m_dca_returns: computed_di!("1m_dca_returns"), + _3m_dca_returns: computed_di!("3m_dca_returns"), + _6m_dca_returns: computed_di!("6m_dca_returns"), + _1y_dca_returns: computed_di!("1y_dca_returns"), + _2y_dca_returns: computed_di!("2y_dca_returns"), + _3y_dca_returns: computed_di!("3y_dca_returns"), + _4y_dca_returns: computed_di!("4y_dca_returns"), + _5y_dca_returns: computed_di!("5y_dca_returns"), + _6y_dca_returns: computed_di!("6y_dca_returns"), + _8y_dca_returns: computed_di!("8y_dca_returns"), + _10y_dca_returns: computed_di!("10y_dca_returns"), + _2y_dca_cagr: computed_di!("2y_dca_cagr"), + _3y_dca_cagr: computed_di!("3y_dca_cagr"), + _4y_dca_cagr: computed_di!("4y_dca_cagr"), + _5y_dca_cagr: computed_di!("5y_dca_cagr"), + _6y_dca_cagr: computed_di!("6y_dca_cagr"), + _8y_dca_cagr: computed_di!("8y_dca_cagr"), + _10y_dca_cagr: computed_di!("10y_dca_cagr"), + _1w_dca_avg_price: computed_di!("1w_dca_avg_price"), + _1m_dca_avg_price: computed_di!("1m_dca_avg_price"), + _3m_dca_avg_price: computed_di!("3m_dca_avg_price"), + _6m_dca_avg_price: computed_di!("6m_dca_avg_price"), + _1y_dca_avg_price: computed_di!("1y_dca_avg_price"), + _2y_dca_avg_price: computed_di!("2y_dca_avg_price"), + _3y_dca_avg_price: computed_di!("3y_dca_avg_price"), + _4y_dca_avg_price: computed_di!("4y_dca_avg_price"), + _5y_dca_avg_price: computed_di!("5y_dca_avg_price"), + _6y_dca_avg_price: computed_di!("6y_dca_avg_price"), + _8y_dca_avg_price: computed_di!("8y_dca_avg_price"), + _10y_dca_avg_price: computed_di!("10y_dca_avg_price"), + price_1d_ago: computed_di!("price_1d_ago"), + price_1w_ago: computed_di!("price_1w_ago"), + price_1m_ago: computed_di!("price_1m_ago"), + price_3m_ago: computed_di!("price_3m_ago"), + price_6m_ago: computed_di!("price_6m_ago"), + price_1y_ago: computed_di!("price_1y_ago"), + price_2y_ago: computed_di!("price_2y_ago"), + price_3y_ago: computed_di!("price_3y_ago"), + price_4y_ago: computed_di!("price_4y_ago"), + price_5y_ago: computed_di!("price_5y_ago"), + price_6y_ago: computed_di!("price_6y_ago"), + price_8y_ago: computed_di!("price_8y_ago"), + price_10y_ago: computed_di!("price_10y_ago"), + _1w_dca_stack: computed_di!("1w_dca_stack"), + _1m_dca_stack: computed_di!("1m_dca_stack"), + _3m_dca_stack: computed_di!("3m_dca_stack"), + _6m_dca_stack: computed_di!("6m_dca_stack"), + _1y_dca_stack: computed_di!("1y_dca_stack"), + _2y_dca_stack: computed_di!("2y_dca_stack"), + _3y_dca_stack: computed_di!("3y_dca_stack"), + _4y_dca_stack: computed_di!("4y_dca_stack"), + _5y_dca_stack: computed_di!("5y_dca_stack"), + _6y_dca_stack: computed_di!("6y_dca_stack"), + _8y_dca_stack: computed_di!("8y_dca_stack"), + _10y_dca_stack: computed_di!("10y_dca_stack"), - dca_class_2025_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2025_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2024_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2024_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2023_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2023_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2022_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2022_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2021_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2021_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2020_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2020_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2019_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2019_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2018_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2018_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2017_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2017_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2016_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2016_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2015_stack: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2015_stack", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + dca_class_2025_stack: computed_di!("dca_class_2025_stack"), + dca_class_2024_stack: computed_di!("dca_class_2024_stack"), + dca_class_2023_stack: computed_di!("dca_class_2023_stack"), + dca_class_2022_stack: computed_di!("dca_class_2022_stack"), + dca_class_2021_stack: computed_di!("dca_class_2021_stack"), + dca_class_2020_stack: computed_di!("dca_class_2020_stack"), + dca_class_2019_stack: computed_di!("dca_class_2019_stack"), + dca_class_2018_stack: computed_di!("dca_class_2018_stack"), + dca_class_2017_stack: computed_di!("dca_class_2017_stack"), + dca_class_2016_stack: computed_di!("dca_class_2016_stack"), + dca_class_2015_stack: computed_di!("dca_class_2015_stack"), - dca_class_2025_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2025_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2024_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2024_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2023_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2023_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2022_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2022_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2021_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2021_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2020_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2020_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2019_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2019_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2018_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2018_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2017_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2017_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2016_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2016_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2015_avg_price: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2015_avg_price", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + dca_class_2025_avg_price: computed_di!("dca_class_2025_avg_price"), + dca_class_2024_avg_price: computed_di!("dca_class_2024_avg_price"), + dca_class_2023_avg_price: computed_di!("dca_class_2023_avg_price"), + dca_class_2022_avg_price: computed_di!("dca_class_2022_avg_price"), + dca_class_2021_avg_price: computed_di!("dca_class_2021_avg_price"), + dca_class_2020_avg_price: computed_di!("dca_class_2020_avg_price"), + dca_class_2019_avg_price: computed_di!("dca_class_2019_avg_price"), + dca_class_2018_avg_price: computed_di!("dca_class_2018_avg_price"), + dca_class_2017_avg_price: computed_di!("dca_class_2017_avg_price"), + dca_class_2016_avg_price: computed_di!("dca_class_2016_avg_price"), + dca_class_2015_avg_price: computed_di!("dca_class_2015_avg_price"), - dca_class_2025_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2025_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2024_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2024_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2023_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2023_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2022_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2022_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2021_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2021_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2020_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2020_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2019_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2019_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2018_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2018_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2017_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2017_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2016_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2016_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dca_class_2015_returns: ComputedVecsFromDateIndex::forced_import( - &db, - "dca_class_2015_returns", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, + dca_class_2025_returns: computed_di!("dca_class_2025_returns"), + dca_class_2024_returns: computed_di!("dca_class_2024_returns"), + dca_class_2023_returns: computed_di!("dca_class_2023_returns"), + dca_class_2022_returns: computed_di!("dca_class_2022_returns"), + dca_class_2021_returns: computed_di!("dca_class_2021_returns"), + dca_class_2020_returns: computed_di!("dca_class_2020_returns"), + dca_class_2019_returns: computed_di!("dca_class_2019_returns"), + dca_class_2018_returns: computed_di!("dca_class_2018_returns"), + dca_class_2017_returns: computed_di!("dca_class_2017_returns"), + dca_class_2016_returns: computed_di!("dca_class_2016_returns"), + dca_class_2015_returns: computed_di!("dca_class_2015_returns"), - indexes_to_price_200d_sma_x2_4: ComputedVecsFromDateIndex::forced_import( - &db, - "price_200d_sma_x2_4", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_200d_sma_x0_8: ComputedVecsFromDateIndex::forced_import( - &db, - "price_200d_sma_x0_8", - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - dateindex_to_price_true_range: EagerVec::forced_import( - &db, - "price_true_range", - version + Version::ZERO, - )?, - dateindex_to_price_true_range_2w_sum: EagerVec::forced_import( - &db, - "price_true_range_2w_sum", - version + Version::ZERO, - )?, - indexes_to_price_1w_min: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1w_min", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1w_max: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1w_max", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_2w_min: ComputedVecsFromDateIndex::forced_import( - &db, - "price_2w_min", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_2w_max: ComputedVecsFromDateIndex::forced_import( - &db, - "price_2w_max", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1m_min: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1m_min", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1m_max: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1m_max", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1y_min: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1y_min", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_1y_max: ComputedVecsFromDateIndex::forced_import( - &db, - "price_1y_max", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_price_2w_choppiness_index: ComputedVecsFromDateIndex::forced_import( - &db, - "price_2w_choppiness_index", - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - )?, + indexes_to_price_200d_sma_x2_4: computed_di!("price_200d_sma_x2_4"), + indexes_to_price_200d_sma_x0_8: computed_di!("price_200d_sma_x0_8"), + dateindex_to_price_true_range: eager_di!("price_true_range", v0), + dateindex_to_price_true_range_2w_sum: eager_di!("price_true_range_2w_sum", v0), + indexes_to_price_1w_min: computed_di!("price_1w_min", v1), + indexes_to_price_1w_max: computed_di!("price_1w_max", v1), + indexes_to_price_2w_min: computed_di!("price_2w_min", v1), + indexes_to_price_2w_max: computed_di!("price_2w_max", v1), + indexes_to_price_1m_min: computed_di!("price_1m_min", v1), + indexes_to_price_1m_max: computed_di!("price_1m_max", v1), + indexes_to_price_1y_min: computed_di!("price_1y_min", v1), + indexes_to_price_1y_max: computed_di!("price_1y_max", v1), + indexes_to_price_2w_choppiness_index: computed_di!("price_2w_choppiness_index", v1), db, }; @@ -1563,7 +466,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_all_time_high( starting_indexes.dateindex, - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_high.dateindex.u(), exit, )?; Ok(()) @@ -1573,8 +476,8 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_drawdown( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), - self.indexes_to_price_ath.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), + self.indexes_to_price_ath.dateindex.u(), exit, )?; Ok(()) @@ -1582,16 +485,11 @@ impl Vecs { self.indexes_to_days_since_price_ath .compute_all(starting_indexes, exit, |v| { - let mut high_iter = price - .timeindexes_to_price_high - .dateindex - .as_ref() - .unwrap() - .into_iter(); + let mut high_iter = price.timeindexes_to_price_high.dateindex.u().into_iter(); let mut prev = None; v.compute_transform( starting_indexes.dateindex, - self.indexes_to_price_ath.dateindex.as_ref().unwrap(), + self.indexes_to_price_ath.dateindex.u(), |(i, ath, slf)| { if prev.is_none() { let i = i.to_usize(); @@ -1619,10 +517,7 @@ impl Vecs { let mut prev = None; v.compute_transform( starting_indexes.dateindex, - self.indexes_to_days_since_price_ath - .dateindex - .as_ref() - .unwrap(), + self.indexes_to_days_since_price_ath.dateindex.u(), |(i, days, slf)| { if prev.is_none() { let i = i.to_usize(); @@ -1645,10 +540,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.indexes_to_max_days_between_price_aths - .dateindex - .as_ref() - .unwrap(), + self.indexes_to_max_days_between_price_aths.dateindex.u(), |(i, max, ..)| (i, StoredF32::from(*max as f64 / 365.0)), exit, )?; @@ -1730,7 +622,7 @@ impl Vecs { ago.compute_all(starting_indexes, exit, |v| { v.compute_previous_value( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), days, exit, )?; @@ -1740,7 +632,7 @@ impl Vecs { returns.compute_all(starting_indexes, exit, |v| { v.compute_percentage_change( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), days, exit, )?; @@ -1751,7 +643,7 @@ impl Vecs { cagr.compute_all(starting_indexes, exit, |v| { v.compute_cagr( starting_indexes.dateindex, - returns.dateindex.as_ref().unwrap(), + returns.dateindex.u(), days, exit, )?; @@ -1854,7 +746,7 @@ impl Vecs { dca_stack.compute_all(starting_indexes, exit, |v| { v.compute_dca_stack_via_len( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), days, exit, )?; @@ -1864,7 +756,7 @@ impl Vecs { dca_avg_price.compute_all(starting_indexes, exit, |v| { v.compute_dca_avg_price_via_len( starting_indexes.dateindex, - dca_stack.dateindex.as_ref().unwrap(), + dca_stack.dateindex.u(), days, exit, )?; @@ -1874,8 +766,8 @@ impl Vecs { dca_returns.compute_all(starting_indexes, exit, |v| { v.compute_percentage_difference( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), - dca_avg_price.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), + dca_avg_price.dateindex.u(), exit, )?; Ok(()) @@ -1885,7 +777,7 @@ impl Vecs { dca_cagr.compute_all(starting_indexes, exit, |v| { v.compute_cagr( starting_indexes.dateindex, - dca_returns.dateindex.as_ref().unwrap(), + dca_returns.dateindex.u(), days, exit, )?; @@ -1972,7 +864,7 @@ impl Vecs { stack.compute_all(starting_indexes, exit, |v| { v.compute_dca_stack_via_from( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), dateindex, exit, )?; @@ -1982,7 +874,7 @@ impl Vecs { avg_price.compute_all(starting_indexes, exit, |v| { v.compute_dca_avg_price_via_from( starting_indexes.dateindex, - stack.dateindex.as_ref().unwrap(), + stack.dateindex.u(), dateindex, exit, )?; @@ -1992,8 +884,8 @@ impl Vecs { returns.compute_all(starting_indexes, exit, |v| { v.compute_percentage_difference( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), - avg_price.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), + avg_price.dateindex.u(), exit, )?; Ok(()) @@ -2081,7 +973,7 @@ impl Vecs { sma.compute_all(price, starting_indexes, exit, |v| { v.compute_sma( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), days, exit, )?; @@ -2091,7 +983,7 @@ impl Vecs { ema.compute_all(price, starting_indexes, exit, |v| { v.compute_ema( starting_indexes.dateindex, - price.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_close.dateindex.u(), days, exit, )?; @@ -2139,19 +1031,19 @@ impl Vecs { self.indexes_to_1d_returns_1w_sd.compute_all( starting_indexes, exit, - self._1d_price_returns.dateindex.as_ref().unwrap(), + self._1d_price_returns.dateindex.u(), None as Option<&EagerVec>>, )?; self.indexes_to_1d_returns_1m_sd.compute_all( starting_indexes, exit, - self._1d_price_returns.dateindex.as_ref().unwrap(), + self._1d_price_returns.dateindex.u(), None as Option<&EagerVec>>, )?; self.indexes_to_1d_returns_1y_sd.compute_all( starting_indexes, exit, - self._1d_price_returns.dateindex.as_ref().unwrap(), + self._1d_price_returns.dateindex.u(), None as Option<&EagerVec>>, )?; @@ -2200,9 +1092,9 @@ impl Vecs { self.dateindex_to_price_true_range.compute_transform3( starting_indexes.dateindex, - price.timeindexes_to_price_open.dateindex.as_ref().unwrap(), - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), - price.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_open.dateindex.u(), + price.timeindexes_to_price_high.dateindex.u(), + price.timeindexes_to_price_low.dateindex.u(), |(i, open, high, low, ..)| { let high_min_low = **high - **low; let high_min_open = (**high - **open).abs(); @@ -2223,7 +1115,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_max( starting_indexes.dateindex, - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_high.dateindex.u(), 7, exit, )?; @@ -2234,7 +1126,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_min( starting_indexes.dateindex, - price.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_low.dateindex.u(), 7, exit, )?; @@ -2245,7 +1137,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_max( starting_indexes.dateindex, - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_high.dateindex.u(), 14, exit, )?; @@ -2256,7 +1148,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_min( starting_indexes.dateindex, - price.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_low.dateindex.u(), 14, exit, )?; @@ -2267,7 +1159,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_max( starting_indexes.dateindex, - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_high.dateindex.u(), 30, exit, )?; @@ -2278,7 +1170,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_min( starting_indexes.dateindex, - price.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_low.dateindex.u(), 30, exit, )?; @@ -2289,7 +1181,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_max( starting_indexes.dateindex, - price.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_high.dateindex.u(), 365, exit, )?; @@ -2300,7 +1192,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_min( starting_indexes.dateindex, - price.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + price.timeindexes_to_price_low.dateindex.u(), 365, exit, )?; @@ -2314,8 +1206,8 @@ impl Vecs { v.compute_transform3( starting_indexes.dateindex, &self.dateindex_to_price_true_range_2w_sum, - self.indexes_to_price_2w_max.dateindex.as_ref().unwrap(), - self.indexes_to_price_2w_min.dateindex.as_ref().unwrap(), + self.indexes_to_price_2w_max.dateindex.u(), + self.indexes_to_price_2w_min.dateindex.u(), |(i, tr_sum, max, min, ..)| { ( i, diff --git a/crates/brk_computer/src/pools/vecs.rs b/crates/brk_computer/src/pools/vecs.rs index 086dc698a..c8fd3b812 100644 --- a/crates/brk_computer/src/pools/vecs.rs +++ b/crates/brk_computer/src/pools/vecs.rs @@ -11,6 +11,7 @@ use crate::{ }, indexes::{self, Indexes}, price, + utils::OptionExt, }; #[derive(Clone, Traversable)] @@ -47,115 +48,40 @@ impl Vecs { let compute_dollars = price.is_some(); let version = parent_version + Version::ZERO; + let last = VecBuilderOptions::default().add_last(); + let sum_cum = VecBuilderOptions::default().add_sum().add_cumulative(); + + macro_rules! import_di { + ($name:expr) => { + ComputedVecsFromDateIndex::forced_import( + db, &suffix($name), Source::Compute, version, indexes, last.clone(), + )? + }; + } + Ok(Self { id, indexes_to_blocks_mined: ComputedVecsFromHeight::forced_import( - db, - &suffix("blocks_mined"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_1w_blocks_mined: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1w_blocks_mined"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1m_blocks_mined: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1m_blocks_mined"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1y_blocks_mined: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1y_blocks_mined"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), + db, &suffix("blocks_mined"), Source::Compute, version, indexes, sum_cum.clone(), )?, + indexes_to_1w_blocks_mined: import_di!("1w_blocks_mined"), + indexes_to_1m_blocks_mined: import_di!("1m_blocks_mined"), + indexes_to_1y_blocks_mined: import_di!("1y_blocks_mined"), indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import( - db, - &suffix("subsidy"), - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum().add_cumulative(), - compute_dollars, - indexes, + db, &suffix("subsidy"), Source::Compute, version, sum_cum.clone(), compute_dollars, indexes, )?, indexes_to_fee: ComputedValueVecsFromHeight::forced_import( - db, - &suffix("fee"), - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum().add_cumulative(), - compute_dollars, - indexes, + db, &suffix("fee"), Source::Compute, version, sum_cum.clone(), compute_dollars, indexes, )?, indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import( - db, - &suffix("coinbase"), - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum().add_cumulative(), - compute_dollars, - indexes, - )?, - indexes_to_dominance: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("dominance"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1d_dominance: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1d_dominance"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1w_dominance: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1w_dominance"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1m_dominance: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1m_dominance"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_1y_dominance: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("1y_dominance"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_days_since_block: ComputedVecsFromDateIndex::forced_import( - db, - &suffix("days_since_block"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), + db, &suffix("coinbase"), Source::Compute, version, sum_cum, compute_dollars, indexes, )?, + indexes_to_dominance: import_di!("dominance"), + indexes_to_1d_dominance: import_di!("1d_dominance"), + indexes_to_1w_dominance: import_di!("1w_dominance"), + indexes_to_1m_dominance: import_di!("1m_dominance"), + indexes_to_1y_dominance: import_di!("1y_dominance"), + indexes_to_days_since_block: import_di!("days_since_block"), }) } @@ -222,14 +148,14 @@ impl Vecs { Ok(()) })?; - let height_to_blocks_mined = self.indexes_to_blocks_mined.height.as_ref().unwrap(); + let height_to_blocks_mined = self.indexes_to_blocks_mined.height.u(); self.indexes_to_subsidy .compute_all(indexes, price, starting_indexes, exit, |vec| { vec.compute_transform2( starting_indexes.height, height_to_blocks_mined, - chain.indexes_to_subsidy.sats.height.as_ref().unwrap(), + chain.indexes_to_subsidy.sats.height.u(), |(h, mined, sats, ..)| { ( h, @@ -271,7 +197,7 @@ impl Vecs { vec.compute_transform2( starting_indexes.height, height_to_blocks_mined, - chain.indexes_to_coinbase.sats.height.as_ref().unwrap(), + chain.indexes_to_coinbase.sats.height.u(), |(h, mined, sats, ..)| { ( h, @@ -313,8 +239,8 @@ impl Vecs { .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.indexes_to_1w_blocks_mined.dateindex.as_ref().unwrap(), - chain.indexes_to_1w_block_count.dateindex.as_ref().unwrap(), + self.indexes_to_1w_blocks_mined.dateindex.u(), + chain.indexes_to_1w_block_count.dateindex.u(), exit, )?; Ok(()) @@ -324,8 +250,8 @@ impl Vecs { .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.indexes_to_1m_blocks_mined.dateindex.as_ref().unwrap(), - chain.indexes_to_1m_block_count.dateindex.as_ref().unwrap(), + self.indexes_to_1m_blocks_mined.dateindex.u(), + chain.indexes_to_1m_block_count.dateindex.u(), exit, )?; Ok(()) @@ -335,8 +261,8 @@ impl Vecs { .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.indexes_to_1y_blocks_mined.dateindex.as_ref().unwrap(), - chain.indexes_to_1y_block_count.dateindex.as_ref().unwrap(), + self.indexes_to_1y_blocks_mined.dateindex.u(), + chain.indexes_to_1y_block_count.dateindex.u(), exit, )?; Ok(()) diff --git a/crates/brk_computer/src/price.rs b/crates/brk_computer/src/price.rs index b78da158f..acb22e150 100644 --- a/crates/brk_computer/src/price.rs +++ b/crates/brk_computer/src/price.rs @@ -8,7 +8,7 @@ use brk_types::{ }; use vecdb::{BytesVec, Database, EagerVec, Exit, ImportableVec, PAGE_SIZE, PcoVec}; -use crate::{fetched, grouped::Source}; +use crate::{fetched, grouped::Source, utils::OptionExt}; use super::{ Indexes, @@ -74,251 +74,85 @@ impl Vecs { let db = Database::open(&parent.join("price"))?; db.set_min_len(PAGE_SIZE * 1_000_000)?; + let v = version + VERSION; + let v_sats = version + VERSION + VERSION_IN_SATS; + + macro_rules! eager { + ($name:expr) => { EagerVec::forced_import(&db, $name, v)? }; + } + macro_rules! eager_sats { + ($name:expr) => { EagerVec::forced_import(&db, $name, v_sats)? }; + } + macro_rules! computed_di { + ($name:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, v, indexes, $opts)? + }; + } + macro_rules! computed_di_sats { + ($name:expr, $opts:expr) => { + ComputedVecsFromDateIndex::forced_import(&db, $name, Source::Compute, v_sats, indexes, $opts)? + }; + } + macro_rules! computed_h { + ($name:expr, $opts:expr) => { + ComputedVecsFromHeightStrict::forced_import(&db, $name, v, $opts)? + }; + } + macro_rules! computed_h_sats { + ($name:expr, $opts:expr) => { + ComputedVecsFromHeightStrict::forced_import(&db, $name, v_sats, $opts)? + }; + } + let first = || VecBuilderOptions::default().add_first(); + let last = || VecBuilderOptions::default().add_last(); + let min = || VecBuilderOptions::default().add_min(); + let max = || VecBuilderOptions::default().add_max(); + let this = Self { - dateindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - dateindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - dateindex_to_price_close_in_cents: EagerVec::forced_import( - &db, - "price_close_in_cents", - version + VERSION + Version::ZERO, - )?, - dateindex_to_price_high_in_cents: EagerVec::forced_import( - &db, - "price_high_in_cents", - version + VERSION + Version::ZERO, - )?, - dateindex_to_price_low_in_cents: EagerVec::forced_import( - &db, - "price_low_in_cents", - version + VERSION + Version::ZERO, - )?, - dateindex_to_price_open_in_cents: EagerVec::forced_import( - &db, - "price_open_in_cents", - version + VERSION + Version::ZERO, - )?, - height_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - height_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - height_to_price_close_in_cents: EagerVec::forced_import( - &db, - "price_close_in_cents", - version + VERSION + Version::ZERO, - )?, - height_to_price_high_in_cents: EagerVec::forced_import( - &db, - "price_high_in_cents", - version + VERSION + Version::ZERO, - )?, - height_to_price_low_in_cents: EagerVec::forced_import( - &db, - "price_low_in_cents", - version + VERSION + Version::ZERO, - )?, - height_to_price_open_in_cents: EagerVec::forced_import( - &db, - "price_open_in_cents", - version + VERSION + Version::ZERO, - )?, - timeindexes_to_price_open: ComputedVecsFromDateIndex::forced_import( - &db, - "price_open", - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_first(), - )?, - timeindexes_to_price_high: ComputedVecsFromDateIndex::forced_import( - &db, - "price_high", - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_max(), - )?, - timeindexes_to_price_low: ComputedVecsFromDateIndex::forced_import( - &db, - "price_low", - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_min(), - )?, - timeindexes_to_price_close: ComputedVecsFromDateIndex::forced_import( - &db, - "price_close", - Source::Compute, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - timeindexes_to_price_open_in_sats: ComputedVecsFromDateIndex::forced_import( - &db, - "price_open_in_sats", - Source::Compute, - version + VERSION + VERSION_IN_SATS + Version::ZERO, - indexes, - VecBuilderOptions::default().add_first(), - )?, - timeindexes_to_price_high_in_sats: ComputedVecsFromDateIndex::forced_import( - &db, - "price_high_in_sats", - Source::Compute, - version + VERSION + VERSION_IN_SATS + Version::ZERO, - indexes, - VecBuilderOptions::default().add_max(), - )?, - timeindexes_to_price_low_in_sats: ComputedVecsFromDateIndex::forced_import( - &db, - "price_low_in_sats", - Source::Compute, - version + VERSION + VERSION_IN_SATS + Version::ZERO, - indexes, - VecBuilderOptions::default().add_min(), - )?, - timeindexes_to_price_close_in_sats: ComputedVecsFromDateIndex::forced_import( - &db, - "price_close_in_sats", - Source::Compute, - version + VERSION + VERSION_IN_SATS + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - chainindexes_to_price_open: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_open", - version + VERSION + Version::ZERO, - VecBuilderOptions::default().add_first(), - )?, - chainindexes_to_price_high: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_high", - version + VERSION + Version::ZERO, - VecBuilderOptions::default().add_max(), - )?, - chainindexes_to_price_low: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_low", - version + VERSION + Version::ZERO, - VecBuilderOptions::default().add_min(), - )?, - chainindexes_to_price_close: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_close", - version + VERSION + Version::ZERO, - VecBuilderOptions::default().add_last(), - )?, - chainindexes_to_price_open_in_sats: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_open_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - VecBuilderOptions::default().add_first(), - )?, - chainindexes_to_price_high_in_sats: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_high_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - VecBuilderOptions::default().add_max(), - )?, - chainindexes_to_price_low_in_sats: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_low_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - VecBuilderOptions::default().add_min(), - )?, - chainindexes_to_price_close_in_sats: ComputedVecsFromHeightStrict::forced_import( - &db, - "price_close_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - VecBuilderOptions::default().add_last(), - )?, - weekindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - weekindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - difficultyepoch_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - difficultyepoch_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - monthindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - monthindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - quarterindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - quarterindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - semesterindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - semesterindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, - yearindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - yearindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, + dateindex_to_price_ohlc: eager!("price_ohlc"), + dateindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + dateindex_to_price_close_in_cents: eager!("price_close_in_cents"), + dateindex_to_price_high_in_cents: eager!("price_high_in_cents"), + dateindex_to_price_low_in_cents: eager!("price_low_in_cents"), + dateindex_to_price_open_in_cents: eager!("price_open_in_cents"), + height_to_price_ohlc: eager!("price_ohlc"), + height_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + height_to_price_close_in_cents: eager!("price_close_in_cents"), + height_to_price_high_in_cents: eager!("price_high_in_cents"), + height_to_price_low_in_cents: eager!("price_low_in_cents"), + height_to_price_open_in_cents: eager!("price_open_in_cents"), + timeindexes_to_price_open: computed_di!("price_open", first()), + timeindexes_to_price_high: computed_di!("price_high", max()), + timeindexes_to_price_low: computed_di!("price_low", min()), + timeindexes_to_price_close: computed_di!("price_close", last()), + timeindexes_to_price_open_in_sats: computed_di_sats!("price_open_in_sats", first()), + timeindexes_to_price_high_in_sats: computed_di_sats!("price_high_in_sats", max()), + timeindexes_to_price_low_in_sats: computed_di_sats!("price_low_in_sats", min()), + timeindexes_to_price_close_in_sats: computed_di_sats!("price_close_in_sats", last()), + chainindexes_to_price_open: computed_h!("price_open", first()), + chainindexes_to_price_high: computed_h!("price_high", max()), + chainindexes_to_price_low: computed_h!("price_low", min()), + chainindexes_to_price_close: computed_h!("price_close", last()), + chainindexes_to_price_open_in_sats: computed_h_sats!("price_open_in_sats", first()), + chainindexes_to_price_high_in_sats: computed_h_sats!("price_high_in_sats", max()), + chainindexes_to_price_low_in_sats: computed_h_sats!("price_low_in_sats", min()), + chainindexes_to_price_close_in_sats: computed_h_sats!("price_close_in_sats", last()), + weekindex_to_price_ohlc: eager!("price_ohlc"), + weekindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + difficultyepoch_to_price_ohlc: eager!("price_ohlc"), + difficultyepoch_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + monthindex_to_price_ohlc: eager!("price_ohlc"), + monthindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + quarterindex_to_price_ohlc: eager!("price_ohlc"), + quarterindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + semesterindex_to_price_ohlc: eager!("price_ohlc"), + semesterindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), + yearindex_to_price_ohlc: eager!("price_ohlc"), + yearindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), // halvingepoch_to_price_ohlc: StorableVec::forced_import(db, // "halvingepoch_to_price_ohlc"), version + VERSION + Version::ZERO, format)?, - decadeindex_to_price_ohlc: EagerVec::forced_import( - &db, - "price_ohlc", - version + VERSION + Version::ZERO, - )?, - decadeindex_to_price_ohlc_in_sats: EagerVec::forced_import( - &db, - "price_ohlc_in_sats", - version + VERSION + VERSION_IN_SATS + Version::ZERO, - )?, + decadeindex_to_price_ohlc: eager!("price_ohlc"), + decadeindex_to_price_ohlc_in_sats: eager_sats!("price_ohlc_in_sats"), db, }; @@ -706,7 +540,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.timeindexes_to_price_open.dateindex.as_ref().unwrap(), + self.timeindexes_to_price_open.dateindex.u(), |(i, open, ..)| (i, Open::new(Sats::ONE_BTC / *open)), exit, )?; @@ -717,7 +551,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.timeindexes_to_price_low.dateindex.as_ref().unwrap(), + self.timeindexes_to_price_low.dateindex.u(), |(i, low, ..)| (i, High::new(Sats::ONE_BTC / *low)), exit, )?; @@ -728,7 +562,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.timeindexes_to_price_high.dateindex.as_ref().unwrap(), + self.timeindexes_to_price_high.dateindex.u(), |(i, high, ..)| (i, Low::new(Sats::ONE_BTC / *high)), exit, )?; @@ -739,7 +573,7 @@ impl Vecs { .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.timeindexes_to_price_close.dateindex.as_ref().unwrap(), + self.timeindexes_to_price_close.dateindex.u(), |(i, close, ..)| (i, Close::new(Sats::ONE_BTC / *close)), exit, )?; diff --git a/crates/brk_computer/src/stateful/address_cohort.rs b/crates/brk_computer/src/stateful/address_cohort.rs index fa1bed7ca..7c3d12645 100644 --- a/crates/brk_computer/src/stateful/address_cohort.rs +++ b/crates/brk_computer/src/stateful/address_cohort.rs @@ -18,6 +18,7 @@ use crate::{ r#trait::{CohortVecs, DynCohortVecs}, }, states::AddressCohortState, + utils::OptionExt, }; const VERSION: Version = Version::ZERO; @@ -37,7 +38,6 @@ pub struct Vecs { } impl Vecs { - #[allow(clippy::too_many_arguments)] pub fn forced_import( db: &Database, filter: Filter, @@ -45,7 +45,6 @@ impl Vecs { indexes: &indexes::Vecs, price: Option<&price::Vecs>, states_path: Option<&Path>, - compute_rel_to_all: bool, ) -> Result { let compute_dollars = price.is_some(); @@ -83,9 +82,6 @@ impl Vecs { version, indexes, price, - false, - compute_rel_to_all, - false, )?, }) } @@ -106,12 +102,12 @@ impl DynCohortVecs for Vecs { fn import_state(&mut self, starting_height: Height) -> Result { let starting_height = self .inner - .import_state(starting_height, &mut self.state.as_mut().unwrap().inner)?; + .import_state(starting_height, &mut self.state.um().inner)?; self.starting_height = Some(starting_height); if let Some(prev_height) = starting_height.decremented() { - self.state.as_mut().unwrap().addr_count = *self + self.state.um().addr_count = *self .height_to_addr_count .into_iter() .get_unwrap(prev_height); @@ -135,10 +131,10 @@ impl DynCohortVecs for Vecs { } self.height_to_addr_count - .truncate_push(height, self.state.as_ref().unwrap().addr_count.into())?; + .truncate_push(height, self.state.u().addr_count.into())?; self.inner - .truncate_push(height, &self.state.as_ref().unwrap().inner) + .truncate_push(height, &self.state.u().inner) } fn compute_then_truncate_push_unrealized_states( @@ -153,7 +149,7 @@ impl DynCohortVecs for Vecs { height_price, dateindex, date_price, - &self.state.as_ref().unwrap().inner, + &self.state.u().inner, ) } @@ -161,7 +157,7 @@ impl DynCohortVecs for Vecs { self.height_to_addr_count.safe_flush(exit)?; self.inner - .safe_flush_stateful_vecs(height, exit, &mut self.state.as_mut().unwrap().inner) + .safe_flush_stateful_vecs(height, exit, &mut self.state.um().inner) } #[allow(clippy::too_many_arguments)] diff --git a/crates/brk_computer/src/stateful/address_cohorts.rs b/crates/brk_computer/src/stateful/address_cohorts.rs index 6635d372a..fd814ba05 100644 --- a/crates/brk_computer/src/stateful/address_cohorts.rs +++ b/crates/brk_computer/src/stateful/address_cohorts.rs @@ -41,7 +41,6 @@ impl Vecs { indexes, price, states_path, - true, ) .unwrap() }))) diff --git a/crates/brk_computer/src/stateful/address_indexes.rs b/crates/brk_computer/src/stateful/address_indexes.rs new file mode 100644 index 000000000..1206c9f67 --- /dev/null +++ b/crates/brk_computer/src/stateful/address_indexes.rs @@ -0,0 +1,184 @@ +use brk_error::Result; +use brk_traversable::Traversable; +use brk_types::{ + AnyAddressIndex, EmptyAddressData, EmptyAddressIndex, Height, LoadedAddressData, + LoadedAddressIndex, OutputType, P2AAddressIndex, P2PK33AddressIndex, P2PK65AddressIndex, + P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex, P2WPKHAddressIndex, P2WSHAddressIndex, + TypeIndex, +}; +use vecdb::{AnyStoredVec, BytesVec, GenericStoredVec, Reader, Stamp}; + +#[derive(Clone, Traversable)] +pub struct AnyAddressIndexesVecs { + pub p2pk33: BytesVec, + pub p2pk65: BytesVec, + pub p2pkh: BytesVec, + pub p2sh: BytesVec, + pub p2tr: BytesVec, + pub p2wpkh: BytesVec, + pub p2wsh: BytesVec, + pub p2a: BytesVec, +} + +impl AnyAddressIndexesVecs { + pub fn min_stamped_height(&self) -> Height { + Height::from(self.p2pk33.stamp()) + .incremented() + .min(Height::from(self.p2pk65.stamp()).incremented()) + .min(Height::from(self.p2pkh.stamp()).incremented()) + .min(Height::from(self.p2sh.stamp()).incremented()) + .min(Height::from(self.p2tr.stamp()).incremented()) + .min(Height::from(self.p2wpkh.stamp()).incremented()) + .min(Height::from(self.p2wsh.stamp()).incremented()) + .min(Height::from(self.p2a.stamp()).incremented()) + } + + pub fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 8]> { + Ok([ + self.p2pk33.rollback_before(stamp)?, + self.p2pk65.rollback_before(stamp)?, + self.p2pkh.rollback_before(stamp)?, + self.p2sh.rollback_before(stamp)?, + self.p2tr.rollback_before(stamp)?, + self.p2wpkh.rollback_before(stamp)?, + self.p2wsh.rollback_before(stamp)?, + self.p2a.rollback_before(stamp)?, + ]) + } + + pub fn reset(&mut self) -> Result<()> { + self.p2pk33.reset()?; + self.p2pk65.reset()?; + self.p2pkh.reset()?; + self.p2sh.reset()?; + self.p2tr.reset()?; + self.p2wpkh.reset()?; + self.p2wsh.reset()?; + self.p2a.reset()?; + Ok(()) + } + + pub fn get_anyaddressindex( + &self, + address_type: OutputType, + typeindex: TypeIndex, + reader: &Reader, + ) -> AnyAddressIndex { + match address_type { + OutputType::P2PK33 => self + .p2pk33 + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2PK65 => self + .p2pk65 + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2PKH => self + .p2pkh + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2SH => self + .p2sh + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2TR => self + .p2tr + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2WPKH => self + .p2wpkh + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2WSH => self + .p2wsh + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + OutputType::P2A => self + .p2a + .get_pushed_or_read_at_unwrap(typeindex.into(), reader), + _ => unreachable!(), + } + } + + pub fn update_or_push( + &mut self, + address_type: OutputType, + typeindex: TypeIndex, + anyaddressindex: AnyAddressIndex, + ) -> Result<()> { + (match address_type { + OutputType::P2PK33 => self + .p2pk33 + .update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2PK65 => self + .p2pk65 + .update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2PKH => self.p2pkh.update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2SH => self.p2sh.update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2TR => self.p2tr.update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2WPKH => self + .p2wpkh + .update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2WSH => self.p2wsh.update_or_push(typeindex.into(), anyaddressindex), + OutputType::P2A => self.p2a.update_or_push(typeindex.into(), anyaddressindex), + _ => unreachable!(), + })?; + Ok(()) + } + + pub fn stamped_flush_maybe_with_changes( + &mut self, + stamp: Stamp, + with_changes: bool, + ) -> Result<()> { + self.p2pk33 + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2pk65 + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2pkh + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2sh + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2tr + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2wpkh + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2wsh + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.p2a + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + Ok(()) + } +} + +#[derive(Clone, Traversable)] +pub struct AddressesDataVecs { + pub loaded: BytesVec, + pub empty: BytesVec, +} + +impl AddressesDataVecs { + pub fn min_stamped_height(&self) -> Height { + Height::from(self.loaded.stamp()) + .incremented() + .min(Height::from(self.empty.stamp()).incremented()) + } + + pub fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 2]> { + Ok([ + self.loaded.rollback_before(stamp)?, + self.empty.rollback_before(stamp)?, + ]) + } + + pub fn reset(&mut self) -> Result<()> { + self.loaded.reset()?; + self.empty.reset()?; + Ok(()) + } + + pub fn stamped_flush_maybe_with_changes( + &mut self, + stamp: Stamp, + with_changes: bool, + ) -> Result<()> { + self.loaded + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + self.empty + .stamped_flush_maybe_with_changes(stamp, with_changes)?; + Ok(()) + } +} diff --git a/crates/brk_computer/src/stateful/common.rs b/crates/brk_computer/src/stateful/common.rs index 62f7586df..ccf676f3b 100644 --- a/crates/brk_computer/src/stateful/common.rs +++ b/crates/brk_computer/src/stateful/common.rs @@ -18,6 +18,7 @@ use crate::{ }, indexes, price, states::CohortState, + utils::OptionExt, }; #[derive(Clone, Traversable)] @@ -176,11 +177,11 @@ impl Vecs { parent_version: Version, indexes: &indexes::Vecs, price: Option<&price::Vecs>, - extended: bool, - compute_rel_to_all: bool, - compute_adjusted: bool, ) -> Result { let compute_dollars = price.is_some(); + let extended = filter.is_extended(context); + let compute_rel_to_all = filter.compute_rel_to_all(); + let compute_adjusted = filter.compute_adjusted(context); let version = parent_version + Version::ZERO; @@ -193,796 +194,222 @@ impl Vecs { } }; - let dateindex_to_supply_in_profit = compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("supply_in_profit"), version + Version::ZERO) - .unwrap() - }); + // Helper macros for imports + macro_rules! eager { + ($idx:ty, $val:ty, $name:expr, $v:expr) => { + EagerVec::>::forced_import(db, &suffix($name), version + $v).unwrap() + }; + } + macro_rules! computed_h { + ($name:expr, $source:expr, $v:expr, $opts:expr $(,)?) => { + ComputedVecsFromHeight::forced_import(db, &suffix($name), $source, version + $v, indexes, $opts).unwrap() + }; + } + macro_rules! computed_di { + ($name:expr, $source:expr, $v:expr, $opts:expr $(,)?) => { + ComputedVecsFromDateIndex::forced_import(db, &suffix($name), $source, version + $v, indexes, $opts).unwrap() + }; + } - let dateindex_to_supply_in_loss = compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("supply_in_loss"), version + Version::ZERO).unwrap() - }); + // Common option patterns + let v0 = Version::ZERO; + let v1 = Version::ONE; + let v2 = Version::TWO; + let v3 = Version::new(3); + let last = || VecBuilderOptions::default().add_last(); + let sum = || VecBuilderOptions::default().add_sum(); + let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative(); - let dateindex_to_unrealized_profit = compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("unrealized_profit"), version + Version::ZERO) - .unwrap() - }); - - let dateindex_to_unrealized_loss = compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("unrealized_loss"), version + Version::ZERO) - .unwrap() - }); + // Pre-create dateindex vecs that are used in computed vecs + let dateindex_to_supply_in_profit = + compute_dollars.then(|| eager!(DateIndex, Sats,"supply_in_profit", v0)); + let dateindex_to_supply_in_loss = compute_dollars.then(|| eager!(DateIndex, Sats,"supply_in_loss", v0)); + let dateindex_to_unrealized_profit = + compute_dollars.then(|| eager!(DateIndex, Dollars,"unrealized_profit", v0)); + let dateindex_to_unrealized_loss = + compute_dollars.then(|| eager!(DateIndex, Dollars,"unrealized_loss", v0)); Ok(Self { filter, - height_to_supply_in_profit: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("supply_in_profit"), version + Version::ZERO) - .unwrap() - }), - indexes_to_supply_in_profit: compute_dollars.then(|| { - ComputedValueVecsFromDateIndex::forced_import( - db, - &suffix("supply_in_profit"), - dateindex_to_supply_in_profit - .as_ref() - .map(|v| v.boxed_clone()) - .into(), - version + Version::ZERO, - VecBuilderOptions::default().add_last(), - compute_dollars, - indexes, - ) - .unwrap() - }), - dateindex_to_supply_in_profit, - height_to_supply_in_loss: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("supply_in_loss"), version + Version::ZERO) - .unwrap() - }), - indexes_to_supply_in_loss: compute_dollars.then(|| { - ComputedValueVecsFromDateIndex::forced_import( - db, - &suffix("supply_in_loss"), - dateindex_to_supply_in_loss - .as_ref() - .map(|v| v.boxed_clone()) - .into(), - version + Version::ZERO, - VecBuilderOptions::default().add_last(), - compute_dollars, - indexes, - ) - .unwrap() - }), - dateindex_to_supply_in_loss, - height_to_unrealized_profit: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("unrealized_profit"), version + Version::ZERO) - .unwrap() - }), - indexes_to_unrealized_profit: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_profit"), - dateindex_to_unrealized_profit - .as_ref() - .map(|v| v.boxed_clone()) - .into(), - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - dateindex_to_unrealized_profit, - height_to_unrealized_loss: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("unrealized_loss"), version + Version::ZERO) - .unwrap() - }), - height_to_min_price_paid: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("min_price_paid"), version + Version::ZERO) - .unwrap() - }), - height_to_max_price_paid: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("max_price_paid"), version + Version::ZERO) - .unwrap() - }), - indexes_to_unrealized_loss: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_loss"), - dateindex_to_unrealized_loss - .as_ref() - .map(|v| v.boxed_clone()) - .into(), - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_total_unrealized_pnl: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("total_unrealized_pnl"), - version + Version::ZERO, - ) - .unwrap() - }), - indexes_to_total_unrealized_pnl: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("total_unrealized_pnl"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_total_realized_pnl: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("total_realized_pnl"), version + Version::ZERO) - .unwrap() - }), - indexes_to_total_realized_pnl: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("total_realized_pnl"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - dateindex_to_unrealized_loss, - height_to_realized_cap: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("realized_cap"), version + Version::ZERO) - .unwrap() - }), - indexes_to_realized_cap: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_cap"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_min_price_paid: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("min_price_paid"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_max_price_paid: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("max_price_paid"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - price_percentiles: (compute_dollars && extended).then(|| { - PricePercentiles::forced_import( - db, - &suffix(""), - version + Version::ZERO, - indexes, - true, - ) - .unwrap() - }), - height_to_supply: EagerVec::forced_import( - db, - &suffix("supply"), - version + Version::ZERO, - )?, + // Supply & UTXO count (always computed) + height_to_supply: EagerVec::forced_import(db, &suffix("supply"), version + v0)?, height_to_supply_value: ComputedHeightValueVecs::forced_import( db, &suffix("supply"), Source::None, - version + Version::ZERO, + version + v0, compute_dollars, )?, indexes_to_supply: ComputedValueVecsFromDateIndex::forced_import( db, &suffix("supply"), Source::Compute, - version + Version::ONE, - VecBuilderOptions::default().add_last(), + version + v1, + last(), compute_dollars, indexes, )?, - height_to_utxo_count: EagerVec::forced_import( - db, - &suffix("utxo_count"), - version + Version::ZERO, - )?, - indexes_to_utxo_count: ComputedVecsFromHeight::forced_import( - db, - &suffix("utxo_count"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - indexes_to_realized_price: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_price"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_realized_price_extra: compute_dollars.then(|| { - ComputedRatioVecsFromDateIndex::forced_import( - db, - &suffix("realized_price"), - Source::None, - version + Version::ZERO, - indexes, - extended, - ) - .unwrap() - }), - indexes_to_realized_cap_rel_to_own_market_cap: (compute_dollars && extended).then( - || { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_cap_rel_to_own_market_cap"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }, - ), - height_to_realized_profit: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("realized_profit"), version + Version::ZERO) - .unwrap() - }), - indexes_to_realized_profit: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_profit"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - ) - .unwrap() - }), - height_to_realized_loss: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("realized_loss"), version + Version::ZERO) - .unwrap() - }), - indexes_to_realized_loss: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_loss"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - ) - .unwrap() - }), - indexes_to_neg_realized_loss: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("neg_realized_loss"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - ) - .unwrap() - }), - height_to_value_created: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("value_created"), version + Version::ZERO) - .unwrap() - }), - indexes_to_value_created: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("value_created"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - indexes_to_realized_value: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_value"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - height_to_adjusted_value_created: (compute_dollars && compute_adjusted).then(|| { - EagerVec::forced_import( - db, - &suffix("adjusted_value_created"), - version + Version::ZERO, - ) - .unwrap() - }), - indexes_to_adjusted_value_created: (compute_dollars && compute_adjusted).then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("adjusted_value_created"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - height_to_value_destroyed: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("value_destroyed"), version + Version::ZERO) - .unwrap() - }), - indexes_to_value_destroyed: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("value_destroyed"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - height_to_adjusted_value_destroyed: (compute_dollars && compute_adjusted).then(|| { - EagerVec::forced_import( - db, - &suffix("adjusted_value_destroyed"), - version + Version::ZERO, - ) - .unwrap() - }), - indexes_to_adjusted_value_destroyed: (compute_dollars && compute_adjusted).then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("adjusted_value_destroyed"), - Source::None, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - indexes_to_realized_cap_30d_delta: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("realized_cap_30d_delta"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_net_realized_pnl: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("net_realized_pnl"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - ) - .unwrap() - }), - dateindex_to_sell_side_risk_ratio: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("sell_side_risk_ratio"), version + Version::ONE) - .unwrap() - }), - dateindex_to_sell_side_risk_ratio_7d_ema: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("sell_side_risk_ratio_7d_ema"), - version + Version::ONE, - ) - .unwrap() - }), - dateindex_to_sell_side_risk_ratio_30d_ema: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("sell_side_risk_ratio_30d_ema"), - version + Version::ONE, - ) - .unwrap() - }), - dateindex_to_sopr: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("sopr"), version + Version::ONE).unwrap() - }), - dateindex_to_sopr_7d_ema: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("sopr_7d_ema"), version + Version::ONE).unwrap() - }), - dateindex_to_sopr_30d_ema: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("sopr_30d_ema"), version + Version::ONE) - .unwrap() - }), - dateindex_to_adjusted_sopr: (compute_dollars && compute_adjusted).then(|| { - EagerVec::forced_import(db, &suffix("adjusted_sopr"), version + Version::ONE) - .unwrap() - }), - dateindex_to_adjusted_sopr_7d_ema: (compute_dollars && compute_adjusted).then(|| { - EagerVec::forced_import(db, &suffix("adjusted_sopr_7d_ema"), version + Version::ONE) - .unwrap() - }), - dateindex_to_adjusted_sopr_30d_ema: (compute_dollars && compute_adjusted).then(|| { - EagerVec::forced_import( - db, - &suffix("adjusted_sopr_30d_ema"), - version + Version::ONE, - ) - .unwrap() - }), + height_to_utxo_count: EagerVec::forced_import(db, &suffix("utxo_count"), version + v0)?, + indexes_to_utxo_count: computed_h!("utxo_count", Source::None, v0, last()), height_to_supply_half_value: ComputedHeightValueVecs::forced_import( db, &suffix("supply_half"), Source::Compute, - version + Version::ZERO, + version + v0, compute_dollars, )?, indexes_to_supply_half: ComputedValueVecsFromDateIndex::forced_import( db, &suffix("supply_half"), Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_last(), + version + v0, + last(), compute_dollars, indexes, )?, - height_to_neg_unrealized_loss: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("neg_unrealized_loss"), version + Version::ZERO) - .unwrap() - }), - indexes_to_neg_unrealized_loss: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( + + // Sent & destroyed (always computed) + height_to_sent: EagerVec::forced_import(db, &suffix("sent"), version + v0)?, + height_to_satblocks_destroyed: EagerVec::forced_import( + db, + &suffix("satblocks_destroyed"), + version + v0, + )?, + height_to_satdays_destroyed: EagerVec::forced_import( + db, + &suffix("satdays_destroyed"), + version + v0, + )?, + indexes_to_sent: ComputedValueVecsFromHeight::forced_import( + db, + &suffix("sent"), + Source::Compute, + version + v0, + sum(), + compute_dollars, + indexes, + )?, + indexes_to_coinblocks_destroyed: computed_h!( + "coinblocks_destroyed", + Source::Compute, + v2, + sum_cum(), + ), + indexes_to_coindays_destroyed: computed_h!( + "coindays_destroyed", + Source::Compute, + v2, + sum_cum(), + ), + + // Realized cap & related (conditional on compute_dollars) + height_to_realized_cap: compute_dollars.then(|| eager!(Height, Dollars,"realized_cap", v0)), + indexes_to_realized_cap: compute_dollars + .then(|| computed_h!("realized_cap", Source::None, v0, last())), + indexes_to_realized_price: compute_dollars + .then(|| computed_h!("realized_price", Source::Compute, v0, last())), + indexes_to_realized_price_extra: compute_dollars.then(|| { + ComputedRatioVecsFromDateIndex::forced_import( db, - &suffix("neg_unrealized_loss"), - Source::Compute, - version + Version::ZERO, + &suffix("realized_price"), + Source::None, + version + v0, indexes, - VecBuilderOptions::default().add_last(), + extended, ) .unwrap() }), - height_to_net_unrealized_pnl: compute_dollars.then(|| { - EagerVec::forced_import(db, &suffix("net_unrealized_pnl"), version + Version::ZERO) - .unwrap() + indexes_to_realized_cap_rel_to_own_market_cap: (compute_dollars && extended).then(|| { + computed_h!("realized_cap_rel_to_own_market_cap", Source::Compute, v0, last()) }), - indexes_to_net_unrealized_pnl: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( + indexes_to_realized_cap_30d_delta: compute_dollars + .then(|| computed_di!("realized_cap_30d_delta", Source::Compute, v0, last())), + + // Realized profit & loss + height_to_realized_profit: compute_dollars.then(|| eager!(Height, Dollars,"realized_profit", v0)), + indexes_to_realized_profit: compute_dollars + .then(|| computed_h!("realized_profit", Source::None, v0, sum_cum())), + height_to_realized_loss: compute_dollars.then(|| eager!(Height, Dollars,"realized_loss", v0)), + indexes_to_realized_loss: compute_dollars + .then(|| computed_h!("realized_loss", Source::None, v0, sum_cum())), + indexes_to_neg_realized_loss: compute_dollars + .then(|| computed_h!("neg_realized_loss", Source::Compute, v1, sum_cum())), + indexes_to_net_realized_pnl: compute_dollars + .then(|| computed_h!("net_realized_pnl", Source::Compute, v0, sum_cum())), + indexes_to_realized_value: compute_dollars + .then(|| computed_h!("realized_value", Source::Compute, v0, sum())), + indexes_to_realized_profit_rel_to_realized_cap: compute_dollars + .then(|| computed_h!("realized_profit_rel_to_realized_cap", Source::Compute, v0, sum())), + indexes_to_realized_loss_rel_to_realized_cap: compute_dollars + .then(|| computed_h!("realized_loss_rel_to_realized_cap", Source::Compute, v0, sum())), + indexes_to_net_realized_pnl_rel_to_realized_cap: compute_dollars + .then(|| computed_h!("net_realized_pnl_rel_to_realized_cap", Source::Compute, v1, sum())), + height_to_total_realized_pnl: compute_dollars.then(|| eager!(Height, Dollars,"total_realized_pnl", v0)), + indexes_to_total_realized_pnl: compute_dollars + .then(|| computed_di!("total_realized_pnl", Source::Compute, v1, sum())), + dateindex_to_realized_profit_to_loss_ratio: (compute_dollars && extended) + .then(|| eager!(DateIndex, StoredF64,"realized_profit_to_loss_ratio", v1)), + + // Value created & destroyed + height_to_value_created: compute_dollars.then(|| eager!(Height, Dollars,"value_created", v0)), + indexes_to_value_created: compute_dollars + .then(|| computed_h!("value_created", Source::None, v0, sum())), + height_to_value_destroyed: compute_dollars.then(|| eager!(Height, Dollars,"value_destroyed", v0)), + indexes_to_value_destroyed: compute_dollars + .then(|| computed_h!("value_destroyed", Source::None, v0, sum())), + height_to_adjusted_value_created: (compute_dollars && compute_adjusted) + .then(|| eager!(Height, Dollars,"adjusted_value_created", v0)), + indexes_to_adjusted_value_created: (compute_dollars && compute_adjusted) + .then(|| computed_h!("adjusted_value_created", Source::None, v0, sum())), + height_to_adjusted_value_destroyed: (compute_dollars && compute_adjusted) + .then(|| eager!(Height, Dollars,"adjusted_value_destroyed", v0)), + indexes_to_adjusted_value_destroyed: (compute_dollars && compute_adjusted) + .then(|| computed_h!("adjusted_value_destroyed", Source::None, v0, sum())), + + // SOPR + dateindex_to_sopr: compute_dollars.then(|| eager!(DateIndex, StoredF64,"sopr", v1)), + dateindex_to_sopr_7d_ema: compute_dollars.then(|| eager!(DateIndex, StoredF64,"sopr_7d_ema", v1)), + dateindex_to_sopr_30d_ema: compute_dollars.then(|| eager!(DateIndex, StoredF64,"sopr_30d_ema", v1)), + dateindex_to_adjusted_sopr: (compute_dollars && compute_adjusted) + .then(|| eager!(DateIndex, StoredF64,"adjusted_sopr", v1)), + dateindex_to_adjusted_sopr_7d_ema: (compute_dollars && compute_adjusted) + .then(|| eager!(DateIndex, StoredF64,"adjusted_sopr_7d_ema", v1)), + dateindex_to_adjusted_sopr_30d_ema: (compute_dollars && compute_adjusted) + .then(|| eager!(DateIndex, StoredF64,"adjusted_sopr_30d_ema", v1)), + + // Sell side risk ratio + dateindex_to_sell_side_risk_ratio: compute_dollars + .then(|| eager!(DateIndex, StoredF32,"sell_side_risk_ratio", v1)), + dateindex_to_sell_side_risk_ratio_7d_ema: compute_dollars + .then(|| eager!(DateIndex, StoredF32,"sell_side_risk_ratio_7d_ema", v1)), + dateindex_to_sell_side_risk_ratio_30d_ema: compute_dollars + .then(|| eager!(DateIndex, StoredF32,"sell_side_risk_ratio_30d_ema", v1)), + + // Supply in profit/loss + height_to_supply_in_profit: compute_dollars.then(|| eager!(Height, Sats,"supply_in_profit", v0)), + indexes_to_supply_in_profit: compute_dollars.then(|| { + ComputedValueVecsFromDateIndex::forced_import( db, - &suffix("net_unrealized_pnl"), - Source::Compute, - version + Version::ZERO, + &suffix("supply_in_profit"), + dateindex_to_supply_in_profit.as_ref().map(|v| v.boxed_clone()).into(), + version + v0, + last(), + compute_dollars, indexes, - VecBuilderOptions::default().add_last(), ) .unwrap() }), - height_to_unrealized_profit_rel_to_market_cap: compute_dollars.then(|| { - EagerVec::forced_import( + height_to_supply_in_loss: compute_dollars.then(|| eager!(Height, Sats,"supply_in_loss", v0)), + indexes_to_supply_in_loss: compute_dollars.then(|| { + ComputedValueVecsFromDateIndex::forced_import( db, - &suffix("unrealized_profit_rel_to_market_cap"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_unrealized_loss_rel_to_market_cap: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("unrealized_loss_rel_to_market_cap"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_neg_unrealized_loss_rel_to_market_cap: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_market_cap"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_net_unrealized_pnl_rel_to_market_cap: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_market_cap"), - version + Version::ONE, - ) - .unwrap() - }), - indexes_to_unrealized_profit_rel_to_market_cap: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_profit_rel_to_market_cap"), - Source::Compute, - version + Version::ONE, + &suffix("supply_in_loss"), + dateindex_to_supply_in_loss.as_ref().map(|v| v.boxed_clone()).into(), + version + v0, + last(), + compute_dollars, indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_unrealized_loss_rel_to_market_cap: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_loss_rel_to_market_cap"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_neg_unrealized_loss_rel_to_market_cap: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_market_cap"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_net_unrealized_pnl_rel_to_market_cap: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_market_cap"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_unrealized_profit_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - EagerVec::forced_import( - db, - &suffix("unrealized_profit_rel_to_own_market_cap"), - version + Version::ONE, - ) - .unwrap() - }), - height_to_unrealized_loss_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - EagerVec::forced_import( - db, - &suffix("unrealized_loss_rel_to_own_market_cap"), - version + Version::ONE, - ) - .unwrap() - }), - height_to_neg_unrealized_loss_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - EagerVec::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_own_market_cap"), - version + Version::ONE, - ) - .unwrap() - }), - height_to_net_unrealized_pnl_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - EagerVec::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_own_market_cap"), - version + Version::TWO, - ) - .unwrap() - }), - indexes_to_unrealized_profit_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_profit_rel_to_own_market_cap"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_unrealized_loss_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_loss_rel_to_own_market_cap"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_neg_unrealized_loss_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_own_market_cap"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_net_unrealized_pnl_rel_to_own_market_cap: (compute_dollars - && extended - && compute_rel_to_all) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_own_market_cap"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - EagerVec::forced_import( - db, - &suffix("unrealized_profit_rel_to_own_total_unrealized_pnl"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - EagerVec::forced_import( - db, - &suffix("unrealized_loss_rel_to_own_total_unrealized_pnl"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - EagerVec::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), - version + Version::ZERO, - ) - .unwrap() - }), - height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - EagerVec::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), - version + Version::ONE, - ) - .unwrap() - }), - indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_profit_rel_to_own_total_unrealized_pnl"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("unrealized_loss_rel_to_own_total_unrealized_pnl"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("neg_unrealized_loss_rel_to_own_total_unrealized_pnl"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars - && extended) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_unrealized_pnl_rel_to_own_total_unrealized_pnl"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_realized_profit_rel_to_realized_cap: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_profit_rel_to_realized_cap"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - indexes_to_realized_loss_rel_to_realized_cap: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("realized_loss_rel_to_realized_cap"), - Source::Compute, - version + Version::ZERO, - indexes, - VecBuilderOptions::default().add_sum(), - ) - .unwrap() - }), - indexes_to_net_realized_pnl_rel_to_realized_cap: compute_dollars.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("net_realized_pnl_rel_to_realized_cap"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_sum(), ) .unwrap() }), @@ -991,7 +418,7 @@ impl Vecs { db, &suffix("supply_in_loss"), Source::None, - version + Version::ZERO, + version + v0, compute_dollars, ) .unwrap() @@ -1001,189 +428,141 @@ impl Vecs { db, &suffix("supply_in_profit"), Source::None, - version + Version::ZERO, + version + v0, compute_dollars, ) .unwrap() }), - height_to_supply_in_loss_rel_to_own_supply: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("supply_in_loss_rel_to_own_supply"), - version + Version::ONE, - ) - .unwrap() - }), - height_to_supply_in_profit_rel_to_own_supply: compute_dollars.then(|| { - EagerVec::forced_import( - db, - &suffix("supply_in_profit_rel_to_own_supply"), - version + Version::ONE, - ) - .unwrap() - }), - indexes_to_supply_in_loss_rel_to_own_supply: compute_dollars.then(|| { + height_to_supply_in_loss_rel_to_own_supply: compute_dollars + .then(|| eager!(Height, StoredF64,"supply_in_loss_rel_to_own_supply", v1)), + height_to_supply_in_profit_rel_to_own_supply: compute_dollars + .then(|| eager!(Height, StoredF64,"supply_in_profit_rel_to_own_supply", v1)), + indexes_to_supply_in_loss_rel_to_own_supply: compute_dollars + .then(|| computed_di!("supply_in_loss_rel_to_own_supply", Source::Compute, v1, last())), + indexes_to_supply_in_profit_rel_to_own_supply: compute_dollars + .then(|| computed_di!("supply_in_profit_rel_to_own_supply", Source::Compute, v1, last())), + indexes_to_supply_rel_to_circulating_supply: compute_rel_to_all + .then(|| computed_h!("supply_rel_to_circulating_supply", Source::Compute, v1, last())), + height_to_supply_in_loss_rel_to_circulating_supply: (compute_rel_to_all && compute_dollars) + .then(|| eager!(Height, StoredF64,"supply_in_loss_rel_to_circulating_supply", v1)), + height_to_supply_in_profit_rel_to_circulating_supply: (compute_rel_to_all && compute_dollars) + .then(|| eager!(Height, StoredF64,"supply_in_profit_rel_to_circulating_supply", v1)), + indexes_to_supply_in_loss_rel_to_circulating_supply: (compute_rel_to_all && compute_dollars) + .then(|| computed_di!("supply_in_loss_rel_to_circulating_supply", Source::Compute, v1, last())), + indexes_to_supply_in_profit_rel_to_circulating_supply: (compute_rel_to_all && compute_dollars) + .then(|| computed_di!("supply_in_profit_rel_to_circulating_supply", Source::Compute, v1, last())), + dateindex_to_supply_in_profit, + dateindex_to_supply_in_loss, + + // Unrealized profit/loss + height_to_unrealized_profit: compute_dollars.then(|| eager!(Height, Dollars,"unrealized_profit", v0)), + indexes_to_unrealized_profit: compute_dollars.then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("supply_in_loss_rel_to_own_supply"), - Source::Compute, - version + Version::ONE, + &suffix("unrealized_profit"), + dateindex_to_unrealized_profit.as_ref().map(|v| v.boxed_clone()).into(), + version + v0, indexes, - VecBuilderOptions::default().add_last(), + last(), ) .unwrap() }), - indexes_to_supply_in_profit_rel_to_own_supply: compute_dollars.then(|| { + height_to_unrealized_loss: compute_dollars.then(|| eager!(Height, Dollars,"unrealized_loss", v0)), + indexes_to_unrealized_loss: compute_dollars.then(|| { ComputedVecsFromDateIndex::forced_import( db, - &suffix("supply_in_profit_rel_to_own_supply"), - Source::Compute, - version + Version::ONE, + &suffix("unrealized_loss"), + dateindex_to_unrealized_loss.as_ref().map(|v| v.boxed_clone()).into(), + version + v0, indexes, - VecBuilderOptions::default().add_last(), + last(), ) .unwrap() }), - indexes_to_supply_rel_to_circulating_supply: compute_rel_to_all.then(|| { - ComputedVecsFromHeight::forced_import( - db, - &suffix("supply_rel_to_circulating_supply"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_supply_in_loss_rel_to_circulating_supply: (compute_rel_to_all - && compute_dollars) - .then(|| { - EagerVec::forced_import( - db, - &suffix("supply_in_loss_rel_to_circulating_supply"), - version + Version::ONE, - ) - .unwrap() - }), - height_to_supply_in_profit_rel_to_circulating_supply: (compute_rel_to_all - && compute_dollars) - .then(|| { - EagerVec::forced_import( - db, - &suffix("supply_in_profit_rel_to_circulating_supply"), - version + Version::ONE, - ) - .unwrap() - }), - indexes_to_supply_in_loss_rel_to_circulating_supply: (compute_rel_to_all - && compute_dollars) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("supply_in_loss_rel_to_circulating_supply"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - indexes_to_supply_in_profit_rel_to_circulating_supply: (compute_rel_to_all - && compute_dollars) - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("supply_in_profit_rel_to_circulating_supply"), - Source::Compute, - version + Version::ONE, - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - height_to_sent: EagerVec::forced_import( - db, - &suffix("sent"), - version + Version::ZERO, - )?, - height_to_satblocks_destroyed: EagerVec::forced_import( - db, - &suffix("satblocks_destroyed"), - version + Version::ZERO, - )?, - height_to_satdays_destroyed: EagerVec::forced_import( - db, - &suffix("satdays_destroyed"), - version + Version::ZERO, - )?, - indexes_to_sent: ComputedValueVecsFromHeight::forced_import( - db, - &suffix("sent"), - Source::Compute, - version + Version::ZERO, - VecBuilderOptions::default().add_sum(), - compute_dollars, - indexes, - )?, - indexes_to_coinblocks_destroyed: ComputedVecsFromHeight::forced_import( - db, - &suffix("coinblocks_destroyed"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_coindays_destroyed: ComputedVecsFromHeight::forced_import( - db, - &suffix("coindays_destroyed"), - Source::Compute, - version + Version::TWO, - indexes, - VecBuilderOptions::default().add_sum().add_cumulative(), - )?, - indexes_to_net_realized_pnl_cumulative_30d_delta: compute_dollars.then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_realized_pnl_cumulative_30d_delta"), - Source::Compute, - version + Version::new(3), - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() + dateindex_to_unrealized_profit, + dateindex_to_unrealized_loss, + height_to_total_unrealized_pnl: compute_dollars.then(|| eager!(Height, Dollars,"total_unrealized_pnl", v0)), + indexes_to_total_unrealized_pnl: compute_dollars + .then(|| computed_di!("total_unrealized_pnl", Source::Compute, v0, last())), + height_to_neg_unrealized_loss: compute_dollars.then(|| eager!(Height, Dollars,"neg_unrealized_loss", v0)), + indexes_to_neg_unrealized_loss: compute_dollars + .then(|| computed_di!("neg_unrealized_loss", Source::Compute, v0, last())), + height_to_net_unrealized_pnl: compute_dollars.then(|| eager!(Height, Dollars,"net_unrealized_pnl", v0)), + indexes_to_net_unrealized_pnl: compute_dollars + .then(|| computed_di!("net_unrealized_pnl", Source::Compute, v0, last())), + + // Unrealized rel to market cap + height_to_unrealized_profit_rel_to_market_cap: compute_dollars + .then(|| eager!(Height, StoredF32,"unrealized_profit_rel_to_market_cap", v0)), + height_to_unrealized_loss_rel_to_market_cap: compute_dollars + .then(|| eager!(Height, StoredF32,"unrealized_loss_rel_to_market_cap", v0)), + height_to_neg_unrealized_loss_rel_to_market_cap: compute_dollars + .then(|| eager!(Height, StoredF32,"neg_unrealized_loss_rel_to_market_cap", v0)), + height_to_net_unrealized_pnl_rel_to_market_cap: compute_dollars + .then(|| eager!(Height, StoredF32,"net_unrealized_pnl_rel_to_market_cap", v1)), + indexes_to_unrealized_profit_rel_to_market_cap: compute_dollars + .then(|| computed_di!("unrealized_profit_rel_to_market_cap", Source::Compute, v1, last())), + indexes_to_unrealized_loss_rel_to_market_cap: compute_dollars + .then(|| computed_di!("unrealized_loss_rel_to_market_cap", Source::Compute, v1, last())), + indexes_to_neg_unrealized_loss_rel_to_market_cap: compute_dollars + .then(|| computed_di!("neg_unrealized_loss_rel_to_market_cap", Source::Compute, v1, last())), + indexes_to_net_unrealized_pnl_rel_to_market_cap: compute_dollars + .then(|| computed_di!("net_unrealized_pnl_rel_to_market_cap", Source::Compute, v1, last())), + + // Unrealized rel to own market cap + height_to_unrealized_profit_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| eager!(Height, StoredF32,"unrealized_profit_rel_to_own_market_cap", v1)), + height_to_unrealized_loss_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| eager!(Height, StoredF32,"unrealized_loss_rel_to_own_market_cap", v1)), + height_to_neg_unrealized_loss_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| eager!(Height, StoredF32,"neg_unrealized_loss_rel_to_own_market_cap", v1)), + height_to_net_unrealized_pnl_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| eager!(Height, StoredF32,"net_unrealized_pnl_rel_to_own_market_cap", v2)), + indexes_to_unrealized_profit_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| computed_di!("unrealized_profit_rel_to_own_market_cap", Source::Compute, v2, last())), + indexes_to_unrealized_loss_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| computed_di!("unrealized_loss_rel_to_own_market_cap", Source::Compute, v2, last())), + indexes_to_neg_unrealized_loss_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| computed_di!("neg_unrealized_loss_rel_to_own_market_cap", Source::Compute, v2, last())), + indexes_to_net_unrealized_pnl_rel_to_own_market_cap: (compute_dollars && extended && compute_rel_to_all) + .then(|| computed_di!("net_unrealized_pnl_rel_to_own_market_cap", Source::Compute, v2, last())), + + // Unrealized rel to own total unrealized pnl + height_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| eager!(Height, StoredF32,"unrealized_profit_rel_to_own_total_unrealized_pnl", v0)), + height_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| eager!(Height, StoredF32,"unrealized_loss_rel_to_own_total_unrealized_pnl", v0)), + height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| eager!(Height, StoredF32,"neg_unrealized_loss_rel_to_own_total_unrealized_pnl", v0)), + height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| eager!(Height, StoredF32,"net_unrealized_pnl_rel_to_own_total_unrealized_pnl", v1)), + indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| computed_di!("unrealized_profit_rel_to_own_total_unrealized_pnl", Source::Compute, v1, last())), + indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| computed_di!("unrealized_loss_rel_to_own_total_unrealized_pnl", Source::Compute, v1, last())), + indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| computed_di!("neg_unrealized_loss_rel_to_own_total_unrealized_pnl", Source::Compute, v1, last())), + indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl: (compute_dollars && extended) + .then(|| computed_di!("net_unrealized_pnl_rel_to_own_total_unrealized_pnl", Source::Compute, v1, last())), + + // Price paid + height_to_min_price_paid: compute_dollars.then(|| eager!(Height, Dollars,"min_price_paid", v0)), + height_to_max_price_paid: compute_dollars.then(|| eager!(Height, Dollars,"max_price_paid", v0)), + indexes_to_min_price_paid: compute_dollars + .then(|| computed_h!("min_price_paid", Source::None, v0, last())), + indexes_to_max_price_paid: compute_dollars + .then(|| computed_h!("max_price_paid", Source::None, v0, last())), + price_percentiles: (compute_dollars && extended).then(|| { + PricePercentiles::forced_import(db, &suffix(""), version + v0, indexes, true).unwrap() }), + + // Net realized pnl cumulative deltas + indexes_to_net_realized_pnl_cumulative_30d_delta: compute_dollars + .then(|| computed_di!("net_realized_pnl_cumulative_30d_delta", Source::Compute, v3, last())), indexes_to_net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap: compute_dollars - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap"), - Source::Compute, - version + Version::new(3), - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), + .then(|| computed_di!("net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap", Source::Compute, v3, last())), indexes_to_net_realized_pnl_cumulative_30d_delta_rel_to_market_cap: compute_dollars - .then(|| { - ComputedVecsFromDateIndex::forced_import( - db, - &suffix("net_realized_pnl_cumulative_30d_delta_rel_to_market_cap"), - Source::Compute, - version + Version::new(3), - indexes, - VecBuilderOptions::default().add_last(), - ) - .unwrap() - }), - dateindex_to_realized_profit_to_loss_ratio: (compute_dollars && extended).then(|| { - EagerVec::forced_import( - db, - &suffix("realized_profit_to_loss_ratio"), - version + Version::ONE, - ) - .unwrap() - }), + .then(|| computed_di!("net_realized_pnl_cumulative_30d_delta_rel_to_market_cap", Source::Compute, v3, last())), }) } @@ -1256,7 +635,7 @@ impl Vecs { .get_unwrap(prev_height); if let Some(height_to_realized_cap) = self.height_to_realized_cap.as_mut() { - state.realized.as_mut().unwrap().cap = + state.realized.um().cap = height_to_realized_cap.into_iter().get_unwrap(prev_height); } @@ -1298,155 +677,127 @@ impl Vecs { let height_to_realized_profit_inner_version = self .height_to_realized_profit - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_realized_profit - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_realized_profit_inner_version, )?; let height_to_realized_loss_inner_version = self .height_to_realized_loss - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_realized_loss - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_realized_loss_inner_version, )?; let height_to_value_created_inner_version = self .height_to_value_created - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_value_created - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_value_created_inner_version, )?; let height_to_value_destroyed_inner_version = self .height_to_value_destroyed - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_value_destroyed - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_value_destroyed_inner_version, )?; let height_to_supply_in_profit_inner_version = self .height_to_supply_in_profit - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_supply_in_profit - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_supply_in_profit_inner_version, )?; let height_to_supply_in_loss_inner_version = self .height_to_supply_in_loss - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_supply_in_loss - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_supply_in_loss_inner_version, )?; let height_to_unrealized_profit_inner_version = self .height_to_unrealized_profit - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_unrealized_profit - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_unrealized_profit_inner_version, )?; let height_to_unrealized_loss_inner_version = self .height_to_unrealized_loss - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_unrealized_loss - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_unrealized_loss_inner_version, )?; let dateindex_to_supply_in_profit_inner_version = self .dateindex_to_supply_in_profit - .as_ref() - .unwrap() + .u() .inner_version(); self.dateindex_to_supply_in_profit - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + dateindex_to_supply_in_profit_inner_version, )?; let dateindex_to_supply_in_loss_inner_version = self .dateindex_to_supply_in_loss - .as_ref() - .unwrap() + .u() .inner_version(); self.dateindex_to_supply_in_loss - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + dateindex_to_supply_in_loss_inner_version, )?; let dateindex_to_unrealized_profit_inner_version = self .dateindex_to_unrealized_profit - .as_ref() - .unwrap() + .u() .inner_version(); self.dateindex_to_unrealized_profit - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + dateindex_to_unrealized_profit_inner_version, )?; let dateindex_to_unrealized_loss_inner_version = self .dateindex_to_unrealized_loss - .as_ref() - .unwrap() + .u() .inner_version(); self.dateindex_to_unrealized_loss - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + dateindex_to_unrealized_loss_inner_version, )?; let height_to_min_price_paid_inner_version = self .height_to_min_price_paid - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_min_price_paid - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_min_price_paid_inner_version, )?; let height_to_max_price_paid_inner_version = self .height_to_max_price_paid - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_max_price_paid - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_max_price_paid_inner_version, )?; @@ -1454,23 +805,19 @@ impl Vecs { if self.height_to_adjusted_value_created.is_some() { let height_to_adjusted_value_created_inner_version = self .height_to_adjusted_value_created - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_adjusted_value_created - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_adjusted_value_created_inner_version, )?; let height_to_adjusted_value_destroyed_inner_version = self .height_to_adjusted_value_destroyed - .as_ref() - .unwrap() + .u() .inner_version(); self.height_to_adjusted_value_destroyed - .as_mut() - .unwrap() + .um() .validate_computed_version_or_reset( base_version + height_to_adjusted_value_destroyed_inner_version, )?; @@ -1504,30 +851,24 @@ impl Vecs { height_to_realized_cap.truncate_push(height, realized.cap)?; self.height_to_realized_profit - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.profit)?; self.height_to_realized_loss - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.loss)?; self.height_to_value_created - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.value_created)?; self.height_to_value_destroyed - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.value_destroyed)?; if self.height_to_adjusted_value_created.is_some() { self.height_to_adjusted_value_created - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.adj_value_created)?; self.height_to_adjusted_value_destroyed - .as_mut() - .unwrap() + .um() .truncate_push(height, realized.adj_value_destroyed)?; } } @@ -1544,8 +885,7 @@ impl Vecs { ) -> Result<()> { if let Some(height_price) = height_price { self.height_to_min_price_paid - .as_mut() - .unwrap() + .um() .truncate_push( height, state @@ -1554,8 +894,7 @@ impl Vecs { .unwrap_or(Dollars::NAN), )?; self.height_to_max_price_paid - .as_mut() - .unwrap() + .um() .truncate_push( height, state @@ -1568,40 +907,32 @@ impl Vecs { state.compute_unrealized_states(height_price, date_price.unwrap()); self.height_to_supply_in_profit - .as_mut() - .unwrap() + .um() .truncate_push(height, height_unrealized_state.supply_in_profit)?; self.height_to_supply_in_loss - .as_mut() - .unwrap() + .um() .truncate_push(height, height_unrealized_state.supply_in_loss)?; self.height_to_unrealized_profit - .as_mut() - .unwrap() + .um() .truncate_push(height, height_unrealized_state.unrealized_profit)?; self.height_to_unrealized_loss - .as_mut() - .unwrap() + .um() .truncate_push(height, height_unrealized_state.unrealized_loss)?; if let Some(date_unrealized_state) = date_unrealized_state { let dateindex = dateindex.unwrap(); self.dateindex_to_supply_in_profit - .as_mut() - .unwrap() + .um() .truncate_push(dateindex, date_unrealized_state.supply_in_profit)?; self.dateindex_to_supply_in_loss - .as_mut() - .unwrap() + .um() .truncate_push(dateindex, date_unrealized_state.supply_in_loss)?; self.dateindex_to_unrealized_profit - .as_mut() - .unwrap() + .um() .truncate_push(dateindex, date_unrealized_state.unrealized_profit)?; self.dateindex_to_unrealized_loss - .as_mut() - .unwrap() + .um() .truncate_push(dateindex, date_unrealized_state.unrealized_loss)?; } @@ -1630,70 +961,54 @@ impl Vecs { if let Some(height_to_realized_cap) = self.height_to_realized_cap.as_mut() { height_to_realized_cap.safe_flush(exit)?; self.height_to_realized_profit - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_realized_loss - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_value_created - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_value_destroyed - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_supply_in_profit - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_supply_in_loss - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_unrealized_profit - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_unrealized_loss - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.dateindex_to_supply_in_profit - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.dateindex_to_supply_in_loss - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.dateindex_to_unrealized_profit - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.dateindex_to_unrealized_loss - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_min_price_paid - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_max_price_paid - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; if self.height_to_adjusted_value_created.is_some() { self.height_to_adjusted_value_created - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; self.height_to_adjusted_value_destroyed - .as_mut() - .unwrap() + .um() .safe_flush(exit)?; } } @@ -1760,200 +1075,184 @@ impl Vecs { starting_indexes.height, others .iter() - .map(|v| v.height_to_realized_cap.as_ref().unwrap()) + .map(|v| v.height_to_realized_cap.u()) .collect::>() .as_slice(), exit, )?; self.height_to_min_price_paid - .as_mut() - .unwrap() + .um() .compute_min_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_min_price_paid.as_ref().unwrap()) + .map(|v| v.height_to_min_price_paid.u()) .collect::>() .as_slice(), exit, )?; self.height_to_max_price_paid - .as_mut() - .unwrap() + .um() .compute_max_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_max_price_paid.as_ref().unwrap()) + .map(|v| v.height_to_max_price_paid.u()) .collect::>() .as_slice(), exit, )?; self.height_to_realized_profit - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_realized_profit.as_ref().unwrap()) + .map(|v| v.height_to_realized_profit.u()) .collect::>() .as_slice(), exit, )?; self.height_to_realized_loss - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_realized_loss.as_ref().unwrap()) + .map(|v| v.height_to_realized_loss.u()) .collect::>() .as_slice(), exit, )?; self.height_to_value_created - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_value_created.as_ref().unwrap()) + .map(|v| v.height_to_value_created.u()) .collect::>() .as_slice(), exit, )?; self.height_to_value_destroyed - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_value_destroyed.as_ref().unwrap()) + .map(|v| v.height_to_value_destroyed.u()) .collect::>() .as_slice(), exit, )?; self.height_to_supply_in_profit - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_supply_in_profit.as_ref().unwrap()) + .map(|v| v.height_to_supply_in_profit.u()) .collect::>() .as_slice(), exit, )?; self.height_to_supply_in_loss - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_supply_in_loss.as_ref().unwrap()) + .map(|v| v.height_to_supply_in_loss.u()) .collect::>() .as_slice(), exit, )?; self.height_to_unrealized_profit - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_unrealized_profit.as_ref().unwrap()) + .map(|v| v.height_to_unrealized_profit.u()) .collect::>() .as_slice(), exit, )?; self.height_to_unrealized_loss - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_unrealized_loss.as_ref().unwrap()) + .map(|v| v.height_to_unrealized_loss.u()) .collect::>() .as_slice(), exit, )?; self.dateindex_to_supply_in_profit - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.dateindex, others .iter() - .map(|v| v.dateindex_to_supply_in_profit.as_ref().unwrap()) + .map(|v| v.dateindex_to_supply_in_profit.u()) .collect::>() .as_slice(), exit, )?; self.dateindex_to_supply_in_loss - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.dateindex, others .iter() - .map(|v| v.dateindex_to_supply_in_loss.as_ref().unwrap()) + .map(|v| v.dateindex_to_supply_in_loss.u()) .collect::>() .as_slice(), exit, )?; self.dateindex_to_unrealized_profit - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.dateindex, others .iter() - .map(|v| v.dateindex_to_unrealized_profit.as_ref().unwrap()) + .map(|v| v.dateindex_to_unrealized_profit.u()) .collect::>() .as_slice(), exit, )?; self.dateindex_to_unrealized_loss - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.dateindex, others .iter() - .map(|v| v.dateindex_to_unrealized_loss.as_ref().unwrap()) + .map(|v| v.dateindex_to_unrealized_loss.u()) .collect::>() .as_slice(), exit, )?; self.height_to_min_price_paid - .as_mut() - .unwrap() + .um() .compute_min_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_min_price_paid.as_ref().unwrap()) + .map(|v| v.height_to_min_price_paid.u()) .collect::>() .as_slice(), exit, )?; self.height_to_max_price_paid - .as_mut() - .unwrap() + .um() .compute_max_of_others( starting_indexes.height, others .iter() - .map(|v| v.height_to_max_price_paid.as_ref().unwrap()) + .map(|v| v.height_to_max_price_paid.u()) .collect::>() .as_slice(), exit, @@ -1961,8 +1260,7 @@ impl Vecs { if self.height_to_adjusted_value_created.is_some() { self.height_to_adjusted_value_created - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others @@ -1970,15 +1268,14 @@ impl Vecs { .map(|v| { v.height_to_adjusted_value_created .as_ref() - .unwrap_or(v.height_to_value_created.as_ref().unwrap()) + .unwrap_or(v.height_to_value_created.u()) }) .collect::>() .as_slice(), exit, )?; self.height_to_adjusted_value_destroyed - .as_mut() - .unwrap() + .um() .compute_sum_of_others( starting_indexes.height, others @@ -1986,7 +1283,7 @@ impl Vecs { .map(|v| { v.height_to_adjusted_value_destroyed .as_ref() - .unwrap_or(v.height_to_value_destroyed.as_ref().unwrap()) + .unwrap_or(v.height_to_value_destroyed.u()) }) .collect::>() .as_slice(), @@ -2056,7 +1353,7 @@ impl Vecs { .compute_all(price, starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.indexes_to_supply.sats.dateindex.as_ref().unwrap(), + self.indexes_to_supply.sats.dateindex.u(), |(i, sats, ..)| (i, sats / 2), exit, )?; @@ -2125,16 +1422,15 @@ impl Vecs { indexes, starting_indexes, exit, - Some(self.height_to_realized_cap.as_ref().unwrap()), + Some(self.height_to_realized_cap.u()), )?; self.indexes_to_realized_price - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_divide( starting_indexes.height, - self.height_to_realized_cap.as_ref().unwrap(), + self.height_to_realized_cap.u(), &self.height_to_supply_value.bitcoin, exit, )?; @@ -2142,48 +1438,43 @@ impl Vecs { })?; self.indexes_to_realized_price_extra - .as_mut() - .unwrap() + .um() .compute_rest( - price.as_ref().unwrap(), + price.u(), starting_indexes, exit, Some( self.indexes_to_realized_price - .as_ref() - .unwrap() + .u() .dateindex .unwrap_last(), ), )?; self.indexes_to_realized_profit - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_realized_profit.as_ref().unwrap()), + Some(self.height_to_realized_profit.u()), )?; self.indexes_to_realized_loss - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_realized_loss.as_ref().unwrap()), + Some(self.height_to_realized_loss.u()), )?; self.indexes_to_neg_realized_loss - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_transform( starting_indexes.height, - self.height_to_realized_loss.as_ref().unwrap(), + self.height_to_realized_loss.u(), |(i, v, ..)| (i, v * -1_i64), exit, )?; @@ -2191,34 +1482,30 @@ impl Vecs { })?; self.indexes_to_value_created - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_value_created.as_ref().unwrap()), + Some(self.height_to_value_created.u()), )?; self.indexes_to_value_destroyed - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_value_destroyed.as_ref().unwrap()), + Some(self.height_to_value_destroyed.u()), )?; self.indexes_to_realized_cap_30d_delta - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_change( starting_indexes.dateindex, self.indexes_to_realized_cap - .as_ref() - .unwrap() + .u() .dateindex .unwrap_last(), 30, @@ -2228,182 +1515,161 @@ impl Vecs { })?; self.indexes_to_net_realized_pnl - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_subtract( starting_indexes.height, - self.height_to_realized_profit.as_ref().unwrap(), - self.height_to_realized_loss.as_ref().unwrap(), + self.height_to_realized_profit.u(), + self.height_to_realized_loss.u(), exit, )?; Ok(()) })?; self.indexes_to_realized_value - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_add( starting_indexes.height, - self.height_to_realized_profit.as_ref().unwrap(), - self.height_to_realized_loss.as_ref().unwrap(), + self.height_to_realized_profit.u(), + self.height_to_realized_loss.u(), exit, )?; Ok(()) })?; - self.dateindex_to_sopr.as_mut().unwrap().compute_divide( + self.dateindex_to_sopr.um().compute_divide( starting_indexes.dateindex, self.indexes_to_value_created - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), self.indexes_to_value_destroyed - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), exit, )?; self.dateindex_to_sopr_7d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_sopr.as_ref().unwrap(), + self.dateindex_to_sopr.u(), 7, exit, )?; self.dateindex_to_sopr_30d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_sopr.as_ref().unwrap(), + self.dateindex_to_sopr.u(), 30, exit, )?; self.dateindex_to_sell_side_risk_ratio - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.dateindex, self.indexes_to_realized_value - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), self.indexes_to_realized_cap - .as_ref() - .unwrap() + .u() .dateindex .unwrap_last(), exit, )?; self.dateindex_to_sell_side_risk_ratio_7d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_sell_side_risk_ratio.as_ref().unwrap(), + self.dateindex_to_sell_side_risk_ratio.u(), 7, exit, )?; self.dateindex_to_sell_side_risk_ratio_30d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_sell_side_risk_ratio.as_ref().unwrap(), + self.dateindex_to_sell_side_risk_ratio.u(), 30, exit, )?; self.indexes_to_supply_in_profit - .as_mut() - .unwrap() + .um() .compute_rest( price, starting_indexes, exit, - Some(self.dateindex_to_supply_in_profit.as_ref().unwrap()), + Some(self.dateindex_to_supply_in_profit.u()), )?; self.indexes_to_supply_in_loss - .as_mut() - .unwrap() + .um() .compute_rest( price, starting_indexes, exit, - Some(self.dateindex_to_supply_in_loss.as_ref().unwrap()), + Some(self.dateindex_to_supply_in_loss.u()), )?; self.indexes_to_unrealized_profit - .as_mut() - .unwrap() + .um() .compute_rest( starting_indexes, exit, - Some(self.dateindex_to_unrealized_profit.as_ref().unwrap()), + Some(self.dateindex_to_unrealized_profit.u()), )?; self.indexes_to_unrealized_loss - .as_mut() - .unwrap() + .um() .compute_rest( starting_indexes, exit, - Some(self.dateindex_to_unrealized_loss.as_ref().unwrap()), + Some(self.dateindex_to_unrealized_loss.u()), )?; self.height_to_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_add( starting_indexes.height, - self.height_to_unrealized_profit.as_ref().unwrap(), - self.height_to_unrealized_loss.as_ref().unwrap(), + self.height_to_unrealized_profit.u(), + self.height_to_unrealized_loss.u(), exit, )?; self.indexes_to_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_add( starting_indexes.dateindex, - self.dateindex_to_unrealized_profit.as_ref().unwrap(), - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_profit.u(), + self.dateindex_to_unrealized_loss.u(), exit, )?; Ok(()) })?; self.height_to_total_realized_pnl - .as_mut() - .unwrap() + .um() .compute_add( starting_indexes.height, - self.height_to_realized_profit.as_ref().unwrap(), - self.height_to_realized_loss.as_ref().unwrap(), + self.height_to_realized_profit.u(), + self.height_to_realized_loss.u(), exit, )?; self.indexes_to_total_realized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_add( starting_indexes.dateindex, self.indexes_to_realized_profit - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), self.indexes_to_realized_loss - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), exit, @@ -2412,156 +1678,138 @@ impl Vecs { })?; self.indexes_to_min_price_paid - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_min_price_paid.as_ref().unwrap()), + Some(self.height_to_min_price_paid.u()), )?; self.indexes_to_max_price_paid - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_max_price_paid.as_ref().unwrap()), + Some(self.height_to_max_price_paid.u()), )?; self.height_to_neg_unrealized_loss - .as_mut() - .unwrap() + .um() .compute_transform( starting_indexes.height, - self.height_to_unrealized_loss.as_ref().unwrap(), + self.height_to_unrealized_loss.u(), |(h, v, ..)| (h, v * -1_i64), exit, )?; self.indexes_to_neg_unrealized_loss - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_transform( starting_indexes.dateindex, - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_loss.u(), |(h, v, ..)| (h, v * -1_i64), exit, )?; Ok(()) })?; self.height_to_net_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_subtract( starting_indexes.height, - self.height_to_unrealized_profit.as_ref().unwrap(), - self.height_to_unrealized_loss.as_ref().unwrap(), + self.height_to_unrealized_profit.u(), + self.height_to_unrealized_loss.u(), exit, )?; self.indexes_to_net_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_subtract( starting_indexes.dateindex, - self.dateindex_to_unrealized_profit.as_ref().unwrap(), - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_profit.u(), + self.dateindex_to_unrealized_loss.u(), exit, )?; Ok(()) })?; self.height_to_unrealized_profit_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_profit.as_ref().unwrap(), + self.height_to_unrealized_profit.u(), height_to_market_cap, exit, )?; self.height_to_unrealized_loss_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_loss.as_ref().unwrap(), + self.height_to_unrealized_loss.u(), height_to_market_cap, exit, )?; self.height_to_neg_unrealized_loss_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_neg_unrealized_loss.as_ref().unwrap(), + self.height_to_neg_unrealized_loss.u(), height_to_market_cap, exit, )?; self.height_to_net_unrealized_pnl_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_net_unrealized_pnl.as_ref().unwrap(), + self.height_to_net_unrealized_pnl.u(), height_to_market_cap, exit, )?; self.indexes_to_unrealized_profit_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_profit.as_ref().unwrap(), + self.dateindex_to_unrealized_profit.u(), dateindex_to_market_cap, exit, )?; Ok(()) })?; self.indexes_to_unrealized_loss_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_loss.u(), dateindex_to_market_cap, exit, )?; Ok(()) })?; self.indexes_to_neg_unrealized_loss_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, self.indexes_to_neg_unrealized_loss - .as_ref() - .unwrap() + .u() .dateindex - .as_ref() - .unwrap(), + .u(), dateindex_to_market_cap, exit, )?; Ok(()) })?; self.indexes_to_net_unrealized_pnl_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, self.indexes_to_net_unrealized_pnl - .as_ref() - .unwrap() + .u() .dateindex - .as_ref() - .unwrap(), + .u(), dateindex_to_market_cap, exit, )?; @@ -2573,48 +1821,43 @@ impl Vecs { .is_some() { self.height_to_unrealized_profit_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_profit.as_ref().unwrap(), - self.height_to_supply_value.dollars.as_ref().unwrap(), + self.height_to_unrealized_profit.u(), + self.height_to_supply_value.dollars.u(), exit, )?; self.height_to_unrealized_loss_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_loss.as_ref().unwrap(), - self.height_to_supply_value.dollars.as_ref().unwrap(), + self.height_to_unrealized_loss.u(), + self.height_to_supply_value.dollars.u(), exit, )?; self.height_to_neg_unrealized_loss_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_neg_unrealized_loss.as_ref().unwrap(), - self.height_to_supply_value.dollars.as_ref().unwrap(), + self.height_to_neg_unrealized_loss.u(), + self.height_to_supply_value.dollars.u(), exit, )?; self.height_to_net_unrealized_pnl_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_net_unrealized_pnl.as_ref().unwrap(), - self.height_to_supply_value.dollars.as_ref().unwrap(), + self.height_to_net_unrealized_pnl.u(), + self.height_to_supply_value.dollars.u(), exit, )?; self.indexes_to_unrealized_profit_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_profit.as_ref().unwrap(), + self.dateindex_to_unrealized_profit.u(), self.indexes_to_supply .dollars .as_ref() @@ -2627,12 +1870,11 @@ impl Vecs { Ok(()) })?; self.indexes_to_unrealized_loss_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_loss.u(), self.indexes_to_supply .dollars .as_ref() @@ -2645,8 +1887,7 @@ impl Vecs { Ok(()) })?; self.indexes_to_neg_unrealized_loss_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, @@ -2668,8 +1909,7 @@ impl Vecs { Ok(()) })?; self.indexes_to_net_unrealized_pnl_rel_to_own_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, @@ -2697,48 +1937,43 @@ impl Vecs { .is_some() { self.height_to_unrealized_profit_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_profit.as_ref().unwrap(), - self.height_to_total_unrealized_pnl.as_ref().unwrap(), + self.height_to_unrealized_profit.u(), + self.height_to_total_unrealized_pnl.u(), exit, )?; self.height_to_unrealized_loss_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_unrealized_loss.as_ref().unwrap(), - self.height_to_total_unrealized_pnl.as_ref().unwrap(), + self.height_to_unrealized_loss.u(), + self.height_to_total_unrealized_pnl.u(), exit, )?; self.height_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_neg_unrealized_loss.as_ref().unwrap(), - self.height_to_total_unrealized_pnl.as_ref().unwrap(), + self.height_to_neg_unrealized_loss.u(), + self.height_to_total_unrealized_pnl.u(), exit, )?; self.height_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, - self.height_to_net_unrealized_pnl.as_ref().unwrap(), - self.height_to_total_unrealized_pnl.as_ref().unwrap(), + self.height_to_net_unrealized_pnl.u(), + self.height_to_total_unrealized_pnl.u(), exit, )?; self.indexes_to_unrealized_profit_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_profit.as_ref().unwrap(), + self.dateindex_to_unrealized_profit.u(), self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() @@ -2750,12 +1985,11 @@ impl Vecs { Ok(()) })?; self.indexes_to_unrealized_loss_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, - self.dateindex_to_unrealized_loss.as_ref().unwrap(), + self.dateindex_to_unrealized_loss.u(), self.indexes_to_total_unrealized_pnl .as_ref() .unwrap() @@ -2767,8 +2001,7 @@ impl Vecs { Ok(()) })?; self.indexes_to_neg_unrealized_loss_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, @@ -2789,8 +2022,7 @@ impl Vecs { Ok(()) })?; self.indexes_to_net_unrealized_pnl_rel_to_own_total_unrealized_pnl - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.dateindex, @@ -2813,139 +2045,120 @@ impl Vecs { } self.indexes_to_realized_profit_rel_to_realized_cap - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.height, - self.height_to_realized_profit.as_ref().unwrap(), - *height_to_realized_cap.as_ref().unwrap(), + self.height_to_realized_profit.u(), + *height_to_realized_cap.u(), exit, )?; Ok(()) })?; self.indexes_to_realized_loss_rel_to_realized_cap - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.height, - self.height_to_realized_loss.as_ref().unwrap(), - *height_to_realized_cap.as_ref().unwrap(), + self.height_to_realized_loss.u(), + *height_to_realized_cap.u(), exit, )?; Ok(()) })?; self.indexes_to_net_realized_pnl_rel_to_realized_cap - .as_mut() - .unwrap() + .um() .compute_all(indexes, starting_indexes, exit, |vec| { vec.compute_percentage( starting_indexes.height, self.indexes_to_net_realized_pnl - .as_ref() - .unwrap() + .u() .height - .as_ref() - .unwrap(), - *height_to_realized_cap.as_ref().unwrap(), + .u(), + *height_to_realized_cap.u(), exit, )?; Ok(()) })?; self.height_to_supply_in_loss_value - .as_mut() - .unwrap() + .um() .compute_rest( price, starting_indexes, exit, - Some(self.height_to_supply_in_loss.as_ref().unwrap()), + Some(self.height_to_supply_in_loss.u()), )?; self.height_to_supply_in_profit_value - .as_mut() - .unwrap() + .um() .compute_rest( price, starting_indexes, exit, - Some(self.height_to_supply_in_profit.as_ref().unwrap()), + Some(self.height_to_supply_in_profit.u()), )?; self.height_to_supply_in_loss_rel_to_own_supply - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, &self .height_to_supply_in_loss_value - .as_ref() - .unwrap() + .u() .bitcoin, &self.height_to_supply_value.bitcoin, exit, )?; self.height_to_supply_in_profit_rel_to_own_supply - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, &self .height_to_supply_in_profit_value - .as_ref() - .unwrap() + .u() .bitcoin, &self.height_to_supply_value.bitcoin, exit, )?; self.indexes_to_supply_in_loss_rel_to_own_supply - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, self.indexes_to_supply_in_loss - .as_ref() - .unwrap() + .u() .bitcoin .dateindex - .as_ref() - .unwrap(), - self.indexes_to_supply.bitcoin.dateindex.as_ref().unwrap(), + .u(), + self.indexes_to_supply.bitcoin.dateindex.u(), exit, )?; Ok(()) })?; self.indexes_to_supply_in_profit_rel_to_own_supply - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, self.indexes_to_supply_in_profit - .as_ref() - .unwrap() + .u() .bitcoin .dateindex - .as_ref() - .unwrap(), - self.indexes_to_supply.bitcoin.dateindex.as_ref().unwrap(), + .u(), + self.indexes_to_supply.bitcoin.dateindex.u(), exit, )?; Ok(()) })?; self.indexes_to_net_realized_pnl_cumulative_30d_delta - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_change( starting_indexes.dateindex, self.indexes_to_net_realized_pnl - .as_ref() - .unwrap() + .u() .dateindex .unwrap_cumulative(), 30, @@ -2955,35 +2168,29 @@ impl Vecs { })?; self.indexes_to_net_realized_pnl_cumulative_30d_delta_rel_to_realized_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, self.indexes_to_net_realized_pnl_cumulative_30d_delta - .as_ref() - .unwrap() + .u() .dateindex - .as_ref() - .unwrap(), - *dateindex_to_realized_cap.as_ref().unwrap(), + .u(), + *dateindex_to_realized_cap.u(), exit, )?; Ok(()) })?; self.indexes_to_net_realized_pnl_cumulative_30d_delta_rel_to_market_cap - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, self.indexes_to_net_realized_pnl_cumulative_30d_delta - .as_ref() - .unwrap() + .u() .dateindex - .as_ref() - .unwrap(), + .u(), dateindex_to_market_cap, exit, )?; @@ -2996,34 +2203,29 @@ impl Vecs { .is_some() { self.height_to_supply_in_loss_rel_to_circulating_supply - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, &self .height_to_supply_in_loss_value - .as_ref() - .unwrap() + .u() .bitcoin, height_to_supply, exit, )?; self.height_to_supply_in_profit_rel_to_circulating_supply - .as_mut() - .unwrap() + .um() .compute_percentage( starting_indexes.height, &self .height_to_supply_in_profit_value - .as_ref() - .unwrap() + .u() .bitcoin, height_to_supply, exit, )?; self.indexes_to_supply_in_loss_rel_to_circulating_supply - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, @@ -3040,8 +2242,7 @@ impl Vecs { Ok(()) })?; self.indexes_to_supply_in_profit_rel_to_circulating_supply - .as_mut() - .unwrap() + .um() .compute_all(starting_indexes, exit, |v| { v.compute_percentage( starting_indexes.dateindex, @@ -3061,59 +2262,52 @@ impl Vecs { if self.indexes_to_adjusted_value_created.is_some() { self.indexes_to_adjusted_value_created - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_adjusted_value_created.as_ref().unwrap()), + Some(self.height_to_adjusted_value_created.u()), )?; self.indexes_to_adjusted_value_destroyed - .as_mut() - .unwrap() + .um() .compute_rest( indexes, starting_indexes, exit, - Some(self.height_to_adjusted_value_destroyed.as_ref().unwrap()), + Some(self.height_to_adjusted_value_destroyed.u()), )?; self.dateindex_to_adjusted_sopr - .as_mut() - .unwrap() + .um() .compute_divide( starting_indexes.dateindex, self.indexes_to_adjusted_value_created - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), self.indexes_to_adjusted_value_destroyed - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), exit, )?; self.dateindex_to_adjusted_sopr_7d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_adjusted_sopr.as_ref().unwrap(), + self.dateindex_to_adjusted_sopr.u(), 7, exit, )?; self.dateindex_to_adjusted_sopr_30d_ema - .as_mut() - .unwrap() + .um() .compute_ema( starting_indexes.dateindex, - self.dateindex_to_adjusted_sopr.as_ref().unwrap(), + self.dateindex_to_adjusted_sopr.u(), 30, exit, )?; @@ -3129,8 +2323,8 @@ impl Vecs { |v| { v.compute_percentage( starting_indexes.height, - self.height_to_realized_cap.as_ref().unwrap(), - self.height_to_supply_value.dollars.as_ref().unwrap(), + self.height_to_realized_cap.u(), + self.height_to_supply_value.dollars.u(), exit, )?; Ok(()) @@ -3145,13 +2339,11 @@ impl Vecs { dateindex_to_realized_profit_to_loss_ratio.compute_divide( starting_indexes.dateindex, self.indexes_to_realized_profit - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), self.indexes_to_realized_loss - .as_ref() - .unwrap() + .u() .dateindex .unwrap_sum(), exit, diff --git a/crates/brk_computer/src/stateful/mod.rs b/crates/brk_computer/src/stateful/mod.rs index 29a3be445..8477566ee 100644 --- a/crates/brk_computer/src/stateful/mod.rs +++ b/crates/brk_computer/src/stateful/mod.rs @@ -1,24 +1,22 @@ use std::{cmp::Ordering, collections::BTreeSet, mem, path::Path, thread}; use brk_error::Result; -use brk_grouper::{ByAddressType, ByAnyAddress, Filtered}; +use brk_grouper::ByAddressType; use brk_indexer::Indexer; use brk_traversable::Traversable; use brk_types::{ - AnyAddressDataIndexEnum, AnyAddressIndex, CheckedSub, DateIndex, Dollars, EmptyAddressData, - EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex, OutputType, P2AAddressIndex, - P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex, - P2WPKHAddressIndex, P2WSHAddressIndex, Sats, StoredU64, Timestamp, TxInIndex, TxIndex, - TxOutIndex, TypeIndex, Version, + AnyAddressDataIndexEnum, AnyAddressIndex, DateIndex, Dollars, EmptyAddressData, + EmptyAddressIndex, Height, LoadedAddressData, LoadedAddressIndex, OutputType, Sats, StoredU64, + TxInIndex, TxIndex, TxOutIndex, TypeIndex, Version, }; use log::info; use rayon::prelude::*; use rustc_hash::FxHashMap; use smallvec::SmallVec; use vecdb::{ - AnyStoredVec, AnyVec, BoxedVecIterator, BytesVec, CollectableVec, Database, EagerVec, Exit, - GenericStoredVec, ImportOptions, ImportableVec, IterableCloneableVec, IterableVec, - LazyVecFrom1, PAGE_SIZE, PcoVec, Reader, Stamp, TypedVecIterator, VecIndex, + AnyStoredVec, AnyVec, BytesVec, CollectableVec, Database, EagerVec, Exit, GenericStoredVec, + ImportOptions, ImportableVec, IterableCloneableVec, IterableVec, LazyVecFrom1, PAGE_SIZE, + PcoVec, Stamp, TypedVecIterator, VecIndex, }; use crate::{ @@ -28,20 +26,28 @@ use crate::{ VecBuilderOptions, }, indexes, price, + utils::OptionExt, }; mod address_cohort; mod address_cohorts; +mod address_indexes; mod addresstype; mod common; mod range_map; +mod readers; mod r#trait; +mod transaction_processing; mod utxo_cohort; mod utxo_cohorts; mod withaddressdatasource; +use address_indexes::{AddressesDataVecs, AnyAddressIndexesVecs}; use addresstype::*; use range_map::*; +use readers::{ + IndexerReaders, VecsReaders, build_txinindex_to_txindex, build_txoutindex_to_txindex, +}; use r#trait::*; use withaddressdatasource::*; @@ -57,8 +63,8 @@ pub struct Vecs { // States // --- pub chain_state: BytesVec, - pub any_address_indexes: AnyAddressIndexes, - pub addresses_data: AddressesData, + pub any_address_indexes: AnyAddressIndexesVecs, + pub addresses_data: AddressesDataVecs, pub utxo_cohorts: utxo_cohorts::Vecs, pub address_cohorts: address_cohorts::Vecs, @@ -101,47 +107,50 @@ impl Vecs { db.set_min_regions(50_000)?; let compute_dollars = price.is_some(); + let v0 = version + VERSION + Version::ZERO; + let v1 = version + VERSION + Version::ONE; + let v2 = version + VERSION + Version::TWO; let utxo_cohorts = utxo_cohorts::Vecs::forced_import(&db, version, indexes, price, &states_path)?; let loadedaddressindex_to_loadedaddressdata = BytesVec::forced_import_with( - ImportOptions::new(&db, "loadedaddressdata", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "loadedaddressdata", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?; let emptyaddressindex_to_emptyaddressdata = BytesVec::forced_import_with( - ImportOptions::new(&db, "emptyaddressdata", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "emptyaddressdata", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?; let loadedaddressindex_to_loadedaddressindex = LazyVecFrom1::init( "loadedaddressindex", - version + VERSION + Version::ZERO, + v0, loadedaddressindex_to_loadedaddressdata.boxed_clone(), |index, _| Some(index), ); let emptyaddressindex_to_emptyaddressindex = LazyVecFrom1::init( "emptyaddressindex", - version + VERSION + Version::ZERO, + v0, emptyaddressindex_to_emptyaddressdata.boxed_clone(), |index, _| Some(index), ); let this = Self { chain_state: BytesVec::forced_import_with( - ImportOptions::new(&db, "chain", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "chain", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, height_to_unspendable_supply: EagerVec::forced_import( &db, "unspendable_supply", - version + VERSION + Version::ZERO, + v0, )?, indexes_to_unspendable_supply: ComputedValueVecsFromHeight::forced_import( &db, "unspendable_supply", Source::None, - version + VERSION + Version::ZERO, + v0, VecBuilderOptions::default().add_last(), compute_dollars, indexes, @@ -149,13 +158,13 @@ impl Vecs { height_to_opreturn_supply: EagerVec::forced_import( &db, "opreturn_supply", - version + VERSION + Version::ZERO, + v0, )?, indexes_to_opreturn_supply: ComputedValueVecsFromHeight::forced_import( &db, "opreturn_supply", Source::None, - version + VERSION + Version::ZERO, + v0, VecBuilderOptions::default().add_last(), compute_dollars, indexes, @@ -164,7 +173,7 @@ impl Vecs { &db, "addr_count", Source::Compute, - version + VERSION + Version::ZERO, + v0, indexes, VecBuilderOptions::default().add_last(), )?, @@ -172,14 +181,14 @@ impl Vecs { &db, "empty_addr_count", Source::Compute, - version + VERSION + Version::ZERO, + v0, indexes, VecBuilderOptions::default().add_last(), )?, height_to_market_cap: compute_dollars.then(|| { LazyVecFrom1::init( "market_cap", - version + VERSION + Version::ONE, + v1, utxo_cohorts .all .inner @@ -196,235 +205,45 @@ impl Vecs { &db, "market_cap", Source::Compute, - version + VERSION + Version::TWO, + v2, indexes, VecBuilderOptions::default().add_last(), ) .unwrap() }), addresstype_to_height_to_addr_count: AddressTypeToHeightToAddressCount::from( - ByAddressType { - p2pk65: EagerVec::forced_import( - &db, - "p2pk65_addr_count", - version + VERSION + Version::ZERO, - )?, - p2pk33: EagerVec::forced_import( - &db, - "p2pk33_addr_count", - version + VERSION + Version::ZERO, - )?, - p2pkh: EagerVec::forced_import( - &db, - "p2pkh_addr_count", - version + VERSION + Version::ZERO, - )?, - p2sh: EagerVec::forced_import( - &db, - "p2sh_addr_count", - version + VERSION + Version::ZERO, - )?, - p2wpkh: EagerVec::forced_import( - &db, - "p2wpkh_addr_count", - version + VERSION + Version::ZERO, - )?, - p2wsh: EagerVec::forced_import( - &db, - "p2wsh_addr_count", - version + VERSION + Version::ZERO, - )?, - p2tr: EagerVec::forced_import( - &db, - "p2tr_addr_count", - version + VERSION + Version::ZERO, - )?, - p2a: EagerVec::forced_import( - &db, - "p2a_addr_count", - version + VERSION + Version::ZERO, - )?, - }, + ByAddressType::new_with_name(|name| { + Ok(EagerVec::forced_import(&db, &format!("{name}_addr_count"), v0)?) + })?, ), addresstype_to_height_to_empty_addr_count: AddressTypeToHeightToAddressCount::from( - ByAddressType { - p2pk65: EagerVec::forced_import( - &db, - "p2pk65_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2pk33: EagerVec::forced_import( - &db, - "p2pk33_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2pkh: EagerVec::forced_import( - &db, - "p2pkh_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2sh: EagerVec::forced_import( - &db, - "p2sh_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2wpkh: EagerVec::forced_import( - &db, - "p2wpkh_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2wsh: EagerVec::forced_import( - &db, - "p2wsh_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2tr: EagerVec::forced_import( - &db, - "p2tr_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - p2a: EagerVec::forced_import( - &db, - "p2a_empty_addr_count", - version + VERSION + Version::ZERO, - )?, - }, + ByAddressType::new_with_name(|name| { + Ok(EagerVec::forced_import(&db, &format!("{name}_empty_addr_count"), v0)?) + })?, ), addresstype_to_indexes_to_addr_count: AddressTypeToIndexesToAddressCount::from( - ByAddressType { - p2pk65: ComputedVecsFromHeight::forced_import( + ByAddressType::new_with_name(|name| { + ComputedVecsFromHeight::forced_import( &db, - "p2pk65_addr_count", + &format!("{name}_addr_count"), Source::None, - version + VERSION + Version::ZERO, + v0, indexes, VecBuilderOptions::default().add_last(), - )?, - p2pk33: ComputedVecsFromHeight::forced_import( - &db, - "p2pk33_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2pkh: ComputedVecsFromHeight::forced_import( - &db, - "p2pkh_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2sh: ComputedVecsFromHeight::forced_import( - &db, - "p2sh_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2wpkh: ComputedVecsFromHeight::forced_import( - &db, - "p2wpkh_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2wsh: ComputedVecsFromHeight::forced_import( - &db, - "p2wsh_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2tr: ComputedVecsFromHeight::forced_import( - &db, - "p2tr_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2a: ComputedVecsFromHeight::forced_import( - &db, - "p2a_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - }, + ) + })?, ), addresstype_to_indexes_to_empty_addr_count: AddressTypeToIndexesToAddressCount::from( - ByAddressType { - p2pk65: ComputedVecsFromHeight::forced_import( + ByAddressType::new_with_name(|name| { + ComputedVecsFromHeight::forced_import( &db, - "p2pk65_empty_addr_count", + &format!("{name}_empty_addr_count"), Source::None, - version + VERSION + Version::ZERO, + v0, indexes, VecBuilderOptions::default().add_last(), - )?, - p2pk33: ComputedVecsFromHeight::forced_import( - &db, - "p2pk33_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2pkh: ComputedVecsFromHeight::forced_import( - &db, - "p2pkh_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2sh: ComputedVecsFromHeight::forced_import( - &db, - "p2sh_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2wpkh: ComputedVecsFromHeight::forced_import( - &db, - "p2wpkh_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2wsh: ComputedVecsFromHeight::forced_import( - &db, - "p2wsh_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2tr: ComputedVecsFromHeight::forced_import( - &db, - "p2tr_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - p2a: ComputedVecsFromHeight::forced_import( - &db, - "p2a_empty_addr_count", - Source::None, - version + VERSION + Version::ZERO, - indexes, - VecBuilderOptions::default().add_last(), - )?, - }, + ) + })?, ), utxo_cohorts, address_cohorts: address_cohorts::Vecs::forced_import( @@ -435,41 +254,41 @@ impl Vecs { &states_path, )?, - any_address_indexes: AnyAddressIndexes { + any_address_indexes: AnyAddressIndexesVecs { p2a: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2pk33: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2pk65: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2pkh: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2sh: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2tr: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2wpkh: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, p2wsh: BytesVec::forced_import_with( - ImportOptions::new(&db, "anyaddressindex", version + VERSION + Version::ZERO) + ImportOptions::new(&db, "anyaddressindex", v0) .with_saved_stamped_changes(SAVED_STAMPED_CHANGES), )?, }, - addresses_data: AddressesData { + addresses_data: AddressesDataVecs { loaded: loadedaddressindex_to_loadedaddressdata, empty: emptyaddressindex_to_emptyaddressdata, }, @@ -521,7 +340,7 @@ impl Vecs { let dateindex_to_height_count = &indexes.dateindex_to_height_count; let dateindex_to_price_close = price .as_ref() - .map(|price| price.timeindexes_to_price_close.dateindex.as_ref().unwrap()); + .map(|price| price.timeindexes_to_price_close.dateindex.u()); let height_to_date_fixed = &indexes.height_to_date_fixed; let height_to_first_p2aaddressindex = &indexer.vecs.height_to_first_p2aaddressindex; let height_to_first_p2pk33addressindex = &indexer.vecs.height_to_first_p2pk33addressindex; @@ -532,7 +351,7 @@ impl Vecs { let height_to_first_p2wpkhaddressindex = &indexer.vecs.height_to_first_p2wpkhaddressindex; let height_to_first_p2wshaddressindex = &indexer.vecs.height_to_first_p2wshaddressindex; let height_to_first_txindex = &indexer.vecs.height_to_first_txindex; - let height_to_txindex_count = chain.indexes_to_tx_count.height.as_ref().unwrap(); + let height_to_txindex_count = chain.indexes_to_tx_count.height.u(); let height_to_first_txinindex = &indexer.vecs.height_to_first_txinindex; let height_to_first_txoutindex = &indexer.vecs.height_to_first_txoutindex; let height_to_input_count = chain.indexes_to_input_count.height.unwrap_sum(); @@ -541,7 +360,7 @@ impl Vecs { .as_ref() .map(|price| &price.chainindexes_to_price_close.height); let height_to_timestamp_fixed = &indexes.height_to_timestamp_fixed; - let height_to_tx_count = chain.indexes_to_tx_count.height.as_ref().unwrap(); + let height_to_tx_count = chain.indexes_to_tx_count.height.u(); let height_to_unclaimed_rewards = chain .indexes_to_unclaimed_rewards .sats @@ -703,25 +522,26 @@ impl Vecs { Height::ZERO }; - // Import aggregate cohorts' price_to_amount - // We need to drop the borrows first to access utxo_cohorts directly - drop(separate_utxo_vecs); - drop(separate_address_vecs); - let starting_height = if starting_height.is_not_zero() - && self - .utxo_cohorts - .import_aggregate_price_to_amount(starting_height)? - == starting_height - { - starting_height - } else { - Height::ZERO + // Import aggregate cohorts' price_to_amount. + // Need to temporarily release the separate vecs borrows since iter_aggregate_mut + // borrows the whole UTXOGroups struct, even though it accesses non-overlapping fields. + let starting_height = { + drop(separate_utxo_vecs); + drop(separate_address_vecs); + let result = if starting_height.is_not_zero() + && self + .utxo_cohorts + .import_aggregate_price_to_amount(starting_height)? + == starting_height + { + starting_height + } else { + Height::ZERO + }; + separate_utxo_vecs = self.utxo_cohorts.iter_separate_mut().collect(); + separate_address_vecs = self.address_cohorts.iter_separate_mut().collect(); + result }; - // Re-collect the separate vecs - let mut separate_utxo_vecs = - self.utxo_cohorts.iter_separate_mut().collect::>(); - let mut separate_address_vecs = - self.address_cohorts.iter_separate_mut().collect::>(); // info!("starting_height = {starting_height}"); @@ -755,22 +575,18 @@ impl Vecs { self.any_address_indexes.reset()?; self.addresses_data.reset()?; - separate_utxo_vecs - .par_iter_mut() - .try_for_each(|v| { - v.reset_state_starting_height(); - v.state.as_mut().unwrap().reset_price_to_amount_if_needed() - })?; + separate_utxo_vecs.par_iter_mut().try_for_each(|v| { + v.reset_state_starting_height(); + v.state.um().reset_price_to_amount_if_needed() + })?; // Reset aggregate cohorts' price_to_amount self.utxo_cohorts.reset_aggregate_price_to_amount()?; - separate_address_vecs - .par_iter_mut() - .try_for_each(|v| { - v.reset_state_starting_height(); - v.state.as_mut().unwrap().reset_price_to_amount_if_needed() - })?; + separate_address_vecs.par_iter_mut().try_for_each(|v| { + v.reset_state_starting_height(); + v.state.um().reset_price_to_amount_if_needed() + })?; } chain_state_starting_height = starting_height; @@ -862,15 +678,11 @@ impl Vecs { self.utxo_cohorts .iter_separate_mut() - .for_each(|v| { - v.state.as_mut().unwrap().reset_single_iteration_values() - }); + .for_each(|v| v.state.um().reset_single_iteration_values()); self.address_cohorts .iter_separate_mut() - .for_each(|v| { - v.state.as_mut().unwrap().reset_single_iteration_values() - }); + .for_each(|v| v.state.um().reset_single_iteration_values()); let timestamp = height_to_timestamp_fixed_iter.get_unwrap(height); let price = height_to_price_close_iter @@ -1517,7 +1329,7 @@ impl Vecs { let dateindex_to_market_cap = self .indexes_to_market_cap .as_ref() - .map(|v| v.dateindex.as_ref().unwrap().clone()); + .map(|v| v.dateindex.u().clone()); let height_to_realized_cap = self.utxo_cohorts.all.inner.height_to_realized_cap.clone(); let dateindex_to_realized_cap = self .utxo_cohorts @@ -1526,7 +1338,7 @@ impl Vecs { .indexes_to_realized_cap .as_ref() .map(|v| v.dateindex.unwrap_last().clone()); - let dateindex_to_supply_ref = dateindex_to_supply.as_ref().unwrap(); + let dateindex_to_supply_ref = dateindex_to_supply.u(); let height_to_market_cap_ref = height_to_market_cap.as_ref(); let dateindex_to_market_cap_ref = dateindex_to_market_cap.as_ref(); let height_to_realized_cap_ref = height_to_realized_cap.as_ref(); @@ -1573,8 +1385,8 @@ impl Vecs { WithAddressDataSource, >, vr: &VecsReaders, - any_address_indexes: &AnyAddressIndexes, - addresses_data: &AddressesData, + any_address_indexes: &AnyAddressIndexesVecs, + addresses_data: &AddressesDataVecs, ) -> Option> { if *first_addressindexes.get(address_type).unwrap() <= typeindex { return Some(WithAddressDataSource::New(LoadedAddressData::default())); @@ -1782,474 +1594,3 @@ impl Vecs { } } -impl AddressTypeToVec<(TypeIndex, Sats)> { - #[allow(clippy::too_many_arguments)] - fn process_received( - self, - vecs: &mut address_cohorts::Vecs, - addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - addresstype_to_typeindex_to_emptyaddressdata: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - price: Option, - addresstype_to_addr_count: &mut ByAddressType, - addresstype_to_empty_addr_count: &mut ByAddressType, - stored_or_new_addresstype_to_typeindex_to_addressdatawithsource: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - ) { - self.unwrap().into_iter().for_each(|(_type, vec)| { - vec.into_iter().for_each(|(type_index, value)| { - let mut is_new = false; - let mut from_any_empty = false; - - let addressdata_withsource = addresstype_to_typeindex_to_loadedaddressdata - .get_mut(_type) - .unwrap() - .entry(type_index) - .or_insert_with(|| { - addresstype_to_typeindex_to_emptyaddressdata - .get_mut(_type) - .unwrap() - .remove(&type_index) - .map(|ad| { - from_any_empty = true; - ad.into() - }) - .unwrap_or_else(|| { - let addressdata = - stored_or_new_addresstype_to_typeindex_to_addressdatawithsource - .remove_for_type(_type, &type_index); - is_new = addressdata.is_new(); - from_any_empty = addressdata.is_from_emptyaddressdata(); - addressdata - }) - }); - - if is_new || from_any_empty { - (*addresstype_to_addr_count.get_mut(_type).unwrap()) += 1; - if from_any_empty { - (*addresstype_to_empty_addr_count.get_mut(_type).unwrap()) -= 1; - } - } - - let addressdata = addressdata_withsource.deref_mut(); - - let prev_amount = addressdata.balance(); - - let amount = prev_amount + value; - - if is_new - || from_any_empty - || vecs.amount_range.get_mut(amount).filter().clone() - != vecs.amount_range.get_mut(prev_amount).filter().clone() - { - if !is_new && !from_any_empty { - vecs.amount_range - .get_mut(prev_amount) - .state - .as_mut() - .unwrap() - .subtract(addressdata); - } - - addressdata.receive(value, price); - - vecs.amount_range - .get_mut(amount) - .state - .as_mut() - .unwrap() - .add(addressdata); - } else { - vecs.amount_range - .get_mut(amount) - .state - .as_mut() - .unwrap() - .receive(addressdata, value, price); - } - }); - }); - } -} - -impl HeightToAddressTypeToVec<(TypeIndex, Sats)> { - #[allow(clippy::too_many_arguments)] - fn process_sent( - self, - vecs: &mut address_cohorts::Vecs, - addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - addresstype_to_typeindex_to_emptyaddressdata: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - price: Option, - addresstype_to_addr_count: &mut ByAddressType, - addresstype_to_empty_addr_count: &mut ByAddressType, - height_to_price_close_vec: Option<&Vec>>, - height_to_timestamp_fixed_vec: &[Timestamp], - height: Height, - timestamp: Timestamp, - stored_or_new_addresstype_to_typeindex_to_addressdatawithsource: &mut AddressTypeToTypeIndexMap< - WithAddressDataSource, - >, - ) -> Result<()> { - self.0.into_iter().try_for_each(|(prev_height, v)| { - let prev_price = height_to_price_close_vec - .as_ref() - .map(|v| **v.get(prev_height.to_usize()).unwrap()); - - let prev_timestamp = *height_to_timestamp_fixed_vec - .get(prev_height.to_usize()) - .unwrap(); - - let blocks_old = height.to_usize() - prev_height.to_usize(); - - let days_old = timestamp.difference_in_days_between_float(prev_timestamp); - - let older_than_hour = timestamp - .checked_sub(prev_timestamp) - .unwrap() - .is_more_than_hour(); - - v.unwrap().into_iter().try_for_each(|(_type, vec)| { - vec.into_iter().try_for_each(|(type_index, value)| { - let typeindex_to_loadedaddressdata = - addresstype_to_typeindex_to_loadedaddressdata.get_mut_unwrap(_type); - - let addressdata_withsource = typeindex_to_loadedaddressdata - .entry(type_index) - .or_insert_with(|| { - stored_or_new_addresstype_to_typeindex_to_addressdatawithsource - .remove_for_type(_type, &type_index) - }); - - let addressdata = addressdata_withsource.deref_mut(); - - let prev_amount = addressdata.balance(); - - let amount = prev_amount.checked_sub(value).unwrap(); - - let will_be_empty = addressdata.has_1_utxos(); - - if will_be_empty - || vecs.amount_range.get_mut(amount).filter().clone() - != vecs.amount_range.get_mut(prev_amount).filter().clone() - { - vecs.amount_range - .get_mut(prev_amount) - .state - .as_mut() - .unwrap() - .subtract(addressdata); - - addressdata.send(value, prev_price)?; - - if will_be_empty { - if amount.is_not_zero() { - unreachable!() - } - - (*addresstype_to_addr_count.get_mut(_type).unwrap()) -= 1; - (*addresstype_to_empty_addr_count.get_mut(_type).unwrap()) += 1; - - let addressdata = - typeindex_to_loadedaddressdata.remove(&type_index).unwrap(); - - addresstype_to_typeindex_to_emptyaddressdata - .get_mut(_type) - .unwrap() - .insert(type_index, addressdata.into()); - } else { - vecs.amount_range - .get_mut(amount) - .state - .as_mut() - .unwrap() - .add(addressdata); - } - } else { - vecs.amount_range - .get_mut(amount) - .state - .as_mut() - .unwrap() - .send( - addressdata, - value, - price, - prev_price, - blocks_old, - days_old, - older_than_hour, - )?; - } - - Ok(()) - }) - }) - }) - } -} - -#[derive(Clone, Traversable)] -pub struct AnyAddressIndexes { - pub p2pk33: BytesVec, - pub p2pk65: BytesVec, - pub p2pkh: BytesVec, - pub p2sh: BytesVec, - pub p2tr: BytesVec, - pub p2wpkh: BytesVec, - pub p2wsh: BytesVec, - pub p2a: BytesVec, -} - -impl AnyAddressIndexes { - fn min_stamped_height(&self) -> Height { - Height::from(self.p2pk33.stamp()) - .incremented() - .min(Height::from(self.p2pk65.stamp()).incremented()) - .min(Height::from(self.p2pkh.stamp()).incremented()) - .min(Height::from(self.p2sh.stamp()).incremented()) - .min(Height::from(self.p2tr.stamp()).incremented()) - .min(Height::from(self.p2wpkh.stamp()).incremented()) - .min(Height::from(self.p2wsh.stamp()).incremented()) - .min(Height::from(self.p2a.stamp()).incremented()) - } - - fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 8]> { - Ok([ - self.p2pk33.rollback_before(stamp)?, - self.p2pk65.rollback_before(stamp)?, - self.p2pkh.rollback_before(stamp)?, - self.p2sh.rollback_before(stamp)?, - self.p2tr.rollback_before(stamp)?, - self.p2wpkh.rollback_before(stamp)?, - self.p2wsh.rollback_before(stamp)?, - self.p2a.rollback_before(stamp)?, - ]) - } - - fn reset(&mut self) -> Result<()> { - self.p2pk33.reset()?; - self.p2pk65.reset()?; - self.p2pkh.reset()?; - self.p2sh.reset()?; - self.p2tr.reset()?; - self.p2wpkh.reset()?; - self.p2wsh.reset()?; - self.p2a.reset()?; - Ok(()) - } - - fn get_anyaddressindex( - &self, - address_type: OutputType, - typeindex: TypeIndex, - reader: &Reader, - ) -> AnyAddressIndex { - match address_type { - OutputType::P2PK33 => self - .p2pk33 - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2PK65 => self - .p2pk65 - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2PKH => self - .p2pkh - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2SH => self - .p2sh - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2TR => self - .p2tr - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2WPKH => self - .p2wpkh - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2WSH => self - .p2wsh - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - OutputType::P2A => self - .p2a - .get_pushed_or_read_at_unwrap(typeindex.into(), reader), - _ => unreachable!(), - } - } - - fn update_or_push( - &mut self, - address_type: OutputType, - typeindex: TypeIndex, - anyaddressindex: AnyAddressIndex, - ) -> Result<()> { - (match address_type { - OutputType::P2PK33 => self - .p2pk33 - .update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2PK65 => self - .p2pk65 - .update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2PKH => self.p2pkh.update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2SH => self.p2sh.update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2TR => self.p2tr.update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2WPKH => self - .p2wpkh - .update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2WSH => self.p2wsh.update_or_push(typeindex.into(), anyaddressindex), - OutputType::P2A => self.p2a.update_or_push(typeindex.into(), anyaddressindex), - _ => unreachable!(), - })?; - Ok(()) - } - - fn stamped_flush_maybe_with_changes(&mut self, stamp: Stamp, with_changes: bool) -> Result<()> { - self.p2pk33 - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2pk65 - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2pkh - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2sh - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2tr - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2wpkh - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2wsh - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.p2a - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - Ok(()) - } -} - -#[derive(Clone, Traversable)] -pub struct AddressesData { - pub loaded: BytesVec, - pub empty: BytesVec, -} - -impl AddressesData { - fn min_stamped_height(&self) -> Height { - Height::from(self.loaded.stamp()) - .incremented() - .min(Height::from(self.empty.stamp()).incremented()) - } - - fn rollback_before(&mut self, stamp: Stamp) -> Result<[Stamp; 2]> { - Ok([ - self.loaded.rollback_before(stamp)?, - self.empty.rollback_before(stamp)?, - ]) - } - - fn reset(&mut self) -> Result<()> { - self.loaded.reset()?; - self.empty.reset()?; - Ok(()) - } - - fn stamped_flush_maybe_with_changes(&mut self, stamp: Stamp, with_changes: bool) -> Result<()> { - self.loaded - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - self.empty - .stamped_flush_maybe_with_changes(stamp, with_changes)?; - Ok(()) - } -} - -struct IndexerReaders { - txinindex_to_outpoint: Reader, - txindex_to_first_txoutindex: Reader, - txoutindex_to_value: Reader, - txoutindex_to_outputtype: Reader, - txoutindex_to_typeindex: Reader, -} - -impl IndexerReaders { - fn new(indexer: &Indexer) -> Self { - Self { - txinindex_to_outpoint: indexer.vecs.txinindex_to_outpoint.create_reader(), - txindex_to_first_txoutindex: indexer.vecs.txindex_to_first_txoutindex.create_reader(), - txoutindex_to_value: indexer.vecs.txoutindex_to_value.create_reader(), - txoutindex_to_outputtype: indexer.vecs.txoutindex_to_outputtype.create_reader(), - txoutindex_to_typeindex: indexer.vecs.txoutindex_to_typeindex.create_reader(), - } - } -} - -struct VecsReaders { - addresstypeindex_to_anyaddressindex: ByAddressType, - anyaddressindex_to_anyaddressdata: ByAnyAddress, -} - -impl VecsReaders { - fn new(vecs: &Vecs) -> Self { - Self { - addresstypeindex_to_anyaddressindex: ByAddressType { - p2pk33: vecs.any_address_indexes.p2pk33.create_reader(), - p2pk65: vecs.any_address_indexes.p2pk65.create_reader(), - p2pkh: vecs.any_address_indexes.p2pkh.create_reader(), - p2sh: vecs.any_address_indexes.p2sh.create_reader(), - p2tr: vecs.any_address_indexes.p2tr.create_reader(), - p2wpkh: vecs.any_address_indexes.p2wpkh.create_reader(), - p2wsh: vecs.any_address_indexes.p2wsh.create_reader(), - p2a: vecs.any_address_indexes.p2a.create_reader(), - }, - anyaddressindex_to_anyaddressdata: ByAnyAddress { - loaded: vecs.addresses_data.loaded.create_reader(), - empty: vecs.addresses_data.empty.create_reader(), - }, - } - } - - fn get_anyaddressindex_reader(&self, address_type: OutputType) -> &Reader { - self.addresstypeindex_to_anyaddressindex - .get_unwrap(address_type) - } -} - -fn build_txoutindex_to_txindex<'a>( - block_first_txindex: TxIndex, - block_tx_count: u64, - txindex_to_output_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>, -) -> Vec { - let mut vec = Vec::new(); - - let block_first_txindex = block_first_txindex.to_usize(); - for tx_offset in 0..block_tx_count as usize { - let txindex = TxIndex::from(block_first_txindex + tx_offset); - let output_count = u64::from(txindex_to_output_count.get_unwrap(txindex)); - - for _ in 0..output_count { - vec.push(txindex); - } - } - - vec -} - -fn build_txinindex_to_txindex<'a>( - block_first_txindex: TxIndex, - block_tx_count: u64, - txindex_to_input_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>, -) -> Vec { - let mut vec = Vec::new(); - - let block_first_txindex = block_first_txindex.to_usize(); - for tx_offset in 0..block_tx_count as usize { - let txindex = TxIndex::from(block_first_txindex + tx_offset); - let input_count = u64::from(txindex_to_input_count.get_unwrap(txindex)); - - for _ in 0..input_count { - vec.push(txindex); - } - } - - vec -} diff --git a/crates/brk_computer/src/stateful/readers.rs b/crates/brk_computer/src/stateful/readers.rs new file mode 100644 index 000000000..7cac3e696 --- /dev/null +++ b/crates/brk_computer/src/stateful/readers.rs @@ -0,0 +1,97 @@ +use brk_grouper::{ByAddressType, ByAnyAddress}; +use brk_indexer::Indexer; +use brk_types::{OutputType, StoredU64, TxIndex}; +use vecdb::{BoxedVecIterator, GenericStoredVec, Reader, VecIndex}; + +use super::Vecs; + +pub struct IndexerReaders { + pub txinindex_to_outpoint: Reader, + pub txindex_to_first_txoutindex: Reader, + pub txoutindex_to_value: Reader, + pub txoutindex_to_outputtype: Reader, + pub txoutindex_to_typeindex: Reader, +} + +impl IndexerReaders { + pub fn new(indexer: &Indexer) -> Self { + Self { + txinindex_to_outpoint: indexer.vecs.txinindex_to_outpoint.create_reader(), + txindex_to_first_txoutindex: indexer.vecs.txindex_to_first_txoutindex.create_reader(), + txoutindex_to_value: indexer.vecs.txoutindex_to_value.create_reader(), + txoutindex_to_outputtype: indexer.vecs.txoutindex_to_outputtype.create_reader(), + txoutindex_to_typeindex: indexer.vecs.txoutindex_to_typeindex.create_reader(), + } + } +} + +pub struct VecsReaders { + pub addresstypeindex_to_anyaddressindex: ByAddressType, + pub anyaddressindex_to_anyaddressdata: ByAnyAddress, +} + +impl VecsReaders { + pub fn new(vecs: &Vecs) -> Self { + Self { + addresstypeindex_to_anyaddressindex: ByAddressType { + p2pk33: vecs.any_address_indexes.p2pk33.create_reader(), + p2pk65: vecs.any_address_indexes.p2pk65.create_reader(), + p2pkh: vecs.any_address_indexes.p2pkh.create_reader(), + p2sh: vecs.any_address_indexes.p2sh.create_reader(), + p2tr: vecs.any_address_indexes.p2tr.create_reader(), + p2wpkh: vecs.any_address_indexes.p2wpkh.create_reader(), + p2wsh: vecs.any_address_indexes.p2wsh.create_reader(), + p2a: vecs.any_address_indexes.p2a.create_reader(), + }, + anyaddressindex_to_anyaddressdata: ByAnyAddress { + loaded: vecs.addresses_data.loaded.create_reader(), + empty: vecs.addresses_data.empty.create_reader(), + }, + } + } + + pub fn get_anyaddressindex_reader(&self, address_type: OutputType) -> &Reader { + self.addresstypeindex_to_anyaddressindex + .get_unwrap(address_type) + } +} + +pub fn build_txoutindex_to_txindex<'a>( + block_first_txindex: TxIndex, + block_tx_count: u64, + txindex_to_output_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>, +) -> Vec { + let mut vec = Vec::new(); + + let block_first_txindex = block_first_txindex.to_usize(); + for tx_offset in 0..block_tx_count as usize { + let txindex = TxIndex::from(block_first_txindex + tx_offset); + let output_count = u64::from(txindex_to_output_count.get_unwrap(txindex)); + + for _ in 0..output_count { + vec.push(txindex); + } + } + + vec +} + +pub fn build_txinindex_to_txindex<'a>( + block_first_txindex: TxIndex, + block_tx_count: u64, + txindex_to_input_count: &mut BoxedVecIterator<'a, TxIndex, StoredU64>, +) -> Vec { + let mut vec = Vec::new(); + + let block_first_txindex = block_first_txindex.to_usize(); + for tx_offset in 0..block_tx_count as usize { + let txindex = TxIndex::from(block_first_txindex + tx_offset); + let input_count = u64::from(txindex_to_input_count.get_unwrap(txindex)); + + for _ in 0..input_count { + vec.push(txindex); + } + } + + vec +} diff --git a/crates/brk_computer/src/stateful/transaction_processing.rs b/crates/brk_computer/src/stateful/transaction_processing.rs new file mode 100644 index 000000000..b55156123 --- /dev/null +++ b/crates/brk_computer/src/stateful/transaction_processing.rs @@ -0,0 +1,217 @@ +use brk_error::Result; +use brk_grouper::{ByAddressType, Filtered}; +use brk_types::{CheckedSub, Dollars, EmptyAddressData, Height, LoadedAddressData, Sats, Timestamp, TypeIndex}; +use vecdb::VecIndex; + +use crate::utils::OptionExt; + +use super::{ + address_cohorts, + addresstype::{ + AddressTypeToTypeIndexMap, AddressTypeToVec, + HeightToAddressTypeToVec, + }, + withaddressdatasource::WithAddressDataSource, +}; + +impl AddressTypeToVec<(TypeIndex, Sats)> { + #[allow(clippy::too_many_arguments)] + pub fn process_received( + self, + vecs: &mut address_cohorts::Vecs, + addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + addresstype_to_typeindex_to_emptyaddressdata: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + price: Option, + addresstype_to_addr_count: &mut ByAddressType, + addresstype_to_empty_addr_count: &mut ByAddressType, + stored_or_new_addresstype_to_typeindex_to_addressdatawithsource: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + ) { + self.unwrap().into_iter().for_each(|(_type, vec)| { + vec.into_iter().for_each(|(type_index, value)| { + let mut is_new = false; + let mut from_any_empty = false; + + let addressdata_withsource = addresstype_to_typeindex_to_loadedaddressdata + .get_mut(_type) + .unwrap() + .entry(type_index) + .or_insert_with(|| { + addresstype_to_typeindex_to_emptyaddressdata + .get_mut(_type) + .unwrap() + .remove(&type_index) + .map(|ad| { + from_any_empty = true; + ad.into() + }) + .unwrap_or_else(|| { + let addressdata = + stored_or_new_addresstype_to_typeindex_to_addressdatawithsource + .remove_for_type(_type, &type_index); + is_new = addressdata.is_new(); + from_any_empty = addressdata.is_from_emptyaddressdata(); + addressdata + }) + }); + + if is_new || from_any_empty { + (*addresstype_to_addr_count.get_mut(_type).unwrap()) += 1; + if from_any_empty { + (*addresstype_to_empty_addr_count.get_mut(_type).unwrap()) -= 1; + } + } + + let addressdata = addressdata_withsource.deref_mut(); + + let prev_amount = addressdata.balance(); + + let amount = prev_amount + value; + + if is_new + || from_any_empty + || vecs.amount_range.get_mut(amount).filter().clone() + != vecs.amount_range.get_mut(prev_amount).filter().clone() + { + if !is_new && !from_any_empty { + vecs.amount_range + .get_mut(prev_amount) + .state.um() + .subtract(addressdata); + } + + addressdata.receive(value, price); + + vecs.amount_range + .get_mut(amount) + .state.um() + .add(addressdata); + } else { + vecs.amount_range + .get_mut(amount) + .state.um() + .receive(addressdata, value, price); + } + }); + }); + } +} + +impl HeightToAddressTypeToVec<(TypeIndex, Sats)> { + #[allow(clippy::too_many_arguments)] + pub fn process_sent( + self, + vecs: &mut address_cohorts::Vecs, + addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + addresstype_to_typeindex_to_emptyaddressdata: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + price: Option, + addresstype_to_addr_count: &mut ByAddressType, + addresstype_to_empty_addr_count: &mut ByAddressType, + height_to_price_close_vec: Option<&Vec>>, + height_to_timestamp_fixed_vec: &[Timestamp], + height: Height, + timestamp: Timestamp, + stored_or_new_addresstype_to_typeindex_to_addressdatawithsource: &mut AddressTypeToTypeIndexMap< + WithAddressDataSource, + >, + ) -> Result<()> { + self.0.into_iter().try_for_each(|(prev_height, v)| { + let prev_price = height_to_price_close_vec + .as_ref() + .map(|v| **v.get(prev_height.to_usize()).unwrap()); + + let prev_timestamp = *height_to_timestamp_fixed_vec + .get(prev_height.to_usize()) + .unwrap(); + + let blocks_old = height.to_usize() - prev_height.to_usize(); + + let days_old = timestamp.difference_in_days_between_float(prev_timestamp); + + let older_than_hour = timestamp + .checked_sub(prev_timestamp) + .unwrap() + .is_more_than_hour(); + + v.unwrap().into_iter().try_for_each(|(_type, vec)| { + vec.into_iter().try_for_each(|(type_index, value)| { + let typeindex_to_loadedaddressdata = + addresstype_to_typeindex_to_loadedaddressdata.get_mut_unwrap(_type); + + let addressdata_withsource = typeindex_to_loadedaddressdata + .entry(type_index) + .or_insert_with(|| { + stored_or_new_addresstype_to_typeindex_to_addressdatawithsource + .remove_for_type(_type, &type_index) + }); + + let addressdata = addressdata_withsource.deref_mut(); + + let prev_amount = addressdata.balance(); + + let amount = prev_amount.checked_sub(value).unwrap(); + + let will_be_empty = addressdata.has_1_utxos(); + + if will_be_empty + || vecs.amount_range.get_mut(amount).filter().clone() + != vecs.amount_range.get_mut(prev_amount).filter().clone() + { + vecs.amount_range + .get_mut(prev_amount) + .state.um() + .subtract(addressdata); + + addressdata.send(value, prev_price)?; + + if will_be_empty { + if amount.is_not_zero() { + unreachable!() + } + + (*addresstype_to_addr_count.get_mut(_type).unwrap()) -= 1; + (*addresstype_to_empty_addr_count.get_mut(_type).unwrap()) += 1; + + let addressdata = + typeindex_to_loadedaddressdata.remove(&type_index).unwrap(); + + addresstype_to_typeindex_to_emptyaddressdata + .get_mut(_type) + .unwrap() + .insert(type_index, addressdata.into()); + } else { + vecs.amount_range + .get_mut(amount) + .state.um() + .add(addressdata); + } + } else { + vecs.amount_range + .get_mut(amount) + .state.um() + .send( + addressdata, + value, + price, + prev_price, + blocks_old, + days_old, + older_than_hour, + )?; + } + + Ok(()) + }) + }) + }) + } +} diff --git a/crates/brk_computer/src/stateful/utxo_cohort.rs b/crates/brk_computer/src/stateful/utxo_cohort.rs index eaeb1f52d..aebe57d9b 100644 --- a/crates/brk_computer/src/stateful/utxo_cohort.rs +++ b/crates/brk_computer/src/stateful/utxo_cohort.rs @@ -14,6 +14,7 @@ use crate::{ common, r#trait::{CohortVecs, DynCohortVecs}, }, + utils::OptionExt, }; #[derive(Clone, Traversable)] @@ -32,7 +33,6 @@ pub struct Vecs { } impl Vecs { - #[allow(clippy::too_many_arguments)] pub fn forced_import( db: &Database, filter: Filter, @@ -41,9 +41,6 @@ impl Vecs { price: Option<&price::Vecs>, states_path: &Path, state_level: StateLevel, - extended: bool, - compute_rel_to_all: bool, - compute_adjusted: bool, ) -> Result { let compute_dollars = price.is_some(); @@ -75,9 +72,6 @@ impl Vecs { version, indexes, price, - extended, - compute_rel_to_all, - compute_adjusted, )?, }) } @@ -95,7 +89,7 @@ impl DynCohortVecs for Vecs { fn import_state(&mut self, starting_height: Height) -> Result { let starting_height = self .inner - .import_state(starting_height, self.state.as_mut().unwrap())?; + .import_state(starting_height, self.state.um())?; self.state_starting_height = Some(starting_height); @@ -112,7 +106,7 @@ impl DynCohortVecs for Vecs { } self.inner - .truncate_push(height, self.state.as_ref().unwrap()) + .truncate_push(height, self.state.u()) } fn compute_then_truncate_push_unrealized_states( @@ -127,13 +121,13 @@ impl DynCohortVecs for Vecs { height_price, dateindex, date_price, - self.state.as_mut().unwrap(), + self.state.um(), ) } fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> { self.inner - .safe_flush_stateful_vecs(height, exit, self.state.as_mut().unwrap()) + .safe_flush_stateful_vecs(height, exit, self.state.um()) } #[allow(clippy::too_many_arguments)] diff --git a/crates/brk_computer/src/stateful/utxo_cohorts.rs b/crates/brk_computer/src/stateful/utxo_cohorts.rs index 365e08c39..a590685db 100644 --- a/crates/brk_computer/src/stateful/utxo_cohorts.rs +++ b/crates/brk_computer/src/stateful/utxo_cohorts.rs @@ -20,6 +20,7 @@ use crate::{ Indexes, indexes, price, stateful::r#trait::DynCohortVecs, states::{BlockState, Transacted}, + utils::OptionExt, }; use super::{r#trait::CohortVecs, utxo_cohort}; @@ -37,7 +38,21 @@ impl Vecs { price: Option<&price::Vecs>, states_path: &Path, ) -> Result { + let v = version + VERSION + Version::ZERO; + + // Helper to create a cohort - booleans are now derived from filter + let create = + |filter: Filter, state_level: StateLevel| -> Result { + utxo_cohort::Vecs::forced_import( + db, filter, v, indexes, price, states_path, state_level, + ) + }; + + let full = |f: Filter| create(f, StateLevel::Full); + let none = |f: Filter| create(f, StateLevel::None); + Ok(Self(UTXOGroups { + // Special case: all uses Version::ONE all: utxo_cohort::Vecs::forced_import( db, Filter::All, @@ -46,1407 +61,148 @@ impl Vecs { price, states_path, StateLevel::PriceOnly, - true, - false, - true, )?, + term: ByTerm { - short: utxo_cohort::Vecs::forced_import( - db, - Filter::Term(Term::Sth), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::PriceOnly, - true, - true, - true, - )?, - long: utxo_cohort::Vecs::forced_import( - db, - Filter::Term(Term::Lth), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::PriceOnly, - true, - true, - false, - )?, + short: create(Filter::Term(Term::Sth), StateLevel::PriceOnly)?, + long: create(Filter::Term(Term::Lth), StateLevel::PriceOnly)?, }, + epoch: ByEpoch { - _0: utxo_cohort::Vecs::forced_import( - db, - Filter::Epoch(HalvingEpoch::new(0)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _1: utxo_cohort::Vecs::forced_import( - db, - Filter::Epoch(HalvingEpoch::new(1)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _2: utxo_cohort::Vecs::forced_import( - db, - Filter::Epoch(HalvingEpoch::new(2)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _3: utxo_cohort::Vecs::forced_import( - db, - Filter::Epoch(HalvingEpoch::new(3)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _4: utxo_cohort::Vecs::forced_import( - db, - Filter::Epoch(HalvingEpoch::new(4)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, + _0: full(Filter::Epoch(HalvingEpoch::new(0)))?, + _1: full(Filter::Epoch(HalvingEpoch::new(1)))?, + _2: full(Filter::Epoch(HalvingEpoch::new(2)))?, + _3: full(Filter::Epoch(HalvingEpoch::new(3)))?, + _4: full(Filter::Epoch(HalvingEpoch::new(4)))?, }, + type_: BySpendableType { - p2pk65: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2PK65), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2pk33: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2PK33), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2pkh: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2PKH), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2sh: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2SH), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2wpkh: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2WPKH), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2wsh: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2WSH), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2tr: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2TR), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2a: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2A), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - p2ms: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::P2MS), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - empty: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::Empty), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - unknown: utxo_cohort::Vecs::forced_import( - db, - Filter::Type(OutputType::Unknown), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, + p2pk65: full(Filter::Type(OutputType::P2PK65))?, + p2pk33: full(Filter::Type(OutputType::P2PK33))?, + p2pkh: full(Filter::Type(OutputType::P2PKH))?, + p2sh: full(Filter::Type(OutputType::P2SH))?, + p2wpkh: full(Filter::Type(OutputType::P2WPKH))?, + p2wsh: full(Filter::Type(OutputType::P2WSH))?, + p2tr: full(Filter::Type(OutputType::P2TR))?, + p2a: full(Filter::Type(OutputType::P2A))?, + p2ms: full(Filter::Type(OutputType::P2MS))?, + empty: full(Filter::Type(OutputType::Empty))?, + unknown: full(Filter::Type(OutputType::Unknown))?, }, + max_age: ByMaxAge { - _1w: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(7)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _1m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _2m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(2 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _3m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(3 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _4m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(4 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _5m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(5 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _6m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(6 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _1y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _2y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(2 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _3y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(3 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _4y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(4 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _5y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(5 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _6y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(6 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _7y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(7 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _8y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(8 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _10y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(10 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _12y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(12 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, - _15y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::LowerThan(15 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - true, - )?, + _1w: none(Filter::Time(TimeFilter::LowerThan(7)))?, + _1m: none(Filter::Time(TimeFilter::LowerThan(30)))?, + _2m: none(Filter::Time(TimeFilter::LowerThan(2 * 30)))?, + _3m: none(Filter::Time(TimeFilter::LowerThan(3 * 30)))?, + _4m: none(Filter::Time(TimeFilter::LowerThan(4 * 30)))?, + _5m: none(Filter::Time(TimeFilter::LowerThan(5 * 30)))?, + _6m: none(Filter::Time(TimeFilter::LowerThan(6 * 30)))?, + _1y: none(Filter::Time(TimeFilter::LowerThan(365)))?, + _2y: none(Filter::Time(TimeFilter::LowerThan(2 * 365)))?, + _3y: none(Filter::Time(TimeFilter::LowerThan(3 * 365)))?, + _4y: none(Filter::Time(TimeFilter::LowerThan(4 * 365)))?, + _5y: none(Filter::Time(TimeFilter::LowerThan(5 * 365)))?, + _6y: none(Filter::Time(TimeFilter::LowerThan(6 * 365)))?, + _7y: none(Filter::Time(TimeFilter::LowerThan(7 * 365)))?, + _8y: none(Filter::Time(TimeFilter::LowerThan(8 * 365)))?, + _10y: none(Filter::Time(TimeFilter::LowerThan(10 * 365)))?, + _12y: none(Filter::Time(TimeFilter::LowerThan(12 * 365)))?, + _15y: none(Filter::Time(TimeFilter::LowerThan(15 * 365)))?, }, + min_age: ByMinAge { - _1d: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(1)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _1w: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(7)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _1m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _2m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(2 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _3m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(3 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _4m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(4 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _5m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(5 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _6m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(6 * 30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _1y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _2y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(2 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _3y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(3 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _4y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(4 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _5y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(5 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _6y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(6 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _7y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(7 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _8y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(8 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _10y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(10 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, - _12y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(12 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - true, - true, - false, - )?, + _1d: none(Filter::Time(TimeFilter::GreaterOrEqual(1)))?, + _1w: none(Filter::Time(TimeFilter::GreaterOrEqual(7)))?, + _1m: none(Filter::Time(TimeFilter::GreaterOrEqual(30)))?, + _2m: none(Filter::Time(TimeFilter::GreaterOrEqual(2 * 30)))?, + _3m: none(Filter::Time(TimeFilter::GreaterOrEqual(3 * 30)))?, + _4m: none(Filter::Time(TimeFilter::GreaterOrEqual(4 * 30)))?, + _5m: none(Filter::Time(TimeFilter::GreaterOrEqual(5 * 30)))?, + _6m: none(Filter::Time(TimeFilter::GreaterOrEqual(6 * 30)))?, + _1y: none(Filter::Time(TimeFilter::GreaterOrEqual(365)))?, + _2y: none(Filter::Time(TimeFilter::GreaterOrEqual(2 * 365)))?, + _3y: none(Filter::Time(TimeFilter::GreaterOrEqual(3 * 365)))?, + _4y: none(Filter::Time(TimeFilter::GreaterOrEqual(4 * 365)))?, + _5y: none(Filter::Time(TimeFilter::GreaterOrEqual(5 * 365)))?, + _6y: none(Filter::Time(TimeFilter::GreaterOrEqual(6 * 365)))?, + _7y: none(Filter::Time(TimeFilter::GreaterOrEqual(7 * 365)))?, + _8y: none(Filter::Time(TimeFilter::GreaterOrEqual(8 * 365)))?, + _10y: none(Filter::Time(TimeFilter::GreaterOrEqual(10 * 365)))?, + _12y: none(Filter::Time(TimeFilter::GreaterOrEqual(12 * 365)))?, }, + age_range: ByAgeRange { - up_to_1d: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(0..1)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - true, - )?, - _1d_to_1w: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(1..7)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _1w_to_1m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(7..30)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _1m_to_2m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(30..60)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _2m_to_3m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(60..90)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _3m_to_4m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(90..120)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _4m_to_5m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(120..150)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _5m_to_6m: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(150..180)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _6m_to_1y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(180..365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _1y_to_2y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(365..730)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _2y_to_3y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(730..1095)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _3y_to_4y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(1095..1460)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _4y_to_5y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(1460..1825)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _5y_to_6y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(1825..2190)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _6y_to_7y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(2190..2555)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _7y_to_8y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(2555..2920)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _8y_to_10y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(2920..3650)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _10y_to_12y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(3650..4380)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - _12y_to_15y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::Range(4380..5475)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, - from_15y: utxo_cohort::Vecs::forced_import( - db, - Filter::Time(TimeFilter::GreaterOrEqual(15 * 365)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - true, - true, - false, - )?, + up_to_1d: full(Filter::Time(TimeFilter::Range(0..1)))?, + _1d_to_1w: full(Filter::Time(TimeFilter::Range(1..7)))?, + _1w_to_1m: full(Filter::Time(TimeFilter::Range(7..30)))?, + _1m_to_2m: full(Filter::Time(TimeFilter::Range(30..60)))?, + _2m_to_3m: full(Filter::Time(TimeFilter::Range(60..90)))?, + _3m_to_4m: full(Filter::Time(TimeFilter::Range(90..120)))?, + _4m_to_5m: full(Filter::Time(TimeFilter::Range(120..150)))?, + _5m_to_6m: full(Filter::Time(TimeFilter::Range(150..180)))?, + _6m_to_1y: full(Filter::Time(TimeFilter::Range(180..365)))?, + _1y_to_2y: full(Filter::Time(TimeFilter::Range(365..730)))?, + _2y_to_3y: full(Filter::Time(TimeFilter::Range(730..1095)))?, + _3y_to_4y: full(Filter::Time(TimeFilter::Range(1095..1460)))?, + _4y_to_5y: full(Filter::Time(TimeFilter::Range(1460..1825)))?, + _5y_to_6y: full(Filter::Time(TimeFilter::Range(1825..2190)))?, + _6y_to_7y: full(Filter::Time(TimeFilter::Range(2190..2555)))?, + _7y_to_8y: full(Filter::Time(TimeFilter::Range(2555..2920)))?, + _8y_to_10y: full(Filter::Time(TimeFilter::Range(2920..3650)))?, + _10y_to_12y: full(Filter::Time(TimeFilter::Range(3650..4380)))?, + _12y_to_15y: full(Filter::Time(TimeFilter::Range(4380..5475)))?, + from_15y: full(Filter::Time(TimeFilter::GreaterOrEqual(15 * 365)))?, }, + amount_range: ByAmountRange { - _0sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_1)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _1sat_to_10sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_1..Sats::_10)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _10sats_to_100sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_10..Sats::_100)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _100sats_to_1k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_100..Sats::_1K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _1k_sats_to_10k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_1K..Sats::_10K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _10k_sats_to_100k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_10K..Sats::_100K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _100k_sats_to_1m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_100K..Sats::_1M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _1m_sats_to_10m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_1M..Sats::_10M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _10m_sats_to_1btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_10M..Sats::_1BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _1btc_to_10btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_1BTC..Sats::_10BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _10btc_to_100btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_10BTC..Sats::_100BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _100btc_to_1k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_100BTC..Sats::_1K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _1k_btc_to_10k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_1K_BTC..Sats::_10K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _10k_btc_to_100k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::Range(Sats::_10K_BTC..Sats::_100K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, - _100k_btc_or_more: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::Full, - false, - true, - false, - )?, + _0sats: full(Filter::Amount(AmountFilter::LowerThan(Sats::_1)))?, + _1sat_to_10sats: full(Filter::Amount(AmountFilter::Range(Sats::_1..Sats::_10)))?, + _10sats_to_100sats: full(Filter::Amount(AmountFilter::Range(Sats::_10..Sats::_100)))?, + _100sats_to_1k_sats: full(Filter::Amount(AmountFilter::Range(Sats::_100..Sats::_1K)))?, + _1k_sats_to_10k_sats: full(Filter::Amount(AmountFilter::Range(Sats::_1K..Sats::_10K)))?, + _10k_sats_to_100k_sats: full(Filter::Amount(AmountFilter::Range(Sats::_10K..Sats::_100K)))?, + _100k_sats_to_1m_sats: full(Filter::Amount(AmountFilter::Range(Sats::_100K..Sats::_1M)))?, + _1m_sats_to_10m_sats: full(Filter::Amount(AmountFilter::Range(Sats::_1M..Sats::_10M)))?, + _10m_sats_to_1btc: full(Filter::Amount(AmountFilter::Range(Sats::_10M..Sats::_1BTC)))?, + _1btc_to_10btc: full(Filter::Amount(AmountFilter::Range(Sats::_1BTC..Sats::_10BTC)))?, + _10btc_to_100btc: full(Filter::Amount(AmountFilter::Range(Sats::_10BTC..Sats::_100BTC)))?, + _100btc_to_1k_btc: full(Filter::Amount(AmountFilter::Range(Sats::_100BTC..Sats::_1K_BTC)))?, + _1k_btc_to_10k_btc: full(Filter::Amount(AmountFilter::Range(Sats::_1K_BTC..Sats::_10K_BTC)))?, + _10k_btc_to_100k_btc: full(Filter::Amount(AmountFilter::Range(Sats::_10K_BTC..Sats::_100K_BTC)))?, + _100k_btc_or_more: full(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100K_BTC)))?, }, + lt_amount: ByLowerThanAmount { - _10sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_10)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_100)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_1K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_10K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_100K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_1M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_10M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_1BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_10BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_100BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_1K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_10K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::LowerThan(Sats::_100K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, + _10sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_10)))?, + _100sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_100)))?, + _1k_sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_1K)))?, + _10k_sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_10K)))?, + _100k_sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_100K)))?, + _1m_sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_1M)))?, + _10m_sats: none(Filter::Amount(AmountFilter::LowerThan(Sats::_10M)))?, + _1btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_1BTC)))?, + _10btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_10BTC)))?, + _100btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_100BTC)))?, + _1k_btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_1K_BTC)))?, + _10k_btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_10K_BTC)))?, + _100k_btc: none(Filter::Amount(AmountFilter::LowerThan(Sats::_100K_BTC)))?, }, + ge_amount: ByGreatEqualAmount { - _1sat: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100k_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100K)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10m_sats: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10M)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _100btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _1k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, - _10k_btc: utxo_cohort::Vecs::forced_import( - db, - Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10K_BTC)), - version + VERSION + Version::ZERO, - indexes, - price, - states_path, - StateLevel::None, - false, - true, - false, - )?, + _1sat: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1)))?, + _10sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10)))?, + _100sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100)))?, + _1k_sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1K)))?, + _10k_sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10K)))?, + _100k_sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100K)))?, + _1m_sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1M)))?, + _10m_sats: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10M)))?, + _1btc: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1BTC)))?, + _10btc: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10BTC)))?, + _100btc: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_100BTC)))?, + _1k_btc: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_1K_BTC)))?, + _10k_btc: none(Filter::Amount(AmountFilter::GreaterOrEqual(Sats::_10K_BTC)))?, }, })) } @@ -1524,9 +280,9 @@ impl Vecs { let was = filter.contains_time(prev_days_old); if is && !was { - p2a.as_mut().unwrap().increment(price, &block_state.supply); + p2a.um().increment(price, &block_state.supply); } else if was && !is { - p2a.as_mut().unwrap().decrement(price, &block_state.supply); + p2a.um().decrement(price, &block_state.supply); } }); } @@ -1602,7 +358,7 @@ impl Vecs { _ => unreachable!(), }) .for_each(|vecs| { - vecs.state.as_mut().unwrap().send( + vecs.state.um().send( &sent.spendable_supply, current_price, prev_price, @@ -1616,7 +372,7 @@ impl Vecs { .spendable .iter_typed() .for_each(|(output_type, supply_state)| { - type_.get_mut(output_type).state.as_mut().unwrap().send( + type_.get_mut(output_type).state.um().send( supply_state, current_price, prev_price, @@ -1629,7 +385,7 @@ impl Vecs { sent.by_size_group .iter_typed() .for_each(|(group, supply_state)| { - amount_range.get_mut(group).state.as_mut().unwrap().send( + amount_range.get_mut(group).state.um().send( supply_state, current_price, prev_price, @@ -1648,7 +404,7 @@ impl Vecs { .filter(|(f, _)| f.contains_time(days_old)) .map(|(_, p2a)| p2a) .for_each(|p2a| { - p2a.as_mut().unwrap().decrement(prev_price, supply_state); + p2a.um().decrement(prev_price, supply_state); }); } } @@ -1664,7 +420,7 @@ impl Vecs { ] .into_iter() .for_each(|v| { - v.state.as_mut().unwrap().receive(&supply_state, price); + v.state.um().receive(&supply_state, price); }); // Update aggregate cohorts' price_to_amount @@ -1859,7 +615,7 @@ impl Vecs { .map(|sub| { ( sub.filter().clone(), - sub.state.as_ref().unwrap().supply.value, + sub.state.u().supply.value, ) }) .collect(); diff --git a/crates/brk_computer/src/states/cohorts/common.rs b/crates/brk_computer/src/states/cohorts/common.rs index a70822ff4..df99ad6f6 100644 --- a/crates/brk_computer/src/states/cohorts/common.rs +++ b/crates/brk_computer/src/states/cohorts/common.rs @@ -5,6 +5,7 @@ use brk_types::{CheckedSub, Dollars, Height, Sats}; use crate::{ grouped::{PERCENTILES, PERCENTILES_LEN}, + utils::OptionExt, PriceToAmount, RealizedState, SupplyState, UnrealizedState, }; @@ -49,11 +50,11 @@ impl CohortState { } pub fn price_to_amount_first_key_value(&self) -> Option<(&Dollars, &Sats)> { - self.price_to_amount.as_ref().unwrap().first_key_value() + self.price_to_amount.u().first_key_value() } pub fn price_to_amount_last_key_value(&self) -> Option<(&Dollars, &Sats)> { - self.price_to_amount.as_ref().unwrap().last_key_value() + self.price_to_amount.u().last_key_value() } pub fn reset_single_iteration_values(&mut self) { @@ -287,7 +288,7 @@ impl CohortState { height_price: Dollars, date_price: Option, ) -> (UnrealizedState, Option) { - if self.price_to_amount.as_ref().unwrap().is_empty() { + if self.price_to_amount.u().is_empty() { return ( UnrealizedState::NAN, date_price.map(|_| UnrealizedState::NAN), @@ -340,7 +341,7 @@ impl CohortState { price, date_price, sats, - date_unrealized_state.as_mut().unwrap(), + date_unrealized_state.um(), ) } }); diff --git a/crates/brk_computer/src/states/price_to_amount.rs b/crates/brk_computer/src/states/price_to_amount.rs index 995fedad2..d558d2173 100644 --- a/crates/brk_computer/src/states/price_to_amount.rs +++ b/crates/brk_computer/src/states/price_to_amount.rs @@ -11,7 +11,7 @@ use pco::standalone::{simple_decompress, simpler_compress}; use serde::{Deserialize, Serialize}; use vecdb::Bytes; -use crate::states::SupplyState; +use crate::{states::SupplyState, utils::OptionExt}; #[derive(Clone, Debug)] pub struct PriceToAmount { @@ -41,30 +41,30 @@ impl PriceToAmount { } pub fn iter(&self) -> impl Iterator { - self.state.as_ref().unwrap().iter() + self.state.u().iter() } pub fn is_empty(&self) -> bool { - self.state.as_ref().unwrap().is_empty() + self.state.u().is_empty() } pub fn first_key_value(&self) -> Option<(&Dollars, &Sats)> { - self.state.as_ref().unwrap().first_key_value() + self.state.u().first_key_value() } pub fn last_key_value(&self) -> Option<(&Dollars, &Sats)> { - self.state.as_ref().unwrap().last_key_value() + self.state.u().last_key_value() } pub fn increment(&mut self, price: Dollars, supply_state: &SupplyState) { - *self.state.as_mut().unwrap().entry(price).or_default() += supply_state.value; + *self.state.um().entry(price).or_default() += supply_state.value; } pub fn decrement(&mut self, price: Dollars, supply_state: &SupplyState) { - if let Some(amount) = self.state.as_mut().unwrap().get_mut(&price) { + if let Some(amount) = self.state.um().get_mut(&price) { *amount -= supply_state.value; if *amount == Sats::ZERO { - self.state.as_mut().unwrap().remove(&price); + self.state.um().remove(&price); } } else { dbg!(price, &self.pathbuf); @@ -114,7 +114,7 @@ impl PriceToAmount { fs::write( self.path_state(height), - self.state.as_ref().unwrap().serialize()?, + self.state.u().serialize()?, )?; Ok(()) diff --git a/crates/brk_computer/src/utils.rs b/crates/brk_computer/src/utils.rs index 574b63aca..ec0df2f70 100644 --- a/crates/brk_computer/src/utils.rs +++ b/crates/brk_computer/src/utils.rs @@ -1,5 +1,25 @@ use std::ops::{Add, Div}; +/// 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() + } +} + pub fn get_percentile(sorted: &[T], percentile: f64) -> T where T: Clone + Div + Add, diff --git a/crates/brk_grouper/src/filter.rs b/crates/brk_grouper/src/filter.rs index d0771e372..2acf4a393 100644 --- a/crates/brk_grouper/src/filter.rs +++ b/crates/brk_grouper/src/filter.rs @@ -106,4 +106,35 @@ impl Filter { _ => false, } } + + /// Whether to compute extended metrics (realized cap ratios, profit/loss ratios, percentiles) + /// For UTXO context: false for Type and Amount filters + /// For Address context: always false + pub fn is_extended(&self, context: CohortContext) -> bool { + match context { + CohortContext::Address => false, + CohortContext::Utxo => !matches!(self, Filter::Type(_) | Filter::Amount(_)), + } + } + + /// Whether to compute metrics relative to the "all" baseline + /// False only for All itself (it IS the baseline) + pub fn compute_rel_to_all(&self) -> bool { + !matches!(self, Filter::All) + } + + /// Whether to compute adjusted metrics (adjusted SOPR, adjusted value created/destroyed) + /// For UTXO context: true for All, Term, max_age (LowerThan), and up_to_1d age range + /// For Address context: always false + pub fn compute_adjusted(&self, context: CohortContext) -> bool { + match context { + CohortContext::Address => false, + CohortContext::Utxo => match self { + Filter::All | Filter::Term(_) => true, + Filter::Time(TimeFilter::LowerThan(_)) => true, + Filter::Time(TimeFilter::Range(r)) if r.start == 0 => true, + _ => false, + }, + } + } }