Compare commits

...

21 Commits

Author SHA1 Message Date
nym21 e9c0121a18 release: v0.0.107 2025-09-13 18:27:45 +02:00
nym21 01aa425f81 global: chain + cointime datasets 2025-09-13 18:26:28 +02:00
nym21 38d5c7dff6 computer: add tx annualized volume + tx velocity + rename _in_usd/_in_btc to _usd/_btc 2025-09-13 00:29:34 +02:00
nym21 e3b4b9b618 computer: some cleanup 2025-09-12 12:07:04 +02:00
nym21 a5951c58f3 global: add sent volume 2025-09-12 12:00:03 +02:00
nym21 504d6eaa9f cargo: update 2025-09-11 22:53:16 +02:00
nym21 6253fa30ef global: more mining related datasets 2025-09-11 18:45:54 +02:00
nym21 47f7cef4f4 global: add hash related datasets 2025-09-11 01:02:29 +02:00
nym21 72bba06e71 global: add mining related datasets 2025-09-10 21:57:15 +02:00
nym21 9b92c5ce38 computer: convert vecs functions to iterators 2025-09-10 16:25:38 +02:00
nym21 dfa077a1c9 computer: simplify compute_all functions 2025-09-09 19:22:56 +02:00
nym21 18fb2e7d4d release: v0.0.106 2025-09-09 17:53:09 +02:00
nym21 a610fd53e2 global: add min max choppiness datasets + fixes 2025-09-09 17:52:45 +02:00
nym21 16abce1f2d release: v0.0.105 2025-09-08 20:16:38 +02:00
nym21 f3b42f34a6 dist: add config back to config.toml 2025-09-08 20:16:21 +02:00
nym21 6483d324de release: v0.0.104 2025-09-08 20:02:18 +02:00
nym21 5ab97050dd ci: udpate dist + release.yml 2025-09-08 20:01:51 +02:00
nym21 17eed70903 release: v0.0.103 2025-09-08 19:24:00 +02:00
nym21 88067c03b7 release: v0.0.102 2025-09-08 19:21:43 +02:00
nym21 7c1e5b913f cargo: update 2025-09-08 19:20:53 +02:00
nym21 0014235e91 global: add price volatility datasets 2025-09-08 18:24:22 +02:00
67 changed files with 6519 additions and 5234 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ jobs:
# we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.29.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v4
with:
Generated
+247 -176
View File
File diff suppressed because it is too large Load Diff
+36 -16
View File
@@ -4,16 +4,25 @@ members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT"
package.edition = "2024"
package.version = "0.0.101"
package.version = "0.0.107"
package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md"
package.rust-version = "1.89"
[profile.dev]
lto = "thin"
debug = true
codegen-units = 1
opt-level = 3
overflow-checks = true
[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
strip = true
overflow-checks = false
[profile.profiling]
inherits = "release"
@@ -22,25 +31,36 @@ debug = true
[profile.dist]
inherits = "release"
[profile.clippy]
inherits = "dev"
lto = "off"
codegen-units = 256
opt-level = 0
incremental = true
debug = false
overflow-checks = false
panic = "abort"
debug-assertions = false
[workspace.dependencies]
allocative = { version = "0.3.4", features = ["parking_lot"] }
allocative_derive = "0.3.3"
axum = "0.8.4"
bitcoin = { version = "0.32.7", features = ["serde"] }
bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.101", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.101", path = "crates/brk_cli" }
brk_computer = { version = "0.0.101", path = "crates/brk_computer" }
brk_error = { version = "0.0.101", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.101", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.101", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.101", path = "crates/brk_interface" }
brk_logger = { version = "0.0.101", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.101", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.101", path = "crates/brk_parser" }
brk_server = { version = "0.0.101", path = "crates/brk_server" }
brk_store = { version = "0.0.101", path = "crates/brk_store" }
brk_structs = { version = "0.0.101", path = "crates/brk_structs" }
brk_bundler = { version = "0.0.107", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.107", path = "crates/brk_cli" }
brk_computer = { version = "0.0.107", path = "crates/brk_computer" }
brk_error = { version = "0.0.107", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.107", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.107", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.107", path = "crates/brk_interface" }
brk_logger = { version = "0.0.107", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.107", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.107", path = "crates/brk_parser" }
brk_server = { version = "0.0.107", path = "crates/brk_server" }
brk_store = { version = "0.0.107", path = "crates/brk_store" }
brk_structs = { version = "0.0.107", path = "crates/brk_structs" }
byteview = "=0.6.1"
derive_deref = "1.1.1"
fjall = "2.11.2"
@@ -56,7 +76,7 @@ serde_derive = "1.0.219"
serde_json = { version = "1.0.143", features = ["float_roundtrip"] }
tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]}
vecdb = { version = "0.2.11", features = ["derive"]}
vecdb = { version = "0.2.14", features = ["derive"]}
zerocopy = "0.8.27"
zerocopy-derive = "0.8.27"
@@ -67,7 +87,7 @@ pre-release-commit-message = "release: v{{version}}"
tag-message = "release: v{{version}}"
[workspace.metadata.dist]
cargo-dist-version = "0.29.0"
cargo-dist-version = "0.30.0"
ci = "github"
allow-dirty = ["ci"]
installers = []
+1 -1
View File
@@ -12,7 +12,7 @@ build = "build.rs"
[dependencies]
log = { workspace = true }
notify = "8.2.0"
brk_rolldown = "0.1.4"
brk_rolldown = "0.1.5"
# brk_rolldown = { path = "../../../rolldown/crates/rolldown"}
sugar_path = "1.2.0"
tokio = { workspace = true }
+1 -1
View File
@@ -28,7 +28,7 @@ minreq = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true }
toml = "0.9.5"
zip = { version = "5.0.0", default-features = false, features = ["deflate"] }
zip = { version = "5.1.1", default-features = false, features = ["deflate"] }
[[bin]]
name = "brk"
File diff suppressed because it is too large Load Diff
+211 -190
View File
@@ -1,10 +1,11 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF64, Version};
use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF32, StoredF64, Version};
use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator};
use crate::grouped::ComputedVecsFromDateIndex;
use super::{
Indexes, chain,
grouped::{
@@ -14,8 +15,6 @@ use super::{
indexes, price, stateful,
};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Vecs {
db: Database,
@@ -43,27 +42,32 @@ pub struct Vecs {
pub indexes_to_cointime_price: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_cap: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_price_ratio: ComputedRatioVecsFromDateIndex,
pub indexes_to_cointime_adj_inflation_rate: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_cointime_adj_tx_btc_velocity: ComputedVecsFromDateIndex<StoredF64>,
pub indexes_to_cointime_adj_tx_usd_velocity: ComputedVecsFromDateIndex<StoredF64>,
// pub indexes_to_thermo_cap_rel_to_investor_cap: ComputedValueVecsFromHeight,
}
impl Vecs {
pub fn forced_import(
parent: &Path,
version: Version,
parent_path: &Path,
parent_version: Version,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
) -> Result<Self> {
let db = Database::open(&parent.join("cointime"))?;
let db = Database::open(&parent_path.join("cointime"))?;
db.set_min_len(PAGE_SIZE * 1_000_000)?;
let compute_dollars = price.is_some();
let version = parent_version + Version::ZERO;
let this = Self {
indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import(
&db,
"coinblocks_created",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -71,7 +75,7 @@ impl Vecs {
&db,
"coinblocks_stored",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -79,7 +83,7 @@ impl Vecs {
&db,
"liveliness",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -87,7 +91,7 @@ impl Vecs {
&db,
"vaultedness",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -95,7 +99,7 @@ impl Vecs {
&db,
"activity_to_vaultedness_ratio",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -103,7 +107,7 @@ impl Vecs {
&db,
"vaulted_supply",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
@@ -112,7 +116,7 @@ impl Vecs {
&db,
"active_supply",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
@@ -121,7 +125,7 @@ impl Vecs {
&db,
"thermo_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -129,7 +133,7 @@ impl Vecs {
&db,
"investor_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -137,7 +141,7 @@ impl Vecs {
&db,
"vaulted_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -145,7 +149,7 @@ impl Vecs {
&db,
"active_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -153,7 +157,7 @@ impl Vecs {
&db,
"vaulted_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -161,7 +165,7 @@ impl Vecs {
&db,
"vaulted_price",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -169,7 +173,7 @@ impl Vecs {
&db,
"active_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -177,7 +181,7 @@ impl Vecs {
&db,
"active_price",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -185,7 +189,7 @@ impl Vecs {
&db,
"true_market_mean",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -193,7 +197,7 @@ impl Vecs {
&db,
"true_market_mean",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -201,7 +205,7 @@ impl Vecs {
&db,
"cointime_value_destroyed",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -209,7 +213,7 @@ impl Vecs {
&db,
"cointime_value_created",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -217,7 +221,7 @@ impl Vecs {
&db,
"cointime_value_stored",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -225,7 +229,7 @@ impl Vecs {
&db,
"cointime_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -233,7 +237,7 @@ impl Vecs {
&db,
"cointime_cap",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -241,17 +245,40 @@ impl Vecs {
&db,
"cointime_price",
Source::None,
version + VERSION + Version::ZERO,
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(),
)?,
db,
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -262,7 +289,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
@@ -270,15 +296,7 @@ impl Vecs {
stateful: &stateful::Vecs,
exit: &Exit,
) -> Result<()> {
self.compute_(
indexer,
indexes,
starting_indexes,
price,
chain,
stateful,
exit,
)?;
self.compute_(indexes, starting_indexes, price, chain, stateful, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
@@ -286,7 +304,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
@@ -296,12 +313,8 @@ impl Vecs {
) -> Result<()> {
let circulating_supply = &stateful.utxo_cohorts.all.1.height_to_supply;
self.indexes_to_coinblocks_created.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_coinblocks_created
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
circulating_supply,
@@ -309,18 +322,13 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let indexes_to_coinblocks_destroyed =
&stateful.utxo_cohorts.all.1.indexes_to_coinblocks_destroyed;
self.indexes_to_coinblocks_stored.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_coinblocks_stored
.compute_all(indexes, starting_indexes, exit, |vec| {
let mut coinblocks_destroyed_iter = indexes_to_coinblocks_destroyed
.height
.as_ref()
@@ -336,15 +344,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_liveliness.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_liveliness
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
indexes_to_coinblocks_destroyed
@@ -356,16 +359,11 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let liveliness = &self.indexes_to_liveliness;
self.indexes_to_vaultedness.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaultedness
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
liveliness.height.as_ref().unwrap(),
@@ -373,16 +371,14 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let vaultedness = &self.indexes_to_vaultedness;
self.indexes_to_activity_to_vaultedness_ratio.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_divide(
starting_indexes.height,
liveliness.height.as_ref().unwrap(),
@@ -394,12 +390,11 @@ impl Vecs {
)?;
self.indexes_to_vaulted_supply.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
circulating_supply,
@@ -411,12 +406,11 @@ impl Vecs {
)?;
self.indexes_to_active_supply.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
circulating_supply,
@@ -427,6 +421,32 @@ impl Vecs {
},
)?;
self.indexes_to_cointime_adj_inflation_rate
.compute_all(starting_indexes, exit, |v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_inflation_rate.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
self.indexes_to_cointime_adj_tx_btc_velocity
.compute_all(starting_indexes, exit, |v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_tx_btc_velocity.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
if let Some(price) = price {
let realized_cap = stateful
.utxo_cohorts
@@ -447,12 +467,8 @@ impl Vecs {
.as_ref()
.unwrap();
self.indexes_to_thermo_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_thermo_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
chain
@@ -466,15 +482,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_investor_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_investor_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_subtract(
starting_indexes.height,
realized_cap,
@@ -482,15 +493,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaulted_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
realized_cap,
@@ -498,15 +504,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_active_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_active_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
realized_cap,
@@ -514,15 +515,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaulted_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
realized_price,
@@ -530,24 +526,17 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
Some(self.indexes_to_vaulted_price.dateindex.unwrap_last()),
)?;
self.indexes_to_active_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_active_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
realized_price,
@@ -555,12 +544,9 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_active_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
@@ -568,11 +554,10 @@ impl Vecs {
)?;
self.indexes_to_true_market_mean.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_divide(
starting_indexes.height,
self.indexes_to_investor_cap.height.as_ref().unwrap(),
@@ -588,8 +573,6 @@ impl Vecs {
)?;
self.indexes_to_true_market_mean_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
@@ -597,11 +580,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_destroyed.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
// TODO: Another example when the callback should be applied to each index, instead of to base then merging from more granular to less
// The price taken won't be correct for time based indexes
vec.compute_multiply(
@@ -615,11 +597,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_created.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
&price.chainindexes_to_price_close.height,
@@ -631,11 +612,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_stored.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
&price.chainindexes_to_price_close.height,
@@ -646,12 +626,8 @@ impl Vecs {
},
)?;
self.indexes_to_cointime_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_cointime_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
self.indexes_to_cointime_value_destroyed
@@ -663,15 +639,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_cointime_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_cointime_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
self.indexes_to_cointime_price.height.as_ref().unwrap(),
@@ -679,50 +650,100 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_cointime_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
Some(self.indexes_to_cointime_price.dateindex.unwrap_last()),
)?;
self.indexes_to_cointime_adj_tx_usd_velocity.compute_all(
starting_indexes,
exit,
|v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_tx_usd_velocity.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
},
)?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_coinblocks_created.vecs(),
self.indexes_to_coinblocks_stored.vecs(),
self.indexes_to_liveliness.vecs(),
self.indexes_to_vaultedness.vecs(),
self.indexes_to_activity_to_vaultedness_ratio.vecs(),
self.indexes_to_vaulted_supply.vecs(),
self.indexes_to_active_supply.vecs(),
self.indexes_to_thermo_cap.vecs(),
self.indexes_to_investor_cap.vecs(),
self.indexes_to_vaulted_cap.vecs(),
self.indexes_to_active_cap.vecs(),
self.indexes_to_vaulted_price.vecs(),
self.indexes_to_vaulted_price_ratio.vecs(),
self.indexes_to_active_price.vecs(),
self.indexes_to_active_price_ratio.vecs(),
self.indexes_to_true_market_mean.vecs(),
self.indexes_to_true_market_mean_ratio.vecs(),
self.indexes_to_cointime_price.vecs(),
self.indexes_to_cointime_cap.vecs(),
self.indexes_to_cointime_price_ratio.vecs(),
self.indexes_to_cointime_value_destroyed.vecs(),
self.indexes_to_cointime_value_created.vecs(),
self.indexes_to_cointime_value_stored.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_inflation_rate
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_tx_btc_velocity
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_tx_usd_velocity
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_coinblocks_created.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_coinblocks_stored.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_liveliness.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaultedness.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_activity_to_vaultedness_ratio
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_vaulted_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_thermo_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_investor_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_price_ratio.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_price_ratio.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_true_market_mean.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_true_market_mean_ratio
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_cointime_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_cointime_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_cointime_price_ratio.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_cointime_value_destroyed
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_value_created
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_cointime_value_stored.iter_any_collectable()));
iter
}
}
+79 -57
View File
@@ -1,8 +1,7 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{StoredI16, StoredU16, Version};
use brk_structs::{StoredF32, StoredI16, StoredU16, Version};
use vecdb::{AnyCollectableVec, AnyVec, Database, Exit};
use crate::grouped::Source;
@@ -24,7 +23,9 @@ pub struct Vecs {
pub constant_2: ComputedVecsFromHeight<StoredU16>,
pub constant_3: ComputedVecsFromHeight<StoredU16>,
pub constant_4: ComputedVecsFromHeight<StoredU16>,
pub constant_38_2: ComputedVecsFromHeight<StoredF32>,
pub constant_50: ComputedVecsFromHeight<StoredU16>,
pub constant_61_8: ComputedVecsFromHeight<StoredF32>,
pub constant_100: ComputedVecsFromHeight<StoredU16>,
pub constant_600: ComputedVecsFromHeight<StoredU16>,
pub constant_minus_1: ComputedVecsFromHeight<StoredI16>,
@@ -78,6 +79,14 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_38_2: ComputedVecsFromHeight::forced_import(
&db,
"constant_38_2",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_50: ComputedVecsFromHeight::forced_import(
&db,
"constant_50",
@@ -86,6 +95,14 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_61_8: ComputedVecsFromHeight::forced_import(
&db,
"constant_61_8",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_100: ComputedVecsFromHeight::forced_import(
&db,
"constant_100",
@@ -139,8 +156,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -150,19 +166,17 @@ impl Vecs {
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, exit)?;
self.compute_(indexes, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
@@ -179,22 +193,16 @@ impl Vecs {
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
},
)
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
})
})?;
[
@@ -205,44 +213,58 @@ impl Vecs {
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(value)),
exit,
)?;
Ok(())
},
)
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(value)),
exit,
)?;
Ok(())
})
})?;
[
(&mut self.constant_38_2, 38.2),
(&mut self.constant_61_8, 61.8),
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredF32::from(value)),
exit,
)?;
Ok(())
})
})?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.constant_0.vecs(),
self.constant_1.vecs(),
self.constant_2.vecs(),
self.constant_3.vecs(),
self.constant_4.vecs(),
self.constant_50.vecs(),
self.constant_100.vecs(),
self.constant_600.vecs(),
self.constant_minus_1.vecs(),
self.constant_minus_2.vecs(),
self.constant_minus_3.vecs(),
self.constant_minus_4.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
iter = Box::new(iter.chain(self.constant_0.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_1.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_3.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_4.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_38_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_50.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_61_8.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_100.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_600.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_1.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_3.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_4.iter_any_collectable()));
iter
}
}
+4 -4
View File
@@ -42,8 +42,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -140,10 +139,11 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[
&self.dateindex_to_price_ohlc_in_cents as &dyn AnyCollectableVec,
&self.height_to_price_ohlc_in_cents,
]
.into_iter()
}
}
@@ -1,473 +0,0 @@
use brk_error::Result;
use brk_structs::Version;
use vecdb::{
AnyBoxedIterableVec, AnyCloneableIterableVec, AnyCollectableVec, AnyIterableVec, Computation,
ComputedVec, ComputedVecFrom2, Database, Exit, Format, FromCoarserIndex, StoredIndex,
};
use crate::grouped::{EagerVecBuilder, VecBuilderOptions};
use super::ComputedType;
#[allow(clippy::type_complexity)]
#[derive(Clone)]
pub struct ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType,
S2T: ComputedType,
{
pub first: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub average: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub sum: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub max: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub min: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub last: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub cumulative: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
}
const VERSION: Version = Version::ZERO;
impl<I, T, S1I, S2T> ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType + 'static,
S1I: StoredIndex + 'static + FromCoarserIndex<I>,
S2T: ComputedType,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
db: &Database,
name: &str,
version: Version,
format: Format,
computation: Computation,
source: Option<AnyBoxedIterableVec<S1I, T>>,
source_extra: &EagerVecBuilder<S1I, T>,
len_source: AnyBoxedIterableVec<I, S2T>,
options: ComputedVecBuilderOptions,
) -> Result<Self> {
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)
}
};
Ok(Self {
first: options.first.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("first"),
version + VERSION + Version::ZERO,
format,
source_extra
.first
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::min_from(i))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
last: options.last.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
name,
version + VERSION + Version::ZERO,
format,
source_extra.last.as_ref().map_or_else(
|| {
source
.as_ref()
.unwrap_or_else(|| {
dbg!(db, name, I::to_string());
panic!()
})
.clone()
},
|v| v.clone(),
),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
min: options.min.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("min"),
version + VERSION + Version::ZERO,
format,
source_extra
.min
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.min()
},
)
.unwrap(),
)
}),
max: options.max.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("max"),
version + VERSION + Version::ZERO,
format,
source_extra
.max
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.max()
},
)
.unwrap(),
)
}),
average: options.average.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("average"),
version + VERSION + Version::ZERO,
format,
source_extra
.average
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
let len = vec.len();
vec.into_iter().for_each(|v| sum += v);
Some(sum / len)
},
)
.unwrap(),
)
}),
sum: options.sum.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&(if !options.last && !options.average && !options.min && !options.max {
name.to_string()
} else {
maybe_suffix("sum")
}),
version + VERSION + Version::ZERO,
format,
source_extra
.sum
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
vec.into_iter().for_each(|v| sum += v);
Some(sum)
},
)
.unwrap(),
)
}),
cumulative: options.cumulative.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&suffix("cumulative"),
version + VERSION + Version::ZERO,
format,
source_extra.cumulative.as_ref().unwrap().boxed_clone(),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
})
}
pub fn compute_if_necessary<T2>(
&mut self,
max_from: I,
len_source: &impl AnyIterableVec<I, T2>,
exit: &Exit,
) -> Result<()> {
if let Some(first) = self.first.as_mut() {
first.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(last) = self.last.as_mut() {
last.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(min) = self.min.as_mut() {
min.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(max) = self.max.as_mut() {
max.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(average) = self.average.as_mut() {
average.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(sum) = self.sum.as_mut() {
sum.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.compute_if_necessary(max_from, len_source, exit)?;
}
Ok(())
}
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
))
}
pub fn unwrap_first(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.first.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_average(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.average.as_ref().unwrap()
}
pub fn unwrap_sum(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.sum.as_ref().unwrap()
}
pub fn unwrap_max(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.max.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.min.as_ref().unwrap()
}
pub fn unwrap_last(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.last.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_cumulative(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
v
}
}
#[derive(Default, Clone, Copy)]
pub struct ComputedVecBuilderOptions {
average: bool,
sum: bool,
max: bool,
min: bool,
first: bool,
last: bool,
cumulative: bool,
}
impl From<VecBuilderOptions> for ComputedVecBuilderOptions {
fn from(value: VecBuilderOptions) -> Self {
Self {
average: value.average(),
sum: value.sum(),
max: value.max(),
min: value.min(),
first: value.first(),
last: value.last(),
cumulative: value.cumulative(),
}
}
}
impl ComputedVecBuilderOptions {
pub fn add_first(mut self) -> Self {
self.first = true;
self
}
pub fn add_last(mut self) -> Self {
self.last = true;
self
}
pub fn add_min(mut self) -> Self {
self.min = true;
self
}
pub fn add_max(mut self) -> Self {
self.max = true;
self
}
pub fn add_average(mut self) -> Self {
self.average = true;
self
}
pub fn add_sum(mut self) -> Self {
self.sum = true;
self
}
pub fn add_cumulative(mut self) -> Self {
self.cumulative = true;
self
}
#[allow(unused)]
pub fn rm_min(mut self) -> Self {
self.min = false;
self
}
#[allow(unused)]
pub fn rm_max(mut self) -> Self {
self.max = false;
self
}
#[allow(unused)]
pub fn rm_average(mut self) -> Self {
self.average = false;
self
}
#[allow(unused)]
pub fn rm_sum(mut self) -> Self {
self.sum = false;
self
}
#[allow(unused)]
pub fn rm_cumulative(mut self) -> Self {
self.cumulative = false;
self
}
pub fn add_minmax(mut self) -> Self {
self.min = true;
self.max = true;
self
}
pub fn is_only_one_active(&self) -> bool {
[
self.average,
self.sum,
self.max,
self.min,
self.first,
self.last,
self.cumulative,
]
.iter()
.filter(|b| **b)
.count()
== 1
}
pub fn copy_self_extra(&self) -> Self {
Self {
cumulative: self.cumulative,
..Self::default()
}
}
}
+181 -132
View File
@@ -20,11 +20,11 @@ where
pub average: Option<Box<EagerVec<I, T>>>,
pub sum: Option<Box<EagerVec<I, T>>>,
pub max: Option<Box<EagerVec<I, T>>>,
pub p90: Option<Box<EagerVec<I, T>>>,
pub p75: Option<Box<EagerVec<I, T>>>,
pub pct90: Option<Box<EagerVec<I, T>>>,
pub pct75: Option<Box<EagerVec<I, T>>>,
pub median: Option<Box<EagerVec<I, T>>>,
pub p25: Option<Box<EagerVec<I, T>>>,
pub p10: Option<Box<EagerVec<I, T>>>,
pub pct25: Option<Box<EagerVec<I, T>>>,
pub pct10: Option<Box<EagerVec<I, T>>>,
pub min: Option<Box<EagerVec<I, T>>>,
pub last: Option<Box<EagerVec<I, T>>>,
pub cumulative: Option<Box<EagerVec<I, T>>>,
@@ -152,44 +152,44 @@ where
.unwrap(),
)
}),
p90: options.p90.then(|| {
pct90: options.pct90.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p90"),
&maybe_suffix("pct90"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p75: options.p75.then(|| {
pct75: options.pct75.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p75"),
&maybe_suffix("pct75"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p25: options.p25.then(|| {
pct25: options.pct25.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p25"),
&maybe_suffix("pct25"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p10: options.p10.then(|| {
pct10: options.pct10.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p10"),
&maybe_suffix("pct10"),
version + VERSION + Version::ZERO,
format,
)
@@ -293,11 +293,11 @@ where
let needs_average_sum_or_cumulative =
needs_sum_or_cumulative || self.average.is_some();
let needs_sorted = self.max.is_some()
|| self.p90.is_some()
|| self.p75.is_some()
|| self.pct90.is_some()
|| self.pct75.is_some()
|| self.median.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
|| self.pct25.is_some()
|| self.pct10.is_some()
|| self.min.is_some();
let needs_values = needs_sorted || needs_average_sum_or_cumulative;
@@ -334,24 +334,24 @@ where
)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
}
if let Some(median) = self.median.as_mut() {
median.forced_push_at(index, get_percentile(&values, 0.50), exit)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
}
if let Some(min) = self.min.as_mut() {
@@ -402,11 +402,11 @@ where
where
I2: StoredIndex + StoredRaw + CheckedSub<I2>,
{
if self.p90.is_some()
|| self.p75.is_some()
if self.pct90.is_some()
|| self.pct75.is_some()
|| self.median.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
|| self.pct25.is_some()
|| self.pct10.is_some()
{
panic!("unsupported");
}
@@ -541,7 +541,7 @@ where
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
self.iter_any_collectable().map(|v| v.len()).min().unwrap(),
))
}
@@ -559,24 +559,24 @@ where
self.max.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p90(&self) -> &EagerVec<I, T> {
self.p90.as_ref().unwrap()
pub fn unwrap_pct90(&self) -> &EagerVec<I, T> {
self.pct90.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p75(&self) -> &EagerVec<I, T> {
self.p75.as_ref().unwrap()
pub fn unwrap_pct75(&self) -> &EagerVec<I, T> {
self.pct75.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_median(&self) -> &EagerVec<I, T> {
self.median.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p25(&self) -> &EagerVec<I, T> {
self.p25.as_ref().unwrap()
pub fn unwrap_pct25(&self) -> &EagerVec<I, T> {
self.pct25.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p10(&self) -> &EagerVec<I, T> {
self.p10.as_ref().unwrap()
pub fn unwrap_pct10(&self) -> &EagerVec<I, T> {
self.pct10.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &EagerVec<I, T> {
self.min.as_ref().unwrap()
@@ -589,47 +589,96 @@ where
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(median) = self.median.as_ref() {
v.push(median.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
if let Some(p90) = self.p90.as_ref() {
v.push(p90.as_ref());
}
if let Some(p75) = self.p75.as_ref() {
v.push(p75.as_ref());
}
if let Some(p25) = self.p25.as_ref() {
v.push(p25.as_ref());
}
if let Some(p10) = self.p10.as_ref() {
v.push(p10.as_ref());
}
iter = Box::new(
iter.chain(
self.first
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.last
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.min
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.max
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.median
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.average
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.sum
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.cumulative
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct90
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct75
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct25
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct10
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
v
iter
}
pub fn safe_flush(&mut self, exit: &Exit) -> Result<()> {
@@ -657,17 +706,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.safe_flush(exit)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.safe_flush(exit)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.safe_flush(exit)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.safe_flush(exit)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.safe_flush(exit)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.safe_flush(exit)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.safe_flush(exit)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.safe_flush(exit)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.safe_flush(exit)?;
}
Ok(())
@@ -698,17 +747,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.validate_computed_version_or_reset(Version::ZERO + version)?;
}
Ok(())
@@ -720,11 +769,11 @@ pub struct VecBuilderOptions {
average: bool,
sum: bool,
max: bool,
p90: bool,
p75: bool,
pct90: bool,
pct75: bool,
median: bool,
p25: bool,
p10: bool,
pct25: bool,
pct10: bool,
min: bool,
first: bool,
last: bool,
@@ -744,24 +793,24 @@ impl VecBuilderOptions {
self.max
}
pub fn p90(&self) -> bool {
self.p90
pub fn pct90(&self) -> bool {
self.pct90
}
pub fn p75(&self) -> bool {
self.p75
pub fn pct75(&self) -> bool {
self.pct75
}
pub fn median(&self) -> bool {
self.median
}
pub fn p25(&self) -> bool {
self.p25
pub fn pct25(&self) -> bool {
self.pct25
}
pub fn p10(&self) -> bool {
self.p10
pub fn pct10(&self) -> bool {
self.pct10
}
pub fn min(&self) -> bool {
@@ -817,26 +866,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn add_p90(mut self) -> Self {
self.p90 = true;
pub fn add_pct90(mut self) -> Self {
self.pct90 = true;
self
}
#[allow(unused)]
pub fn add_p75(mut self) -> Self {
self.p75 = true;
pub fn add_pct75(mut self) -> Self {
self.pct75 = true;
self
}
#[allow(unused)]
pub fn add_p25(mut self) -> Self {
self.p25 = true;
pub fn add_pct25(mut self) -> Self {
self.pct25 = true;
self
}
#[allow(unused)]
pub fn add_p10(mut self) -> Self {
self.p10 = true;
pub fn add_pct10(mut self) -> Self {
self.pct10 = true;
self
}
@@ -876,26 +925,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn rm_p90(mut self) -> Self {
self.p90 = false;
pub fn rm_pct90(mut self) -> Self {
self.pct90 = false;
self
}
#[allow(unused)]
pub fn rm_p75(mut self) -> Self {
self.p75 = false;
pub fn rm_pct75(mut self) -> Self {
self.pct75 = false;
self
}
#[allow(unused)]
pub fn rm_p25(mut self) -> Self {
self.p25 = false;
pub fn rm_pct25(mut self) -> Self {
self.pct25 = false;
self
}
#[allow(unused)]
pub fn rm_p10(mut self) -> Self {
self.p10 = false;
pub fn rm_pct10(mut self) -> Self {
self.pct10 = false;
self
}
@@ -912,20 +961,20 @@ impl VecBuilderOptions {
}
pub fn add_percentiles(mut self) -> Self {
self.p90 = true;
self.p75 = true;
self.pct90 = true;
self.pct75 = true;
self.median = true;
self.p25 = true;
self.p10 = true;
self.pct25 = true;
self.pct10 = true;
self
}
pub fn remove_percentiles(mut self) -> Self {
self.p90 = false;
self.p75 = false;
self.pct90 = false;
self.pct75 = false;
self.median = false;
self.p25 = false;
self.p10 = false;
self.pct25 = false;
self.pct10 = false;
self
}
@@ -934,11 +983,11 @@ impl VecBuilderOptions {
self.average,
self.sum,
self.max,
self.p90,
self.p75,
self.pct90,
self.pct75,
self.median,
self.p25,
self.p10,
self.pct25,
self.pct10,
self.min,
self.first,
self.last,
+54 -25
View File
@@ -217,7 +217,7 @@ where
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
self.iter_any_collectable().map(|v| v.len()).min().unwrap(),
))
}
@@ -245,32 +245,61 @@ where
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
iter = Box::new(
iter.chain(
self.first
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.last
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.min
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.max
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.average
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.sum
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.cumulative
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
v
iter
}
}
@@ -1,7 +1,6 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex,
};
@@ -112,28 +111,14 @@ where
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, T>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, T>) -> Result<()>,
{
compute(
self.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.dateindex.as_mut().unwrap())?;
let dateindex: Option<&EagerVec<DateIndex, T>> = None;
self.compute_rest(starting_indexes, exit, dateindex)
@@ -158,21 +143,22 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.dateindex
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_extra.vecs(),
self.weekindex.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.dateindex_extra.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
+19 -27
View File
@@ -1,7 +1,6 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
Version, WeekIndex, YearIndex,
@@ -134,22 +133,15 @@ where
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(&mut EagerVec<Height, T>, &Indexer, &indexes::Vecs, &Indexes, &Exit) -> Result<()>,
F: FnMut(&mut EagerVec<Height, T>) -> Result<()>,
{
compute(
self.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.height.as_mut().unwrap())?;
let height: Option<&EagerVec<Height, T>> = None;
self.compute_rest(indexes, starting_indexes, exit, height)
@@ -207,24 +199,24 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.height
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.height_extra.vecs(),
self.dateindex.vecs(),
self.weekindex.vecs(),
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.height_extra.iter_any_collectable()));
iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
@@ -1,6 +1,5 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{DifficultyEpoch, Height, Version};
use vecdb::{AnyCollectableVec, Database, EagerVec, Exit};
@@ -59,16 +58,15 @@ where
pub fn compute<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(&mut EagerVec<Height, T>, &Indexer, &indexes::Vecs, &Indexes, &Exit) -> Result<()>,
F: FnMut(&mut EagerVec<Height, T>) -> Result<()>,
{
compute(&mut self.height, indexer, indexes, starting_indexes, exit)?;
compute(&mut self.height)?;
self.height_extra
.extend(starting_indexes.height, &self.height, exit)?;
@@ -84,15 +82,10 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![&self.height as &dyn AnyCollectableVec],
self.height_extra.vecs(),
self.difficultyepoch.vecs(),
// self.halvingepoch.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.height as &dyn AnyCollectableVec]
.into_iter()
.chain(self.height_extra.iter_any_collectable())
.chain(self.difficultyepoch.iter_any_collectable())
}
}
+41 -41
View File
@@ -226,25 +226,25 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.txindex
.as_ref()
.map_or(vec![], |v| vec![v.as_ref() as &dyn AnyCollectableVec]),
self.height.vecs(),
self.dateindex.vecs(),
self.weekindex.vecs(),
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x.as_ref() as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.height.iter_any_collectable()));
iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
@@ -320,24 +320,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p90()
.unwrap_pct90()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p75()
.unwrap_pct75()
.into_iter()
.unwrap_get_inner(height),
),
@@ -356,24 +356,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p25()
.unwrap_pct25()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p10()
.unwrap_pct10()
.into_iter()
.unwrap_get_inner(height),
),
@@ -503,25 +503,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p90()
.unwrap_pct90()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p75()
.unwrap_pct75()
.into_iter()
.unwrap_get_inner(height),
exit,
@@ -539,25 +539,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p25()
.unwrap_pct25()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p10()
.unwrap_pct10()
.into_iter()
.unwrap_get_inner(height),
exit,
@@ -1,5 +1,4 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Date, DateIndex, Dollars, StoredF32, Version};
use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec,
@@ -8,7 +7,9 @@ use vecdb::{
use crate::{
Indexes,
grouped::{ComputedStandardDeviationVecsFromDateIndex, source::Source},
grouped::{
ComputedStandardDeviationVecsFromDateIndex, StandardDeviationVecsOptions, source::Source,
},
indexes, price,
utils::get_percentile,
};
@@ -28,12 +29,12 @@ pub struct ComputedRatioVecsFromDateIndex {
pub ratio_pct5: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct2: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct1: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct99_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct98_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct95_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct5_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct2_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct1_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct99_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct98_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct95_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct5_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct2_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct1_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
pub ratio_4y_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
@@ -105,6 +106,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -116,6 +118,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -127,6 +130,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -138,6 +142,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -207,10 +212,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct99_in_usd: extended.then(|| {
ratio_pct99_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct99_in_usd"),
&format!("{name}_ratio_pct99_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -218,10 +223,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct98_in_usd: extended.then(|| {
ratio_pct98_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct98_in_usd"),
&format!("{name}_ratio_pct98_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -229,10 +234,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct95_in_usd: extended.then(|| {
ratio_pct95_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct95_in_usd"),
&format!("{name}_ratio_pct95_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -240,10 +245,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct5_in_usd: extended.then(|| {
ratio_pct5_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct5_in_usd"),
&format!("{name}_ratio_pct5_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -251,10 +256,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct2_in_usd: extended.then(|| {
ratio_pct2_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct2_in_usd"),
&format!("{name}_ratio_pct2_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -262,10 +267,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct1_in_usd: extended.then(|| {
ratio_pct1_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct1_in_usd"),
&format!("{name}_ratio_pct1_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -278,45 +283,25 @@ impl ComputedRatioVecsFromDateIndex {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, Dollars>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, Dollars>) -> Result<()>,
{
self.price.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
compute,
)?;
self.price
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, compute)?;
let date_to_price_opt: Option<&EagerVec<DateIndex, Dollars>> = None;
self.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
date_to_price_opt,
)
self.compute_rest(price, starting_indexes, exit, date_to_price_opt)
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
@@ -328,28 +313,22 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
});
self.ratio.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform2(
starting_indexes.dateindex,
closes,
price,
|(i, close, price, ..)| {
if price == Dollars::ZERO {
(i, StoredF32::from(1.0))
} else {
(i, StoredF32::from(*close / price))
}
},
exit,
)?;
Ok(())
},
)?;
self.ratio.compute_all(starting_indexes, exit, |v| {
v.compute_transform2(
starting_indexes.dateindex,
closes,
price,
|(i, close, price, ..)| {
if price == Dollars::ZERO {
(i, StoredF32::from(1.0))
} else {
(i, StoredF32::from(*close / price))
}
},
exit,
)?;
Ok(())
})?;
if self.ratio_1w_sma.is_none() {
return Ok(());
@@ -357,12 +336,10 @@ impl ComputedRatioVecsFromDateIndex {
let min_ratio_date = DateIndex::try_from(Date::MIN_RATIO).unwrap();
self.ratio_1w_sma.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.ratio_1w_sma
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |v| {
v.compute_sma_(
starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(),
@@ -371,15 +348,12 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date),
)?;
Ok(())
},
)?;
})?;
self.ratio_1m_sma.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.ratio_1m_sma
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |v| {
v.compute_sma_(
starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(),
@@ -388,8 +362,7 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date),
)?;
Ok(())
},
)?;
})?;
let ratio_version = self.ratio.dateindex.as_ref().unwrap().version();
self.mut_ratio_vecs()
@@ -556,12 +529,10 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
});
self.ratio_pct99_in_usd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.ratio_pct99_usd
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |vec| {
let mut iter = self
.ratio_pct99
.as_ref()
@@ -580,67 +551,52 @@ impl ComputedRatioVecsFromDateIndex {
exit,
)?;
Ok(())
},
)?;
})?;
let compute_in_usd =
|in_usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>,
let compute_usd =
|usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>,
source: Option<&ComputedVecsFromDateIndex<StoredF32>>| {
in_usd.unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter();
vec.compute_transform(
starting_indexes.dateindex,
date_to_price,
|(i, price, ..)| {
let multiplier = iter.unwrap_get_inner(i);
(i, price * multiplier)
},
exit,
)?;
Ok(())
},
)
usd.unwrap().compute_all(starting_indexes, exit, |vec| {
let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter();
vec.compute_transform(
starting_indexes.dateindex,
date_to_price,
|(i, price, ..)| {
let multiplier = iter.unwrap_get_inner(i);
(i, price * multiplier)
},
exit,
)?;
Ok(())
})
};
compute_in_usd(self.ratio_pct1_in_usd.as_mut(), self.ratio_pct1.as_ref())?;
compute_in_usd(self.ratio_pct2_in_usd.as_mut(), self.ratio_pct2.as_ref())?;
compute_in_usd(self.ratio_pct5_in_usd.as_mut(), self.ratio_pct5.as_ref())?;
compute_in_usd(self.ratio_pct95_in_usd.as_mut(), self.ratio_pct95.as_ref())?;
compute_in_usd(self.ratio_pct98_in_usd.as_mut(), self.ratio_pct98.as_ref())?;
compute_in_usd(self.ratio_pct99_in_usd.as_mut(), self.ratio_pct99.as_ref())?;
compute_usd(self.ratio_pct1_usd.as_mut(), self.ratio_pct1.as_ref())?;
compute_usd(self.ratio_pct2_usd.as_mut(), self.ratio_pct2.as_ref())?;
compute_usd(self.ratio_pct5_usd.as_mut(), self.ratio_pct5.as_ref())?;
compute_usd(self.ratio_pct95_usd.as_mut(), self.ratio_pct95.as_ref())?;
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(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_4y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_2y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_1y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
@@ -676,37 +632,132 @@ impl ComputedRatioVecsFromDateIndex {
.collect::<Vec<_>>()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.price.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio.vecs(),
self.ratio_1w_sma.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_1m_sma.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_1y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_2y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_4y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct1.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct2.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct5.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct95.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct98.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct99.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct1_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct2_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct5_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct95_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.ratio_pct98_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.ratio_pct99_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(self.price.iter().flat_map(|v| v.iter_any_collectable()));
iter = Box::new(iter.chain(self.ratio.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.ratio_1w_sma
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_1m_sma
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(iter.chain(self.ratio_sd.iter().flat_map(|v| v.iter_any_collectable())));
iter = Box::new(
iter.chain(
self.ratio_1y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_2y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_4y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct1
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct2
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct5
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct95
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct98
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct99
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct1_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct2_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct5_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct95_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct98_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct99_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter
}
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,4 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -43,7 +42,7 @@ impl ComputedValueVecsFromDateIndex {
)?,
bitcoin: ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
Source::Compute,
version + VERSION,
indexes,
@@ -52,7 +51,7 @@ impl ComputedValueVecsFromDateIndex {
dollars: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
Source::Compute,
version + VERSION,
indexes,
@@ -65,40 +64,24 @@ impl ComputedValueVecsFromDateIndex {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, Sats>) -> Result<()>,
{
compute(
self.sats.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.dateindex.as_mut().unwrap())?;
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
self.compute_rest(indexer, indexes, price, starting_indexes, exit, dateindex)?;
self.compute_rest(price, starting_indexes, exit, dateindex)?;
Ok(())
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
@@ -108,33 +91,21 @@ impl ComputedValueVecsFromDateIndex {
self.sats
.compute_rest(starting_indexes, exit, Some(dateindex))?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
},
)?;
self.bitcoin.compute_all(starting_indexes, exit, |v| {
v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
})?;
} else {
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
self.sats.compute_rest(starting_indexes, exit, dateindex)?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(
starting_indexes.dateindex,
self.sats.dateindex.as_ref().unwrap(),
exit,
)
},
)?;
self.bitcoin.compute_all(starting_indexes, exit, |v| {
v.compute_from_sats(
starting_indexes.dateindex,
self.sats.dateindex.as_ref().unwrap(),
exit,
)
})?;
}
let dateindex_to_bitcoin = self.bitcoin.dateindex.as_ref().unwrap();
@@ -147,33 +118,23 @@ impl ComputedValueVecsFromDateIndex {
.unwrap();
if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_bitcoin(
starting_indexes.dateindex,
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
},
)?;
dollars.compute_all(starting_indexes, exit, |v| {
v.compute_from_bitcoin(
starting_indexes.dateindex,
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
})?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
self.bitcoin.vecs(),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
std::iter::empty()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
@@ -1,6 +1,5 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -44,7 +43,7 @@ impl ComputedValueVecsFromHeight {
)?,
bitcoin: ComputedVecsFromHeight::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
Source::Compute,
version + VERSION,
indexes,
@@ -53,7 +52,7 @@ impl ComputedValueVecsFromHeight {
dollars: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
Source::Compute,
version + VERSION,
indexes,
@@ -66,7 +65,6 @@ impl ComputedValueVecsFromHeight {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -74,31 +72,18 @@ impl ComputedValueVecsFromHeight {
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
{
compute(
self.sats.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.height.as_mut().unwrap())?;
let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(indexer, indexes, price, starting_indexes, exit, height)?;
self.compute_rest(indexes, price, starting_indexes, exit, height)?;
Ok(())
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -109,67 +94,47 @@ impl ComputedValueVecsFromHeight {
self.sats
.compute_rest(indexes, starting_indexes, exit, Some(height))?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.bitcoin
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_sats(starting_indexes.height, height, exit)
},
)?;
})?;
} else {
let height: Option<&StoredVec<Height, Sats>> = None;
self.sats
.compute_rest(indexes, starting_indexes, exit, height)?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.bitcoin
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_sats(
starting_indexes.height,
self.sats.height.as_ref().unwrap(),
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;
if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_bitcoin(
starting_indexes.height,
height_to_bitcoin,
height_to_price_close,
exit,
)
},
)?;
dollars.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_bitcoin(
starting_indexes.height,
height_to_bitcoin,
height_to_price_close,
exit,
)
})?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
self.bitcoin.vecs(),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
std::iter::empty()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
@@ -38,8 +38,8 @@ impl ComputedValueVecsFromTxindex {
) -> Result<Self> {
let compute_dollars = price.is_some();
let name_in_btc = format!("{name}_in_btc");
let name_in_usd = format!("{name}_in_usd");
let name_btc = format!("{name}_btc");
let name_usd = format!("{name}_usd");
let sats = ComputedVecsFromTxindex::forced_import(
db,
@@ -53,7 +53,7 @@ impl ComputedValueVecsFromTxindex {
let source_vec = source.vec();
let bitcoin_txindex = LazyVecFrom1::init(
&name_in_btc,
&name_btc,
version + VERSION,
source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|txindex: TxIndex, iter| {
@@ -66,7 +66,7 @@ impl ComputedValueVecsFromTxindex {
let bitcoin = ComputedVecsFromTxindex::forced_import(
db,
&name_in_btc,
&name_btc,
Source::None,
version + VERSION,
indexes,
@@ -75,29 +75,27 @@ impl ComputedValueVecsFromTxindex {
let dollars_txindex = price.map(|price| {
LazyVecFrom3::init(
&name_in_usd,
&name_usd,
version + VERSION,
bitcoin_txindex.boxed_clone(),
indexes.txindex_to_height.boxed_clone(),
price.chainindexes_to_price_close.height.boxed_clone(),
|txindex: TxIndex,
txindex_to_in_btc_iter,
txindex_to_btc_iter,
txindex_to_height_iter,
height_to_price_close_iter| {
let txindex = txindex.unwrap_to_usize();
txindex_to_in_btc_iter
.next_at(txindex)
.and_then(|(_, value)| {
let btc = value.into_owned();
txindex_to_height_iter
.next_at(txindex)
.and_then(|(_, value)| {
let height = value.into_owned();
height_to_price_close_iter
.next_at(height.unwrap_to_usize())
.map(|(_, close)| *close.into_owned() * btc)
})
})
txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
let btc = value.into_owned();
txindex_to_height_iter
.next_at(txindex)
.and_then(|(_, value)| {
let height = value.into_owned();
height_to_price_close_iter
.next_at(height.unwrap_to_usize())
.map(|(_, close)| *close.into_owned() * btc)
})
})
},
)
});
@@ -110,7 +108,7 @@ impl ComputedValueVecsFromTxindex {
dollars: compute_dollars.then(|| {
ComputedVecsFromTxindex::forced_import(
db,
&name_in_usd,
&name_usd,
Source::None,
version + VERSION,
indexes,
@@ -204,18 +202,16 @@ impl ComputedValueVecsFromTxindex {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
vec![&self.bitcoin_txindex as &dyn AnyCollectableVec],
self.bitcoin.vecs(),
self.dollars_txindex
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.bitcoin_txindex as &dyn AnyCollectableVec]
.into_iter()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(
self.dollars_txindex
.iter()
.map(|v| v as &dyn AnyCollectableVec),
)
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
+10 -29
View File
@@ -1,12 +1,11 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, Format, StoredVec};
use crate::{
Indexes,
grouped::Source,
indexes, price,
price,
traits::{ComputeFromBitcoin, ComputeFromSats},
};
@@ -35,14 +34,14 @@ impl ComputedHeightValueVecs {
}),
bitcoin: EagerVec::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
version + VERSION + Version::ZERO,
format,
)?,
dollars: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
version + VERSION + Version::ZERO,
format,
)
@@ -53,29 +52,15 @@ impl ComputedHeightValueVecs {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
{
compute(
self.sats.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.as_mut().unwrap())?;
let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(price, starting_indexes, exit, height)?;
@@ -116,14 +101,10 @@ impl ComputedHeightValueVecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![&self.bitcoin as &dyn AnyCollectableVec],
self.sats.as_ref().map_or(vec![], |v| vec![v]),
self.dollars.as_ref().map_or(vec![], |v| vec![v]),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.bitcoin as &dyn AnyCollectableVec]
.into_iter()
.chain(self.sats.iter().map(|v| v as &dyn AnyCollectableVec))
.chain(self.dollars.iter().map(|v| v as &dyn AnyCollectableVec))
}
}
+5 -5
View File
@@ -475,8 +475,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -934,9 +933,9 @@ impl Vecs {
})
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
&self.dateindex_to_date,
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[
&self.dateindex_to_date as &dyn AnyCollectableVec,
&self.dateindex_to_dateindex,
&self.dateindex_to_first_height,
&self.dateindex_to_height_count,
@@ -997,6 +996,7 @@ impl Vecs {
&self.yearindex_to_yearindex,
&self.outputindex_to_txindex,
]
.into_iter()
}
}
+16 -20
View File
@@ -116,7 +116,7 @@ impl Computer {
info!("Computing constants...");
self.constants
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
.compute(&self.indexes, &starting_indexes, exit)?;
if let Some(fetched) = self.fetched.as_mut() {
info!("Computing fetched...");
@@ -124,7 +124,6 @@ impl Computer {
info!("Computing prices...");
self.price.as_mut().unwrap().compute(
indexer,
&self.indexes,
&starting_indexes,
fetched,
@@ -147,8 +146,7 @@ impl Computer {
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market
.compute(indexer, &self.indexes, price, &starting_indexes, exit)?;
self.market.compute(price, &starting_indexes, exit)?;
}
chain.join().unwrap()?;
@@ -178,7 +176,6 @@ impl Computer {
info!("Computing cointime...");
self.cointime.compute(
indexer,
&self.indexes,
&starting_indexes,
self.price.as_ref(),
@@ -190,21 +187,20 @@ impl Computer {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.constants.vecs(),
self.indexes.vecs(),
self.market.vecs(),
self.chain.vecs(),
self.stateful.vecs(),
self.cointime.vecs(),
self.pools.vecs(),
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),
self.price.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(self.fetched.iter().flat_map(|v| v.iter_any_collectable()));
iter = Box::new(iter.chain(self.price.iter().flat_map(|v| v.iter_any_collectable())));
iter = Box::new(iter.chain(self.pools.iter_any_collectable()));
iter = Box::new(iter.chain(self.constants.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes.iter_any_collectable()));
iter = Box::new(iter.chain(self.market.iter_any_collectable()));
iter = Box::new(iter.chain(self.chain.iter_any_collectable()));
iter = Box::new(iter.chain(self.stateful.iter_any_collectable()));
iter = Box::new(iter.chain(self.cointime.iter_any_collectable()));
iter
}
pub fn static_clone(&self) -> &'static Self {
File diff suppressed because it is too large Load Diff
+9 -14
View File
@@ -70,8 +70,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -106,7 +105,6 @@ impl Vecs {
self.vecs.par_iter_mut().try_for_each(|(_, vecs)| {
vecs.compute(
indexer,
indexes,
starting_indexes,
&self.height_to_pool,
@@ -225,16 +223,13 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.vecs
.iter()
.flat_map(|(_, vecs)| vecs.vecs())
.collect::<Vec<_>>(),
vec![&self.height_to_pool],
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.height_to_pool as &dyn AnyCollectableVec]
.into_iter()
.chain(
self.vecs
.iter()
.flat_map(|(_, vecs)| vecs.iter_any_collectable()),
)
}
}
+58 -128
View File
@@ -1,6 +1,5 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Height, Sats, StoredF32, StoredU16, StoredU32};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, StoredIndex, VecIterator, Version};
@@ -163,7 +162,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
height_to_pool: &impl AnyIterableVec<Height, PoolId>,
@@ -171,12 +169,8 @@ impl Vecs {
price: Option<&price::Vecs>,
exit: &Exit,
) -> Result<()> {
self.indexes_to_blocks_mined.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_blocks_mined
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
height_to_pool,
@@ -193,15 +187,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1w_blocks_mined.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_1w_blocks_mined
.compute_all(starting_indexes, exit, |v| {
v.compute_sum(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_sum(),
@@ -209,15 +198,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1m_blocks_mined.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_1m_blocks_mined
.compute_all(starting_indexes, exit, |v| {
v.compute_sum(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_sum(),
@@ -225,15 +209,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1y_blocks_mined.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_1y_blocks_mined
.compute_all(starting_indexes, exit, |v| {
v.compute_sum(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_sum(),
@@ -241,18 +220,12 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let height_to_blocks_mined = self.indexes_to_blocks_mined.height.as_ref().unwrap();
self.indexes_to_subsidy.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_subsidy
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
@@ -270,16 +243,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_fee.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_fee
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
@@ -297,16 +264,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_coinbase.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_coinbase
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
@@ -324,15 +285,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_dominance.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_cumulative(),
@@ -340,15 +296,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1d_dominance.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_1d_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_sum(),
@@ -356,15 +307,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1w_dominance.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_1w_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_1w_blocks_mined.dateindex.as_ref().unwrap(),
@@ -372,15 +318,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1m_dominance.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_1m_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_1m_blocks_mined.dateindex.as_ref().unwrap(),
@@ -388,15 +329,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_1y_dominance.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_1y_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_1y_blocks_mined.dateindex.as_ref().unwrap(),
@@ -404,15 +340,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_days_since_block.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_days_since_block
.compute_all(starting_indexes, exit, |v| {
let mut prev = None;
v.compute_transform2(
starting_indexes.dateindex,
@@ -438,30 +369,29 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_blocks_mined.vecs(),
self.indexes_to_1w_blocks_mined.vecs(),
self.indexes_to_1m_blocks_mined.vecs(),
self.indexes_to_1y_blocks_mined.vecs(),
self.indexes_to_subsidy.vecs(),
self.indexes_to_fee.vecs(),
self.indexes_to_coinbase.vecs(),
self.indexes_to_dominance.vecs(),
self.indexes_to_1d_dominance.vecs(),
self.indexes_to_1w_dominance.vecs(),
self.indexes_to_1m_dominance.vecs(),
self.indexes_to_1y_dominance.vecs(),
self.indexes_to_days_since_block.vecs(),
]
.into_iter()
.flatten()
.collect()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
iter = Box::new(iter.chain(self.indexes_to_blocks_mined.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1w_blocks_mined.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1m_blocks_mined.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1y_blocks_mined.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_subsidy.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_fee.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_coinbase.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_dominance.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1d_dominance.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1w_dominance.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1m_dominance.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_1y_dominance.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_days_since_block.iter_any_collectable()));
iter
}
}
+110 -160
View File
@@ -1,7 +1,6 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
Cents, Close, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, High, Low, MonthIndex,
OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, SemesterIndex, Version, WeekIndex, YearIndex,
@@ -327,8 +326,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -338,20 +336,18 @@ impl Vecs {
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
fetched: &fetched::Vecs,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, fetched, exit)?;
self.compute_(indexes, starting_indexes, fetched, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
fetched: &fetched::Vecs,
@@ -445,12 +441,8 @@ impl Vecs {
})?;
self.dateindex_to_price_ohlc.safe_flush(exit)?;
self.timeindexes_to_price_close.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_close
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -458,15 +450,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_high.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_high
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -474,15 +461,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_low.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_low
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -490,15 +472,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_open.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_open
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -506,15 +483,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_close.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_close
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -522,15 +494,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_high.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_high
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -538,15 +505,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_low.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_low
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -554,15 +516,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_open.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_open
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -570,8 +527,7 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let mut weekindex_first_iter = self
.timeindexes_to_price_open
@@ -843,12 +799,8 @@ impl Vecs {
})?;
self.decadeindex_to_price_ohlc.safe_flush(exit)?;
self.chainindexes_to_price_open_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_open_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_open.height,
@@ -856,15 +808,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_high_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_high_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_low.height,
@@ -872,15 +819,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_low_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_low_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_high.height,
@@ -888,15 +830,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_close_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_close_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_close.height,
@@ -904,15 +841,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_open_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_open_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_open.dateindex.as_ref().unwrap(),
@@ -920,15 +852,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_high_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_high_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_low.dateindex.as_ref().unwrap(),
@@ -936,15 +863,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_low_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_low_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_high.dateindex.as_ref().unwrap(),
@@ -952,15 +874,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_close_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_close_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_close.dateindex.as_ref().unwrap(),
@@ -968,8 +885,7 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let mut height_first_iter = self.chainindexes_to_price_open_in_sats.height.iter();
let mut height_max_iter = self.chainindexes_to_price_high_in_sats.height.iter();
@@ -1311,9 +1227,9 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
vec![
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
[
&self.dateindex_to_price_close_in_cents as &dyn AnyCollectableVec,
&self.dateindex_to_price_high_in_cents,
&self.dateindex_to_price_low_in_cents,
@@ -1330,7 +1246,6 @@ impl Vecs {
&self.quarterindex_to_price_ohlc,
&self.semesterindex_to_price_ohlc,
&self.yearindex_to_price_ohlc,
// &self.halvingepoch_to_price_ohlc,
&self.decadeindex_to_price_ohlc,
&self.height_to_price_ohlc_in_sats,
&self.dateindex_to_price_ohlc_in_sats,
@@ -1340,28 +1255,63 @@ impl Vecs {
&self.quarterindex_to_price_ohlc_in_sats,
&self.semesterindex_to_price_ohlc_in_sats,
&self.yearindex_to_price_ohlc_in_sats,
// &self.halvingepoch_to_price_ohlc_in_sats,
&self.decadeindex_to_price_ohlc_in_sats,
],
self.timeindexes_to_price_close.vecs(),
self.timeindexes_to_price_high.vecs(),
self.timeindexes_to_price_low.vecs(),
self.timeindexes_to_price_open.vecs(),
self.chainindexes_to_price_close.vecs(),
self.chainindexes_to_price_high.vecs(),
self.chainindexes_to_price_low.vecs(),
self.chainindexes_to_price_open.vecs(),
self.timeindexes_to_price_close_in_sats.vecs(),
self.timeindexes_to_price_high_in_sats.vecs(),
self.timeindexes_to_price_low_in_sats.vecs(),
self.timeindexes_to_price_open_in_sats.vecs(),
self.chainindexes_to_price_close_in_sats.vecs(),
self.chainindexes_to_price_high_in_sats.vecs(),
self.chainindexes_to_price_low_in_sats.vecs(),
self.chainindexes_to_price_open_in_sats.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
]
.into_iter(),
);
iter = Box::new(iter.chain(self.timeindexes_to_price_close.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_high.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_low.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_open.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_close.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_high.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_low.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_open.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.timeindexes_to_price_close_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.timeindexes_to_price_high_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.timeindexes_to_price_low_in_sats.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.timeindexes_to_price_open_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_close_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_high_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_low_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_open_in_sats
.iter_any_collectable(),
),
);
iter
}
}
@@ -1,7 +1,6 @@
use std::{ops::Deref, path::Path};
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, StoredU64, Version};
use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, Database, EagerVec, Exit, Format,
@@ -85,17 +84,21 @@ impl Vecs {
)?,
})
}
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
self.inner
.iter_any_collectable()
.chain([&self.height_to_addr_count as &dyn AnyCollectableVec])
.chain(self.indexes_to_addr_count.iter_any_collectable())
}
}
impl DynCohortVecs for Vecs {
fn min_height_vecs_len(&self) -> usize {
[
std::cmp::min(
self.height_to_addr_count.len(),
self.inner.min_height_vecs_len(),
]
.into_iter()
.min()
.unwrap()
)
}
fn reset_state_starting_height(&mut self) {
@@ -171,7 +174,6 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -185,16 +187,7 @@ impl DynCohortVecs for Vecs {
)?;
self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
}
fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.inner.vecs(),
self.indexes_to_addr_count.vecs(),
vec![&self.height_to_addr_count],
]
.concat()
.compute_rest_part1(indexes, price, starting_indexes, exit)
}
}
@@ -224,7 +217,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -237,7 +229,6 @@ impl CohortVecs for Vecs {
exit: &Exit,
) -> Result<()> {
self.inner.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -251,10 +242,3 @@ impl CohortVecs for Vecs {
)
}
}
impl Deref for Vecs {
type Target = common::Vecs;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
@@ -1,7 +1,6 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
AddressGroups, Bitcoin, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, DateIndex,
Dollars, GroupFilter, Height, Version,
@@ -459,18 +458,17 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let by_size_range = self.0.amount_range.as_vec();
let by_size_range = &self.0.amount_range;
[
self.0
.ge_amount
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
@@ -479,13 +477,12 @@ impl Vecs {
.collect::<Vec<_>>(),
self.0
.lt_amount
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
@@ -502,21 +499,19 @@ impl Vecs {
pub fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
})
self.iter_mut()
.into_iter()
.try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
}
#[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -528,27 +523,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| {
v.into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
self.0.iter_mut().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
}
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs()
self.iter_separate_mut()
.into_iter()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
}
@@ -75,11 +75,9 @@ impl AddressTypeToIndexesToAddressCount {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
self.0
.as_typed_vec()
.into_iter()
.flat_map(|(_, v)| v.vecs())
.collect::<Vec<_>>()
.iter_typed()
.flat_map(|(_, v)| v.iter_any_collectable())
}
}
@@ -27,6 +27,10 @@ impl<T> AddressTypeToTypeIndexTree<T> {
mem::swap(own, other);
}
}
pub fn unwrap(self) -> ByAddressType<BTreeMap<TypeIndex, T>> {
self.0
}
}
impl<T> Default for AddressTypeToTypeIndexTree<T> {
@@ -38,6 +38,10 @@ impl<T> AddressTypeToVec<T> {
mem::swap(own, other);
}
}
pub fn unwrap(self) -> ByAddressType<Vec<T>> {
self.0
}
}
impl<T> Default for AddressTypeToVec<T> {
File diff suppressed because it is too large Load Diff
+123 -123
View File
@@ -493,8 +493,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -598,8 +597,9 @@ impl Vecs {
+ dateindex_to_first_height.version()
+ dateindex_to_height_count.version();
let mut separate_utxo_vecs = self.utxo_cohorts.as_mut_separate_vecs();
let mut separate_address_vecs = self.address_cohorts.as_mut_separate_vecs();
let mut separate_utxo_vecs = self.utxo_cohorts.iter_separate_mut().collect::<Vec<_>>();
let mut separate_address_vecs =
self.address_cohorts.iter_separate_mut().collect::<Vec<_>>();
separate_utxo_vecs
.par_iter_mut()
@@ -878,13 +878,11 @@ impl Vecs {
info!("Processing chain at {height}...");
self.utxo_cohorts
.as_mut_separate_vecs()
.iter_mut()
.iter_separate_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
self.address_cohorts
.as_mut_separate_vecs()
.iter_mut()
.iter_separate_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
let timestamp = height_to_timestamp_fixed_iter.unwrap_get_inner(height);
@@ -1252,12 +1250,11 @@ impl Vecs {
let dateindex = is_date_last_height.then_some(dateindex);
self.utxo_cohorts.as_mut_separate_vecs()
.into_par_iter()
self.utxo_cohorts.iter_separate_mut().par_bridge()
.map(|(_, v)| v as &mut dyn DynCohortVecs)
.chain(
self.address_cohorts.as_mut_separate_vecs()
.into_par_iter()
self.address_cohorts.iter_separate_mut()
.par_bridge()
.map(|(_, v)| v as &mut dyn DynCohortVecs),
)
.try_for_each(|v| {
@@ -1309,48 +1306,35 @@ impl Vecs {
info!("Computing rest part 1...");
self.indexes_to_addr_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_addr_count
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_sum_of_others(
starting_indexes.height,
&self
.addresstype_to_height_to_addr_count
.as_typed_vec()
.into_iter()
.iter_typed()
.map(|(_, v)| v)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_empty_addr_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_empty_addr_count
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_sum_of_others(
starting_indexes.height,
&self
.addresstype_to_height_to_empty_addr_count
.as_typed_vec()
.into_iter()
.iter_typed()
.map(|(_, v)| v)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_unspendable_supply.compute_rest(
indexer,
indexes,
price,
starting_indexes,
@@ -1358,7 +1342,6 @@ impl Vecs {
Some(&self.height_to_unspendable_supply),
)?;
self.indexes_to_opreturn_supply.compute_rest(
indexer,
indexes,
price,
starting_indexes,
@@ -1381,36 +1364,30 @@ impl Vecs {
)?;
self.utxo_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?;
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
self.address_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?;
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
if let Some(indexes_to_market_cap) = self.indexes_to_market_cap.as_mut() {
indexes_to_market_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform(
starting_indexes.dateindex,
self.utxo_cohorts
.all
.1
.indexes_to_supply
.dollars
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
},
)?;
indexes_to_market_cap.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.utxo_cohorts
.all
.1
.indexes_to_supply
.dollars
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
})?;
}
info!("Computing rest part 2...");
@@ -1450,7 +1427,6 @@ impl Vecs {
let dateindex_to_realized_cap_ref = dateindex_to_realized_cap.as_ref();
self.utxo_cohorts.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -1464,7 +1440,6 @@ impl Vecs {
)?;
self.address_cohorts.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -1655,10 +1630,10 @@ impl Vecs {
&mut self,
height: Height,
chain_state: &[BlockState],
mut addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree<
addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>,
>,
mut addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<EmptyAddressData>,
>,
with_changes: bool,
@@ -1667,30 +1642,28 @@ impl Vecs {
info!("Flushing...");
self.utxo_cohorts
.as_mut_separate_vecs()
.par_iter_mut()
.iter_separate_mut()
.par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.address_cohorts
.as_mut_separate_vecs()
.par_iter_mut()
.iter_separate_mut()
.par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.height_to_unspendable_supply.safe_flush(exit)?;
self.height_to_opreturn_supply.safe_flush(exit)?;
self.addresstype_to_height_to_addr_count
.as_mut_vec()
.into_iter()
.iter_mut()
.try_for_each(|v| v.safe_flush(exit))?;
self.addresstype_to_height_to_empty_addr_count
.as_mut_vec()
.into_iter()
.iter_mut()
.try_for_each(|v| v.safe_flush(exit))?;
let mut addresstype_to_typeindex_to_new_or_updated_anyaddressindex =
AddressTypeToTypeIndexTree::default();
addresstype_to_typeindex_to_emptyaddressdata
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each(
|(typeindex, emptyaddressdata_with_source)| -> Result<()> {
@@ -1742,8 +1715,8 @@ impl Vecs {
})?;
addresstype_to_typeindex_to_loadedaddressdata
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each(
|(typeindex, loadedaddressdata_with_source)| -> Result<()> {
@@ -1795,8 +1768,8 @@ impl Vecs {
})?;
addresstype_to_typeindex_to_new_or_updated_anyaddressindex
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter()
.try_for_each(|(typeindex, anyaddressindex)| -> Result<()> {
@@ -1864,42 +1837,10 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.utxo_cohorts
.vecs()
.into_iter()
.flat_map(|v| v.vecs())
.collect::<Vec<_>>(),
self.address_cohorts
.vecs()
.into_iter()
.flat_map(|v| v.vecs())
.collect::<Vec<_>>(),
self.indexes_to_unspendable_supply.vecs(),
self.indexes_to_opreturn_supply.vecs(),
self.indexes_to_addr_count.vecs(),
self.indexes_to_empty_addr_count.vecs(),
self.addresstype_to_indexes_to_addr_count.vecs(),
self.indexes_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.addresstype_to_indexes_to_empty_addr_count.vecs(),
self.addresstype_to_height_to_addr_count
.as_typed_vec()
.into_iter()
.map(|(_, v)| v as &dyn AnyCollectableVec)
.collect::<Vec<_>>(),
self.addresstype_to_height_to_empty_addr_count
.as_typed_vec()
.into_iter()
.map(|(_, v)| v as &dyn AnyCollectableVec)
.collect::<Vec<_>>(),
self.height_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
vec![
&self.height_to_unspendable_supply,
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
[
&self.height_to_unspendable_supply as &dyn AnyCollectableVec,
&self.height_to_opreturn_supply,
&self.chain_state,
&self.p2pk33addressindex_to_anyaddressindex,
@@ -1914,18 +1855,77 @@ impl Vecs {
&self.emptyaddressindex_to_emptyaddressdata,
&self.loadedaddressindex_to_loadedaddressindex,
&self.emptyaddressindex_to_emptyaddressindex,
],
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
]
.into_iter(),
);
iter = Box::new(
iter.chain(
self.utxo_cohorts
.iter_right()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.address_cohorts
.iter_right()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(iter.chain(self.indexes_to_unspendable_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_opreturn_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_addr_count.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_empty_addr_count.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.addresstype_to_indexes_to_addr_count
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_market_cap
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_indexes_to_empty_addr_count
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_height_to_addr_count
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_height_to_empty_addr_count
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.height_to_market_cap
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter
}
}
impl AddressTypeToVec<(TypeIndex, Sats)> {
#[allow(clippy::too_many_arguments)]
fn process_received(
mut self,
self,
vecs: &mut address_cohorts::Vecs,
addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>,
@@ -1940,7 +1940,7 @@ impl AddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>,
>,
) {
self.into_typed_vec().into_iter().for_each(|(_type, vec)| {
self.unwrap().into_iter_typed().for_each(|(_type, vec)| {
vec.into_iter().for_each(|(type_index, value)| {
let mut is_new = false;
let mut from_any_empty = false;
@@ -2044,7 +2044,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>,
>,
) -> Result<()> {
self.0.into_iter().try_for_each(|(prev_height, mut v)| {
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.unwrap_to_usize()).unwrap());
@@ -2062,7 +2062,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
.unwrap()
.is_more_than_hour();
v.into_typed_vec().into_iter().try_for_each(|(_type, vec)| {
v.unwrap().into_iter_typed().try_for_each(|(_type, vec)| {
vec.into_iter().try_for_each(|(type_index, value)| {
let typeindex_to_loadedaddressdata =
addresstype_to_typeindex_to_loadedaddressdata
+1 -6
View File
@@ -1,7 +1,6 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Exit};
use vecdb::{AnyIterableVec, Exit};
use crate::{Indexes, indexes, price};
@@ -29,14 +28,11 @@ pub trait DynCohortVecs: Send + Sync {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>;
fn vecs(&self) -> Vec<&dyn AnyCollectableVec>;
}
pub trait CohortVecs: DynCohortVecs {
@@ -50,7 +46,6 @@ pub trait CohortVecs: DynCohortVecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -1,9 +1,8 @@
use std::{ops::Deref, path::Path};
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, Format};
use vecdb::{AnyIterableVec, Database, Exit, Format};
use crate::{
Indexes, UTXOCohortState, indexes, price,
@@ -122,18 +121,13 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
}
fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
self.inner.vecs()
.compute_rest_part1(indexes, price, starting_indexes, exit)
}
}
@@ -154,7 +148,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -167,7 +160,6 @@ impl CohortVecs for Vecs {
exit: &Exit,
) -> Result<()> {
self.inner.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
+91 -135
View File
@@ -1,7 +1,6 @@
use std::{collections::BTreeMap, ops::ControlFlow, path::Path};
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
Bitcoin, ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge,
ByMinAge, BySpendableType, ByTerm, CheckedSub, DateIndex, Dollars, GroupFilter, HalvingEpoch,
@@ -1458,8 +1457,7 @@ impl Vecs {
let mut vecs = self
.age_range
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, v)| (filter, &mut v.state))
.collect::<Vec<_>>();
@@ -1503,9 +1501,8 @@ impl Vecs {
let mut time_based_vecs = self
.0
.age_range
.as_mut_vec()
.into_iter()
.chain(self.0.epoch.as_mut_vec())
.iter_mut()
.chain(self.0.epoch.iter_mut())
.collect::<Vec<_>>();
let last_timestamp = chain_state.last().unwrap().timestamp;
@@ -1551,8 +1548,10 @@ impl Vecs {
);
});
sent.by_type.spendable.as_typed_vec().into_iter().for_each(
|(output_type, supply_state)| {
sent.by_type
.spendable
.iter_typed()
.for_each(|(output_type, supply_state)| {
self.0
._type
.get_mut(output_type)
@@ -1568,12 +1567,10 @@ impl Vecs {
days_old_float,
older_than_hour,
)
},
);
});
sent.by_size_group
.as_typed_vec()
.into_iter()
.iter_typed()
.for_each(|(group, supply_state)| {
self.0
.amount_range
@@ -1606,24 +1603,20 @@ impl Vecs {
v.state.as_mut().unwrap().receive(&supply_state, price);
});
self._type
.as_mut_vec()
.into_iter()
.for_each(|(filter, vecs)| {
let output_type = match filter {
GroupFilter::Type(output_type) => *output_type,
_ => unreachable!(),
};
vecs.state
.as_mut()
.unwrap()
.receive(received.by_type.get(output_type), price)
});
self._type.iter_mut().for_each(|(filter, vecs)| {
let output_type = match filter {
GroupFilter::Type(output_type) => *output_type,
_ => unreachable!(),
};
vecs.state
.as_mut()
.unwrap()
.receive(received.by_type.get(output_type), price)
});
received
.by_size_group
.as_typed_vec()
.into_iter()
.iter_typed()
.for_each(|(group, supply_state)| {
self.amount_range
.get_mut(group)
@@ -1640,95 +1633,64 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let by_date_range = self.0.age_range.as_vec();
let by_size_range = self.0.amount_range.as_vec();
let by_date_range = &self.0.age_range;
let by_size_range = &self.0.amount_range;
[
vec![(
&mut self.0.all.1,
[(
&mut self.0.all.1,
by_date_range.iter().map(|(_, v)| v).collect::<Vec<_>>(),
)]
.into_iter()
.chain(self.0.min_age.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)],
self.0
.min_age
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.max_age
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.term
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.ge_amount
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.lt_amount
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
]
.into_iter()
.flatten()
)
}))
.chain(self.0.max_age.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.term.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.ge_amount.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_size_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.lt_amount.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_size_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.try_for_each(|(vecs, stateful)| {
vecs.compute_from_stateful(starting_indexes, &stateful, exit)
})
@@ -1736,21 +1698,19 @@ impl Vecs {
pub fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
})
self.iter_mut()
.into_iter()
.try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
}
#[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -1762,28 +1722,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| {
v.into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
self.iter_mut().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
}
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs()
.into_iter()
self.iter_separate_mut()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
}
}
+4 -2
View File
@@ -2,8 +2,8 @@ use std::collections::BTreeMap;
use brk_computer::Computer;
use brk_indexer::Indexer;
use vecdb::AnyCollectableVec;
use derive_deref::{Deref, DerefMut};
use vecdb::AnyCollectableVec;
use crate::pagination::{PaginatedIndexParam, PaginationParam};
@@ -33,7 +33,9 @@ impl<'a> Vecs<'a> {
.into_iter()
.for_each(|vec| this.insert(vec));
computer.vecs().into_iter().for_each(|vec| this.insert(vec));
computer
.iter_any_collectable()
.for_each(|vec| this.insert(vec));
let mut ids = this.id_to_index_to_vec.keys().cloned().collect::<Vec<_>>();
+12 -31
View File
@@ -8,47 +8,28 @@ pub struct AddressGroups<T> {
}
impl<T> AddressGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.ge_amount
.as_mut_vec()
.into_iter()
.chain(self.amount_range.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.collect::<Vec<_>>()
.iter_mut()
.chain(self.amount_range.iter_mut())
.chain(self.lt_amount.iter_mut())
}
pub fn as_mut_separate_vecs(&mut self) -> Vec<&mut T> {
self.amount_range
.as_mut_vec()
.into_iter()
.collect::<Vec<_>>()
pub fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.amount_range.iter_mut()
}
pub fn as_mut_overlapping_vecs(&mut self) -> Vec<&mut T> {
self.lt_amount
.as_mut_vec()
.into_iter()
.chain(self.ge_amount.as_mut_vec())
.collect::<Vec<_>>()
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.lt_amount.iter_mut().chain(self.ge_amount.iter_mut())
}
}
impl<T> AddressGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
self.amount_range
.vecs()
.into_iter()
.chain(self.lt_amount.vecs())
.chain(self.ge_amount.vecs())
.collect::<Vec<_>>()
.iter_right()
.chain(self.lt_amount.iter_right())
.chain(self.ge_amount.iter_right())
}
}
@@ -1,7 +1,4 @@
use std::{
mem,
ops::{Add, AddAssign},
};
use std::ops::{Add, AddAssign};
use super::GroupFilter;
use crate::OutputType;
@@ -51,7 +48,21 @@ impl<T> ByAddressType<T> {
}
}
pub fn as_mut_vec(&mut self) -> [&mut T; 8] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65,
&self.p2pk33,
&self.p2pkh,
&self.p2sh,
&self.p2wpkh,
&self.p2wsh,
&self.p2tr,
&self.p2a,
]
.into_iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.p2pk65,
&mut self.p2pk33,
@@ -62,9 +73,10 @@ impl<T> ByAddressType<T> {
&mut self.p2tr,
&mut self.p2a,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(OutputType, &T); 8] {
pub fn iter_typed(&self) -> impl Iterator<Item = (OutputType, &T)> {
[
(OutputType::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33),
@@ -75,9 +87,24 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &self.p2tr),
(OutputType::P2A, &self.p2a),
]
.into_iter()
}
pub fn as_mut_typed_vec(&mut self) -> [(OutputType, &mut T); 8] {
pub fn into_iter_typed(self) -> impl Iterator<Item = (OutputType, T)> {
[
(OutputType::P2PK65, self.p2pk65),
(OutputType::P2PK33, self.p2pk33),
(OutputType::P2PKH, self.p2pkh),
(OutputType::P2SH, self.p2sh),
(OutputType::P2WPKH, self.p2wpkh),
(OutputType::P2WSH, self.p2wsh),
(OutputType::P2TR, self.p2tr),
(OutputType::P2A, self.p2a),
]
.into_iter()
}
pub fn iter_typed_mut(&mut self) -> impl Iterator<Item = (OutputType, &mut T)> {
[
(OutputType::P2PK65, &mut self.p2pk65),
(OutputType::P2PK33, &mut self.p2pk33),
@@ -88,27 +115,12 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &mut self.p2tr),
(OutputType::P2A, &mut self.p2a),
]
}
pub fn into_typed_vec(&mut self) -> [(OutputType, T); 8]
where
T: Default,
{
[
(OutputType::P2PK65, mem::take(&mut self.p2pk65)),
(OutputType::P2PK33, mem::take(&mut self.p2pk33)),
(OutputType::P2PKH, mem::take(&mut self.p2pkh)),
(OutputType::P2SH, mem::take(&mut self.p2sh)),
(OutputType::P2WPKH, mem::take(&mut self.p2wpkh)),
(OutputType::P2WSH, mem::take(&mut self.p2wsh)),
(OutputType::P2TR, mem::take(&mut self.p2tr)),
(OutputType::P2A, mem::take(&mut self.p2a)),
]
.into_iter()
}
}
impl<T> ByAddressType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 8] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65.1,
&self.p2pk33.1,
@@ -119,6 +131,7 @@ impl<T> ByAddressType<(GroupFilter, T)> {
&self.p2tr.1,
&self.p2a.1,
]
.into_iter()
}
}
@@ -174,7 +187,7 @@ where
impl<T> ByAddressType<Option<T>> {
pub fn take(&mut self) {
self.as_mut_vec().into_iter().for_each(|opt| {
self.iter_mut().for_each(|opt| {
opt.take();
});
}
@@ -52,7 +52,7 @@ impl<T> From<ByAgeRange<T>> for ByAgeRange<(GroupFilter, T)> {
}
impl<T> ByAgeRange<T> {
pub fn as_vec(&mut self) -> [&T; 20] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self.up_to_1d,
&self._1d_to_1w,
@@ -75,9 +75,10 @@ impl<T> ByAgeRange<T> {
&self._12y_to_15y,
&self.from_15y,
]
.into_iter()
}
pub fn as_mut_vec(&mut self) -> [&mut T; 20] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.up_to_1d,
&mut self._1d_to_1w,
@@ -100,11 +101,12 @@ impl<T> ByAgeRange<T> {
&mut self._12y_to_15y,
&mut self.from_15y,
]
.into_iter()
}
}
impl<T> ByAgeRange<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 20] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.up_to_1d.1,
&self._1d_to_1w.1,
@@ -127,5 +129,6 @@ impl<T> ByAgeRange<(GroupFilter, T)> {
&self._12y_to_15y.1,
&self.from_15y.1,
]
.into_iter()
}
}
@@ -124,7 +124,7 @@ impl<T> ByAmountRange<T> {
}
}
pub fn as_vec(&self) -> [&T; 15] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self._0sats,
&self._1sat_to_10sats,
@@ -142,9 +142,10 @@ impl<T> ByAmountRange<T> {
&self._10k_btc_to_100k_btc,
&self._100k_btc_or_more,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(Sats, &T); 15] {
pub fn iter_typed(&self) -> impl Iterator<Item = (Sats, &T)> {
[
(Sats::ZERO, &self._0sats),
(Sats::_1, &self._1sat_to_10sats),
@@ -162,9 +163,10 @@ impl<T> ByAmountRange<T> {
(Sats::_10K_BTC, &self._10k_btc_to_100k_btc),
(Sats::_100K_BTC, &self._100k_btc_or_more),
]
.into_iter()
}
pub fn as_mut_vec(&mut self) -> [&mut T; 15] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._0sats,
&mut self._1sat_to_10sats,
@@ -182,11 +184,12 @@ impl<T> ByAmountRange<T> {
&mut self._10k_btc_to_100k_btc,
&mut self._100k_btc_or_more,
]
.into_iter()
}
}
impl<T> ByAmountRange<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 15] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._0sats.1,
&self._1sat_to_10sats.1,
@@ -204,6 +207,7 @@ impl<T> ByAmountRange<(GroupFilter, T)> {
&self._10k_btc_to_100k_btc.1,
&self._100k_btc_or_more.1,
]
.into_iter()
}
}
+4 -3
View File
@@ -24,7 +24,7 @@ impl<T> From<ByEpoch<T>> for ByEpoch<(GroupFilter, T)> {
}
impl<T> ByEpoch<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 5] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._0,
&mut self._1,
@@ -32,6 +32,7 @@ impl<T> ByEpoch<T> {
&mut self._3,
&mut self._4,
]
.into_iter()
}
pub fn mut_vec_from_height(&mut self, height: Height) -> &mut T {
@@ -53,7 +54,7 @@ impl<T> ByEpoch<T> {
}
impl<T> ByEpoch<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 5] {
[&self._0.1, &self._1.1, &self._2.1, &self._3.1, &self._4.1]
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self._0.1, &self._1.1, &self._2.1, &self._3.1, &self._4.1].into_iter()
}
}
@@ -20,7 +20,7 @@ pub struct ByGreatEqualAmount<T> {
}
impl<T> ByGreatEqualAmount<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 13] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1sat,
&mut self._10sats,
@@ -36,11 +36,12 @@ impl<T> ByGreatEqualAmount<T> {
&mut self._1k_btc,
&mut self._10k_btc,
]
.into_iter()
}
}
impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1sat.1,
&self._10sats.1,
@@ -56,6 +57,7 @@ impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
&self._1k_btc.1,
&self._10k_btc.1,
]
.into_iter()
}
}
@@ -20,7 +20,7 @@ pub struct ByLowerThanAmount<T> {
}
impl<T> ByLowerThanAmount<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 13] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._10sats,
&mut self._100sats,
@@ -36,11 +36,12 @@ impl<T> ByLowerThanAmount<T> {
&mut self._10k_btc,
&mut self._100k_btc,
]
.into_iter()
}
}
impl<T> ByLowerThanAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._10sats.1,
&self._100sats.1,
@@ -56,6 +57,7 @@ impl<T> ByLowerThanAmount<(GroupFilter, T)> {
&self._10k_btc.1,
&self._100k_btc.1,
]
.into_iter()
}
}
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMaxAge<T> {
}
impl<T> ByMaxAge<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 18] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1w,
&mut self._1m,
@@ -44,11 +44,12 @@ impl<T> ByMaxAge<T> {
&mut self._12y,
&mut self._15y,
]
.into_iter()
}
}
impl<T> ByMaxAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1w.1,
&self._1m.1,
@@ -69,6 +70,7 @@ impl<T> ByMaxAge<(GroupFilter, T)> {
&self._12y.1,
&self._15y.1,
]
.into_iter()
}
}
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMinAge<T> {
}
impl<T> ByMinAge<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 18] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1d,
&mut self._1w,
@@ -44,11 +44,12 @@ impl<T> ByMinAge<T> {
&mut self._10y,
&mut self._12y,
]
.into_iter()
}
}
impl<T> ByMinAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1d.1,
&self._1w.1,
@@ -69,6 +70,7 @@ impl<T> ByMinAge<(GroupFilter, T)> {
&self._10y.1,
&self._12y.1,
]
.into_iter()
}
}
@@ -37,7 +37,7 @@ impl<T> BySpendableType<T> {
}
}
pub fn as_mut_vec(&mut self) -> [&mut T; 11] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.p2pk65,
&mut self.p2pk33,
@@ -51,9 +51,10 @@ impl<T> BySpendableType<T> {
&mut self.unknown,
&mut self.empty,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(OutputType, &T); 11] {
pub fn iter_typed(&self) -> impl Iterator<Item = (OutputType, &T)> {
[
(OutputType::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33),
@@ -67,11 +68,12 @@ impl<T> BySpendableType<T> {
(OutputType::Unknown, &self.unknown),
(OutputType::Empty, &self.empty),
]
.into_iter()
}
}
impl<T> BySpendableType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 11] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65.1,
&self.p2pk33.1,
@@ -85,6 +87,7 @@ impl<T> BySpendableType<(GroupFilter, T)> {
&self.unknown.1,
&self.empty.1,
]
.into_iter()
}
}
+4 -4
View File
@@ -7,14 +7,14 @@ pub struct ByTerm<T> {
}
impl<T> ByTerm<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 2] {
[&mut self.short, &mut self.long]
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.short, &mut self.long].into_iter()
}
}
impl<T> ByTerm<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 2] {
[&self.short.1, &self.long.1]
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.short.1, &self.long.1].into_iter()
}
}
+31 -51
View File
@@ -18,72 +18,52 @@ pub struct UTXOGroups<T> {
}
impl<T> UTXOGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new([&mut self.all]),
Box::new(self.term.as_mut_vec()),
Box::new(self.max_age.as_mut_vec()),
Box::new(self.min_age.as_mut_vec()),
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.age_range.as_mut_vec()),
Box::new(self.epoch.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
Box::new(self._type.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.all]
.into_iter()
.chain(self.term.as_mut_vec())
.chain(self.max_age.as_mut_vec())
.chain(self.min_age.as_mut_vec())
.chain(self.ge_amount.as_mut_vec())
.chain(self.age_range.as_mut_vec())
.chain(self.epoch.as_mut_vec())
.chain(self.amount_range.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.chain(self._type.as_mut_vec())
.collect::<Vec<_>>()
.chain(self.term.iter_mut())
.chain(self.max_age.iter_mut())
.chain(self.min_age.iter_mut())
.chain(self.ge_amount.iter_mut())
.chain(self.age_range.iter_mut())
.chain(self.epoch.iter_mut())
.chain(self.amount_range.iter_mut())
.chain(self.lt_amount.iter_mut())
.chain(self._type.iter_mut())
}
pub fn as_mut_separate_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.age_range
.as_mut_vec()
.into_iter()
.chain(self.epoch.as_mut_vec())
.chain(self.amount_range.as_mut_vec())
.chain(self._type.as_mut_vec())
.collect::<Vec<_>>()
.iter_mut()
.chain(self.epoch.iter_mut())
.chain(self.amount_range.iter_mut())
.chain(self._type.iter_mut())
}
pub fn as_mut_overlapping_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.all]
.into_iter()
.chain(self.term.as_mut_vec())
.chain(self.max_age.as_mut_vec())
.chain(self.min_age.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.chain(self.ge_amount.as_mut_vec())
.collect::<Vec<_>>()
.chain(self.term.iter_mut())
.chain(self.max_age.iter_mut())
.chain(self.min_age.iter_mut())
.chain(self.lt_amount.iter_mut())
.chain(self.ge_amount.iter_mut())
}
}
impl<T> UTXOGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.all.1]
.into_iter()
.chain(self.term.vecs())
.chain(self.max_age.vecs())
.chain(self.min_age.vecs())
.chain(self.age_range.vecs())
.chain(self.epoch.vecs())
.chain(self.amount_range.vecs())
.chain(self._type.vecs())
.chain(self.lt_amount.vecs())
.chain(self.ge_amount.vecs())
.collect::<Vec<_>>()
.chain(self.term.iter_right())
.chain(self.max_age.iter_right())
.chain(self.min_age.iter_right())
.chain(self.age_range.iter_right())
.chain(self.epoch.iter_right())
.chain(self.amount_range.iter_right())
.chain(self._type.iter_right())
.chain(self.lt_amount.iter_right())
.chain(self.ge_amount.iter_right())
}
}
@@ -134,3 +134,8 @@ impl CheckedSub<usize> for Bitcoin {
Some(Self(self.0 - rhs as f64))
}
}
impl CheckedSub<Bitcoin> for Bitcoin {
fn checked_sub(self, rhs: Bitcoin) -> Option<Self> {
Some(Self(self.0 - rhs.0))
}
}
+24 -1
View File
@@ -1,8 +1,10 @@
use jiff::{Span, civil::Date as Date_, tz::TimeZone};
use jiff::{Span, Zoned, civil::Date as Date_, tz::TimeZone};
use serde::{Serialize, Serializer};
use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::ONE_DAY_IN_SEC_F64;
use super::{DateIndex, Timestamp};
#[derive(
@@ -51,6 +53,21 @@ impl Date {
pub fn today() -> Self {
Self::from(Timestamp::now())
}
pub fn completion(&self) -> f64 {
let date = Date_::from(*self);
let now = Zoned::now().with_time_zone(TimeZone::UTC);
let today = now.date();
if date < today {
1.0
} else if date == today {
let rounded = jiff::Timestamp::from(*self);
now.timestamp().duration_since(rounded).as_secs_f64() / ONE_DAY_IN_SEC_F64
} else {
0.0
}
}
}
impl Default for Date {
@@ -71,6 +88,12 @@ impl From<Date> for Date_ {
}
}
impl From<Date> for jiff::Timestamp {
fn from(value: Date) -> Self {
Self::from(Timestamp::from(value))
}
}
impl From<Timestamp> for Date {
fn from(value: Timestamp) -> Self {
Self::from(Date_::from(
@@ -10,6 +10,8 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
pub const BLOCKS_PER_DIFF_EPOCHS: u32 = 2016;
#[derive(
Debug,
Clone,
@@ -79,7 +81,7 @@ impl Div<usize> for DifficultyEpoch {
impl From<Height> for DifficultyEpoch {
fn from(value: Height) -> Self {
Self((u32::from(value) / 2016) as u16)
Self((u32::from(value) / BLOCKS_PER_DIFF_EPOCHS) as u16)
}
}
+26 -4
View File
@@ -1,6 +1,7 @@
use std::{
cmp::Ordering,
f64,
iter::Sum,
ops::{Add, AddAssign, Div, Mul},
};
@@ -10,6 +11,8 @@ use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Low, Open};
use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64};
#[derive(
@@ -80,15 +83,27 @@ impl From<Dollars> for f64 {
}
}
impl From<Close<Dollars>> for Dollars {
fn from(value: Close<Dollars>) -> Self {
Self(value.0)
impl From<Open<Dollars>> for Dollars {
fn from(value: Open<Dollars>) -> Self {
*value
}
}
impl From<High<Dollars>> for Dollars {
fn from(value: High<Dollars>) -> Self {
Self(value.0)
*value
}
}
impl From<Low<Dollars>> for Dollars {
fn from(value: Low<Dollars>) -> Self {
*value
}
}
impl From<Close<Dollars>> for Dollars {
fn from(value: Close<Dollars>) -> Self {
*value
}
}
@@ -364,3 +379,10 @@ impl Ord for Dollars {
}
}
}
impl Sum for Dollars {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let dollars: f64 = iter.map(|dollars| dollars.0).sum();
Self::from(dollars)
}
}
@@ -10,6 +10,8 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
pub const BLOCKS_PER_HALVING: u32 = 210_000;
#[derive(
Debug,
Clone,
@@ -78,7 +80,7 @@ impl Add<usize> for HalvingEpoch {
impl From<Height> for HalvingEpoch {
fn from(value: Height) -> Self {
Self((u32::from(value) / 210_000) as u16)
Self((u32::from(value) / BLOCKS_PER_HALVING) as u16)
}
}
+9 -1
View File
@@ -12,7 +12,7 @@ use vecdb::{CheckedSub, Printable, Stamp, StoredCompressed};
use zerocopy::{FromBytes, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::copy_first_4bytes;
use crate::{BLOCKS_PER_DIFF_EPOCHS, BLOCKS_PER_HALVING, copy_first_4bytes};
use super::StoredU64;
@@ -72,6 +72,14 @@ impl Height {
pub fn is_not_zero(self) -> bool {
self != Self::ZERO
}
pub fn left_before_next_diff_adj(self) -> u32 {
BLOCKS_PER_DIFF_EPOCHS - (*self % BLOCKS_PER_DIFF_EPOCHS)
}
pub fn left_before_next_halving(self) -> u32 {
BLOCKS_PER_HALVING - (*self % BLOCKS_PER_HALVING)
}
}
impl PartialEq<u64> for Height {
+38
View File
@@ -9,6 +9,8 @@ use serde::{Serialize, Serializer, ser::SerializeTuple};
use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::StoredF64;
use super::{Cents, Dollars, Sats};
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
@@ -217,6 +219,15 @@ where
}
}
impl<T> From<Open<T>> for StoredF64
where
StoredF64: From<T>,
{
fn from(value: Open<T>) -> Self {
Self::from(value.0)
}
}
impl<T> From<Close<T>> for Open<T>
where
T: Copy,
@@ -315,6 +326,15 @@ where
}
}
impl<T> From<High<T>> for StoredF64
where
StoredF64: From<T>,
{
fn from(value: High<T>) -> Self {
Self::from(value.0)
}
}
impl<T> From<Close<T>> for High<T>
where
T: Copy,
@@ -413,6 +433,15 @@ where
}
}
impl<T> From<Low<T>> for StoredF64
where
StoredF64: From<T>,
{
fn from(value: Low<T>) -> Self {
Self::from(value.0)
}
}
impl<T> From<Close<T>> for Low<T>
where
T: Copy,
@@ -530,6 +559,15 @@ where
}
}
impl<T> From<Close<T>> for StoredF64
where
StoredF64: From<T>,
{
fn from(value: Close<T>) -> Self {
Self::from(value.0)
}
}
// impl<A, B> From<Close<A>> for Close<B>
// where
// B: From<A>,
@@ -153,6 +153,13 @@ impl Mul<usize> for StoredF32 {
}
}
impl Mul<StoredF32> for StoredF32 {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl Mul<StoredF32> for usize {
type Output = StoredF32;
fn mul(self, rhs: StoredF32) -> Self::Output {
@@ -64,6 +64,20 @@ impl Mul<usize> for StoredF64 {
}
}
impl Mul<StoredF64> for StoredF64 {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
Self(self.0 * rhs.0)
}
}
impl Mul<Dollars> for StoredF64 {
type Output = Self;
fn mul(self, rhs: Dollars) -> Self::Output {
Self(self.0 * *rhs)
}
}
impl Div<usize> for StoredF64 {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
@@ -175,3 +189,10 @@ impl Sum for StoredF64 {
Self(iter.map(|v| v.0).sum::<f64>())
}
}
impl Div<Bitcoin> for StoredF64 {
type Output = Self;
fn div(self, rhs: Bitcoin) -> Self::Output {
Self(self.0 / f64::from(rhs))
}
}
+3 -11
View File
@@ -28,9 +28,9 @@ use super::Date;
)]
pub struct Timestamp(u32);
const ONE_HOUR_IN_SEC: u32 = 60 * 60;
const ONE_DAY_IN_SEC: u32 = 24 * 60 * 60;
const ONE_DAY_IN_SEC_F64: f64 = ONE_DAY_IN_SEC as f64;
pub const ONE_HOUR_IN_SEC: u32 = 60 * 60;
pub const ONE_DAY_IN_SEC: u32 = 24 * 60 * 60;
pub const ONE_DAY_IN_SEC_F64: f64 = ONE_DAY_IN_SEC as f64;
impl Timestamp {
pub const ZERO: Self = Self(0);
@@ -75,14 +75,6 @@ impl Timestamp {
pub fn now() -> Self {
Self::from(jiff::Timestamp::now())
}
pub fn day_completion(&self) -> f64 {
let rounded = jiff::Timestamp::from(Self::from(Date::from(*self)));
ONE_DAY_IN_SEC_F64
/ jiff::Timestamp::from(*self)
.duration_since(rounded)
.as_secs_f64()
}
}
impl From<u32> for Timestamp {
+2
View File
@@ -0,0 +1,2 @@
[toolchain]
channel = "1.89.0"
@@ -143,6 +143,7 @@ function createChartElement({
}),
);
// Takes a bit more space sometimes but it's better UX than having the scale being resized on option change
ichart.priceScale("right").applyOptions({
minimumWidth: 80,
});
@@ -288,7 +289,7 @@ function createChartElement({
choices: /** @type {const} */ (["lin", "log"]),
id: utils.stringToId(`${id} ${paneIndex} ${unit}`),
defaultValue:
unit === "USD" && seriesType !== "Baseline" ? "log" : "lin",
unit === "usd" && seriesType !== "Baseline" ? "log" : "lin",
key: `${id}-price-scale-${paneIndex}`,
signals,
});
@@ -680,7 +681,7 @@ function createChartElement({
data,
options,
}) {
color ||= unit === "USD" ? colors.green : colors.orange;
color ||= unit === "usd" ? colors.green : colors.orange;
/** @type {LineISeries} */
const iseries = /** @type {any} */ (
@@ -691,6 +692,9 @@ function createChartElement({
visible: defaultActive !== false,
priceLineVisible: false,
color: color(),
// lineVisible: false,
// pointMarkersVisible: true,
// pointMarkersRadius: 1,
...options,
},
paneIndex,
+2 -2
View File
@@ -367,7 +367,7 @@ export function init({
case null:
case CANDLE: {
series = chart.addCandlestickSeries({
vecId: "ohlc_in_sats",
vecId: "price_ohlc_in_sats",
name: "Price",
unit: topUnit,
inverse: true,
@@ -378,7 +378,7 @@ export function init({
}
case LINE: {
series = chart.addLineSeries({
vecId: "close_in_sats",
vecId: "price_close_in_sats",
name: "Price",
unit: topUnit,
color: colors.default,
+114 -74
View File
@@ -12,54 +12,57 @@
/**
* @typedef {"" |
* "BTC" |
* "Cents" |
* "coinblocks" |
* "coindays" |
* "satblocks" |
* "satdays" |
* "Count" |
* "Date" |
* "Difficulty" |
* "ExaHash / Second" |
* "Gigabytes" |
* "Hash" |
* "Index" |
* "percentage" |
* "Ratio" |
* "Sats" |
* "secs" |
* "Timestamp" |
* "tx" |
* "Type" |
* "USD / (PetaHash / Second)" |
* "USD" |
* "Version" |
* "WU" |
* "Bool" |
* "Days" |
* "%mcap" |
* "%all" |
* "%cmcap" |
* "%cp+l" |
* "%mcap" |
* "%pnl" |
* "%rcap" |
* "%self" |
* "%all" |
* "Years" |
* "H/s" |
* "Locktime" |
* "sat/vB" |
* "%pnl" |
* "constant" |
* "vB" |
* "block" |
* "id" |
* "/sec" |
* "address data" |
* "block" |
* "blocks" |
* "bool" |
* "btc" |
* "bytes" |
* "cents" |
* "coinblocks" |
* "coindays" |
* "constant" |
* "count" |
* "date" |
* "days" |
* "difficulty" |
* "epoch" |
* "gigabytes" |
* "h/s" |
* "hash" |
* "height" |
* "id" |
* "index" |
* "locktime" |
* "percentage" |
* "ratio" |
* "sat/vb" |
* "satblocks" |
* "satdays" |
* "sats" |
* "sats/(ph/s)/day" |
* "sats/(th/s)/day" |
* "sd" |
* "Epoch" |
* "Height" |
* "Type" |
* "Bytes"
* } Unit
* "secs" |
* "timestamp" |
* "tx" |
* "type" |
* "usd" |
* "usd/(ph/s)/day" |
* "usd/(th/s)/day" |
* "vb" |
* "version" |
* "wu" |
* "years" |
* "" } Unit
*/
const localhost = window.location.hostname === "localhost";
@@ -742,6 +745,8 @@ function createUtils() {
(id.includes("in_sats") ||
(id.endsWith("supply") &&
!(id.endsWith("circulating_supply") || id.endsWith("_own_supply"))) ||
id === "sent" ||
id === "annualized_volume" ||
id.endsWith("supply_half") ||
id.endsWith("supply_breakeven") ||
id.endsWith("supply_in_profit") ||
@@ -760,14 +765,23 @@ function createUtils() {
id.endsWith("dominance")
)))
) {
setUnit("Sats");
setUnit("sats");
}
if ((!unit || thoroughUnitCheck) && id.includes("in_btc")) {
setUnit("BTC");
if (
(!unit || thoroughUnitCheck) &&
!id.endsWith("velocity") &&
((id.includes("_btc") &&
!(id.includes("0k_btc") || id.includes("1k_btc"))) ||
id.endsWith("_btc"))
) {
setUnit("btc");
}
if ((!unit || thoroughUnitCheck) && id === "chain") {
setUnit("block");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("blocks_before")) {
setUnit("blocks");
}
if (
(!unit || thoroughUnitCheck) &&
(id === "emptyaddressdata" || id === "loadedaddressdata")
@@ -783,11 +797,14 @@ function createUtils() {
id === "price_open" ||
id === "price_ath" ||
id === "market_cap" ||
id.includes("_usd") ||
id.startsWith("price_true_range") ||
(id.includes("_usd") && !id.endsWith("velocity")) ||
id.includes("cointime_value") ||
id.endsWith("_ago") ||
id.endsWith("price_paid") ||
id.endsWith("_price") ||
(id.startsWith("price") &&
(id.endsWith("min") || id.endsWith("max"))) ||
(id.endsWith("_cap") && !id.includes("rel_to")) ||
id.endsWith("value_created") ||
id.endsWith("value_destroyed") ||
@@ -800,10 +817,10 @@ function createUtils() {
!id.includes("hash_rate")) ||
id === "ath")
) {
setUnit("USD");
setUnit("usd");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("cents")) {
setUnit("Cents");
setUnit("cents");
}
if (
((!unit || thoroughUnitCheck) &&
@@ -825,17 +842,22 @@ function createUtils() {
id.endsWith("pct99"))) ||
id.includes("liveliness") ||
id.includes("vaultedness") ||
id == "puell_multiple"
id == "puell_multiple" ||
id.endsWith("velocity")
) {
setUnit("Ratio");
setUnit("ratio");
}
if (
(!unit || thoroughUnitCheck) &&
(id === "price_drawdown" ||
id.endsWith("oscillator") ||
id.endsWith("dominance") ||
id.endsWith("returns") ||
id.endsWith("cagr"))
id === "difficulty_adjustment" ||
id.endsWith("inflation_rate") ||
id.endsWith("_oscillator") ||
id.endsWith("_dominance") ||
id.endsWith("_returns") ||
id.endsWith("_rebound") ||
id.endsWith("_volatility") ||
id.endsWith("_cagr"))
) {
setUnit("percentage");
}
@@ -847,25 +869,25 @@ function createUtils() {
id.includes("blocks_mined") ||
(id.includes("tx_v") && !id.includes("vsize")))
) {
setUnit("Count");
setUnit("count");
}
if (
(!unit || thoroughUnitCheck) &&
(id.startsWith("hash_rate") || id.endsWith("as_hash"))
) {
setUnit("H/s");
setUnit("h/s");
}
if ((!unit || thoroughUnitCheck) && id === "pool") {
setUnit("id");
}
if ((!unit || thoroughUnitCheck) && id.includes("fee_rate")) {
setUnit("sat/vB");
setUnit("sat/vb");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("is_")) {
setUnit("Bool");
setUnit("bool");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("type")) {
setUnit("Type");
setUnit("type");
}
if (
(!unit || thoroughUnitCheck) &&
@@ -873,12 +895,15 @@ function createUtils() {
) {
setUnit("secs");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("_per_sec")) {
setUnit("/sec");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("locktime")) {
setUnit("Locktime");
setUnit("locktime");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("version")) {
setUnit("Version");
setUnit("version");
}
if (
(!unit || thoroughUnitCheck) &&
@@ -888,7 +913,7 @@ function createUtils() {
id.endsWith("total_size") ||
id.includes("block_size"))
) {
setUnit("Bytes");
setUnit("bytes");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("_sd")) {
setUnit("sd");
@@ -897,25 +922,25 @@ function createUtils() {
(!unit || thoroughUnitCheck) &&
(id.includes("vsize") || id.includes("vbytes"))
) {
setUnit("vB");
setUnit("vb");
}
if ((!unit || thoroughUnitCheck) && id.includes("weight")) {
setUnit("WU");
setUnit("wu");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("index")) {
setUnit("Index");
setUnit("index");
}
if (
(!unit || thoroughUnitCheck) &&
(id === "date" || id === "date_fixed")
) {
setUnit("Date");
setUnit("date");
}
if (
(!unit || thoroughUnitCheck) &&
(id === "timestamp" || id === "timestamp_fixed")
) {
setUnit("Timestamp");
setUnit("timestamp");
}
if ((!unit || thoroughUnitCheck) && id.includes("coinblocks")) {
setUnit("coinblocks");
@@ -930,7 +955,7 @@ function createUtils() {
setUnit("satdays");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("height")) {
setUnit("Height");
setUnit("height");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("rel_to_market_cap")) {
setUnit("%mcap");
@@ -964,22 +989,37 @@ function createUtils() {
setUnit("%self");
}
if ((!unit || thoroughUnitCheck) && id.endsWith("epoch")) {
setUnit("Epoch");
setUnit("epoch");
}
if ((!unit || thoroughUnitCheck) && id === "difficulty") {
setUnit("Difficulty");
setUnit("difficulty");
}
if ((!unit || thoroughUnitCheck) && id === "blockhash") {
setUnit("Hash");
setUnit("hash");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("hash_price_phs")) {
setUnit("usd/(ph/s)/day");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("hash_price_ths")) {
setUnit("usd/(th/s)/day");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("hash_value_phs")) {
setUnit("sats/(ph/s)/day");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("hash_value_ths")) {
setUnit("sats/(th/s)/day");
}
if (
(!unit || thoroughUnitCheck) &&
(id.includes("days_between") || id.includes("days_since"))
(id.includes("days_between") ||
id.includes("days_since") ||
id.startsWith("days_before"))
) {
setUnit("Days");
setUnit("days");
}
if ((!unit || thoroughUnitCheck) && id.includes("years_between")) {
setUnit("Years");
setUnit("years");
}
if ((!unit || thoroughUnitCheck) && id.startsWith("constant")) {
setUnit("constant");
File diff suppressed because it is too large Load Diff
+3 -1
View File
@@ -520,7 +520,9 @@ function createIndexToVecIds(vecIdToIndexes) {
*/
function serializeValue({ value, unit }) {
const t = typeof value;
if (typeof value === "string") {
if (value === null) {
return "null";
} else if (typeof value === "string") {
return value;
} else if (t !== "number") {
return JSON.stringify(value).replaceAll('"', "").slice(1, -1);