Compare commits

...

29 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
nym21 a39b7be1d1 release: v0.0.101 2025-09-07 21:55:56 +02:00
nym21 de98c5f706 global: fixes 2025-09-07 21:55:39 +02:00
nym21 10b496e845 release: v0.0.100 2025-09-07 17:14:10 +02:00
nym21 bbe7bf390d crates: upgrade rest 2025-09-07 17:13:57 +02:00
nym21 4777b3400a crates: upgrade seqdb 2025-09-07 17:13:01 +02:00
nym21 acaa70e944 release: v0.0.99 2025-09-07 17:01:58 +02:00
nym21 4049d694f7 global: snapshot + pools + fixes 2025-09-07 17:01:34 +02:00
nym21 e155a3dacf bitview: fix localstorage error 2025-09-06 15:41:16 +02:00
111 changed files with 9121 additions and 6503 deletions
+1 -1
View File
@@ -64,7 +64,7 @@ jobs:
# we specify bash to get pipefail; it guards against the `curl` command # we specify bash to get pipefail; it guards against the `curl` command
# failing. otherwise `sh` won't catch that `curl` returned non-0 # failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash 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 - name: Cache dist
uses: actions/upload-artifact@v4 uses: actions/upload-artifact@v4
with: with:
+1 -1
View File
@@ -4,7 +4,7 @@
# Builds # Builds
target target
websites/dist websites/dist
vecid-to-indexes.js bridge/
/ids.txt /ids.txt
# Copies # Copies
Generated
+465 -200
View File
File diff suppressed because it is too large Load Diff
+40 -18
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.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.license = "MIT"
package.edition = "2024" package.edition = "2024"
package.version = "0.0.98" package.version = "0.0.107"
package.homepage = "https://bitcoinresearchkit.org" package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk" package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md" package.readme = "README.md"
package.rust-version = "1.89" package.rust-version = "1.89"
[profile.dev]
lto = "thin"
debug = true
codegen-units = 1
opt-level = 3
overflow-checks = true
[profile.release] [profile.release]
lto = "fat" lto = "fat"
codegen-units = 1 codegen-units = 1
panic = "abort" panic = "abort"
strip = true
overflow-checks = false
[profile.profiling] [profile.profiling]
inherits = "release" inherits = "release"
@@ -22,23 +31,36 @@ debug = true
[profile.dist] [profile.dist]
inherits = "release" 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] [workspace.dependencies]
allocative = { version = "0.3.4", features = ["parking_lot"] }
allocative_derive = "0.3.3"
axum = "0.8.4" axum = "0.8.4"
bitcoin = { version = "0.32.7", features = ["serde"] } bitcoin = { version = "0.32.7", features = ["serde"] }
bitcoincore-rpc = "0.19.0" bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.98", path = "crates/brk_bundler" } brk_bundler = { version = "0.0.107", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.98", path = "crates/brk_cli" } brk_cli = { version = "0.0.107", path = "crates/brk_cli" }
brk_computer = { version = "0.0.98", path = "crates/brk_computer" } brk_computer = { version = "0.0.107", path = "crates/brk_computer" }
brk_error = { version = "0.0.98", path = "crates/brk_error" } brk_error = { version = "0.0.107", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.98", path = "crates/brk_fetcher" } brk_fetcher = { version = "0.0.107", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.98", path = "crates/brk_indexer" } brk_indexer = { version = "0.0.107", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.98", path = "crates/brk_interface" } brk_interface = { version = "0.0.107", path = "crates/brk_interface" }
brk_logger = { version = "0.0.98", path = "crates/brk_logger" } brk_logger = { version = "0.0.107", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.98", path = "crates/brk_mcp" } brk_mcp = { version = "0.0.107", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.98", path = "crates/brk_parser" } brk_parser = { version = "0.0.107", path = "crates/brk_parser" }
brk_server = { version = "0.0.98", path = "crates/brk_server" } brk_server = { version = "0.0.107", path = "crates/brk_server" }
brk_store = { version = "0.0.98", path = "crates/brk_store" } brk_store = { version = "0.0.107", path = "crates/brk_store" }
brk_structs = { version = "0.0.98", path = "crates/brk_structs" } brk_structs = { version = "0.0.107", path = "crates/brk_structs" }
byteview = "=0.6.1" byteview = "=0.6.1"
derive_deref = "1.1.1" derive_deref = "1.1.1"
fjall = "2.11.2" fjall = "2.11.2"
@@ -54,9 +76,9 @@ serde_derive = "1.0.219"
serde_json = { version = "1.0.143", features = ["float_roundtrip"] } serde_json = { version = "1.0.143", features = ["float_roundtrip"] }
tokio = { version = "1.47.1", features = ["rt-multi-thread"] } tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]} # vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]}
vecdb = { version = "0.2.9", features = ["derive"]} vecdb = { version = "0.2.14", features = ["derive"]}
zerocopy = "0.8.26" zerocopy = "0.8.27"
zerocopy-derive = "0.8.26" zerocopy-derive = "0.8.27"
[workspace.metadata.release] [workspace.metadata.release]
shared-version = true shared-version = true
@@ -65,7 +87,7 @@ pre-release-commit-message = "release: v{{version}}"
tag-message = "release: v{{version}}" tag-message = "release: v{{version}}"
[workspace.metadata.dist] [workspace.metadata.dist]
cargo-dist-version = "0.29.0" cargo-dist-version = "0.30.0"
ci = "github" ci = "github"
allow-dirty = ["ci"] allow-dirty = ["ci"]
installers = [] installers = []
+1 -3
View File
@@ -64,11 +64,9 @@
- miners - miners
- maybe xpubs - maybe xpubs
- charts - charts
- improve some names and colors - improve names and colors
- remove `sum` series when it's a duplicate of the `base` (in subsidy for example)
- selected unit sometimes changes when going back end forth - selected unit sometimes changes when going back end forth
- add support for custom charts - add support for custom charts
- separate z-score charts from "realized price" (with their own prices), have 4y, 2y and 1y
- price scale format depends on unit, hide digits for sats for example (if/when possible) - price scale format depends on unit, hide digits for sats for example (if/when possible)
- table - table
- pagination - pagination
+1 -1
View File
@@ -12,7 +12,7 @@ build = "build.rs"
[dependencies] [dependencies]
log = { workspace = true } log = { workspace = true }
notify = "8.2.0" notify = "8.2.0"
brk_rolldown = "0.1.4" brk_rolldown = "0.1.5"
# brk_rolldown = { path = "../../../rolldown/crates/rolldown"} # brk_rolldown = { path = "../../../rolldown/crates/rolldown"}
sugar_path = "1.2.0" sugar_path = "1.2.0"
tokio = { workspace = true } tokio = { workspace = true }
+3 -1
View File
@@ -35,7 +35,9 @@ pub async fn bundle(websites_path: &Path, source_folder: &str, watch: bool) -> i
..Default::default() ..Default::default()
}); });
bundler.write().await.unwrap(); if let Err(error) = bundler.write().await {
error!("{error:?}");
}
let absolute_source_index_path = source_path.join("index.html").absolutize(); let absolute_source_index_path = source_path.join("index.html").absolutize();
let absolute_source_index_path_clone = absolute_source_index_path.clone(); let absolute_source_index_path_clone = absolute_source_index_path.clone();
+1 -1
View File
@@ -28,7 +28,7 @@ minreq = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
tokio = { workspace = true } tokio = { workspace = true }
toml = "0.9.5" toml = "0.9.5"
zip = { version = "4.6.1", default-features = false, features = ["deflate"] } zip = { version = "5.1.1", default-features = false, features = ["deflate"] }
[[bin]] [[bin]]
name = "brk" name = "brk"
+98 -55
View File
@@ -1,19 +1,20 @@
use std::{fs, io, path::Path}; use std::{fs, io, path::Path};
use brk_computer::pools;
use brk_interface::{Index, Interface}; use brk_interface::{Index, Interface};
use brk_server::VERSION; use brk_server::VERSION;
use crate::website::Website; use crate::website::Website;
const SCRIPTS: &str = "scripts"; const BRIDGE_PATH: &str = "scripts/bridge";
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
pub trait Bridge { pub trait Bridge {
fn generate_bridge_file(&self, website: Website, websites_path: &Path) -> io::Result<()>; fn generate_bridge_files(&self, website: Website, websites_path: &Path) -> io::Result<()>;
} }
impl Bridge for Interface<'static> { impl Bridge for Interface<'static> {
fn generate_bridge_file(&self, website: Website, websites_path: &Path) -> io::Result<()> { fn generate_bridge_files(&self, website: Website, websites_path: &Path) -> io::Result<()> {
if website.is_none() { if website.is_none() {
return Ok(()); return Ok(());
} }
@@ -24,88 +25,130 @@ impl Bridge for Interface<'static> {
return Ok(()); return Ok(());
} }
let path = path.join(SCRIPTS); let path = path.join(BRIDGE_PATH);
fs::create_dir_all(&path)?; fs::create_dir_all(&path)?;
let path = path.join(Path::new("vecid-to-indexes.js")); generate_vecs_file(self, &path)?;
generate_pools_file(&path)
}
}
let indexes = Index::all(); fn generate_pools_file(parent: &Path) -> io::Result<()> {
let path = parent.join(Path::new("pools.js"));
let mut contents = format!( let pools = pools();
"//
let mut contents = "//
// File auto-generated, any modifications will be overwritten
//
"
.to_string();
contents += "
/** @typedef {ReturnType<typeof createPools>} Pools */
/** @typedef {keyof Pools} Pool */
export function createPools() {
return /** @type {const} */ ({
";
let mut sorted_pools: Vec<_> = pools.iter().collect();
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
contents += &sorted_pools
.iter()
.map(|pool| {
let id = pool.serialized_id();
format!(" {id}: \"{}\",", pool.name)
})
.collect::<Vec<_>>()
.join("\n");
contents += "\n });\n}\n";
fs::write(path, contents)
}
fn generate_vecs_file(interface: &Interface<'static>, parent: &Path) -> io::Result<()> {
let path = parent.join(Path::new("vecs.js"));
let indexes = Index::all();
let mut contents = format!(
"//
// File auto-generated, any modifications will be overwritten // File auto-generated, any modifications will be overwritten
// //
export const VERSION = \"v{VERSION}\"; export const VERSION = \"v{VERSION}\";
" "
); );
contents += &indexes contents += &indexes
.iter()
.enumerate()
.map(|(i_of_i, i)| {
// let lowered = i.to_string().to_lowercase();
format!("/** @typedef {{{i_of_i}}} {i} */",)
})
.collect::<Vec<_>>()
.join("\n");
contents += &format!(
"\n\n/** @typedef {{{}}} Index */\n",
indexes
.iter() .iter()
.enumerate() .map(|i| i.to_string())
.map(|(i_of_i, i)| {
// let lowered = i.to_string().to_lowercase();
format!("/** @typedef {{{i_of_i}}} {i} */",)
})
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join(" | ")
);
contents += &format!( contents += "
"\n\n/** @typedef {{{}}} Index */\n",
indexes
.iter()
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join(" | ")
);
contents += "
/** @typedef {ReturnType<typeof createIndexes>} Indexes */ /** @typedef {ReturnType<typeof createIndexes>} Indexes */
export function createIndexes() { export function createIndexes() {
return { return {
"; ";
contents += &indexes contents += &indexes
.iter() .iter()
.enumerate() .enumerate()
.map(|(i_of_i, i)| { .map(|(i_of_i, i)| {
let lowered = i.to_string().to_lowercase(); let lowered = i.to_string().to_lowercase();
format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",) format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",)
}) })
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join("\n"); .join("\n");
contents += " };\n}\n"; contents += " };\n}\n";
contents += " contents += "
/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes /** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes
/** @typedef {keyof VecIdToIndexes} VecId */ /** @typedef {keyof VecIdToIndexes} VecId */
/** /**
* @returns {Record<any, number[]>} * @returns {Record<any, number[]>}
*/ */
export function createVecIdToIndexes() { export function createVecIdToIndexes() {
return { return {
"; ";
self.id_to_index_to_vec() interface
.iter() .id_to_index_to_vec()
.for_each(|(id, index_to_vec)| { .iter()
let indexes = index_to_vec .for_each(|(id, index_to_vec)| {
.keys() let indexes = index_to_vec
.map(|i| (*i as u8).to_string()) .keys()
// .map(|i| i.to_string()) .map(|i| (*i as u8).to_string())
.collect::<Vec<_>>() // .map(|i| i.to_string())
.join(", "); .collect::<Vec<_>>()
.join(", ");
contents += &format!(" \"{id}\": [{indexes}],\n"); contents += &format!(" \"{id}\": [{indexes}],\n");
}); });
contents += " };\n}\n"; contents += " };\n}\n";
fs::write(path, contents) fs::write(path, contents)
}
} }
-1
View File
@@ -6,7 +6,6 @@ use std::{
use bitcoincore_rpc::{self, Auth, Client}; use bitcoincore_rpc::{self, Auth, Client};
use brk_fetcher::Fetcher; use brk_fetcher::Fetcher;
use clap::Parser; use clap::Parser;
use clap_derive::Parser;
use color_eyre::eyre::eyre; use color_eyre::eyre::eyre;
use serde::{Deserialize, Deserializer, Serialize}; use serde::{Deserialize, Deserializer, Serialize};
+3 -1
View File
@@ -107,7 +107,7 @@ pub fn run() -> color_eyre::Result<()> {
downloaded_websites_path downloaded_websites_path
}; };
interface.generate_bridge_file(website, websites_path.as_path())?; interface.generate_bridge_files(website, websites_path.as_path())?;
Some(bundle(&websites_path, website.to_folder_name(), true).await?) Some(bundle(&websites_path, website.to_folder_name(), true).await?)
} else { } else {
@@ -135,6 +135,8 @@ pub fn run() -> color_eyre::Result<()> {
let starting_indexes = let starting_indexes =
indexer.index(&parser, rpc, &exit, config.check_collisions()).unwrap(); indexer.index(&parser, rpc, &exit, config.check_collisions()).unwrap();
// dbg!(&starting_indexes);
computer.compute(&indexer, starting_indexes, &exit).unwrap(); computer.compute(&indexer, starting_indexes, &exit).unwrap();
info!("Waiting for new blocks..."); info!("Waiting for new blocks...");
+1
View File
@@ -2,6 +2,7 @@ use clap_derive::ValueEnum;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)]
#[serde(rename_all = "lowercase")]
pub enum Website { pub enum Website {
None, None,
Bitview, Bitview,
+6
View File
@@ -10,6 +10,8 @@ rust-version.workspace = true
build = "build.rs" build = "build.rs"
[dependencies] [dependencies]
allocative = { workspace = true }
allocative_derive = { workspace = true }
bitcoin = { workspace = true } bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true } bitcoincore-rpc = { workspace = true }
brk_structs = { workspace = true } brk_structs = { workspace = true }
@@ -17,14 +19,18 @@ brk_error = { workspace = true }
brk_fetcher = { workspace = true } brk_fetcher = { workspace = true }
brk_indexer = { workspace = true } brk_indexer = { workspace = true }
brk_logger = { workspace = true } brk_logger = { workspace = true }
brk_store = { workspace = true }
brk_parser = { workspace = true } brk_parser = { workspace = true }
vecdb = { workspace = true } vecdb = { workspace = true }
derive_deref = { workspace = true } derive_deref = { workspace = true }
inferno = "0.12.3"
jiff = { workspace = true }
log = { workspace = true } log = { workspace = true }
num_enum = "0.7.4" num_enum = "0.7.4"
pco = "0.4.6" pco = "0.4.6"
rayon = { workspace = true } rayon = { workspace = true }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true }
zerocopy = { workspace = true } zerocopy = { workspace = true }
zerocopy-derive = { workspace = true } zerocopy-derive = { workspace = true }
+82 -12
View File
@@ -4,7 +4,8 @@ use brk_computer::{Computer, pools};
use brk_error::Result; use brk_error::Result;
use brk_fetcher::Fetcher; use brk_fetcher::Fetcher;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use vecdb::Exit; use brk_structs::{AddressBytes, OutputIndex, OutputType};
use vecdb::{AnyIterableVec, Exit, VecIterator};
fn main() -> Result<()> { fn main() -> Result<()> {
brk_logger::init(Some(Path::new(".log")))?; brk_logger::init(Some(Path::new(".log")))?;
@@ -27,20 +28,89 @@ fn main() -> Result<()> {
let mut res: BTreeMap<&'static str, usize> = BTreeMap::default(); let mut res: BTreeMap<&'static str, usize> = BTreeMap::default();
let mut height_to_first_txindex_iter = indexer.vecs.height_to_first_txindex.iter(); let vecs = indexer.vecs;
// let mut i = indexer.vecs.txz let stores = indexer.stores;
indexer let mut height_to_first_txindex_iter = vecs.height_to_first_txindex.iter();
.stores let mut txindex_to_first_outputindex_iter = vecs.txindex_to_first_outputindex.iter();
let mut txindex_to_output_count_iter = computer.indexes.txindex_to_output_count.iter();
let mut outputindex_to_outputtype_iter = vecs.outputindex_to_outputtype.iter();
let mut outputindex_to_typeindex_iter = vecs.outputindex_to_typeindex.iter();
let mut p2pk65addressindex_to_p2pk65bytes_iter =
vecs.p2pk65addressindex_to_p2pk65bytes.iter();
let mut p2pk33addressindex_to_p2pk33bytes_iter =
vecs.p2pk33addressindex_to_p2pk33bytes.iter();
let mut p2pkhaddressindex_to_p2pkhbytes_iter =
vecs.p2pkhaddressindex_to_p2pkhbytes.iter();
let mut p2shaddressindex_to_p2shbytes_iter = vecs.p2shaddressindex_to_p2shbytes.iter();
let mut p2wpkhaddressindex_to_p2wpkhbytes_iter =
vecs.p2wpkhaddressindex_to_p2wpkhbytes.iter();
let mut p2wshaddressindex_to_p2wshbytes_iter =
vecs.p2wshaddressindex_to_p2wshbytes.iter();
let mut p2traddressindex_to_p2trbytes_iter = vecs.p2traddressindex_to_p2trbytes.iter();
let mut p2aaddressindex_to_p2abytes_iter = vecs.p2aaddressindex_to_p2abytes.iter();
let unknown = pools.get_unknown();
stores
.height_to_coinbase_tag .height_to_coinbase_tag
.iter() .iter()
.for_each(|(_, coinbase_tag)| { .for_each(|(height, coinbase_tag)| {
let pool = pools.find_from_coinbase_tag(&coinbase_tag); let txindex = height_to_first_txindex_iter.unwrap_get_inner(height);
if let Some(pool) = pool { let outputindex = txindex_to_first_outputindex_iter.unwrap_get_inner(txindex);
*res.entry(pool.name).or_default() += 1; let outputcount = txindex_to_output_count_iter.unwrap_get_inner(txindex);
} else {
*res.entry(pools.get_unknown().name).or_default() += 1; let pool = (*outputindex..(*outputindex + *outputcount))
} .map(OutputIndex::from)
.find_map(|outputindex| {
let outputtype =
outputindex_to_outputtype_iter.unwrap_get_inner(outputindex);
let typeindex =
outputindex_to_typeindex_iter.unwrap_get_inner(outputindex);
let address = match outputtype {
OutputType::P2PK65 => Some(AddressBytes::from(
p2pk65addressindex_to_p2pk65bytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2PK33 => Some(AddressBytes::from(
p2pk33addressindex_to_p2pk33bytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2PKH => Some(AddressBytes::from(
p2pkhaddressindex_to_p2pkhbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2SH => Some(AddressBytes::from(
p2shaddressindex_to_p2shbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2WPKH => Some(AddressBytes::from(
p2wpkhaddressindex_to_p2wpkhbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2WSH => Some(AddressBytes::from(
p2wshaddressindex_to_p2wshbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2TR => Some(AddressBytes::from(
p2traddressindex_to_p2trbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2A => Some(AddressBytes::from(
p2aaddressindex_to_p2abytes_iter
.unwrap_get_inner(typeindex.into()),
)),
_ => None,
};
address
.and_then(|address| pools.find_from_address(&address.to_string()))
})
.or_else(|| pools.find_from_coinbase_tag(&coinbase_tag))
.unwrap_or(unknown);
*res.entry(pool.name).or_default() += 1;
}); });
let mut v = res.into_iter().map(|(k, v)| (v, k)).collect::<Vec<_>>(); let mut v = res.into_iter().map(|(k, v)| (v, k)).collect::<Vec<_>>();
File diff suppressed because it is too large Load Diff
+211 -190
View File
@@ -1,10 +1,11 @@
use std::path::Path; use std::path::Path;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer; use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF32, StoredF64, Version};
use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF64, Version};
use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator}; use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator};
use crate::grouped::ComputedVecsFromDateIndex;
use super::{ use super::{
Indexes, chain, Indexes, chain,
grouped::{ grouped::{
@@ -14,8 +15,6 @@ use super::{
indexes, price, stateful, indexes, price, stateful,
}; };
const VERSION: Version = Version::ZERO;
#[derive(Clone)] #[derive(Clone)]
pub struct Vecs { pub struct Vecs {
db: Database, db: Database,
@@ -43,27 +42,32 @@ pub struct Vecs {
pub indexes_to_cointime_price: ComputedVecsFromHeight<Dollars>, pub indexes_to_cointime_price: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_cap: ComputedVecsFromHeight<Dollars>, pub indexes_to_cointime_cap: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_price_ratio: ComputedRatioVecsFromDateIndex, 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, // pub indexes_to_thermo_cap_rel_to_investor_cap: ComputedValueVecsFromHeight,
} }
impl Vecs { impl Vecs {
pub fn forced_import( pub fn forced_import(
parent: &Path, parent_path: &Path,
version: Version, parent_version: Version,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
) -> Result<Self> { ) -> 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)?; db.set_min_len(PAGE_SIZE * 1_000_000)?;
let compute_dollars = price.is_some(); let compute_dollars = price.is_some();
let version = parent_version + Version::ZERO;
let this = Self { let this = Self {
indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import( indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import(
&db, &db,
"coinblocks_created", "coinblocks_created",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default().add_sum().add_cumulative(),
)?, )?,
@@ -71,7 +75,7 @@ impl Vecs {
&db, &db,
"coinblocks_stored", "coinblocks_stored",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default().add_sum().add_cumulative(),
)?, )?,
@@ -79,7 +83,7 @@ impl Vecs {
&db, &db,
"liveliness", "liveliness",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -87,7 +91,7 @@ impl Vecs {
&db, &db,
"vaultedness", "vaultedness",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -95,7 +99,7 @@ impl Vecs {
&db, &db,
"activity_to_vaultedness_ratio", "activity_to_vaultedness_ratio",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -103,7 +107,7 @@ impl Vecs {
&db, &db,
"vaulted_supply", "vaulted_supply",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
compute_dollars, compute_dollars,
indexes, indexes,
@@ -112,7 +116,7 @@ impl Vecs {
&db, &db,
"active_supply", "active_supply",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
compute_dollars, compute_dollars,
indexes, indexes,
@@ -121,7 +125,7 @@ impl Vecs {
&db, &db,
"thermo_cap", "thermo_cap",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -129,7 +133,7 @@ impl Vecs {
&db, &db,
"investor_cap", "investor_cap",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -137,7 +141,7 @@ impl Vecs {
&db, &db,
"vaulted_cap", "vaulted_cap",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -145,7 +149,7 @@ impl Vecs {
&db, &db,
"active_cap", "active_cap",
Source::Compute, Source::Compute,
version + VERSION + Version::ONE, version + Version::ONE,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -153,7 +157,7 @@ impl Vecs {
&db, &db,
"vaulted_price", "vaulted_price",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -161,7 +165,7 @@ impl Vecs {
&db, &db,
"vaulted_price", "vaulted_price",
Source::None, Source::None,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
true, true,
)?, )?,
@@ -169,7 +173,7 @@ impl Vecs {
&db, &db,
"active_price", "active_price",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -177,7 +181,7 @@ impl Vecs {
&db, &db,
"active_price", "active_price",
Source::None, Source::None,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
true, true,
)?, )?,
@@ -185,7 +189,7 @@ impl Vecs {
&db, &db,
"true_market_mean", "true_market_mean",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -193,7 +197,7 @@ impl Vecs {
&db, &db,
"true_market_mean", "true_market_mean",
Source::None, Source::None,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
true, true,
)?, )?,
@@ -201,7 +205,7 @@ impl Vecs {
&db, &db,
"cointime_value_destroyed", "cointime_value_destroyed",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default().add_sum().add_cumulative(),
)?, )?,
@@ -209,7 +213,7 @@ impl Vecs {
&db, &db,
"cointime_value_created", "cointime_value_created",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default().add_sum().add_cumulative(),
)?, )?,
@@ -217,7 +221,7 @@ impl Vecs {
&db, &db,
"cointime_value_stored", "cointime_value_stored",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_sum().add_cumulative(), VecBuilderOptions::default().add_sum().add_cumulative(),
)?, )?,
@@ -225,7 +229,7 @@ impl Vecs {
&db, &db,
"cointime_price", "cointime_price",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -233,7 +237,7 @@ impl Vecs {
&db, &db,
"cointime_cap", "cointime_cap",
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
VecBuilderOptions::default().add_last(), VecBuilderOptions::default().add_last(),
)?, )?,
@@ -241,17 +245,40 @@ impl Vecs {
&db, &db,
"cointime_price", "cointime_price",
Source::None, Source::None,
version + VERSION + Version::ZERO, version + Version::ZERO,
indexes, indexes,
true, 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, db,
}; };
this.db.retain_regions( this.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -262,7 +289,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn compute( pub fn compute(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
@@ -270,15 +296,7 @@ impl Vecs {
stateful: &stateful::Vecs, stateful: &stateful::Vecs,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.compute_( self.compute_(indexes, starting_indexes, price, chain, stateful, exit)?;
indexer,
indexes,
starting_indexes,
price,
chain,
stateful,
exit,
)?;
self.db.flush_then_punch()?; self.db.flush_then_punch()?;
Ok(()) Ok(())
} }
@@ -286,7 +304,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_( fn compute_(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
@@ -296,12 +313,8 @@ impl Vecs {
) -> Result<()> { ) -> Result<()> {
let circulating_supply = &stateful.utxo_cohorts.all.1.height_to_supply; let circulating_supply = &stateful.utxo_cohorts.all.1.height_to_supply;
self.indexes_to_coinblocks_created.compute_all( self.indexes_to_coinblocks_created
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_transform( vec.compute_transform(
starting_indexes.height, starting_indexes.height,
circulating_supply, circulating_supply,
@@ -309,18 +322,13 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let indexes_to_coinblocks_destroyed = let indexes_to_coinblocks_destroyed =
&stateful.utxo_cohorts.all.1.indexes_to_coinblocks_destroyed; &stateful.utxo_cohorts.all.1.indexes_to_coinblocks_destroyed;
self.indexes_to_coinblocks_stored.compute_all( self.indexes_to_coinblocks_stored
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
let mut coinblocks_destroyed_iter = indexes_to_coinblocks_destroyed let mut coinblocks_destroyed_iter = indexes_to_coinblocks_destroyed
.height .height
.as_ref() .as_ref()
@@ -336,15 +344,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_liveliness.compute_all( self.indexes_to_liveliness
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
indexes_to_coinblocks_destroyed indexes_to_coinblocks_destroyed
@@ -356,16 +359,11 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let liveliness = &self.indexes_to_liveliness; let liveliness = &self.indexes_to_liveliness;
self.indexes_to_vaultedness.compute_all( self.indexes_to_vaultedness
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_transform( vec.compute_transform(
starting_indexes.height, starting_indexes.height,
liveliness.height.as_ref().unwrap(), liveliness.height.as_ref().unwrap(),
@@ -373,16 +371,14 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let vaultedness = &self.indexes_to_vaultedness; let vaultedness = &self.indexes_to_vaultedness;
self.indexes_to_activity_to_vaultedness_ratio.compute_all( self.indexes_to_activity_to_vaultedness_ratio.compute_all(
indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
liveliness.height.as_ref().unwrap(), liveliness.height.as_ref().unwrap(),
@@ -394,12 +390,11 @@ impl Vecs {
)?; )?;
self.indexes_to_vaulted_supply.compute_all( self.indexes_to_vaulted_supply.compute_all(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
circulating_supply, circulating_supply,
@@ -411,12 +406,11 @@ impl Vecs {
)?; )?;
self.indexes_to_active_supply.compute_all( self.indexes_to_active_supply.compute_all(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
circulating_supply, 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 { if let Some(price) = price {
let realized_cap = stateful let realized_cap = stateful
.utxo_cohorts .utxo_cohorts
@@ -447,12 +467,8 @@ impl Vecs {
.as_ref() .as_ref()
.unwrap(); .unwrap();
self.indexes_to_thermo_cap.compute_all( self.indexes_to_thermo_cap
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_transform( vec.compute_transform(
starting_indexes.height, starting_indexes.height,
chain chain
@@ -466,15 +482,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_investor_cap.compute_all( self.indexes_to_investor_cap
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_subtract( vec.compute_subtract(
starting_indexes.height, starting_indexes.height,
realized_cap, realized_cap,
@@ -482,15 +493,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_vaulted_cap.compute_all( self.indexes_to_vaulted_cap
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
realized_cap, realized_cap,
@@ -498,15 +504,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_active_cap.compute_all( self.indexes_to_active_cap
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
realized_cap, realized_cap,
@@ -514,15 +515,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_vaulted_price.compute_all( self.indexes_to_vaulted_price
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
realized_price, realized_price,
@@ -530,24 +526,17 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_vaulted_price_ratio.compute_rest( self.indexes_to_vaulted_price_ratio.compute_rest(
indexer,
indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
Some(self.indexes_to_vaulted_price.dateindex.unwrap_last()), Some(self.indexes_to_vaulted_price.dateindex.unwrap_last()),
)?; )?;
self.indexes_to_active_price.compute_all( self.indexes_to_active_price
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
realized_price, realized_price,
@@ -555,12 +544,9 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_active_price_ratio.compute_rest( self.indexes_to_active_price_ratio.compute_rest(
indexer,
indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
@@ -568,11 +554,10 @@ impl Vecs {
)?; )?;
self.indexes_to_true_market_mean.compute_all( self.indexes_to_true_market_mean.compute_all(
indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
self.indexes_to_investor_cap.height.as_ref().unwrap(), self.indexes_to_investor_cap.height.as_ref().unwrap(),
@@ -588,8 +573,6 @@ impl Vecs {
)?; )?;
self.indexes_to_true_market_mean_ratio.compute_rest( self.indexes_to_true_market_mean_ratio.compute_rest(
indexer,
indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
@@ -597,11 +580,10 @@ impl Vecs {
)?; )?;
self.indexes_to_cointime_value_destroyed.compute_all( self.indexes_to_cointime_value_destroyed.compute_all(
indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, 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 // 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 // The price taken won't be correct for time based indexes
vec.compute_multiply( vec.compute_multiply(
@@ -615,11 +597,10 @@ impl Vecs {
)?; )?;
self.indexes_to_cointime_value_created.compute_all( self.indexes_to_cointime_value_created.compute_all(
indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
&price.chainindexes_to_price_close.height, &price.chainindexes_to_price_close.height,
@@ -631,11 +612,10 @@ impl Vecs {
)?; )?;
self.indexes_to_cointime_value_stored.compute_all( self.indexes_to_cointime_value_stored.compute_all(
indexer,
indexes, indexes,
starting_indexes, starting_indexes,
exit, exit,
|vec, _, _, starting_indexes, exit| { |vec| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
&price.chainindexes_to_price_close.height, &price.chainindexes_to_price_close.height,
@@ -646,12 +626,8 @@ impl Vecs {
}, },
)?; )?;
self.indexes_to_cointime_price.compute_all( self.indexes_to_cointime_price
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_divide( vec.compute_divide(
starting_indexes.height, starting_indexes.height,
self.indexes_to_cointime_value_destroyed self.indexes_to_cointime_value_destroyed
@@ -663,15 +639,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_cointime_cap.compute_all( self.indexes_to_cointime_cap
indexer, .compute_all(indexes, starting_indexes, exit, |vec| {
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
vec.compute_multiply( vec.compute_multiply(
starting_indexes.height, starting_indexes.height,
self.indexes_to_cointime_price.height.as_ref().unwrap(), self.indexes_to_cointime_price.height.as_ref().unwrap(),
@@ -679,50 +650,100 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_cointime_price_ratio.compute_rest( self.indexes_to_cointime_price_ratio.compute_rest(
indexer,
indexes,
price, price,
starting_indexes, starting_indexes,
exit, exit,
Some(self.indexes_to_cointime_price.dateindex.unwrap_last()), 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(()) 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>> =
self.indexes_to_coinblocks_created.vecs(), Box::new(std::iter::empty());
self.indexes_to_coinblocks_stored.vecs(),
self.indexes_to_liveliness.vecs(), iter = Box::new(
self.indexes_to_vaultedness.vecs(), iter.chain(
self.indexes_to_activity_to_vaultedness_ratio.vecs(), self.indexes_to_cointime_adj_inflation_rate
self.indexes_to_vaulted_supply.vecs(), .iter_any_collectable(),
self.indexes_to_active_supply.vecs(), ),
self.indexes_to_thermo_cap.vecs(), );
self.indexes_to_investor_cap.vecs(), iter = Box::new(
self.indexes_to_vaulted_cap.vecs(), iter.chain(
self.indexes_to_active_cap.vecs(), self.indexes_to_cointime_adj_tx_btc_velocity
self.indexes_to_vaulted_price.vecs(), .iter_any_collectable(),
self.indexes_to_vaulted_price_ratio.vecs(), ),
self.indexes_to_active_price.vecs(), );
self.indexes_to_active_price_ratio.vecs(), iter = Box::new(
self.indexes_to_true_market_mean.vecs(), iter.chain(
self.indexes_to_true_market_mean_ratio.vecs(), self.indexes_to_cointime_adj_tx_usd_velocity
self.indexes_to_cointime_price.vecs(), .iter_any_collectable(),
self.indexes_to_cointime_cap.vecs(), ),
self.indexes_to_cointime_price_ratio.vecs(), );
self.indexes_to_cointime_value_destroyed.vecs(), iter = Box::new(iter.chain(self.indexes_to_coinblocks_created.iter_any_collectable()));
self.indexes_to_cointime_value_created.vecs(), iter = Box::new(iter.chain(self.indexes_to_coinblocks_stored.iter_any_collectable()));
self.indexes_to_cointime_value_stored.vecs(), iter = Box::new(iter.chain(self.indexes_to_liveliness.iter_any_collectable()));
] iter = Box::new(iter.chain(self.indexes_to_vaultedness.iter_any_collectable()));
.into_iter() iter = Box::new(
.flatten() iter.chain(
.collect::<Vec<_>>() 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 std::path::Path;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer; use brk_structs::{StoredF32, StoredI16, StoredU16, Version};
use brk_structs::{StoredI16, StoredU16, Version};
use vecdb::{AnyCollectableVec, AnyVec, Database, Exit}; use vecdb::{AnyCollectableVec, AnyVec, Database, Exit};
use crate::grouped::Source; use crate::grouped::Source;
@@ -24,7 +23,9 @@ pub struct Vecs {
pub constant_2: ComputedVecsFromHeight<StoredU16>, pub constant_2: ComputedVecsFromHeight<StoredU16>,
pub constant_3: ComputedVecsFromHeight<StoredU16>, pub constant_3: ComputedVecsFromHeight<StoredU16>,
pub constant_4: ComputedVecsFromHeight<StoredU16>, pub constant_4: ComputedVecsFromHeight<StoredU16>,
pub constant_38_2: ComputedVecsFromHeight<StoredF32>,
pub constant_50: ComputedVecsFromHeight<StoredU16>, pub constant_50: ComputedVecsFromHeight<StoredU16>,
pub constant_61_8: ComputedVecsFromHeight<StoredF32>,
pub constant_100: ComputedVecsFromHeight<StoredU16>, pub constant_100: ComputedVecsFromHeight<StoredU16>,
pub constant_600: ComputedVecsFromHeight<StoredU16>, pub constant_600: ComputedVecsFromHeight<StoredU16>,
pub constant_minus_1: ComputedVecsFromHeight<StoredI16>, pub constant_minus_1: ComputedVecsFromHeight<StoredI16>,
@@ -78,6 +79,14 @@ impl Vecs {
indexes, indexes,
VecBuilderOptions::default().add_last(), 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( constant_50: ComputedVecsFromHeight::forced_import(
&db, &db,
"constant_50", "constant_50",
@@ -86,6 +95,14 @@ impl Vecs {
indexes, indexes,
VecBuilderOptions::default().add_last(), 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( constant_100: ComputedVecsFromHeight::forced_import(
&db, &db,
"constant_100", "constant_100",
@@ -139,8 +156,7 @@ impl Vecs {
}; };
this.db.retain_regions( this.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -150,19 +166,17 @@ impl Vecs {
pub fn compute( pub fn compute(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, exit)?; self.compute_(indexes, starting_indexes, exit)?;
self.db.flush_then_punch()?; self.db.flush_then_punch()?;
Ok(()) Ok(())
} }
fn compute_( fn compute_(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
@@ -179,22 +193,16 @@ impl Vecs {
] ]
.into_iter() .into_iter()
.try_for_each(|(vec, value)| { .try_for_each(|(vec, value)| {
vec.compute_all( vec.compute_all(indexes, starting_indexes, exit, |vec| {
indexer, vec.compute_to(
indexes, starting_indexes.height,
starting_indexes, indexes.height_to_date.len(),
exit, indexes.height_to_date.version(),
|vec, _, indexes, starting_indexes, exit| { |i| (i, StoredU16::new(value)),
vec.compute_to( exit,
starting_indexes.height, )?;
indexes.height_to_date.len(), Ok(())
indexes.height_to_date.version(), })
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
},
)
})?; })?;
[ [
@@ -205,44 +213,58 @@ impl Vecs {
] ]
.into_iter() .into_iter()
.try_for_each(|(vec, value)| { .try_for_each(|(vec, value)| {
vec.compute_all( vec.compute_all(indexes, starting_indexes, exit, |vec| {
indexer, vec.compute_to(
indexes, starting_indexes.height,
starting_indexes, indexes.height_to_date.len(),
exit, indexes.height_to_date.version(),
|vec, _, indexes, starting_indexes, exit| { |i| (i, StoredI16::new(value)),
vec.compute_to( exit,
starting_indexes.height, )?;
indexes.height_to_date.len(), Ok(())
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(()) 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>> =
self.constant_0.vecs(), Box::new(std::iter::empty());
self.constant_1.vecs(),
self.constant_2.vecs(), iter = Box::new(iter.chain(self.constant_0.iter_any_collectable()));
self.constant_3.vecs(), iter = Box::new(iter.chain(self.constant_1.iter_any_collectable()));
self.constant_4.vecs(), iter = Box::new(iter.chain(self.constant_2.iter_any_collectable()));
self.constant_50.vecs(), iter = Box::new(iter.chain(self.constant_3.iter_any_collectable()));
self.constant_100.vecs(), iter = Box::new(iter.chain(self.constant_4.iter_any_collectable()));
self.constant_600.vecs(), iter = Box::new(iter.chain(self.constant_38_2.iter_any_collectable()));
self.constant_minus_1.vecs(), iter = Box::new(iter.chain(self.constant_50.iter_any_collectable()));
self.constant_minus_2.vecs(), iter = Box::new(iter.chain(self.constant_61_8.iter_any_collectable()));
self.constant_minus_3.vecs(), iter = Box::new(iter.chain(self.constant_100.iter_any_collectable()));
self.constant_minus_4.vecs(), iter = Box::new(iter.chain(self.constant_600.iter_any_collectable()));
] iter = Box::new(iter.chain(self.constant_minus_1.iter_any_collectable()));
.into_iter() iter = Box::new(iter.chain(self.constant_minus_2.iter_any_collectable()));
.flatten() iter = Box::new(iter.chain(self.constant_minus_3.iter_any_collectable()));
.collect::<Vec<_>>() 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.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -140,10 +139,11 @@ impl Vecs {
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
vec![ [
&self.dateindex_to_price_ohlc_in_cents as &dyn AnyCollectableVec, &self.dateindex_to_price_ohlc_in_cents as &dyn AnyCollectableVec,
&self.height_to_price_ohlc_in_cents, &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()
}
}
}
+183 -133
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::{Error, Result}; use brk_error::{Error, Result};
use brk_structs::{CheckedSub, StoredU64, Version}; use brk_structs::{CheckedSub, StoredU64, Version};
use vecdb::{ use vecdb::{
@@ -9,7 +10,7 @@ use crate::utils::get_percentile;
use super::ComputedType; use super::ComputedType;
#[derive(Clone, Debug)] #[derive(Clone, Debug, Allocative)]
pub struct EagerVecBuilder<I, T> pub struct EagerVecBuilder<I, T>
where where
I: StoredIndex, I: StoredIndex,
@@ -19,11 +20,11 @@ where
pub average: Option<Box<EagerVec<I, T>>>, pub average: Option<Box<EagerVec<I, T>>>,
pub sum: Option<Box<EagerVec<I, T>>>, pub sum: Option<Box<EagerVec<I, T>>>,
pub max: Option<Box<EagerVec<I, T>>>, pub max: Option<Box<EagerVec<I, T>>>,
pub p90: Option<Box<EagerVec<I, T>>>, pub pct90: Option<Box<EagerVec<I, T>>>,
pub p75: Option<Box<EagerVec<I, T>>>, pub pct75: Option<Box<EagerVec<I, T>>>,
pub median: Option<Box<EagerVec<I, T>>>, pub median: Option<Box<EagerVec<I, T>>>,
pub p25: Option<Box<EagerVec<I, T>>>, pub pct25: Option<Box<EagerVec<I, T>>>,
pub p10: Option<Box<EagerVec<I, T>>>, pub pct10: Option<Box<EagerVec<I, T>>>,
pub min: Option<Box<EagerVec<I, T>>>, pub min: Option<Box<EagerVec<I, T>>>,
pub last: Option<Box<EagerVec<I, T>>>, pub last: Option<Box<EagerVec<I, T>>>,
pub cumulative: Option<Box<EagerVec<I, T>>>, pub cumulative: Option<Box<EagerVec<I, T>>>,
@@ -151,44 +152,44 @@ where
.unwrap(), .unwrap(),
) )
}), }),
p90: options.p90.then(|| { pct90: options.pct90.then(|| {
Box::new( Box::new(
EagerVec::forced_import( EagerVec::forced_import(
db, db,
&maybe_suffix("p90"), &maybe_suffix("pct90"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
) )
.unwrap(), .unwrap(),
) )
}), }),
p75: options.p75.then(|| { pct75: options.pct75.then(|| {
Box::new( Box::new(
EagerVec::forced_import( EagerVec::forced_import(
db, db,
&maybe_suffix("p75"), &maybe_suffix("pct75"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
) )
.unwrap(), .unwrap(),
) )
}), }),
p25: options.p25.then(|| { pct25: options.pct25.then(|| {
Box::new( Box::new(
EagerVec::forced_import( EagerVec::forced_import(
db, db,
&maybe_suffix("p25"), &maybe_suffix("pct25"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
) )
.unwrap(), .unwrap(),
) )
}), }),
p10: options.p10.then(|| { pct10: options.pct10.then(|| {
Box::new( Box::new(
EagerVec::forced_import( EagerVec::forced_import(
db, db,
&maybe_suffix("p10"), &maybe_suffix("pct10"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
) )
@@ -292,11 +293,11 @@ where
let needs_average_sum_or_cumulative = let needs_average_sum_or_cumulative =
needs_sum_or_cumulative || self.average.is_some(); needs_sum_or_cumulative || self.average.is_some();
let needs_sorted = self.max.is_some() let needs_sorted = self.max.is_some()
|| self.p90.is_some() || self.pct90.is_some()
|| self.p75.is_some() || self.pct75.is_some()
|| self.median.is_some() || self.median.is_some()
|| self.p25.is_some() || self.pct25.is_some()
|| self.p10.is_some() || self.pct10.is_some()
|| self.min.is_some(); || self.min.is_some();
let needs_values = needs_sorted || needs_average_sum_or_cumulative; let needs_values = needs_sorted || needs_average_sum_or_cumulative;
@@ -333,24 +334,24 @@ where
)?; )?;
} }
if let Some(p90) = self.p90.as_mut() { if let Some(pct90) = self.pct90.as_mut() {
p90.forced_push_at(index, get_percentile(&values, 0.90), exit)?; pct90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
} }
if let Some(p75) = self.p75.as_mut() { if let Some(pct75) = self.pct75.as_mut() {
p75.forced_push_at(index, get_percentile(&values, 0.75), exit)?; pct75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
} }
if let Some(median) = self.median.as_mut() { if let Some(median) = self.median.as_mut() {
median.forced_push_at(index, get_percentile(&values, 0.50), exit)?; median.forced_push_at(index, get_percentile(&values, 0.50), exit)?;
} }
if let Some(p25) = self.p25.as_mut() { if let Some(pct25) = self.pct25.as_mut() {
p25.forced_push_at(index, get_percentile(&values, 0.25), exit)?; pct25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
} }
if let Some(p10) = self.p10.as_mut() { if let Some(pct10) = self.pct10.as_mut() {
p10.forced_push_at(index, get_percentile(&values, 0.10), exit)?; pct10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
} }
if let Some(min) = self.min.as_mut() { if let Some(min) = self.min.as_mut() {
@@ -401,11 +402,11 @@ where
where where
I2: StoredIndex + StoredRaw + CheckedSub<I2>, I2: StoredIndex + StoredRaw + CheckedSub<I2>,
{ {
if self.p90.is_some() if self.pct90.is_some()
|| self.p75.is_some() || self.pct75.is_some()
|| self.median.is_some() || self.median.is_some()
|| self.p25.is_some() || self.pct25.is_some()
|| self.p10.is_some() || self.pct10.is_some()
{ {
panic!("unsupported"); panic!("unsupported");
} }
@@ -540,7 +541,7 @@ where
pub fn starting_index(&self, max_from: I) -> I { pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from( 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(),
)) ))
} }
@@ -558,24 +559,24 @@ where
self.max.as_ref().unwrap() self.max.as_ref().unwrap()
} }
#[allow(unused)] #[allow(unused)]
pub fn unwrap_p90(&self) -> &EagerVec<I, T> { pub fn unwrap_pct90(&self) -> &EagerVec<I, T> {
self.p90.as_ref().unwrap() self.pct90.as_ref().unwrap()
} }
#[allow(unused)] #[allow(unused)]
pub fn unwrap_p75(&self) -> &EagerVec<I, T> { pub fn unwrap_pct75(&self) -> &EagerVec<I, T> {
self.p75.as_ref().unwrap() self.pct75.as_ref().unwrap()
} }
#[allow(unused)] #[allow(unused)]
pub fn unwrap_median(&self) -> &EagerVec<I, T> { pub fn unwrap_median(&self) -> &EagerVec<I, T> {
self.median.as_ref().unwrap() self.median.as_ref().unwrap()
} }
#[allow(unused)] #[allow(unused)]
pub fn unwrap_p25(&self) -> &EagerVec<I, T> { pub fn unwrap_pct25(&self) -> &EagerVec<I, T> {
self.p25.as_ref().unwrap() self.pct25.as_ref().unwrap()
} }
#[allow(unused)] #[allow(unused)]
pub fn unwrap_p10(&self) -> &EagerVec<I, T> { pub fn unwrap_pct10(&self) -> &EagerVec<I, T> {
self.p10.as_ref().unwrap() self.pct10.as_ref().unwrap()
} }
pub fn unwrap_min(&self) -> &EagerVec<I, T> { pub fn unwrap_min(&self) -> &EagerVec<I, T> {
self.min.as_ref().unwrap() self.min.as_ref().unwrap()
@@ -588,47 +589,96 @@ where
self.cumulative.as_ref().unwrap() self.cumulative.as_ref().unwrap()
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![]; let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() { iter = Box::new(
v.push(first.as_ref()); iter.chain(
} self.first
if let Some(last) = self.last.as_ref() { .as_ref()
v.push(last.as_ref()); .map(|x| x.as_ref() as &dyn AnyCollectableVec),
} ),
if let Some(min) = self.min.as_ref() { );
v.push(min.as_ref()); iter = Box::new(
} iter.chain(
if let Some(max) = self.max.as_ref() { self.last
v.push(max.as_ref()); .as_ref()
} .map(|x| x.as_ref() as &dyn AnyCollectableVec),
if let Some(median) = self.median.as_ref() { ),
v.push(median.as_ref()); );
} iter = Box::new(
if let Some(average) = self.average.as_ref() { iter.chain(
v.push(average.as_ref()); self.min
} .as_ref()
if let Some(sum) = self.sum.as_ref() { .map(|x| x.as_ref() as &dyn AnyCollectableVec),
v.push(sum.as_ref()); ),
} );
if let Some(cumulative) = self.cumulative.as_ref() { iter = Box::new(
v.push(cumulative.as_ref()); iter.chain(
} self.max
if let Some(p90) = self.p90.as_ref() { .as_ref()
v.push(p90.as_ref()); .map(|x| x.as_ref() as &dyn AnyCollectableVec),
} ),
if let Some(p75) = self.p75.as_ref() { );
v.push(p75.as_ref()); iter = Box::new(
} iter.chain(
if let Some(p25) = self.p25.as_ref() { self.median
v.push(p25.as_ref()); .as_ref()
} .map(|x| x.as_ref() as &dyn AnyCollectableVec),
if let Some(p10) = self.p10.as_ref() { ),
v.push(p10.as_ref()); );
} 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<()> { pub fn safe_flush(&mut self, exit: &Exit) -> Result<()> {
@@ -656,17 +706,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() { if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.safe_flush(exit)?; cumulative.safe_flush(exit)?;
} }
if let Some(p90) = self.p90.as_mut() { if let Some(pct90) = self.pct90.as_mut() {
p90.safe_flush(exit)?; pct90.safe_flush(exit)?;
} }
if let Some(p75) = self.p75.as_mut() { if let Some(pct75) = self.pct75.as_mut() {
p75.safe_flush(exit)?; pct75.safe_flush(exit)?;
} }
if let Some(p25) = self.p25.as_mut() { if let Some(pct25) = self.pct25.as_mut() {
p25.safe_flush(exit)?; pct25.safe_flush(exit)?;
} }
if let Some(p10) = self.p10.as_mut() { if let Some(pct10) = self.pct10.as_mut() {
p10.safe_flush(exit)?; pct10.safe_flush(exit)?;
} }
Ok(()) Ok(())
@@ -697,17 +747,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() { if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.validate_computed_version_or_reset(Version::ZERO + version)?; cumulative.validate_computed_version_or_reset(Version::ZERO + version)?;
} }
if let Some(p90) = self.p90.as_mut() { if let Some(pct90) = self.pct90.as_mut() {
p90.validate_computed_version_or_reset(Version::ZERO + version)?; pct90.validate_computed_version_or_reset(Version::ZERO + version)?;
} }
if let Some(p75) = self.p75.as_mut() { if let Some(pct75) = self.pct75.as_mut() {
p75.validate_computed_version_or_reset(Version::ZERO + version)?; pct75.validate_computed_version_or_reset(Version::ZERO + version)?;
} }
if let Some(p25) = self.p25.as_mut() { if let Some(pct25) = self.pct25.as_mut() {
p25.validate_computed_version_or_reset(Version::ZERO + version)?; pct25.validate_computed_version_or_reset(Version::ZERO + version)?;
} }
if let Some(p10) = self.p10.as_mut() { if let Some(pct10) = self.pct10.as_mut() {
p10.validate_computed_version_or_reset(Version::ZERO + version)?; pct10.validate_computed_version_or_reset(Version::ZERO + version)?;
} }
Ok(()) Ok(())
@@ -719,11 +769,11 @@ pub struct VecBuilderOptions {
average: bool, average: bool,
sum: bool, sum: bool,
max: bool, max: bool,
p90: bool, pct90: bool,
p75: bool, pct75: bool,
median: bool, median: bool,
p25: bool, pct25: bool,
p10: bool, pct10: bool,
min: bool, min: bool,
first: bool, first: bool,
last: bool, last: bool,
@@ -743,24 +793,24 @@ impl VecBuilderOptions {
self.max self.max
} }
pub fn p90(&self) -> bool { pub fn pct90(&self) -> bool {
self.p90 self.pct90
} }
pub fn p75(&self) -> bool { pub fn pct75(&self) -> bool {
self.p75 self.pct75
} }
pub fn median(&self) -> bool { pub fn median(&self) -> bool {
self.median self.median
} }
pub fn p25(&self) -> bool { pub fn pct25(&self) -> bool {
self.p25 self.pct25
} }
pub fn p10(&self) -> bool { pub fn pct10(&self) -> bool {
self.p10 self.pct10
} }
pub fn min(&self) -> bool { pub fn min(&self) -> bool {
@@ -816,26 +866,26 @@ impl VecBuilderOptions {
} }
#[allow(unused)] #[allow(unused)]
pub fn add_p90(mut self) -> Self { pub fn add_pct90(mut self) -> Self {
self.p90 = true; self.pct90 = true;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn add_p75(mut self) -> Self { pub fn add_pct75(mut self) -> Self {
self.p75 = true; self.pct75 = true;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn add_p25(mut self) -> Self { pub fn add_pct25(mut self) -> Self {
self.p25 = true; self.pct25 = true;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn add_p10(mut self) -> Self { pub fn add_pct10(mut self) -> Self {
self.p10 = true; self.pct10 = true;
self self
} }
@@ -875,26 +925,26 @@ impl VecBuilderOptions {
} }
#[allow(unused)] #[allow(unused)]
pub fn rm_p90(mut self) -> Self { pub fn rm_pct90(mut self) -> Self {
self.p90 = false; self.pct90 = false;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn rm_p75(mut self) -> Self { pub fn rm_pct75(mut self) -> Self {
self.p75 = false; self.pct75 = false;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn rm_p25(mut self) -> Self { pub fn rm_pct25(mut self) -> Self {
self.p25 = false; self.pct25 = false;
self self
} }
#[allow(unused)] #[allow(unused)]
pub fn rm_p10(mut self) -> Self { pub fn rm_pct10(mut self) -> Self {
self.p10 = false; self.pct10 = false;
self self
} }
@@ -911,20 +961,20 @@ impl VecBuilderOptions {
} }
pub fn add_percentiles(mut self) -> Self { pub fn add_percentiles(mut self) -> Self {
self.p90 = true; self.pct90 = true;
self.p75 = true; self.pct75 = true;
self.median = true; self.median = true;
self.p25 = true; self.pct25 = true;
self.p10 = true; self.pct10 = true;
self self
} }
pub fn remove_percentiles(mut self) -> Self { pub fn remove_percentiles(mut self) -> Self {
self.p90 = false; self.pct90 = false;
self.p75 = false; self.pct75 = false;
self.median = false; self.median = false;
self.p25 = false; self.pct25 = false;
self.p10 = false; self.pct10 = false;
self self
} }
@@ -933,11 +983,11 @@ impl VecBuilderOptions {
self.average, self.average,
self.sum, self.sum,
self.max, self.max,
self.p90, self.pct90,
self.p75, self.pct75,
self.median, self.median,
self.p25, self.pct25,
self.p10, self.pct10,
self.min, self.min,
self.first, self.first,
self.last, self.last,
+56 -26
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_structs::Version; use brk_structs::Version;
use vecdb::{ use vecdb::{
AnyBoxedIterableVec, AnyCloneableIterableVec, AnyCollectableVec, FromCoarserIndex, AnyBoxedIterableVec, AnyCloneableIterableVec, AnyCollectableVec, FromCoarserIndex,
@@ -9,7 +10,7 @@ use crate::grouped::{EagerVecBuilder, VecBuilderOptions};
use super::ComputedType; use super::ComputedType;
#[allow(clippy::type_complexity)] #[allow(clippy::type_complexity)]
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct LazyVecBuilder<I, T, S1I, S2T> pub struct LazyVecBuilder<I, T, S1I, S2T>
where where
I: StoredIndex, I: StoredIndex,
@@ -216,7 +217,7 @@ where
pub fn starting_index(&self, max_from: I) -> I { pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from( 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(),
)) ))
} }
@@ -244,32 +245,61 @@ where
self.cumulative.as_ref().unwrap() self.cumulative.as_ref().unwrap()
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![]; let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() { iter = Box::new(
v.push(first.as_ref()); iter.chain(
} self.first
if let Some(last) = self.last.as_ref() { .as_ref()
v.push(last.as_ref()); .map(|x| x.as_ref() as &dyn AnyCollectableVec),
} ),
if let Some(min) = self.min.as_ref() { );
v.push(min.as_ref()); iter = Box::new(
} iter.chain(
if let Some(max) = self.max.as_ref() { self.last
v.push(max.as_ref()); .as_ref()
} .map(|x| x.as_ref() as &dyn AnyCollectableVec),
if let Some(average) = self.average.as_ref() { ),
v.push(average.as_ref()); );
} iter = Box::new(
if let Some(sum) = self.sum.as_ref() { iter.chain(
v.push(sum.as_ref()); self.min
} .as_ref()
if let Some(cumulative) = self.cumulative.as_ref() { .map(|x| x.as_ref() as &dyn AnyCollectableVec),
v.push(cumulative.as_ref()); ),
} );
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,6 +1,6 @@
use allocative::Allocative;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex, DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex,
}; };
@@ -10,7 +10,7 @@ use crate::{Indexes, grouped::LazyVecBuilder, indexes};
use super::{ComputedType, EagerVecBuilder, Source, VecBuilderOptions}; use super::{ComputedType, EagerVecBuilder, Source, VecBuilderOptions};
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct ComputedVecsFromDateIndex<T> pub struct ComputedVecsFromDateIndex<T>
where where
T: ComputedType + PartialOrd, T: ComputedType + PartialOrd,
@@ -111,28 +111,14 @@ where
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut( F: FnMut(&mut EagerVec<DateIndex, T>) -> Result<()>,
&mut EagerVec<DateIndex, T>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
{ {
compute( compute(self.dateindex.as_mut().unwrap())?;
self.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
let dateindex: Option<&EagerVec<DateIndex, T>> = None; let dateindex: Option<&EagerVec<DateIndex, T>> = None;
self.compute_rest(starting_indexes, exit, dateindex) self.compute_rest(starting_indexes, exit, dateindex)
@@ -157,21 +143,22 @@ where
Ok(()) 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 self.dateindex
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]), .map(|x| x as &dyn AnyCollectableVec)
self.dateindex_extra.vecs(), .into_iter(),
self.weekindex.vecs(), );
self.monthindex.vecs(),
self.quarterindex.vecs(), iter = Box::new(iter.chain(self.dateindex_extra.iter_any_collectable()));
self.semesterindex.vecs(), iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
self.yearindex.vecs(), iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
self.decadeindex.vecs(), iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
] iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
.into_iter() iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
.flatten() iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
.collect::<Vec<_>>()
iter
} }
} }
+21 -28
View File
@@ -1,6 +1,6 @@
use allocative::Allocative;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex, DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
Version, WeekIndex, YearIndex, Version, WeekIndex, YearIndex,
@@ -15,7 +15,7 @@ use crate::{
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions}; use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct ComputedVecsFromHeight<T> pub struct ComputedVecsFromHeight<T>
where where
T: ComputedType + PartialOrd, T: ComputedType + PartialOrd,
@@ -133,22 +133,15 @@ where
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut(&mut EagerVec<Height, T>, &Indexer, &indexes::Vecs, &Indexes, &Exit) -> Result<()>, F: FnMut(&mut EagerVec<Height, T>) -> Result<()>,
{ {
compute( compute(self.height.as_mut().unwrap())?;
self.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
let height: Option<&EagerVec<Height, T>> = None; let height: Option<&EagerVec<Height, T>> = None;
self.compute_rest(indexes, starting_indexes, exit, height) self.compute_rest(indexes, starting_indexes, exit, height)
@@ -206,24 +199,24 @@ where
Ok(()) 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 self.height
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]), .map(|x| x as &dyn AnyCollectableVec)
self.height_extra.vecs(), .into_iter(),
self.dateindex.vecs(), );
self.weekindex.vecs(),
self.difficultyepoch.vecs(), iter = Box::new(iter.chain(self.height_extra.iter_any_collectable()));
self.monthindex.vecs(), iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
self.quarterindex.vecs(), iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
self.semesterindex.vecs(), iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
self.yearindex.vecs(), iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
// self.halvingepoch.vecs(), iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
self.decadeindex.vecs(), iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
] iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
.into_iter() iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
.flatten()
.collect::<Vec<_>>() iter
} }
} }
@@ -1,6 +1,5 @@
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{DifficultyEpoch, Height, Version}; use brk_structs::{DifficultyEpoch, Height, Version};
use vecdb::{AnyCollectableVec, Database, EagerVec, Exit}; use vecdb::{AnyCollectableVec, Database, EagerVec, Exit};
@@ -59,16 +58,15 @@ where
pub fn compute<F>( pub fn compute<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where 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 self.height_extra
.extend(starting_indexes.height, &self.height, exit)?; .extend(starting_indexes.height, &self.height, exit)?;
@@ -84,15 +82,10 @@ where
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[ [&self.height as &dyn AnyCollectableVec]
vec![&self.height as &dyn AnyCollectableVec], .into_iter()
self.height_extra.vecs(), .chain(self.height_extra.iter_any_collectable())
self.difficultyepoch.vecs(), .chain(self.difficultyepoch.iter_any_collectable())
// self.halvingepoch.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
} }
} }
+43 -42
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
@@ -17,7 +18,7 @@ use crate::{
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions}; use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct ComputedVecsFromTxindex<T> pub struct ComputedVecsFromTxindex<T>
where where
T: ComputedType + PartialOrd, T: ComputedType + PartialOrd,
@@ -225,25 +226,25 @@ where
Ok(()) 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 self.txindex
.as_ref() .as_ref()
.map_or(vec![], |v| vec![v.as_ref() as &dyn AnyCollectableVec]), .map(|x| x.as_ref() as &dyn AnyCollectableVec)
self.height.vecs(), .into_iter(),
self.dateindex.vecs(), );
self.weekindex.vecs(),
self.difficultyepoch.vecs(), iter = Box::new(iter.chain(self.height.iter_any_collectable()));
self.monthindex.vecs(), iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
self.quarterindex.vecs(), iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
self.semesterindex.vecs(), iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
self.yearindex.vecs(), iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
// self.halvingepoch.vecs(), iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
self.decadeindex.vecs(), iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
] iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
.into_iter() iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
.flatten()
.collect::<Vec<_>>() iter
} }
} }
@@ -319,24 +320,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit, exit,
)?; )?;
} }
if let Some(_90p) = self.height.p90.as_mut() { if let Some(pct90) = self.height.pct90.as_mut() {
_90p.forced_push_at( pct90.forced_push_at(
height, height,
Bitcoin::from( Bitcoin::from(
sats.height sats.height
.unwrap_p90() .unwrap_pct90()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
), ),
exit, exit,
)?; )?;
} }
if let Some(_75p) = self.height.p75.as_mut() { if let Some(pct75) = self.height.pct75.as_mut() {
_75p.forced_push_at( pct75.forced_push_at(
height, height,
Bitcoin::from( Bitcoin::from(
sats.height sats.height
.unwrap_p75() .unwrap_pct75()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
), ),
@@ -355,24 +356,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit, exit,
)?; )?;
} }
if let Some(_25p) = self.height.p25.as_mut() { if let Some(pct25) = self.height.pct25.as_mut() {
_25p.forced_push_at( pct25.forced_push_at(
height, height,
Bitcoin::from( Bitcoin::from(
sats.height sats.height
.unwrap_p25() .unwrap_pct25()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
), ),
exit, exit,
)?; )?;
} }
if let Some(_10p) = self.height.p10.as_mut() { if let Some(pct10) = self.height.pct10.as_mut() {
_10p.forced_push_at( pct10.forced_push_at(
height, height,
Bitcoin::from( Bitcoin::from(
sats.height sats.height
.unwrap_p10() .unwrap_pct10()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
), ),
@@ -502,25 +503,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit, exit,
)?; )?;
} }
if let Some(_90p) = self.height.p90.as_mut() { if let Some(pct90) = self.height.pct90.as_mut() {
_90p.forced_push_at( pct90.forced_push_at(
height, height,
price price
* bitcoin * bitcoin
.height .height
.unwrap_p90() .unwrap_pct90()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
exit, exit,
)?; )?;
} }
if let Some(_75p) = self.height.p75.as_mut() { if let Some(pct75) = self.height.pct75.as_mut() {
_75p.forced_push_at( pct75.forced_push_at(
height, height,
price price
* bitcoin * bitcoin
.height .height
.unwrap_p75() .unwrap_pct75()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
exit, exit,
@@ -538,25 +539,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit, exit,
)?; )?;
} }
if let Some(_25p) = self.height.p25.as_mut() { if let Some(pct25) = self.height.pct25.as_mut() {
_25p.forced_push_at( pct25.forced_push_at(
height, height,
price price
* bitcoin * bitcoin
.height .height
.unwrap_p25() .unwrap_pct25()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
exit, exit,
)?; )?;
} }
if let Some(_10p) = self.height.p10.as_mut() { if let Some(pct10) = self.height.pct10.as_mut() {
_10p.forced_push_at( pct10.forced_push_at(
height, height,
price price
* bitcoin * bitcoin
.height .height
.unwrap_p10() .unwrap_pct10()
.into_iter() .into_iter()
.unwrap_get_inner(height), .unwrap_get_inner(height),
exit, exit,
@@ -1,5 +1,4 @@
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Date, DateIndex, Dollars, StoredF32, Version}; use brk_structs::{Date, DateIndex, Dollars, StoredF32, Version};
use vecdb::{ use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec, AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec,
@@ -8,7 +7,9 @@ use vecdb::{
use crate::{ use crate::{
Indexes, Indexes,
grouped::{ComputedStandardDeviationVecsFromDateIndex, source::Source}, grouped::{
ComputedStandardDeviationVecsFromDateIndex, StandardDeviationVecsOptions, source::Source,
},
indexes, price, indexes, price,
utils::get_percentile, utils::get_percentile,
}; };
@@ -28,12 +29,12 @@ pub struct ComputedRatioVecsFromDateIndex {
pub ratio_pct5: Option<ComputedVecsFromDateIndex<StoredF32>>, pub ratio_pct5: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct2: Option<ComputedVecsFromDateIndex<StoredF32>>, pub ratio_pct2: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct1: Option<ComputedVecsFromDateIndex<StoredF32>>, pub ratio_pct1: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct99_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct99_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct98_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct98_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct95_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct95_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct5_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct5_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct2_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct2_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct1_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>, pub ratio_pct1_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_sd: Option<ComputedStandardDeviationVecsFromDateIndex>, pub ratio_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
pub ratio_4y_sd: Option<ComputedStandardDeviationVecsFromDateIndex>, pub ratio_4y_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
@@ -105,6 +106,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
StandardDeviationVecsOptions::default().add_all(),
) )
.unwrap() .unwrap()
}), }),
@@ -116,6 +118,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
StandardDeviationVecsOptions::default().add_all(),
) )
.unwrap() .unwrap()
}), }),
@@ -127,6 +130,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
StandardDeviationVecsOptions::default().add_all(),
) )
.unwrap() .unwrap()
}), }),
@@ -138,6 +142,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
StandardDeviationVecsOptions::default().add_all(),
) )
.unwrap() .unwrap()
}), }),
@@ -207,10 +212,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct99_in_usd: extended.then(|| { ratio_pct99_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct99_in_usd"), &format!("{name}_ratio_pct99_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -218,10 +223,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct98_in_usd: extended.then(|| { ratio_pct98_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct98_in_usd"), &format!("{name}_ratio_pct98_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -229,10 +234,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct95_in_usd: extended.then(|| { ratio_pct95_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct95_in_usd"), &format!("{name}_ratio_pct95_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -240,10 +245,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct5_in_usd: extended.then(|| { ratio_pct5_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct5_in_usd"), &format!("{name}_ratio_pct5_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -251,10 +256,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct2_in_usd: extended.then(|| { ratio_pct2_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct2_in_usd"), &format!("{name}_ratio_pct2_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -262,10 +267,10 @@ impl ComputedRatioVecsFromDateIndex {
) )
.unwrap() .unwrap()
}), }),
ratio_pct1_in_usd: extended.then(|| { ratio_pct1_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_ratio_pct1_in_usd"), &format!("{name}_ratio_pct1_usd"),
Source::Compute, Source::Compute,
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
indexes, indexes,
@@ -278,45 +283,25 @@ impl ComputedRatioVecsFromDateIndex {
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs, price: &price::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
compute: F, compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut( F: FnMut(&mut EagerVec<DateIndex, Dollars>) -> Result<()>,
&mut EagerVec<DateIndex, Dollars>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
{ {
self.price.as_mut().unwrap().compute_all( self.price
indexer, .as_mut()
indexes, .unwrap()
starting_indexes, .compute_all(starting_indexes, exit, compute)?;
exit,
compute,
)?;
let date_to_price_opt: Option<&EagerVec<DateIndex, Dollars>> = None; let date_to_price_opt: Option<&EagerVec<DateIndex, Dollars>> = None;
self.compute_rest( self.compute_rest(price, starting_indexes, exit, date_to_price_opt)
indexer,
indexes,
price,
starting_indexes,
exit,
date_to_price_opt,
)
} }
pub fn compute_rest( pub fn compute_rest(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs, price: &price::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
@@ -328,28 +313,22 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex) std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
}); });
self.ratio.compute_all( self.ratio.compute_all(starting_indexes, exit, |v| {
indexer, v.compute_transform2(
indexes, starting_indexes.dateindex,
starting_indexes, closes,
exit, price,
|v, _, _, starting_indexes, exit| { |(i, close, price, ..)| {
v.compute_transform2( if price == Dollars::ZERO {
starting_indexes.dateindex, (i, StoredF32::from(1.0))
closes, } else {
price, (i, StoredF32::from(*close / price))
|(i, close, price, ..)| { }
if price == Dollars::ZERO { },
(i, StoredF32::from(1.0)) exit,
} else { )?;
(i, StoredF32::from(*close / price)) Ok(())
} })?;
},
exit,
)?;
Ok(())
},
)?;
if self.ratio_1w_sma.is_none() { if self.ratio_1w_sma.is_none() {
return Ok(()); return Ok(());
@@ -357,12 +336,10 @@ impl ComputedRatioVecsFromDateIndex {
let min_ratio_date = DateIndex::try_from(Date::MIN_RATIO).unwrap(); let min_ratio_date = DateIndex::try_from(Date::MIN_RATIO).unwrap();
self.ratio_1w_sma.as_mut().unwrap().compute_all( self.ratio_1w_sma
indexer, .as_mut()
indexes, .unwrap()
starting_indexes, .compute_all(starting_indexes, exit, |v| {
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma_( v.compute_sma_(
starting_indexes.dateindex, starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
@@ -371,15 +348,12 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date), Some(min_ratio_date),
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.ratio_1m_sma.as_mut().unwrap().compute_all( self.ratio_1m_sma
indexer, .as_mut()
indexes, .unwrap()
starting_indexes, .compute_all(starting_indexes, exit, |v| {
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sma_( v.compute_sma_(
starting_indexes.dateindex, starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
@@ -388,8 +362,7 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date), Some(min_ratio_date),
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let ratio_version = self.ratio.dateindex.as_ref().unwrap().version(); let ratio_version = self.ratio.dateindex.as_ref().unwrap().version();
self.mut_ratio_vecs() self.mut_ratio_vecs()
@@ -556,12 +529,10 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex) std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
}); });
self.ratio_pct99_in_usd.as_mut().unwrap().compute_all( self.ratio_pct99_usd
indexer, .as_mut()
indexes, .unwrap()
starting_indexes, .compute_all(starting_indexes, exit, |vec| {
exit,
|vec, _, _, starting_indexes, exit| {
let mut iter = self let mut iter = self
.ratio_pct99 .ratio_pct99
.as_ref() .as_ref()
@@ -580,67 +551,52 @@ impl ComputedRatioVecsFromDateIndex {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let compute_in_usd = let compute_usd =
|in_usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>, |usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>,
source: Option<&ComputedVecsFromDateIndex<StoredF32>>| { source: Option<&ComputedVecsFromDateIndex<StoredF32>>| {
in_usd.unwrap().compute_all( usd.unwrap().compute_all(starting_indexes, exit, |vec| {
indexer, let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter();
indexes, vec.compute_transform(
starting_indexes, starting_indexes.dateindex,
exit, date_to_price,
|vec, _, _, starting_indexes, exit| { |(i, price, ..)| {
let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter(); let multiplier = iter.unwrap_get_inner(i);
vec.compute_transform( (i, price * multiplier)
starting_indexes.dateindex, },
date_to_price, exit,
|(i, price, ..)| { )?;
let multiplier = iter.unwrap_get_inner(i); Ok(())
(i, price * multiplier) })
},
exit,
)?;
Ok(())
},
)
}; };
compute_in_usd(self.ratio_pct1_in_usd.as_mut(), self.ratio_pct1.as_ref())?; compute_usd(self.ratio_pct1_usd.as_mut(), self.ratio_pct1.as_ref())?;
compute_in_usd(self.ratio_pct2_in_usd.as_mut(), self.ratio_pct2.as_ref())?; compute_usd(self.ratio_pct2_usd.as_mut(), self.ratio_pct2.as_ref())?;
compute_in_usd(self.ratio_pct5_in_usd.as_mut(), self.ratio_pct5.as_ref())?; compute_usd(self.ratio_pct5_usd.as_mut(), self.ratio_pct5.as_ref())?;
compute_in_usd(self.ratio_pct95_in_usd.as_mut(), self.ratio_pct95.as_ref())?; compute_usd(self.ratio_pct95_usd.as_mut(), self.ratio_pct95.as_ref())?;
compute_in_usd(self.ratio_pct98_in_usd.as_mut(), self.ratio_pct98.as_ref())?; compute_usd(self.ratio_pct98_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_pct99_usd.as_mut(), self.ratio_pct99.as_ref())?;
self.ratio_sd.as_mut().unwrap().compute_all( self.ratio_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes, starting_indexes,
exit, exit,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price), Some(date_to_price),
)?; )?;
self.ratio_4y_sd.as_mut().unwrap().compute_all( self.ratio_4y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes, starting_indexes,
exit, exit,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price), Some(date_to_price),
)?; )?;
self.ratio_2y_sd.as_mut().unwrap().compute_all( self.ratio_2y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes, starting_indexes,
exit, exit,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price), Some(date_to_price),
)?; )?;
self.ratio_1y_sd.as_mut().unwrap().compute_all( self.ratio_1y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes, starting_indexes,
exit, exit,
self.ratio.dateindex.as_ref().unwrap(), self.ratio.dateindex.as_ref().unwrap(),
@@ -676,37 +632,132 @@ impl ComputedRatioVecsFromDateIndex {
.collect::<Vec<_>>() .collect::<Vec<_>>()
} }
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>> =
self.price.as_ref().map_or(vec![], |v| v.vecs()), Box::new(self.price.iter().flat_map(|v| v.iter_any_collectable()));
self.ratio.vecs(),
self.ratio_1w_sma.as_ref().map_or(vec![], |v| v.vecs()), iter = Box::new(iter.chain(self.ratio.iter_any_collectable()));
self.ratio_1m_sma.as_ref().map_or(vec![], |v| v.vecs()), iter = Box::new(
self.ratio_sd.as_ref().map_or(vec![], |v| v.vecs()), iter.chain(
self.ratio_1y_sd.as_ref().map_or(vec![], |v| v.vecs()), self.ratio_1w_sma
self.ratio_2y_sd.as_ref().map_or(vec![], |v| v.vecs()), .iter()
self.ratio_4y_sd.as_ref().map_or(vec![], |v| v.vecs()), .flat_map(|v| v.iter_any_collectable()),
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()), iter = Box::new(
self.ratio_pct95.as_ref().map_or(vec![], |v| v.vecs()), iter.chain(
self.ratio_pct98.as_ref().map_or(vec![], |v| v.vecs()), self.ratio_1m_sma
self.ratio_pct99.as_ref().map_or(vec![], |v| v.vecs()), .iter()
self.ratio_pct1_in_usd.as_ref().map_or(vec![], |v| v.vecs()), .flat_map(|v| v.iter_any_collectable()),
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 iter = Box::new(iter.chain(self.ratio_sd.iter().flat_map(|v| v.iter_any_collectable())));
.as_ref() iter = Box::new(
.map_or(vec![], |v| v.vecs()), iter.chain(
self.ratio_pct98_in_usd self.ratio_1y_sd
.as_ref() .iter()
.map_or(vec![], |v| v.vecs()), .flat_map(|v| v.iter_any_collectable()),
self.ratio_pct99_in_usd ),
.as_ref() );
.map_or(vec![], |v| v.vecs()), iter = Box::new(
] iter.chain(
.into_iter() self.ratio_2y_sd
.flatten() .iter()
.collect::<Vec<_>>() .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_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Sats, Version}; use brk_structs::{Bitcoin, DateIndex, Dollars, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec}; use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -43,7 +42,7 @@ impl ComputedValueVecsFromDateIndex {
)?, )?,
bitcoin: ComputedVecsFromDateIndex::forced_import( bitcoin: ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_in_btc"), &format!("{name}_btc"),
Source::Compute, Source::Compute,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -52,7 +51,7 @@ impl ComputedValueVecsFromDateIndex {
dollars: compute_dollars.then(|| { dollars: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import( ComputedVecsFromDateIndex::forced_import(
db, db,
&format!("{name}_in_usd"), &format!("{name}_usd"),
Source::Compute, Source::Compute,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -65,40 +64,24 @@ impl ComputedValueVecsFromDateIndex {
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut( F: FnMut(&mut EagerVec<DateIndex, Sats>) -> Result<()>,
&mut EagerVec<DateIndex, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
{ {
compute( compute(self.sats.dateindex.as_mut().unwrap())?;
self.sats.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None; 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(()) Ok(())
} }
pub fn compute_rest( pub fn compute_rest(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
@@ -108,33 +91,21 @@ impl ComputedValueVecsFromDateIndex {
self.sats self.sats
.compute_rest(starting_indexes, exit, Some(dateindex))?; .compute_rest(starting_indexes, exit, Some(dateindex))?;
self.bitcoin.compute_all( self.bitcoin.compute_all(starting_indexes, exit, |v| {
indexer, v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
indexes, })?;
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
},
)?;
} else { } else {
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None; let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
self.sats.compute_rest(starting_indexes, exit, dateindex)?; self.sats.compute_rest(starting_indexes, exit, dateindex)?;
self.bitcoin.compute_all( self.bitcoin.compute_all(starting_indexes, exit, |v| {
indexer, v.compute_from_sats(
indexes, starting_indexes.dateindex,
starting_indexes, self.sats.dateindex.as_ref().unwrap(),
exit, exit,
|v, _, _, starting_indexes, exit| { )
v.compute_from_sats( })?;
starting_indexes.dateindex,
self.sats.dateindex.as_ref().unwrap(),
exit,
)
},
)?;
} }
let dateindex_to_bitcoin = self.bitcoin.dateindex.as_ref().unwrap(); let dateindex_to_bitcoin = self.bitcoin.dateindex.as_ref().unwrap();
@@ -147,33 +118,23 @@ impl ComputedValueVecsFromDateIndex {
.unwrap(); .unwrap();
if let Some(dollars) = self.dollars.as_mut() { if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all( dollars.compute_all(starting_indexes, exit, |v| {
indexer, v.compute_from_bitcoin(
indexes, starting_indexes.dateindex,
starting_indexes, dateindex_to_bitcoin,
exit, dateindex_to_price_close,
|v, _, _, starting_indexes, exit| { exit,
v.compute_from_bitcoin( )
starting_indexes.dateindex, })?;
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
},
)?;
} }
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[ std::iter::empty()
self.sats.vecs(), .chain(self.sats.iter_any_collectable())
self.bitcoin.vecs(), .chain(self.bitcoin.iter_any_collectable())
self.dollars.as_ref().map_or(vec![], |v| v.vecs()), .chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
} }
} }
@@ -1,5 +1,5 @@
use allocative::Allocative;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version}; use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec}; use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -12,7 +12,7 @@ use crate::{
use super::{ComputedVecsFromHeight, VecBuilderOptions}; use super::{ComputedVecsFromHeight, VecBuilderOptions};
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct ComputedValueVecsFromHeight { pub struct ComputedValueVecsFromHeight {
pub sats: ComputedVecsFromHeight<Sats>, pub sats: ComputedVecsFromHeight<Sats>,
pub bitcoin: ComputedVecsFromHeight<Bitcoin>, pub bitcoin: ComputedVecsFromHeight<Bitcoin>,
@@ -43,7 +43,7 @@ impl ComputedValueVecsFromHeight {
)?, )?,
bitcoin: ComputedVecsFromHeight::forced_import( bitcoin: ComputedVecsFromHeight::forced_import(
db, db,
&format!("{name}_in_btc"), &format!("{name}_btc"),
Source::Compute, Source::Compute,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -52,7 +52,7 @@ impl ComputedValueVecsFromHeight {
dollars: compute_dollars.then(|| { dollars: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import( ComputedVecsFromHeight::forced_import(
db, db,
&format!("{name}_in_usd"), &format!("{name}_usd"),
Source::Compute, Source::Compute,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -65,7 +65,6 @@ impl ComputedValueVecsFromHeight {
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -73,31 +72,18 @@ impl ComputedValueVecsFromHeight {
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut( F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
{ {
compute( compute(self.sats.height.as_mut().unwrap())?;
self.sats.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
let height: Option<&StoredVec<Height, Sats>> = None; 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(()) Ok(())
} }
pub fn compute_rest( pub fn compute_rest(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -108,67 +94,47 @@ impl ComputedValueVecsFromHeight {
self.sats self.sats
.compute_rest(indexes, starting_indexes, exit, Some(height))?; .compute_rest(indexes, starting_indexes, exit, Some(height))?;
self.bitcoin.compute_all( self.bitcoin
indexer, .compute_all(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(starting_indexes.height, height, exit) v.compute_from_sats(starting_indexes.height, height, exit)
}, })?;
)?;
} else { } else {
let height: Option<&StoredVec<Height, Sats>> = None; let height: Option<&StoredVec<Height, Sats>> = None;
self.sats self.sats
.compute_rest(indexes, starting_indexes, exit, height)?; .compute_rest(indexes, starting_indexes, exit, height)?;
self.bitcoin.compute_all( self.bitcoin
indexer, .compute_all(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats( v.compute_from_sats(
starting_indexes.height, starting_indexes.height,
self.sats.height.as_ref().unwrap(), self.sats.height.as_ref().unwrap(),
exit, exit,
) )
}, })?;
)?;
} }
let height_to_bitcoin = self.bitcoin.height.as_ref().unwrap(); let height_to_bitcoin = self.bitcoin.height.as_ref().unwrap();
let height_to_price_close = &price.as_ref().unwrap().chainindexes_to_price_close.height; let height_to_price_close = &price.as_ref().unwrap().chainindexes_to_price_close.height;
if let Some(dollars) = self.dollars.as_mut() { if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all( dollars.compute_all(indexes, starting_indexes, exit, |v| {
indexer, v.compute_from_bitcoin(
indexes, starting_indexes.height,
starting_indexes, height_to_bitcoin,
exit, height_to_price_close,
|v, _, _, starting_indexes, exit| { exit,
v.compute_from_bitcoin( )
starting_indexes.height, })?;
height_to_bitcoin,
height_to_price_close,
exit,
)
},
)?;
} }
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[ std::iter::empty()
self.sats.vecs(), .chain(self.sats.iter_any_collectable())
self.bitcoin.vecs(), .chain(self.bitcoin.iter_any_collectable())
self.dollars.as_ref().map_or(vec![], |v| v.vecs()), .chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
} }
} }
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Close, Dollars, Height, Sats, TxIndex, Version}; use brk_structs::{Bitcoin, Close, Dollars, Height, Sats, TxIndex, Version};
@@ -10,7 +11,7 @@ use crate::{Indexes, grouped::Source, indexes, price};
use super::{ComputedVecsFromTxindex, VecBuilderOptions}; use super::{ComputedVecsFromTxindex, VecBuilderOptions};
#[derive(Clone)] #[derive(Clone, Allocative)]
pub struct ComputedValueVecsFromTxindex { pub struct ComputedValueVecsFromTxindex {
pub sats: ComputedVecsFromTxindex<Sats>, pub sats: ComputedVecsFromTxindex<Sats>,
pub bitcoin_txindex: LazyVecFrom1<TxIndex, Bitcoin, TxIndex, Sats>, pub bitcoin_txindex: LazyVecFrom1<TxIndex, Bitcoin, TxIndex, Sats>,
@@ -37,8 +38,8 @@ impl ComputedValueVecsFromTxindex {
) -> Result<Self> { ) -> Result<Self> {
let compute_dollars = price.is_some(); let compute_dollars = price.is_some();
let name_in_btc = format!("{name}_in_btc"); let name_btc = format!("{name}_btc");
let name_in_usd = format!("{name}_in_usd"); let name_usd = format!("{name}_usd");
let sats = ComputedVecsFromTxindex::forced_import( let sats = ComputedVecsFromTxindex::forced_import(
db, db,
@@ -52,7 +53,7 @@ impl ComputedValueVecsFromTxindex {
let source_vec = source.vec(); let source_vec = source.vec();
let bitcoin_txindex = LazyVecFrom1::init( let bitcoin_txindex = LazyVecFrom1::init(
&name_in_btc, &name_btc,
version + VERSION, version + VERSION,
source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s), source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|txindex: TxIndex, iter| { |txindex: TxIndex, iter| {
@@ -65,7 +66,7 @@ impl ComputedValueVecsFromTxindex {
let bitcoin = ComputedVecsFromTxindex::forced_import( let bitcoin = ComputedVecsFromTxindex::forced_import(
db, db,
&name_in_btc, &name_btc,
Source::None, Source::None,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -74,29 +75,27 @@ impl ComputedValueVecsFromTxindex {
let dollars_txindex = price.map(|price| { let dollars_txindex = price.map(|price| {
LazyVecFrom3::init( LazyVecFrom3::init(
&name_in_usd, &name_usd,
version + VERSION, version + VERSION,
bitcoin_txindex.boxed_clone(), bitcoin_txindex.boxed_clone(),
indexes.txindex_to_height.boxed_clone(), indexes.txindex_to_height.boxed_clone(),
price.chainindexes_to_price_close.height.boxed_clone(), price.chainindexes_to_price_close.height.boxed_clone(),
|txindex: TxIndex, |txindex: TxIndex,
txindex_to_in_btc_iter, txindex_to_btc_iter,
txindex_to_height_iter, txindex_to_height_iter,
height_to_price_close_iter| { height_to_price_close_iter| {
let txindex = txindex.unwrap_to_usize(); let txindex = txindex.unwrap_to_usize();
txindex_to_in_btc_iter txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
.next_at(txindex) let btc = value.into_owned();
.and_then(|(_, value)| { txindex_to_height_iter
let btc = value.into_owned(); .next_at(txindex)
txindex_to_height_iter .and_then(|(_, value)| {
.next_at(txindex) let height = value.into_owned();
.and_then(|(_, value)| { height_to_price_close_iter
let height = value.into_owned(); .next_at(height.unwrap_to_usize())
height_to_price_close_iter .map(|(_, close)| *close.into_owned() * btc)
.next_at(height.unwrap_to_usize()) })
.map(|(_, close)| *close.into_owned() * btc) })
})
})
}, },
) )
}); });
@@ -109,7 +108,7 @@ impl ComputedValueVecsFromTxindex {
dollars: compute_dollars.then(|| { dollars: compute_dollars.then(|| {
ComputedVecsFromTxindex::forced_import( ComputedVecsFromTxindex::forced_import(
db, db,
&name_in_usd, &name_usd,
Source::None, Source::None,
version + VERSION, version + VERSION,
indexes, indexes,
@@ -203,18 +202,16 @@ impl ComputedValueVecsFromTxindex {
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[ [&self.bitcoin_txindex as &dyn AnyCollectableVec]
self.sats.vecs(), .into_iter()
vec![&self.bitcoin_txindex as &dyn AnyCollectableVec], .chain(self.sats.iter_any_collectable())
self.bitcoin.vecs(), .chain(self.bitcoin.iter_any_collectable())
self.dollars_txindex .chain(
.as_ref() self.dollars_txindex
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]), .iter()
self.dollars.as_ref().map_or(vec![], |v| v.vecs()), .map(|v| v as &dyn AnyCollectableVec),
] )
.into_iter() .chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
.flatten()
.collect::<Vec<_>>()
} }
} }
+10 -29
View File
@@ -1,12 +1,11 @@
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version}; use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, Format, StoredVec}; use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, Format, StoredVec};
use crate::{ use crate::{
Indexes, Indexes,
grouped::Source, grouped::Source,
indexes, price, price,
traits::{ComputeFromBitcoin, ComputeFromSats}, traits::{ComputeFromBitcoin, ComputeFromSats},
}; };
@@ -35,14 +34,14 @@ impl ComputedHeightValueVecs {
}), }),
bitcoin: EagerVec::forced_import( bitcoin: EagerVec::forced_import(
db, db,
&format!("{name}_in_btc"), &format!("{name}_btc"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
)?, )?,
dollars: compute_dollars.then(|| { dollars: compute_dollars.then(|| {
EagerVec::forced_import( EagerVec::forced_import(
db, db,
&format!("{name}_in_usd"), &format!("{name}_usd"),
version + VERSION + Version::ZERO, version + VERSION + Version::ZERO,
format, format,
) )
@@ -53,29 +52,15 @@ impl ComputedHeightValueVecs {
pub fn compute_all<F>( pub fn compute_all<F>(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
mut compute: F, mut compute: F,
) -> Result<()> ) -> Result<()>
where where
F: FnMut( F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
{ {
compute( compute(self.sats.as_mut().unwrap())?;
self.sats.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
let height: Option<&StoredVec<Height, Sats>> = None; let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(price, starting_indexes, exit, height)?; self.compute_rest(price, starting_indexes, exit, height)?;
@@ -116,14 +101,10 @@ impl ComputedHeightValueVecs {
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[ [&self.bitcoin as &dyn AnyCollectableVec]
vec![&self.bitcoin as &dyn AnyCollectableVec], .into_iter()
self.sats.as_ref().map_or(vec![], |v| vec![v]), .chain(self.sats.iter().map(|v| v as &dyn AnyCollectableVec))
self.dollars.as_ref().map_or(vec![], |v| vec![v]), .chain(self.dollars.iter().map(|v| v as &dyn AnyCollectableVec))
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
} }
} }
+5 -5
View File
@@ -475,8 +475,7 @@ impl Vecs {
}; };
this.db.retain_regions( this.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -934,9 +933,9 @@ impl Vecs {
}) })
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
vec![ [
&self.dateindex_to_date, &self.dateindex_to_date as &dyn AnyCollectableVec,
&self.dateindex_to_dateindex, &self.dateindex_to_dateindex,
&self.dateindex_to_first_height, &self.dateindex_to_first_height,
&self.dateindex_to_height_count, &self.dateindex_to_height_count,
@@ -997,6 +996,7 @@ impl Vecs {
&self.yearindex_to_yearindex, &self.yearindex_to_yearindex,
&self.outputindex_to_txindex, &self.outputindex_to_txindex,
] ]
.into_iter()
} }
} }
+76 -31
View File
@@ -1,6 +1,6 @@
#![doc = include_str!("../README.md")] #![doc = include_str!("../README.md")]
use std::{path::Path, thread}; use std::path::Path;
use brk_error::Result; use brk_error::Result;
use brk_fetcher::Fetcher; use brk_fetcher::Fetcher;
@@ -34,6 +34,7 @@ pub struct Computer {
pub indexes: indexes::Vecs, pub indexes: indexes::Vecs,
pub constants: constants::Vecs, pub constants: constants::Vecs,
pub market: market::Vecs, pub market: market::Vecs,
pub pools: pools::Vecs,
pub price: Option<price::Vecs>, pub price: Option<price::Vecs>,
pub chain: chain::Vecs, pub chain: chain::Vecs,
pub stateful: stateful::Vecs, pub stateful: stateful::Vecs,
@@ -41,7 +42,7 @@ pub struct Computer {
pub cointime: cointime::Vecs, pub cointime: cointime::Vecs,
} }
const VERSION: Version = Version::TWO; const VERSION: Version = Version::new(4);
impl Computer { impl Computer {
/// Do NOT import multiple times or things will break !!! /// Do NOT import multiple times or things will break !!!
@@ -86,6 +87,12 @@ impl Computer {
&indexes, &indexes,
price.as_ref(), price.as_ref(),
)?, )?,
pools: pools::Vecs::forced_import(
&computed_path,
VERSION + Version::ZERO,
&indexes,
price.as_ref(),
)?,
cointime: cointime::Vecs::forced_import( cointime: cointime::Vecs::forced_import(
&computed_path, &computed_path,
VERSION + Version::ZERO, VERSION + Version::ZERO,
@@ -109,7 +116,7 @@ impl Computer {
info!("Computing constants..."); info!("Computing constants...");
self.constants self.constants
.compute(indexer, &self.indexes, &starting_indexes, exit)?; .compute(&self.indexes, &starting_indexes, exit)?;
if let Some(fetched) = self.fetched.as_mut() { if let Some(fetched) = self.fetched.as_mut() {
info!("Computing fetched..."); info!("Computing fetched...");
@@ -117,7 +124,6 @@ impl Computer {
info!("Computing prices..."); info!("Computing prices...");
self.price.as_mut().unwrap().compute( self.price.as_mut().unwrap().compute(
indexer,
&self.indexes, &self.indexes,
&starting_indexes, &starting_indexes,
fetched, fetched,
@@ -125,8 +131,8 @@ impl Computer {
)?; )?;
} }
thread::scope(|scope| -> Result<()> { std::thread::scope(|scope| -> Result<()> {
let chain = scope.spawn(|| { let chain = scope.spawn(|| -> Result<()> {
info!("Computing chain..."); info!("Computing chain...");
self.chain.compute( self.chain.compute(
indexer, indexer,
@@ -134,23 +140,30 @@ impl Computer {
&starting_indexes, &starting_indexes,
self.price.as_ref(), self.price.as_ref(),
exit, exit,
) )?;
});
let market = scope.spawn(|| -> Result<()> {
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market
.compute(indexer, &self.indexes, price, &starting_indexes, exit)?;
}
Ok(()) Ok(())
}); });
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market.compute(price, &starting_indexes, exit)?;
}
chain.join().unwrap()?; chain.join().unwrap()?;
market.join().unwrap()?;
Ok(()) Ok(())
})?; })?;
self.pools.compute(
indexer,
&self.indexes,
&starting_indexes,
&self.chain,
self.price.as_ref(),
exit,
)?;
// return Ok(());
info!("Computing stateful..."); info!("Computing stateful...");
self.stateful.compute( self.stateful.compute(
indexer, indexer,
@@ -163,7 +176,6 @@ impl Computer {
info!("Computing cointime..."); info!("Computing cointime...");
self.cointime.compute( self.cointime.compute(
indexer,
&self.indexes, &self.indexes,
&starting_indexes, &starting_indexes,
self.price.as_ref(), self.price.as_ref(),
@@ -175,23 +187,56 @@ impl Computer {
Ok(()) 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>> =
self.constants.vecs(), Box::new(self.fetched.iter().flat_map(|v| v.iter_any_collectable()));
self.indexes.vecs(),
self.market.vecs(), iter = Box::new(iter.chain(self.price.iter().flat_map(|v| v.iter_any_collectable())));
self.chain.vecs(), iter = Box::new(iter.chain(self.pools.iter_any_collectable()));
self.stateful.vecs(), iter = Box::new(iter.chain(self.constants.iter_any_collectable()));
self.cointime.vecs(), iter = Box::new(iter.chain(self.indexes.iter_any_collectable()));
self.fetched.as_ref().map_or(vec![], |v| v.vecs()), iter = Box::new(iter.chain(self.market.iter_any_collectable()));
self.price.as_ref().map_or(vec![], |v| v.vecs()), iter = Box::new(iter.chain(self.chain.iter_any_collectable()));
] iter = Box::new(iter.chain(self.stateful.iter_any_collectable()));
.into_iter() iter = Box::new(iter.chain(self.cointime.iter_any_collectable()));
.flatten()
.collect::<Vec<_>>() iter
} }
pub fn static_clone(&self) -> &'static Self { pub fn static_clone(&self) -> &'static Self {
Box::leak(Box::new(self.clone())) Box::leak(Box::new(self.clone()))
} }
} }
// pub fn generate_allocation_files(monitored: &pools::Vecs) -> Result<()> {
// info!("Generating Allocative files...");
// let mut flamegraph = allocative::FlameGraphBuilder::default();
// flamegraph.visit_root(monitored);
// let output = flamegraph.finish();
// let folder = format!(
// "at-{}",
// jiff::Timestamp::now().strftime("%Y-%m-%d_%Hh%Mm%Ss"),
// );
// let path = std::path::PathBuf::from(&format!("./target/flamegraph/{folder}"));
// std::fs::create_dir_all(&path)?;
// // fs::write(path.join("flamegraph.src"), &output.flamegraph())?;
// let mut fg_svg = Vec::new();
// inferno::flamegraph::from_reader(
// &mut inferno::flamegraph::Options::default(),
// output.flamegraph().write().as_bytes(),
// &mut fg_svg,
// )?;
// std::fs::write(path.join("flamegraph.svg"), &fg_svg)?;
// std::fs::write(path.join("warnings.txt"), output.warnings())?;
// info!("Successfully generated Allocative files");
// Ok(())
// }
File diff suppressed because it is too large Load Diff
+187 -75
View File
@@ -1,101 +1,123 @@
use allocative::Allocative;
use num_enum::{FromPrimitive, IntoPrimitive}; use num_enum::{FromPrimitive, IntoPrimitive};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
// Created from the list in `pools.rs`
// Can be used as index for said list
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, FromPrimitive, IntoPrimitive)] #[derive(
#[repr(u16)] Debug,
Copy,
Clone,
PartialEq,
Eq,
PartialOrd,
Ord,
Serialize,
Deserialize,
FromPrimitive,
IntoPrimitive,
FromBytes,
IntoBytes,
Immutable,
KnownLayout,
Allocative,
)]
#[serde(rename_all = "lowercase")]
#[repr(u8)]
pub enum PoolId { pub enum PoolId {
#[default] #[default]
Unknown, Unknown,
BlockFills, BlockFills,
Ultimuspool, UltimusPool,
TerraPool, TerraPool,
Luxor, Luxor,
OneTHash, OneThash,
BTCCom, BtcCom,
Bitfarms, Bitfarms,
HuobiPool, HuobiPool,
WayiCn, WayiCn,
CanoePool, CanoePool,
BTCTop, BtcTop,
BitcoinCom, BitcoinCom,
OneSevenFiveBtc, Pool175btc,
GBMiners, GbMiners,
AXbt, AXbt,
ASICMiner, AsicMiner,
BitMinter, BitMinter,
BitcoinRussia, BitcoinRussia,
BTCServ, BtcServ,
SimplecoinUs, SimplecoinUs,
BTCGuild, BtcGuild,
Eligius, Eligius,
OzCoin, OzCoin,
EclipseMC, EclipseMc,
MaxBTC, MaxBtc,
TripleMining, TripleMining,
CoinLab, CoinLab,
FiftyBTC, Pool50btc,
GHashIO, GhashIo,
STMiningCorp, StMiningCorp,
Bitparking, Bitparking,
MMPool, Mmpool,
Polmine, Polmine,
KnCMiner, KncMiner,
Bitalo, Bitalo,
F2Pool, F2Pool,
HHTT, Hhtt,
MegaBigPower, MegaBigPower,
MtRed, MtRed,
NMCbit, NmcBit,
YourbtcNet, YourbtcNet,
GiveMeCoins, GiveMeCoins,
BraiinsPool, BraiinsPool,
AntPool, AntPool,
MultiCoinCo, MultiCoinCo,
BCPoolIo, BcpoolIo,
Cointerra, Cointerra,
KanoPool, KanoPool,
SoloCK, SoloCk,
CKPool, CkPool,
NiceHash, NiceHash,
BitClub, BitClub,
BitcoinAffiliateNetwork, BitcoinAffiliateNetwork,
BTCC, Btcc,
BWPool, BwPool,
EXXAndBW, ExxBw,
Bitsolo, Bitsolo,
BitFury, BitFury,
TwentyOneInc, TwentyOneInc,
DigitalBTC, DigitalBtc,
EightBaochi, EightBaochi,
MyBTCcoinPool, MyBtcCoinPool,
TBDice, TbDice,
HASHPOOL, HashPool,
Nexious, Nexious,
BravoMining, BravoMining,
HotPool, HotPool,
OKExPool, OkExPool,
BCMonster, BcMonster,
OneHash, OneHash,
Bixin, Bixin,
TATMASPool, TatmasPool,
ViaBTC, ViaBtc,
ConnectBTC, ConnectBtc,
BATPOOL, BatPool,
Waterhole, Waterhole,
DCExploration, DcExploration,
DCEX, Dcex,
BTPOOL, BtPool,
FiftyEightCoin, FiftyEightCoin,
BitcoinIndiaLowercase, BitcoinIndia,
ShawnP0wers, ShawnP0wers,
PHashIO, PHashIo,
RigPool, RigPool,
HAOZHUZHU, HaoZhuZhu,
SevenPool, SevenPool,
MiningKings, MiningKings,
HashBX, HashBx,
DPOOL, DPool,
Rawpool, Rawpool,
Haominer, Haominer,
Helix, Helix,
@@ -114,62 +136,152 @@ pub enum PoolId {
BinancePool, BinancePool,
Minerium, Minerium,
LubianCom, LubianCom,
OKKONG, Okkong,
AAOPool, AaoPool,
EMCDPool, EmcdPool,
FoundryUSA, FoundryUsa,
SBICrypto, SbiCrypto,
ArkPool, ArkPool,
PureBTCCom, PureBtcCom,
MARAPool, MaraPool,
KuCoinPool, KuCoinPool,
EntrustCharityPool, EntrustCharityPool,
OKMINER, OkMiner,
Titan, Titan,
PEGAPool, PegaPool,
BTCNuggets, BtcNuggets,
CloudHashing, CloudHashing,
DigitalXMintsy, DigitalXMintsy,
Telco214, Telco214,
BTCPoolParty, BtcPoolParty,
Multipool, Multipool,
TransactionCoinMining, TransactionCoinMining,
BTCDig, BtcDig,
TrickysBTCPool, TrickysBtcPool,
BTCMP, BtcMp,
Eobot, Eobot,
UNOMP, Unomp,
Patels, Patels,
GoGreenLight, GoGreenLight,
BitcoinIndiaCamel, // duplicate-ish entry preserved with slight name change EkanemBtc,
EkanemBTC, Canoe,
CanoeUppercase, Tiger,
TigerLowercase, OneM1x,
OneM1X,
Zulupool, Zulupool,
SECPOOL, SecPool,
OCEAN, Ocean,
WhitePool, WhitePool,
Wiz,
Mononaut,
Rijndael,
Wk057, Wk057,
FutureBitApolloSolo, FutureBitApolloSolo,
Emzy,
Knorrium,
CarbonNegative, CarbonNegative,
PortlandHODL, PortlandHodl,
Phoenix, Phoenix,
Neopool, Neopool,
MaxiPool, MaxiPool,
DrDetroit,
BitFuFuPool, BitFuFuPool,
LuckyPool, LuckyPool,
MiningDutch, MiningDutch,
PublicPool, PublicPool,
MiningSquared, MiningSquared,
InnopolisTech, InnopolisTech,
Nymkappa, BtcLab,
BTCLab,
Parasite, Parasite,
Dummy158,
Dummy159,
Dummy160,
Dummy161,
Dummy162,
Dummy163,
Dummy164,
Dummy165,
Dummy166,
Dummy167,
Dummy168,
Dummy169,
Dummy170,
Dummy171,
Dummy172,
Dummy173,
Dummy174,
Dummy175,
Dummy176,
Dummy177,
Dummy178,
Dummy179,
Dummy180,
Dummy181,
Dummy182,
Dummy183,
Dummy184,
Dummy185,
Dummy186,
Dummy187,
Dummy188,
Dummy189,
Dummy190,
Dummy191,
Dummy192,
Dummy193,
Dummy194,
Dummy195,
Dummy196,
Dummy197,
Dummy198,
Dummy199,
Dummy200,
Dummy201,
Dummy202,
Dummy203,
Dummy204,
Dummy205,
Dummy206,
Dummy207,
Dummy208,
Dummy209,
Dummy210,
Dummy211,
Dummy212,
Dummy213,
Dummy214,
Dummy215,
Dummy216,
Dummy217,
Dummy218,
Dummy219,
Dummy220,
Dummy221,
Dummy222,
Dummy223,
Dummy224,
Dummy225,
Dummy226,
Dummy227,
Dummy228,
Dummy229,
Dummy230,
Dummy231,
Dummy232,
Dummy233,
Dummy234,
Dummy235,
Dummy236,
Dummy237,
Dummy238,
Dummy239,
Dummy240,
Dummy241,
Dummy242,
Dummy243,
Dummy244,
Dummy245,
Dummy246,
Dummy247,
Dummy248,
Dummy249,
Dummy250,
Dummy251,
Dummy252,
Dummy253,
Dummy254,
Dummy255,
} }
+228
View File
@@ -1,7 +1,235 @@
use std::{collections::BTreeMap, path::Path};
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_store::AnyStore;
use brk_structs::{AddressBytes, Height, OutputIndex, OutputType};
use rayon::prelude::*;
use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, Database, Exit, GenericStoredVec,
PAGE_SIZE, RawVec, StoredIndex, VecIterator, Version,
};
mod id; mod id;
mod pool; mod pool;
#[allow(clippy::module_inception)]
mod pools; mod pools;
mod vecs;
pub use id::*; pub use id::*;
pub use pool::*; pub use pool::*;
pub use pools::*; pub use pools::*;
use crate::{
chain,
indexes::{self, Indexes},
price,
};
#[derive(Clone, Allocative)]
pub struct Vecs {
db: Database,
pools: &'static Pools,
height_to_pool: RawVec<Height, PoolId>,
vecs: BTreeMap<PoolId, vecs::Vecs>,
}
impl Vecs {
pub fn forced_import(
parent_path: &Path,
parent_version: Version,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
) -> Result<Self> {
let db = Database::open(&parent_path.join("pools"))?;
db.set_min_len(PAGE_SIZE * 1_000_000)?;
let pools = pools();
let version = parent_version + Version::new(3) + Version::new(pools.len() as u64);
let this = Self {
height_to_pool: RawVec::forced_import(&db, "pool", version + Version::ZERO)?,
vecs: pools
.iter()
.map(|pool| {
vecs::Vecs::forced_import(
&db,
pool.id,
pools,
version + Version::ZERO,
indexes,
price,
)
.map(|vecs| (pool.id, vecs))
})
.collect::<Result<BTreeMap<_, _>>>()?,
pools,
db,
};
this.db.retain_regions(
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
Ok(this)
}
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
chain: &chain::Vecs,
price: Option<&price::Vecs>,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, chain, price, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
chain: &chain::Vecs,
price: Option<&price::Vecs>,
exit: &Exit,
) -> Result<()> {
self.compute_height_to_pool(indexer, indexes, starting_indexes, exit)?;
self.vecs.par_iter_mut().try_for_each(|(_, vecs)| {
vecs.compute(
indexes,
starting_indexes,
&self.height_to_pool,
chain,
price,
exit,
)
})?;
Ok(())
}
fn compute_height_to_pool(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.height_to_pool.validate_computed_version_or_reset(
self.height_to_pool.version() + indexer.stores.height_to_coinbase_tag.version(),
)?;
let mut height_to_first_txindex_iter = indexer.vecs.height_to_first_txindex.iter();
let mut txindex_to_first_outputindex_iter =
indexer.vecs.txindex_to_first_outputindex.iter();
let mut txindex_to_output_count_iter = indexes.txindex_to_output_count.iter();
let mut outputindex_to_outputtype_iter = indexer.vecs.outputindex_to_outputtype.iter();
let mut outputindex_to_typeindex_iter = indexer.vecs.outputindex_to_typeindex.iter();
let mut p2pk65addressindex_to_p2pk65bytes_iter =
indexer.vecs.p2pk65addressindex_to_p2pk65bytes.iter();
let mut p2pk33addressindex_to_p2pk33bytes_iter =
indexer.vecs.p2pk33addressindex_to_p2pk33bytes.iter();
let mut p2pkhaddressindex_to_p2pkhbytes_iter =
indexer.vecs.p2pkhaddressindex_to_p2pkhbytes.iter();
let mut p2shaddressindex_to_p2shbytes_iter =
indexer.vecs.p2shaddressindex_to_p2shbytes.iter();
let mut p2wpkhaddressindex_to_p2wpkhbytes_iter =
indexer.vecs.p2wpkhaddressindex_to_p2wpkhbytes.iter();
let mut p2wshaddressindex_to_p2wshbytes_iter =
indexer.vecs.p2wshaddressindex_to_p2wshbytes.iter();
let mut p2traddressindex_to_p2trbytes_iter =
indexer.vecs.p2traddressindex_to_p2trbytes.iter();
let mut p2aaddressindex_to_p2abytes_iter = indexer.vecs.p2aaddressindex_to_p2abytes.iter();
let unknown = self.pools.get_unknown();
let min = starting_indexes
.height
.unwrap_to_usize()
.min(self.height_to_pool.len());
indexer
.stores
.height_to_coinbase_tag
.iter()
.skip(min)
.try_for_each(|(height, coinbase_tag)| -> Result<()> {
let txindex = height_to_first_txindex_iter.unwrap_get_inner(height);
let outputindex = txindex_to_first_outputindex_iter.unwrap_get_inner(txindex);
let outputcount = txindex_to_output_count_iter.unwrap_get_inner(txindex);
let pool = (*outputindex..(*outputindex + *outputcount))
.map(OutputIndex::from)
.find_map(|outputindex| {
let outputtype =
outputindex_to_outputtype_iter.unwrap_get_inner(outputindex);
let typeindex = outputindex_to_typeindex_iter.unwrap_get_inner(outputindex);
let address = match outputtype {
OutputType::P2PK65 => Some(AddressBytes::from(
p2pk65addressindex_to_p2pk65bytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2PK33 => Some(AddressBytes::from(
p2pk33addressindex_to_p2pk33bytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2PKH => Some(AddressBytes::from(
p2pkhaddressindex_to_p2pkhbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2SH => Some(AddressBytes::from(
p2shaddressindex_to_p2shbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2WPKH => Some(AddressBytes::from(
p2wpkhaddressindex_to_p2wpkhbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2WSH => Some(AddressBytes::from(
p2wshaddressindex_to_p2wshbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2TR => Some(AddressBytes::from(
p2traddressindex_to_p2trbytes_iter
.unwrap_get_inner(typeindex.into()),
)),
OutputType::P2A => Some(AddressBytes::from(
p2aaddressindex_to_p2abytes_iter.unwrap_get_inner(typeindex.into()),
)),
_ => None,
};
address
.and_then(|address| self.pools.find_from_address(&address.to_string()))
})
.or_else(|| self.pools.find_from_coinbase_tag(&coinbase_tag))
.unwrap_or(unknown);
self.height_to_pool.push_if_needed(height, pool.id)?;
Ok(())
})?;
self.height_to_pool.safe_flush(exit)?;
Ok(())
}
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()),
)
}
}
+36 -2
View File
@@ -1,10 +1,44 @@
use serde::{Deserialize, Serialize}; use allocative::Allocative;
use crate::pools::PoolId; use crate::pools::PoolId;
#[derive(Debug, Serialize, Deserialize)] #[derive(Debug, Allocative)]
pub struct Pool { pub struct Pool {
pub id: PoolId, pub id: PoolId,
pub name: &'static str,
pub addresses: Box<[&'static str]>,
pub tags: Box<[&'static str]>,
pub tags_lowercase: Box<[String]>,
pub link: &'static str,
}
impl Pool {
pub fn serialized_id(&self) -> String {
let value = serde_json::to_value(self.id).unwrap();
value.as_str().unwrap().to_string()
}
}
impl From<(usize, JSONPool)> for Pool {
fn from((index, pool): (usize, JSONPool)) -> Self {
Self {
id: (index as u8).into(),
name: pool.name,
addresses: pool.addresses,
tags_lowercase: pool
.tags
.iter()
.map(|t| t.to_lowercase())
.collect::<Vec<_>>()
.into_boxed_slice(),
tags: pool.tags,
link: pool.link,
}
}
}
#[derive(Debug)]
pub struct JSONPool {
pub name: &'static str, pub name: &'static str,
pub addresses: Box<[&'static str]>, pub addresses: Box<[&'static str]>,
pub tags: Box<[&'static str]>, pub tags: Box<[&'static str]>,
File diff suppressed because it is too large Load Diff
+397
View File
@@ -0,0 +1,397 @@
use allocative::Allocative;
use brk_error::Result;
use brk_structs::{Height, Sats, StoredF32, StoredU16, StoredU32};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, StoredIndex, VecIterator, Version};
use crate::{
PoolId, Pools, chain,
grouped::{
ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source,
VecBuilderOptions,
},
indexes::{self, Indexes},
price,
};
#[derive(Clone, Allocative)]
pub struct Vecs {
id: PoolId,
indexes_to_blocks_mined: ComputedVecsFromHeight<StoredU32>,
indexes_to_1w_blocks_mined: ComputedVecsFromDateIndex<StoredU32>,
indexes_to_1m_blocks_mined: ComputedVecsFromDateIndex<StoredU32>,
indexes_to_1y_blocks_mined: ComputedVecsFromDateIndex<StoredU32>,
indexes_to_subsidy: ComputedValueVecsFromHeight,
indexes_to_fee: ComputedValueVecsFromHeight,
indexes_to_coinbase: ComputedValueVecsFromHeight,
indexes_to_dominance: ComputedVecsFromDateIndex<StoredF32>,
indexes_to_1d_dominance: ComputedVecsFromDateIndex<StoredF32>,
indexes_to_1w_dominance: ComputedVecsFromDateIndex<StoredF32>,
indexes_to_1m_dominance: ComputedVecsFromDateIndex<StoredF32>,
indexes_to_1y_dominance: ComputedVecsFromDateIndex<StoredF32>,
indexes_to_days_since_block: ComputedVecsFromDateIndex<StoredU16>,
}
impl Vecs {
pub fn forced_import(
db: &Database,
id: PoolId,
pools: &Pools,
parent_version: Version,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
) -> Result<Self> {
let pool = pools.get(id);
let name = pool.serialized_id();
let suffix = |s: &str| format!("{name}_{s}");
let compute_dollars = price.is_some();
let version = parent_version + Version::ZERO;
Ok(Self {
id,
indexes_to_blocks_mined: ComputedVecsFromHeight::forced_import(
db,
&suffix("blocks_mined"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_1w_blocks_mined: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1w_blocks_mined"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1m_blocks_mined: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1m_blocks_mined"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1y_blocks_mined: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1y_blocks_mined"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import(
db,
&suffix("subsidy"),
Source::Compute,
version + Version::ZERO,
VecBuilderOptions::default().add_sum().add_cumulative(),
compute_dollars,
indexes,
)?,
indexes_to_fee: ComputedValueVecsFromHeight::forced_import(
db,
&suffix("fee"),
Source::Compute,
version + Version::ZERO,
VecBuilderOptions::default().add_sum().add_cumulative(),
compute_dollars,
indexes,
)?,
indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import(
db,
&suffix("coinbase"),
Source::Compute,
version + Version::ZERO,
VecBuilderOptions::default().add_sum().add_cumulative(),
compute_dollars,
indexes,
)?,
indexes_to_dominance: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("dominance"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1d_dominance: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1d_dominance"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1w_dominance: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1w_dominance"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1m_dominance: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1m_dominance"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_1y_dominance: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("1y_dominance"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_days_since_block: ComputedVecsFromDateIndex::forced_import(
db,
&suffix("days_since_block"),
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
})
}
#[allow(clippy::too_many_arguments)]
pub fn compute(
&mut self,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
height_to_pool: &impl AnyIterableVec<Height, PoolId>,
chain: &chain::Vecs,
price: Option<&price::Vecs>,
exit: &Exit,
) -> Result<()> {
self.indexes_to_blocks_mined
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
height_to_pool,
|(h, id, ..)| {
(
h,
if id == self.id {
StoredU32::ONE
} else {
StoredU32::ZERO
},
)
},
exit,
)?;
Ok(())
})?;
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(),
7,
exit,
)?;
Ok(())
})?;
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(),
30,
exit,
)?;
Ok(())
})?;
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(),
365,
exit,
)?;
Ok(())
})?;
let height_to_blocks_mined = self.indexes_to_blocks_mined.height.as_ref().unwrap();
self.indexes_to_subsidy
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
chain.indexes_to_subsidy.sats.height.as_ref().unwrap(),
|(h, mined, sats, ..)| {
(
h,
if mined == StoredU32::ONE {
sats
} else {
Sats::ZERO
},
)
},
exit,
)?;
Ok(())
})?;
self.indexes_to_fee
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
chain.indexes_to_fee.sats.height.unwrap_sum(),
|(h, mined, sats, ..)| {
(
h,
if mined == StoredU32::ONE {
sats
} else {
Sats::ZERO
},
)
},
exit,
)?;
Ok(())
})?;
self.indexes_to_coinbase
.compute_all(indexes, price, starting_indexes, exit, |vec| {
vec.compute_transform2(
starting_indexes.height,
height_to_blocks_mined,
chain.indexes_to_coinbase.sats.height.as_ref().unwrap(),
|(h, mined, sats, ..)| {
(
h,
if mined == StoredU32::ONE {
sats
} else {
Sats::ZERO
},
)
},
exit,
)?;
Ok(())
})?;
self.indexes_to_dominance
.compute_all(starting_indexes, exit, |vec| {
vec.compute_percentage(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_cumulative(),
chain.indexes_to_block_count.dateindex.unwrap_cumulative(),
exit,
)?;
Ok(())
})?;
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(),
chain.indexes_to_block_count.dateindex.unwrap_sum(),
exit,
)?;
Ok(())
})?;
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(),
chain.indexes_to_1w_block_count.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
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(),
chain.indexes_to_1m_block_count.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
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(),
chain.indexes_to_1y_block_count.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
self.indexes_to_days_since_block
.compute_all(starting_indexes, exit, |v| {
let mut prev = None;
v.compute_transform2(
starting_indexes.dateindex,
self.indexes_to_blocks_mined.dateindex.unwrap_sum(),
self.indexes_to_blocks_mined.dateindex.unwrap_cumulative(),
|(i, sum, cumulative, slf)| {
if prev.is_none() {
let i = i.unwrap_to_usize();
prev.replace(if i > 0 {
slf.into_iter().unwrap_get_inner_(i - 1)
} else {
StoredU16::ZERO
});
}
let days = if !cumulative.is_zero() && sum.is_zero() {
prev.unwrap() + StoredU16::ONE
} else {
StoredU16::ZERO
};
prev.replace(days);
(i, days)
},
exit,
)?;
Ok(())
})?;
Ok(())
}
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 std::path::Path;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
Cents, Close, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, High, Low, MonthIndex, Cents, Close, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, High, Low, MonthIndex,
OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, SemesterIndex, Version, WeekIndex, YearIndex, OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, SemesterIndex, Version, WeekIndex, YearIndex,
@@ -327,8 +326,7 @@ impl Vecs {
}; };
this.db.retain_regions( this.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -338,20 +336,18 @@ impl Vecs {
pub fn compute( pub fn compute(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
fetched: &fetched::Vecs, fetched: &fetched::Vecs,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, fetched, exit)?; self.compute_(indexes, starting_indexes, fetched, exit)?;
self.db.flush_then_punch()?; self.db.flush_then_punch()?;
Ok(()) Ok(())
} }
fn compute_( fn compute_(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
starting_indexes: &Indexes, starting_indexes: &Indexes,
fetched: &fetched::Vecs, fetched: &fetched::Vecs,
@@ -445,12 +441,8 @@ impl Vecs {
})?; })?;
self.dateindex_to_price_ohlc.safe_flush(exit)?; self.dateindex_to_price_ohlc.safe_flush(exit)?;
self.timeindexes_to_price_close.compute_all( self.timeindexes_to_price_close
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
&self.dateindex_to_price_ohlc, &self.dateindex_to_price_ohlc,
@@ -458,15 +450,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_high.compute_all( self.timeindexes_to_price_high
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
&self.dateindex_to_price_ohlc, &self.dateindex_to_price_ohlc,
@@ -474,15 +461,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_low.compute_all( self.timeindexes_to_price_low
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
&self.dateindex_to_price_ohlc, &self.dateindex_to_price_ohlc,
@@ -490,15 +472,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_open.compute_all( self.timeindexes_to_price_open
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
&self.dateindex_to_price_ohlc, &self.dateindex_to_price_ohlc,
@@ -506,15 +483,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_close.compute( self.chainindexes_to_price_close
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.height_to_price_ohlc, &self.height_to_price_ohlc,
@@ -522,15 +494,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_high.compute( self.chainindexes_to_price_high
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.height_to_price_ohlc, &self.height_to_price_ohlc,
@@ -538,15 +505,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_low.compute( self.chainindexes_to_price_low
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.height_to_price_ohlc, &self.height_to_price_ohlc,
@@ -554,15 +516,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_open.compute( self.chainindexes_to_price_open
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.height_to_price_ohlc, &self.height_to_price_ohlc,
@@ -570,8 +527,7 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let mut weekindex_first_iter = self let mut weekindex_first_iter = self
.timeindexes_to_price_open .timeindexes_to_price_open
@@ -843,12 +799,8 @@ impl Vecs {
})?; })?;
self.decadeindex_to_price_ohlc.safe_flush(exit)?; self.decadeindex_to_price_ohlc.safe_flush(exit)?;
self.chainindexes_to_price_open_in_sats.compute( self.chainindexes_to_price_open_in_sats
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.chainindexes_to_price_open.height, &self.chainindexes_to_price_open.height,
@@ -856,15 +808,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_high_in_sats.compute( self.chainindexes_to_price_high_in_sats
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.chainindexes_to_price_low.height, &self.chainindexes_to_price_low.height,
@@ -872,15 +819,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_low_in_sats.compute( self.chainindexes_to_price_low_in_sats
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.chainindexes_to_price_high.height, &self.chainindexes_to_price_high.height,
@@ -888,15 +830,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.chainindexes_to_price_close_in_sats.compute( self.chainindexes_to_price_close_in_sats
indexer, .compute(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.height, starting_indexes.height,
&self.chainindexes_to_price_close.height, &self.chainindexes_to_price_close.height,
@@ -904,15 +841,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_open_in_sats.compute_all( self.timeindexes_to_price_open_in_sats
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
self.timeindexes_to_price_open.dateindex.as_ref().unwrap(), self.timeindexes_to_price_open.dateindex.as_ref().unwrap(),
@@ -920,15 +852,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_high_in_sats.compute_all( self.timeindexes_to_price_high_in_sats
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
self.timeindexes_to_price_low.dateindex.as_ref().unwrap(), self.timeindexes_to_price_low.dateindex.as_ref().unwrap(),
@@ -936,15 +863,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_low_in_sats.compute_all( self.timeindexes_to_price_low_in_sats
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
self.timeindexes_to_price_high.dateindex.as_ref().unwrap(), self.timeindexes_to_price_high.dateindex.as_ref().unwrap(),
@@ -952,15 +874,10 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.timeindexes_to_price_close_in_sats.compute_all( self.timeindexes_to_price_close_in_sats
indexer, .compute_all(starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform( v.compute_transform(
starting_indexes.dateindex, starting_indexes.dateindex,
self.timeindexes_to_price_close.dateindex.as_ref().unwrap(), self.timeindexes_to_price_close.dateindex.as_ref().unwrap(),
@@ -968,8 +885,7 @@ impl Vecs {
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
let mut height_first_iter = self.chainindexes_to_price_open_in_sats.height.iter(); 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(); let mut height_max_iter = self.chainindexes_to_price_high_in_sats.height.iter();
@@ -1311,9 +1227,9 @@ impl Vecs {
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
vec![ let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
vec![ [
&self.dateindex_to_price_close_in_cents as &dyn AnyCollectableVec, &self.dateindex_to_price_close_in_cents as &dyn AnyCollectableVec,
&self.dateindex_to_price_high_in_cents, &self.dateindex_to_price_high_in_cents,
&self.dateindex_to_price_low_in_cents, &self.dateindex_to_price_low_in_cents,
@@ -1330,7 +1246,6 @@ impl Vecs {
&self.quarterindex_to_price_ohlc, &self.quarterindex_to_price_ohlc,
&self.semesterindex_to_price_ohlc, &self.semesterindex_to_price_ohlc,
&self.yearindex_to_price_ohlc, &self.yearindex_to_price_ohlc,
// &self.halvingepoch_to_price_ohlc,
&self.decadeindex_to_price_ohlc, &self.decadeindex_to_price_ohlc,
&self.height_to_price_ohlc_in_sats, &self.height_to_price_ohlc_in_sats,
&self.dateindex_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.quarterindex_to_price_ohlc_in_sats,
&self.semesterindex_to_price_ohlc_in_sats, &self.semesterindex_to_price_ohlc_in_sats,
&self.yearindex_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.decadeindex_to_price_ohlc_in_sats,
], ]
self.timeindexes_to_price_close.vecs(), .into_iter(),
self.timeindexes_to_price_high.vecs(), );
self.timeindexes_to_price_low.vecs(),
self.timeindexes_to_price_open.vecs(), iter = Box::new(iter.chain(self.timeindexes_to_price_close.iter_any_collectable()));
self.chainindexes_to_price_close.vecs(), iter = Box::new(iter.chain(self.timeindexes_to_price_high.iter_any_collectable()));
self.chainindexes_to_price_high.vecs(), iter = Box::new(iter.chain(self.timeindexes_to_price_low.iter_any_collectable()));
self.chainindexes_to_price_low.vecs(), iter = Box::new(iter.chain(self.timeindexes_to_price_open.iter_any_collectable()));
self.chainindexes_to_price_open.vecs(), iter = Box::new(iter.chain(self.chainindexes_to_price_close.iter_any_collectable()));
self.timeindexes_to_price_close_in_sats.vecs(), iter = Box::new(iter.chain(self.chainindexes_to_price_high.iter_any_collectable()));
self.timeindexes_to_price_high_in_sats.vecs(), iter = Box::new(iter.chain(self.chainindexes_to_price_low.iter_any_collectable()));
self.timeindexes_to_price_low_in_sats.vecs(), iter = Box::new(iter.chain(self.chainindexes_to_price_open.iter_any_collectable()));
self.timeindexes_to_price_open_in_sats.vecs(), iter = Box::new(
self.chainindexes_to_price_close_in_sats.vecs(), iter.chain(
self.chainindexes_to_price_high_in_sats.vecs(), self.timeindexes_to_price_close_in_sats
self.chainindexes_to_price_low_in_sats.vecs(), .iter_any_collectable(),
self.chainindexes_to_price_open_in_sats.vecs(), ),
] );
.into_iter() iter = Box::new(
.flatten() iter.chain(
.collect::<Vec<_>>() 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_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, StoredU64, Version}; use brk_structs::{Bitcoin, DateIndex, Dollars, Height, StoredU64, Version};
use vecdb::{ use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, Database, EagerVec, Exit, Format, 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 { impl DynCohortVecs for Vecs {
fn min_height_vecs_len(&self) -> usize { fn min_height_vecs_len(&self) -> usize {
[ std::cmp::min(
self.height_to_addr_count.len(), self.height_to_addr_count.len(),
self.inner.min_height_vecs_len(), self.inner.min_height_vecs_len(),
] )
.into_iter()
.min()
.unwrap()
} }
fn reset_state_starting_height(&mut self) { fn reset_state_starting_height(&mut self) {
@@ -171,7 +174,6 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part1( fn compute_rest_part1(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -185,16 +187,7 @@ impl DynCohortVecs for Vecs {
)?; )?;
self.inner self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit) .compute_rest_part1(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()
} }
} }
@@ -224,7 +217,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part2( fn compute_rest_part2(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -237,7 +229,6 @@ impl CohortVecs for Vecs {
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.inner.compute_rest_part2( self.inner.compute_rest_part2(
indexer,
indexes, indexes,
price, price,
starting_indexes, 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 std::path::Path;
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
AddressGroups, Bitcoin, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, DateIndex, AddressGroups, Bitcoin, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, DateIndex,
Dollars, GroupFilter, Height, Version, Dollars, GroupFilter, Height, Version,
@@ -459,18 +458,17 @@ impl Vecs {
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
let by_size_range = self.0.amount_range.as_vec(); let by_size_range = &self.0.amount_range;
[ [
self.0 self.0
.ge_amount .ge_amount
.as_mut_vec() .iter_mut()
.into_iter()
.map(|(filter, vecs)| { .map(|(filter, vecs)| {
( (
vecs, vecs,
by_size_range by_size_range
.into_iter() .iter()
.filter(|(other, _)| filter.includes(other)) .filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v) .map(|(_, v)| v)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
@@ -479,13 +477,12 @@ impl Vecs {
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
self.0 self.0
.lt_amount .lt_amount
.as_mut_vec() .iter_mut()
.into_iter()
.map(|(filter, vecs)| { .map(|(filter, vecs)| {
( (
vecs, vecs,
by_size_range by_size_range
.into_iter() .iter()
.filter(|(other, _)| filter.includes(other)) .filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v) .map(|(_, v)| v)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
@@ -502,21 +499,19 @@ impl Vecs {
pub fn compute_rest_part1( pub fn compute_rest_part1(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| { self.iter_mut()
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit) .into_iter()
}) .try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2( pub fn compute_rest_part2(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -528,27 +523,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>, dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| { self.0.iter_mut().try_for_each(|(_, v)| {
v.into_iter().try_for_each(|(_, v)| { v.compute_rest_part2(
v.compute_rest_part2( indexes,
indexer, price,
indexes, starting_indexes,
price, height_to_supply,
starting_indexes, dateindex_to_supply,
height_to_supply, height_to_market_cap,
dateindex_to_supply, dateindex_to_market_cap,
height_to_market_cap, height_to_realized_cap,
dateindex_to_market_cap, dateindex_to_realized_cap,
height_to_realized_cap, exit,
dateindex_to_realized_cap, )
exit,
)
})
}) })
} }
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> { pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs() self.iter_separate_mut()
.into_iter() .into_iter()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit)) .try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
} }
@@ -75,11 +75,9 @@ impl AddressTypeToIndexesToAddressCount {
Ok(()) Ok(())
} }
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> { pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
self.0 self.0
.as_typed_vec() .iter_typed()
.into_iter() .flat_map(|(_, v)| v.iter_any_collectable())
.flat_map(|(_, v)| v.vecs())
.collect::<Vec<_>>()
} }
} }
@@ -27,6 +27,10 @@ impl<T> AddressTypeToTypeIndexTree<T> {
mem::swap(own, other); mem::swap(own, other);
} }
} }
pub fn unwrap(self) -> ByAddressType<BTreeMap<TypeIndex, T>> {
self.0
}
} }
impl<T> Default for AddressTypeToTypeIndexTree<T> { impl<T> Default for AddressTypeToTypeIndexTree<T> {
@@ -38,6 +38,10 @@ impl<T> AddressTypeToVec<T> {
mem::swap(own, other); mem::swap(own, other);
} }
} }
pub fn unwrap(self) -> ByAddressType<Vec<T>> {
self.0
}
} }
impl<T> Default for AddressTypeToVec<T> { 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.db.retain_regions(
this.vecs() this.iter_any_collectable()
.into_iter()
.flat_map(|v| v.region_names()) .flat_map(|v| v.region_names())
.collect(), .collect(),
)?; )?;
@@ -598,8 +597,9 @@ impl Vecs {
+ dateindex_to_first_height.version() + dateindex_to_first_height.version()
+ dateindex_to_height_count.version(); + dateindex_to_height_count.version();
let mut separate_utxo_vecs = self.utxo_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.as_mut_separate_vecs(); let mut separate_address_vecs =
self.address_cohorts.iter_separate_mut().collect::<Vec<_>>();
separate_utxo_vecs separate_utxo_vecs
.par_iter_mut() .par_iter_mut()
@@ -878,13 +878,11 @@ impl Vecs {
info!("Processing chain at {height}..."); info!("Processing chain at {height}...");
self.utxo_cohorts self.utxo_cohorts
.as_mut_separate_vecs() .iter_separate_mut()
.iter_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values()); .for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
self.address_cohorts self.address_cohorts
.as_mut_separate_vecs() .iter_separate_mut()
.iter_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values()); .for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
let timestamp = height_to_timestamp_fixed_iter.unwrap_get_inner(height); 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); let dateindex = is_date_last_height.then_some(dateindex);
self.utxo_cohorts.as_mut_separate_vecs() self.utxo_cohorts.iter_separate_mut().par_bridge()
.into_par_iter()
.map(|(_, v)| v as &mut dyn DynCohortVecs) .map(|(_, v)| v as &mut dyn DynCohortVecs)
.chain( .chain(
self.address_cohorts.as_mut_separate_vecs() self.address_cohorts.iter_separate_mut()
.into_par_iter() .par_bridge()
.map(|(_, v)| v as &mut dyn DynCohortVecs), .map(|(_, v)| v as &mut dyn DynCohortVecs),
) )
.try_for_each(|v| { .try_for_each(|v| {
@@ -1309,48 +1306,35 @@ impl Vecs {
info!("Computing rest part 1..."); info!("Computing rest part 1...");
self.indexes_to_addr_count.compute_all( self.indexes_to_addr_count
indexer, .compute_all(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sum_of_others( v.compute_sum_of_others(
starting_indexes.height, starting_indexes.height,
&self &self
.addresstype_to_height_to_addr_count .addresstype_to_height_to_addr_count
.as_typed_vec() .iter_typed()
.into_iter()
.map(|(_, v)| v) .map(|(_, v)| v)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_empty_addr_count.compute_all( self.indexes_to_empty_addr_count
indexer, .compute_all(indexes, starting_indexes, exit, |v| {
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_sum_of_others( v.compute_sum_of_others(
starting_indexes.height, starting_indexes.height,
&self &self
.addresstype_to_height_to_empty_addr_count .addresstype_to_height_to_empty_addr_count
.as_typed_vec() .iter_typed()
.into_iter()
.map(|(_, v)| v) .map(|(_, v)| v)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
exit, exit,
)?; )?;
Ok(()) Ok(())
}, })?;
)?;
self.indexes_to_unspendable_supply.compute_rest( self.indexes_to_unspendable_supply.compute_rest(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
@@ -1358,7 +1342,6 @@ impl Vecs {
Some(&self.height_to_unspendable_supply), Some(&self.height_to_unspendable_supply),
)?; )?;
self.indexes_to_opreturn_supply.compute_rest( self.indexes_to_opreturn_supply.compute_rest(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
@@ -1381,36 +1364,30 @@ impl Vecs {
)?; )?;
self.utxo_cohorts self.utxo_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?; .compute_rest_part1(indexes, price, starting_indexes, exit)?;
self.address_cohorts 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() { if let Some(indexes_to_market_cap) = self.indexes_to_market_cap.as_mut() {
indexes_to_market_cap.compute_all( indexes_to_market_cap.compute_all(starting_indexes, exit, |v| {
indexer, v.compute_transform(
indexes, starting_indexes.dateindex,
starting_indexes, self.utxo_cohorts
exit, .all
|v, _, _, starting_indexes, exit| { .1
v.compute_transform( .indexes_to_supply
starting_indexes.dateindex, .dollars
self.utxo_cohorts .as_ref()
.all .unwrap()
.1 .dateindex
.indexes_to_supply .as_ref()
.dollars .unwrap(),
.as_ref() |(i, v, ..)| (i, v),
.unwrap() exit,
.dateindex )?;
.as_ref() Ok(())
.unwrap(), })?;
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
},
)?;
} }
info!("Computing rest part 2..."); info!("Computing rest part 2...");
@@ -1450,7 +1427,6 @@ impl Vecs {
let dateindex_to_realized_cap_ref = dateindex_to_realized_cap.as_ref(); let dateindex_to_realized_cap_ref = dateindex_to_realized_cap.as_ref();
self.utxo_cohorts.compute_rest_part2( self.utxo_cohorts.compute_rest_part2(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
@@ -1464,7 +1440,6 @@ impl Vecs {
)?; )?;
self.address_cohorts.compute_rest_part2( self.address_cohorts.compute_rest_part2(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
@@ -1655,10 +1630,10 @@ impl Vecs {
&mut self, &mut self,
height: Height, height: Height,
chain_state: &[BlockState], chain_state: &[BlockState],
mut addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree< addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>, WithAddressDataSource<LoadedAddressData>,
>, >,
mut addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree< addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<EmptyAddressData>, WithAddressDataSource<EmptyAddressData>,
>, >,
with_changes: bool, with_changes: bool,
@@ -1667,30 +1642,28 @@ impl Vecs {
info!("Flushing..."); info!("Flushing...");
self.utxo_cohorts self.utxo_cohorts
.as_mut_separate_vecs() .iter_separate_mut()
.par_iter_mut() .par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?; .try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.address_cohorts self.address_cohorts
.as_mut_separate_vecs() .iter_separate_mut()
.par_iter_mut() .par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?; .try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.height_to_unspendable_supply.safe_flush(exit)?; self.height_to_unspendable_supply.safe_flush(exit)?;
self.height_to_opreturn_supply.safe_flush(exit)?; self.height_to_opreturn_supply.safe_flush(exit)?;
self.addresstype_to_height_to_addr_count self.addresstype_to_height_to_addr_count
.as_mut_vec() .iter_mut()
.into_iter()
.try_for_each(|v| v.safe_flush(exit))?; .try_for_each(|v| v.safe_flush(exit))?;
self.addresstype_to_height_to_empty_addr_count self.addresstype_to_height_to_empty_addr_count
.as_mut_vec() .iter_mut()
.into_iter()
.try_for_each(|v| v.safe_flush(exit))?; .try_for_each(|v| v.safe_flush(exit))?;
let mut addresstype_to_typeindex_to_new_or_updated_anyaddressindex = let mut addresstype_to_typeindex_to_new_or_updated_anyaddressindex =
AddressTypeToTypeIndexTree::default(); AddressTypeToTypeIndexTree::default();
addresstype_to_typeindex_to_emptyaddressdata addresstype_to_typeindex_to_emptyaddressdata
.into_typed_vec() .unwrap()
.into_iter() .into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> { .try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each( tree.into_iter().try_for_each(
|(typeindex, emptyaddressdata_with_source)| -> Result<()> { |(typeindex, emptyaddressdata_with_source)| -> Result<()> {
@@ -1742,8 +1715,8 @@ impl Vecs {
})?; })?;
addresstype_to_typeindex_to_loadedaddressdata addresstype_to_typeindex_to_loadedaddressdata
.into_typed_vec() .unwrap()
.into_iter() .into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> { .try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each( tree.into_iter().try_for_each(
|(typeindex, loadedaddressdata_with_source)| -> Result<()> { |(typeindex, loadedaddressdata_with_source)| -> Result<()> {
@@ -1795,8 +1768,8 @@ impl Vecs {
})?; })?;
addresstype_to_typeindex_to_new_or_updated_anyaddressindex addresstype_to_typeindex_to_new_or_updated_anyaddressindex
.into_typed_vec() .unwrap()
.into_iter() .into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> { .try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter() tree.into_iter()
.try_for_each(|(typeindex, anyaddressindex)| -> Result<()> { .try_for_each(|(typeindex, anyaddressindex)| -> Result<()> {
@@ -1864,42 +1837,10 @@ impl Vecs {
Ok(()) 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.utxo_cohorts [
.vecs() &self.height_to_unspendable_supply as &dyn AnyCollectableVec,
.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,
&self.height_to_opreturn_supply, &self.height_to_opreturn_supply,
&self.chain_state, &self.chain_state,
&self.p2pk33addressindex_to_anyaddressindex, &self.p2pk33addressindex_to_anyaddressindex,
@@ -1914,18 +1855,77 @@ impl Vecs {
&self.emptyaddressindex_to_emptyaddressdata, &self.emptyaddressindex_to_emptyaddressdata,
&self.loadedaddressindex_to_loadedaddressindex, &self.loadedaddressindex_to_loadedaddressindex,
&self.emptyaddressindex_to_emptyaddressindex, &self.emptyaddressindex_to_emptyaddressindex,
], ]
] .into_iter(),
.into_iter() );
.flatten()
.collect::<Vec<_>>() 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)> { impl AddressTypeToVec<(TypeIndex, Sats)> {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn process_received( fn process_received(
mut self, self,
vecs: &mut address_cohorts::Vecs, vecs: &mut address_cohorts::Vecs,
addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexTree< addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>, WithAddressDataSource<LoadedAddressData>,
@@ -1940,7 +1940,7 @@ impl AddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>, 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)| { vec.into_iter().for_each(|(type_index, value)| {
let mut is_new = false; let mut is_new = false;
let mut from_any_empty = false; let mut from_any_empty = false;
@@ -2044,7 +2044,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>, WithAddressDataSource<LoadedAddressData>,
>, >,
) -> Result<()> { ) -> 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 let prev_price = height_to_price_close_vec
.as_ref() .as_ref()
.map(|v| **v.get(prev_height.unwrap_to_usize()).unwrap()); .map(|v| **v.get(prev_height.unwrap_to_usize()).unwrap());
@@ -2062,7 +2062,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
.unwrap() .unwrap()
.is_more_than_hour(); .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)| { vec.into_iter().try_for_each(|(type_index, value)| {
let typeindex_to_loadedaddressdata = let typeindex_to_loadedaddressdata =
addresstype_to_typeindex_to_loadedaddressdata addresstype_to_typeindex_to_loadedaddressdata
+1 -6
View File
@@ -1,7 +1,6 @@
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version}; use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Exit}; use vecdb::{AnyIterableVec, Exit};
use crate::{Indexes, indexes, price}; use crate::{Indexes, indexes, price};
@@ -29,14 +28,11 @@ pub trait DynCohortVecs: Send + Sync {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part1( fn compute_rest_part1(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()>; ) -> Result<()>;
fn vecs(&self) -> Vec<&dyn AnyCollectableVec>;
} }
pub trait CohortVecs: DynCohortVecs { pub trait CohortVecs: DynCohortVecs {
@@ -50,7 +46,6 @@ pub trait CohortVecs: DynCohortVecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part2( fn compute_rest_part2(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -1,9 +1,8 @@
use std::{ops::Deref, path::Path}; use std::{ops::Deref, path::Path};
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version}; use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, Format}; use vecdb::{AnyIterableVec, Database, Exit, Format};
use crate::{ use crate::{
Indexes, UTXOCohortState, indexes, price, Indexes, UTXOCohortState, indexes, price,
@@ -122,18 +121,13 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part1( fn compute_rest_part1(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.inner self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit) .compute_rest_part1(indexes, price, starting_indexes, exit)
}
fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
self.inner.vecs()
} }
} }
@@ -154,7 +148,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
fn compute_rest_part2( fn compute_rest_part2(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -167,7 +160,6 @@ impl CohortVecs for Vecs {
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.inner.compute_rest_part2( self.inner.compute_rest_part2(
indexer,
indexes, indexes,
price, price,
starting_indexes, starting_indexes,
+91 -135
View File
@@ -1,7 +1,6 @@
use std::{collections::BTreeMap, ops::ControlFlow, path::Path}; use std::{collections::BTreeMap, ops::ControlFlow, path::Path};
use brk_error::Result; use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{ use brk_structs::{
Bitcoin, ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge, Bitcoin, ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge,
ByMinAge, BySpendableType, ByTerm, CheckedSub, DateIndex, Dollars, GroupFilter, HalvingEpoch, ByMinAge, BySpendableType, ByTerm, CheckedSub, DateIndex, Dollars, GroupFilter, HalvingEpoch,
@@ -1458,8 +1457,7 @@ impl Vecs {
let mut vecs = self let mut vecs = self
.age_range .age_range
.as_mut_vec() .iter_mut()
.into_iter()
.map(|(filter, v)| (filter, &mut v.state)) .map(|(filter, v)| (filter, &mut v.state))
.collect::<Vec<_>>(); .collect::<Vec<_>>();
@@ -1503,9 +1501,8 @@ impl Vecs {
let mut time_based_vecs = self let mut time_based_vecs = self
.0 .0
.age_range .age_range
.as_mut_vec() .iter_mut()
.into_iter() .chain(self.0.epoch.iter_mut())
.chain(self.0.epoch.as_mut_vec())
.collect::<Vec<_>>(); .collect::<Vec<_>>();
let last_timestamp = chain_state.last().unwrap().timestamp; 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( sent.by_type
|(output_type, supply_state)| { .spendable
.iter_typed()
.for_each(|(output_type, supply_state)| {
self.0 self.0
._type ._type
.get_mut(output_type) .get_mut(output_type)
@@ -1568,12 +1567,10 @@ impl Vecs {
days_old_float, days_old_float,
older_than_hour, older_than_hour,
) )
}, });
);
sent.by_size_group sent.by_size_group
.as_typed_vec() .iter_typed()
.into_iter()
.for_each(|(group, supply_state)| { .for_each(|(group, supply_state)| {
self.0 self.0
.amount_range .amount_range
@@ -1606,24 +1603,20 @@ impl Vecs {
v.state.as_mut().unwrap().receive(&supply_state, price); v.state.as_mut().unwrap().receive(&supply_state, price);
}); });
self._type self._type.iter_mut().for_each(|(filter, vecs)| {
.as_mut_vec() let output_type = match filter {
.into_iter() GroupFilter::Type(output_type) => *output_type,
.for_each(|(filter, vecs)| { _ => unreachable!(),
let output_type = match filter { };
GroupFilter::Type(output_type) => *output_type, vecs.state
_ => unreachable!(), .as_mut()
}; .unwrap()
vecs.state .receive(received.by_type.get(output_type), price)
.as_mut() });
.unwrap()
.receive(received.by_type.get(output_type), price)
});
received received
.by_size_group .by_size_group
.as_typed_vec() .iter_typed()
.into_iter()
.for_each(|(group, supply_state)| { .for_each(|(group, supply_state)| {
self.amount_range self.amount_range
.get_mut(group) .get_mut(group)
@@ -1640,95 +1633,64 @@ impl Vecs {
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
let by_date_range = self.0.age_range.as_vec(); let by_date_range = &self.0.age_range;
let by_size_range = self.0.amount_range.as_vec(); 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 by_date_range
.into_iter() .iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v) .map(|(_, v)| v)
.collect::<Vec<_>>(), .collect::<Vec<_>>(),
)], )
self.0 }))
.min_age .chain(self.0.max_age.iter_mut().map(|(filter, vecs)| {
.as_mut_vec() (
.into_iter() vecs,
.map(|(filter, vecs)| { by_date_range
( .iter()
vecs, .filter(|(other, _)| filter.includes(other))
by_date_range .map(|(_, v)| v)
.into_iter() .collect::<Vec<_>>(),
.filter(|(other, _)| filter.includes(other)) )
.map(|(_, v)| v) }))
.collect::<Vec<_>>(), .chain(self.0.term.iter_mut().map(|(filter, vecs)| {
) (
}) vecs,
.collect::<Vec<_>>(), by_date_range
self.0 .iter()
.max_age .filter(|(other, _)| filter.includes(other))
.as_mut_vec() .map(|(_, v)| v)
.into_iter() .collect::<Vec<_>>(),
.map(|(filter, vecs)| { )
( }))
vecs, .chain(self.0.ge_amount.iter_mut().map(|(filter, vecs)| {
by_date_range (
.into_iter() vecs,
.filter(|(other, _)| filter.includes(other)) by_size_range
.map(|(_, v)| v) .iter()
.collect::<Vec<_>>(), .filter(|(other, _)| filter.includes(other))
) .map(|(_, v)| v)
}) .collect::<Vec<_>>(),
.collect::<Vec<_>>(), )
self.0 }))
.term .chain(self.0.lt_amount.iter_mut().map(|(filter, vecs)| {
.as_mut_vec() (
.into_iter() vecs,
.map(|(filter, vecs)| { by_size_range
( .iter()
vecs, .filter(|(other, _)| filter.includes(other))
by_date_range .map(|(_, v)| v)
.into_iter() .collect::<Vec<_>>(),
.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()
.try_for_each(|(vecs, stateful)| { .try_for_each(|(vecs, stateful)| {
vecs.compute_from_stateful(starting_indexes, &stateful, exit) vecs.compute_from_stateful(starting_indexes, &stateful, exit)
}) })
@@ -1736,21 +1698,19 @@ impl Vecs {
pub fn compute_rest_part1( pub fn compute_rest_part1(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| { self.iter_mut()
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit) .into_iter()
}) .try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
} }
#[allow(clippy::too_many_arguments)] #[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2( pub fn compute_rest_part2(
&mut self, &mut self,
indexer: &Indexer,
indexes: &indexes::Vecs, indexes: &indexes::Vecs,
price: Option<&price::Vecs>, price: Option<&price::Vecs>,
starting_indexes: &Indexes, starting_indexes: &Indexes,
@@ -1762,28 +1722,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>, dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit, exit: &Exit,
) -> Result<()> { ) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| { self.iter_mut().into_iter().try_for_each(|(_, v)| {
v.into_iter().try_for_each(|(_, v)| { v.compute_rest_part2(
v.compute_rest_part2( indexes,
indexer, price,
indexes, starting_indexes,
price, height_to_supply,
starting_indexes, dateindex_to_supply,
height_to_supply, height_to_market_cap,
dateindex_to_supply, dateindex_to_market_cap,
height_to_market_cap, height_to_realized_cap,
dateindex_to_market_cap, dateindex_to_realized_cap,
height_to_realized_cap, exit,
dateindex_to_realized_cap, )
exit,
)
})
}) })
} }
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> { 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)) .try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
} }
} }
+6 -3
View File
@@ -23,9 +23,12 @@ pub use indexes::*;
pub use stores::*; pub use stores::*;
pub use vecs::*; pub use vecs::*;
// One version for all data sources
// Increment on change OR addition
const VERSION: Version = Version::new(21);
const SNAPSHOT_BLOCK_RANGE: usize = 1_000; const SNAPSHOT_BLOCK_RANGE: usize = 1_000;
const COLLISIONS_CHECKED_UP_TO: Height = Height::new(909_150); const COLLISIONS_CHECKED_UP_TO: Height = Height::new(909_150);
const VERSION: Version = Version::ONE;
#[derive(Clone)] #[derive(Clone)]
pub struct Indexer { pub struct Indexer {
@@ -39,10 +42,10 @@ impl Indexer {
let path = outputs_dir.join("indexed"); let path = outputs_dir.join("indexed");
let vecs = Vecs::forced_import(&path, VERSION + Version::ZERO)?; let vecs = Vecs::forced_import(&path, VERSION)?;
info!("Imported vecs"); info!("Imported vecs");
let stores = Stores::forced_import(&path, VERSION + Version::ZERO)?; let stores = Stores::forced_import(&path, VERSION)?;
info!("Imported stores"); info!("Imported stores");
Ok(Self { vecs, stores }) Ok(Self { vecs, stores })
+14 -34
View File
@@ -27,8 +27,6 @@ pub struct Stores {
ByAddressType<Store<TypeIndexWithOutputindex, Unit>>, ByAddressType<Store<TypeIndexWithOutputindex, Unit>>,
} }
const VERSION: Version = Version::ZERO;
impl Stores { impl Stores {
pub fn forced_import(parent: &Path, version: Version) -> Result<Self> { pub fn forced_import(parent: &Path, version: Version) -> Result<Self> {
let path = parent.join("stores"); let path = parent.join("stores");
@@ -49,34 +47,21 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"addressbyteshash_to_typeindex", "addressbyteshash_to_typeindex",
version + VERSION + Version::ZERO, version,
None, None,
) )
}); });
let blockhashprefix_to_height = scope.spawn(|| { let blockhashprefix_to_height = scope.spawn(|| {
Store::import( Store::import(&keyspace, &path, "blockhashprefix_to_height", version, None)
&keyspace,
&path,
"blockhashprefix_to_height",
version + VERSION + Version::ZERO,
None,
)
});
let txidprefix_to_txindex = scope.spawn(|| {
Store::import(
&keyspace,
&path,
"txidprefix_to_txindex",
version + VERSION + Version::ZERO,
None,
)
}); });
let txidprefix_to_txindex = scope
.spawn(|| Store::import(&keyspace, &path, "txidprefix_to_txindex", version, None));
let p2aaddressindex_with_outputindex = scope.spawn(|| { let p2aaddressindex_with_outputindex = scope.spawn(|| {
Store::import( Store::import(
&keyspace, &keyspace,
&path, &path,
"p2aaddressindex_with_outputindex", "p2aaddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -85,7 +70,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2pk33addressindex_with_outputindex", "p2pk33addressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -94,7 +79,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2pk65addressindex_with_outputindex", "p2pk65addressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -103,7 +88,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2pkhaddressindex_with_outputindex", "p2pkhaddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -112,7 +97,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2shaddressindex_with_outputindex", "p2shaddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -121,7 +106,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2traddressindex_with_outputindex", "p2traddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -130,7 +115,7 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2wpkhaddressindex_with_outputindex", "p2wpkhaddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
@@ -139,18 +124,13 @@ impl Stores {
&keyspace, &keyspace,
&path, &path,
"p2wshaddressindex_with_outputindex", "p2wshaddressindex_with_outputindex",
version + VERSION + Version::ZERO, version,
Some(false), Some(false),
) )
}); });
let height_to_coinbase_tag = Store::import( let height_to_coinbase_tag =
&keyspace, Store::import(&keyspace, &path, "height_to_coinbase_tag", version, None)?;
&path,
"height_to_coinbase_tag",
version + VERSION + Version::ZERO,
None,
)?;
Ok(Self { Ok(Self {
keyspace: keyspace.clone(), keyspace: keyspace.clone(),
+44 -150
View File
@@ -17,8 +17,6 @@ use vecdb::{
use crate::Indexes; use crate::Indexes;
const VERSION: Version = Version::ZERO;
#[derive(Clone)] #[derive(Clone)]
pub struct Vecs { pub struct Vecs {
db: Database, db: Database,
@@ -78,222 +76,118 @@ impl Vecs {
db.set_min_len(PAGE_SIZE * 50_000_000)?; db.set_min_len(PAGE_SIZE * 50_000_000)?;
let this = Self { let this = Self {
emptyoutputindex_to_txindex: CompressedVec::forced_import( emptyoutputindex_to_txindex: CompressedVec::forced_import(&db, "txindex", version)?,
&db, height_to_blockhash: RawVec::forced_import(&db, "blockhash", version)?,
"txindex", height_to_difficulty: CompressedVec::forced_import(&db, "difficulty", version)?,
version + VERSION + Version::ZERO,
)?,
height_to_blockhash: RawVec::forced_import(
&db,
"blockhash",
version + VERSION + Version::ZERO,
)?,
height_to_difficulty: CompressedVec::forced_import(
&db,
"difficulty",
version + VERSION + Version::ZERO,
)?,
height_to_first_emptyoutputindex: CompressedVec::forced_import( height_to_first_emptyoutputindex: CompressedVec::forced_import(
&db, &db,
"first_emptyoutputindex", "first_emptyoutputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_inputindex: CompressedVec::forced_import( height_to_first_inputindex: CompressedVec::forced_import(
&db, &db,
"first_inputindex", "first_inputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_opreturnindex: CompressedVec::forced_import( height_to_first_opreturnindex: CompressedVec::forced_import(
&db, &db,
"first_opreturnindex", "first_opreturnindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_outputindex: CompressedVec::forced_import( height_to_first_outputindex: CompressedVec::forced_import(
&db, &db,
"first_outputindex", "first_outputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2aaddressindex: CompressedVec::forced_import( height_to_first_p2aaddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2aaddressindex", "first_p2aaddressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2msoutputindex: CompressedVec::forced_import( height_to_first_p2msoutputindex: CompressedVec::forced_import(
&db, &db,
"first_p2msoutputindex", "first_p2msoutputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2pk33addressindex: CompressedVec::forced_import( height_to_first_p2pk33addressindex: CompressedVec::forced_import(
&db, &db,
"first_p2pk33addressindex", "first_p2pk33addressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2pk65addressindex: CompressedVec::forced_import( height_to_first_p2pk65addressindex: CompressedVec::forced_import(
&db, &db,
"first_p2pk65addressindex", "first_p2pk65addressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2pkhaddressindex: CompressedVec::forced_import( height_to_first_p2pkhaddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2pkhaddressindex", "first_p2pkhaddressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2shaddressindex: CompressedVec::forced_import( height_to_first_p2shaddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2shaddressindex", "first_p2shaddressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2traddressindex: CompressedVec::forced_import( height_to_first_p2traddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2traddressindex", "first_p2traddressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2wpkhaddressindex: CompressedVec::forced_import( height_to_first_p2wpkhaddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2wpkhaddressindex", "first_p2wpkhaddressindex",
version + VERSION + Version::ZERO, version,
)?, )?,
height_to_first_p2wshaddressindex: CompressedVec::forced_import( height_to_first_p2wshaddressindex: CompressedVec::forced_import(
&db, &db,
"first_p2wshaddressindex", "first_p2wshaddressindex",
version + VERSION + Version::ZERO, version,
)?,
height_to_first_txindex: CompressedVec::forced_import(
&db,
"first_txindex",
version + VERSION + Version::ZERO,
)?, )?,
height_to_first_txindex: CompressedVec::forced_import(&db, "first_txindex", version)?,
height_to_first_unknownoutputindex: CompressedVec::forced_import( height_to_first_unknownoutputindex: CompressedVec::forced_import(
&db, &db,
"first_unknownoutputindex", "first_unknownoutputindex",
version + VERSION + Version::ZERO, version,
)?,
height_to_timestamp: CompressedVec::forced_import(
&db,
"timestamp",
version + VERSION + Version::ZERO,
)?,
height_to_total_size: CompressedVec::forced_import(
&db,
"total_size",
version + VERSION + Version::ZERO,
)?,
height_to_weight: CompressedVec::forced_import(
&db,
"weight",
version + VERSION + Version::ZERO,
)?,
inputindex_to_outputindex: RawVec::forced_import(
&db,
"outputindex",
version + VERSION + Version::ZERO,
)?,
opreturnindex_to_txindex: CompressedVec::forced_import(
&db,
"txindex",
version + VERSION + Version::ZERO,
)?,
outputindex_to_outputtype: RawVec::forced_import(
&db,
"outputtype",
version + VERSION + Version::ZERO,
)?,
outputindex_to_typeindex: RawVec::forced_import(
&db,
"typeindex",
version + VERSION + Version::ZERO,
)?,
outputindex_to_value: RawVec::forced_import(
&db,
"value",
version + VERSION + Version::ZERO,
)?,
p2aaddressindex_to_p2abytes: RawVec::forced_import(
&db,
"p2abytes",
version + VERSION + Version::ZERO,
)?,
p2msoutputindex_to_txindex: CompressedVec::forced_import(
&db,
"txindex",
version + VERSION + Version::ZERO,
)?,
p2pk33addressindex_to_p2pk33bytes: RawVec::forced_import(
&db,
"p2pk33bytes",
version + VERSION + Version::ZERO,
)?,
p2pk65addressindex_to_p2pk65bytes: RawVec::forced_import(
&db,
"p2pk65bytes",
version + VERSION + Version::ZERO,
)?,
p2pkhaddressindex_to_p2pkhbytes: RawVec::forced_import(
&db,
"p2pkhbytes",
version + VERSION + Version::ZERO,
)?,
p2shaddressindex_to_p2shbytes: RawVec::forced_import(
&db,
"p2shbytes",
version + VERSION + Version::ZERO,
)?,
p2traddressindex_to_p2trbytes: RawVec::forced_import(
&db,
"p2trbytes",
version + VERSION + Version::ZERO,
)?,
p2wpkhaddressindex_to_p2wpkhbytes: RawVec::forced_import(
&db,
"p2wpkhbytes",
version + VERSION + Version::ZERO,
)?,
p2wshaddressindex_to_p2wshbytes: RawVec::forced_import(
&db,
"p2wshbytes",
version + VERSION + Version::ZERO,
)?,
txindex_to_base_size: CompressedVec::forced_import(
&db,
"base_size",
version + VERSION + Version::ZERO,
)?, )?,
height_to_timestamp: CompressedVec::forced_import(&db, "timestamp", version)?,
height_to_total_size: CompressedVec::forced_import(&db, "total_size", version)?,
height_to_weight: CompressedVec::forced_import(&db, "weight", version)?,
inputindex_to_outputindex: RawVec::forced_import(&db, "outputindex", version)?,
opreturnindex_to_txindex: CompressedVec::forced_import(&db, "txindex", version)?,
outputindex_to_outputtype: RawVec::forced_import(&db, "outputtype", version)?,
outputindex_to_typeindex: RawVec::forced_import(&db, "typeindex", version)?,
outputindex_to_value: RawVec::forced_import(&db, "value", version)?,
p2aaddressindex_to_p2abytes: RawVec::forced_import(&db, "p2abytes", version)?,
p2msoutputindex_to_txindex: CompressedVec::forced_import(&db, "txindex", version)?,
p2pk33addressindex_to_p2pk33bytes: RawVec::forced_import(&db, "p2pk33bytes", version)?,
p2pk65addressindex_to_p2pk65bytes: RawVec::forced_import(&db, "p2pk65bytes", version)?,
p2pkhaddressindex_to_p2pkhbytes: RawVec::forced_import(&db, "p2pkhbytes", version)?,
p2shaddressindex_to_p2shbytes: RawVec::forced_import(&db, "p2shbytes", version)?,
p2traddressindex_to_p2trbytes: RawVec::forced_import(&db, "p2trbytes", version)?,
p2wpkhaddressindex_to_p2wpkhbytes: RawVec::forced_import(&db, "p2wpkhbytes", version)?,
p2wshaddressindex_to_p2wshbytes: RawVec::forced_import(&db, "p2wshbytes", version)?,
txindex_to_base_size: CompressedVec::forced_import(&db, "base_size", version)?,
txindex_to_first_inputindex: CompressedVec::forced_import( txindex_to_first_inputindex: CompressedVec::forced_import(
&db, &db,
"first_inputindex", "first_inputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
txindex_to_first_outputindex: CompressedVec::forced_import( txindex_to_first_outputindex: CompressedVec::forced_import(
&db, &db,
"first_outputindex", "first_outputindex",
version + VERSION + Version::ZERO, version,
)?, )?,
txindex_to_is_explicitly_rbf: CompressedVec::forced_import( txindex_to_is_explicitly_rbf: CompressedVec::forced_import(
&db, &db,
"is_explicitly_rbf", "is_explicitly_rbf",
version + VERSION + Version::ZERO, version,
)?,
txindex_to_rawlocktime: CompressedVec::forced_import(
&db,
"rawlocktime",
version + VERSION + Version::ZERO,
)?,
txindex_to_total_size: CompressedVec::forced_import(
&db,
"total_size",
version + VERSION + Version::ZERO,
)?,
txindex_to_txid: RawVec::forced_import(&db, "txid", version + VERSION + Version::ZERO)?,
txindex_to_txversion: CompressedVec::forced_import(
&db,
"txversion",
version + VERSION + Version::ZERO,
)?,
unknownoutputindex_to_txindex: CompressedVec::forced_import(
&db,
"txindex",
version + VERSION + Version::ZERO,
)?, )?,
txindex_to_rawlocktime: CompressedVec::forced_import(&db, "rawlocktime", version)?,
txindex_to_total_size: CompressedVec::forced_import(&db, "total_size", version)?,
txindex_to_txid: RawVec::forced_import(&db, "txid", version)?,
txindex_to_txversion: CompressedVec::forced_import(&db, "txversion", version)?,
unknownoutputindex_to_txindex: CompressedVec::forced_import(&db, "txindex", version)?,
db, db,
}; };
+1
View File
@@ -4,6 +4,7 @@ use serde::Deserialize;
#[allow(clippy::upper_case_acronyms)] #[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, JsonSchema)] #[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Format { pub enum Format {
#[serde(alias = "json")] #[serde(alias = "json")]
JSON, JSON,
+4 -4
View File
@@ -7,8 +7,8 @@ use serde::Deserialize;
#[derive(Debug, Deref, JsonSchema)] #[derive(Debug, Deref, JsonSchema)]
pub struct MaybeIds(Vec<String>); pub struct MaybeIds(Vec<String>);
const MAX_STRING_SIZE: usize = 10_000; const MAX_VECS: usize = 32;
const MAX_VECS: usize = 64; const MAX_STRING_SIZE: usize = 64 * MAX_VECS;
impl From<String> for MaybeIds { impl From<String> for MaybeIds {
fn from(value: String) -> Self { fn from(value: String) -> Self {
@@ -29,7 +29,7 @@ impl<'de> Deserialize<'de> for MaybeIds {
{ {
match serde_json::Value::deserialize(deserializer)? { match serde_json::Value::deserialize(deserializer)? {
serde_json::Value::String(str) => { serde_json::Value::String(str) => {
if str.len() > MAX_STRING_SIZE { if str.len() <= MAX_STRING_SIZE {
Ok(MaybeIds(sanitize_ids( Ok(MaybeIds(sanitize_ids(
str.split(",").map(|s| s.to_string()), str.split(",").map(|s| s.to_string()),
))) )))
@@ -38,7 +38,7 @@ impl<'de> Deserialize<'de> for MaybeIds {
} }
} }
serde_json::Value::Array(vec) => { serde_json::Value::Array(vec) => {
if vec.len() > MAX_VECS { if vec.len() <= MAX_VECS {
Ok(MaybeIds(sanitize_ids( Ok(MaybeIds(sanitize_ids(
vec.into_iter().map(|s| s.as_str().unwrap().to_string()), vec.into_iter().map(|s| s.as_str().unwrap().to_string()),
))) )))
+1
View File
@@ -12,6 +12,7 @@ use schemars::JsonSchema;
use serde::Deserialize; use serde::Deserialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, JsonSchema)] #[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Index { pub enum Index {
#[schemars(description = "Date/day index")] #[schemars(description = "Date/day index")]
DateIndex, DateIndex,
+1 -1
View File
@@ -6,7 +6,7 @@ use tabled::Tabled as TabledTabled;
use crate::Format; use crate::Format;
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(untagged)] #[serde(untagged, rename_all = "lowercase")]
pub enum Output { pub enum Output {
Json(Value), Json(Value),
CSV(String), CSV(String),
+4 -2
View File
@@ -2,8 +2,8 @@ use std::collections::BTreeMap;
use brk_computer::Computer; use brk_computer::Computer;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use vecdb::AnyCollectableVec;
use derive_deref::{Deref, DerefMut}; use derive_deref::{Deref, DerefMut};
use vecdb::AnyCollectableVec;
use crate::pagination::{PaginatedIndexParam, PaginationParam}; use crate::pagination::{PaginatedIndexParam, PaginationParam};
@@ -33,7 +33,9 @@ impl<'a> Vecs<'a> {
.into_iter() .into_iter()
.for_each(|vec| this.insert(vec)); .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<_>>(); let mut ids = this.id_to_index_to_vec.keys().cloned().collect::<Vec<_>>();
+15 -44
View File
@@ -1,7 +1,7 @@
use std::path::Path; use std::path::Path;
use bitcoincore_rpc::{Auth, Client, Result}; use bitcoincore_rpc::{Auth, Client, Result};
use brk_parser::Parser; use brk_parser::{BlockExtended, Parser};
use brk_structs::Height; use brk_structs::Height;
#[allow(clippy::needless_doctest_main)] #[allow(clippy::needless_doctest_main)]
@@ -21,55 +21,26 @@ fn main() -> Result<()> {
let parser = Parser::new(bitcoin_dir.join("blocks"), Some(brk_dir), rpc); let parser = Parser::new(bitcoin_dir.join("blocks"), Some(brk_dir), rpc);
let start = None; // let start = None;
let end = None; // let end = None;
parser // parser
.parse(start, end) // .parse(start, end)
.iter() // .iter()
.for_each(|(height, _block, hash)| { // .for_each(|(height, _block, hash)| {
println!("{height}: {}", hash); // println!("{height}: {}", hash);
}); // });
let block_0 = parser.get(Height::new(0)); let block_0 = parser.get(Height::new(0));
dbg!("{}", block_0.coinbase_tag());
println!(
"{}",
block_0
.txdata
.first()
.unwrap()
.output
.first()
.unwrap()
.script_pubkey
);
let block_158251 = parser.get(Height::new(158251)); let block_158251 = parser.get(Height::new(158251));
println!( dbg!("{}", block_158251.coinbase_tag());
"{}",
block_158251 let block_173195 = parser.get(Height::new(173195));
.txdata dbg!("{}", block_173195.coinbase_tag());
.first()
.unwrap()
.output
.first()
.unwrap()
.script_pubkey
);
let block_840_000 = parser.get(Height::new(840_004)); let block_840_000 = parser.get(Height::new(840_004));
dbg!("{}", block_840_000.coinbase_tag());
println!(
"{}",
block_840_000
.txdata
.first()
.unwrap()
.output
.first()
.unwrap()
.value
);
dbg!(i.elapsed()); dbg!(i.elapsed());
+12 -11
View File
@@ -1,19 +1,20 @@
use std::borrow::Cow;
use bitcoin::Block; use bitcoin::Block;
pub trait BlockExtended { pub trait BlockExtended {
fn coinbase_tag(&self) -> String; fn coinbase_tag(&self) -> Cow<'_, str>;
} }
impl BlockExtended for Block { impl BlockExtended for Block {
fn coinbase_tag(&self) -> String { fn coinbase_tag(&self) -> Cow<'_, str> {
let Some(input) = self.txdata.first().and_then(|tx| tx.input.first()) else { String::from_utf8_lossy(
return String::new(); self.txdata
}; .first()
let bytes = input.script_sig.as_bytes(); .and_then(|tx| tx.input.first())
String::from_utf8_lossy(bytes) .unwrap()
.chars() .script_sig
.filter(|&c| c != '\u{FFFD}' && (c >= ' ' || c == '\n' || c == '\r' || c == '\t')) .as_bytes(),
.take(1_024) )
.collect()
} }
} }
+2
View File
@@ -10,6 +10,8 @@ rust-version.workspace = true
build = "build.rs" build = "build.rs"
[dependencies] [dependencies]
allocative = { workspace = true }
allocative_derive = { workspace = true }
bitcoin = { workspace = true } bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true } bitcoincore-rpc = { workspace = true }
brk_error = {workspace = true} brk_error = {workspace = true}
+12 -31
View File
@@ -8,47 +8,28 @@ pub struct AddressGroups<T> {
} }
impl<T> AddressGroups<T> { impl<T> AddressGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> { pub fn iter_mut(&mut self) -> impl Iterator<Item = &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> {
self.ge_amount self.ge_amount
.as_mut_vec() .iter_mut()
.into_iter() .chain(self.amount_range.iter_mut())
.chain(self.amount_range.as_mut_vec()) .chain(self.lt_amount.iter_mut())
.chain(self.lt_amount.as_mut_vec())
.collect::<Vec<_>>()
} }
pub fn as_mut_separate_vecs(&mut self) -> Vec<&mut T> { pub fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.amount_range self.amount_range.iter_mut()
.as_mut_vec()
.into_iter()
.collect::<Vec<_>>()
} }
pub fn as_mut_overlapping_vecs(&mut self) -> Vec<&mut T> { pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.lt_amount self.lt_amount.iter_mut().chain(self.ge_amount.iter_mut())
.as_mut_vec()
.into_iter()
.chain(self.ge_amount.as_mut_vec())
.collect::<Vec<_>>()
} }
} }
impl<T> AddressGroups<(GroupFilter, T)> { impl<T> AddressGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
self.amount_range self.amount_range
.vecs() .iter_right()
.into_iter() .chain(self.lt_amount.iter_right())
.chain(self.lt_amount.vecs()) .chain(self.ge_amount.iter_right())
.chain(self.ge_amount.vecs())
.collect::<Vec<_>>()
} }
} }
@@ -1,7 +1,4 @@
use std::{ use std::ops::{Add, AddAssign};
mem,
ops::{Add, AddAssign},
};
use super::GroupFilter; use super::GroupFilter;
use crate::OutputType; 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.p2pk65,
&mut self.p2pk33, &mut self.p2pk33,
@@ -62,9 +73,10 @@ impl<T> ByAddressType<T> {
&mut self.p2tr, &mut self.p2tr,
&mut self.p2a, &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::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33), (OutputType::P2PK33, &self.p2pk33),
@@ -75,9 +87,24 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &self.p2tr), (OutputType::P2TR, &self.p2tr),
(OutputType::P2A, &self.p2a), (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::P2PK65, &mut self.p2pk65),
(OutputType::P2PK33, &mut self.p2pk33), (OutputType::P2PK33, &mut self.p2pk33),
@@ -88,27 +115,12 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &mut self.p2tr), (OutputType::P2TR, &mut self.p2tr),
(OutputType::P2A, &mut self.p2a), (OutputType::P2A, &mut self.p2a),
] ]
} .into_iter()
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)),
]
} }
} }
impl<T> ByAddressType<(GroupFilter, T)> { impl<T> ByAddressType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 8] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self.p2pk65.1, &self.p2pk65.1,
&self.p2pk33.1, &self.p2pk33.1,
@@ -119,6 +131,7 @@ impl<T> ByAddressType<(GroupFilter, T)> {
&self.p2tr.1, &self.p2tr.1,
&self.p2a.1, &self.p2a.1,
] ]
.into_iter()
} }
} }
@@ -174,7 +187,7 @@ where
impl<T> ByAddressType<Option<T>> { impl<T> ByAddressType<Option<T>> {
pub fn take(&mut self) { pub fn take(&mut self) {
self.as_mut_vec().into_iter().for_each(|opt| { self.iter_mut().for_each(|opt| {
opt.take(); opt.take();
}); });
} }
@@ -52,7 +52,7 @@ impl<T> From<ByAgeRange<T>> for ByAgeRange<(GroupFilter, T)> {
} }
impl<T> ByAgeRange<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.up_to_1d,
&self._1d_to_1w, &self._1d_to_1w,
@@ -75,9 +75,10 @@ impl<T> ByAgeRange<T> {
&self._12y_to_15y, &self._12y_to_15y,
&self.from_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.up_to_1d,
&mut self._1d_to_1w, &mut self._1d_to_1w,
@@ -100,11 +101,12 @@ impl<T> ByAgeRange<T> {
&mut self._12y_to_15y, &mut self._12y_to_15y,
&mut self.from_15y, &mut self.from_15y,
] ]
.into_iter()
} }
} }
impl<T> ByAgeRange<(GroupFilter, T)> { 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.up_to_1d.1,
&self._1d_to_1w.1, &self._1d_to_1w.1,
@@ -127,5 +129,6 @@ impl<T> ByAgeRange<(GroupFilter, T)> {
&self._12y_to_15y.1, &self._12y_to_15y.1,
&self.from_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._0sats,
&self._1sat_to_10sats, &self._1sat_to_10sats,
@@ -142,9 +142,10 @@ impl<T> ByAmountRange<T> {
&self._10k_btc_to_100k_btc, &self._10k_btc_to_100k_btc,
&self._100k_btc_or_more, &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::ZERO, &self._0sats),
(Sats::_1, &self._1sat_to_10sats), (Sats::_1, &self._1sat_to_10sats),
@@ -162,9 +163,10 @@ impl<T> ByAmountRange<T> {
(Sats::_10K_BTC, &self._10k_btc_to_100k_btc), (Sats::_10K_BTC, &self._10k_btc_to_100k_btc),
(Sats::_100K_BTC, &self._100k_btc_or_more), (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._0sats,
&mut self._1sat_to_10sats, &mut self._1sat_to_10sats,
@@ -182,11 +184,12 @@ impl<T> ByAmountRange<T> {
&mut self._10k_btc_to_100k_btc, &mut self._10k_btc_to_100k_btc,
&mut self._100k_btc_or_more, &mut self._100k_btc_or_more,
] ]
.into_iter()
} }
} }
impl<T> ByAmountRange<(GroupFilter, T)> { impl<T> ByAmountRange<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 15] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self._0sats.1, &self._0sats.1,
&self._1sat_to_10sats.1, &self._1sat_to_10sats.1,
@@ -204,6 +207,7 @@ impl<T> ByAmountRange<(GroupFilter, T)> {
&self._10k_btc_to_100k_btc.1, &self._10k_btc_to_100k_btc.1,
&self._100k_btc_or_more.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> { 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._0,
&mut self._1, &mut self._1,
@@ -32,6 +32,7 @@ impl<T> ByEpoch<T> {
&mut self._3, &mut self._3,
&mut self._4, &mut self._4,
] ]
.into_iter()
} }
pub fn mut_vec_from_height(&mut self, height: Height) -> &mut T { 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)> { impl<T> ByEpoch<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 5] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self._0.1, &self._1.1, &self._2.1, &self._3.1, &self._4.1] [&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> { 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._1sat,
&mut self._10sats, &mut self._10sats,
@@ -36,11 +36,12 @@ impl<T> ByGreatEqualAmount<T> {
&mut self._1k_btc, &mut self._1k_btc,
&mut self._10k_btc, &mut self._10k_btc,
] ]
.into_iter()
} }
} }
impl<T> ByGreatEqualAmount<(GroupFilter, T)> { impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self._1sat.1, &self._1sat.1,
&self._10sats.1, &self._10sats.1,
@@ -56,6 +57,7 @@ impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
&self._1k_btc.1, &self._1k_btc.1,
&self._10k_btc.1, &self._10k_btc.1,
] ]
.into_iter()
} }
} }
@@ -20,7 +20,7 @@ pub struct ByLowerThanAmount<T> {
} }
impl<T> 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._10sats,
&mut self._100sats, &mut self._100sats,
@@ -36,11 +36,12 @@ impl<T> ByLowerThanAmount<T> {
&mut self._10k_btc, &mut self._10k_btc,
&mut self._100k_btc, &mut self._100k_btc,
] ]
.into_iter()
} }
} }
impl<T> ByLowerThanAmount<(GroupFilter, T)> { impl<T> ByLowerThanAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self._10sats.1, &self._10sats.1,
&self._100sats.1, &self._100sats.1,
@@ -56,6 +57,7 @@ impl<T> ByLowerThanAmount<(GroupFilter, T)> {
&self._10k_btc.1, &self._10k_btc.1,
&self._100k_btc.1, &self._100k_btc.1,
] ]
.into_iter()
} }
} }
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMaxAge<T> {
} }
impl<T> 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._1w,
&mut self._1m, &mut self._1m,
@@ -44,11 +44,12 @@ impl<T> ByMaxAge<T> {
&mut self._12y, &mut self._12y,
&mut self._15y, &mut self._15y,
] ]
.into_iter()
} }
} }
impl<T> ByMaxAge<(GroupFilter, T)> { impl<T> ByMaxAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self._1w.1, &self._1w.1,
&self._1m.1, &self._1m.1,
@@ -69,6 +70,7 @@ impl<T> ByMaxAge<(GroupFilter, T)> {
&self._12y.1, &self._12y.1,
&self._15y.1, &self._15y.1,
] ]
.into_iter()
} }
} }
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMinAge<T> {
} }
impl<T> 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._1d,
&mut self._1w, &mut self._1w,
@@ -44,11 +44,12 @@ impl<T> ByMinAge<T> {
&mut self._10y, &mut self._10y,
&mut self._12y, &mut self._12y,
] ]
.into_iter()
} }
} }
impl<T> ByMinAge<(GroupFilter, T)> { impl<T> ByMinAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self._1d.1, &self._1d.1,
&self._1w.1, &self._1w.1,
@@ -69,6 +70,7 @@ impl<T> ByMinAge<(GroupFilter, T)> {
&self._10y.1, &self._10y.1,
&self._12y.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.p2pk65,
&mut self.p2pk33, &mut self.p2pk33,
@@ -51,9 +51,10 @@ impl<T> BySpendableType<T> {
&mut self.unknown, &mut self.unknown,
&mut self.empty, &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::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33), (OutputType::P2PK33, &self.p2pk33),
@@ -67,11 +68,12 @@ impl<T> BySpendableType<T> {
(OutputType::Unknown, &self.unknown), (OutputType::Unknown, &self.unknown),
(OutputType::Empty, &self.empty), (OutputType::Empty, &self.empty),
] ]
.into_iter()
} }
} }
impl<T> BySpendableType<(GroupFilter, T)> { impl<T> BySpendableType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 11] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[ [
&self.p2pk65.1, &self.p2pk65.1,
&self.p2pk33.1, &self.p2pk33.1,
@@ -85,6 +87,7 @@ impl<T> BySpendableType<(GroupFilter, T)> {
&self.unknown.1, &self.unknown.1,
&self.empty.1, &self.empty.1,
] ]
.into_iter()
} }
} }
+4 -4
View File
@@ -7,14 +7,14 @@ pub struct ByTerm<T> {
} }
impl<T> ByTerm<T> { impl<T> ByTerm<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 2] { pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.short, &mut self.long] [&mut self.short, &mut self.long].into_iter()
} }
} }
impl<T> ByTerm<(GroupFilter, T)> { impl<T> ByTerm<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 2] { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.short.1, &self.long.1] [&self.short.1, &self.long.1].into_iter()
} }
} }
+31 -51
View File
@@ -18,72 +18,52 @@ pub struct UTXOGroups<T> {
} }
impl<T> UTXOGroups<T> { impl<T> UTXOGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> { pub fn iter_mut(&mut self) -> impl Iterator<Item = &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> {
[&mut self.all] [&mut self.all]
.into_iter() .into_iter()
.chain(self.term.as_mut_vec()) .chain(self.term.iter_mut())
.chain(self.max_age.as_mut_vec()) .chain(self.max_age.iter_mut())
.chain(self.min_age.as_mut_vec()) .chain(self.min_age.iter_mut())
.chain(self.ge_amount.as_mut_vec()) .chain(self.ge_amount.iter_mut())
.chain(self.age_range.as_mut_vec()) .chain(self.age_range.iter_mut())
.chain(self.epoch.as_mut_vec()) .chain(self.epoch.iter_mut())
.chain(self.amount_range.as_mut_vec()) .chain(self.amount_range.iter_mut())
.chain(self.lt_amount.as_mut_vec()) .chain(self.lt_amount.iter_mut())
.chain(self._type.as_mut_vec()) .chain(self._type.iter_mut())
.collect::<Vec<_>>()
} }
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 self.age_range
.as_mut_vec() .iter_mut()
.into_iter() .chain(self.epoch.iter_mut())
.chain(self.epoch.as_mut_vec()) .chain(self.amount_range.iter_mut())
.chain(self.amount_range.as_mut_vec()) .chain(self._type.iter_mut())
.chain(self._type.as_mut_vec())
.collect::<Vec<_>>()
} }
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] [&mut self.all]
.into_iter() .into_iter()
.chain(self.term.as_mut_vec()) .chain(self.term.iter_mut())
.chain(self.max_age.as_mut_vec()) .chain(self.max_age.iter_mut())
.chain(self.min_age.as_mut_vec()) .chain(self.min_age.iter_mut())
.chain(self.lt_amount.as_mut_vec()) .chain(self.lt_amount.iter_mut())
.chain(self.ge_amount.as_mut_vec()) .chain(self.ge_amount.iter_mut())
.collect::<Vec<_>>()
} }
} }
impl<T> UTXOGroups<(GroupFilter, T)> { impl<T> UTXOGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> { pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.all.1] [&self.all.1]
.into_iter() .into_iter()
.chain(self.term.vecs()) .chain(self.term.iter_right())
.chain(self.max_age.vecs()) .chain(self.max_age.iter_right())
.chain(self.min_age.vecs()) .chain(self.min_age.iter_right())
.chain(self.age_range.vecs()) .chain(self.age_range.iter_right())
.chain(self.epoch.vecs()) .chain(self.epoch.iter_right())
.chain(self.amount_range.vecs()) .chain(self.amount_range.iter_right())
.chain(self._type.vecs()) .chain(self._type.iter_right())
.chain(self.lt_amount.vecs()) .chain(self.lt_amount.iter_right())
.chain(self.ge_amount.vecs()) .chain(self.ge_amount.iter_right())
.collect::<Vec<_>>()
} }
} }
@@ -25,6 +25,25 @@ pub enum AddressBytes {
P2A(P2ABytes), P2A(P2ABytes),
} }
impl fmt::Display for AddressBytes {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(
f,
"{}",
match self {
AddressBytes::P2PK65(bytes) => bytes.to_string(),
AddressBytes::P2PK33(bytes) => bytes.to_string(),
AddressBytes::P2PKH(bytes) => bytes.to_string(),
AddressBytes::P2SH(bytes) => bytes.to_string(),
AddressBytes::P2WPKH(bytes) => bytes.to_string(),
AddressBytes::P2WSH(bytes) => bytes.to_string(),
AddressBytes::P2TR(bytes) => bytes.to_string(),
AddressBytes::P2A(bytes) => bytes.to_string(),
}
)
}
}
impl AddressBytes { impl AddressBytes {
pub fn as_slice(&self) -> &[u8] { pub fn as_slice(&self) -> &[u8] {
match self { match self {
@@ -44,6 +44,7 @@ impl Serialize for AnyAddressIndex {
} }
#[derive(Debug, Serialize)] #[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum AnyAddressDataIndexEnum { pub enum AnyAddressDataIndexEnum {
Loaded(LoadedAddressIndex), Loaded(LoadedAddressIndex),
Empty(EmptyAddressIndex), Empty(EmptyAddressIndex),
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div, Mul}, ops::{Add, AddAssign, Div, Mul},
}; };
use allocative::Allocative;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, StoredCompressed}; use vecdb::{CheckedSub, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -20,6 +21,7 @@ use super::{Sats, StoredF64};
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct Bitcoin(f64); pub struct Bitcoin(f64);
@@ -132,3 +134,8 @@ impl CheckedSub<usize> for Bitcoin {
Some(Self(self.0 - rhs as f64)) 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 serde::{Serialize, Serializer};
use vecdb::StoredCompressed; use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::ONE_DAY_IN_SEC_F64;
use super::{DateIndex, Timestamp}; use super::{DateIndex, Timestamp};
#[derive( #[derive(
@@ -51,6 +53,21 @@ impl Date {
pub fn today() -> Self { pub fn today() -> Self {
Self::from(Timestamp::now()) 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 { 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 { impl From<Timestamp> for Date {
fn from(value: Timestamp) -> Self { fn from(value: Timestamp) -> Self {
Self::from(Date_::from( Self::from(Date_::from(
+3 -1
View File
@@ -3,10 +3,11 @@ use std::{
ops::{Add, Rem}, ops::{Add, Rem},
}; };
use allocative::Allocative;
use brk_error::Error; use brk_error::Error;
use vecdb::{CheckedSub, FromCoarserIndex, Printable, StoredCompressed};
use jiff::Span; use jiff::Span;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, FromCoarserIndex, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, WeekIndex, YearIndex}; use crate::{DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, WeekIndex, YearIndex};
@@ -28,6 +29,7 @@ use super::Date;
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct DateIndex(u16); pub struct DateIndex(u16);
@@ -3,8 +3,9 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use vecdb::{CheckedSub, Printable, StoredCompressed}; use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Date, DateIndex, YearIndex}; use super::{Date, DateIndex, YearIndex};
@@ -25,6 +26,7 @@ use super::{Date, DateIndex, YearIndex};
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct DecadeIndex(u16); pub struct DecadeIndex(u16);
@@ -3,12 +3,15 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height; use super::Height;
pub const BLOCKS_PER_DIFF_EPOCHS: u32 = 2016;
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
@@ -25,6 +28,7 @@ use super::Height;
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct DifficultyEpoch(u16); pub struct DifficultyEpoch(u16);
@@ -77,7 +81,7 @@ impl Div<usize> for DifficultyEpoch {
impl From<Height> for DifficultyEpoch { impl From<Height> for DifficultyEpoch {
fn from(value: Height) -> Self { fn from(value: Height) -> Self {
Self((u32::from(value) / 2016) as u16) Self((u32::from(value) / BLOCKS_PER_DIFF_EPOCHS) as u16)
} }
} }
+28 -4
View File
@@ -1,14 +1,18 @@
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
f64, f64,
iter::Sum,
ops::{Add, AddAssign, Div, Mul}, ops::{Add, AddAssign, Div, Mul},
}; };
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, StoredCompressed}; use vecdb::{CheckedSub, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Low, Open};
use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64}; use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64};
#[derive( #[derive(
@@ -24,6 +28,7 @@ use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64};
Serialize, Serialize,
Deserialize, Deserialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct Dollars(f64); pub struct Dollars(f64);
@@ -78,15 +83,27 @@ impl From<Dollars> for f64 {
} }
} }
impl From<Close<Dollars>> for Dollars { impl From<Open<Dollars>> for Dollars {
fn from(value: Close<Dollars>) -> Self { fn from(value: Open<Dollars>) -> Self {
Self(value.0) *value
} }
} }
impl From<High<Dollars>> for Dollars { impl From<High<Dollars>> for Dollars {
fn from(value: High<Dollars>) -> Self { 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
} }
} }
@@ -362,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)
}
}
+11 -1
View File
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use serde::Serialize; use serde::Serialize;
use vecdb::StoredCompressed; use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -10,7 +11,16 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Sats, StoredU64}; use super::{Sats, StoredU64};
#[derive( #[derive(
Debug, Clone, Copy, Serialize, FromBytes, Immutable, IntoBytes, KnownLayout, StoredCompressed, Debug,
Clone,
Copy,
Serialize,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)] )]
pub struct FeeRate(f64); pub struct FeeRate(f64);
@@ -3,12 +3,15 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height; use super::Height;
pub const BLOCKS_PER_HALVING: u32 = 210_000;
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
@@ -25,6 +28,7 @@ use super::Height;
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct HalvingEpoch(u16); pub struct HalvingEpoch(u16);
@@ -76,7 +80,7 @@ impl Add<usize> for HalvingEpoch {
impl From<Height> for HalvingEpoch { impl From<Height> for HalvingEpoch {
fn from(value: Height) -> Self { fn from(value: Height) -> Self {
Self((u32::from(value) / 210_000) as u16) Self((u32::from(value) / BLOCKS_PER_HALVING) as u16)
} }
} }
+11 -1
View File
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Rem}, ops::{Add, AddAssign, Rem},
}; };
use allocative::Allocative;
use bitcoincore_rpc::{Client, RpcApi}; use bitcoincore_rpc::{Client, RpcApi};
use byteview::ByteView; use byteview::ByteView;
use derive_deref::Deref; use derive_deref::Deref;
@@ -11,7 +12,7 @@ use vecdb::{CheckedSub, Printable, Stamp, StoredCompressed};
use zerocopy::{FromBytes, IntoBytes}; use zerocopy::{FromBytes, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; 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; use super::StoredU64;
@@ -32,6 +33,7 @@ use super::StoredU64;
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct Height(u32); pub struct Height(u32);
@@ -70,6 +72,14 @@ impl Height {
pub fn is_not_zero(self) -> bool { pub fn is_not_zero(self) -> bool {
self != Self::ZERO 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 { impl PartialEq<u64> for Height {
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign}; use std::ops::{Add, AddAssign};
use allocative::Allocative;
use derive_deref::{Deref, DerefMut}; use derive_deref::{Deref, DerefMut};
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -24,6 +25,7 @@ use super::Vin;
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct InputIndex(u64); pub struct InputIndex(u64);
+3 -1
View File
@@ -3,8 +3,9 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use vecdb::{CheckedSub, Printable, StoredCompressed}; use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Date, DateIndex, YearIndex}; use super::{Date, DateIndex, YearIndex};
@@ -25,6 +26,7 @@ use super::{Date, DateIndex, YearIndex};
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct MonthIndex(u16); pub struct MonthIndex(u16);
+40
View File
@@ -3,11 +3,14 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use derive_deref::{Deref, DerefMut}; use derive_deref::{Deref, DerefMut};
use serde::{Serialize, Serializer, ser::SerializeTuple}; use serde::{Serialize, Serializer, ser::SerializeTuple};
use vecdb::StoredCompressed; use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::StoredF64;
use super::{Cents, Dollars, Sats}; use super::{Cents, Dollars, Sats};
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)] #[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
@@ -216,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> impl<T> From<Close<T>> for Open<T>
where where
T: Copy, T: Copy,
@@ -314,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> impl<T> From<Close<T>> for High<T>
where where
T: Copy, T: Copy,
@@ -412,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> impl<T> From<Close<T>> for Low<T>
where where
T: Copy, T: Copy,
@@ -473,6 +503,7 @@ where
DerefMut, DerefMut,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
#[repr(transparent)] #[repr(transparent)]
pub struct Close<T>(T); pub struct Close<T>(T);
@@ -528,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> // impl<A, B> From<Close<A>> for Close<B>
// where // where
// B: From<A>, // B: From<A>,
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign}; use std::ops::{Add, AddAssign};
use allocative::Allocative;
use derive_deref::{Deref, DerefMut}; use derive_deref::{Deref, DerefMut};
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -26,6 +27,7 @@ use super::Vout;
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct OutputIndex(u64); pub struct OutputIndex(u64);
@@ -16,6 +16,7 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
KnownLayout, KnownLayout,
Serialize, Serialize,
)] )]
#[serde(rename_all = "lowercase")]
#[repr(u8)] #[repr(u8)]
pub enum OutputType { pub enum OutputType {
P2PK65, P2PK65,
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -25,6 +26,7 @@ use super::MonthIndex;
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct QuarterIndex(u16); pub struct QuarterIndex(u16);
+2
View File
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div, Mul, SubAssign}, ops::{Add, AddAssign, Div, Mul, SubAssign},
}; };
use allocative::Allocative;
use bitcoin::Amount; use bitcoin::Amount;
use derive_deref::Deref; use derive_deref::Deref;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@@ -30,6 +31,7 @@ use super::{Bitcoin, Cents, Dollars, Height};
Serialize, Serialize,
Deserialize, Deserialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct Sats(u64); pub struct Sats(u64);
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div}, ops::{Add, AddAssign, Div},
}; };
use allocative::Allocative;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -25,6 +26,7 @@ use super::MonthIndex;
IntoBytes, IntoBytes,
KnownLayout, KnownLayout,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct SemesterIndex(u16); pub struct SemesterIndex(u16);
@@ -1,3 +1,4 @@
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{Printable, StoredCompressed}; use vecdb::{Printable, StoredCompressed};
@@ -19,6 +20,7 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredBool(u16); pub struct StoredBool(u16);
@@ -6,11 +6,14 @@ use std::{
ops::{Add, AddAssign, Div, Mul, Sub}, ops::{Add, AddAssign, Div, Mul, Sub},
}; };
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Close, StoredU32};
use super::{Dollars, StoredF64}; use super::{Dollars, StoredF64};
#[derive( #[derive(
@@ -25,6 +28,7 @@ use super::{Dollars, StoredF64};
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredF32(f32); pub struct StoredF32(f32);
@@ -65,12 +69,24 @@ impl From<usize> for StoredF32 {
} }
} }
impl From<StoredU32> for StoredF32 {
fn from(value: StoredU32) -> Self {
Self(f32::from(value))
}
}
impl CheckedSub<StoredF32> for StoredF32 { impl CheckedSub<StoredF32> for StoredF32 {
fn checked_sub(self, rhs: Self) -> Option<Self> { fn checked_sub(self, rhs: Self) -> Option<Self> {
Some(Self(self.0 - rhs.0)) Some(Self(self.0 - rhs.0))
} }
} }
impl CheckedSub<usize> for StoredF32 {
fn checked_sub(self, rhs: usize) -> Option<Self> {
Some(Self(self.0 - rhs as f32))
}
}
impl Div<usize> for StoredF32 { impl Div<usize> for StoredF32 {
type Output = Self; type Output = Self;
fn div(self, rhs: usize) -> Self::Output { fn div(self, rhs: usize) -> Self::Output {
@@ -78,6 +94,13 @@ impl Div<usize> for StoredF32 {
} }
} }
impl Div<StoredU32> for StoredF32 {
type Output = Self;
fn div(self, rhs: StoredU32) -> Self::Output {
Self(self.0 / f32::from(rhs))
}
}
impl Add for StoredF32 { impl Add for StoredF32 {
type Output = Self; type Output = Self;
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
@@ -103,6 +126,12 @@ impl From<Dollars> for StoredF32 {
} }
} }
impl From<Close<Dollars>> for StoredF32 {
fn from(value: Close<Dollars>) -> Self {
Self::from(*value)
}
}
impl Div<Dollars> for StoredF32 { impl Div<Dollars> for StoredF32 {
type Output = Self; type Output = Self;
fn div(self, rhs: Dollars) -> Self::Output { fn div(self, rhs: Dollars) -> Self::Output {
@@ -124,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 { impl Mul<StoredF32> for usize {
type Output = StoredF32; type Output = StoredF32;
fn mul(self, rhs: StoredF32) -> Self::Output { fn mul(self, rhs: StoredF32) -> Self::Output {
@@ -1,9 +1,11 @@
use std::{ use std::{
cmp::Ordering, cmp::Ordering,
f64, f64,
iter::Sum,
ops::{Add, AddAssign, Div, Mul}, ops::{Add, AddAssign, Div, Mul},
}; };
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -23,6 +25,7 @@ use crate::{Bitcoin, Dollars};
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredF64(f64); pub struct StoredF64(f64);
@@ -61,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 { impl Div<usize> for StoredF64 {
type Output = Self; type Output = Self;
fn div(self, rhs: usize) -> Self::Output { fn div(self, rhs: usize) -> Self::Output {
@@ -75,6 +92,13 @@ impl Div<StoredF64> for StoredF64 {
} }
} }
impl Div<Dollars> for StoredF64 {
type Output = Self;
fn div(self, rhs: Dollars) -> Self::Output {
Self::from(self.0 / *rhs)
}
}
impl Add for StoredF64 { impl Add for StoredF64 {
type Output = Self; type Output = Self;
fn add(self, rhs: Self) -> Self::Output { fn add(self, rhs: Self) -> Self::Output {
@@ -159,3 +183,16 @@ impl Printable for StoredF64 {
&["f64"] &["f64"]
} }
} }
impl Sum for StoredF64 {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
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))
}
}
@@ -1,3 +1,5 @@
use std::borrow::Cow;
use byteview::ByteView; use byteview::ByteView;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
@@ -26,6 +28,12 @@ impl From<String> for StoredString {
} }
} }
impl From<Cow<'_, str>> for StoredString {
fn from(value: Cow<'_, str>) -> Self {
Self(value.to_string())
}
}
impl From<ByteView> for StoredString { impl From<ByteView> for StoredString {
fn from(value: ByteView) -> Self { fn from(value: ByteView) -> Self {
let bytes = &*value; let bytes = &*value;
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div}; use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -27,11 +28,13 @@ use super::{
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredU16(u16); pub struct StoredU16(u16);
impl StoredU16 { impl StoredU16 {
pub const ZERO: Self = Self(0); pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
pub fn new(v: u16) -> Self { pub fn new(v: u16) -> Self {
Self(v) Self(v)
+34 -1
View File
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div}; use std::ops::{Add, AddAssign, Div, Mul};
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -27,15 +28,21 @@ use super::{
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredU32(u32); pub struct StoredU32(u32);
impl StoredU32 { impl StoredU32 {
pub const ZERO: Self = Self(0); pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
pub fn new(counter: u32) -> Self { pub fn new(counter: u32) -> Self {
Self(counter) Self(counter)
} }
pub fn is_zero(&self) -> bool {
self.0 == 0
}
} }
impl From<u32> for StoredU32 { impl From<u32> for StoredU32 {
@@ -44,6 +51,12 @@ impl From<u32> for StoredU32 {
} }
} }
impl From<StoredU32> for f32 {
fn from(value: StoredU32) -> Self {
value.0 as f32
}
}
impl From<usize> for StoredU32 { impl From<usize> for StoredU32 {
fn from(value: usize) -> Self { fn from(value: usize) -> Self {
if value > u32::MAX as usize { if value > u32::MAX as usize {
@@ -59,6 +72,15 @@ impl CheckedSub<StoredU32> for StoredU32 {
} }
} }
impl CheckedSub<usize> for StoredU32 {
fn checked_sub(self, rhs: usize) -> Option<Self> {
if rhs > u32::MAX as usize {
panic!()
}
self.0.checked_sub(rhs as u32).map(Self)
}
}
impl Div<usize> for StoredU32 { impl Div<usize> for StoredU32 {
type Output = Self; type Output = Self;
fn div(self, rhs: usize) -> Self::Output { fn div(self, rhs: usize) -> Self::Output {
@@ -79,6 +101,17 @@ impl AddAssign for StoredU32 {
} }
} }
impl Mul<usize> for StoredU32 {
type Output = Self;
fn mul(self, rhs: usize) -> Self::Output {
let res = self.0 as usize * rhs;
if res > u32::MAX as usize {
panic!()
}
Self::from(res)
}
}
impl From<f64> for StoredU32 { impl From<f64> for StoredU32 {
fn from(value: f64) -> Self { fn from(value: f64) -> Self {
if value < 0.0 || value > u32::MAX as f64 { if value < 0.0 || value > u32::MAX as f64 {
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div}; use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed}; use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -28,6 +29,7 @@ use super::{
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct StoredU64(u64); pub struct StoredU64(u64);
+5 -11
View File
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div}; use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref; use derive_deref::Deref;
use jiff::{civil::date, tz::TimeZone}; use jiff::{civil::date, tz::TimeZone};
use serde::Serialize; use serde::Serialize;
@@ -23,12 +24,13 @@ use super::Date;
KnownLayout, KnownLayout,
Serialize, Serialize,
StoredCompressed, StoredCompressed,
Allocative,
)] )]
pub struct Timestamp(u32); pub struct Timestamp(u32);
const ONE_HOUR_IN_SEC: u32 = 60 * 60; pub const ONE_HOUR_IN_SEC: u32 = 60 * 60;
const ONE_DAY_IN_SEC: u32 = 24 * 60 * 60; pub 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_DAY_IN_SEC_F64: f64 = ONE_DAY_IN_SEC as f64;
impl Timestamp { impl Timestamp {
pub const ZERO: Self = Self(0); pub const ZERO: Self = Self(0);
@@ -73,14 +75,6 @@ impl Timestamp {
pub fn now() -> Self { pub fn now() -> Self {
Self::from(jiff::Timestamp::now()) 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 { impl From<u32> for Timestamp {

Some files were not shown because too many files have changed in this diff Show More