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
# failing. otherwise `sh` won't catch that `curl` returned non-0
shell: bash
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.29.0/cargo-dist-installer.sh | sh"
run: "curl --proto '=https' --tlsv1.2 -LsSf https://github.com/axodotdev/cargo-dist/releases/download/v0.30.0/cargo-dist-installer.sh | sh"
- name: Cache dist
uses: actions/upload-artifact@v4
with:
+1 -1
View File
@@ -4,7 +4,7 @@
# Builds
target
websites/dist
vecid-to-indexes.js
bridge/
/ids.txt
# 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.license = "MIT"
package.edition = "2024"
package.version = "0.0.98"
package.version = "0.0.107"
package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md"
package.rust-version = "1.89"
[profile.dev]
lto = "thin"
debug = true
codegen-units = 1
opt-level = 3
overflow-checks = true
[profile.release]
lto = "fat"
codegen-units = 1
panic = "abort"
strip = true
overflow-checks = false
[profile.profiling]
inherits = "release"
@@ -22,23 +31,36 @@ debug = true
[profile.dist]
inherits = "release"
[profile.clippy]
inherits = "dev"
lto = "off"
codegen-units = 256
opt-level = 0
incremental = true
debug = false
overflow-checks = false
panic = "abort"
debug-assertions = false
[workspace.dependencies]
allocative = { version = "0.3.4", features = ["parking_lot"] }
allocative_derive = "0.3.3"
axum = "0.8.4"
bitcoin = { version = "0.32.7", features = ["serde"] }
bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.98", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.98", path = "crates/brk_cli" }
brk_computer = { version = "0.0.98", path = "crates/brk_computer" }
brk_error = { version = "0.0.98", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.98", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.98", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.98", path = "crates/brk_interface" }
brk_logger = { version = "0.0.98", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.98", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.98", path = "crates/brk_parser" }
brk_server = { version = "0.0.98", path = "crates/brk_server" }
brk_store = { version = "0.0.98", path = "crates/brk_store" }
brk_structs = { version = "0.0.98", path = "crates/brk_structs" }
brk_bundler = { version = "0.0.107", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.107", path = "crates/brk_cli" }
brk_computer = { version = "0.0.107", path = "crates/brk_computer" }
brk_error = { version = "0.0.107", path = "crates/brk_error" }
brk_fetcher = { version = "0.0.107", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.107", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.107", path = "crates/brk_interface" }
brk_logger = { version = "0.0.107", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.107", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.107", path = "crates/brk_parser" }
brk_server = { version = "0.0.107", path = "crates/brk_server" }
brk_store = { version = "0.0.107", path = "crates/brk_store" }
brk_structs = { version = "0.0.107", path = "crates/brk_structs" }
byteview = "=0.6.1"
derive_deref = "1.1.1"
fjall = "2.11.2"
@@ -54,9 +76,9 @@ serde_derive = "1.0.219"
serde_json = { version = "1.0.143", features = ["float_roundtrip"] }
tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"]}
vecdb = { version = "0.2.9", features = ["derive"]}
zerocopy = "0.8.26"
zerocopy-derive = "0.8.26"
vecdb = { version = "0.2.14", features = ["derive"]}
zerocopy = "0.8.27"
zerocopy-derive = "0.8.27"
[workspace.metadata.release]
shared-version = true
@@ -65,7 +87,7 @@ pre-release-commit-message = "release: v{{version}}"
tag-message = "release: v{{version}}"
[workspace.metadata.dist]
cargo-dist-version = "0.29.0"
cargo-dist-version = "0.30.0"
ci = "github"
allow-dirty = ["ci"]
installers = []
+1 -3
View File
@@ -64,11 +64,9 @@
- miners
- maybe xpubs
- charts
- improve some names and colors
- remove `sum` series when it's a duplicate of the `base` (in subsidy for example)
- improve names and colors
- selected unit sometimes changes when going back end forth
- 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)
- table
- pagination
+1 -1
View File
@@ -12,7 +12,7 @@ build = "build.rs"
[dependencies]
log = { workspace = true }
notify = "8.2.0"
brk_rolldown = "0.1.4"
brk_rolldown = "0.1.5"
# brk_rolldown = { path = "../../../rolldown/crates/rolldown"}
sugar_path = "1.2.0"
tokio = { workspace = true }
+3 -1
View File
@@ -35,7 +35,9 @@ pub async fn bundle(websites_path: &Path, source_folder: &str, watch: bool) -> i
..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_clone = absolute_source_index_path.clone();
+1 -1
View File
@@ -28,7 +28,7 @@ minreq = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true }
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]]
name = "brk"
+98 -55
View File
@@ -1,19 +1,20 @@
use std::{fs, io, path::Path};
use brk_computer::pools;
use brk_interface::{Index, Interface};
use brk_server::VERSION;
use crate::website::Website;
const SCRIPTS: &str = "scripts";
const BRIDGE_PATH: &str = "scripts/bridge";
#[allow(clippy::upper_case_acronyms)]
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> {
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() {
return Ok(());
}
@@ -24,88 +25,130 @@ impl Bridge for Interface<'static> {
return Ok(());
}
let path = path.join(SCRIPTS);
let path = path.join(BRIDGE_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
//
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()
.enumerate()
.map(|(i_of_i, i)| {
// let lowered = i.to_string().to_lowercase();
format!("/** @typedef {{{i_of_i}}} {i} */",)
})
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join("\n");
.join(" | ")
);
contents += &format!(
"\n\n/** @typedef {{{}}} Index */\n",
indexes
.iter()
.map(|i| i.to_string())
.collect::<Vec<_>>()
.join(" | ")
);
contents += "
contents += "
/** @typedef {ReturnType<typeof createIndexes>} Indexes */
export function createIndexes() {
return {
return {
";
contents += &indexes
.iter()
.enumerate()
.map(|(i_of_i, i)| {
let lowered = i.to_string().to_lowercase();
format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",)
})
.collect::<Vec<_>>()
.join("\n");
contents += &indexes
.iter()
.enumerate()
.map(|(i_of_i, i)| {
let lowered = i.to_string().to_lowercase();
format!(" {lowered}: /** @satisfies {{{i}}} */ ({i_of_i}),",)
})
.collect::<Vec<_>>()
.join("\n");
contents += " };\n}\n";
contents += " };\n}\n";
contents += "
contents += "
/** @typedef {ReturnType<typeof createVecIdToIndexes>} VecIdToIndexes
/** @typedef {keyof VecIdToIndexes} VecId */
/**
* @returns {Record<any, number[]>}
*/
* @returns {Record<any, number[]>}
*/
export function createVecIdToIndexes() {
return {
return {
";
self.id_to_index_to_vec()
.iter()
.for_each(|(id, index_to_vec)| {
let indexes = index_to_vec
.keys()
.map(|i| (*i as u8).to_string())
// .map(|i| i.to_string())
.collect::<Vec<_>>()
.join(", ");
interface
.id_to_index_to_vec()
.iter()
.for_each(|(id, index_to_vec)| {
let indexes = index_to_vec
.keys()
.map(|i| (*i as u8).to_string())
// .map(|i| i.to_string())
.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 brk_fetcher::Fetcher;
use clap::Parser;
use clap_derive::Parser;
use color_eyre::eyre::eyre;
use serde::{Deserialize, Deserializer, Serialize};
+3 -1
View File
@@ -107,7 +107,7 @@ pub fn run() -> color_eyre::Result<()> {
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?)
} else {
@@ -135,6 +135,8 @@ pub fn run() -> color_eyre::Result<()> {
let starting_indexes =
indexer.index(&parser, rpc, &exit, config.check_collisions()).unwrap();
// dbg!(&starting_indexes);
computer.compute(&indexer, starting_indexes, &exit).unwrap();
info!("Waiting for new blocks...");
+1
View File
@@ -2,6 +2,7 @@ use clap_derive::ValueEnum;
use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize, ValueEnum)]
#[serde(rename_all = "lowercase")]
pub enum Website {
None,
Bitview,
+6
View File
@@ -10,6 +10,8 @@ rust-version.workspace = true
build = "build.rs"
[dependencies]
allocative = { workspace = true }
allocative_derive = { workspace = true }
bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true }
brk_structs = { workspace = true }
@@ -17,14 +19,18 @@ brk_error = { workspace = true }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_logger = { workspace = true }
brk_store = { workspace = true }
brk_parser = { workspace = true }
vecdb = { workspace = true }
derive_deref = { workspace = true }
inferno = "0.12.3"
jiff = { workspace = true }
log = { workspace = true }
num_enum = "0.7.4"
pco = "0.4.6"
rayon = { workspace = true }
serde = { workspace = true }
serde_json = { workspace = true }
zerocopy = { 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_fetcher::Fetcher;
use brk_indexer::Indexer;
use vecdb::Exit;
use brk_structs::{AddressBytes, OutputIndex, OutputType};
use vecdb::{AnyIterableVec, Exit, VecIterator};
fn main() -> Result<()> {
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 height_to_first_txindex_iter = indexer.vecs.height_to_first_txindex.iter();
// let mut i = indexer.vecs.txz
let vecs = indexer.vecs;
let stores = indexer.stores;
indexer
.stores
let mut height_to_first_txindex_iter = vecs.height_to_first_txindex.iter();
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
.iter()
.for_each(|(_, coinbase_tag)| {
let pool = pools.find_from_coinbase_tag(&coinbase_tag);
if let Some(pool) = pool {
*res.entry(pool.name).or_default() += 1;
} else {
*res.entry(pools.get_unknown().name).or_default() += 1;
}
.for_each(|(height, coinbase_tag)| {
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| 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<_>>();
File diff suppressed because it is too large Load Diff
+211 -190
View File
@@ -1,10 +1,11 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF64, Version};
use brk_structs::{Bitcoin, CheckedSub, Dollars, StoredF32, StoredF64, Version};
use vecdb::{AnyCollectableVec, Database, Exit, PAGE_SIZE, VecIterator};
use crate::grouped::ComputedVecsFromDateIndex;
use super::{
Indexes, chain,
grouped::{
@@ -14,8 +15,6 @@ use super::{
indexes, price, stateful,
};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Vecs {
db: Database,
@@ -43,27 +42,32 @@ pub struct Vecs {
pub indexes_to_cointime_price: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_cap: ComputedVecsFromHeight<Dollars>,
pub indexes_to_cointime_price_ratio: ComputedRatioVecsFromDateIndex,
pub indexes_to_cointime_adj_inflation_rate: ComputedVecsFromDateIndex<StoredF32>,
pub indexes_to_cointime_adj_tx_btc_velocity: ComputedVecsFromDateIndex<StoredF64>,
pub indexes_to_cointime_adj_tx_usd_velocity: ComputedVecsFromDateIndex<StoredF64>,
// pub indexes_to_thermo_cap_rel_to_investor_cap: ComputedValueVecsFromHeight,
}
impl Vecs {
pub fn forced_import(
parent: &Path,
version: Version,
parent_path: &Path,
parent_version: Version,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
) -> Result<Self> {
let db = Database::open(&parent.join("cointime"))?;
let db = Database::open(&parent_path.join("cointime"))?;
db.set_min_len(PAGE_SIZE * 1_000_000)?;
let compute_dollars = price.is_some();
let version = parent_version + Version::ZERO;
let this = Self {
indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import(
&db,
"coinblocks_created",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -71,7 +75,7 @@ impl Vecs {
&db,
"coinblocks_stored",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -79,7 +83,7 @@ impl Vecs {
&db,
"liveliness",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -87,7 +91,7 @@ impl Vecs {
&db,
"vaultedness",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -95,7 +99,7 @@ impl Vecs {
&db,
"activity_to_vaultedness_ratio",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -103,7 +107,7 @@ impl Vecs {
&db,
"vaulted_supply",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
@@ -112,7 +116,7 @@ impl Vecs {
&db,
"active_supply",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
@@ -121,7 +125,7 @@ impl Vecs {
&db,
"thermo_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -129,7 +133,7 @@ impl Vecs {
&db,
"investor_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -137,7 +141,7 @@ impl Vecs {
&db,
"vaulted_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -145,7 +149,7 @@ impl Vecs {
&db,
"active_cap",
Source::Compute,
version + VERSION + Version::ONE,
version + Version::ONE,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -153,7 +157,7 @@ impl Vecs {
&db,
"vaulted_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -161,7 +165,7 @@ impl Vecs {
&db,
"vaulted_price",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -169,7 +173,7 @@ impl Vecs {
&db,
"active_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -177,7 +181,7 @@ impl Vecs {
&db,
"active_price",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -185,7 +189,7 @@ impl Vecs {
&db,
"true_market_mean",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -193,7 +197,7 @@ impl Vecs {
&db,
"true_market_mean",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
@@ -201,7 +205,7 @@ impl Vecs {
&db,
"cointime_value_destroyed",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -209,7 +213,7 @@ impl Vecs {
&db,
"cointime_value_created",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -217,7 +221,7 @@ impl Vecs {
&db,
"cointime_value_stored",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
@@ -225,7 +229,7 @@ impl Vecs {
&db,
"cointime_price",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -233,7 +237,7 @@ impl Vecs {
&db,
"cointime_cap",
Source::Compute,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
@@ -241,17 +245,40 @@ impl Vecs {
&db,
"cointime_price",
Source::None,
version + VERSION + Version::ZERO,
version + Version::ZERO,
indexes,
true,
)?,
indexes_to_cointime_adj_inflation_rate: ComputedVecsFromDateIndex::forced_import(
&db,
"cointime_adj_inflation_rate",
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_cointime_adj_tx_btc_velocity: ComputedVecsFromDateIndex::forced_import(
&db,
"cointime_adj_tx_btc_velocity",
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_cointime_adj_tx_usd_velocity: ComputedVecsFromDateIndex::forced_import(
&db,
"cointime_adj_tx_usd_velocity",
Source::Compute,
version + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
db,
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -262,7 +289,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
@@ -270,15 +296,7 @@ impl Vecs {
stateful: &stateful::Vecs,
exit: &Exit,
) -> Result<()> {
self.compute_(
indexer,
indexes,
starting_indexes,
price,
chain,
stateful,
exit,
)?;
self.compute_(indexes, starting_indexes, price, chain, stateful, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
@@ -286,7 +304,6 @@ impl Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
price: Option<&price::Vecs>,
@@ -296,12 +313,8 @@ impl Vecs {
) -> Result<()> {
let circulating_supply = &stateful.utxo_cohorts.all.1.height_to_supply;
self.indexes_to_coinblocks_created.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_coinblocks_created
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
circulating_supply,
@@ -309,18 +322,13 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let indexes_to_coinblocks_destroyed =
&stateful.utxo_cohorts.all.1.indexes_to_coinblocks_destroyed;
self.indexes_to_coinblocks_stored.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_coinblocks_stored
.compute_all(indexes, starting_indexes, exit, |vec| {
let mut coinblocks_destroyed_iter = indexes_to_coinblocks_destroyed
.height
.as_ref()
@@ -336,15 +344,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_liveliness.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_liveliness
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
indexes_to_coinblocks_destroyed
@@ -356,16 +359,11 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let liveliness = &self.indexes_to_liveliness;
self.indexes_to_vaultedness.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaultedness
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
liveliness.height.as_ref().unwrap(),
@@ -373,16 +371,14 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let vaultedness = &self.indexes_to_vaultedness;
self.indexes_to_activity_to_vaultedness_ratio.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_divide(
starting_indexes.height,
liveliness.height.as_ref().unwrap(),
@@ -394,12 +390,11 @@ impl Vecs {
)?;
self.indexes_to_vaulted_supply.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
circulating_supply,
@@ -411,12 +406,11 @@ impl Vecs {
)?;
self.indexes_to_active_supply.compute_all(
indexer,
indexes,
price,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
circulating_supply,
@@ -427,6 +421,32 @@ impl Vecs {
},
)?;
self.indexes_to_cointime_adj_inflation_rate
.compute_all(starting_indexes, exit, |v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_inflation_rate.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
self.indexes_to_cointime_adj_tx_btc_velocity
.compute_all(starting_indexes, exit, |v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_tx_btc_velocity.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
})?;
if let Some(price) = price {
let realized_cap = stateful
.utxo_cohorts
@@ -447,12 +467,8 @@ impl Vecs {
.as_ref()
.unwrap();
self.indexes_to_thermo_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_thermo_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_transform(
starting_indexes.height,
chain
@@ -466,15 +482,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_investor_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_investor_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_subtract(
starting_indexes.height,
realized_cap,
@@ -482,15 +493,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaulted_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
realized_cap,
@@ -498,15 +504,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_active_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_active_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
realized_cap,
@@ -514,15 +515,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_vaulted_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
realized_price,
@@ -530,24 +526,17 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_vaulted_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
Some(self.indexes_to_vaulted_price.dateindex.unwrap_last()),
)?;
self.indexes_to_active_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_active_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
realized_price,
@@ -555,12 +544,9 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_active_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
@@ -568,11 +554,10 @@ impl Vecs {
)?;
self.indexes_to_true_market_mean.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_divide(
starting_indexes.height,
self.indexes_to_investor_cap.height.as_ref().unwrap(),
@@ -588,8 +573,6 @@ impl Vecs {
)?;
self.indexes_to_true_market_mean_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
@@ -597,11 +580,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_destroyed.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
// TODO: Another example when the callback should be applied to each index, instead of to base then merging from more granular to less
// The price taken won't be correct for time based indexes
vec.compute_multiply(
@@ -615,11 +597,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_created.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
&price.chainindexes_to_price_close.height,
@@ -631,11 +612,10 @@ impl Vecs {
)?;
self.indexes_to_cointime_value_stored.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
|vec| {
vec.compute_multiply(
starting_indexes.height,
&price.chainindexes_to_price_close.height,
@@ -646,12 +626,8 @@ impl Vecs {
},
)?;
self.indexes_to_cointime_price.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_cointime_price
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_divide(
starting_indexes.height,
self.indexes_to_cointime_value_destroyed
@@ -663,15 +639,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_cointime_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.indexes_to_cointime_cap
.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_multiply(
starting_indexes.height,
self.indexes_to_cointime_price.height.as_ref().unwrap(),
@@ -679,50 +650,100 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_cointime_price_ratio.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
Some(self.indexes_to_cointime_price.dateindex.unwrap_last()),
)?;
self.indexes_to_cointime_adj_tx_usd_velocity.compute_all(
starting_indexes,
exit,
|v| {
v.compute_multiply(
starting_indexes.dateindex,
self.indexes_to_activity_to_vaultedness_ratio
.dateindex
.unwrap_last(),
chain.indexes_to_tx_usd_velocity.dateindex.as_ref().unwrap(),
exit,
)?;
Ok(())
},
)?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.indexes_to_coinblocks_created.vecs(),
self.indexes_to_coinblocks_stored.vecs(),
self.indexes_to_liveliness.vecs(),
self.indexes_to_vaultedness.vecs(),
self.indexes_to_activity_to_vaultedness_ratio.vecs(),
self.indexes_to_vaulted_supply.vecs(),
self.indexes_to_active_supply.vecs(),
self.indexes_to_thermo_cap.vecs(),
self.indexes_to_investor_cap.vecs(),
self.indexes_to_vaulted_cap.vecs(),
self.indexes_to_active_cap.vecs(),
self.indexes_to_vaulted_price.vecs(),
self.indexes_to_vaulted_price_ratio.vecs(),
self.indexes_to_active_price.vecs(),
self.indexes_to_active_price_ratio.vecs(),
self.indexes_to_true_market_mean.vecs(),
self.indexes_to_true_market_mean_ratio.vecs(),
self.indexes_to_cointime_price.vecs(),
self.indexes_to_cointime_cap.vecs(),
self.indexes_to_cointime_price_ratio.vecs(),
self.indexes_to_cointime_value_destroyed.vecs(),
self.indexes_to_cointime_value_created.vecs(),
self.indexes_to_cointime_value_stored.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_inflation_rate
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_tx_btc_velocity
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_adj_tx_usd_velocity
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_coinblocks_created.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_coinblocks_stored.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_liveliness.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaultedness.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_activity_to_vaultedness_ratio
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_vaulted_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_thermo_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_investor_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_vaulted_price_ratio.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_active_price_ratio.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_true_market_mean.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_true_market_mean_ratio
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_cointime_price.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_cointime_cap.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_cointime_price_ratio.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.indexes_to_cointime_value_destroyed
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_cointime_value_created
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.indexes_to_cointime_value_stored.iter_any_collectable()));
iter
}
}
+79 -57
View File
@@ -1,8 +1,7 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{StoredI16, StoredU16, Version};
use brk_structs::{StoredF32, StoredI16, StoredU16, Version};
use vecdb::{AnyCollectableVec, AnyVec, Database, Exit};
use crate::grouped::Source;
@@ -24,7 +23,9 @@ pub struct Vecs {
pub constant_2: ComputedVecsFromHeight<StoredU16>,
pub constant_3: ComputedVecsFromHeight<StoredU16>,
pub constant_4: ComputedVecsFromHeight<StoredU16>,
pub constant_38_2: ComputedVecsFromHeight<StoredF32>,
pub constant_50: ComputedVecsFromHeight<StoredU16>,
pub constant_61_8: ComputedVecsFromHeight<StoredF32>,
pub constant_100: ComputedVecsFromHeight<StoredU16>,
pub constant_600: ComputedVecsFromHeight<StoredU16>,
pub constant_minus_1: ComputedVecsFromHeight<StoredI16>,
@@ -78,6 +79,14 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_38_2: ComputedVecsFromHeight::forced_import(
&db,
"constant_38_2",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_50: ComputedVecsFromHeight::forced_import(
&db,
"constant_50",
@@ -86,6 +95,14 @@ impl Vecs {
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_61_8: ComputedVecsFromHeight::forced_import(
&db,
"constant_61_8",
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_100: ComputedVecsFromHeight::forced_import(
&db,
"constant_100",
@@ -139,8 +156,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -150,19 +166,17 @@ impl Vecs {
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, exit)?;
self.compute_(indexes, starting_indexes, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
@@ -179,22 +193,16 @@ impl Vecs {
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
},
)
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredU16::new(value)),
exit,
)?;
Ok(())
})
})?;
[
@@ -205,44 +213,58 @@ impl Vecs {
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, indexes, starting_indexes, exit| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(value)),
exit,
)?;
Ok(())
},
)
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredI16::new(value)),
exit,
)?;
Ok(())
})
})?;
[
(&mut self.constant_38_2, 38.2),
(&mut self.constant_61_8, 61.8),
]
.into_iter()
.try_for_each(|(vec, value)| {
vec.compute_all(indexes, starting_indexes, exit, |vec| {
vec.compute_to(
starting_indexes.height,
indexes.height_to_date.len(),
indexes.height_to_date.version(),
|i| (i, StoredF32::from(value)),
exit,
)?;
Ok(())
})
})?;
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.constant_0.vecs(),
self.constant_1.vecs(),
self.constant_2.vecs(),
self.constant_3.vecs(),
self.constant_4.vecs(),
self.constant_50.vecs(),
self.constant_100.vecs(),
self.constant_600.vecs(),
self.constant_minus_1.vecs(),
self.constant_minus_2.vecs(),
self.constant_minus_3.vecs(),
self.constant_minus_4.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
iter = Box::new(iter.chain(self.constant_0.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_1.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_3.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_4.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_38_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_50.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_61_8.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_100.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_600.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_1.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_2.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_3.iter_any_collectable()));
iter = Box::new(iter.chain(self.constant_minus_4.iter_any_collectable()));
iter
}
}
+4 -4
View File
@@ -42,8 +42,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -140,10 +139,11 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[
&self.dateindex_to_price_ohlc_in_cents as &dyn AnyCollectableVec,
&self.height_to_price_ohlc_in_cents,
]
.into_iter()
}
}
@@ -1,473 +0,0 @@
use brk_error::Result;
use brk_structs::Version;
use vecdb::{
AnyBoxedIterableVec, AnyCloneableIterableVec, AnyCollectableVec, AnyIterableVec, Computation,
ComputedVec, ComputedVecFrom2, Database, Exit, Format, FromCoarserIndex, StoredIndex,
};
use crate::grouped::{EagerVecBuilder, VecBuilderOptions};
use super::ComputedType;
#[allow(clippy::type_complexity)]
#[derive(Clone)]
pub struct ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType,
S2T: ComputedType,
{
pub first: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub average: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub sum: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub max: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub min: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub last: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub cumulative: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
}
const VERSION: Version = Version::ZERO;
impl<I, T, S1I, S2T> ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType + 'static,
S1I: StoredIndex + 'static + FromCoarserIndex<I>,
S2T: ComputedType,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
db: &Database,
name: &str,
version: Version,
format: Format,
computation: Computation,
source: Option<AnyBoxedIterableVec<S1I, T>>,
source_extra: &EagerVecBuilder<S1I, T>,
len_source: AnyBoxedIterableVec<I, S2T>,
options: ComputedVecBuilderOptions,
) -> Result<Self> {
let only_one_active = options.is_only_one_active();
let suffix = |s: &str| format!("{name}_{s}");
let maybe_suffix = |s: &str| {
if only_one_active {
name.to_string()
} else {
suffix(s)
}
};
Ok(Self {
first: options.first.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("first"),
version + VERSION + Version::ZERO,
format,
source_extra
.first
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::min_from(i))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
last: options.last.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
name,
version + VERSION + Version::ZERO,
format,
source_extra.last.as_ref().map_or_else(
|| {
source
.as_ref()
.unwrap_or_else(|| {
dbg!(db, name, I::to_string());
panic!()
})
.clone()
},
|v| v.clone(),
),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
min: options.min.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("min"),
version + VERSION + Version::ZERO,
format,
source_extra
.min
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.min()
},
)
.unwrap(),
)
}),
max: options.max.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("max"),
version + VERSION + Version::ZERO,
format,
source_extra
.max
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.max()
},
)
.unwrap(),
)
}),
average: options.average.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&maybe_suffix("average"),
version + VERSION + Version::ZERO,
format,
source_extra
.average
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
let len = vec.len();
vec.into_iter().for_each(|v| sum += v);
Some(sum / len)
},
)
.unwrap(),
)
}),
sum: options.sum.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&(if !options.last && !options.average && !options.min && !options.max {
name.to_string()
} else {
maybe_suffix("sum")
}),
version + VERSION + Version::ZERO,
format,
source_extra
.sum
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
vec.into_iter().for_each(|v| sum += v);
Some(sum)
},
)
.unwrap(),
)
}),
cumulative: options.cumulative.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
db,
&suffix("cumulative"),
version + VERSION + Version::ZERO,
format,
source_extra.cumulative.as_ref().unwrap().boxed_clone(),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
})
}
pub fn compute_if_necessary<T2>(
&mut self,
max_from: I,
len_source: &impl AnyIterableVec<I, T2>,
exit: &Exit,
) -> Result<()> {
if let Some(first) = self.first.as_mut() {
first.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(last) = self.last.as_mut() {
last.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(min) = self.min.as_mut() {
min.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(max) = self.max.as_mut() {
max.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(average) = self.average.as_mut() {
average.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(sum) = self.sum.as_mut() {
sum.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.compute_if_necessary(max_from, len_source, exit)?;
}
Ok(())
}
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
))
}
pub fn unwrap_first(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.first.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_average(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.average.as_ref().unwrap()
}
pub fn unwrap_sum(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.sum.as_ref().unwrap()
}
pub fn unwrap_max(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.max.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.min.as_ref().unwrap()
}
pub fn unwrap_last(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.last.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_cumulative(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
v
}
}
#[derive(Default, Clone, Copy)]
pub struct ComputedVecBuilderOptions {
average: bool,
sum: bool,
max: bool,
min: bool,
first: bool,
last: bool,
cumulative: bool,
}
impl From<VecBuilderOptions> for ComputedVecBuilderOptions {
fn from(value: VecBuilderOptions) -> Self {
Self {
average: value.average(),
sum: value.sum(),
max: value.max(),
min: value.min(),
first: value.first(),
last: value.last(),
cumulative: value.cumulative(),
}
}
}
impl ComputedVecBuilderOptions {
pub fn add_first(mut self) -> Self {
self.first = true;
self
}
pub fn add_last(mut self) -> Self {
self.last = true;
self
}
pub fn add_min(mut self) -> Self {
self.min = true;
self
}
pub fn add_max(mut self) -> Self {
self.max = true;
self
}
pub fn add_average(mut self) -> Self {
self.average = true;
self
}
pub fn add_sum(mut self) -> Self {
self.sum = true;
self
}
pub fn add_cumulative(mut self) -> Self {
self.cumulative = true;
self
}
#[allow(unused)]
pub fn rm_min(mut self) -> Self {
self.min = false;
self
}
#[allow(unused)]
pub fn rm_max(mut self) -> Self {
self.max = false;
self
}
#[allow(unused)]
pub fn rm_average(mut self) -> Self {
self.average = false;
self
}
#[allow(unused)]
pub fn rm_sum(mut self) -> Self {
self.sum = false;
self
}
#[allow(unused)]
pub fn rm_cumulative(mut self) -> Self {
self.cumulative = false;
self
}
pub fn add_minmax(mut self) -> Self {
self.min = true;
self.max = true;
self
}
pub fn is_only_one_active(&self) -> bool {
[
self.average,
self.sum,
self.max,
self.min,
self.first,
self.last,
self.cumulative,
]
.iter()
.filter(|b| **b)
.count()
== 1
}
pub fn copy_self_extra(&self) -> Self {
Self {
cumulative: self.cumulative,
..Self::default()
}
}
}
+183 -133
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::{Error, Result};
use brk_structs::{CheckedSub, StoredU64, Version};
use vecdb::{
@@ -9,7 +10,7 @@ use crate::utils::get_percentile;
use super::ComputedType;
#[derive(Clone, Debug)]
#[derive(Clone, Debug, Allocative)]
pub struct EagerVecBuilder<I, T>
where
I: StoredIndex,
@@ -19,11 +20,11 @@ where
pub average: Option<Box<EagerVec<I, T>>>,
pub sum: Option<Box<EagerVec<I, T>>>,
pub max: Option<Box<EagerVec<I, T>>>,
pub p90: Option<Box<EagerVec<I, T>>>,
pub p75: Option<Box<EagerVec<I, T>>>,
pub pct90: Option<Box<EagerVec<I, T>>>,
pub pct75: Option<Box<EagerVec<I, T>>>,
pub median: Option<Box<EagerVec<I, T>>>,
pub p25: Option<Box<EagerVec<I, T>>>,
pub p10: Option<Box<EagerVec<I, T>>>,
pub pct25: Option<Box<EagerVec<I, T>>>,
pub pct10: Option<Box<EagerVec<I, T>>>,
pub min: Option<Box<EagerVec<I, T>>>,
pub last: Option<Box<EagerVec<I, T>>>,
pub cumulative: Option<Box<EagerVec<I, T>>>,
@@ -151,44 +152,44 @@ where
.unwrap(),
)
}),
p90: options.p90.then(|| {
pct90: options.pct90.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p90"),
&maybe_suffix("pct90"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p75: options.p75.then(|| {
pct75: options.pct75.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p75"),
&maybe_suffix("pct75"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p25: options.p25.then(|| {
pct25: options.pct25.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p25"),
&maybe_suffix("pct25"),
version + VERSION + Version::ZERO,
format,
)
.unwrap(),
)
}),
p10: options.p10.then(|| {
pct10: options.pct10.then(|| {
Box::new(
EagerVec::forced_import(
db,
&maybe_suffix("p10"),
&maybe_suffix("pct10"),
version + VERSION + Version::ZERO,
format,
)
@@ -292,11 +293,11 @@ where
let needs_average_sum_or_cumulative =
needs_sum_or_cumulative || self.average.is_some();
let needs_sorted = self.max.is_some()
|| self.p90.is_some()
|| self.p75.is_some()
|| self.pct90.is_some()
|| self.pct75.is_some()
|| self.median.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
|| self.pct25.is_some()
|| self.pct10.is_some()
|| self.min.is_some();
let needs_values = needs_sorted || needs_average_sum_or_cumulative;
@@ -333,24 +334,24 @@ where
)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.forced_push_at(index, get_percentile(&values, 0.90), exit)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.forced_push_at(index, get_percentile(&values, 0.75), exit)?;
}
if let Some(median) = self.median.as_mut() {
median.forced_push_at(index, get_percentile(&values, 0.50), exit)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.forced_push_at(index, get_percentile(&values, 0.25), exit)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.forced_push_at(index, get_percentile(&values, 0.10), exit)?;
}
if let Some(min) = self.min.as_mut() {
@@ -401,11 +402,11 @@ where
where
I2: StoredIndex + StoredRaw + CheckedSub<I2>,
{
if self.p90.is_some()
|| self.p75.is_some()
if self.pct90.is_some()
|| self.pct75.is_some()
|| self.median.is_some()
|| self.p25.is_some()
|| self.p10.is_some()
|| self.pct25.is_some()
|| self.pct10.is_some()
{
panic!("unsupported");
}
@@ -540,7 +541,7 @@ where
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
self.iter_any_collectable().map(|v| v.len()).min().unwrap(),
))
}
@@ -558,24 +559,24 @@ where
self.max.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p90(&self) -> &EagerVec<I, T> {
self.p90.as_ref().unwrap()
pub fn unwrap_pct90(&self) -> &EagerVec<I, T> {
self.pct90.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p75(&self) -> &EagerVec<I, T> {
self.p75.as_ref().unwrap()
pub fn unwrap_pct75(&self) -> &EagerVec<I, T> {
self.pct75.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_median(&self) -> &EagerVec<I, T> {
self.median.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p25(&self) -> &EagerVec<I, T> {
self.p25.as_ref().unwrap()
pub fn unwrap_pct25(&self) -> &EagerVec<I, T> {
self.pct25.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_p10(&self) -> &EagerVec<I, T> {
self.p10.as_ref().unwrap()
pub fn unwrap_pct10(&self) -> &EagerVec<I, T> {
self.pct10.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &EagerVec<I, T> {
self.min.as_ref().unwrap()
@@ -588,47 +589,96 @@ where
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(median) = self.median.as_ref() {
v.push(median.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
if let Some(p90) = self.p90.as_ref() {
v.push(p90.as_ref());
}
if let Some(p75) = self.p75.as_ref() {
v.push(p75.as_ref());
}
if let Some(p25) = self.p25.as_ref() {
v.push(p25.as_ref());
}
if let Some(p10) = self.p10.as_ref() {
v.push(p10.as_ref());
}
iter = Box::new(
iter.chain(
self.first
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.last
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.min
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.max
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.median
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.average
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.sum
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.cumulative
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct90
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct75
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct25
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.pct10
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
v
iter
}
pub fn safe_flush(&mut self, exit: &Exit) -> Result<()> {
@@ -656,17 +706,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.safe_flush(exit)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.safe_flush(exit)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.safe_flush(exit)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.safe_flush(exit)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.safe_flush(exit)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.safe_flush(exit)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.safe_flush(exit)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.safe_flush(exit)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.safe_flush(exit)?;
}
Ok(())
@@ -697,17 +747,17 @@ where
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p90) = self.p90.as_mut() {
p90.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct90) = self.pct90.as_mut() {
pct90.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p75) = self.p75.as_mut() {
p75.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct75) = self.pct75.as_mut() {
pct75.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p25) = self.p25.as_mut() {
p25.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct25) = self.pct25.as_mut() {
pct25.validate_computed_version_or_reset(Version::ZERO + version)?;
}
if let Some(p10) = self.p10.as_mut() {
p10.validate_computed_version_or_reset(Version::ZERO + version)?;
if let Some(pct10) = self.pct10.as_mut() {
pct10.validate_computed_version_or_reset(Version::ZERO + version)?;
}
Ok(())
@@ -719,11 +769,11 @@ pub struct VecBuilderOptions {
average: bool,
sum: bool,
max: bool,
p90: bool,
p75: bool,
pct90: bool,
pct75: bool,
median: bool,
p25: bool,
p10: bool,
pct25: bool,
pct10: bool,
min: bool,
first: bool,
last: bool,
@@ -743,24 +793,24 @@ impl VecBuilderOptions {
self.max
}
pub fn p90(&self) -> bool {
self.p90
pub fn pct90(&self) -> bool {
self.pct90
}
pub fn p75(&self) -> bool {
self.p75
pub fn pct75(&self) -> bool {
self.pct75
}
pub fn median(&self) -> bool {
self.median
}
pub fn p25(&self) -> bool {
self.p25
pub fn pct25(&self) -> bool {
self.pct25
}
pub fn p10(&self) -> bool {
self.p10
pub fn pct10(&self) -> bool {
self.pct10
}
pub fn min(&self) -> bool {
@@ -816,26 +866,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn add_p90(mut self) -> Self {
self.p90 = true;
pub fn add_pct90(mut self) -> Self {
self.pct90 = true;
self
}
#[allow(unused)]
pub fn add_p75(mut self) -> Self {
self.p75 = true;
pub fn add_pct75(mut self) -> Self {
self.pct75 = true;
self
}
#[allow(unused)]
pub fn add_p25(mut self) -> Self {
self.p25 = true;
pub fn add_pct25(mut self) -> Self {
self.pct25 = true;
self
}
#[allow(unused)]
pub fn add_p10(mut self) -> Self {
self.p10 = true;
pub fn add_pct10(mut self) -> Self {
self.pct10 = true;
self
}
@@ -875,26 +925,26 @@ impl VecBuilderOptions {
}
#[allow(unused)]
pub fn rm_p90(mut self) -> Self {
self.p90 = false;
pub fn rm_pct90(mut self) -> Self {
self.pct90 = false;
self
}
#[allow(unused)]
pub fn rm_p75(mut self) -> Self {
self.p75 = false;
pub fn rm_pct75(mut self) -> Self {
self.pct75 = false;
self
}
#[allow(unused)]
pub fn rm_p25(mut self) -> Self {
self.p25 = false;
pub fn rm_pct25(mut self) -> Self {
self.pct25 = false;
self
}
#[allow(unused)]
pub fn rm_p10(mut self) -> Self {
self.p10 = false;
pub fn rm_pct10(mut self) -> Self {
self.pct10 = false;
self
}
@@ -911,20 +961,20 @@ impl VecBuilderOptions {
}
pub fn add_percentiles(mut self) -> Self {
self.p90 = true;
self.p75 = true;
self.pct90 = true;
self.pct75 = true;
self.median = true;
self.p25 = true;
self.p10 = true;
self.pct25 = true;
self.pct10 = true;
self
}
pub fn remove_percentiles(mut self) -> Self {
self.p90 = false;
self.p75 = false;
self.pct90 = false;
self.pct75 = false;
self.median = false;
self.p25 = false;
self.p10 = false;
self.pct25 = false;
self.pct10 = false;
self
}
@@ -933,11 +983,11 @@ impl VecBuilderOptions {
self.average,
self.sum,
self.max,
self.p90,
self.p75,
self.pct90,
self.pct75,
self.median,
self.p25,
self.p10,
self.pct25,
self.pct10,
self.min,
self.first,
self.last,
+56 -26
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_structs::Version;
use vecdb::{
AnyBoxedIterableVec, AnyCloneableIterableVec, AnyCollectableVec, FromCoarserIndex,
@@ -9,7 +10,7 @@ use crate::grouped::{EagerVecBuilder, VecBuilderOptions};
use super::ComputedType;
#[allow(clippy::type_complexity)]
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct LazyVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
@@ -216,7 +217,7 @@ where
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
self.iter_any_collectable().map(|v| v.len()).min().unwrap(),
))
}
@@ -244,32 +245,61 @@ where
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(std::iter::empty());
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
iter = Box::new(
iter.chain(
self.first
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.last
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.min
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.max
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.average
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.sum
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.cumulative
.as_ref()
.map(|x| x.as_ref() as &dyn AnyCollectableVec),
),
);
v
iter
}
}
@@ -1,6 +1,6 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, Version, WeekIndex, YearIndex,
};
@@ -10,7 +10,7 @@ use crate::{Indexes, grouped::LazyVecBuilder, indexes};
use super::{ComputedType, EagerVecBuilder, Source, VecBuilderOptions};
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct ComputedVecsFromDateIndex<T>
where
T: ComputedType + PartialOrd,
@@ -111,28 +111,14 @@ where
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, T>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, T>) -> Result<()>,
{
compute(
self.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.dateindex.as_mut().unwrap())?;
let dateindex: Option<&EagerVec<DateIndex, T>> = None;
self.compute_rest(starting_indexes, exit, dateindex)
@@ -157,21 +143,22 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.dateindex
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dateindex_extra.vecs(),
self.weekindex.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.dateindex_extra.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
+21 -28
View File
@@ -1,6 +1,6 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, SemesterIndex,
Version, WeekIndex, YearIndex,
@@ -15,7 +15,7 @@ use crate::{
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct ComputedVecsFromHeight<T>
where
T: ComputedType + PartialOrd,
@@ -133,22 +133,15 @@ where
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(&mut EagerVec<Height, T>, &Indexer, &indexes::Vecs, &Indexes, &Exit) -> Result<()>,
F: FnMut(&mut EagerVec<Height, T>) -> Result<()>,
{
compute(
self.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.height.as_mut().unwrap())?;
let height: Option<&EagerVec<Height, T>> = None;
self.compute_rest(indexes, starting_indexes, exit, height)
@@ -206,24 +199,24 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.height
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.height_extra.vecs(),
self.dateindex.vecs(),
self.weekindex.vecs(),
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.height_extra.iter_any_collectable()));
iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
@@ -1,6 +1,5 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{DifficultyEpoch, Height, Version};
use vecdb::{AnyCollectableVec, Database, EagerVec, Exit};
@@ -59,16 +58,15 @@ where
pub fn compute<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(&mut EagerVec<Height, T>, &Indexer, &indexes::Vecs, &Indexes, &Exit) -> Result<()>,
F: FnMut(&mut EagerVec<Height, T>) -> Result<()>,
{
compute(&mut self.height, indexer, indexes, starting_indexes, exit)?;
compute(&mut self.height)?;
self.height_extra
.extend(starting_indexes.height, &self.height, exit)?;
@@ -84,15 +82,10 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![&self.height as &dyn AnyCollectableVec],
self.height_extra.vecs(),
self.difficultyepoch.vecs(),
// self.halvingepoch.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.height as &dyn AnyCollectableVec]
.into_iter()
.chain(self.height_extra.iter_any_collectable())
.chain(self.difficultyepoch.iter_any_collectable())
}
}
+43 -42
View File
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
@@ -17,7 +18,7 @@ use crate::{
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct ComputedVecsFromTxindex<T>
where
T: ComputedType + PartialOrd,
@@ -225,25 +226,25 @@ where
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
self.txindex
.as_ref()
.map_or(vec![], |v| vec![v.as_ref() as &dyn AnyCollectableVec]),
self.height.vecs(),
self.dateindex.vecs(),
self.weekindex.vecs(),
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
.map(|x| x.as_ref() as &dyn AnyCollectableVec)
.into_iter(),
);
iter = Box::new(iter.chain(self.height.iter_any_collectable()));
iter = Box::new(iter.chain(self.dateindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.weekindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.difficultyepoch.iter_any_collectable()));
iter = Box::new(iter.chain(self.monthindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.quarterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.semesterindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.yearindex.iter_any_collectable()));
iter = Box::new(iter.chain(self.decadeindex.iter_any_collectable()));
iter
}
}
@@ -319,24 +320,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p90()
.unwrap_pct90()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p75()
.unwrap_pct75()
.into_iter()
.unwrap_get_inner(height),
),
@@ -355,24 +356,24 @@ impl ComputedVecsFromTxindex<Bitcoin> {
exit,
)?;
}
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p25()
.unwrap_pct25()
.into_iter()
.unwrap_get_inner(height),
),
exit,
)?;
}
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.forced_push_at(
height,
Bitcoin::from(
sats.height
.unwrap_p10()
.unwrap_pct10()
.into_iter()
.unwrap_get_inner(height),
),
@@ -502,25 +503,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_90p) = self.height.p90.as_mut() {
_90p.forced_push_at(
if let Some(pct90) = self.height.pct90.as_mut() {
pct90.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p90()
.unwrap_pct90()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_75p) = self.height.p75.as_mut() {
_75p.forced_push_at(
if let Some(pct75) = self.height.pct75.as_mut() {
pct75.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p75()
.unwrap_pct75()
.into_iter()
.unwrap_get_inner(height),
exit,
@@ -538,25 +539,25 @@ impl ComputedVecsFromTxindex<Dollars> {
exit,
)?;
}
if let Some(_25p) = self.height.p25.as_mut() {
_25p.forced_push_at(
if let Some(pct25) = self.height.pct25.as_mut() {
pct25.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p25()
.unwrap_pct25()
.into_iter()
.unwrap_get_inner(height),
exit,
)?;
}
if let Some(_10p) = self.height.p10.as_mut() {
_10p.forced_push_at(
if let Some(pct10) = self.height.pct10.as_mut() {
pct10.forced_push_at(
height,
price
* bitcoin
.height
.unwrap_p10()
.unwrap_pct10()
.into_iter()
.unwrap_get_inner(height),
exit,
@@ -1,5 +1,4 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Date, DateIndex, Dollars, StoredF32, Version};
use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, CollectableVec, Database, EagerVec,
@@ -8,7 +7,9 @@ use vecdb::{
use crate::{
Indexes,
grouped::{ComputedStandardDeviationVecsFromDateIndex, source::Source},
grouped::{
ComputedStandardDeviationVecsFromDateIndex, StandardDeviationVecsOptions, source::Source,
},
indexes, price,
utils::get_percentile,
};
@@ -28,12 +29,12 @@ pub struct ComputedRatioVecsFromDateIndex {
pub ratio_pct5: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct2: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct1: Option<ComputedVecsFromDateIndex<StoredF32>>,
pub ratio_pct99_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct98_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct95_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct5_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct2_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct1_in_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct99_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct98_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct95_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct5_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct2_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_pct1_usd: Option<ComputedVecsFromDateIndex<Dollars>>,
pub ratio_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
pub ratio_4y_sd: Option<ComputedStandardDeviationVecsFromDateIndex>,
@@ -105,6 +106,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -116,6 +118,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -127,6 +130,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -138,6 +142,7 @@ impl ComputedRatioVecsFromDateIndex {
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
StandardDeviationVecsOptions::default().add_all(),
)
.unwrap()
}),
@@ -207,10 +212,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct99_in_usd: extended.then(|| {
ratio_pct99_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct99_in_usd"),
&format!("{name}_ratio_pct99_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -218,10 +223,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct98_in_usd: extended.then(|| {
ratio_pct98_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct98_in_usd"),
&format!("{name}_ratio_pct98_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -229,10 +234,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct95_in_usd: extended.then(|| {
ratio_pct95_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct95_in_usd"),
&format!("{name}_ratio_pct95_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -240,10 +245,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct5_in_usd: extended.then(|| {
ratio_pct5_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct5_in_usd"),
&format!("{name}_ratio_pct5_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -251,10 +256,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct2_in_usd: extended.then(|| {
ratio_pct2_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct2_in_usd"),
&format!("{name}_ratio_pct2_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -262,10 +267,10 @@ impl ComputedRatioVecsFromDateIndex {
)
.unwrap()
}),
ratio_pct1_in_usd: extended.then(|| {
ratio_pct1_usd: extended.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_ratio_pct1_in_usd"),
&format!("{name}_ratio_pct1_usd"),
Source::Compute,
version + VERSION + Version::ZERO,
indexes,
@@ -278,45 +283,25 @@ impl ComputedRatioVecsFromDateIndex {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, Dollars>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, Dollars>) -> Result<()>,
{
self.price.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
compute,
)?;
self.price
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, compute)?;
let date_to_price_opt: Option<&EagerVec<DateIndex, Dollars>> = None;
self.compute_rest(
indexer,
indexes,
price,
starting_indexes,
exit,
date_to_price_opt,
)
self.compute_rest(price, starting_indexes, exit, date_to_price_opt)
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: &price::Vecs,
starting_indexes: &Indexes,
exit: &Exit,
@@ -328,28 +313,22 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
});
self.ratio.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform2(
starting_indexes.dateindex,
closes,
price,
|(i, close, price, ..)| {
if price == Dollars::ZERO {
(i, StoredF32::from(1.0))
} else {
(i, StoredF32::from(*close / price))
}
},
exit,
)?;
Ok(())
},
)?;
self.ratio.compute_all(starting_indexes, exit, |v| {
v.compute_transform2(
starting_indexes.dateindex,
closes,
price,
|(i, close, price, ..)| {
if price == Dollars::ZERO {
(i, StoredF32::from(1.0))
} else {
(i, StoredF32::from(*close / price))
}
},
exit,
)?;
Ok(())
})?;
if self.ratio_1w_sma.is_none() {
return Ok(());
@@ -357,12 +336,10 @@ impl ComputedRatioVecsFromDateIndex {
let min_ratio_date = DateIndex::try_from(Date::MIN_RATIO).unwrap();
self.ratio_1w_sma.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.ratio_1w_sma
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |v| {
v.compute_sma_(
starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(),
@@ -371,15 +348,12 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date),
)?;
Ok(())
},
)?;
})?;
self.ratio_1m_sma.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.ratio_1m_sma
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |v| {
v.compute_sma_(
starting_indexes.dateindex,
self.ratio.dateindex.as_ref().unwrap(),
@@ -388,8 +362,7 @@ impl ComputedRatioVecsFromDateIndex {
Some(min_ratio_date),
)?;
Ok(())
},
)?;
})?;
let ratio_version = self.ratio.dateindex.as_ref().unwrap().version();
self.mut_ratio_vecs()
@@ -556,12 +529,10 @@ impl ComputedRatioVecsFromDateIndex {
std::mem::transmute(&self.price.as_ref().unwrap().dateindex)
});
self.ratio_pct99_in_usd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
self.ratio_pct99_usd
.as_mut()
.unwrap()
.compute_all(starting_indexes, exit, |vec| {
let mut iter = self
.ratio_pct99
.as_ref()
@@ -580,67 +551,52 @@ impl ComputedRatioVecsFromDateIndex {
exit,
)?;
Ok(())
},
)?;
})?;
let compute_in_usd =
|in_usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>,
let compute_usd =
|usd: Option<&mut ComputedVecsFromDateIndex<Dollars>>,
source: Option<&ComputedVecsFromDateIndex<StoredF32>>| {
in_usd.unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
|vec, _, _, starting_indexes, exit| {
let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter();
vec.compute_transform(
starting_indexes.dateindex,
date_to_price,
|(i, price, ..)| {
let multiplier = iter.unwrap_get_inner(i);
(i, price * multiplier)
},
exit,
)?;
Ok(())
},
)
usd.unwrap().compute_all(starting_indexes, exit, |vec| {
let mut iter = source.unwrap().dateindex.as_ref().unwrap().into_iter();
vec.compute_transform(
starting_indexes.dateindex,
date_to_price,
|(i, price, ..)| {
let multiplier = iter.unwrap_get_inner(i);
(i, price * multiplier)
},
exit,
)?;
Ok(())
})
};
compute_in_usd(self.ratio_pct1_in_usd.as_mut(), self.ratio_pct1.as_ref())?;
compute_in_usd(self.ratio_pct2_in_usd.as_mut(), self.ratio_pct2.as_ref())?;
compute_in_usd(self.ratio_pct5_in_usd.as_mut(), self.ratio_pct5.as_ref())?;
compute_in_usd(self.ratio_pct95_in_usd.as_mut(), self.ratio_pct95.as_ref())?;
compute_in_usd(self.ratio_pct98_in_usd.as_mut(), self.ratio_pct98.as_ref())?;
compute_in_usd(self.ratio_pct99_in_usd.as_mut(), self.ratio_pct99.as_ref())?;
compute_usd(self.ratio_pct1_usd.as_mut(), self.ratio_pct1.as_ref())?;
compute_usd(self.ratio_pct2_usd.as_mut(), self.ratio_pct2.as_ref())?;
compute_usd(self.ratio_pct5_usd.as_mut(), self.ratio_pct5.as_ref())?;
compute_usd(self.ratio_pct95_usd.as_mut(), self.ratio_pct95.as_ref())?;
compute_usd(self.ratio_pct98_usd.as_mut(), self.ratio_pct98.as_ref())?;
compute_usd(self.ratio_pct99_usd.as_mut(), self.ratio_pct99.as_ref())?;
self.ratio_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_4y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_2y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
Some(date_to_price),
)?;
self.ratio_1y_sd.as_mut().unwrap().compute_all(
indexer,
indexes,
starting_indexes,
exit,
self.ratio.dateindex.as_ref().unwrap(),
@@ -676,37 +632,132 @@ impl ComputedRatioVecsFromDateIndex {
.collect::<Vec<_>>()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.price.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio.vecs(),
self.ratio_1w_sma.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_1m_sma.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_1y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_2y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_4y_sd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct1.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct2.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct5.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct95.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct98.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct99.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct1_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct2_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct5_in_usd.as_ref().map_or(vec![], |v| v.vecs()),
self.ratio_pct95_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.ratio_pct98_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.ratio_pct99_in_usd
.as_ref()
.map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(self.price.iter().flat_map(|v| v.iter_any_collectable()));
iter = Box::new(iter.chain(self.ratio.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.ratio_1w_sma
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_1m_sma
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(iter.chain(self.ratio_sd.iter().flat_map(|v| v.iter_any_collectable())));
iter = Box::new(
iter.chain(
self.ratio_1y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_2y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_4y_sd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct1
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct2
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct5
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct95
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct98
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct99
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct1_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct2_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct5_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct95_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct98_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.ratio_pct99_usd
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter
}
}
File diff suppressed because it is too large Load Diff
@@ -1,5 +1,4 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -43,7 +42,7 @@ impl ComputedValueVecsFromDateIndex {
)?,
bitcoin: ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
Source::Compute,
version + VERSION,
indexes,
@@ -52,7 +51,7 @@ impl ComputedValueVecsFromDateIndex {
dollars: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
Source::Compute,
version + VERSION,
indexes,
@@ -65,40 +64,24 @@ impl ComputedValueVecsFromDateIndex {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<DateIndex, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<DateIndex, Sats>) -> Result<()>,
{
compute(
self.sats.dateindex.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.dateindex.as_mut().unwrap())?;
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
self.compute_rest(indexer, indexes, price, starting_indexes, exit, dateindex)?;
self.compute_rest(price, starting_indexes, exit, dateindex)?;
Ok(())
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
@@ -108,33 +91,21 @@ impl ComputedValueVecsFromDateIndex {
self.sats
.compute_rest(starting_indexes, exit, Some(dateindex))?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
},
)?;
self.bitcoin.compute_all(starting_indexes, exit, |v| {
v.compute_from_sats(starting_indexes.dateindex, dateindex, exit)
})?;
} else {
let dateindex: Option<&StoredVec<DateIndex, Sats>> = None;
self.sats.compute_rest(starting_indexes, exit, dateindex)?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_sats(
starting_indexes.dateindex,
self.sats.dateindex.as_ref().unwrap(),
exit,
)
},
)?;
self.bitcoin.compute_all(starting_indexes, exit, |v| {
v.compute_from_sats(
starting_indexes.dateindex,
self.sats.dateindex.as_ref().unwrap(),
exit,
)
})?;
}
let dateindex_to_bitcoin = self.bitcoin.dateindex.as_ref().unwrap();
@@ -147,33 +118,23 @@ impl ComputedValueVecsFromDateIndex {
.unwrap();
if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_bitcoin(
starting_indexes.dateindex,
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
},
)?;
dollars.compute_all(starting_indexes, exit, |v| {
v.compute_from_bitcoin(
starting_indexes.dateindex,
dateindex_to_bitcoin,
dateindex_to_price_close,
exit,
)
})?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
self.bitcoin.vecs(),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
std::iter::empty()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
@@ -1,5 +1,5 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, StoredVec};
@@ -12,7 +12,7 @@ use crate::{
use super::{ComputedVecsFromHeight, VecBuilderOptions};
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct ComputedValueVecsFromHeight {
pub sats: ComputedVecsFromHeight<Sats>,
pub bitcoin: ComputedVecsFromHeight<Bitcoin>,
@@ -43,7 +43,7 @@ impl ComputedValueVecsFromHeight {
)?,
bitcoin: ComputedVecsFromHeight::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
Source::Compute,
version + VERSION,
indexes,
@@ -52,7 +52,7 @@ impl ComputedValueVecsFromHeight {
dollars: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
Source::Compute,
version + VERSION,
indexes,
@@ -65,7 +65,6 @@ impl ComputedValueVecsFromHeight {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -73,31 +72,18 @@ impl ComputedValueVecsFromHeight {
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
{
compute(
self.sats.height.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.height.as_mut().unwrap())?;
let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(indexer, indexes, price, starting_indexes, exit, height)?;
self.compute_rest(indexes, price, starting_indexes, exit, height)?;
Ok(())
}
pub fn compute_rest(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -108,67 +94,47 @@ impl ComputedValueVecsFromHeight {
self.sats
.compute_rest(indexes, starting_indexes, exit, Some(height))?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.bitcoin
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_sats(starting_indexes.height, height, exit)
},
)?;
})?;
} else {
let height: Option<&StoredVec<Height, Sats>> = None;
self.sats
.compute_rest(indexes, starting_indexes, exit, height)?;
self.bitcoin.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.bitcoin
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_sats(
starting_indexes.height,
self.sats.height.as_ref().unwrap(),
exit,
)
},
)?;
})?;
}
let height_to_bitcoin = self.bitcoin.height.as_ref().unwrap();
let height_to_price_close = &price.as_ref().unwrap().chainindexes_to_price_close.height;
if let Some(dollars) = self.dollars.as_mut() {
dollars.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_from_bitcoin(
starting_indexes.height,
height_to_bitcoin,
height_to_price_close,
exit,
)
},
)?;
dollars.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_from_bitcoin(
starting_indexes.height,
height_to_bitcoin,
height_to_price_close,
exit,
)
})?;
}
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
self.bitcoin.vecs(),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
std::iter::empty()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
@@ -1,3 +1,4 @@
use allocative::Allocative;
use brk_error::Result;
use brk_indexer::Indexer;
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};
#[derive(Clone)]
#[derive(Clone, Allocative)]
pub struct ComputedValueVecsFromTxindex {
pub sats: ComputedVecsFromTxindex<Sats>,
pub bitcoin_txindex: LazyVecFrom1<TxIndex, Bitcoin, TxIndex, Sats>,
@@ -37,8 +38,8 @@ impl ComputedValueVecsFromTxindex {
) -> Result<Self> {
let compute_dollars = price.is_some();
let name_in_btc = format!("{name}_in_btc");
let name_in_usd = format!("{name}_in_usd");
let name_btc = format!("{name}_btc");
let name_usd = format!("{name}_usd");
let sats = ComputedVecsFromTxindex::forced_import(
db,
@@ -52,7 +53,7 @@ impl ComputedValueVecsFromTxindex {
let source_vec = source.vec();
let bitcoin_txindex = LazyVecFrom1::init(
&name_in_btc,
&name_btc,
version + VERSION,
source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|txindex: TxIndex, iter| {
@@ -65,7 +66,7 @@ impl ComputedValueVecsFromTxindex {
let bitcoin = ComputedVecsFromTxindex::forced_import(
db,
&name_in_btc,
&name_btc,
Source::None,
version + VERSION,
indexes,
@@ -74,29 +75,27 @@ impl ComputedValueVecsFromTxindex {
let dollars_txindex = price.map(|price| {
LazyVecFrom3::init(
&name_in_usd,
&name_usd,
version + VERSION,
bitcoin_txindex.boxed_clone(),
indexes.txindex_to_height.boxed_clone(),
price.chainindexes_to_price_close.height.boxed_clone(),
|txindex: TxIndex,
txindex_to_in_btc_iter,
txindex_to_btc_iter,
txindex_to_height_iter,
height_to_price_close_iter| {
let txindex = txindex.unwrap_to_usize();
txindex_to_in_btc_iter
.next_at(txindex)
.and_then(|(_, value)| {
let btc = value.into_owned();
txindex_to_height_iter
.next_at(txindex)
.and_then(|(_, value)| {
let height = value.into_owned();
height_to_price_close_iter
.next_at(height.unwrap_to_usize())
.map(|(_, close)| *close.into_owned() * btc)
})
})
txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
let btc = value.into_owned();
txindex_to_height_iter
.next_at(txindex)
.and_then(|(_, value)| {
let height = value.into_owned();
height_to_price_close_iter
.next_at(height.unwrap_to_usize())
.map(|(_, close)| *close.into_owned() * btc)
})
})
},
)
});
@@ -109,7 +108,7 @@ impl ComputedValueVecsFromTxindex {
dollars: compute_dollars.then(|| {
ComputedVecsFromTxindex::forced_import(
db,
&name_in_usd,
&name_usd,
Source::None,
version + VERSION,
indexes,
@@ -203,18 +202,16 @@ impl ComputedValueVecsFromTxindex {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.sats.vecs(),
vec![&self.bitcoin_txindex as &dyn AnyCollectableVec],
self.bitcoin.vecs(),
self.dollars_txindex
.as_ref()
.map_or(vec![], |v| vec![v as &dyn AnyCollectableVec]),
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.bitcoin_txindex as &dyn AnyCollectableVec]
.into_iter()
.chain(self.sats.iter_any_collectable())
.chain(self.bitcoin.iter_any_collectable())
.chain(
self.dollars_txindex
.iter()
.map(|v| v as &dyn AnyCollectableVec),
)
.chain(self.dollars.iter().flat_map(|v| v.iter_any_collectable()))
}
}
+10 -29
View File
@@ -1,12 +1,11 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, Dollars, Height, Sats, Version};
use vecdb::{AnyCollectableVec, CollectableVec, Database, EagerVec, Exit, Format, StoredVec};
use crate::{
Indexes,
grouped::Source,
indexes, price,
price,
traits::{ComputeFromBitcoin, ComputeFromSats},
};
@@ -35,14 +34,14 @@ impl ComputedHeightValueVecs {
}),
bitcoin: EagerVec::forced_import(
db,
&format!("{name}_in_btc"),
&format!("{name}_btc"),
version + VERSION + Version::ZERO,
format,
)?,
dollars: compute_dollars.then(|| {
EagerVec::forced_import(
db,
&format!("{name}_in_usd"),
&format!("{name}_usd"),
version + VERSION + Version::ZERO,
format,
)
@@ -53,29 +52,15 @@ impl ComputedHeightValueVecs {
pub fn compute_all<F>(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
mut compute: F,
) -> Result<()>
where
F: FnMut(
&mut EagerVec<Height, Sats>,
&Indexer,
&indexes::Vecs,
&Indexes,
&Exit,
) -> Result<()>,
F: FnMut(&mut EagerVec<Height, Sats>) -> Result<()>,
{
compute(
self.sats.as_mut().unwrap(),
indexer,
indexes,
starting_indexes,
exit,
)?;
compute(self.sats.as_mut().unwrap())?;
let height: Option<&StoredVec<Height, Sats>> = None;
self.compute_rest(price, starting_indexes, exit, height)?;
@@ -116,14 +101,10 @@ impl ComputedHeightValueVecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
vec![&self.bitcoin as &dyn AnyCollectableVec],
self.sats.as_ref().map_or(vec![], |v| vec![v]),
self.dollars.as_ref().map_or(vec![], |v| vec![v]),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[&self.bitcoin as &dyn AnyCollectableVec]
.into_iter()
.chain(self.sats.iter().map(|v| v as &dyn AnyCollectableVec))
.chain(self.dollars.iter().map(|v| v as &dyn AnyCollectableVec))
}
}
+5 -5
View File
@@ -475,8 +475,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -934,9 +933,9 @@ impl Vecs {
})
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
&self.dateindex_to_date,
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
[
&self.dateindex_to_date as &dyn AnyCollectableVec,
&self.dateindex_to_dateindex,
&self.dateindex_to_first_height,
&self.dateindex_to_height_count,
@@ -997,6 +996,7 @@ impl Vecs {
&self.yearindex_to_yearindex,
&self.outputindex_to_txindex,
]
.into_iter()
}
}
+76 -31
View File
@@ -1,6 +1,6 @@
#![doc = include_str!("../README.md")]
use std::{path::Path, thread};
use std::path::Path;
use brk_error::Result;
use brk_fetcher::Fetcher;
@@ -34,6 +34,7 @@ pub struct Computer {
pub indexes: indexes::Vecs,
pub constants: constants::Vecs,
pub market: market::Vecs,
pub pools: pools::Vecs,
pub price: Option<price::Vecs>,
pub chain: chain::Vecs,
pub stateful: stateful::Vecs,
@@ -41,7 +42,7 @@ pub struct Computer {
pub cointime: cointime::Vecs,
}
const VERSION: Version = Version::TWO;
const VERSION: Version = Version::new(4);
impl Computer {
/// Do NOT import multiple times or things will break !!!
@@ -86,6 +87,12 @@ impl Computer {
&indexes,
price.as_ref(),
)?,
pools: pools::Vecs::forced_import(
&computed_path,
VERSION + Version::ZERO,
&indexes,
price.as_ref(),
)?,
cointime: cointime::Vecs::forced_import(
&computed_path,
VERSION + Version::ZERO,
@@ -109,7 +116,7 @@ impl Computer {
info!("Computing constants...");
self.constants
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
.compute(&self.indexes, &starting_indexes, exit)?;
if let Some(fetched) = self.fetched.as_mut() {
info!("Computing fetched...");
@@ -117,7 +124,6 @@ impl Computer {
info!("Computing prices...");
self.price.as_mut().unwrap().compute(
indexer,
&self.indexes,
&starting_indexes,
fetched,
@@ -125,8 +131,8 @@ impl Computer {
)?;
}
thread::scope(|scope| -> Result<()> {
let chain = scope.spawn(|| {
std::thread::scope(|scope| -> Result<()> {
let chain = scope.spawn(|| -> Result<()> {
info!("Computing chain...");
self.chain.compute(
indexer,
@@ -134,23 +140,30 @@ impl Computer {
&starting_indexes,
self.price.as_ref(),
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(())
});
if let Some(price) = self.price.as_ref() {
info!("Computing market...");
self.market.compute(price, &starting_indexes, exit)?;
}
chain.join().unwrap()?;
market.join().unwrap()?;
Ok(())
})?;
self.pools.compute(
indexer,
&self.indexes,
&starting_indexes,
&self.chain,
self.price.as_ref(),
exit,
)?;
// return Ok(());
info!("Computing stateful...");
self.stateful.compute(
indexer,
@@ -163,7 +176,6 @@ impl Computer {
info!("Computing cointime...");
self.cointime.compute(
indexer,
&self.indexes,
&starting_indexes,
self.price.as_ref(),
@@ -175,23 +187,56 @@ impl Computer {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.constants.vecs(),
self.indexes.vecs(),
self.market.vecs(),
self.chain.vecs(),
self.stateful.vecs(),
self.cointime.vecs(),
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),
self.price.as_ref().map_or(vec![], |v| v.vecs()),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> =
Box::new(self.fetched.iter().flat_map(|v| v.iter_any_collectable()));
iter = Box::new(iter.chain(self.price.iter().flat_map(|v| v.iter_any_collectable())));
iter = Box::new(iter.chain(self.pools.iter_any_collectable()));
iter = Box::new(iter.chain(self.constants.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes.iter_any_collectable()));
iter = Box::new(iter.chain(self.market.iter_any_collectable()));
iter = Box::new(iter.chain(self.chain.iter_any_collectable()));
iter = Box::new(iter.chain(self.stateful.iter_any_collectable()));
iter = Box::new(iter.chain(self.cointime.iter_any_collectable()));
iter
}
pub fn static_clone(&self) -> &'static Self {
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 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)]
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize, FromPrimitive, IntoPrimitive)]
#[repr(u16)]
#[derive(
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 {
#[default]
Unknown,
BlockFills,
Ultimuspool,
UltimusPool,
TerraPool,
Luxor,
OneTHash,
BTCCom,
OneThash,
BtcCom,
Bitfarms,
HuobiPool,
WayiCn,
CanoePool,
BTCTop,
BtcTop,
BitcoinCom,
OneSevenFiveBtc,
GBMiners,
Pool175btc,
GbMiners,
AXbt,
ASICMiner,
AsicMiner,
BitMinter,
BitcoinRussia,
BTCServ,
BtcServ,
SimplecoinUs,
BTCGuild,
BtcGuild,
Eligius,
OzCoin,
EclipseMC,
MaxBTC,
EclipseMc,
MaxBtc,
TripleMining,
CoinLab,
FiftyBTC,
GHashIO,
STMiningCorp,
Pool50btc,
GhashIo,
StMiningCorp,
Bitparking,
MMPool,
Mmpool,
Polmine,
KnCMiner,
KncMiner,
Bitalo,
F2Pool,
HHTT,
Hhtt,
MegaBigPower,
MtRed,
NMCbit,
NmcBit,
YourbtcNet,
GiveMeCoins,
BraiinsPool,
AntPool,
MultiCoinCo,
BCPoolIo,
BcpoolIo,
Cointerra,
KanoPool,
SoloCK,
CKPool,
SoloCk,
CkPool,
NiceHash,
BitClub,
BitcoinAffiliateNetwork,
BTCC,
BWPool,
EXXAndBW,
Btcc,
BwPool,
ExxBw,
Bitsolo,
BitFury,
TwentyOneInc,
DigitalBTC,
DigitalBtc,
EightBaochi,
MyBTCcoinPool,
TBDice,
HASHPOOL,
MyBtcCoinPool,
TbDice,
HashPool,
Nexious,
BravoMining,
HotPool,
OKExPool,
BCMonster,
OkExPool,
BcMonster,
OneHash,
Bixin,
TATMASPool,
ViaBTC,
ConnectBTC,
BATPOOL,
TatmasPool,
ViaBtc,
ConnectBtc,
BatPool,
Waterhole,
DCExploration,
DCEX,
BTPOOL,
DcExploration,
Dcex,
BtPool,
FiftyEightCoin,
BitcoinIndiaLowercase,
BitcoinIndia,
ShawnP0wers,
PHashIO,
PHashIo,
RigPool,
HAOZHUZHU,
HaoZhuZhu,
SevenPool,
MiningKings,
HashBX,
DPOOL,
HashBx,
DPool,
Rawpool,
Haominer,
Helix,
@@ -114,62 +136,152 @@ pub enum PoolId {
BinancePool,
Minerium,
LubianCom,
OKKONG,
AAOPool,
EMCDPool,
FoundryUSA,
SBICrypto,
Okkong,
AaoPool,
EmcdPool,
FoundryUsa,
SbiCrypto,
ArkPool,
PureBTCCom,
MARAPool,
PureBtcCom,
MaraPool,
KuCoinPool,
EntrustCharityPool,
OKMINER,
OkMiner,
Titan,
PEGAPool,
BTCNuggets,
PegaPool,
BtcNuggets,
CloudHashing,
DigitalXMintsy,
Telco214,
BTCPoolParty,
BtcPoolParty,
Multipool,
TransactionCoinMining,
BTCDig,
TrickysBTCPool,
BTCMP,
BtcDig,
TrickysBtcPool,
BtcMp,
Eobot,
UNOMP,
Unomp,
Patels,
GoGreenLight,
BitcoinIndiaCamel, // duplicate-ish entry preserved with slight name change
EkanemBTC,
CanoeUppercase,
TigerLowercase,
OneM1X,
EkanemBtc,
Canoe,
Tiger,
OneM1x,
Zulupool,
SECPOOL,
OCEAN,
SecPool,
Ocean,
WhitePool,
Wiz,
Mononaut,
Rijndael,
Wk057,
FutureBitApolloSolo,
Emzy,
Knorrium,
CarbonNegative,
PortlandHODL,
PortlandHodl,
Phoenix,
Neopool,
MaxiPool,
DrDetroit,
BitFuFuPool,
LuckyPool,
MiningDutch,
PublicPool,
MiningSquared,
InnopolisTech,
Nymkappa,
BTCLab,
BtcLab,
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 pool;
#[allow(clippy::module_inception)]
mod pools;
mod vecs;
pub use id::*;
pub use pool::*;
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;
#[derive(Debug, Serialize, Deserialize)]
#[derive(Debug, Allocative)]
pub struct Pool {
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 addresses: 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 brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
Cents, Close, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, High, Low, MonthIndex,
OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, SemesterIndex, Version, WeekIndex, YearIndex,
@@ -327,8 +326,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -338,20 +336,18 @@ impl Vecs {
pub fn compute(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
fetched: &fetched::Vecs,
exit: &Exit,
) -> Result<()> {
self.compute_(indexer, indexes, starting_indexes, fetched, exit)?;
self.compute_(indexes, starting_indexes, fetched, exit)?;
self.db.flush_then_punch()?;
Ok(())
}
fn compute_(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
starting_indexes: &Indexes,
fetched: &fetched::Vecs,
@@ -445,12 +441,8 @@ impl Vecs {
})?;
self.dateindex_to_price_ohlc.safe_flush(exit)?;
self.timeindexes_to_price_close.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_close
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -458,15 +450,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_high.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_high
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -474,15 +461,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_low.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_low
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -490,15 +472,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_open.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_open
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
&self.dateindex_to_price_ohlc,
@@ -506,15 +483,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_close.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_close
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -522,15 +494,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_high.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_high
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -538,15 +505,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_low.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_low
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -554,15 +516,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_open.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_open
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.height_to_price_ohlc,
@@ -570,8 +527,7 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let mut weekindex_first_iter = self
.timeindexes_to_price_open
@@ -843,12 +799,8 @@ impl Vecs {
})?;
self.decadeindex_to_price_ohlc.safe_flush(exit)?;
self.chainindexes_to_price_open_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_open_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_open.height,
@@ -856,15 +808,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_high_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_high_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_low.height,
@@ -872,15 +819,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_low_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_low_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_high.height,
@@ -888,15 +830,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.chainindexes_to_price_close_in_sats.compute(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.chainindexes_to_price_close_in_sats
.compute(indexes, starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.height,
&self.chainindexes_to_price_close.height,
@@ -904,15 +841,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_open_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_open_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_open.dateindex.as_ref().unwrap(),
@@ -920,15 +852,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_high_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_high_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_low.dateindex.as_ref().unwrap(),
@@ -936,15 +863,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_low_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_low_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_high.dateindex.as_ref().unwrap(),
@@ -952,15 +874,10 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
self.timeindexes_to_price_close_in_sats.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.timeindexes_to_price_close_in_sats
.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.timeindexes_to_price_close.dateindex.as_ref().unwrap(),
@@ -968,8 +885,7 @@ impl Vecs {
exit,
)?;
Ok(())
},
)?;
})?;
let mut height_first_iter = self.chainindexes_to_price_open_in_sats.height.iter();
let mut height_max_iter = self.chainindexes_to_price_high_in_sats.height.iter();
@@ -1311,9 +1227,9 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
vec![
vec![
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
[
&self.dateindex_to_price_close_in_cents as &dyn AnyCollectableVec,
&self.dateindex_to_price_high_in_cents,
&self.dateindex_to_price_low_in_cents,
@@ -1330,7 +1246,6 @@ impl Vecs {
&self.quarterindex_to_price_ohlc,
&self.semesterindex_to_price_ohlc,
&self.yearindex_to_price_ohlc,
// &self.halvingepoch_to_price_ohlc,
&self.decadeindex_to_price_ohlc,
&self.height_to_price_ohlc_in_sats,
&self.dateindex_to_price_ohlc_in_sats,
@@ -1340,28 +1255,63 @@ impl Vecs {
&self.quarterindex_to_price_ohlc_in_sats,
&self.semesterindex_to_price_ohlc_in_sats,
&self.yearindex_to_price_ohlc_in_sats,
// &self.halvingepoch_to_price_ohlc_in_sats,
&self.decadeindex_to_price_ohlc_in_sats,
],
self.timeindexes_to_price_close.vecs(),
self.timeindexes_to_price_high.vecs(),
self.timeindexes_to_price_low.vecs(),
self.timeindexes_to_price_open.vecs(),
self.chainindexes_to_price_close.vecs(),
self.chainindexes_to_price_high.vecs(),
self.chainindexes_to_price_low.vecs(),
self.chainindexes_to_price_open.vecs(),
self.timeindexes_to_price_close_in_sats.vecs(),
self.timeindexes_to_price_high_in_sats.vecs(),
self.timeindexes_to_price_low_in_sats.vecs(),
self.timeindexes_to_price_open_in_sats.vecs(),
self.chainindexes_to_price_close_in_sats.vecs(),
self.chainindexes_to_price_high_in_sats.vecs(),
self.chainindexes_to_price_low_in_sats.vecs(),
self.chainindexes_to_price_open_in_sats.vecs(),
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
]
.into_iter(),
);
iter = Box::new(iter.chain(self.timeindexes_to_price_close.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_high.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_low.iter_any_collectable()));
iter = Box::new(iter.chain(self.timeindexes_to_price_open.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_close.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_high.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_low.iter_any_collectable()));
iter = Box::new(iter.chain(self.chainindexes_to_price_open.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.timeindexes_to_price_close_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.timeindexes_to_price_high_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(iter.chain(self.timeindexes_to_price_low_in_sats.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.timeindexes_to_price_open_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_close_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_high_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_low_in_sats
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.chainindexes_to_price_open_in_sats
.iter_any_collectable(),
),
);
iter
}
}
@@ -1,7 +1,6 @@
use std::{ops::Deref, path::Path};
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, StoredU64, Version};
use vecdb::{
AnyCollectableVec, AnyIterableVec, AnyStoredVec, AnyVec, Database, EagerVec, Exit, Format,
@@ -85,17 +84,21 @@ impl Vecs {
)?,
})
}
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
self.inner
.iter_any_collectable()
.chain([&self.height_to_addr_count as &dyn AnyCollectableVec])
.chain(self.indexes_to_addr_count.iter_any_collectable())
}
}
impl DynCohortVecs for Vecs {
fn min_height_vecs_len(&self) -> usize {
[
std::cmp::min(
self.height_to_addr_count.len(),
self.inner.min_height_vecs_len(),
]
.into_iter()
.min()
.unwrap()
)
}
fn reset_state_starting_height(&mut self) {
@@ -171,7 +174,6 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -185,16 +187,7 @@ impl DynCohortVecs for Vecs {
)?;
self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
}
fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.inner.vecs(),
self.indexes_to_addr_count.vecs(),
vec![&self.height_to_addr_count],
]
.concat()
.compute_rest_part1(indexes, price, starting_indexes, exit)
}
}
@@ -224,7 +217,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -237,7 +229,6 @@ impl CohortVecs for Vecs {
exit: &Exit,
) -> Result<()> {
self.inner.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -251,10 +242,3 @@ impl CohortVecs for Vecs {
)
}
}
impl Deref for Vecs {
type Target = common::Vecs;
fn deref(&self) -> &Self::Target {
&self.inner
}
}
@@ -1,7 +1,6 @@
use std::path::Path;
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
AddressGroups, Bitcoin, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, DateIndex,
Dollars, GroupFilter, Height, Version,
@@ -459,18 +458,17 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let by_size_range = self.0.amount_range.as_vec();
let by_size_range = &self.0.amount_range;
[
self.0
.ge_amount
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
@@ -479,13 +477,12 @@ impl Vecs {
.collect::<Vec<_>>(),
self.0
.lt_amount
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
@@ -502,21 +499,19 @@ impl Vecs {
pub fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
})
self.iter_mut()
.into_iter()
.try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
}
#[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -528,27 +523,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| {
v.into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
self.0.iter_mut().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
}
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs()
self.iter_separate_mut()
.into_iter()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
}
@@ -75,11 +75,9 @@ impl AddressTypeToIndexesToAddressCount {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
self.0
.as_typed_vec()
.into_iter()
.flat_map(|(_, v)| v.vecs())
.collect::<Vec<_>>()
.iter_typed()
.flat_map(|(_, v)| v.iter_any_collectable())
}
}
@@ -27,6 +27,10 @@ impl<T> AddressTypeToTypeIndexTree<T> {
mem::swap(own, other);
}
}
pub fn unwrap(self) -> ByAddressType<BTreeMap<TypeIndex, T>> {
self.0
}
}
impl<T> Default for AddressTypeToTypeIndexTree<T> {
@@ -38,6 +38,10 @@ impl<T> AddressTypeToVec<T> {
mem::swap(own, other);
}
}
pub fn unwrap(self) -> ByAddressType<Vec<T>> {
self.0
}
}
impl<T> Default for AddressTypeToVec<T> {
File diff suppressed because it is too large Load Diff
+123 -123
View File
@@ -493,8 +493,7 @@ impl Vecs {
};
this.db.retain_regions(
this.vecs()
.into_iter()
this.iter_any_collectable()
.flat_map(|v| v.region_names())
.collect(),
)?;
@@ -598,8 +597,9 @@ impl Vecs {
+ dateindex_to_first_height.version()
+ dateindex_to_height_count.version();
let mut separate_utxo_vecs = self.utxo_cohorts.as_mut_separate_vecs();
let mut separate_address_vecs = self.address_cohorts.as_mut_separate_vecs();
let mut separate_utxo_vecs = self.utxo_cohorts.iter_separate_mut().collect::<Vec<_>>();
let mut separate_address_vecs =
self.address_cohorts.iter_separate_mut().collect::<Vec<_>>();
separate_utxo_vecs
.par_iter_mut()
@@ -878,13 +878,11 @@ impl Vecs {
info!("Processing chain at {height}...");
self.utxo_cohorts
.as_mut_separate_vecs()
.iter_mut()
.iter_separate_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
self.address_cohorts
.as_mut_separate_vecs()
.iter_mut()
.iter_separate_mut()
.for_each(|(_, v)| v.state.as_mut().unwrap().reset_single_iteration_values());
let timestamp = height_to_timestamp_fixed_iter.unwrap_get_inner(height);
@@ -1252,12 +1250,11 @@ impl Vecs {
let dateindex = is_date_last_height.then_some(dateindex);
self.utxo_cohorts.as_mut_separate_vecs()
.into_par_iter()
self.utxo_cohorts.iter_separate_mut().par_bridge()
.map(|(_, v)| v as &mut dyn DynCohortVecs)
.chain(
self.address_cohorts.as_mut_separate_vecs()
.into_par_iter()
self.address_cohorts.iter_separate_mut()
.par_bridge()
.map(|(_, v)| v as &mut dyn DynCohortVecs),
)
.try_for_each(|v| {
@@ -1309,48 +1306,35 @@ impl Vecs {
info!("Computing rest part 1...");
self.indexes_to_addr_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_addr_count
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_sum_of_others(
starting_indexes.height,
&self
.addresstype_to_height_to_addr_count
.as_typed_vec()
.into_iter()
.iter_typed()
.map(|(_, v)| v)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_empty_addr_count.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
self.indexes_to_empty_addr_count
.compute_all(indexes, starting_indexes, exit, |v| {
v.compute_sum_of_others(
starting_indexes.height,
&self
.addresstype_to_height_to_empty_addr_count
.as_typed_vec()
.into_iter()
.iter_typed()
.map(|(_, v)| v)
.collect::<Vec<_>>(),
exit,
)?;
Ok(())
},
)?;
})?;
self.indexes_to_unspendable_supply.compute_rest(
indexer,
indexes,
price,
starting_indexes,
@@ -1358,7 +1342,6 @@ impl Vecs {
Some(&self.height_to_unspendable_supply),
)?;
self.indexes_to_opreturn_supply.compute_rest(
indexer,
indexes,
price,
starting_indexes,
@@ -1381,36 +1364,30 @@ impl Vecs {
)?;
self.utxo_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?;
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
self.address_cohorts
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)?;
.compute_rest_part1(indexes, price, starting_indexes, exit)?;
if let Some(indexes_to_market_cap) = self.indexes_to_market_cap.as_mut() {
indexes_to_market_cap.compute_all(
indexer,
indexes,
starting_indexes,
exit,
|v, _, _, starting_indexes, exit| {
v.compute_transform(
starting_indexes.dateindex,
self.utxo_cohorts
.all
.1
.indexes_to_supply
.dollars
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
},
)?;
indexes_to_market_cap.compute_all(starting_indexes, exit, |v| {
v.compute_transform(
starting_indexes.dateindex,
self.utxo_cohorts
.all
.1
.indexes_to_supply
.dollars
.as_ref()
.unwrap()
.dateindex
.as_ref()
.unwrap(),
|(i, v, ..)| (i, v),
exit,
)?;
Ok(())
})?;
}
info!("Computing rest part 2...");
@@ -1450,7 +1427,6 @@ impl Vecs {
let dateindex_to_realized_cap_ref = dateindex_to_realized_cap.as_ref();
self.utxo_cohorts.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -1464,7 +1440,6 @@ impl Vecs {
)?;
self.address_cohorts.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
@@ -1655,10 +1630,10 @@ impl Vecs {
&mut self,
height: Height,
chain_state: &[BlockState],
mut addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree<
addresstype_to_typeindex_to_loadedaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>,
>,
mut addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<EmptyAddressData>,
>,
with_changes: bool,
@@ -1667,30 +1642,28 @@ impl Vecs {
info!("Flushing...");
self.utxo_cohorts
.as_mut_separate_vecs()
.par_iter_mut()
.iter_separate_mut()
.par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.address_cohorts
.as_mut_separate_vecs()
.par_iter_mut()
.iter_separate_mut()
.par_bridge()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))?;
self.height_to_unspendable_supply.safe_flush(exit)?;
self.height_to_opreturn_supply.safe_flush(exit)?;
self.addresstype_to_height_to_addr_count
.as_mut_vec()
.into_iter()
.iter_mut()
.try_for_each(|v| v.safe_flush(exit))?;
self.addresstype_to_height_to_empty_addr_count
.as_mut_vec()
.into_iter()
.iter_mut()
.try_for_each(|v| v.safe_flush(exit))?;
let mut addresstype_to_typeindex_to_new_or_updated_anyaddressindex =
AddressTypeToTypeIndexTree::default();
addresstype_to_typeindex_to_emptyaddressdata
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each(
|(typeindex, emptyaddressdata_with_source)| -> Result<()> {
@@ -1742,8 +1715,8 @@ impl Vecs {
})?;
addresstype_to_typeindex_to_loadedaddressdata
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter().try_for_each(
|(typeindex, loadedaddressdata_with_source)| -> Result<()> {
@@ -1795,8 +1768,8 @@ impl Vecs {
})?;
addresstype_to_typeindex_to_new_or_updated_anyaddressindex
.into_typed_vec()
.into_iter()
.unwrap()
.into_iter_typed()
.try_for_each(|(_type, tree)| -> Result<()> {
tree.into_iter()
.try_for_each(|(typeindex, anyaddressindex)| -> Result<()> {
@@ -1864,42 +1837,10 @@ impl Vecs {
Ok(())
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
[
self.utxo_cohorts
.vecs()
.into_iter()
.flat_map(|v| v.vecs())
.collect::<Vec<_>>(),
self.address_cohorts
.vecs()
.into_iter()
.flat_map(|v| v.vecs())
.collect::<Vec<_>>(),
self.indexes_to_unspendable_supply.vecs(),
self.indexes_to_opreturn_supply.vecs(),
self.indexes_to_addr_count.vecs(),
self.indexes_to_empty_addr_count.vecs(),
self.addresstype_to_indexes_to_addr_count.vecs(),
self.indexes_to_market_cap
.as_ref()
.map_or(vec![], |v| v.vecs()),
self.addresstype_to_indexes_to_empty_addr_count.vecs(),
self.addresstype_to_height_to_addr_count
.as_typed_vec()
.into_iter()
.map(|(_, v)| v as &dyn AnyCollectableVec)
.collect::<Vec<_>>(),
self.addresstype_to_height_to_empty_addr_count
.as_typed_vec()
.into_iter()
.map(|(_, v)| v as &dyn AnyCollectableVec)
.collect::<Vec<_>>(),
self.height_to_market_cap
.as_ref()
.map_or(vec![], |v| vec![v]),
vec![
&self.height_to_unspendable_supply,
pub fn iter_any_collectable(&self) -> impl Iterator<Item = &dyn AnyCollectableVec> {
let mut iter: Box<dyn Iterator<Item = &dyn AnyCollectableVec>> = Box::new(
[
&self.height_to_unspendable_supply as &dyn AnyCollectableVec,
&self.height_to_opreturn_supply,
&self.chain_state,
&self.p2pk33addressindex_to_anyaddressindex,
@@ -1914,18 +1855,77 @@ impl Vecs {
&self.emptyaddressindex_to_emptyaddressdata,
&self.loadedaddressindex_to_loadedaddressindex,
&self.emptyaddressindex_to_emptyaddressindex,
],
]
.into_iter()
.flatten()
.collect::<Vec<_>>()
]
.into_iter(),
);
iter = Box::new(
iter.chain(
self.utxo_cohorts
.iter_right()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.address_cohorts
.iter_right()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(iter.chain(self.indexes_to_unspendable_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_opreturn_supply.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_addr_count.iter_any_collectable()));
iter = Box::new(iter.chain(self.indexes_to_empty_addr_count.iter_any_collectable()));
iter = Box::new(
iter.chain(
self.addresstype_to_indexes_to_addr_count
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.indexes_to_market_cap
.iter()
.flat_map(|v| v.iter_any_collectable()),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_indexes_to_empty_addr_count
.iter_any_collectable(),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_height_to_addr_count
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.addresstype_to_height_to_empty_addr_count
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter = Box::new(
iter.chain(
self.height_to_market_cap
.iter()
.map(|v| v as &dyn AnyCollectableVec),
),
);
iter
}
}
impl AddressTypeToVec<(TypeIndex, Sats)> {
#[allow(clippy::too_many_arguments)]
fn process_received(
mut self,
self,
vecs: &mut address_cohorts::Vecs,
addresstype_to_typeindex_to_loadedaddressdata: &mut AddressTypeToTypeIndexTree<
WithAddressDataSource<LoadedAddressData>,
@@ -1940,7 +1940,7 @@ impl AddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>,
>,
) {
self.into_typed_vec().into_iter().for_each(|(_type, vec)| {
self.unwrap().into_iter_typed().for_each(|(_type, vec)| {
vec.into_iter().for_each(|(type_index, value)| {
let mut is_new = false;
let mut from_any_empty = false;
@@ -2044,7 +2044,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
WithAddressDataSource<LoadedAddressData>,
>,
) -> Result<()> {
self.0.into_iter().try_for_each(|(prev_height, mut v)| {
self.0.into_iter().try_for_each(|(prev_height, v)| {
let prev_price = height_to_price_close_vec
.as_ref()
.map(|v| **v.get(prev_height.unwrap_to_usize()).unwrap());
@@ -2062,7 +2062,7 @@ impl HeightToAddressTypeToVec<(TypeIndex, Sats)> {
.unwrap()
.is_more_than_hour();
v.into_typed_vec().into_iter().try_for_each(|(_type, vec)| {
v.unwrap().into_iter_typed().try_for_each(|(_type, vec)| {
vec.into_iter().try_for_each(|(type_index, value)| {
let typeindex_to_loadedaddressdata =
addresstype_to_typeindex_to_loadedaddressdata
+1 -6
View File
@@ -1,7 +1,6 @@
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Exit};
use vecdb::{AnyIterableVec, Exit};
use crate::{Indexes, indexes, price};
@@ -29,14 +28,11 @@ pub trait DynCohortVecs: Send + Sync {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()>;
fn vecs(&self) -> Vec<&dyn AnyCollectableVec>;
}
pub trait CohortVecs: DynCohortVecs {
@@ -50,7 +46,6 @@ pub trait CohortVecs: DynCohortVecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -1,9 +1,8 @@
use std::{ops::Deref, path::Path};
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{Bitcoin, DateIndex, Dollars, Height, Version};
use vecdb::{AnyCollectableVec, AnyIterableVec, Database, Exit, Format};
use vecdb::{AnyIterableVec, Database, Exit, Format};
use crate::{
Indexes, UTXOCohortState, indexes, price,
@@ -122,18 +121,13 @@ impl DynCohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.inner
.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
}
fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
self.inner.vecs()
.compute_rest_part1(indexes, price, starting_indexes, exit)
}
}
@@ -154,7 +148,6 @@ impl CohortVecs for Vecs {
#[allow(clippy::too_many_arguments)]
fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -167,7 +160,6 @@ impl CohortVecs for Vecs {
exit: &Exit,
) -> Result<()> {
self.inner.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
+91 -135
View File
@@ -1,7 +1,6 @@
use std::{collections::BTreeMap, ops::ControlFlow, path::Path};
use brk_error::Result;
use brk_indexer::Indexer;
use brk_structs::{
Bitcoin, ByAgeRange, ByAmountRange, ByEpoch, ByGreatEqualAmount, ByLowerThanAmount, ByMaxAge,
ByMinAge, BySpendableType, ByTerm, CheckedSub, DateIndex, Dollars, GroupFilter, HalvingEpoch,
@@ -1458,8 +1457,7 @@ impl Vecs {
let mut vecs = self
.age_range
.as_mut_vec()
.into_iter()
.iter_mut()
.map(|(filter, v)| (filter, &mut v.state))
.collect::<Vec<_>>();
@@ -1503,9 +1501,8 @@ impl Vecs {
let mut time_based_vecs = self
.0
.age_range
.as_mut_vec()
.into_iter()
.chain(self.0.epoch.as_mut_vec())
.iter_mut()
.chain(self.0.epoch.iter_mut())
.collect::<Vec<_>>();
let last_timestamp = chain_state.last().unwrap().timestamp;
@@ -1551,8 +1548,10 @@ impl Vecs {
);
});
sent.by_type.spendable.as_typed_vec().into_iter().for_each(
|(output_type, supply_state)| {
sent.by_type
.spendable
.iter_typed()
.for_each(|(output_type, supply_state)| {
self.0
._type
.get_mut(output_type)
@@ -1568,12 +1567,10 @@ impl Vecs {
days_old_float,
older_than_hour,
)
},
);
});
sent.by_size_group
.as_typed_vec()
.into_iter()
.iter_typed()
.for_each(|(group, supply_state)| {
self.0
.amount_range
@@ -1606,24 +1603,20 @@ impl Vecs {
v.state.as_mut().unwrap().receive(&supply_state, price);
});
self._type
.as_mut_vec()
.into_iter()
.for_each(|(filter, vecs)| {
let output_type = match filter {
GroupFilter::Type(output_type) => *output_type,
_ => unreachable!(),
};
vecs.state
.as_mut()
.unwrap()
.receive(received.by_type.get(output_type), price)
});
self._type.iter_mut().for_each(|(filter, vecs)| {
let output_type = match filter {
GroupFilter::Type(output_type) => *output_type,
_ => unreachable!(),
};
vecs.state
.as_mut()
.unwrap()
.receive(received.by_type.get(output_type), price)
});
received
.by_size_group
.as_typed_vec()
.into_iter()
.iter_typed()
.for_each(|(group, supply_state)| {
self.amount_range
.get_mut(group)
@@ -1640,95 +1633,64 @@ impl Vecs {
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
let by_date_range = self.0.age_range.as_vec();
let by_size_range = self.0.amount_range.as_vec();
let by_date_range = &self.0.age_range;
let by_size_range = &self.0.amount_range;
[
vec![(
&mut self.0.all.1,
[(
&mut self.0.all.1,
by_date_range.iter().map(|(_, v)| v).collect::<Vec<_>>(),
)]
.into_iter()
.chain(self.0.min_age.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)],
self.0
.min_age
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.max_age
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.term
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_date_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.ge_amount
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
self.0
.lt_amount
.as_mut_vec()
.into_iter()
.map(|(filter, vecs)| {
(
vecs,
by_size_range
.into_iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
})
.collect::<Vec<_>>(),
]
.into_iter()
.flatten()
)
}))
.chain(self.0.max_age.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.term.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_date_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.ge_amount.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_size_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.chain(self.0.lt_amount.iter_mut().map(|(filter, vecs)| {
(
vecs,
by_size_range
.iter()
.filter(|(other, _)| filter.includes(other))
.map(|(_, v)| v)
.collect::<Vec<_>>(),
)
}))
.try_for_each(|(vecs, stateful)| {
vecs.compute_from_stateful(starting_indexes, &stateful, exit)
})
@@ -1736,21 +1698,19 @@ impl Vecs {
pub fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part1(indexer, indexes, price, starting_indexes, exit)
})
self.iter_mut()
.into_iter()
.try_for_each(|(_, v)| v.compute_rest_part1(indexes, price, starting_indexes, exit))
}
#[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
price: Option<&price::Vecs>,
starting_indexes: &Indexes,
@@ -1762,28 +1722,24 @@ impl Vecs {
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
) -> Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| {
v.into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexer,
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
self.iter_mut().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexes,
price,
starting_indexes,
height_to_supply,
dateindex_to_supply,
height_to_market_cap,
dateindex_to_market_cap,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
}
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs()
.into_iter()
self.iter_separate_mut()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
}
}
+6 -3
View File
@@ -23,9 +23,12 @@ pub use indexes::*;
pub use stores::*;
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 COLLISIONS_CHECKED_UP_TO: Height = Height::new(909_150);
const VERSION: Version = Version::ONE;
#[derive(Clone)]
pub struct Indexer {
@@ -39,10 +42,10 @@ impl Indexer {
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");
let stores = Stores::forced_import(&path, VERSION + Version::ZERO)?;
let stores = Stores::forced_import(&path, VERSION)?;
info!("Imported stores");
Ok(Self { vecs, stores })
+14 -34
View File
@@ -27,8 +27,6 @@ pub struct Stores {
ByAddressType<Store<TypeIndexWithOutputindex, Unit>>,
}
const VERSION: Version = Version::ZERO;
impl Stores {
pub fn forced_import(parent: &Path, version: Version) -> Result<Self> {
let path = parent.join("stores");
@@ -49,34 +47,21 @@ impl Stores {
&keyspace,
&path,
"addressbyteshash_to_typeindex",
version + VERSION + Version::ZERO,
version,
None,
)
});
let blockhashprefix_to_height = scope.spawn(|| {
Store::import(
&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,
)
Store::import(&keyspace, &path, "blockhashprefix_to_height", version, None)
});
let txidprefix_to_txindex = scope
.spawn(|| Store::import(&keyspace, &path, "txidprefix_to_txindex", version, None));
let p2aaddressindex_with_outputindex = scope.spawn(|| {
Store::import(
&keyspace,
&path,
"p2aaddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -85,7 +70,7 @@ impl Stores {
&keyspace,
&path,
"p2pk33addressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -94,7 +79,7 @@ impl Stores {
&keyspace,
&path,
"p2pk65addressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -103,7 +88,7 @@ impl Stores {
&keyspace,
&path,
"p2pkhaddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -112,7 +97,7 @@ impl Stores {
&keyspace,
&path,
"p2shaddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -121,7 +106,7 @@ impl Stores {
&keyspace,
&path,
"p2traddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -130,7 +115,7 @@ impl Stores {
&keyspace,
&path,
"p2wpkhaddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
@@ -139,18 +124,13 @@ impl Stores {
&keyspace,
&path,
"p2wshaddressindex_with_outputindex",
version + VERSION + Version::ZERO,
version,
Some(false),
)
});
let height_to_coinbase_tag = Store::import(
&keyspace,
&path,
"height_to_coinbase_tag",
version + VERSION + Version::ZERO,
None,
)?;
let height_to_coinbase_tag =
Store::import(&keyspace, &path, "height_to_coinbase_tag", version, None)?;
Ok(Self {
keyspace: keyspace.clone(),
+44 -150
View File
@@ -17,8 +17,6 @@ use vecdb::{
use crate::Indexes;
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Vecs {
db: Database,
@@ -78,222 +76,118 @@ impl Vecs {
db.set_min_len(PAGE_SIZE * 50_000_000)?;
let this = Self {
emptyoutputindex_to_txindex: CompressedVec::forced_import(
&db,
"txindex",
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,
)?,
emptyoutputindex_to_txindex: CompressedVec::forced_import(&db, "txindex", version)?,
height_to_blockhash: RawVec::forced_import(&db, "blockhash", version)?,
height_to_difficulty: CompressedVec::forced_import(&db, "difficulty", version)?,
height_to_first_emptyoutputindex: CompressedVec::forced_import(
&db,
"first_emptyoutputindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_inputindex: CompressedVec::forced_import(
&db,
"first_inputindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_opreturnindex: CompressedVec::forced_import(
&db,
"first_opreturnindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_outputindex: CompressedVec::forced_import(
&db,
"first_outputindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2aaddressindex: CompressedVec::forced_import(
&db,
"first_p2aaddressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2msoutputindex: CompressedVec::forced_import(
&db,
"first_p2msoutputindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2pk33addressindex: CompressedVec::forced_import(
&db,
"first_p2pk33addressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2pk65addressindex: CompressedVec::forced_import(
&db,
"first_p2pk65addressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2pkhaddressindex: CompressedVec::forced_import(
&db,
"first_p2pkhaddressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2shaddressindex: CompressedVec::forced_import(
&db,
"first_p2shaddressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2traddressindex: CompressedVec::forced_import(
&db,
"first_p2traddressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2wpkhaddressindex: CompressedVec::forced_import(
&db,
"first_p2wpkhaddressindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_p2wshaddressindex: CompressedVec::forced_import(
&db,
"first_p2wshaddressindex",
version + VERSION + Version::ZERO,
)?,
height_to_first_txindex: CompressedVec::forced_import(
&db,
"first_txindex",
version + VERSION + Version::ZERO,
version,
)?,
height_to_first_txindex: CompressedVec::forced_import(&db, "first_txindex", version)?,
height_to_first_unknownoutputindex: CompressedVec::forced_import(
&db,
"first_unknownoutputindex",
version + VERSION + Version::ZERO,
)?,
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,
version,
)?,
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(
&db,
"first_inputindex",
version + VERSION + Version::ZERO,
version,
)?,
txindex_to_first_outputindex: CompressedVec::forced_import(
&db,
"first_outputindex",
version + VERSION + Version::ZERO,
version,
)?,
txindex_to_is_explicitly_rbf: CompressedVec::forced_import(
&db,
"is_explicitly_rbf",
version + VERSION + Version::ZERO,
)?,
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,
version,
)?,
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,
};
+1
View File
@@ -4,6 +4,7 @@ use serde::Deserialize;
#[allow(clippy::upper_case_acronyms)]
#[derive(Debug, Clone, Copy, PartialEq, Eq, Deserialize, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Format {
#[serde(alias = "json")]
JSON,
+4 -4
View File
@@ -7,8 +7,8 @@ use serde::Deserialize;
#[derive(Debug, Deref, JsonSchema)]
pub struct MaybeIds(Vec<String>);
const MAX_STRING_SIZE: usize = 10_000;
const MAX_VECS: usize = 64;
const MAX_VECS: usize = 32;
const MAX_STRING_SIZE: usize = 64 * MAX_VECS;
impl From<String> for MaybeIds {
fn from(value: String) -> Self {
@@ -29,7 +29,7 @@ impl<'de> Deserialize<'de> for MaybeIds {
{
match serde_json::Value::deserialize(deserializer)? {
serde_json::Value::String(str) => {
if str.len() > MAX_STRING_SIZE {
if str.len() <= MAX_STRING_SIZE {
Ok(MaybeIds(sanitize_ids(
str.split(",").map(|s| s.to_string()),
)))
@@ -38,7 +38,7 @@ impl<'de> Deserialize<'de> for MaybeIds {
}
}
serde_json::Value::Array(vec) => {
if vec.len() > MAX_VECS {
if vec.len() <= MAX_VECS {
Ok(MaybeIds(sanitize_ids(
vec.into_iter().map(|s| s.as_str().unwrap().to_string()),
)))
+1
View File
@@ -12,6 +12,7 @@ use schemars::JsonSchema;
use serde::Deserialize;
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, JsonSchema)]
#[serde(rename_all = "lowercase")]
pub enum Index {
#[schemars(description = "Date/day index")]
DateIndex,
+1 -1
View File
@@ -6,7 +6,7 @@ use tabled::Tabled as TabledTabled;
use crate::Format;
#[derive(Debug, Serialize)]
#[serde(untagged)]
#[serde(untagged, rename_all = "lowercase")]
pub enum Output {
Json(Value),
CSV(String),
+4 -2
View File
@@ -2,8 +2,8 @@ use std::collections::BTreeMap;
use brk_computer::Computer;
use brk_indexer::Indexer;
use vecdb::AnyCollectableVec;
use derive_deref::{Deref, DerefMut};
use vecdb::AnyCollectableVec;
use crate::pagination::{PaginatedIndexParam, PaginationParam};
@@ -33,7 +33,9 @@ impl<'a> Vecs<'a> {
.into_iter()
.for_each(|vec| this.insert(vec));
computer.vecs().into_iter().for_each(|vec| this.insert(vec));
computer
.iter_any_collectable()
.for_each(|vec| this.insert(vec));
let mut ids = this.id_to_index_to_vec.keys().cloned().collect::<Vec<_>>();
+15 -44
View File
@@ -1,7 +1,7 @@
use std::path::Path;
use bitcoincore_rpc::{Auth, Client, Result};
use brk_parser::Parser;
use brk_parser::{BlockExtended, Parser};
use brk_structs::Height;
#[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 start = None;
let end = None;
parser
.parse(start, end)
.iter()
.for_each(|(height, _block, hash)| {
println!("{height}: {}", hash);
});
// let start = None;
// let end = None;
// parser
// .parse(start, end)
// .iter()
// .for_each(|(height, _block, hash)| {
// println!("{height}: {}", hash);
// });
let block_0 = parser.get(Height::new(0));
println!(
"{}",
block_0
.txdata
.first()
.unwrap()
.output
.first()
.unwrap()
.script_pubkey
);
dbg!("{}", block_0.coinbase_tag());
let block_158251 = parser.get(Height::new(158251));
println!(
"{}",
block_158251
.txdata
.first()
.unwrap()
.output
.first()
.unwrap()
.script_pubkey
);
dbg!("{}", block_158251.coinbase_tag());
let block_173195 = parser.get(Height::new(173195));
dbg!("{}", block_173195.coinbase_tag());
let block_840_000 = parser.get(Height::new(840_004));
println!(
"{}",
block_840_000
.txdata
.first()
.unwrap()
.output
.first()
.unwrap()
.value
);
dbg!("{}", block_840_000.coinbase_tag());
dbg!(i.elapsed());
+12 -11
View File
@@ -1,19 +1,20 @@
use std::borrow::Cow;
use bitcoin::Block;
pub trait BlockExtended {
fn coinbase_tag(&self) -> String;
fn coinbase_tag(&self) -> Cow<'_, str>;
}
impl BlockExtended for Block {
fn coinbase_tag(&self) -> String {
let Some(input) = self.txdata.first().and_then(|tx| tx.input.first()) else {
return String::new();
};
let bytes = input.script_sig.as_bytes();
String::from_utf8_lossy(bytes)
.chars()
.filter(|&c| c != '\u{FFFD}' && (c >= ' ' || c == '\n' || c == '\r' || c == '\t'))
.take(1_024)
.collect()
fn coinbase_tag(&self) -> Cow<'_, str> {
String::from_utf8_lossy(
self.txdata
.first()
.and_then(|tx| tx.input.first())
.unwrap()
.script_sig
.as_bytes(),
)
}
}
+2
View File
@@ -10,6 +10,8 @@ rust-version.workspace = true
build = "build.rs"
[dependencies]
allocative = { workspace = true }
allocative_derive = { workspace = true }
bitcoin = { workspace = true }
bitcoincore-rpc = { workspace = true }
brk_error = {workspace = true}
+12 -31
View File
@@ -8,47 +8,28 @@ pub struct AddressGroups<T> {
}
impl<T> AddressGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.ge_amount
.as_mut_vec()
.into_iter()
.chain(self.amount_range.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.collect::<Vec<_>>()
.iter_mut()
.chain(self.amount_range.iter_mut())
.chain(self.lt_amount.iter_mut())
}
pub fn as_mut_separate_vecs(&mut self) -> Vec<&mut T> {
self.amount_range
.as_mut_vec()
.into_iter()
.collect::<Vec<_>>()
pub fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.amount_range.iter_mut()
}
pub fn as_mut_overlapping_vecs(&mut self) -> Vec<&mut T> {
self.lt_amount
.as_mut_vec()
.into_iter()
.chain(self.ge_amount.as_mut_vec())
.collect::<Vec<_>>()
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.lt_amount.iter_mut().chain(self.ge_amount.iter_mut())
}
}
impl<T> AddressGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
self.amount_range
.vecs()
.into_iter()
.chain(self.lt_amount.vecs())
.chain(self.ge_amount.vecs())
.collect::<Vec<_>>()
.iter_right()
.chain(self.lt_amount.iter_right())
.chain(self.ge_amount.iter_right())
}
}
@@ -1,7 +1,4 @@
use std::{
mem,
ops::{Add, AddAssign},
};
use std::ops::{Add, AddAssign};
use super::GroupFilter;
use crate::OutputType;
@@ -51,7 +48,21 @@ impl<T> ByAddressType<T> {
}
}
pub fn as_mut_vec(&mut self) -> [&mut T; 8] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65,
&self.p2pk33,
&self.p2pkh,
&self.p2sh,
&self.p2wpkh,
&self.p2wsh,
&self.p2tr,
&self.p2a,
]
.into_iter()
}
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.p2pk65,
&mut self.p2pk33,
@@ -62,9 +73,10 @@ impl<T> ByAddressType<T> {
&mut self.p2tr,
&mut self.p2a,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(OutputType, &T); 8] {
pub fn iter_typed(&self) -> impl Iterator<Item = (OutputType, &T)> {
[
(OutputType::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33),
@@ -75,9 +87,24 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &self.p2tr),
(OutputType::P2A, &self.p2a),
]
.into_iter()
}
pub fn as_mut_typed_vec(&mut self) -> [(OutputType, &mut T); 8] {
pub fn into_iter_typed(self) -> impl Iterator<Item = (OutputType, T)> {
[
(OutputType::P2PK65, self.p2pk65),
(OutputType::P2PK33, self.p2pk33),
(OutputType::P2PKH, self.p2pkh),
(OutputType::P2SH, self.p2sh),
(OutputType::P2WPKH, self.p2wpkh),
(OutputType::P2WSH, self.p2wsh),
(OutputType::P2TR, self.p2tr),
(OutputType::P2A, self.p2a),
]
.into_iter()
}
pub fn iter_typed_mut(&mut self) -> impl Iterator<Item = (OutputType, &mut T)> {
[
(OutputType::P2PK65, &mut self.p2pk65),
(OutputType::P2PK33, &mut self.p2pk33),
@@ -88,27 +115,12 @@ impl<T> ByAddressType<T> {
(OutputType::P2TR, &mut self.p2tr),
(OutputType::P2A, &mut self.p2a),
]
}
pub fn into_typed_vec(&mut self) -> [(OutputType, T); 8]
where
T: Default,
{
[
(OutputType::P2PK65, mem::take(&mut self.p2pk65)),
(OutputType::P2PK33, mem::take(&mut self.p2pk33)),
(OutputType::P2PKH, mem::take(&mut self.p2pkh)),
(OutputType::P2SH, mem::take(&mut self.p2sh)),
(OutputType::P2WPKH, mem::take(&mut self.p2wpkh)),
(OutputType::P2WSH, mem::take(&mut self.p2wsh)),
(OutputType::P2TR, mem::take(&mut self.p2tr)),
(OutputType::P2A, mem::take(&mut self.p2a)),
]
.into_iter()
}
}
impl<T> ByAddressType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 8] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65.1,
&self.p2pk33.1,
@@ -119,6 +131,7 @@ impl<T> ByAddressType<(GroupFilter, T)> {
&self.p2tr.1,
&self.p2a.1,
]
.into_iter()
}
}
@@ -174,7 +187,7 @@ where
impl<T> ByAddressType<Option<T>> {
pub fn take(&mut self) {
self.as_mut_vec().into_iter().for_each(|opt| {
self.iter_mut().for_each(|opt| {
opt.take();
});
}
@@ -52,7 +52,7 @@ impl<T> From<ByAgeRange<T>> for ByAgeRange<(GroupFilter, T)> {
}
impl<T> ByAgeRange<T> {
pub fn as_vec(&mut self) -> [&T; 20] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self.up_to_1d,
&self._1d_to_1w,
@@ -75,9 +75,10 @@ impl<T> ByAgeRange<T> {
&self._12y_to_15y,
&self.from_15y,
]
.into_iter()
}
pub fn as_mut_vec(&mut self) -> [&mut T; 20] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.up_to_1d,
&mut self._1d_to_1w,
@@ -100,11 +101,12 @@ impl<T> ByAgeRange<T> {
&mut self._12y_to_15y,
&mut self.from_15y,
]
.into_iter()
}
}
impl<T> ByAgeRange<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 20] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.up_to_1d.1,
&self._1d_to_1w.1,
@@ -127,5 +129,6 @@ impl<T> ByAgeRange<(GroupFilter, T)> {
&self._12y_to_15y.1,
&self.from_15y.1,
]
.into_iter()
}
}
@@ -124,7 +124,7 @@ impl<T> ByAmountRange<T> {
}
}
pub fn as_vec(&self) -> [&T; 15] {
pub fn iter(&self) -> impl Iterator<Item = &T> {
[
&self._0sats,
&self._1sat_to_10sats,
@@ -142,9 +142,10 @@ impl<T> ByAmountRange<T> {
&self._10k_btc_to_100k_btc,
&self._100k_btc_or_more,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(Sats, &T); 15] {
pub fn iter_typed(&self) -> impl Iterator<Item = (Sats, &T)> {
[
(Sats::ZERO, &self._0sats),
(Sats::_1, &self._1sat_to_10sats),
@@ -162,9 +163,10 @@ impl<T> ByAmountRange<T> {
(Sats::_10K_BTC, &self._10k_btc_to_100k_btc),
(Sats::_100K_BTC, &self._100k_btc_or_more),
]
.into_iter()
}
pub fn as_mut_vec(&mut self) -> [&mut T; 15] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._0sats,
&mut self._1sat_to_10sats,
@@ -182,11 +184,12 @@ impl<T> ByAmountRange<T> {
&mut self._10k_btc_to_100k_btc,
&mut self._100k_btc_or_more,
]
.into_iter()
}
}
impl<T> ByAmountRange<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 15] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._0sats.1,
&self._1sat_to_10sats.1,
@@ -204,6 +207,7 @@ impl<T> ByAmountRange<(GroupFilter, T)> {
&self._10k_btc_to_100k_btc.1,
&self._100k_btc_or_more.1,
]
.into_iter()
}
}
+4 -3
View File
@@ -24,7 +24,7 @@ impl<T> From<ByEpoch<T>> for ByEpoch<(GroupFilter, T)> {
}
impl<T> ByEpoch<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 5] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._0,
&mut self._1,
@@ -32,6 +32,7 @@ impl<T> ByEpoch<T> {
&mut self._3,
&mut self._4,
]
.into_iter()
}
pub fn mut_vec_from_height(&mut self, height: Height) -> &mut T {
@@ -53,7 +54,7 @@ impl<T> ByEpoch<T> {
}
impl<T> ByEpoch<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 5] {
[&self._0.1, &self._1.1, &self._2.1, &self._3.1, &self._4.1]
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self._0.1, &self._1.1, &self._2.1, &self._3.1, &self._4.1].into_iter()
}
}
@@ -20,7 +20,7 @@ pub struct ByGreatEqualAmount<T> {
}
impl<T> ByGreatEqualAmount<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 13] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1sat,
&mut self._10sats,
@@ -36,11 +36,12 @@ impl<T> ByGreatEqualAmount<T> {
&mut self._1k_btc,
&mut self._10k_btc,
]
.into_iter()
}
}
impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1sat.1,
&self._10sats.1,
@@ -56,6 +57,7 @@ impl<T> ByGreatEqualAmount<(GroupFilter, T)> {
&self._1k_btc.1,
&self._10k_btc.1,
]
.into_iter()
}
}
@@ -20,7 +20,7 @@ pub struct ByLowerThanAmount<T> {
}
impl<T> ByLowerThanAmount<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 13] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._10sats,
&mut self._100sats,
@@ -36,11 +36,12 @@ impl<T> ByLowerThanAmount<T> {
&mut self._10k_btc,
&mut self._100k_btc,
]
.into_iter()
}
}
impl<T> ByLowerThanAmount<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 13] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._10sats.1,
&self._100sats.1,
@@ -56,6 +57,7 @@ impl<T> ByLowerThanAmount<(GroupFilter, T)> {
&self._10k_btc.1,
&self._100k_btc.1,
]
.into_iter()
}
}
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMaxAge<T> {
}
impl<T> ByMaxAge<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 18] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1w,
&mut self._1m,
@@ -44,11 +44,12 @@ impl<T> ByMaxAge<T> {
&mut self._12y,
&mut self._15y,
]
.into_iter()
}
}
impl<T> ByMaxAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1w.1,
&self._1m.1,
@@ -69,6 +70,7 @@ impl<T> ByMaxAge<(GroupFilter, T)> {
&self._12y.1,
&self._15y.1,
]
.into_iter()
}
}
+4 -2
View File
@@ -23,7 +23,7 @@ pub struct ByMinAge<T> {
}
impl<T> ByMinAge<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 18] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self._1d,
&mut self._1w,
@@ -44,11 +44,12 @@ impl<T> ByMinAge<T> {
&mut self._10y,
&mut self._12y,
]
.into_iter()
}
}
impl<T> ByMinAge<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 18] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self._1d.1,
&self._1w.1,
@@ -69,6 +70,7 @@ impl<T> ByMinAge<(GroupFilter, T)> {
&self._10y.1,
&self._12y.1,
]
.into_iter()
}
}
@@ -37,7 +37,7 @@ impl<T> BySpendableType<T> {
}
}
pub fn as_mut_vec(&mut self) -> [&mut T; 11] {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[
&mut self.p2pk65,
&mut self.p2pk33,
@@ -51,9 +51,10 @@ impl<T> BySpendableType<T> {
&mut self.unknown,
&mut self.empty,
]
.into_iter()
}
pub fn as_typed_vec(&self) -> [(OutputType, &T); 11] {
pub fn iter_typed(&self) -> impl Iterator<Item = (OutputType, &T)> {
[
(OutputType::P2PK65, &self.p2pk65),
(OutputType::P2PK33, &self.p2pk33),
@@ -67,11 +68,12 @@ impl<T> BySpendableType<T> {
(OutputType::Unknown, &self.unknown),
(OutputType::Empty, &self.empty),
]
.into_iter()
}
}
impl<T> BySpendableType<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 11] {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[
&self.p2pk65.1,
&self.p2pk33.1,
@@ -85,6 +87,7 @@ impl<T> BySpendableType<(GroupFilter, T)> {
&self.unknown.1,
&self.empty.1,
]
.into_iter()
}
}
+4 -4
View File
@@ -7,14 +7,14 @@ pub struct ByTerm<T> {
}
impl<T> ByTerm<T> {
pub fn as_mut_vec(&mut self) -> [&mut T; 2] {
[&mut self.short, &mut self.long]
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.short, &mut self.long].into_iter()
}
}
impl<T> ByTerm<(GroupFilter, T)> {
pub fn vecs(&self) -> [&T; 2] {
[&self.short.1, &self.long.1]
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.short.1, &self.long.1].into_iter()
}
}
+31 -51
View File
@@ -18,72 +18,52 @@ pub struct UTXOGroups<T> {
}
impl<T> UTXOGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new([&mut self.all]),
Box::new(self.term.as_mut_vec()),
Box::new(self.max_age.as_mut_vec()),
Box::new(self.min_age.as_mut_vec()),
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.age_range.as_mut_vec()),
Box::new(self.epoch.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
Box::new(self._type.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.all]
.into_iter()
.chain(self.term.as_mut_vec())
.chain(self.max_age.as_mut_vec())
.chain(self.min_age.as_mut_vec())
.chain(self.ge_amount.as_mut_vec())
.chain(self.age_range.as_mut_vec())
.chain(self.epoch.as_mut_vec())
.chain(self.amount_range.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.chain(self._type.as_mut_vec())
.collect::<Vec<_>>()
.chain(self.term.iter_mut())
.chain(self.max_age.iter_mut())
.chain(self.min_age.iter_mut())
.chain(self.ge_amount.iter_mut())
.chain(self.age_range.iter_mut())
.chain(self.epoch.iter_mut())
.chain(self.amount_range.iter_mut())
.chain(self.lt_amount.iter_mut())
.chain(self._type.iter_mut())
}
pub fn as_mut_separate_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_separate_mut(&mut self) -> impl Iterator<Item = &mut T> {
self.age_range
.as_mut_vec()
.into_iter()
.chain(self.epoch.as_mut_vec())
.chain(self.amount_range.as_mut_vec())
.chain(self._type.as_mut_vec())
.collect::<Vec<_>>()
.iter_mut()
.chain(self.epoch.iter_mut())
.chain(self.amount_range.iter_mut())
.chain(self._type.iter_mut())
}
pub fn as_mut_overlapping_vecs(&mut self) -> Vec<&mut T> {
pub fn iter_overlapping_mut(&mut self) -> impl Iterator<Item = &mut T> {
[&mut self.all]
.into_iter()
.chain(self.term.as_mut_vec())
.chain(self.max_age.as_mut_vec())
.chain(self.min_age.as_mut_vec())
.chain(self.lt_amount.as_mut_vec())
.chain(self.ge_amount.as_mut_vec())
.collect::<Vec<_>>()
.chain(self.term.iter_mut())
.chain(self.max_age.iter_mut())
.chain(self.min_age.iter_mut())
.chain(self.lt_amount.iter_mut())
.chain(self.ge_amount.iter_mut())
}
}
impl<T> UTXOGroups<(GroupFilter, T)> {
pub fn vecs(&self) -> Vec<&T> {
pub fn iter_right(&self) -> impl Iterator<Item = &T> {
[&self.all.1]
.into_iter()
.chain(self.term.vecs())
.chain(self.max_age.vecs())
.chain(self.min_age.vecs())
.chain(self.age_range.vecs())
.chain(self.epoch.vecs())
.chain(self.amount_range.vecs())
.chain(self._type.vecs())
.chain(self.lt_amount.vecs())
.chain(self.ge_amount.vecs())
.collect::<Vec<_>>()
.chain(self.term.iter_right())
.chain(self.max_age.iter_right())
.chain(self.min_age.iter_right())
.chain(self.age_range.iter_right())
.chain(self.epoch.iter_right())
.chain(self.amount_range.iter_right())
.chain(self._type.iter_right())
.chain(self.lt_amount.iter_right())
.chain(self.ge_amount.iter_right())
}
}
@@ -25,6 +25,25 @@ pub enum AddressBytes {
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 {
pub fn as_slice(&self) -> &[u8] {
match self {
@@ -44,6 +44,7 @@ impl Serialize for AnyAddressIndex {
}
#[derive(Debug, Serialize)]
#[serde(rename_all = "lowercase")]
pub enum AnyAddressDataIndexEnum {
Loaded(LoadedAddressIndex),
Empty(EmptyAddressIndex),
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div, Mul},
};
use allocative::Allocative;
use serde::Serialize;
use vecdb::{CheckedSub, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -20,6 +21,7 @@ use super::{Sats, StoredF64};
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct Bitcoin(f64);
@@ -132,3 +134,8 @@ impl CheckedSub<usize> for Bitcoin {
Some(Self(self.0 - rhs as f64))
}
}
impl CheckedSub<Bitcoin> for Bitcoin {
fn checked_sub(self, rhs: Bitcoin) -> Option<Self> {
Some(Self(self.0 - rhs.0))
}
}
+24 -1
View File
@@ -1,8 +1,10 @@
use jiff::{Span, civil::Date as Date_, tz::TimeZone};
use jiff::{Span, Zoned, civil::Date as Date_, tz::TimeZone};
use serde::{Serialize, Serializer};
use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::ONE_DAY_IN_SEC_F64;
use super::{DateIndex, Timestamp};
#[derive(
@@ -51,6 +53,21 @@ impl Date {
pub fn today() -> Self {
Self::from(Timestamp::now())
}
pub fn completion(&self) -> f64 {
let date = Date_::from(*self);
let now = Zoned::now().with_time_zone(TimeZone::UTC);
let today = now.date();
if date < today {
1.0
} else if date == today {
let rounded = jiff::Timestamp::from(*self);
now.timestamp().duration_since(rounded).as_secs_f64() / ONE_DAY_IN_SEC_F64
} else {
0.0
}
}
}
impl Default for Date {
@@ -71,6 +88,12 @@ impl From<Date> for Date_ {
}
}
impl From<Date> for jiff::Timestamp {
fn from(value: Date) -> Self {
Self::from(Timestamp::from(value))
}
}
impl From<Timestamp> for Date {
fn from(value: Timestamp) -> Self {
Self::from(Date_::from(
+3 -1
View File
@@ -3,10 +3,11 @@ use std::{
ops::{Add, Rem},
};
use allocative::Allocative;
use brk_error::Error;
use vecdb::{CheckedSub, FromCoarserIndex, Printable, StoredCompressed};
use jiff::Span;
use serde::Serialize;
use vecdb::{CheckedSub, FromCoarserIndex, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, WeekIndex, YearIndex};
@@ -28,6 +29,7 @@ use super::Date;
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct DateIndex(u16);
@@ -3,8 +3,9 @@ use std::{
ops::{Add, AddAssign, Div},
};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Date, DateIndex, YearIndex};
@@ -25,6 +26,7 @@ use super::{Date, DateIndex, YearIndex};
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct DecadeIndex(u16);
@@ -3,12 +3,15 @@ use std::{
ops::{Add, AddAssign, Div},
};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
pub const BLOCKS_PER_DIFF_EPOCHS: u32 = 2016;
#[derive(
Debug,
Clone,
@@ -25,6 +28,7 @@ use super::Height;
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct DifficultyEpoch(u16);
@@ -77,7 +81,7 @@ impl Div<usize> for DifficultyEpoch {
impl From<Height> for DifficultyEpoch {
fn from(value: Height) -> Self {
Self((u32::from(value) / 2016) as u16)
Self((u32::from(value) / BLOCKS_PER_DIFF_EPOCHS) as u16)
}
}
+28 -4
View File
@@ -1,14 +1,18 @@
use std::{
cmp::Ordering,
f64,
iter::Sum,
ops::{Add, AddAssign, Div, Mul},
};
use allocative::Allocative;
use derive_deref::Deref;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Low, Open};
use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64};
#[derive(
@@ -24,6 +28,7 @@ use super::{Bitcoin, Cents, Close, High, Sats, StoredF32, StoredF64};
Serialize,
Deserialize,
StoredCompressed,
Allocative,
)]
pub struct Dollars(f64);
@@ -78,15 +83,27 @@ impl From<Dollars> for f64 {
}
}
impl From<Close<Dollars>> for Dollars {
fn from(value: Close<Dollars>) -> Self {
Self(value.0)
impl From<Open<Dollars>> for Dollars {
fn from(value: Open<Dollars>) -> Self {
*value
}
}
impl From<High<Dollars>> for Dollars {
fn from(value: High<Dollars>) -> Self {
Self(value.0)
*value
}
}
impl From<Low<Dollars>> for Dollars {
fn from(value: Low<Dollars>) -> Self {
*value
}
}
impl From<Close<Dollars>> for Dollars {
fn from(value: Close<Dollars>) -> Self {
*value
}
}
@@ -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},
};
use allocative::Allocative;
use serde::Serialize;
use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -10,7 +11,16 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Sats, StoredU64};
#[derive(
Debug, Clone, Copy, Serialize, FromBytes, Immutable, IntoBytes, KnownLayout, StoredCompressed,
Debug,
Clone,
Copy,
Serialize,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct FeeRate(f64);
@@ -3,12 +3,15 @@ use std::{
ops::{Add, AddAssign, Div},
};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Height;
pub const BLOCKS_PER_HALVING: u32 = 210_000;
#[derive(
Debug,
Clone,
@@ -25,6 +28,7 @@ use super::Height;
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct HalvingEpoch(u16);
@@ -76,7 +80,7 @@ impl Add<usize> for HalvingEpoch {
impl From<Height> for HalvingEpoch {
fn from(value: Height) -> Self {
Self((u32::from(value) / 210_000) as u16)
Self((u32::from(value) / BLOCKS_PER_HALVING) as u16)
}
}
+11 -1
View File
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Rem},
};
use allocative::Allocative;
use bitcoincore_rpc::{Client, RpcApi};
use byteview::ByteView;
use derive_deref::Deref;
@@ -11,7 +12,7 @@ use vecdb::{CheckedSub, Printable, Stamp, StoredCompressed};
use zerocopy::{FromBytes, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::copy_first_4bytes;
use crate::{BLOCKS_PER_DIFF_EPOCHS, BLOCKS_PER_HALVING, copy_first_4bytes};
use super::StoredU64;
@@ -32,6 +33,7 @@ use super::StoredU64;
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct Height(u32);
@@ -70,6 +72,14 @@ impl Height {
pub fn is_not_zero(self) -> bool {
self != Self::ZERO
}
pub fn left_before_next_diff_adj(self) -> u32 {
BLOCKS_PER_DIFF_EPOCHS - (*self % BLOCKS_PER_DIFF_EPOCHS)
}
pub fn left_before_next_halving(self) -> u32 {
BLOCKS_PER_HALVING - (*self % BLOCKS_PER_HALVING)
}
}
impl PartialEq<u64> for Height {
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign};
use allocative::Allocative;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -24,6 +25,7 @@ use super::Vin;
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct InputIndex(u64);
+3 -1
View File
@@ -3,8 +3,9 @@ use std::{
ops::{Add, AddAssign, Div},
};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::{Date, DateIndex, YearIndex};
@@ -25,6 +26,7 @@ use super::{Date, DateIndex, YearIndex};
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct MonthIndex(u16);
+40
View File
@@ -3,11 +3,14 @@ use std::{
ops::{Add, AddAssign, Div},
};
use allocative::Allocative;
use derive_deref::{Deref, DerefMut};
use serde::{Serialize, Serializer, ser::SerializeTuple};
use vecdb::StoredCompressed;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::StoredF64;
use super::{Cents, Dollars, Sats};
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
@@ -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>
where
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>
where
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>
where
T: Copy,
@@ -473,6 +503,7 @@ where
DerefMut,
Serialize,
StoredCompressed,
Allocative,
)]
#[repr(transparent)]
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>
// where
// B: From<A>,
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign};
use allocative::Allocative;
use derive_deref::{Deref, DerefMut};
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -26,6 +27,7 @@ use super::Vout;
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct OutputIndex(u64);
@@ -16,6 +16,7 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
KnownLayout,
Serialize,
)]
#[serde(rename_all = "lowercase")]
#[repr(u8)]
pub enum OutputType {
P2PK65,
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div},
};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -25,6 +26,7 @@ use super::MonthIndex;
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct QuarterIndex(u16);
+2
View File
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div, Mul, SubAssign},
};
use allocative::Allocative;
use bitcoin::Amount;
use derive_deref::Deref;
use serde::{Deserialize, Serialize};
@@ -30,6 +31,7 @@ use super::{Bitcoin, Cents, Dollars, Height};
Serialize,
Deserialize,
StoredCompressed,
Allocative,
)]
pub struct Sats(u64);
@@ -3,6 +3,7 @@ use std::{
ops::{Add, AddAssign, Div},
};
use allocative::Allocative;
use serde::{Deserialize, Serialize};
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -25,6 +26,7 @@ use super::MonthIndex;
IntoBytes,
KnownLayout,
StoredCompressed,
Allocative,
)]
pub struct SemesterIndex(u16);
@@ -1,3 +1,4 @@
use allocative::Allocative;
use derive_deref::Deref;
use serde::Serialize;
use vecdb::{Printable, StoredCompressed};
@@ -19,6 +20,7 @@ use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct StoredBool(u16);
@@ -6,11 +6,14 @@ use std::{
ops::{Add, AddAssign, Div, Mul, Sub},
};
use allocative::Allocative;
use derive_deref::Deref;
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Close, StoredU32};
use super::{Dollars, StoredF64};
#[derive(
@@ -25,6 +28,7 @@ use super::{Dollars, StoredF64};
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
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 {
fn checked_sub(self, rhs: Self) -> Option<Self> {
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 {
type Output = Self;
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 {
type Output = Self;
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 {
type Output = Self;
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 {
type Output = StoredF32;
fn mul(self, rhs: StoredF32) -> Self::Output {
@@ -1,9 +1,11 @@
use std::{
cmp::Ordering,
f64,
iter::Sum,
ops::{Add, AddAssign, Div, Mul},
};
use allocative::Allocative;
use derive_deref::Deref;
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -23,6 +25,7 @@ use crate::{Bitcoin, Dollars};
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
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 {
type Output = Self;
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 {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
@@ -159,3 +183,16 @@ impl Printable for StoredF64 {
&["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 derive_deref::Deref;
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 {
fn from(value: ByteView) -> Self {
let bytes = &*value;
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref;
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -27,11 +28,13 @@ use super::{
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct StoredU16(u16);
impl StoredU16 {
pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
pub fn new(v: u16) -> Self {
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 serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -27,15 +28,21 @@ use super::{
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct StoredU32(u32);
impl StoredU32 {
pub const ZERO: Self = Self(0);
pub const ONE: Self = Self(1);
pub fn new(counter: u32) -> Self {
Self(counter)
}
pub fn is_zero(&self) -> bool {
self.0 == 0
}
}
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 {
fn from(value: usize) -> Self {
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 {
type Output = Self;
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 {
fn from(value: f64) -> Self {
if value < 0.0 || value > u32::MAX as f64 {
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref;
use serde::Serialize;
use vecdb::{CheckedSub, Printable, StoredCompressed};
@@ -28,6 +29,7 @@ use super::{
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct StoredU64(u64);
+5 -11
View File
@@ -1,5 +1,6 @@
use std::ops::{Add, AddAssign, Div};
use allocative::Allocative;
use derive_deref::Deref;
use jiff::{civil::date, tz::TimeZone};
use serde::Serialize;
@@ -23,12 +24,13 @@ use super::Date;
KnownLayout,
Serialize,
StoredCompressed,
Allocative,
)]
pub struct Timestamp(u32);
const ONE_HOUR_IN_SEC: u32 = 60 * 60;
const ONE_DAY_IN_SEC: u32 = 24 * 60 * 60;
const ONE_DAY_IN_SEC_F64: f64 = ONE_DAY_IN_SEC as f64;
pub const ONE_HOUR_IN_SEC: u32 = 60 * 60;
pub const ONE_DAY_IN_SEC: u32 = 24 * 60 * 60;
pub const ONE_DAY_IN_SEC_F64: f64 = ONE_DAY_IN_SEC as f64;
impl Timestamp {
pub const ZERO: Self = Self(0);
@@ -73,14 +75,6 @@ impl Timestamp {
pub fn now() -> Self {
Self::from(jiff::Timestamp::now())
}
pub fn day_completion(&self) -> f64 {
let rounded = jiff::Timestamp::from(Self::from(Date::from(*self)));
ONE_DAY_IN_SEC_F64
/ jiff::Timestamp::from(*self)
.duration_since(rounded)
.as_secs_f64()
}
}
impl From<u32> for Timestamp {

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