mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-06-26 14:14:30 -07:00
Compare commits
26 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7b38355cd4 | |||
| ddc54e0b98 | |||
| 8a7003782b | |||
| 8e6464dacb | |||
| 92b1dc0afb | |||
| 7562f51e07 | |||
| 09bba99e68 | |||
| 9d674cd49b | |||
| 88a0c9ea03 | |||
| 5014e0ce3e | |||
| b7a1ee9ebc | |||
| 292ceddd66 | |||
| 4b52b80000 | |||
| 9f20664c6e | |||
| 851a6aac0e | |||
| 1f1e73c47a | |||
| 112f61ca18 | |||
| 96eeacbe2b | |||
| 3f62da879c | |||
| aa30feb875 | |||
| 9ba3c2b7c5 | |||
| 320c708e10 | |||
| efa7294f59 | |||
| ae0e092935 | |||
| c77aecbfce | |||
| 700352ec45 |
@@ -33,6 +33,5 @@ paths.d.ts
|
||||
# Outputs
|
||||
_outputs
|
||||
|
||||
|
||||
# Logs
|
||||
.log
|
||||
|
||||
Generated
+233
-231
File diff suppressed because it is too large
Load Diff
+13
-10
@@ -4,7 +4,7 @@ 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.31"
|
||||
package.version = "0.0.39"
|
||||
package.repository = "https://github.com/bitcoinresearchkit/brk"
|
||||
|
||||
[profile.release]
|
||||
@@ -16,8 +16,8 @@ panic = "abort"
|
||||
inherits = "release"
|
||||
|
||||
[workspace.dependencies]
|
||||
axum = "0.8.3"
|
||||
bitcoin = { version = "0.32.5", features = ["serde"] }
|
||||
axum = "0.8.4"
|
||||
bitcoin = { version = "0.32.6", features = ["serde"] }
|
||||
bitcoincore-rpc = "0.19.0"
|
||||
brk_cli = { version = "0", path = "crates/brk_cli" }
|
||||
brk_computer = { version = "0", path = "crates/brk_computer" }
|
||||
@@ -30,19 +30,22 @@ brk_parser = { version = "0", path = "crates/brk_parser" }
|
||||
brk_query = { version = "0", path = "crates/brk_query" }
|
||||
brk_server = { version = "0", path = "crates/brk_server" }
|
||||
brk_vec = { version = "0", path = "crates/brk_vec" }
|
||||
byteview = "0.6.1"
|
||||
clap = { version = "4.5.37", features = ["derive", "string"] }
|
||||
color-eyre = "0.6.3"
|
||||
byteview = "0.7.0"
|
||||
clap = { version = "4.5.38", features = ["string"] }
|
||||
clap_derive = "4.5.32"
|
||||
color-eyre = "0.6.4"
|
||||
derive_deref = "1.1.1"
|
||||
fjall = "2.9.0"
|
||||
jiff = "0.2.10"
|
||||
fjall = "2.10.0"
|
||||
jiff = "0.2.13"
|
||||
log = { version = "0.4.27" }
|
||||
minreq = { version = "2.13.4", features = ["https", "serde_json"] }
|
||||
rayon = "1.10.0"
|
||||
serde = { version = "1.0.219", features = ["derive"] }
|
||||
serde = { version = "1.0.219" }
|
||||
serde_derive = "1.0.219"
|
||||
serde_json = { version = "1.0.140", features = ["float_roundtrip"] }
|
||||
tabled = "0.19.0"
|
||||
zerocopy = { version = "0.8.24", features = ["derive"] }
|
||||
zerocopy = { version = "0.8.25" }
|
||||
zerocopy-derive = "0.8.25"
|
||||
|
||||
[workspace.metadata.release]
|
||||
shared-version = true
|
||||
|
||||
@@ -93,8 +93,10 @@ If you'd like to have your own instance hosted for you please contact [hosting@b
|
||||
|
||||
- 2 separate dedicated servers (1 GB/s each) with different ISPs and Cloudflare integration for enhanced performance and optimal availability
|
||||
- 99.9% SLA
|
||||
- Direct communication for feature requests and support
|
||||
- Configurated for speed (`raw + eager`)
|
||||
- Updates delivered at your convenience
|
||||
- Direct communication for feature requests and support
|
||||
- Bitcoin Core or Knots with desired version
|
||||
- Optional subdomains: `*.bitcoinresearchkit.org`, `*.kibo.money` and `*.satonomics.xyz`
|
||||
- Logo featured in the Readme if desired
|
||||
|
||||
|
||||
@@ -16,12 +16,14 @@ brk_logger = { workspace = true }
|
||||
brk_parser = { workspace = true }
|
||||
brk_query = { workspace = true }
|
||||
brk_server = { workspace = true }
|
||||
clap = { workspace = true, features = ["string"] }
|
||||
brk_vec = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_derive = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
log = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
tabled = { workspace = true }
|
||||
toml = "0.8.20"
|
||||
toml = "0.8.22"
|
||||
|
||||
[[bin]]
|
||||
name = "brk"
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::fs;
|
||||
|
||||
use brk_core::{dot_brk_log_path, dot_brk_path};
|
||||
use brk_query::Params as QueryArgs;
|
||||
use clap::{Parser, Subcommand};
|
||||
use clap::Parser;
|
||||
use clap_derive::{Parser, Subcommand};
|
||||
use query::query;
|
||||
use run::{RunConfig, run};
|
||||
|
||||
|
||||
@@ -14,7 +14,7 @@ pub fn query(params: QueryParams) -> color_eyre::Result<()> {
|
||||
indexer.import_vecs()?;
|
||||
|
||||
let mut computer = Computer::new(&config.outputsdir(), config.fetcher(), compressed);
|
||||
computer.import_vecs()?;
|
||||
computer.import_vecs(&indexer, config.computation())?;
|
||||
|
||||
let query = Query::build(&indexer, &computer);
|
||||
|
||||
|
||||
+77
-60
@@ -1,7 +1,7 @@
|
||||
use std::{
|
||||
fs,
|
||||
path::{Path, PathBuf},
|
||||
thread::sleep,
|
||||
thread::{self, sleep},
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
@@ -12,7 +12,8 @@ use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::rpc::{self, Auth, Client, RpcApi};
|
||||
use brk_server::{Server, Website, tokio};
|
||||
use clap::{Parser, ValueEnum};
|
||||
use brk_vec::Computation;
|
||||
use clap_derive::{Parser, ValueEnum};
|
||||
use color_eyre::eyre::eyre;
|
||||
use log::info;
|
||||
use serde::{Deserialize, Serialize};
|
||||
@@ -32,77 +33,85 @@ pub fn run(config: RunConfig) -> color_eyre::Result<()> {
|
||||
indexer.import_stores()?;
|
||||
indexer.import_vecs()?;
|
||||
|
||||
let mut computer = Computer::new(&config.outputsdir(), config.fetcher(), compressed);
|
||||
computer.import_stores(&indexer)?;
|
||||
computer.import_vecs()?;
|
||||
let wait_for_synced_node = || -> color_eyre::Result<()> {
|
||||
let is_synced = || -> color_eyre::Result<bool> {
|
||||
let info = rpc.get_blockchain_info()?;
|
||||
Ok(info.headers == info.blocks)
|
||||
};
|
||||
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()?
|
||||
.block_on(async {
|
||||
let server = if config.serve() {
|
||||
let served_indexer = indexer.clone();
|
||||
let served_computer = computer.clone();
|
||||
if !is_synced()? {
|
||||
info!("Waiting for node to be synced...");
|
||||
while !is_synced()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
|
||||
let server = Server::new(served_indexer, served_computer, config.website())?;
|
||||
Ok(())
|
||||
};
|
||||
|
||||
let opt = Some(tokio::spawn(async move {
|
||||
server.serve().await.unwrap();
|
||||
}));
|
||||
let f = move || -> color_eyre::Result<()> {
|
||||
let mut computer = Computer::new(&config.outputsdir(), config.fetcher(), compressed);
|
||||
computer.import_stores(&indexer)?;
|
||||
computer.import_vecs(&indexer, config.computation())?;
|
||||
|
||||
sleep(Duration::from_secs(1));
|
||||
tokio::runtime::Builder::new_multi_thread()
|
||||
.enable_all()
|
||||
.build()?
|
||||
.block_on(async {
|
||||
let server = if config.serve() {
|
||||
let served_indexer = indexer.clone();
|
||||
let served_computer = computer.clone();
|
||||
|
||||
opt
|
||||
} else {
|
||||
None
|
||||
};
|
||||
let server = Server::new(served_indexer, served_computer, config.website())?;
|
||||
|
||||
if config.process() {
|
||||
let wait_for_synced_node = || -> color_eyre::Result<()> {
|
||||
let is_synced = || -> color_eyre::Result<bool> {
|
||||
let info = rpc.get_blockchain_info()?;
|
||||
Ok(info.headers == info.blocks)
|
||||
};
|
||||
let opt = Some(tokio::spawn(async move {
|
||||
server.serve().await.unwrap();
|
||||
}));
|
||||
|
||||
if !is_synced()? {
|
||||
info!("Waiting for node to be synced...");
|
||||
while !is_synced()? {
|
||||
sleep(Duration::from_secs(1));
|
||||
|
||||
opt
|
||||
} else {
|
||||
None
|
||||
};
|
||||
|
||||
if config.process() {
|
||||
loop {
|
||||
wait_for_synced_node()?;
|
||||
|
||||
let block_count = rpc.get_block_count()?;
|
||||
|
||||
info!("{} blocks found.", block_count + 1);
|
||||
|
||||
let starting_indexes = indexer.index(&parser, rpc, &exit)?;
|
||||
|
||||
computer.compute(&mut indexer, starting_indexes, &exit)?;
|
||||
|
||||
if let Some(delay) = config.delay() {
|
||||
sleep(Duration::from_secs(delay))
|
||||
}
|
||||
|
||||
info!("Waiting for new blocks...");
|
||||
|
||||
while block_count == rpc.get_block_count()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
};
|
||||
|
||||
loop {
|
||||
wait_for_synced_node()?;
|
||||
|
||||
let block_count = rpc.get_block_count()?;
|
||||
|
||||
info!("{} blocks found.", block_count + 1);
|
||||
|
||||
let starting_indexes = indexer.index(&parser, rpc, &exit)?;
|
||||
|
||||
computer.compute(&mut indexer, starting_indexes, &exit)?;
|
||||
|
||||
if let Some(delay) = config.delay() {
|
||||
sleep(Duration::from_secs(delay))
|
||||
}
|
||||
|
||||
info!("Waiting for new blocks...");
|
||||
|
||||
while block_count == rpc.get_block_count()? {
|
||||
sleep(Duration::from_secs(1))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(handle) = server {
|
||||
handle.await.unwrap();
|
||||
}
|
||||
if let Some(handle) = server {
|
||||
handle.await.unwrap();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})
|
||||
Ok(())
|
||||
})
|
||||
};
|
||||
|
||||
thread::Builder::new()
|
||||
.stack_size(128 * 1024 * 1024)
|
||||
.spawn(f)?
|
||||
.join()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
#[derive(Parser, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
|
||||
@@ -123,6 +132,10 @@ pub struct RunConfig {
|
||||
#[arg(short, long)]
|
||||
mode: Option<Mode>,
|
||||
|
||||
/// Computation mode for compatible datasets, `lazy` computes data whenever requested without saving it, `eager` computes the data once and saves it to disk, default: Lazy, saved
|
||||
#[arg(short = 'C', long)]
|
||||
computation: Option<Computation>,
|
||||
|
||||
/// Activate compression of datasets, set to true to save disk space or false if prioritize speed, default: true, saved
|
||||
#[arg(short, long, value_name = "BOOL")]
|
||||
compressed: Option<bool>,
|
||||
@@ -413,6 +426,10 @@ impl RunConfig {
|
||||
.then(|| Fetcher::import(Some(self.harsdir().as_path())).unwrap())
|
||||
}
|
||||
|
||||
pub fn computation(&self) -> Computation {
|
||||
self.computation.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn compressed(&self) -> bool {
|
||||
self.compressed.is_none_or(|b| b)
|
||||
}
|
||||
|
||||
@@ -14,6 +14,12 @@ brk_indexer = { workspace = true }
|
||||
brk_logger = { workspace = true }
|
||||
brk_parser = { workspace = true }
|
||||
brk_vec = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_derive = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
derive_deref = { workspace = true }
|
||||
fjall = { workspace = true }
|
||||
log = { workspace = true }
|
||||
rayon = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::dot_brk_path;
|
||||
use brk_indexer::Indexer;
|
||||
|
||||
pub fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
|
||||
brk_logger::init(Some(Path::new(".log")));
|
||||
|
||||
let outputs_dir = dot_brk_path().join("outputs");
|
||||
// let outputs_dir = Path::new("../../_outputs");
|
||||
|
||||
let compressed = false;
|
||||
|
||||
let mut indexer = Indexer::new(outputs_dir.as_path(), compressed, true)?;
|
||||
indexer.import_stores()?;
|
||||
indexer.import_vecs()?;
|
||||
|
||||
let height_to_timestamp = &indexer.vecs().height_to_timestamp;
|
||||
|
||||
dbg!(height_to_timestamp.len());
|
||||
|
||||
// height_to_timestamp.iter().for_each(|t| {
|
||||
// dbg!(t);
|
||||
// });
|
||||
|
||||
// let index = max_from.min(A::from(self.len()));
|
||||
let mut height_to_timestamp_iter = height_to_timestamp.iter();
|
||||
// height_to_timestamp.iter().for_each(|t| {
|
||||
// dbg!(t);
|
||||
// });
|
||||
(0..2).for_each(|i| {
|
||||
dbg!(height_to_timestamp_iter.get_(i));
|
||||
});
|
||||
// for_each(|t| {
|
||||
// dbg!(t);
|
||||
// });
|
||||
// .try_for_each(|(height, timestamp)| -> Result<()> {
|
||||
// let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| {
|
||||
// dbg!((height, prev_h));
|
||||
// let prev_timestamp = height_to_timestamp_iter
|
||||
// .nth(prev_h.unwrap_to_usize())
|
||||
// .context("To work")
|
||||
// .inspect_err(|_| {
|
||||
// dbg!(prev_h);
|
||||
// })
|
||||
// .unwrap()
|
||||
// .1
|
||||
// .into_inner();
|
||||
// timestamp
|
||||
// .into_inner()
|
||||
// .checked_sub(prev_timestamp)
|
||||
// .unwrap_or(Timestamp::ZERO)
|
||||
// // Ok(())
|
||||
// });
|
||||
|
||||
// Ok(())
|
||||
// // let (i, v) = t((a, b.into_inner(), self, &mut other_iter));
|
||||
// // self.forced_push_at(i, v, exit)
|
||||
// })?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,11 +1,12 @@
|
||||
use std::path::Path;
|
||||
use std::{path::Path, thread};
|
||||
|
||||
use brk_computer::Computer;
|
||||
use brk_core::default_bitcoin_path;
|
||||
use brk_core::{default_bitcoin_path, default_brk_path};
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::{Parser, rpc};
|
||||
use brk_vec::Computation;
|
||||
|
||||
pub fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
@@ -20,25 +21,34 @@ pub fn main() -> color_eyre::Result<()> {
|
||||
)?));
|
||||
let exit = Exit::new();
|
||||
|
||||
let parser = Parser::new(bitcoin_dir.join("blocks"), rpc);
|
||||
// Can't increase main thread's stack programatically, thus we need to use another thread
|
||||
thread::Builder::new()
|
||||
.stack_size(32 * 1024 * 1024)
|
||||
.spawn(move || -> color_eyre::Result<()> {
|
||||
let parser = Parser::new(bitcoin_dir.join("blocks"), rpc);
|
||||
|
||||
let outputs_dir = Path::new("../../_outputs");
|
||||
let _outputs_dir = default_brk_path().join("outputs");
|
||||
let outputs_dir = _outputs_dir.as_path();
|
||||
// let outputs_dir = Path::new("../../_outputs");
|
||||
|
||||
let compressed = false;
|
||||
let compressed = false;
|
||||
|
||||
let mut indexer = Indexer::new(outputs_dir, compressed, true)?;
|
||||
indexer.import_stores()?;
|
||||
indexer.import_vecs()?;
|
||||
let mut indexer = Indexer::new(outputs_dir, compressed, true)?;
|
||||
indexer.import_stores()?;
|
||||
indexer.import_vecs()?;
|
||||
|
||||
let fetcher = Fetcher::import(None)?;
|
||||
let fetcher = Fetcher::import(None)?;
|
||||
|
||||
let mut computer = Computer::new(outputs_dir, Some(fetcher), compressed);
|
||||
computer.import_stores(&indexer)?;
|
||||
computer.import_vecs()?;
|
||||
let mut computer = Computer::new(outputs_dir, Some(fetcher), compressed);
|
||||
computer.import_stores(&indexer)?;
|
||||
computer.import_vecs(&indexer, Computation::Lazy)?;
|
||||
|
||||
let starting_indexes = indexer.index(&parser, rpc, &exit)?;
|
||||
let starting_indexes = indexer.index(&parser, rpc, &exit)?;
|
||||
|
||||
computer.compute(&mut indexer, starting_indexes, &exit)?;
|
||||
computer.compute(&mut indexer, starting_indexes, &exit)?;
|
||||
|
||||
Ok(())
|
||||
Ok(())
|
||||
})?
|
||||
.join()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
@@ -7,14 +7,18 @@ use std::path::{Path, PathBuf};
|
||||
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::{Indexer, Indexes};
|
||||
use brk_indexer::Indexer;
|
||||
pub use brk_parser::rpc;
|
||||
use brk_vec::{AnyCollectableVec, Compressed, Computation};
|
||||
|
||||
mod storage;
|
||||
mod states;
|
||||
mod stores;
|
||||
mod utils;
|
||||
mod vecs;
|
||||
|
||||
use brk_vec::Compressed;
|
||||
use log::info;
|
||||
use storage::{Stores, Vecs};
|
||||
use stores::Stores;
|
||||
use vecs::Vecs;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Computer {
|
||||
@@ -36,10 +40,16 @@ impl Computer {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn import_vecs(&mut self) -> color_eyre::Result<()> {
|
||||
pub fn import_vecs(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
computation: Computation,
|
||||
) -> color_eyre::Result<()> {
|
||||
self.vecs = Some(Vecs::import(
|
||||
&self.path.join("vecs/computed"),
|
||||
indexer,
|
||||
self.fetcher.is_some(),
|
||||
computation,
|
||||
self.compressed,
|
||||
)?);
|
||||
Ok(())
|
||||
@@ -60,7 +70,7 @@ impl Computer {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &mut Indexer,
|
||||
starting_indexes: Indexes,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
info!("Computing...");
|
||||
@@ -75,13 +85,14 @@ impl Computer {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> &Vecs {
|
||||
self.vecs.as_ref().unwrap()
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
// pub fn vecs(&self) -> &Vecs {
|
||||
self.vecs.as_ref().unwrap().vecs()
|
||||
}
|
||||
|
||||
pub fn mut_vecs(&mut self) -> &mut Vecs {
|
||||
self.vecs.as_mut().unwrap()
|
||||
}
|
||||
// pub fn mut_vecs(&mut self) -> &mut Vecs {
|
||||
// self.vecs.as_mut().unwrap()
|
||||
// }
|
||||
|
||||
pub fn stores(&self) -> &Stores {
|
||||
self.stores.as_ref().unwrap()
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use brk_core::{Sats, StoredU32};
|
||||
|
||||
pub struct BlockState {
|
||||
utxos: StoredU32,
|
||||
value: Sats,
|
||||
}
|
||||
@@ -0,0 +1,155 @@
|
||||
#![allow(unused)]
|
||||
|
||||
use brk_core::{Dollars, Sats, StoredUsize};
|
||||
|
||||
// Vecs ? probably
|
||||
#[derive(Default)]
|
||||
pub struct CohortStates {
|
||||
pub realized_cap: Dollars,
|
||||
pub supply: Sats,
|
||||
pub utxo_count: StoredUsize,
|
||||
// pub price_to_amount: PriceToValue<Amount>, save it not rounded in fjall
|
||||
}
|
||||
|
||||
pub struct OneShotSats {
|
||||
pub price_paid_state: PricePaidState,
|
||||
pub unrealized_block_state: UnrealizedState,
|
||||
pub unrealized_date_state: Option<UnrealizedState>,
|
||||
}
|
||||
|
||||
pub struct UnrealizedState {
|
||||
supply_in_profit: Sats,
|
||||
// supply_in_loss: Sats,
|
||||
unrealized_profit: Dollars,
|
||||
unrealized_loss: Dollars,
|
||||
}
|
||||
|
||||
// Why option ?
|
||||
#[derive(Default, Debug)]
|
||||
pub struct PricePaidState {
|
||||
pp_p5: Option<Dollars>,
|
||||
pp_p10: Option<Dollars>,
|
||||
pp_p15: Option<Dollars>,
|
||||
pp_p20: Option<Dollars>,
|
||||
pp_p25: Option<Dollars>,
|
||||
pp_p30: Option<Dollars>,
|
||||
pp_p35: Option<Dollars>,
|
||||
pp_p40: Option<Dollars>,
|
||||
pp_p45: Option<Dollars>,
|
||||
pp_median: Option<Dollars>,
|
||||
pp_p55: Option<Dollars>,
|
||||
pp_p60: Option<Dollars>,
|
||||
pp_p65: Option<Dollars>,
|
||||
pp_p70: Option<Dollars>,
|
||||
pp_p75: Option<Dollars>,
|
||||
pp_p80: Option<Dollars>,
|
||||
pp_p85: Option<Dollars>,
|
||||
pp_p90: Option<Dollars>,
|
||||
pp_p95: Option<Dollars>,
|
||||
|
||||
processed_amount: Sats,
|
||||
}
|
||||
|
||||
pub struct PricePaidStateFull {
|
||||
pp_p1: Option<Dollars>,
|
||||
pp_p2: Option<Dollars>,
|
||||
pp_p3: Option<Dollars>,
|
||||
pp_p4: Option<Dollars>,
|
||||
pp_p5: Option<Dollars>,
|
||||
pp_p6: Option<Dollars>,
|
||||
pp_p7: Option<Dollars>,
|
||||
pp_p8: Option<Dollars>,
|
||||
pp_p9: Option<Dollars>,
|
||||
pp_p10: Option<Dollars>,
|
||||
pp_p11: Option<Dollars>,
|
||||
pp_p12: Option<Dollars>,
|
||||
pp_p13: Option<Dollars>,
|
||||
pp_p14: Option<Dollars>,
|
||||
pp_p15: Option<Dollars>,
|
||||
pp_p16: Option<Dollars>,
|
||||
pp_p17: Option<Dollars>,
|
||||
pp_p18: Option<Dollars>,
|
||||
pp_p19: Option<Dollars>,
|
||||
pp_p20: Option<Dollars>,
|
||||
pp_p21: Option<Dollars>,
|
||||
pp_p22: Option<Dollars>,
|
||||
pp_p23: Option<Dollars>,
|
||||
pp_p24: Option<Dollars>,
|
||||
pp_p25: Option<Dollars>,
|
||||
pp_p26: Option<Dollars>,
|
||||
pp_p27: Option<Dollars>,
|
||||
pp_p28: Option<Dollars>,
|
||||
pp_p29: Option<Dollars>,
|
||||
pp_p30: Option<Dollars>,
|
||||
pp_p31: Option<Dollars>,
|
||||
pp_p32: Option<Dollars>,
|
||||
pp_p33: Option<Dollars>,
|
||||
pp_p34: Option<Dollars>,
|
||||
pp_p35: Option<Dollars>,
|
||||
pp_p36: Option<Dollars>,
|
||||
pp_p37: Option<Dollars>,
|
||||
pp_p38: Option<Dollars>,
|
||||
pp_p39: Option<Dollars>,
|
||||
pp_p40: Option<Dollars>,
|
||||
pp_p41: Option<Dollars>,
|
||||
pp_p42: Option<Dollars>,
|
||||
pp_p43: Option<Dollars>,
|
||||
pp_p44: Option<Dollars>,
|
||||
pp_p45: Option<Dollars>,
|
||||
pp_p46: Option<Dollars>,
|
||||
pp_p47: Option<Dollars>,
|
||||
pp_p48: Option<Dollars>,
|
||||
pp_p49: Option<Dollars>,
|
||||
pp_p50: Option<Dollars>,
|
||||
pp_p51: Option<Dollars>,
|
||||
pp_p52: Option<Dollars>,
|
||||
pp_p53: Option<Dollars>,
|
||||
pp_p54: Option<Dollars>,
|
||||
pp_p55: Option<Dollars>,
|
||||
pp_p56: Option<Dollars>,
|
||||
pp_p57: Option<Dollars>,
|
||||
pp_p58: Option<Dollars>,
|
||||
pp_p59: Option<Dollars>,
|
||||
pp_p60: Option<Dollars>,
|
||||
pp_p61: Option<Dollars>,
|
||||
pp_p62: Option<Dollars>,
|
||||
pp_p63: Option<Dollars>,
|
||||
pp_p64: Option<Dollars>,
|
||||
pp_p65: Option<Dollars>,
|
||||
pp_p66: Option<Dollars>,
|
||||
pp_p67: Option<Dollars>,
|
||||
pp_p68: Option<Dollars>,
|
||||
pp_p69: Option<Dollars>,
|
||||
pp_p70: Option<Dollars>,
|
||||
pp_p71: Option<Dollars>,
|
||||
pp_p72: Option<Dollars>,
|
||||
pp_p73: Option<Dollars>,
|
||||
pp_p74: Option<Dollars>,
|
||||
pp_p75: Option<Dollars>,
|
||||
pp_p76: Option<Dollars>,
|
||||
pp_p77: Option<Dollars>,
|
||||
pp_p78: Option<Dollars>,
|
||||
pp_p79: Option<Dollars>,
|
||||
pp_p80: Option<Dollars>,
|
||||
pp_p81: Option<Dollars>,
|
||||
pp_p82: Option<Dollars>,
|
||||
pp_p83: Option<Dollars>,
|
||||
pp_p84: Option<Dollars>,
|
||||
pp_p85: Option<Dollars>,
|
||||
pp_p86: Option<Dollars>,
|
||||
pp_p87: Option<Dollars>,
|
||||
pp_p88: Option<Dollars>,
|
||||
pp_p89: Option<Dollars>,
|
||||
pp_p90: Option<Dollars>,
|
||||
pp_p91: Option<Dollars>,
|
||||
pp_p92: Option<Dollars>,
|
||||
pp_p93: Option<Dollars>,
|
||||
pp_p94: Option<Dollars>,
|
||||
pp_p95: Option<Dollars>,
|
||||
pp_p96: Option<Dollars>,
|
||||
pp_p97: Option<Dollars>,
|
||||
pp_p98: Option<Dollars>,
|
||||
pp_p99: Option<Dollars>,
|
||||
|
||||
processed_amount: Sats,
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
mod block;
|
||||
mod cohort;
|
||||
mod outputs;
|
||||
|
||||
pub use block::*;
|
||||
pub use cohort::*;
|
||||
pub use outputs::*;
|
||||
@@ -0,0 +1,107 @@
|
||||
#![allow(unused)]
|
||||
|
||||
#[derive(Default, Clone)]
|
||||
pub struct Outputs<T> {
|
||||
pub all: T,
|
||||
// pub by_term: OutputsByTerm<T>,
|
||||
// pub by_up_to: OutputsByUpTo<T>,
|
||||
// pub by_from: OutputsByFrom<T>,
|
||||
// pub by_range: OutputsByRange<T>,
|
||||
// pub by_epoch: OutputsByEpoch<T>,
|
||||
// pub by_size: OutputsBySize<T>,
|
||||
// pub by_value: OutputsByValue<T>,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByTerm<T> {
|
||||
pub short: T,
|
||||
pub long: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByUpTo<T> {
|
||||
pub _1d: T,
|
||||
pub _1w: T,
|
||||
pub _1m: T,
|
||||
pub _2m: T,
|
||||
pub _3m: T,
|
||||
pub _4m: T,
|
||||
pub _5m: T,
|
||||
pub _6m: T,
|
||||
pub _1y: T,
|
||||
pub _2y: T,
|
||||
pub _3y: T,
|
||||
pub _5y: T,
|
||||
pub _7y: T,
|
||||
pub _10y: T,
|
||||
pub _15y: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByRange<T> {
|
||||
pub _1d_to_1w: T,
|
||||
pub _1w_to_1m: T,
|
||||
pub _1m_to_3m: T,
|
||||
pub _3m_to_6m: T,
|
||||
pub _6m_to_1y: T,
|
||||
pub _1y_to_2y: T,
|
||||
pub _2y_to_3y: T,
|
||||
pub _3y_to_5y: T,
|
||||
pub _5y_to_7y: T,
|
||||
pub _7y_to_10y: T,
|
||||
pub _10y_to_15y: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByFrom<T> {
|
||||
pub _1y: T,
|
||||
pub _2y: T,
|
||||
pub _4y: T,
|
||||
pub _10y: T,
|
||||
pub _15y: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByEpoch<T> {
|
||||
pub _1: T,
|
||||
pub _2: T,
|
||||
pub _3: T,
|
||||
pub _4: T,
|
||||
pub _5: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsBySize<T> {
|
||||
pub from_1_to_10: T,
|
||||
pub from_10_to_100: T,
|
||||
pub from_100_to_1_000: T,
|
||||
pub from_1_000_to_10_000: T,
|
||||
pub from_10000_to_100_000: T,
|
||||
pub from_100_000_to_1_000_000: T,
|
||||
pub from_1_000_000_to_10_000_000: T,
|
||||
pub from_10_000_000_to_1btc: T,
|
||||
pub from_1btc_to_10btc: T,
|
||||
pub from_10btc_to_100btc: T,
|
||||
pub from_100btc_to_1_000btc: T,
|
||||
pub from_1_000btc_to_10_000btc: T,
|
||||
pub from_10_000btc_to_100_000btc: T,
|
||||
pub from_100_000btc: T,
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct OutputsByValue<T> {
|
||||
pub up_to_1cent: T,
|
||||
pub from_1c_to_10c: T,
|
||||
pub from_10c_to_1d: T,
|
||||
pub from_1d_to_10d: T,
|
||||
pub from_10usd_to_100usd: T,
|
||||
pub from_100usd_to_1_000usd: T,
|
||||
pub from_1_000usd_to_10_000usd: T,
|
||||
pub from_10_000usd_to_100_000usd: T,
|
||||
pub from_100_000usd_to_1_000_000usd: T,
|
||||
pub from_1_000_000usd_to_10_000_000usd: T,
|
||||
pub from_10_000_000usd_to_100_000_000usd: T,
|
||||
pub from_100_000_000usd_to_1_000_000_000usd: T,
|
||||
pub from_1_000_000_000usd: T,
|
||||
// ...
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
mod stores;
|
||||
mod vecs;
|
||||
|
||||
pub use stores::*;
|
||||
pub use vecs::*;
|
||||
@@ -1,158 +0,0 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::{Bitcoin, Dollars, Sats, TxIndex};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, StoredVec, Version};
|
||||
|
||||
use crate::storage::{
|
||||
EagerVec, marketprice,
|
||||
vecs::{Indexes, indexes},
|
||||
};
|
||||
|
||||
use super::{ComputedVecsFromTxindex, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedValueVecsFromTxindex {
|
||||
pub sats: ComputedVecsFromTxindex<Sats>,
|
||||
pub bitcoin: ComputedVecsFromTxindex<Bitcoin>,
|
||||
pub dollars: Option<ComputedVecsFromTxindex<Dollars>>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ONE;
|
||||
|
||||
impl ComputedValueVecsFromTxindex {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
name: &str,
|
||||
compute_source: bool,
|
||||
version: Version,
|
||||
compressed: Compressed,
|
||||
options: StorableVecGeneatorOptions,
|
||||
compute_dollars: bool,
|
||||
) -> color_eyre::Result<Self> {
|
||||
Ok(Self {
|
||||
sats: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
name,
|
||||
compute_source,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
bitcoin: ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_btc"),
|
||||
true,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
dollars: compute_dollars.then(|| {
|
||||
ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_usd"),
|
||||
true,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute: F,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
F: FnMut(
|
||||
&mut EagerVec<TxIndex, Sats>,
|
||||
&Indexer,
|
||||
&indexes::Vecs,
|
||||
&Indexes,
|
||||
&Exit,
|
||||
) -> Result<()>,
|
||||
{
|
||||
compute(
|
||||
self.sats.txindex.as_mut().unwrap(),
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.compute_rest(indexer, indexes, marketprices, starting_indexes, exit, None)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
txindex: Option<&StoredVec<TxIndex, Sats>>,
|
||||
) -> color_eyre::Result<()> {
|
||||
if let Some(txindex) = txindex.as_ref() {
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, Some(txindex))?;
|
||||
} else {
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, None)?;
|
||||
}
|
||||
|
||||
let txindex = txindex.unwrap_or_else(|| self.sats.txindex.as_ref().unwrap().vec());
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(starting_indexes.txindex, txindex, exit)
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex = self.bitcoin.txindex.as_mut().unwrap().mut_vec();
|
||||
|
||||
if let Some(dollars) = self.dollars.as_mut() {
|
||||
let price = marketprices.unwrap().chainindexes_to_close.height.vec();
|
||||
|
||||
dollars.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, indexes, starting_indexes, exit| {
|
||||
v.compute_from_bitcoin(
|
||||
starting_indexes.txindex,
|
||||
txindex,
|
||||
indexes.txindex_to_height.vec(),
|
||||
price,
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
[
|
||||
self.sats.any_vecs(),
|
||||
self.bitcoin.any_vecs(),
|
||||
self.dollars.as_ref().map_or(vec![], |v| v.any_vecs()),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
@@ -1,944 +0,0 @@
|
||||
use std::{fs, ops::Deref, path::Path};
|
||||
|
||||
use brk_core::{
|
||||
Date, DateIndex, DecadeIndex, DifficultyEpoch, EmptyOutputIndex, HalvingEpoch, Height,
|
||||
InputIndex, MonthIndex, OpReturnIndex, OutputIndex, P2AIndex, P2MSIndex, P2PK33Index,
|
||||
P2PK65Index, P2PKHIndex, P2SHIndex, P2TRIndex, P2WPKHIndex, P2WSHIndex, QuarterIndex,
|
||||
StoredUsize, Timestamp, TxIndex, UnknownOutputIndex, WeekIndex, YearIndex,
|
||||
};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{Compressed, Version};
|
||||
|
||||
use super::EagerVec;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub dateindex_to_date: EagerVec<DateIndex, Date>,
|
||||
pub dateindex_to_dateindex: EagerVec<DateIndex, DateIndex>,
|
||||
pub dateindex_to_first_height: EagerVec<DateIndex, Height>,
|
||||
pub dateindex_to_height_count: EagerVec<DateIndex, StoredUsize>,
|
||||
pub dateindex_to_monthindex: EagerVec<DateIndex, MonthIndex>,
|
||||
pub dateindex_to_weekindex: EagerVec<DateIndex, WeekIndex>,
|
||||
pub decadeindex_to_decadeindex: EagerVec<DecadeIndex, DecadeIndex>,
|
||||
pub decadeindex_to_first_yearindex: EagerVec<DecadeIndex, YearIndex>,
|
||||
pub decadeindex_to_yearindex_count: EagerVec<DecadeIndex, StoredUsize>,
|
||||
pub difficultyepoch_to_difficultyepoch: EagerVec<DifficultyEpoch, DifficultyEpoch>,
|
||||
pub difficultyepoch_to_first_height: EagerVec<DifficultyEpoch, Height>,
|
||||
pub difficultyepoch_to_height_count: EagerVec<DifficultyEpoch, StoredUsize>,
|
||||
pub emptyoutputindex_to_emptyoutputindex: EagerVec<EmptyOutputIndex, EmptyOutputIndex>,
|
||||
pub halvingepoch_to_first_height: EagerVec<HalvingEpoch, Height>,
|
||||
pub halvingepoch_to_halvingepoch: EagerVec<HalvingEpoch, HalvingEpoch>,
|
||||
pub height_to_date: EagerVec<Height, Date>,
|
||||
pub height_to_date_fixed: EagerVec<Height, Date>,
|
||||
pub height_to_dateindex: EagerVec<Height, DateIndex>,
|
||||
pub height_to_difficultyepoch: EagerVec<Height, DifficultyEpoch>,
|
||||
pub height_to_halvingepoch: EagerVec<Height, HalvingEpoch>,
|
||||
pub height_to_height: EagerVec<Height, Height>,
|
||||
pub height_to_timestamp_fixed: EagerVec<Height, Timestamp>,
|
||||
pub height_to_txindex_count: EagerVec<Height, StoredUsize>,
|
||||
pub inputindex_to_inputindex: EagerVec<InputIndex, InputIndex>,
|
||||
pub monthindex_to_dateindex_count: EagerVec<MonthIndex, StoredUsize>,
|
||||
pub monthindex_to_first_dateindex: EagerVec<MonthIndex, DateIndex>,
|
||||
pub monthindex_to_monthindex: EagerVec<MonthIndex, MonthIndex>,
|
||||
pub monthindex_to_quarterindex: EagerVec<MonthIndex, QuarterIndex>,
|
||||
pub monthindex_to_yearindex: EagerVec<MonthIndex, YearIndex>,
|
||||
pub opreturnindex_to_opreturnindex: EagerVec<OpReturnIndex, OpReturnIndex>,
|
||||
pub outputindex_to_outputindex: EagerVec<OutputIndex, OutputIndex>,
|
||||
pub p2aindex_to_p2aindex: EagerVec<P2AIndex, P2AIndex>,
|
||||
pub p2msindex_to_p2msindex: EagerVec<P2MSIndex, P2MSIndex>,
|
||||
pub p2pk33index_to_p2pk33index: EagerVec<P2PK33Index, P2PK33Index>,
|
||||
pub p2pk65index_to_p2pk65index: EagerVec<P2PK65Index, P2PK65Index>,
|
||||
pub p2pkhindex_to_p2pkhindex: EagerVec<P2PKHIndex, P2PKHIndex>,
|
||||
pub p2shindex_to_p2shindex: EagerVec<P2SHIndex, P2SHIndex>,
|
||||
pub p2trindex_to_p2trindex: EagerVec<P2TRIndex, P2TRIndex>,
|
||||
pub p2wpkhindex_to_p2wpkhindex: EagerVec<P2WPKHIndex, P2WPKHIndex>,
|
||||
pub p2wshindex_to_p2wshindex: EagerVec<P2WSHIndex, P2WSHIndex>,
|
||||
pub quarterindex_to_first_monthindex: EagerVec<QuarterIndex, MonthIndex>,
|
||||
pub quarterindex_to_monthindex_count: EagerVec<QuarterIndex, StoredUsize>,
|
||||
pub quarterindex_to_quarterindex: EagerVec<QuarterIndex, QuarterIndex>,
|
||||
pub txindex_to_height: EagerVec<TxIndex, Height>,
|
||||
pub txindex_to_txindex: EagerVec<TxIndex, TxIndex>,
|
||||
pub unknownoutputindex_to_unknownoutputindex: EagerVec<UnknownOutputIndex, UnknownOutputIndex>,
|
||||
pub weekindex_to_dateindex_count: EagerVec<WeekIndex, StoredUsize>,
|
||||
pub weekindex_to_first_dateindex: EagerVec<WeekIndex, DateIndex>,
|
||||
pub weekindex_to_weekindex: EagerVec<WeekIndex, WeekIndex>,
|
||||
pub yearindex_to_decadeindex: EagerVec<YearIndex, DecadeIndex>,
|
||||
pub yearindex_to_first_monthindex: EagerVec<YearIndex, MonthIndex>,
|
||||
pub yearindex_to_monthindex_count: EagerVec<YearIndex, StoredUsize>,
|
||||
pub yearindex_to_yearindex: EagerVec<YearIndex, YearIndex>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(path: &Path, compressed: Compressed) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
dateindex_to_date: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_date"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
dateindex_to_dateindex: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_dateindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
dateindex_to_first_height: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_first_height"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_date: EagerVec::forced_import(
|
||||
&path.join("height_to_date"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_date_fixed: EagerVec::forced_import(
|
||||
&path.join("height_to_date_fixed"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_dateindex: EagerVec::forced_import(
|
||||
&path.join("height_to_dateindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_height: EagerVec::forced_import(
|
||||
&path.join("height_to_height"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
txindex_to_height: EagerVec::forced_import(
|
||||
&path.join("txindex_to_height"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
difficultyepoch_to_first_height: EagerVec::forced_import(
|
||||
&path.join("difficultyepoch_to_first_height"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
halvingepoch_to_first_height: EagerVec::forced_import(
|
||||
&path.join("halvingepoch_to_first_height"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
weekindex_to_first_dateindex: EagerVec::forced_import(
|
||||
&path.join("weekindex_to_first_dateindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
monthindex_to_first_dateindex: EagerVec::forced_import(
|
||||
&path.join("monthindex_to_first_dateindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
yearindex_to_first_monthindex: EagerVec::forced_import(
|
||||
&path.join("yearindex_to_first_monthindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
decadeindex_to_first_yearindex: EagerVec::forced_import(
|
||||
&path.join("decadeindex_to_first_yearindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
dateindex_to_weekindex: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_weekindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
dateindex_to_monthindex: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_monthindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
monthindex_to_yearindex: EagerVec::forced_import(
|
||||
&path.join("monthindex_to_yearindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
yearindex_to_decadeindex: EagerVec::forced_import(
|
||||
&path.join("yearindex_to_decadeindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_difficultyepoch: EagerVec::forced_import(
|
||||
&path.join("height_to_difficultyepoch"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_halvingepoch: EagerVec::forced_import(
|
||||
&path.join("height_to_halvingepoch"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
weekindex_to_weekindex: EagerVec::forced_import(
|
||||
&path.join("weekindex_to_weekindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
monthindex_to_monthindex: EagerVec::forced_import(
|
||||
&path.join("monthindex_to_monthindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
yearindex_to_yearindex: EagerVec::forced_import(
|
||||
&path.join("yearindex_to_yearindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
decadeindex_to_decadeindex: EagerVec::forced_import(
|
||||
&path.join("decadeindex_to_decadeindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
difficultyepoch_to_difficultyepoch: EagerVec::forced_import(
|
||||
&path.join("difficultyepoch_to_difficultyepoch"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
halvingepoch_to_halvingepoch: EagerVec::forced_import(
|
||||
&path.join("halvingepoch_to_halvingepoch"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_timestamp_fixed: EagerVec::forced_import(
|
||||
&path.join("height_to_timestamp_fixed"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
monthindex_to_quarterindex: EagerVec::forced_import(
|
||||
&path.join("monthindex_to_quarterindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
quarterindex_to_first_monthindex: EagerVec::forced_import(
|
||||
&path.join("quarterindex_to_first_monthindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
quarterindex_to_quarterindex: EagerVec::forced_import(
|
||||
&path.join("quarterindex_to_quarterindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2pk33index_to_p2pk33index: EagerVec::forced_import(
|
||||
&path.join("p2pk33index_to_p2pk33index"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2pk65index_to_p2pk65index: EagerVec::forced_import(
|
||||
&path.join("p2pk65index_to_p2pk65index"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2pkhindex_to_p2pkhindex: EagerVec::forced_import(
|
||||
&path.join("p2pkhindex_to_p2pkhindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2shindex_to_p2shindex: EagerVec::forced_import(
|
||||
&path.join("p2shindex_to_p2shindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2trindex_to_p2trindex: EagerVec::forced_import(
|
||||
&path.join("p2trindex_to_p2trindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2wpkhindex_to_p2wpkhindex: EagerVec::forced_import(
|
||||
&path.join("p2wpkhindex_to_p2wpkhindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2wshindex_to_p2wshindex: EagerVec::forced_import(
|
||||
&path.join("p2wshindex_to_p2wshindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
txindex_to_txindex: EagerVec::forced_import(
|
||||
&path.join("txindex_to_txindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
inputindex_to_inputindex: EagerVec::forced_import(
|
||||
&path.join("inputindex_to_inputindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
emptyoutputindex_to_emptyoutputindex: EagerVec::forced_import(
|
||||
&path.join("emptyoutputindex_to_emptyoutputindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2msindex_to_p2msindex: EagerVec::forced_import(
|
||||
&path.join("p2msindex_to_p2msindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
opreturnindex_to_opreturnindex: EagerVec::forced_import(
|
||||
&path.join("opreturnindex_to_opreturnindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
p2aindex_to_p2aindex: EagerVec::forced_import(
|
||||
&path.join("p2aindex_to_p2aindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
unknownoutputindex_to_unknownoutputindex: EagerVec::forced_import(
|
||||
&path.join("unknownoutputindex_to_unknownoutputindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
outputindex_to_outputindex: EagerVec::forced_import(
|
||||
&path.join("outputindex_to_outputindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
height_to_txindex_count: EagerVec::forced_import(
|
||||
&path.join("height_to_txindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
dateindex_to_height_count: EagerVec::forced_import(
|
||||
&path.join("dateindex_to_height_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
weekindex_to_dateindex_count: EagerVec::forced_import(
|
||||
&path.join("weekindex_to_dateindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
difficultyepoch_to_height_count: EagerVec::forced_import(
|
||||
&path.join("difficultyepoch_to_height_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
monthindex_to_dateindex_count: EagerVec::forced_import(
|
||||
&path.join("monthindex_to_dateindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
quarterindex_to_monthindex_count: EagerVec::forced_import(
|
||||
&path.join("quarterindex_to_monthindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
yearindex_to_monthindex_count: EagerVec::forced_import(
|
||||
&path.join("yearindex_to_monthindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
decadeindex_to_yearindex_count: EagerVec::forced_import(
|
||||
&path.join("decadeindex_to_yearindex_count"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<Indexes> {
|
||||
let indexer_vecs = indexer.vecs();
|
||||
|
||||
// ---
|
||||
// OutputIndex
|
||||
// ---
|
||||
|
||||
self.outputindex_to_outputindex.compute_range(
|
||||
starting_indexes.outputindex,
|
||||
indexer_vecs.outputindex_to_value.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2pk33index_to_p2pk33index.compute_range(
|
||||
starting_indexes.p2pk33index,
|
||||
indexer_vecs.p2pk33index_to_p2pk33bytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2pk65index_to_p2pk65index.compute_range(
|
||||
starting_indexes.p2pk65index,
|
||||
indexer_vecs.p2pk65index_to_p2pk65bytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2pkhindex_to_p2pkhindex.compute_range(
|
||||
starting_indexes.p2pkhindex,
|
||||
indexer_vecs.p2pkhindex_to_p2pkhbytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2shindex_to_p2shindex.compute_range(
|
||||
starting_indexes.p2shindex,
|
||||
indexer_vecs.p2shindex_to_p2shbytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2trindex_to_p2trindex.compute_range(
|
||||
starting_indexes.p2trindex,
|
||||
indexer_vecs.p2trindex_to_p2trbytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2wpkhindex_to_p2wpkhindex.compute_range(
|
||||
starting_indexes.p2wpkhindex,
|
||||
indexer_vecs.p2wpkhindex_to_p2wpkhbytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2wshindex_to_p2wshindex.compute_range(
|
||||
starting_indexes.p2wshindex,
|
||||
indexer_vecs.p2wshindex_to_p2wshbytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.emptyoutputindex_to_emptyoutputindex.compute_range(
|
||||
starting_indexes.emptyoutputindex,
|
||||
indexer_vecs.emptyoutputindex_to_txindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2msindex_to_p2msindex.compute_range(
|
||||
starting_indexes.p2msindex,
|
||||
indexer_vecs.p2msindex_to_txindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.opreturnindex_to_opreturnindex.compute_range(
|
||||
starting_indexes.opreturnindex,
|
||||
indexer_vecs.opreturnindex_to_txindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.p2aindex_to_p2aindex.compute_range(
|
||||
starting_indexes.p2aindex,
|
||||
indexer_vecs.p2aindex_to_p2abytes.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.unknownoutputindex_to_unknownoutputindex
|
||||
.compute_range(
|
||||
starting_indexes.unknownoutputindex,
|
||||
indexer_vecs.unknownoutputindex_to_txindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// InputIndex
|
||||
// ---
|
||||
|
||||
self.inputindex_to_inputindex.compute_range(
|
||||
starting_indexes.inputindex,
|
||||
indexer_vecs.inputindex_to_outputindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// TxIndex
|
||||
// ---
|
||||
|
||||
self.txindex_to_txindex.compute_range(
|
||||
starting_indexes.txindex,
|
||||
indexer_vecs.txindex_to_txid.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_txindex_count.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_first_txindex.vec(),
|
||||
indexer_vecs.txindex_to_txid.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_height.compute_inverse_less_to_more(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_first_txindex.vec(),
|
||||
self.height_to_txindex_count.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// Height
|
||||
// ---
|
||||
|
||||
self.height_to_height.compute_range(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_timestamp.vec(),
|
||||
|h| (h, h),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date.compute_transform(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_timestamp.vec(),
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let mut prev_timestamp_fixed = None;
|
||||
self.height_to_timestamp_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_timestamp.vec(),
|
||||
|(h, timestamp, height_to_timestamp_fixed_iter)| {
|
||||
if prev_timestamp_fixed.is_none() {
|
||||
if let Some(prev_h) = h.decremented() {
|
||||
prev_timestamp_fixed.replace(
|
||||
height_to_timestamp_fixed_iter
|
||||
.iter()
|
||||
.unwrap_get_inner(prev_h),
|
||||
);
|
||||
}
|
||||
}
|
||||
let timestamp_fixed =
|
||||
prev_timestamp_fixed.map_or(timestamp, |prev_d| prev_d.max(timestamp));
|
||||
prev_timestamp_fixed.replace(timestamp_fixed);
|
||||
(h, timestamp_fixed)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_timestamp_fixed.vec(),
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let decremented_starting_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
// ---
|
||||
// DateIndex
|
||||
// ---
|
||||
|
||||
let starting_dateindex = self
|
||||
.height_to_dateindex
|
||||
.iter()
|
||||
.get_inner(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_dateindex.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_date_fixed.vec(),
|
||||
|(h, d, ..)| (h, DateIndex::try_from(d).unwrap()),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_dateindex = if let Some(dateindex) = self
|
||||
.height_to_dateindex
|
||||
.iter()
|
||||
.get_inner(decremented_starting_height)
|
||||
{
|
||||
starting_dateindex.min(dateindex)
|
||||
} else {
|
||||
starting_dateindex
|
||||
};
|
||||
|
||||
self.dateindex_to_first_height
|
||||
.compute_inverse_more_to_less(
|
||||
starting_indexes.height,
|
||||
self.height_to_dateindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_dateindex.compute_range(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_first_height.vec(),
|
||||
|di| (di, di),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_date.compute_range(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_dateindex.vec(),
|
||||
|di| (di, Date::from(di)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_height_count.compute_count_from_indexes(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_first_height.vec(),
|
||||
indexer_vecs.height_to_weight.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// WeekIndex
|
||||
// ---
|
||||
|
||||
let starting_weekindex = self
|
||||
.dateindex_to_weekindex
|
||||
.iter()
|
||||
.get_inner(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_weekindex.compute_range(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_dateindex.vec(),
|
||||
|di| (di, WeekIndex::from(di)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_first_dateindex
|
||||
.compute_inverse_more_to_less(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_weekindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_weekindex.compute_range(
|
||||
starting_weekindex,
|
||||
self.weekindex_to_first_dateindex.vec(),
|
||||
|wi| (wi, wi),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_dateindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_weekindex,
|
||||
self.weekindex_to_first_dateindex.vec(),
|
||||
self.dateindex_to_date.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// DifficultyEpoch
|
||||
// ---
|
||||
|
||||
let starting_difficultyepoch = self
|
||||
.height_to_difficultyepoch
|
||||
.iter()
|
||||
.get_inner(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_difficultyepoch.compute_range(
|
||||
starting_indexes.height,
|
||||
self.height_to_height.vec(),
|
||||
|h| (h, DifficultyEpoch::from(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_first_height
|
||||
.compute_inverse_more_to_less(
|
||||
starting_indexes.height,
|
||||
self.height_to_difficultyepoch.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_difficultyepoch.compute_range(
|
||||
starting_difficultyepoch,
|
||||
self.difficultyepoch_to_first_height.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_height_count
|
||||
.compute_count_from_indexes(
|
||||
starting_difficultyepoch,
|
||||
self.difficultyepoch_to_first_height.vec(),
|
||||
self.height_to_date.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// MonthIndex
|
||||
// ---
|
||||
|
||||
let starting_monthindex = self
|
||||
.dateindex_to_monthindex
|
||||
.iter()
|
||||
.get_inner(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_monthindex.compute_range(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_dateindex.vec(),
|
||||
|di| (di, MonthIndex::from(di)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_first_dateindex
|
||||
.compute_inverse_more_to_less(
|
||||
starting_dateindex,
|
||||
self.dateindex_to_monthindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_monthindex.compute_range(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_first_dateindex.vec(),
|
||||
|mi| (mi, mi),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_dateindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_first_dateindex.vec(),
|
||||
self.dateindex_to_date.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// QuarterIndex
|
||||
// ---
|
||||
|
||||
let starting_quarterindex = self
|
||||
.monthindex_to_quarterindex
|
||||
.iter()
|
||||
.get_inner(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_quarterindex.compute_range(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_monthindex.vec(),
|
||||
|mi| (mi, QuarterIndex::from(mi)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_first_monthindex
|
||||
.compute_inverse_more_to_less(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_quarterindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// let quarter_count = self.quarterindex_to_first_monthindex.len();
|
||||
|
||||
self.quarterindex_to_quarterindex.compute_range(
|
||||
starting_quarterindex,
|
||||
self.quarterindex_to_first_monthindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_monthindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_quarterindex,
|
||||
self.quarterindex_to_first_monthindex.vec(),
|
||||
self.monthindex_to_monthindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// YearIndex
|
||||
// ---
|
||||
|
||||
let starting_yearindex = self
|
||||
.monthindex_to_yearindex
|
||||
.iter()
|
||||
.get_inner(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_yearindex.compute_range(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_monthindex.vec(),
|
||||
|i| (i, YearIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_first_monthindex
|
||||
.compute_inverse_more_to_less(
|
||||
starting_monthindex,
|
||||
self.monthindex_to_yearindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_yearindex.compute_range(
|
||||
starting_yearindex,
|
||||
self.yearindex_to_first_monthindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_monthindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_yearindex,
|
||||
self.yearindex_to_first_monthindex.vec(),
|
||||
self.monthindex_to_monthindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
// ---
|
||||
// HalvingEpoch
|
||||
// ---
|
||||
|
||||
let starting_halvingepoch = self
|
||||
.height_to_halvingepoch
|
||||
.iter()
|
||||
.get_inner(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_halvingepoch.compute_range(
|
||||
starting_indexes.height,
|
||||
self.height_to_height.vec(),
|
||||
|h| (h, HalvingEpoch::from(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_first_height
|
||||
.compute_inverse_more_to_less(
|
||||
starting_indexes.height,
|
||||
self.height_to_halvingepoch.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_halvingepoch.compute_range(
|
||||
starting_halvingepoch,
|
||||
self.halvingepoch_to_first_height.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// ---
|
||||
// DecadeIndex
|
||||
// ---
|
||||
|
||||
let starting_decadeindex = self
|
||||
.yearindex_to_decadeindex
|
||||
.iter()
|
||||
.get_inner(starting_yearindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.yearindex_to_decadeindex.compute_range(
|
||||
starting_yearindex,
|
||||
self.yearindex_to_yearindex.vec(),
|
||||
|i| (i, DecadeIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_first_yearindex
|
||||
.compute_inverse_more_to_less(
|
||||
starting_yearindex,
|
||||
self.yearindex_to_decadeindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_decadeindex.compute_range(
|
||||
starting_decadeindex,
|
||||
self.decadeindex_to_first_yearindex.vec(),
|
||||
|i| (i, i),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_yearindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_decadeindex,
|
||||
self.decadeindex_to_first_yearindex.vec(),
|
||||
self.yearindex_to_yearindex.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(Indexes {
|
||||
indexes: starting_indexes,
|
||||
dateindex: starting_dateindex,
|
||||
weekindex: starting_weekindex,
|
||||
monthindex: starting_monthindex,
|
||||
quarterindex: starting_quarterindex,
|
||||
yearindex: starting_yearindex,
|
||||
decadeindex: starting_decadeindex,
|
||||
difficultyepoch: starting_difficultyepoch,
|
||||
halvingepoch: starting_halvingepoch,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
|
||||
vec![
|
||||
self.dateindex_to_date.any_vec(),
|
||||
self.dateindex_to_dateindex.any_vec(),
|
||||
self.dateindex_to_first_height.any_vec(),
|
||||
self.dateindex_to_height_count.any_vec(),
|
||||
self.dateindex_to_monthindex.any_vec(),
|
||||
self.dateindex_to_weekindex.any_vec(),
|
||||
self.decadeindex_to_decadeindex.any_vec(),
|
||||
self.decadeindex_to_first_yearindex.any_vec(),
|
||||
self.decadeindex_to_yearindex_count.any_vec(),
|
||||
self.difficultyepoch_to_difficultyepoch.any_vec(),
|
||||
self.difficultyepoch_to_first_height.any_vec(),
|
||||
self.difficultyepoch_to_height_count.any_vec(),
|
||||
self.emptyoutputindex_to_emptyoutputindex.any_vec(),
|
||||
self.halvingepoch_to_first_height.any_vec(),
|
||||
self.halvingepoch_to_halvingepoch.any_vec(),
|
||||
self.height_to_date.any_vec(),
|
||||
self.height_to_date_fixed.any_vec(),
|
||||
self.height_to_dateindex.any_vec(),
|
||||
self.height_to_difficultyepoch.any_vec(),
|
||||
self.height_to_halvingepoch.any_vec(),
|
||||
self.height_to_height.any_vec(),
|
||||
self.height_to_timestamp_fixed.any_vec(),
|
||||
self.height_to_txindex_count.any_vec(),
|
||||
self.inputindex_to_inputindex.any_vec(),
|
||||
self.monthindex_to_dateindex_count.any_vec(),
|
||||
self.monthindex_to_first_dateindex.any_vec(),
|
||||
self.monthindex_to_monthindex.any_vec(),
|
||||
self.monthindex_to_quarterindex.any_vec(),
|
||||
self.monthindex_to_yearindex.any_vec(),
|
||||
self.opreturnindex_to_opreturnindex.any_vec(),
|
||||
self.outputindex_to_outputindex.any_vec(),
|
||||
self.p2aindex_to_p2aindex.any_vec(),
|
||||
self.p2msindex_to_p2msindex.any_vec(),
|
||||
self.p2pk33index_to_p2pk33index.any_vec(),
|
||||
self.p2pk65index_to_p2pk65index.any_vec(),
|
||||
self.p2pkhindex_to_p2pkhindex.any_vec(),
|
||||
self.p2shindex_to_p2shindex.any_vec(),
|
||||
self.p2trindex_to_p2trindex.any_vec(),
|
||||
self.p2wpkhindex_to_p2wpkhindex.any_vec(),
|
||||
self.p2wshindex_to_p2wshindex.any_vec(),
|
||||
self.quarterindex_to_first_monthindex.any_vec(),
|
||||
self.quarterindex_to_monthindex_count.any_vec(),
|
||||
self.quarterindex_to_quarterindex.any_vec(),
|
||||
self.txindex_to_height.any_vec(),
|
||||
self.txindex_to_txindex.any_vec(),
|
||||
self.unknownoutputindex_to_unknownoutputindex.any_vec(),
|
||||
self.weekindex_to_dateindex_count.any_vec(),
|
||||
self.weekindex_to_first_dateindex.any_vec(),
|
||||
self.weekindex_to_weekindex.any_vec(),
|
||||
self.yearindex_to_decadeindex.any_vec(),
|
||||
self.yearindex_to_first_monthindex.any_vec(),
|
||||
self.yearindex_to_monthindex_count.any_vec(),
|
||||
self.yearindex_to_yearindex.any_vec(),
|
||||
]
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Indexes {
|
||||
indexes: brk_indexer::Indexes,
|
||||
pub dateindex: DateIndex,
|
||||
pub weekindex: WeekIndex,
|
||||
pub monthindex: MonthIndex,
|
||||
pub quarterindex: QuarterIndex,
|
||||
pub yearindex: YearIndex,
|
||||
pub decadeindex: DecadeIndex,
|
||||
pub difficultyepoch: DifficultyEpoch,
|
||||
pub halvingepoch: HalvingEpoch,
|
||||
}
|
||||
|
||||
impl Deref for Indexes {
|
||||
type Target = brk_indexer::Indexes;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.indexes
|
||||
}
|
||||
}
|
||||
@@ -1,89 +0,0 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed};
|
||||
|
||||
pub mod blocks;
|
||||
pub mod grouped;
|
||||
pub mod indexes;
|
||||
pub mod marketprice;
|
||||
pub mod mining;
|
||||
pub mod transactions;
|
||||
pub mod vec;
|
||||
|
||||
pub use indexes::Indexes;
|
||||
pub use vec::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub indexes: indexes::Vecs,
|
||||
pub blocks: blocks::Vecs,
|
||||
pub mining: mining::Vecs,
|
||||
pub transactions: transactions::Vecs,
|
||||
pub marketprice: Option<marketprice::Vecs>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn import(path: &Path, fetch: bool, compressed: Compressed) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
blocks: blocks::Vecs::forced_import(path, compressed)?,
|
||||
indexes: indexes::Vecs::forced_import(path, compressed)?,
|
||||
mining: mining::Vecs::forced_import(path, compressed)?,
|
||||
transactions: transactions::Vecs::forced_import(path, compressed, fetch)?,
|
||||
marketprice: fetch.then(|| marketprice::Vecs::forced_import(path, compressed).unwrap()),
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
fetcher: Option<&mut Fetcher>,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let starting_indexes = self.indexes.compute(indexer, starting_indexes, exit)?;
|
||||
|
||||
self.blocks
|
||||
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
self.mining
|
||||
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
if let Some(marketprice) = self.marketprice.as_mut() {
|
||||
marketprice.compute(
|
||||
indexer,
|
||||
&self.indexes,
|
||||
&starting_indexes,
|
||||
fetcher.unwrap(),
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.transactions.compute(
|
||||
indexer,
|
||||
&self.indexes,
|
||||
&starting_indexes,
|
||||
self.marketprice.as_ref(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
[
|
||||
self.indexes.as_any_vecs(),
|
||||
self.blocks.as_any_vecs(),
|
||||
self.mining.as_any_vecs(),
|
||||
self.transactions.as_any_vecs(),
|
||||
self.marketprice
|
||||
.as_ref()
|
||||
.map_or(vec![], |v| v.as_any_vecs()),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
@@ -1,540 +0,0 @@
|
||||
use core::error;
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
fmt::Debug,
|
||||
ops::Add,
|
||||
path::{Path, PathBuf},
|
||||
};
|
||||
|
||||
use brk_core::{Bitcoin, CheckedSub, Close, Dollars, Height, Sats, StoredUsize, TxIndex};
|
||||
use brk_exit::Exit;
|
||||
use brk_vec::{
|
||||
Compressed, DynamicVec, Error, GenericVec, Result, StoredIndex, StoredType, StoredVec,
|
||||
StoredVecIterator, Value, Version,
|
||||
};
|
||||
use color_eyre::eyre::ContextCompat;
|
||||
use log::info;
|
||||
|
||||
const ONE_KIB: usize = 1024;
|
||||
const ONE_MIB: usize = ONE_KIB * ONE_KIB;
|
||||
const MAX_CACHE_SIZE: usize = 210 * ONE_MIB;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct EagerVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
computed_version: Option<Version>,
|
||||
inner: StoredVec<I, T>,
|
||||
}
|
||||
|
||||
impl<I, T> EagerVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
const SIZE_OF: usize = size_of::<T>();
|
||||
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
version: Version,
|
||||
compressed: Compressed,
|
||||
) -> brk_vec::Result<Self> {
|
||||
let inner = StoredVec::forced_import(path, version, compressed)?;
|
||||
|
||||
Ok(Self {
|
||||
computed_version: None,
|
||||
inner,
|
||||
})
|
||||
}
|
||||
|
||||
fn safe_truncate_if_needed(&mut self, index: I, exit: &Exit) -> Result<()> {
|
||||
if exit.triggered() {
|
||||
return Ok(());
|
||||
}
|
||||
exit.block();
|
||||
self.inner.truncate_if_needed(index)?;
|
||||
exit.release();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[inline]
|
||||
pub fn forced_push_at(&mut self, index: I, value: T, exit: &Exit) -> Result<()> {
|
||||
match self.len().cmp(&index.to_usize()?) {
|
||||
Ordering::Less => {
|
||||
return Err(Error::IndexTooHigh);
|
||||
}
|
||||
ord => {
|
||||
if ord == Ordering::Greater {
|
||||
self.safe_truncate_if_needed(index, exit)?;
|
||||
}
|
||||
self.inner.push(value);
|
||||
}
|
||||
}
|
||||
|
||||
if self.inner.pushed_len() * Self::SIZE_OF >= MAX_CACHE_SIZE {
|
||||
self.safe_flush(exit)
|
||||
} else {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
pub fn safe_flush(&mut self, exit: &Exit) -> Result<()> {
|
||||
if exit.triggered() {
|
||||
return Ok(());
|
||||
}
|
||||
exit.block();
|
||||
self.inner.flush()?;
|
||||
exit.release();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn version(&self) -> Version {
|
||||
self.inner.version()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
|
||||
fn file_name(&self) -> String {
|
||||
self.inner.file_name()
|
||||
}
|
||||
|
||||
pub fn vec(&self) -> &StoredVec<I, T> {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn mut_vec(&mut self) -> &StoredVec<I, T> {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
pub fn any_vec(&self) -> &dyn brk_vec::AnyStoredVec {
|
||||
&self.inner
|
||||
}
|
||||
|
||||
pub fn mut_any_vec(&mut self) -> &mut dyn brk_vec::AnyStoredVec {
|
||||
&mut self.inner
|
||||
}
|
||||
|
||||
pub fn path(&self) -> &Path {
|
||||
self.inner.path()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn path_computed_version(&self) -> PathBuf {
|
||||
self.inner.path().join("computed_version")
|
||||
}
|
||||
|
||||
fn validate_computed_version_or_reset_file(&mut self, version: Version) -> Result<()> {
|
||||
let path = self.path_computed_version();
|
||||
if version.validate(path.as_ref()).is_err() {
|
||||
self.inner.reset()?;
|
||||
}
|
||||
version.write(path.as_ref())?;
|
||||
|
||||
if self.is_empty() {
|
||||
info!("Computing {}...", self.file_name())
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn iter(&self) -> StoredVecIterator<I, T> {
|
||||
self.into_iter()
|
||||
}
|
||||
|
||||
pub fn compute_range<A, F>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
other: &StoredVec<I, A>,
|
||||
mut t: F,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
A: StoredType,
|
||||
F: FnMut(I) -> (I, T),
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + other.version(),
|
||||
)?;
|
||||
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
(index.to_usize()?..other.len()).try_for_each(|i| {
|
||||
let (i, v) = t(I::from(i));
|
||||
self.forced_push_at(i, v, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_transform<A, B, F>(
|
||||
&mut self,
|
||||
max_from: A,
|
||||
other: &StoredVec<A, B>,
|
||||
mut t: F,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
A: StoredIndex,
|
||||
B: StoredType,
|
||||
F: FnMut((A, B, &Self)) -> (I, T),
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + other.version(),
|
||||
)?;
|
||||
|
||||
let index = max_from.min(A::from(self.len()));
|
||||
other.iter_at(index).try_for_each(|(a, b)| {
|
||||
let (i, v) = t((a, b.into_inner(), self));
|
||||
self.forced_push_at(i, v, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_inverse_more_to_less(
|
||||
&mut self,
|
||||
max_from: T,
|
||||
other: &StoredVec<T, I>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
I: StoredType + StoredIndex,
|
||||
T: StoredIndex,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + other.version(),
|
||||
)?;
|
||||
|
||||
let index = max_from.min(
|
||||
self.inner
|
||||
.iter()
|
||||
.last()
|
||||
.map_or_else(T::default, |(_, v)| v.into_inner()),
|
||||
);
|
||||
let mut prev_i = None;
|
||||
other.iter_at(index).try_for_each(|(v, i)| -> Result<()> {
|
||||
let i = i.into_inner();
|
||||
if prev_i.is_some_and(|prev_i| prev_i == i) {
|
||||
return Ok(());
|
||||
}
|
||||
if self
|
||||
.inner
|
||||
.get(i)?
|
||||
.is_none_or(|old_v| old_v.into_inner() > v)
|
||||
{
|
||||
self.forced_push_at(i, v, exit)?;
|
||||
}
|
||||
prev_i.replace(i);
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_inverse_less_to_more(
|
||||
&mut self,
|
||||
max_from: T,
|
||||
first_indexes: &StoredVec<T, I>,
|
||||
indexes_count: &StoredVec<T, StoredUsize>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
I: StoredType,
|
||||
T: StoredIndex,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + first_indexes.version() + indexes_count.version(),
|
||||
)?;
|
||||
|
||||
let mut indexes_count_iter = indexes_count.iter();
|
||||
|
||||
let index = max_from.min(T::from(self.len()));
|
||||
first_indexes
|
||||
.iter_at(index)
|
||||
.try_for_each(|(value, first_index)| {
|
||||
let first_index = (first_index).to_usize()?;
|
||||
let count = *indexes_count_iter.unwrap_get_inner(value);
|
||||
(first_index..first_index + count)
|
||||
.try_for_each(|index| self.forced_push_at(I::from(index), value, exit))
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_count_from_indexes<T2, T3>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
first_indexes: &StoredVec<I, T2>,
|
||||
other_to_else: &StoredVec<T2, T3>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: From<T2>,
|
||||
T2: StoredType
|
||||
+ StoredIndex
|
||||
+ Copy
|
||||
+ Add<usize, Output = T2>
|
||||
+ CheckedSub<T2>
|
||||
+ TryInto<T>
|
||||
+ Default,
|
||||
<T2 as TryInto<T>>::Error: error::Error + 'static,
|
||||
T3: StoredType,
|
||||
{
|
||||
let opt: Option<Box<dyn FnMut(T2) -> bool>> = None;
|
||||
self.compute_filtered_count_from_indexes_(max_from, first_indexes, other_to_else, opt, exit)
|
||||
}
|
||||
|
||||
pub fn compute_filtered_count_from_indexes<T2, T3, F>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
first_indexes: &StoredVec<I, T2>,
|
||||
other_to_else: &StoredVec<T2, T3>,
|
||||
filter: F,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: From<T2>,
|
||||
T2: StoredType
|
||||
+ StoredIndex
|
||||
+ Copy
|
||||
+ Add<usize, Output = T2>
|
||||
+ CheckedSub<T2>
|
||||
+ TryInto<T>
|
||||
+ Default,
|
||||
<T2 as TryInto<T>>::Error: error::Error + 'static,
|
||||
T3: StoredType,
|
||||
F: FnMut(T2) -> bool,
|
||||
{
|
||||
self.compute_filtered_count_from_indexes_(
|
||||
max_from,
|
||||
first_indexes,
|
||||
other_to_else,
|
||||
Some(Box::new(filter)),
|
||||
exit,
|
||||
)
|
||||
}
|
||||
|
||||
fn compute_filtered_count_from_indexes_<T2, T3>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
first_indexes: &StoredVec<I, T2>,
|
||||
other_to_else: &StoredVec<T2, T3>,
|
||||
mut filter: Option<Box<dyn FnMut(T2) -> bool + '_>>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: From<T2>,
|
||||
T2: StoredType
|
||||
+ StoredIndex
|
||||
+ Copy
|
||||
+ Add<usize, Output = T2>
|
||||
+ CheckedSub<T2>
|
||||
+ TryInto<T>
|
||||
+ Default,
|
||||
T3: StoredType,
|
||||
<T2 as TryInto<T>>::Error: error::Error + 'static,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + first_indexes.version(), // + last_indexes.version(),
|
||||
)?;
|
||||
|
||||
let mut other_iter = first_indexes.iter();
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
first_indexes
|
||||
.iter_at(index)
|
||||
.try_for_each(|(i, first_index)| {
|
||||
let end = other_iter
|
||||
.get(i + 1)
|
||||
.map(|(_, v)| v.into_inner().unwrap_to_usize())
|
||||
.unwrap_or_else(|| other_to_else.len());
|
||||
|
||||
let range = first_index.unwrap_to_usize()..end;
|
||||
let count = if let Some(filter) = filter.as_mut() {
|
||||
range.into_iter().filter(|i| filter(T2::from(*i))).count()
|
||||
} else {
|
||||
range.count()
|
||||
};
|
||||
self.forced_push_at(i, T::from(T2::from(count)), exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_is_first_ordered<A>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
self_to_other: &StoredVec<I, A>,
|
||||
other_to_self: &StoredVec<A, I>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
I: StoredType,
|
||||
T: From<bool>,
|
||||
A: StoredIndex + StoredType,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + self_to_other.version() + other_to_self.version(),
|
||||
)?;
|
||||
|
||||
let mut other_to_self_iter = other_to_self.iter();
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
self_to_other.iter_at(index).try_for_each(|(i, other)| {
|
||||
self.forced_push_at(
|
||||
i,
|
||||
T::from(
|
||||
other_to_self_iter
|
||||
.get(other.into_inner())
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner()
|
||||
== i,
|
||||
),
|
||||
exit,
|
||||
)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
|
||||
pub fn compute_sum_from_indexes<T2>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
first_indexes: &StoredVec<I, T2>,
|
||||
indexes_count: &StoredVec<I, StoredUsize>,
|
||||
source: &StoredVec<T2, T>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
T: From<usize> + Add<T, Output = T>,
|
||||
T2: StoredIndex + StoredType,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + first_indexes.version() + indexes_count.version(),
|
||||
)?;
|
||||
|
||||
let mut indexes_count_iter = indexes_count.iter();
|
||||
let mut source_iter = source.iter();
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
first_indexes
|
||||
.iter_at(index)
|
||||
.try_for_each(|(i, first_index)| {
|
||||
let count = *indexes_count_iter.get(i).unwrap().1.into_inner();
|
||||
let first_index = first_index.unwrap_to_usize();
|
||||
let range = first_index..first_index + count;
|
||||
let mut sum = T::from(0_usize);
|
||||
range.into_iter().for_each(|i| {
|
||||
sum = sum.clone() + source_iter.get(T2::from(i)).unwrap().1.into_inner();
|
||||
});
|
||||
self.forced_push_at(i, sum, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I> EagerVec<I, Bitcoin>
|
||||
where
|
||||
I: StoredIndex,
|
||||
{
|
||||
pub fn compute_from_sats(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
sats: &StoredVec<I, Sats>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + sats.version(),
|
||||
)?;
|
||||
|
||||
let index = max_from.min(I::from(self.len()));
|
||||
sats.iter_at(index).try_for_each(|(i, sats)| {
|
||||
let (i, v) = (i, Bitcoin::from(sats.into_inner()));
|
||||
self.forced_push_at(i, v, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
}
|
||||
|
||||
impl EagerVec<Height, Dollars> {
|
||||
pub fn compute_from_bitcoin(
|
||||
&mut self,
|
||||
max_from: Height,
|
||||
bitcoin: &StoredVec<Height, Bitcoin>,
|
||||
price: &StoredVec<Height, Close<Dollars>>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + bitcoin.version(),
|
||||
)?;
|
||||
|
||||
let mut price_iter = price.iter();
|
||||
let index = max_from.min(Height::from(self.len()));
|
||||
bitcoin.iter_at(index).try_for_each(|(i, bitcoin)| {
|
||||
let dollars = price_iter.get(i).unwrap().1.into_inner();
|
||||
let (i, v) = (i, *dollars * bitcoin.into_inner());
|
||||
self.forced_push_at(i, v, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
}
|
||||
|
||||
impl EagerVec<TxIndex, Dollars> {
|
||||
pub fn compute_from_bitcoin(
|
||||
&mut self,
|
||||
max_from: TxIndex,
|
||||
bitcoin: &StoredVec<TxIndex, Bitcoin>,
|
||||
i_to_height: &StoredVec<TxIndex, Height>,
|
||||
price: &StoredVec<Height, Close<Dollars>>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + self.version() + bitcoin.version(),
|
||||
)?;
|
||||
|
||||
let mut i_to_height_iter = i_to_height.iter();
|
||||
let mut price_iter = price.iter();
|
||||
let index = max_from.min(TxIndex::from(self.len()));
|
||||
bitcoin.iter_at(index).try_for_each(|(i, bitcoin, ..)| {
|
||||
let height = i_to_height_iter.get(i).unwrap().1.into_inner();
|
||||
let dollars = price_iter.get(height).unwrap().1.into_inner();
|
||||
let (i, v) = (i, *dollars * bitcoin.into_inner());
|
||||
self.forced_push_at(i, v, exit)
|
||||
})?;
|
||||
|
||||
self.safe_flush(exit)
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T> Clone for EagerVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
computed_version: self.computed_version,
|
||||
inner: self.inner.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, I, T> IntoIterator for &'a EagerVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
type Item = (I, Value<'a, T>);
|
||||
type IntoIter = StoredVecIterator<'a, I, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.inner.into_iter()
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
use std::fmt::Debug;
|
||||
|
||||
use brk_vec::{DynamicVec, GenericVec, StoredIndex, StoredType, StoredVec, Version};
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct LazyVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
inner: StoredVec<I, T>,
|
||||
}
|
||||
|
||||
impl<I, T> LazyVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
const SIZE_OF: usize = size_of::<T>();
|
||||
|
||||
fn version(&self) -> Version {
|
||||
self.inner.version()
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.inner.len()
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.inner.is_empty()
|
||||
}
|
||||
}
|
||||
|
||||
impl<I, T> Clone for LazyVec<I, T>
|
||||
where
|
||||
I: StoredIndex,
|
||||
T: StoredType,
|
||||
{
|
||||
fn clone(&self) -> Self {
|
||||
Self {
|
||||
inner: self.inner.clone(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
mod _type;
|
||||
mod eager;
|
||||
mod lazy;
|
||||
|
||||
pub use _type::*;
|
||||
pub use eager::*;
|
||||
pub use lazy::*;
|
||||
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
enum Mode {
|
||||
Lazy,
|
||||
Eager,
|
||||
}
|
||||
@@ -0,0 +1,27 @@
|
||||
use std::ops::{Add, Div};
|
||||
|
||||
pub fn get_percentile<T>(sorted: &[T], percentile: f64) -> T
|
||||
where
|
||||
T: Clone + Div<usize, Output = T> + Add<T, Output = T>,
|
||||
{
|
||||
let len = sorted.len();
|
||||
|
||||
if len == 0 {
|
||||
panic!();
|
||||
} else if len == 1 {
|
||||
sorted[0].clone()
|
||||
} else {
|
||||
let index = (len - 1) as f64 * percentile;
|
||||
|
||||
let fract = index.fract();
|
||||
|
||||
if fract != 0.0 {
|
||||
let left = sorted.get(index as usize).unwrap().clone();
|
||||
let right = sorted.get(index.ceil() as usize).unwrap().clone();
|
||||
left / 2 + right / 2
|
||||
} else {
|
||||
// dbg!(sorted.len(), index);
|
||||
sorted.get(index as usize).unwrap().clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
+33
-29
@@ -7,11 +7,11 @@ use brk_core::{
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::bitcoin;
|
||||
use brk_vec::{Compressed, Version};
|
||||
use brk_vec::{AnyCollectableVec, AnyIterableVec, Compressed, Computation, EagerVec, Version};
|
||||
|
||||
use super::{
|
||||
EagerVec, Indexes,
|
||||
grouped::{ComputedVecsFromDateindex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
Indexes,
|
||||
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
@@ -21,7 +21,7 @@ pub struct Vecs {
|
||||
pub height_to_vbytes: EagerVec<Height, StoredU64>,
|
||||
pub difficultyepoch_to_timestamp: EagerVec<DifficultyEpoch, Timestamp>,
|
||||
pub halvingepoch_to_timestamp: EagerVec<HalvingEpoch, Timestamp>,
|
||||
pub timeindexes_to_timestamp: ComputedVecsFromDateindex<Timestamp>,
|
||||
pub timeindexes_to_timestamp: ComputedVecsFromDateIndex<Timestamp>,
|
||||
pub indexes_to_block_count: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_block_interval: ComputedVecsFromHeight<Timestamp>,
|
||||
pub indexes_to_block_size: ComputedVecsFromHeight<StoredUsize>,
|
||||
@@ -30,7 +30,11 @@ pub struct Vecs {
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(path: &Path, compressed: Compressed) -> color_eyre::Result<Self> {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
_computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -39,7 +43,7 @@ impl Vecs {
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
timeindexes_to_timestamp: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"timestamp",
|
||||
Version::ZERO,
|
||||
@@ -122,7 +126,7 @@ impl Vecs {
|
||||
|vec, _, indexes, starting_indexes, exit| {
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
indexes.dateindex_to_date.vec(),
|
||||
&indexes.dateindex_to_date,
|
||||
|(di, d, ..)| (di, Timestamp::from(d)),
|
||||
exit,
|
||||
)
|
||||
@@ -139,7 +143,7 @@ impl Vecs {
|
||||
|
||||
v.compute_range(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_weight.vec(),
|
||||
&indexer_vecs.height_to_weight,
|
||||
|h| (h, StoredU32::from(1_u32)),
|
||||
exit,
|
||||
)
|
||||
@@ -151,7 +155,7 @@ impl Vecs {
|
||||
let mut height_to_timestamp_iter = indexer_vecs.height_to_timestamp.iter();
|
||||
self.height_to_interval.compute_transform(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_timestamp.vec(),
|
||||
&indexer_vecs.height_to_timestamp,
|
||||
|(height, timestamp, ..)| {
|
||||
let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| {
|
||||
let prev_timestamp = height_to_timestamp_iter.unwrap_get_inner(prev_h);
|
||||
@@ -168,26 +172,26 @@ impl Vecs {
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(self.height_to_interval.vec()),
|
||||
Some(&self.height_to_interval),
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_weight.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(indexer_vecs.height_to_weight.vec()),
|
||||
Some(&indexer_vecs.height_to_weight),
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_size.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(indexer_vecs.height_to_total_size.vec()),
|
||||
Some(&indexer_vecs.height_to_total_size),
|
||||
)?;
|
||||
|
||||
self.height_to_vbytes.compute_transform(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_weight.vec(),
|
||||
&indexer_vecs.height_to_weight,
|
||||
|(h, w, ..)| {
|
||||
(
|
||||
h,
|
||||
@@ -201,42 +205,42 @@ impl Vecs {
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(self.height_to_vbytes.vec()),
|
||||
Some(&self.height_to_vbytes),
|
||||
)?;
|
||||
|
||||
let mut height_to_timestamp_iter = indexer_vecs.height_to_timestamp.iter();
|
||||
|
||||
self.difficultyepoch_to_timestamp.compute_transform(
|
||||
starting_indexes.difficultyepoch,
|
||||
indexes.difficultyepoch_to_first_height.vec(),
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.get(h).unwrap().1.into_inner()),
|
||||
&indexes.difficultyepoch_to_first_height,
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_timestamp.compute_transform(
|
||||
starting_indexes.halvingepoch,
|
||||
indexes.halvingepoch_to_first_height.vec(),
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.get(h).unwrap().1.into_inner()),
|
||||
&indexes.halvingepoch_to_first_height,
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.unwrap_get_inner(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
vec![
|
||||
self.height_to_interval.any_vec(),
|
||||
self.height_to_vbytes.any_vec(),
|
||||
self.difficultyepoch_to_timestamp.any_vec(),
|
||||
self.halvingepoch_to_timestamp.any_vec(),
|
||||
&self.height_to_interval as &dyn AnyCollectableVec,
|
||||
&self.height_to_vbytes,
|
||||
&self.difficultyepoch_to_timestamp,
|
||||
&self.halvingepoch_to_timestamp,
|
||||
],
|
||||
self.timeindexes_to_timestamp.any_vecs(),
|
||||
self.indexes_to_block_count.any_vecs(),
|
||||
self.indexes_to_block_interval.any_vecs(),
|
||||
self.indexes_to_block_size.any_vecs(),
|
||||
self.indexes_to_block_vbytes.any_vecs(),
|
||||
self.indexes_to_block_weight.any_vecs(),
|
||||
self.timeindexes_to_timestamp.vecs(),
|
||||
self.indexes_to_block_count.vecs(),
|
||||
self.indexes_to_block_interval.vecs(),
|
||||
self.indexes_to_block_size.vecs(),
|
||||
self.indexes_to_block_vbytes.vecs(),
|
||||
self.indexes_to_block_weight.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -0,0 +1,149 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::StoredU8;
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyCollectableVec, AnyVec, Compressed, Computation, Version};
|
||||
|
||||
use super::{
|
||||
Indexes,
|
||||
grouped::{ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub _0: ComputedVecsFromHeight<StoredU8>,
|
||||
pub _1: ComputedVecsFromHeight<StoredU8>,
|
||||
pub _50: ComputedVecsFromHeight<StoredU8>,
|
||||
pub _100: ComputedVecsFromHeight<StoredU8>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
_computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
_0: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"0",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
_1: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"1",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
_50: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"50",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
_100: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"100",
|
||||
true,
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
self._0.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, StoredU8::new(0)),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self._1.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, StoredU8::new(1)),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self._50.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, StoredU8::new(50)),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self._100.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, StoredU8::new(100)),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self._0.vecs(),
|
||||
self._1.vecs(),
|
||||
self._50.vecs(),
|
||||
self._100.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
+113
-129
@@ -7,12 +7,12 @@ use brk_core::{
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{Compressed, Version};
|
||||
use brk_vec::{AnyCollectableVec, AnyIterableVec, Compressed, Computation, EagerVec, Version};
|
||||
|
||||
use super::{
|
||||
EagerVec, Indexes,
|
||||
Indexes,
|
||||
grouped::{
|
||||
ComputedVecsFromDateindex, ComputedVecsFromHeightStrict, StorableVecGeneatorOptions,
|
||||
ComputedVecsFromDateIndex, ComputedVecsFromHeightStrict, StorableVecGeneatorOptions,
|
||||
},
|
||||
indexes,
|
||||
};
|
||||
@@ -33,14 +33,14 @@ pub struct Vecs {
|
||||
pub height_to_ohlc_in_sats: EagerVec<Height, OHLCSats>,
|
||||
pub height_to_ohlc_in_cents: EagerVec<Height, OHLCCents>,
|
||||
pub height_to_open_in_cents: EagerVec<Height, Open<Cents>>,
|
||||
pub timeindexes_to_close: ComputedVecsFromDateindex<Close<Dollars>>,
|
||||
pub timeindexes_to_high: ComputedVecsFromDateindex<High<Dollars>>,
|
||||
pub timeindexes_to_low: ComputedVecsFromDateindex<Low<Dollars>>,
|
||||
pub timeindexes_to_open: ComputedVecsFromDateindex<Open<Dollars>>,
|
||||
pub timeindexes_to_open_in_sats: ComputedVecsFromDateindex<Open<Sats>>,
|
||||
pub timeindexes_to_high_in_sats: ComputedVecsFromDateindex<High<Sats>>,
|
||||
pub timeindexes_to_low_in_sats: ComputedVecsFromDateindex<Low<Sats>>,
|
||||
pub timeindexes_to_close_in_sats: ComputedVecsFromDateindex<Close<Sats>>,
|
||||
pub timeindexes_to_close: ComputedVecsFromDateIndex<Close<Dollars>>,
|
||||
pub timeindexes_to_high: ComputedVecsFromDateIndex<High<Dollars>>,
|
||||
pub timeindexes_to_low: ComputedVecsFromDateIndex<Low<Dollars>>,
|
||||
pub timeindexes_to_open: ComputedVecsFromDateIndex<Open<Dollars>>,
|
||||
pub timeindexes_to_open_in_sats: ComputedVecsFromDateIndex<Open<Sats>>,
|
||||
pub timeindexes_to_high_in_sats: ComputedVecsFromDateIndex<High<Sats>>,
|
||||
pub timeindexes_to_low_in_sats: ComputedVecsFromDateIndex<Low<Sats>>,
|
||||
pub timeindexes_to_close_in_sats: ComputedVecsFromDateIndex<Close<Sats>>,
|
||||
pub chainindexes_to_close: ComputedVecsFromHeightStrict<Close<Dollars>>,
|
||||
pub chainindexes_to_high: ComputedVecsFromHeightStrict<High<Dollars>>,
|
||||
pub chainindexes_to_low: ComputedVecsFromHeightStrict<Low<Dollars>>,
|
||||
@@ -69,7 +69,11 @@ const VERSION: Version = Version::ZERO;
|
||||
const VERSION_IN_SATS: Version = Version::ONE;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(path: &Path, compressed: Compressed) -> color_eyre::Result<Self> {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
_computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
let mut fetched_path = path.to_owned();
|
||||
@@ -147,56 +151,56 @@ impl Vecs {
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
timeindexes_to_open: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_open: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"open",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_first(),
|
||||
)?,
|
||||
timeindexes_to_high: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_high: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"high",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_max(),
|
||||
)?,
|
||||
timeindexes_to_low: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_low: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"low",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_min(),
|
||||
)?,
|
||||
timeindexes_to_close: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_close: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"close",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
timeindexes_to_open_in_sats: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_open_in_sats: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"open_in_sats",
|
||||
VERSION + VERSION_IN_SATS + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_first(),
|
||||
)?,
|
||||
timeindexes_to_high_in_sats: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_high_in_sats: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"high_in_sats",
|
||||
VERSION + VERSION_IN_SATS + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_max(),
|
||||
)?,
|
||||
timeindexes_to_low_in_sats: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_low_in_sats: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"low_in_sats",
|
||||
VERSION + VERSION_IN_SATS + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_min(),
|
||||
)?,
|
||||
timeindexes_to_close_in_sats: ComputedVecsFromDateindex::forced_import(
|
||||
timeindexes_to_close_in_sats: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"close_in_sats",
|
||||
VERSION + VERSION_IN_SATS + Version::ZERO,
|
||||
@@ -336,15 +340,14 @@ impl Vecs {
|
||||
let mut height_to_timestamp_iter = indexer_vecs.height_to_timestamp.iter();
|
||||
self.height_to_ohlc_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
indexer_vecs.height_to_timestamp.vec(),
|
||||
&indexer_vecs.height_to_timestamp,
|
||||
|(h, t, ..)| {
|
||||
let ohlc = fetcher
|
||||
.get_height(
|
||||
h,
|
||||
t,
|
||||
h.decremented().map(|prev_h| {
|
||||
height_to_timestamp_iter.get(prev_h).unwrap().1.into_inner()
|
||||
}),
|
||||
h.decremented()
|
||||
.map(|prev_h| height_to_timestamp_iter.unwrap_get_inner(prev_h)),
|
||||
)
|
||||
.unwrap();
|
||||
(h, ohlc)
|
||||
@@ -354,42 +357,42 @@ impl Vecs {
|
||||
|
||||
self.height_to_open_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc_in_cents.vec(),
|
||||
&self.height_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.open),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_high_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc_in_cents.vec(),
|
||||
&self.height_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.high),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_low_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc_in_cents.vec(),
|
||||
&self.height_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.low),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_close_in_cents.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc_in_cents.vec(),
|
||||
&self.height_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.close),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_ohlc.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc_in_cents.vec(),
|
||||
&self.height_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, OHLCDollars::from(ohlc)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_ohlc_in_cents.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
indexes.dateindex_to_date.vec(),
|
||||
&indexes.dateindex_to_date,
|
||||
|(di, d, ..)| {
|
||||
let ohlc = fetcher.get_date(d).unwrap();
|
||||
(di, ohlc)
|
||||
@@ -399,35 +402,35 @@ impl Vecs {
|
||||
|
||||
self.dateindex_to_open_in_cents.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc_in_cents.vec(),
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.open),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_high_in_cents.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc_in_cents.vec(),
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.high),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_low_in_cents.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc_in_cents.vec(),
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.low),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_close_in_cents.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc_in_cents.vec(),
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, ohlc.close),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_ohlc.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc_in_cents.vec(),
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
|(di, ohlc, ..)| (di, OHLCDollars::from(ohlc)),
|
||||
exit,
|
||||
)?;
|
||||
@@ -440,7 +443,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc.vec(),
|
||||
&self.dateindex_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.close),
|
||||
exit,
|
||||
)
|
||||
@@ -455,7 +458,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc.vec(),
|
||||
&self.dateindex_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.high),
|
||||
exit,
|
||||
)
|
||||
@@ -470,7 +473,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc.vec(),
|
||||
&self.dateindex_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.low),
|
||||
exit,
|
||||
)
|
||||
@@ -485,7 +488,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.dateindex_to_ohlc.vec(),
|
||||
&self.dateindex_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.open),
|
||||
exit,
|
||||
)
|
||||
@@ -500,7 +503,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc.vec(),
|
||||
&self.height_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.close),
|
||||
exit,
|
||||
)
|
||||
@@ -515,7 +518,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc.vec(),
|
||||
&self.height_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.high),
|
||||
exit,
|
||||
)
|
||||
@@ -530,7 +533,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc.vec(),
|
||||
&self.height_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.low),
|
||||
exit,
|
||||
)
|
||||
@@ -545,7 +548,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.height_to_ohlc.vec(),
|
||||
&self.height_to_ohlc,
|
||||
|(di, ohlc, ..)| (di, ohlc.open),
|
||||
exit,
|
||||
)
|
||||
@@ -557,7 +560,7 @@ impl Vecs {
|
||||
let mut weekindex_min_iter = self.timeindexes_to_low.weekindex.unwrap_min().iter();
|
||||
self.weekindex_to_ohlc.compute_transform(
|
||||
starting_indexes.weekindex,
|
||||
self.timeindexes_to_close.weekindex.unwrap_last().vec(),
|
||||
self.timeindexes_to_close.weekindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -586,10 +589,7 @@ impl Vecs {
|
||||
self.chainindexes_to_low.difficultyepoch.unwrap_min().iter();
|
||||
self.difficultyepoch_to_ohlc.compute_transform(
|
||||
starting_indexes.difficultyepoch,
|
||||
self.chainindexes_to_close
|
||||
.difficultyepoch
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.chainindexes_to_close.difficultyepoch.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -609,7 +609,7 @@ impl Vecs {
|
||||
let mut monthindex_min_iter = self.timeindexes_to_low.monthindex.unwrap_min().iter();
|
||||
self.monthindex_to_ohlc.compute_transform(
|
||||
starting_indexes.monthindex,
|
||||
self.timeindexes_to_close.monthindex.unwrap_last().vec(),
|
||||
self.timeindexes_to_close.monthindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -630,7 +630,7 @@ impl Vecs {
|
||||
let mut quarterindex_min_iter = self.timeindexes_to_low.quarterindex.unwrap_min().iter();
|
||||
self.quarterindex_to_ohlc.compute_transform(
|
||||
starting_indexes.quarterindex,
|
||||
self.timeindexes_to_close.quarterindex.unwrap_last().vec(),
|
||||
self.timeindexes_to_close.quarterindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -650,7 +650,7 @@ impl Vecs {
|
||||
let mut yearindex_min_iter = self.timeindexes_to_low.yearindex.unwrap_min().iter();
|
||||
self.yearindex_to_ohlc.compute_transform(
|
||||
starting_indexes.yearindex,
|
||||
self.timeindexes_to_close.yearindex.unwrap_last().vec(),
|
||||
self.timeindexes_to_close.yearindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -673,7 +673,7 @@ impl Vecs {
|
||||
let mut decadeindex_min_iter = self.timeindexes_to_low.decadeindex.unwrap_min().iter();
|
||||
self.decadeindex_to_ohlc.compute_transform(
|
||||
starting_indexes.decadeindex,
|
||||
self.timeindexes_to_close.decadeindex.unwrap_last().vec(),
|
||||
self.timeindexes_to_close.decadeindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -696,7 +696,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.chainindexes_to_open.height.vec(),
|
||||
&self.chainindexes_to_open.height,
|
||||
|(i, open, ..)| (i, Open::new(Sats::ONE_BTC / *open)),
|
||||
exit,
|
||||
)
|
||||
@@ -711,7 +711,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.chainindexes_to_low.height.vec(),
|
||||
&self.chainindexes_to_low.height,
|
||||
|(i, low, ..)| (i, High::new(Sats::ONE_BTC / *low)),
|
||||
exit,
|
||||
)
|
||||
@@ -726,7 +726,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.chainindexes_to_high.height.vec(),
|
||||
&self.chainindexes_to_high.height,
|
||||
|(i, high, ..)| (i, Low::new(Sats::ONE_BTC / *high)),
|
||||
exit,
|
||||
)
|
||||
@@ -741,7 +741,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.chainindexes_to_close.height.vec(),
|
||||
&self.chainindexes_to_close.height,
|
||||
|(i, close, ..)| (i, Close::new(Sats::ONE_BTC / *close)),
|
||||
exit,
|
||||
)
|
||||
@@ -756,7 +756,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.timeindexes_to_open.dateindex.vec(),
|
||||
&self.timeindexes_to_open.dateindex,
|
||||
|(i, open, ..)| (i, Open::new(Sats::ONE_BTC / *open)),
|
||||
exit,
|
||||
)
|
||||
@@ -771,7 +771,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.timeindexes_to_low.dateindex.vec(),
|
||||
&self.timeindexes_to_low.dateindex,
|
||||
|(i, low, ..)| (i, High::new(Sats::ONE_BTC / *low)),
|
||||
exit,
|
||||
)
|
||||
@@ -786,7 +786,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.timeindexes_to_high.dateindex.vec(),
|
||||
&self.timeindexes_to_high.dateindex,
|
||||
|(i, high, ..)| (i, Low::new(Sats::ONE_BTC / *high)),
|
||||
exit,
|
||||
)
|
||||
@@ -801,7 +801,7 @@ impl Vecs {
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.timeindexes_to_close.dateindex.vec(),
|
||||
&self.timeindexes_to_close.dateindex,
|
||||
|(i, close, ..)| (i, Close::new(Sats::ONE_BTC / *close)),
|
||||
exit,
|
||||
)
|
||||
@@ -813,7 +813,7 @@ impl Vecs {
|
||||
let mut height_min_iter = self.chainindexes_to_low_in_sats.height.iter();
|
||||
self.height_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.chainindexes_to_close_in_sats.height.vec(),
|
||||
&self.chainindexes_to_close_in_sats.height,
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -833,7 +833,7 @@ impl Vecs {
|
||||
let mut dateindex_min_iter = self.timeindexes_to_low_in_sats.dateindex.iter();
|
||||
self.dateindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.timeindexes_to_close_in_sats.dateindex.vec(),
|
||||
&self.timeindexes_to_close_in_sats.dateindex,
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -865,10 +865,7 @@ impl Vecs {
|
||||
.iter();
|
||||
self.weekindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.weekindex,
|
||||
self.timeindexes_to_close_in_sats
|
||||
.weekindex
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.timeindexes_to_close_in_sats.weekindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -902,8 +899,7 @@ impl Vecs {
|
||||
starting_indexes.difficultyepoch,
|
||||
self.chainindexes_to_close_in_sats
|
||||
.difficultyepoch
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -935,10 +931,7 @@ impl Vecs {
|
||||
.iter();
|
||||
self.monthindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.monthindex,
|
||||
self.timeindexes_to_close_in_sats
|
||||
.monthindex
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.timeindexes_to_close_in_sats.monthindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -970,10 +963,7 @@ impl Vecs {
|
||||
.iter();
|
||||
self.quarterindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.quarterindex,
|
||||
self.timeindexes_to_close_in_sats
|
||||
.quarterindex
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.timeindexes_to_close_in_sats.quarterindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -1005,10 +995,7 @@ impl Vecs {
|
||||
.iter();
|
||||
self.yearindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.yearindex,
|
||||
self.timeindexes_to_close_in_sats
|
||||
.yearindex
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.timeindexes_to_close_in_sats.yearindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -1043,10 +1030,7 @@ impl Vecs {
|
||||
.iter();
|
||||
self.decadeindex_to_ohlc_in_sats.compute_transform(
|
||||
starting_indexes.decadeindex,
|
||||
self.timeindexes_to_close_in_sats
|
||||
.decadeindex
|
||||
.unwrap_last()
|
||||
.vec(),
|
||||
self.timeindexes_to_close_in_sats.decadeindex.unwrap_last(),
|
||||
|(i, close, ..)| {
|
||||
(
|
||||
i,
|
||||
@@ -1064,54 +1048,54 @@ impl Vecs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
vec![
|
||||
vec![
|
||||
self.dateindex_to_close_in_cents.any_vec(),
|
||||
self.dateindex_to_high_in_cents.any_vec(),
|
||||
self.dateindex_to_low_in_cents.any_vec(),
|
||||
self.dateindex_to_ohlc.any_vec(),
|
||||
self.dateindex_to_ohlc_in_cents.any_vec(),
|
||||
self.dateindex_to_open_in_cents.any_vec(),
|
||||
self.height_to_close_in_cents.any_vec(),
|
||||
self.height_to_high_in_cents.any_vec(),
|
||||
self.height_to_low_in_cents.any_vec(),
|
||||
self.height_to_ohlc.any_vec(),
|
||||
self.height_to_ohlc_in_cents.any_vec(),
|
||||
self.height_to_open_in_cents.any_vec(),
|
||||
self.weekindex_to_ohlc.any_vec(),
|
||||
self.difficultyepoch_to_ohlc.any_vec(),
|
||||
self.monthindex_to_ohlc.any_vec(),
|
||||
self.quarterindex_to_ohlc.any_vec(),
|
||||
self.yearindex_to_ohlc.any_vec(),
|
||||
// self.halvingepoch_to_ohlc.any_vec(),
|
||||
self.decadeindex_to_ohlc.any_vec(),
|
||||
self.height_to_ohlc_in_sats.any_vec(),
|
||||
self.dateindex_to_ohlc_in_sats.any_vec(),
|
||||
self.weekindex_to_ohlc_in_sats.any_vec(),
|
||||
self.difficultyepoch_to_ohlc_in_sats.any_vec(),
|
||||
self.monthindex_to_ohlc_in_sats.any_vec(),
|
||||
self.quarterindex_to_ohlc_in_sats.any_vec(),
|
||||
self.yearindex_to_ohlc_in_sats.any_vec(),
|
||||
// self.halvingepoch_to_ohlc_in_sats.any_vec(),
|
||||
self.decadeindex_to_ohlc_in_sats.any_vec(),
|
||||
&self.dateindex_to_close_in_cents as &dyn AnyCollectableVec,
|
||||
&self.dateindex_to_high_in_cents,
|
||||
&self.dateindex_to_low_in_cents,
|
||||
&self.dateindex_to_ohlc,
|
||||
&self.dateindex_to_ohlc_in_cents,
|
||||
&self.dateindex_to_open_in_cents,
|
||||
&self.height_to_close_in_cents,
|
||||
&self.height_to_high_in_cents,
|
||||
&self.height_to_low_in_cents,
|
||||
&self.height_to_ohlc,
|
||||
&self.height_to_ohlc_in_cents,
|
||||
&self.height_to_open_in_cents,
|
||||
&self.weekindex_to_ohlc,
|
||||
&self.difficultyepoch_to_ohlc,
|
||||
&self.monthindex_to_ohlc,
|
||||
&self.quarterindex_to_ohlc,
|
||||
&self.yearindex_to_ohlc,
|
||||
// &self.halvingepoch_to_ohlc,
|
||||
&self.decadeindex_to_ohlc,
|
||||
&self.height_to_ohlc_in_sats,
|
||||
&self.dateindex_to_ohlc_in_sats,
|
||||
&self.weekindex_to_ohlc_in_sats,
|
||||
&self.difficultyepoch_to_ohlc_in_sats,
|
||||
&self.monthindex_to_ohlc_in_sats,
|
||||
&self.quarterindex_to_ohlc_in_sats,
|
||||
&self.yearindex_to_ohlc_in_sats,
|
||||
// &self.halvingepoch_to_ohlc_in_sats,
|
||||
&self.decadeindex_to_ohlc_in_sats,
|
||||
],
|
||||
self.timeindexes_to_close.any_vecs(),
|
||||
self.timeindexes_to_high.any_vecs(),
|
||||
self.timeindexes_to_low.any_vecs(),
|
||||
self.timeindexes_to_open.any_vecs(),
|
||||
self.chainindexes_to_close.any_vecs(),
|
||||
self.chainindexes_to_high.any_vecs(),
|
||||
self.chainindexes_to_low.any_vecs(),
|
||||
self.chainindexes_to_open.any_vecs(),
|
||||
self.timeindexes_to_close_in_sats.any_vecs(),
|
||||
self.timeindexes_to_high_in_sats.any_vecs(),
|
||||
self.timeindexes_to_low_in_sats.any_vecs(),
|
||||
self.timeindexes_to_open_in_sats.any_vecs(),
|
||||
self.chainindexes_to_close_in_sats.any_vecs(),
|
||||
self.chainindexes_to_high_in_sats.any_vecs(),
|
||||
self.chainindexes_to_low_in_sats.any_vecs(),
|
||||
self.chainindexes_to_open_in_sats.any_vecs(),
|
||||
self.timeindexes_to_close.vecs(),
|
||||
self.timeindexes_to_high.vecs(),
|
||||
self.timeindexes_to_low.vecs(),
|
||||
self.timeindexes_to_open.vecs(),
|
||||
self.chainindexes_to_close.vecs(),
|
||||
self.chainindexes_to_high.vecs(),
|
||||
self.chainindexes_to_low.vecs(),
|
||||
self.chainindexes_to_open.vecs(),
|
||||
self.timeindexes_to_close_in_sats.vecs(),
|
||||
self.timeindexes_to_high_in_sats.vecs(),
|
||||
self.timeindexes_to_low_in_sats.vecs(),
|
||||
self.timeindexes_to_open_in_sats.vecs(),
|
||||
self.chainindexes_to_close_in_sats.vecs(),
|
||||
self.chainindexes_to_high_in_sats.vecs(),
|
||||
self.chainindexes_to_low_in_sats.vecs(),
|
||||
self.chainindexes_to_open_in_sats.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
+248
-135
@@ -2,10 +2,15 @@ use std::path::Path;
|
||||
|
||||
use brk_core::{CheckedSub, StoredUsize};
|
||||
use brk_exit::Exit;
|
||||
use brk_vec::{Compressed, DynamicVec, Result, StoredIndex, StoredType, StoredVec, Version};
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, AnyIterableVec, Compressed, EagerVec, Result, StoredIndex, StoredType,
|
||||
Version,
|
||||
};
|
||||
use color_eyre::eyre::ContextCompat;
|
||||
|
||||
use crate::storage::{ComputedType, EagerVec};
|
||||
use crate::utils::get_percentile;
|
||||
|
||||
use super::ComputedType;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
pub struct ComputedVecBuilder<I, T>
|
||||
@@ -13,18 +18,18 @@ where
|
||||
I: StoredIndex,
|
||||
T: ComputedType,
|
||||
{
|
||||
first: Option<EagerVec<I, T>>,
|
||||
average: Option<EagerVec<I, T>>,
|
||||
sum: Option<EagerVec<I, T>>,
|
||||
max: Option<EagerVec<I, T>>,
|
||||
_90p: Option<EagerVec<I, T>>,
|
||||
_75p: Option<EagerVec<I, T>>,
|
||||
median: Option<EagerVec<I, T>>,
|
||||
_25p: Option<EagerVec<I, T>>,
|
||||
_10p: Option<EagerVec<I, T>>,
|
||||
min: Option<EagerVec<I, T>>,
|
||||
last: Option<EagerVec<I, T>>,
|
||||
total: Option<EagerVec<I, T>>,
|
||||
first: Option<Box<EagerVec<I, T>>>,
|
||||
average: Option<Box<EagerVec<I, T>>>,
|
||||
sum: Option<Box<EagerVec<I, T>>>,
|
||||
max: Option<Box<EagerVec<I, T>>>,
|
||||
_90p: Option<Box<EagerVec<I, T>>>,
|
||||
_75p: Option<Box<EagerVec<I, T>>>,
|
||||
median: Option<Box<EagerVec<I, T>>>,
|
||||
_25p: Option<Box<EagerVec<I, T>>>,
|
||||
_10p: Option<Box<EagerVec<I, T>>>,
|
||||
min: Option<Box<EagerVec<I, T>>>,
|
||||
last: Option<Box<EagerVec<I, T>>>,
|
||||
total: Option<Box<EagerVec<I, T>>>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
@@ -71,71 +76,132 @@ where
|
||||
|
||||
let s = Self {
|
||||
first: options.first.then(|| {
|
||||
EagerVec::forced_import(&maybe_prefix("first"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_prefix("first"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
last: options.last.then(|| {
|
||||
EagerVec::forced_import(
|
||||
&path.join(format!("{key}_to_{name}")),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&path.join(format!("{key}_to_{name}")),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
min: options.min.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("min"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("min"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
max: options.max.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("max"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("max"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
median: options.median.then(|| {
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("median"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("median"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
average: options.average.then(|| {
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("average"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("average"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
sum: options.sum.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("sum"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("sum"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
total: options.total.then(|| {
|
||||
EagerVec::forced_import(&prefix("total"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(&prefix("total"), version + Version::ZERO, compressed)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
_90p: options._90p.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("90p"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("90p"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
_75p: options._75p.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("75p"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("75p"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
_25p: options._25p.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("25p"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("25p"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
_10p: options._10p.then(|| {
|
||||
EagerVec::forced_import(&maybe_suffix("10p"), version + Version::ZERO, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&maybe_suffix("10p"),
|
||||
version + Version::ZERO,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
}),
|
||||
};
|
||||
|
||||
Ok(s)
|
||||
}
|
||||
|
||||
pub fn extend(&mut self, max_from: I, source: &StoredVec<I, T>, exit: &Exit) -> Result<()> {
|
||||
pub fn extend(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
source: &impl AnyIterableVec<I, T>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
if self.total.is_none() {
|
||||
return Ok(());
|
||||
};
|
||||
@@ -160,14 +226,18 @@ where
|
||||
pub fn compute<I2>(
|
||||
&mut self,
|
||||
max_from: I,
|
||||
source: &StoredVec<I2, T>,
|
||||
first_indexes: &StoredVec<I, I2>,
|
||||
count_indexes: &StoredVec<I, StoredUsize>,
|
||||
source: &impl AnyIterableVec<I2, T>,
|
||||
first_indexes: &impl AnyIterableVec<I, I2>,
|
||||
count_indexes: &impl AnyIterableVec<I, StoredUsize>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
I2: StoredIndex + StoredType + CheckedSub<I2>,
|
||||
{
|
||||
self.validate_computed_version_or_reset_file(
|
||||
source.version() + first_indexes.version() + count_indexes.version(),
|
||||
)?;
|
||||
|
||||
let index = self.starting_index(max_from);
|
||||
|
||||
let mut count_indexes_iter = count_indexes.iter();
|
||||
@@ -186,12 +256,12 @@ where
|
||||
.try_for_each(|(i, first_index)| -> Result<()> {
|
||||
let first_index = first_index.into_inner();
|
||||
|
||||
let count_index = count_indexes_iter.get(i).unwrap().1.into_inner();
|
||||
let count_index = count_indexes_iter.unwrap_get_inner(i);
|
||||
|
||||
if let Some(first) = self.first.as_mut() {
|
||||
let f = source_iter
|
||||
.get(first_index)
|
||||
.map_or(T::from(0_usize), |f| f.1.into_inner());
|
||||
.get_inner(first_index)
|
||||
.unwrap_or_else(|| T::from(0_usize));
|
||||
first.forced_push_at(index, f, exit)?;
|
||||
}
|
||||
|
||||
@@ -201,15 +271,13 @@ where
|
||||
panic!("should compute last if count can be 0")
|
||||
}
|
||||
let last_index = first_index + (count_index - 1);
|
||||
let v = source_iter
|
||||
.get(last_index)
|
||||
.context("to work")
|
||||
.inspect_err(|_| {
|
||||
dbg!(first_index, count_index, last_index);
|
||||
})
|
||||
.unwrap()
|
||||
.1
|
||||
.into_inner();
|
||||
let v = source_iter.unwrap_get_inner(last_index);
|
||||
// .context("to work")
|
||||
// .inspect_err(|_| {
|
||||
// dbg!(first_index, count_index, last_index);
|
||||
// })
|
||||
// .unwrap()
|
||||
// .into_inner();
|
||||
last.forced_push_at(index, v, exit)?;
|
||||
}
|
||||
|
||||
@@ -244,12 +312,12 @@ where
|
||||
dbg!(
|
||||
&values,
|
||||
max.path(),
|
||||
first_indexes.path(),
|
||||
first_indexes.name(),
|
||||
first_index,
|
||||
count_indexes.path(),
|
||||
count_indexes.name(),
|
||||
count_index,
|
||||
source.len(),
|
||||
source.path()
|
||||
source.name()
|
||||
);
|
||||
})
|
||||
.unwrap()
|
||||
@@ -259,23 +327,23 @@ where
|
||||
}
|
||||
|
||||
if let Some(_90p) = self._90p.as_mut() {
|
||||
_90p.forced_push_at(i, Self::get_percentile(&values, 0.90), exit)?;
|
||||
_90p.forced_push_at(i, get_percentile(&values, 0.90), exit)?;
|
||||
}
|
||||
|
||||
if let Some(_75p) = self._75p.as_mut() {
|
||||
_75p.forced_push_at(i, Self::get_percentile(&values, 0.75), exit)?;
|
||||
_75p.forced_push_at(i, get_percentile(&values, 0.75), exit)?;
|
||||
}
|
||||
|
||||
if let Some(median) = self.median.as_mut() {
|
||||
median.forced_push_at(i, Self::get_percentile(&values, 0.50), exit)?;
|
||||
median.forced_push_at(i, get_percentile(&values, 0.50), exit)?;
|
||||
}
|
||||
|
||||
if let Some(_25p) = self._25p.as_mut() {
|
||||
_25p.forced_push_at(i, Self::get_percentile(&values, 0.25), exit)?;
|
||||
_25p.forced_push_at(i, get_percentile(&values, 0.25), exit)?;
|
||||
}
|
||||
|
||||
if let Some(_10p) = self._10p.as_mut() {
|
||||
_10p.forced_push_at(i, Self::get_percentile(&values, 0.10), exit)?;
|
||||
_10p.forced_push_at(i, get_percentile(&values, 0.10), exit)?;
|
||||
}
|
||||
|
||||
if let Some(min) = self.min.as_mut() {
|
||||
@@ -319,8 +387,8 @@ where
|
||||
&mut self,
|
||||
max_from: I,
|
||||
source: &ComputedVecBuilder<I2, T>,
|
||||
first_indexes: &StoredVec<I, I2>,
|
||||
count_indexes: &StoredVec<I, StoredUsize>,
|
||||
first_indexes: &impl AnyIterableVec<I, I2>,
|
||||
count_indexes: &impl AnyIterableVec<I, StoredUsize>,
|
||||
exit: &Exit,
|
||||
) -> Result<()>
|
||||
where
|
||||
@@ -335,6 +403,10 @@ where
|
||||
panic!("unsupported");
|
||||
}
|
||||
|
||||
self.validate_computed_version_or_reset_file(
|
||||
VERSION + first_indexes.version() + count_indexes.version(),
|
||||
)?;
|
||||
|
||||
let index = self.starting_index(max_from);
|
||||
|
||||
let mut count_indexes_iter = count_indexes.iter();
|
||||
@@ -357,7 +429,7 @@ where
|
||||
.try_for_each(|(i, first_index, ..)| -> Result<()> {
|
||||
let first_index = first_index.into_inner();
|
||||
|
||||
let count_index = count_indexes_iter.get(i).unwrap().1.into_inner();
|
||||
let count_index = count_indexes_iter.unwrap_get_inner(i);
|
||||
|
||||
if let Some(first) = self.first.as_mut() {
|
||||
let v = source_first_iter
|
||||
@@ -458,109 +530,94 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn get_percentile(sorted: &[T], percentile: f64) -> T {
|
||||
let len = sorted.len();
|
||||
|
||||
if len == 0 {
|
||||
panic!();
|
||||
} else if len == 1 {
|
||||
sorted[0].clone()
|
||||
} else {
|
||||
let index = (len - 1) as f64 * percentile;
|
||||
|
||||
let fract = index.fract();
|
||||
|
||||
if fract != 0.0 {
|
||||
let left = sorted.get(index as usize).unwrap().clone();
|
||||
let right = sorted.get(index.ceil() as usize).unwrap().clone();
|
||||
left / 2 + right / 2
|
||||
} else {
|
||||
sorted.get(index as usize).unwrap().clone()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn starting_index(&self, max_from: I) -> I {
|
||||
max_from.min(I::from(
|
||||
self.any_vecs().into_iter().map(|v| v.len()).min().unwrap(),
|
||||
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn unwrap_first(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.first.as_mut().unwrap()
|
||||
pub fn unwrap_first(&self) -> &EagerVec<I, T> {
|
||||
self.first.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_average(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.average.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_average(&self) -> &EagerVec<I, T> {
|
||||
self.average.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_sum(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.sum.as_mut().unwrap()
|
||||
pub fn unwrap_sum(&self) -> &EagerVec<I, T> {
|
||||
self.sum.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_max(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.max.as_mut().unwrap()
|
||||
pub fn unwrap_max(&self) -> &EagerVec<I, T> {
|
||||
self.max.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_90p(&mut self) -> &mut EagerVec<I, T> {
|
||||
self._90p.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_90p(&self) -> &EagerVec<I, T> {
|
||||
self._90p.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_75p(&mut self) -> &mut EagerVec<I, T> {
|
||||
self._75p.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_75p(&self) -> &EagerVec<I, T> {
|
||||
self._75p.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_median(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.median.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_median(&self) -> &EagerVec<I, T> {
|
||||
self.median.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_25p(&mut self) -> &mut EagerVec<I, T> {
|
||||
self._25p.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_25p(&self) -> &EagerVec<I, T> {
|
||||
self._25p.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_10p(&mut self) -> &mut EagerVec<I, T> {
|
||||
self._10p.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_10p(&self) -> &EagerVec<I, T> {
|
||||
self._10p.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_min(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.min.as_mut().unwrap()
|
||||
pub fn unwrap_min(&self) -> &EagerVec<I, T> {
|
||||
self.min.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_last(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.last.as_mut().unwrap()
|
||||
pub fn unwrap_last(&self) -> &EagerVec<I, T> {
|
||||
self.last.as_ref().unwrap()
|
||||
}
|
||||
pub fn unwrap_total(&mut self) -> &mut EagerVec<I, T> {
|
||||
self.total.as_mut().unwrap()
|
||||
#[allow(unused)]
|
||||
pub fn unwrap_total(&self) -> &EagerVec<I, T> {
|
||||
self.total.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
|
||||
let mut v: Vec<&dyn brk_vec::AnyStoredVec> = vec![];
|
||||
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.any_vec());
|
||||
v.push(first.as_ref());
|
||||
}
|
||||
if let Some(last) = self.last.as_ref() {
|
||||
v.push(last.any_vec());
|
||||
v.push(last.as_ref());
|
||||
}
|
||||
if let Some(min) = self.min.as_ref() {
|
||||
v.push(min.any_vec());
|
||||
v.push(min.as_ref());
|
||||
}
|
||||
if let Some(max) = self.max.as_ref() {
|
||||
v.push(max.any_vec());
|
||||
v.push(max.as_ref());
|
||||
}
|
||||
if let Some(median) = self.median.as_ref() {
|
||||
v.push(median.any_vec());
|
||||
v.push(median.as_ref());
|
||||
}
|
||||
if let Some(average) = self.average.as_ref() {
|
||||
v.push(average.any_vec());
|
||||
v.push(average.as_ref());
|
||||
}
|
||||
if let Some(sum) = self.sum.as_ref() {
|
||||
v.push(sum.any_vec());
|
||||
v.push(sum.as_ref());
|
||||
}
|
||||
if let Some(total) = self.total.as_ref() {
|
||||
v.push(total.any_vec());
|
||||
v.push(total.as_ref());
|
||||
}
|
||||
if let Some(_90p) = self._90p.as_ref() {
|
||||
v.push(_90p.any_vec());
|
||||
v.push(_90p.as_ref());
|
||||
}
|
||||
if let Some(_75p) = self._75p.as_ref() {
|
||||
v.push(_75p.any_vec());
|
||||
v.push(_75p.as_ref());
|
||||
}
|
||||
if let Some(_25p) = self._25p.as_ref() {
|
||||
v.push(_25p.any_vec());
|
||||
v.push(_25p.as_ref());
|
||||
}
|
||||
if let Some(_10p) = self._10p.as_ref() {
|
||||
v.push(_10p.any_vec());
|
||||
v.push(_10p.as_ref());
|
||||
}
|
||||
|
||||
v
|
||||
@@ -606,6 +663,47 @@ where
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn validate_computed_version_or_reset_file(&mut self, version: Version) -> Result<()> {
|
||||
if let Some(first) = self.first.as_mut() {
|
||||
first.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(last) = self.last.as_mut() {
|
||||
last.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(min) = self.min.as_mut() {
|
||||
min.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(max) = self.max.as_mut() {
|
||||
max.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(median) = self.median.as_mut() {
|
||||
median.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(average) = self.average.as_mut() {
|
||||
average.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(sum) = self.sum.as_mut() {
|
||||
sum.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(total) = self.total.as_mut() {
|
||||
total.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(_90p) = self._90p.as_mut() {
|
||||
_90p.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(_75p) = self._75p.as_mut() {
|
||||
_75p.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(_25p) = self._25p.as_mut() {
|
||||
_25p.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
if let Some(_10p) = self._10p.as_mut() {
|
||||
_10p.validate_computed_version_or_reset_file(Version::ZERO + version)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Clone, Copy)]
|
||||
@@ -645,6 +743,7 @@ impl StorableVecGeneatorOptions {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn add_median(mut self) -> Self {
|
||||
self.median = true;
|
||||
self
|
||||
@@ -660,21 +759,25 @@ impl StorableVecGeneatorOptions {
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn add_90p(mut self) -> Self {
|
||||
self._90p = true;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn add_75p(mut self) -> Self {
|
||||
self._75p = true;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn add_25p(mut self) -> Self {
|
||||
self._25p = true;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn add_10p(mut self) -> Self {
|
||||
self._10p = true;
|
||||
self
|
||||
@@ -685,51 +788,61 @@ impl StorableVecGeneatorOptions {
|
||||
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_median(mut self) -> Self {
|
||||
self.median = 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_90p(mut self) -> Self {
|
||||
self._90p = false;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn rm_75p(mut self) -> Self {
|
||||
self._75p = false;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn rm_25p(mut self) -> Self {
|
||||
self._25p = false;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn rm_10p(mut self) -> Self {
|
||||
self._10p = false;
|
||||
self
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn rm_total(mut self) -> Self {
|
||||
self.total = false;
|
||||
self
|
||||
+35
-26
@@ -3,14 +3,14 @@ use std::path::Path;
|
||||
use brk_core::{DateIndex, DecadeIndex, MonthIndex, QuarterIndex, WeekIndex, YearIndex};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, Version};
|
||||
use brk_vec::{AnyCollectableVec, Compressed, EagerVec, Result, Version};
|
||||
|
||||
use crate::storage::{ComputedType, EagerVec, Indexes, indexes};
|
||||
use crate::vecs::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromDateindex<T>
|
||||
pub struct ComputedVecsFromDateIndex<T>
|
||||
where
|
||||
T: ComputedType + PartialOrd,
|
||||
{
|
||||
@@ -25,7 +25,7 @@ where
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
impl<T> ComputedVecsFromDateindex<T>
|
||||
impl<T> ComputedVecsFromDateIndex<T>
|
||||
where
|
||||
T: ComputedType,
|
||||
{
|
||||
@@ -94,61 +94,70 @@ where
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.compute_rest(indexes, starting_indexes, exit)
|
||||
}
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
self.dateindex_extra
|
||||
.extend(starting_indexes.dateindex, self.dateindex.vec(), exit)?;
|
||||
.extend(starting_indexes.dateindex, &self.dateindex, exit)?;
|
||||
|
||||
self.weekindex.compute(
|
||||
starting_indexes.weekindex,
|
||||
self.dateindex.vec(),
|
||||
indexes.weekindex_to_first_dateindex.vec(),
|
||||
indexes.weekindex_to_dateindex_count.vec(),
|
||||
&self.dateindex,
|
||||
&indexes.weekindex_to_first_dateindex,
|
||||
&indexes.weekindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex.compute(
|
||||
starting_indexes.monthindex,
|
||||
self.dateindex.vec(),
|
||||
indexes.monthindex_to_first_dateindex.vec(),
|
||||
indexes.monthindex_to_dateindex_count.vec(),
|
||||
&self.dateindex,
|
||||
&indexes.monthindex_to_first_dateindex,
|
||||
&indexes.monthindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex.from_aligned(
|
||||
starting_indexes.quarterindex,
|
||||
&self.monthindex,
|
||||
indexes.quarterindex_to_first_monthindex.vec(),
|
||||
indexes.quarterindex_to_monthindex_count.vec(),
|
||||
&indexes.quarterindex_to_first_monthindex,
|
||||
&indexes.quarterindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex.from_aligned(
|
||||
starting_indexes.yearindex,
|
||||
&self.monthindex,
|
||||
indexes.yearindex_to_first_monthindex.vec(),
|
||||
indexes.yearindex_to_monthindex_count.vec(),
|
||||
&indexes.yearindex_to_first_monthindex,
|
||||
&indexes.yearindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex.from_aligned(
|
||||
starting_indexes.decadeindex,
|
||||
&self.yearindex,
|
||||
indexes.decadeindex_to_first_yearindex.vec(),
|
||||
indexes.decadeindex_to_yearindex_count.vec(),
|
||||
&indexes.decadeindex_to_first_yearindex,
|
||||
&indexes.decadeindex_to_yearindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
vec![self.dateindex.any_vec()],
|
||||
self.dateindex_extra.any_vecs(),
|
||||
self.weekindex.any_vecs(),
|
||||
self.monthindex.any_vecs(),
|
||||
self.quarterindex.any_vecs(),
|
||||
self.yearindex.any_vecs(),
|
||||
self.decadeindex.any_vecs(),
|
||||
vec![&self.dateindex as &dyn AnyCollectableVec],
|
||||
self.dateindex_extra.vecs(),
|
||||
self.weekindex.vecs(),
|
||||
self.monthindex.vecs(),
|
||||
self.quarterindex.vecs(),
|
||||
self.yearindex.vecs(),
|
||||
self.decadeindex.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
+77
-47
@@ -5,18 +5,18 @@ use brk_core::{
|
||||
};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, StoredVec, Version};
|
||||
use brk_vec::{AnyCollectableVec, AnyIterableVec, Compressed, EagerVec, Result, Version};
|
||||
|
||||
use crate::storage::{ComputedType, EagerVec, Indexes, indexes};
|
||||
use crate::vecs::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromHeight<T>
|
||||
where
|
||||
T: ComputedType + PartialOrd,
|
||||
{
|
||||
pub height: Option<EagerVec<Height, T>>,
|
||||
pub height: Option<Box<EagerVec<Height, T>>>,
|
||||
pub height_extra: ComputedVecBuilder<Height, T>,
|
||||
pub dateindex: ComputedVecBuilder<DateIndex, T>,
|
||||
pub weekindex: ComputedVecBuilder<WeekIndex, T>,
|
||||
@@ -46,8 +46,14 @@ where
|
||||
let version = VERSION + version;
|
||||
|
||||
let height = compute_source.then(|| {
|
||||
EagerVec::forced_import(&path.join(format!("height_to_{name}")), version, compressed)
|
||||
.unwrap()
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&path.join(format!("height_to_{name}")),
|
||||
version,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
});
|
||||
|
||||
let height_extra = ComputedVecBuilder::forced_import(
|
||||
@@ -104,7 +110,8 @@ where
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.compute_rest(indexes, starting_indexes, exit, None)?;
|
||||
let height: Option<&EagerVec<Height, T>> = None;
|
||||
self.compute_rest(indexes, starting_indexes, exit, height)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -114,84 +121,107 @@ where
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
height: Option<&StoredVec<Height, T>>,
|
||||
height: Option<&impl AnyIterableVec<Height, T>>,
|
||||
) -> color_eyre::Result<()> {
|
||||
let height = height.unwrap_or_else(|| self.height.as_ref().unwrap().vec());
|
||||
if let Some(height) = height {
|
||||
self.height_extra
|
||||
.extend(starting_indexes.height, height, exit)?;
|
||||
|
||||
self.height_extra
|
||||
.extend(starting_indexes.height, height, exit)?;
|
||||
self.dateindex.compute(
|
||||
starting_indexes.dateindex,
|
||||
height,
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex.compute(
|
||||
starting_indexes.dateindex,
|
||||
height,
|
||||
indexes.dateindex_to_first_height.vec(),
|
||||
indexes.dateindex_to_height_count.vec(),
|
||||
exit,
|
||||
)?;
|
||||
self.difficultyepoch.compute(
|
||||
starting_indexes.difficultyepoch,
|
||||
height,
|
||||
&indexes.difficultyepoch_to_first_height,
|
||||
&indexes.difficultyepoch_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
} else {
|
||||
let height = self.height.as_ref().unwrap().as_ref();
|
||||
|
||||
self.height_extra
|
||||
.extend(starting_indexes.height, height, exit)?;
|
||||
|
||||
self.dateindex.compute(
|
||||
starting_indexes.dateindex,
|
||||
height,
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch.compute(
|
||||
starting_indexes.difficultyepoch,
|
||||
height,
|
||||
&indexes.difficultyepoch_to_first_height,
|
||||
&indexes.difficultyepoch_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.weekindex.from_aligned(
|
||||
starting_indexes.weekindex,
|
||||
&self.dateindex,
|
||||
indexes.weekindex_to_first_dateindex.vec(),
|
||||
indexes.weekindex_to_dateindex_count.vec(),
|
||||
&indexes.weekindex_to_first_dateindex,
|
||||
&indexes.weekindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex.from_aligned(
|
||||
starting_indexes.monthindex,
|
||||
&self.dateindex,
|
||||
indexes.monthindex_to_first_dateindex.vec(),
|
||||
indexes.monthindex_to_dateindex_count.vec(),
|
||||
&indexes.monthindex_to_first_dateindex,
|
||||
&indexes.monthindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex.from_aligned(
|
||||
starting_indexes.quarterindex,
|
||||
&self.monthindex,
|
||||
indexes.quarterindex_to_first_monthindex.vec(),
|
||||
indexes.quarterindex_to_monthindex_count.vec(),
|
||||
&indexes.quarterindex_to_first_monthindex,
|
||||
&indexes.quarterindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex.from_aligned(
|
||||
starting_indexes.yearindex,
|
||||
&self.monthindex,
|
||||
indexes.yearindex_to_first_monthindex.vec(),
|
||||
indexes.yearindex_to_monthindex_count.vec(),
|
||||
&indexes.yearindex_to_first_monthindex,
|
||||
&indexes.yearindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex.from_aligned(
|
||||
starting_indexes.decadeindex,
|
||||
&self.yearindex,
|
||||
indexes.decadeindex_to_first_yearindex.vec(),
|
||||
indexes.decadeindex_to_yearindex_count.vec(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch.compute(
|
||||
starting_indexes.difficultyepoch,
|
||||
height,
|
||||
indexes.difficultyepoch_to_first_height.vec(),
|
||||
indexes.difficultyepoch_to_height_count.vec(),
|
||||
&indexes.decadeindex_to_first_yearindex,
|
||||
&indexes.decadeindex_to_yearindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.height.as_ref().map_or(vec![], |v| vec![v.any_vec()]),
|
||||
self.height_extra.any_vecs(),
|
||||
self.dateindex.any_vecs(),
|
||||
self.weekindex.any_vecs(),
|
||||
self.difficultyepoch.any_vecs(),
|
||||
self.monthindex.any_vecs(),
|
||||
self.quarterindex.any_vecs(),
|
||||
self.yearindex.any_vecs(),
|
||||
// self.halvingepoch.as_any_vecs(),
|
||||
self.decadeindex.any_vecs(),
|
||||
self.height
|
||||
.as_ref()
|
||||
.map_or(vec![], |v| vec![v.as_ref() as &dyn AnyCollectableVec]),
|
||||
self.height_extra.vecs(),
|
||||
self.dateindex.vecs(),
|
||||
self.weekindex.vecs(),
|
||||
self.difficultyepoch.vecs(),
|
||||
self.monthindex.vecs(),
|
||||
self.quarterindex.vecs(),
|
||||
self.yearindex.vecs(),
|
||||
// self.halvingepoch.vecs(),
|
||||
self.decadeindex.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
+12
-12
@@ -3,11 +3,11 @@ use std::path::Path;
|
||||
use brk_core::{DifficultyEpoch, Height};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, Version};
|
||||
use brk_vec::{AnyCollectableVec, Compressed, EagerVec, Result, Version};
|
||||
|
||||
use crate::storage::{ComputedType, EagerVec, Indexes, indexes};
|
||||
use crate::vecs::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromHeightStrict<T>
|
||||
@@ -73,25 +73,25 @@ where
|
||||
compute(&mut self.height, indexer, indexes, starting_indexes, exit)?;
|
||||
|
||||
self.height_extra
|
||||
.extend(starting_indexes.height, self.height.vec(), exit)?;
|
||||
.extend(starting_indexes.height, &self.height, exit)?;
|
||||
|
||||
self.difficultyepoch.compute(
|
||||
starting_indexes.difficultyepoch,
|
||||
self.height.vec(),
|
||||
indexes.difficultyepoch_to_first_height.vec(),
|
||||
indexes.difficultyepoch_to_height_count.vec(),
|
||||
&self.height,
|
||||
&indexes.difficultyepoch_to_first_height,
|
||||
&indexes.difficultyepoch_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
vec![self.height.any_vec()],
|
||||
self.height_extra.any_vecs(),
|
||||
self.difficultyepoch.any_vecs(),
|
||||
// self.halvingepoch.as_any_vecs(),
|
||||
vec![&self.height as &dyn AnyCollectableVec],
|
||||
self.height_extra.vecs(),
|
||||
self.difficultyepoch.vecs(),
|
||||
// self.halvingepoch.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
+62
-44
@@ -6,18 +6,20 @@ use brk_core::{
|
||||
};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, StoredVec, Version};
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, CollectableVec, Compressed, EagerVec, Result, StoredVec, Version,
|
||||
};
|
||||
|
||||
use crate::storage::{ComputedType, EagerVec, Indexes, indexes};
|
||||
use crate::vecs::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromTxindex<T>
|
||||
where
|
||||
T: ComputedType + PartialOrd,
|
||||
{
|
||||
pub txindex: Option<EagerVec<TxIndex, T>>,
|
||||
pub txindex: Option<Box<EagerVec<TxIndex, T>>>,
|
||||
pub height: ComputedVecBuilder<Height, T>,
|
||||
pub dateindex: ComputedVecBuilder<DateIndex, T>,
|
||||
pub weekindex: ComputedVecBuilder<WeekIndex, T>,
|
||||
@@ -47,12 +49,14 @@ where
|
||||
let version = VERSION + version;
|
||||
|
||||
let txindex = compute_source.then(|| {
|
||||
EagerVec::forced_import(
|
||||
&path.join(format!("txindex_to_{name}")),
|
||||
version,
|
||||
compressed,
|
||||
Box::new(
|
||||
EagerVec::forced_import(
|
||||
&path.join(format!("txindex_to_{name}")),
|
||||
version,
|
||||
compressed,
|
||||
)
|
||||
.unwrap(),
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
let height = ComputedVecBuilder::forced_import(path, name, version, compressed, options)?;
|
||||
@@ -81,6 +85,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
#[allow(unused)]
|
||||
pub fn compute_all<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
@@ -106,7 +111,8 @@ where
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.compute_rest(indexer, indexes, starting_indexes, exit, None)?;
|
||||
let txindex: Option<&StoredVec<TxIndex, T>> = None;
|
||||
self.compute_rest(indexer, indexes, starting_indexes, exit, txindex)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -117,89 +123,101 @@ where
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
txindex: Option<&StoredVec<TxIndex, T>>,
|
||||
txindex: Option<&impl CollectableVec<TxIndex, T>>,
|
||||
) -> color_eyre::Result<()> {
|
||||
let txindex = txindex.unwrap_or_else(|| self.txindex.as_ref().unwrap().vec());
|
||||
if let Some(txindex) = txindex {
|
||||
self.height.compute(
|
||||
starting_indexes.height,
|
||||
txindex,
|
||||
&indexer.vecs().height_to_first_txindex,
|
||||
&indexes.height_to_txindex_count,
|
||||
exit,
|
||||
)?;
|
||||
} else {
|
||||
let txindex = self.txindex.as_ref().unwrap().as_ref();
|
||||
|
||||
self.height.compute(
|
||||
starting_indexes.height,
|
||||
txindex,
|
||||
indexer.vecs().height_to_first_txindex.vec(),
|
||||
indexes.height_to_txindex_count.vec(),
|
||||
exit,
|
||||
)?;
|
||||
self.height.compute(
|
||||
starting_indexes.height,
|
||||
txindex,
|
||||
&indexer.vecs().height_to_first_txindex,
|
||||
&indexes.height_to_txindex_count,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.dateindex.from_aligned(
|
||||
starting_indexes.dateindex,
|
||||
&self.height,
|
||||
indexes.dateindex_to_first_height.vec(),
|
||||
indexes.dateindex_to_height_count.vec(),
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex.from_aligned(
|
||||
starting_indexes.weekindex,
|
||||
&self.dateindex,
|
||||
indexes.weekindex_to_first_dateindex.vec(),
|
||||
indexes.weekindex_to_dateindex_count.vec(),
|
||||
&indexes.weekindex_to_first_dateindex,
|
||||
&indexes.weekindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex.from_aligned(
|
||||
starting_indexes.monthindex,
|
||||
&self.dateindex,
|
||||
indexes.monthindex_to_first_dateindex.vec(),
|
||||
indexes.monthindex_to_dateindex_count.vec(),
|
||||
&indexes.monthindex_to_first_dateindex,
|
||||
&indexes.monthindex_to_dateindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex.from_aligned(
|
||||
starting_indexes.quarterindex,
|
||||
&self.monthindex,
|
||||
indexes.quarterindex_to_first_monthindex.vec(),
|
||||
indexes.quarterindex_to_monthindex_count.vec(),
|
||||
&indexes.quarterindex_to_first_monthindex,
|
||||
&indexes.quarterindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex.from_aligned(
|
||||
starting_indexes.yearindex,
|
||||
&self.monthindex,
|
||||
indexes.yearindex_to_first_monthindex.vec(),
|
||||
indexes.yearindex_to_monthindex_count.vec(),
|
||||
&indexes.yearindex_to_first_monthindex,
|
||||
&indexes.yearindex_to_monthindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex.from_aligned(
|
||||
starting_indexes.decadeindex,
|
||||
&self.yearindex,
|
||||
indexes.decadeindex_to_first_yearindex.vec(),
|
||||
indexes.decadeindex_to_yearindex_count.vec(),
|
||||
&indexes.decadeindex_to_first_yearindex,
|
||||
&indexes.decadeindex_to_yearindex_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch.from_aligned(
|
||||
starting_indexes.difficultyepoch,
|
||||
&self.height,
|
||||
indexes.difficultyepoch_to_first_height.vec(),
|
||||
indexes.difficultyepoch_to_height_count.vec(),
|
||||
&indexes.difficultyepoch_to_first_height,
|
||||
&indexes.difficultyepoch_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.txindex.as_ref().map_or(vec![], |v| vec![v.any_vec()]),
|
||||
self.height.any_vecs(),
|
||||
self.dateindex.any_vecs(),
|
||||
self.weekindex.any_vecs(),
|
||||
self.difficultyepoch.any_vecs(),
|
||||
self.monthindex.any_vecs(),
|
||||
self.quarterindex.any_vecs(),
|
||||
self.yearindex.any_vecs(),
|
||||
// self.halvingepoch.as_any_vecs(),
|
||||
self.decadeindex.any_vecs(),
|
||||
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.yearindex.vecs(),
|
||||
// self.halvingepoch.vecs(),
|
||||
self.decadeindex.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
+4
@@ -3,6 +3,8 @@ mod from_dateindex;
|
||||
mod from_height;
|
||||
mod from_height_strict;
|
||||
mod from_txindex;
|
||||
mod ratio_from_dateindex;
|
||||
mod r#type;
|
||||
mod value_from_height;
|
||||
mod value_from_txindex;
|
||||
|
||||
@@ -11,5 +13,7 @@ pub use from_dateindex::*;
|
||||
pub use from_height::*;
|
||||
pub use from_height_strict::*;
|
||||
pub use from_txindex::*;
|
||||
pub use ratio_from_dateindex::*;
|
||||
use r#type::*;
|
||||
pub use value_from_height::*;
|
||||
pub use value_from_txindex::*;
|
||||
@@ -0,0 +1,901 @@
|
||||
use std::{f32, path::Path};
|
||||
|
||||
use brk_core::{Date, DateIndex, Dollars, StoredF32};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, AnyIterableVec, AnyVec, CollectableVec, Compressed, EagerVec, Result,
|
||||
StoredIndex, VecIterator, Version,
|
||||
};
|
||||
// use rayon::prelude::*;
|
||||
|
||||
use crate::{
|
||||
utils::get_percentile,
|
||||
vecs::{Indexes, fetched, indexes},
|
||||
};
|
||||
|
||||
use super::{ComputedVecsFromDateIndex, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedRatioVecsFromDateIndex {
|
||||
pub price: ComputedVecsFromDateIndex<Dollars>,
|
||||
|
||||
pub ratio: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_1w_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_1m_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_1y_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_1y_sma_momentum_oscillator: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_standard_deviation: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p99_9: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p99_5: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p99: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p1: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p0_5: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p0_1: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p1sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p2sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p3sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_m1sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_m2sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_m3sd: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub ratio_p99_9_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p99_5_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p99_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p1_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p0_5_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p0_1_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p1sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p2sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_p3sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_m1sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_m2sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_m3sd_as_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub ratio_zscore: ComputedVecsFromDateIndex<StoredF32>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
impl ComputedRatioVecsFromDateIndex {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
name: &str,
|
||||
// _compute_source: bool,
|
||||
version: Version,
|
||||
compressed: Compressed,
|
||||
options: StorableVecGeneatorOptions,
|
||||
) -> color_eyre::Result<Self> {
|
||||
Ok(Self {
|
||||
price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
name,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_sma"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_1w_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_1w_sma"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_1m_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_1m_sma"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_1y_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_1y_sma"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_1y_sma_momentum_oscillator: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_1y_sma_momentum_oscillator"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_standard_deviation: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_standard_deviation"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99_9: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99_9"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99_5: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99_5"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p1: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p1"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p0_5: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p0_5"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p0_1: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p0_1"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p1sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p1sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p2sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p2sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p3sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p3sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m1sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m1sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m2sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m2sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m3sd: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m3sd"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99_9_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99_9_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99_5_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99_5_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p99_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p99_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p1_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p1_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p0_5_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p0_5_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p0_1_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p0_1_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p1sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p1sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p2sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p2sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_p3sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_p3sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m1sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m1sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m2sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m2sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_m3sd_as_price: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_m3sd_as_price"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
ratio_zscore: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
&format!("{name}_ratio_zscore"),
|
||||
VERSION + version + Version::ZERO,
|
||||
compressed,
|
||||
options,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute<F>(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
fetched: &fetched::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
compute: F,
|
||||
) -> color_eyre::Result<()>
|
||||
where
|
||||
F: FnMut(
|
||||
&mut EagerVec<DateIndex, Dollars>,
|
||||
&Indexer,
|
||||
&indexes::Vecs,
|
||||
&Indexes,
|
||||
&Exit,
|
||||
) -> Result<()>,
|
||||
{
|
||||
self.price
|
||||
.compute(indexer, indexes, starting_indexes, exit, compute)?;
|
||||
|
||||
let closes = &fetched.timeindexes_to_close.dateindex;
|
||||
|
||||
self.ratio.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
let mut price = self.price.dateindex.into_iter();
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
closes,
|
||||
|(i, close, ..)| {
|
||||
let price = price.unwrap_get_inner(i);
|
||||
if price == Dollars::ZERO {
|
||||
(i, StoredF32::from(1.0))
|
||||
} else {
|
||||
(i, StoredF32::from(*close / price))
|
||||
}
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
let min_ratio_date = DateIndex::try_from(Date::MIN_RATIO).unwrap();
|
||||
|
||||
self.ratio_sma.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_sma_(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
usize::MAX,
|
||||
exit,
|
||||
Some(min_ratio_date),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_1w_sma.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_sma_(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
7,
|
||||
exit,
|
||||
Some(min_ratio_date),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_1m_sma.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_sma_(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
30,
|
||||
exit,
|
||||
Some(min_ratio_date),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_1y_sma.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_sma_(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
365,
|
||||
exit,
|
||||
Some(min_ratio_date),
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_1y_sma_momentum_oscillator.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
let mut ratio_1y_sma_iter = self.ratio_1y_sma.dateindex.into_iter();
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
|(i, ratio, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF32::from(*ratio / *ratio_1y_sma_iter.unwrap_get_inner(i) - 1.0),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
let ratio_version = self.ratio.dateindex.version();
|
||||
self.mut_ratio_vecs()
|
||||
.iter_mut()
|
||||
.try_for_each(|v| -> Result<()> {
|
||||
v.validate_computed_version_or_reset_file(
|
||||
Version::ZERO + v.inner_version() + ratio_version,
|
||||
)
|
||||
})?;
|
||||
|
||||
let starting_dateindex = self
|
||||
.mut_ratio_vecs()
|
||||
.iter()
|
||||
.map(|v| DateIndex::from(v.len()))
|
||||
.min()
|
||||
.unwrap()
|
||||
.min(starting_indexes.dateindex);
|
||||
|
||||
let mut sorted = self.ratio.dateindex.collect_range(
|
||||
Some(min_ratio_date.unwrap_to_usize()),
|
||||
Some(starting_dateindex.unwrap_to_usize()),
|
||||
)?;
|
||||
|
||||
sorted.sort_unstable();
|
||||
|
||||
// if sorted.len() != starting_dateindex.unwrap_to_usize() - min_ratio_date.unwrap_to_usize() {
|
||||
// unreachable!();
|
||||
// }
|
||||
|
||||
let mut sma_iter = self.ratio_sma.dateindex.into_iter();
|
||||
|
||||
let nan = StoredF32::from(f32::NAN);
|
||||
self.ratio
|
||||
.dateindex
|
||||
.iter_at(starting_dateindex)
|
||||
.try_for_each(|(index, ratio)| -> Result<()> {
|
||||
if index < min_ratio_date {
|
||||
self.ratio_p0_1.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p0_5.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p1.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p99.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p99_5
|
||||
.dateindex
|
||||
.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p99_9
|
||||
.dateindex
|
||||
.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_standard_deviation
|
||||
.dateindex
|
||||
.forced_push_at(index, nan, exit)?;
|
||||
|
||||
self.ratio_p1sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p2sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_p3sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_m1sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_m2sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
self.ratio_m3sd.dateindex.forced_push_at(index, nan, exit)?;
|
||||
} else {
|
||||
let ratio = ratio.into_inner();
|
||||
let pos = sorted.binary_search(&ratio).unwrap_or_else(|pos| pos);
|
||||
sorted.insert(pos, ratio);
|
||||
self.ratio_p0_1.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.001),
|
||||
exit,
|
||||
)?;
|
||||
self.ratio_p0_5.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.005),
|
||||
exit,
|
||||
)?;
|
||||
self.ratio_p1.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.01),
|
||||
exit,
|
||||
)?;
|
||||
self.ratio_p99.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.99),
|
||||
exit,
|
||||
)?;
|
||||
self.ratio_p99_5.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.995),
|
||||
exit,
|
||||
)?;
|
||||
self.ratio_p99_9.dateindex.forced_push_at(
|
||||
index,
|
||||
get_percentile(&sorted, 0.999),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let avg = sma_iter.unwrap_get_inner(index);
|
||||
|
||||
let sd = StoredF32::from(
|
||||
(sorted.iter().map(|v| (**v - *avg).powi(2)).sum::<f32>()
|
||||
/ (index.unwrap_to_usize() + 1) as f32)
|
||||
.sqrt(),
|
||||
);
|
||||
|
||||
self.ratio_standard_deviation
|
||||
.dateindex
|
||||
.forced_push_at(index, sd, exit)?;
|
||||
|
||||
self.ratio_p1sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg + sd, exit)?;
|
||||
self.ratio_p2sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg + 2 * sd, exit)?;
|
||||
self.ratio_p3sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg + 3 * sd, exit)?;
|
||||
self.ratio_m1sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg - sd, exit)?;
|
||||
self.ratio_m2sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg - 2 * sd, exit)?;
|
||||
self.ratio_m3sd
|
||||
.dateindex
|
||||
.forced_push_at(index, avg - 3 * sd, exit)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.mut_ratio_vecs()
|
||||
.into_iter()
|
||||
.try_for_each(|v| v.safe_flush(exit))?;
|
||||
|
||||
self.ratio_p99_9
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p99_5
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p99
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p1
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p0_5
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p0_1
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_standard_deviation
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p1sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p2sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_p3sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_m1sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_m2sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
self.ratio_m3sd
|
||||
.compute_rest(indexes, starting_indexes, exit)?;
|
||||
|
||||
self.ratio_p99_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p99.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p99_5_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p99_5.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p99_9_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p99_9.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p1_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p1.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p0_5_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p0_5.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p0_1_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p0_1.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p1sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p1sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p2sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p2sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_p3sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_p3sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_m1sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_m1sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_m2sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_m2sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_m3sd_as_price.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut iter = self.ratio_m3sd.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.price.dateindex,
|
||||
|(i, price, ..)| {
|
||||
let multiplier = iter.unwrap_get_inner(i);
|
||||
(i, price * multiplier)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
self.ratio_zscore.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, _, starting_indexes, exit| {
|
||||
let mut sma_iter = self.ratio_sma.dateindex.into_iter();
|
||||
let mut sd_iter = self.ratio_standard_deviation.dateindex.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&self.ratio.dateindex,
|
||||
|(i, ratio, ..)| {
|
||||
let sma = sma_iter.unwrap_get_inner(i);
|
||||
let sd = sd_iter.unwrap_get_inner(i);
|
||||
(i, (ratio - sma) / sd)
|
||||
},
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn mut_ratio_vecs(&mut self) -> Vec<&mut EagerVec<DateIndex, StoredF32>> {
|
||||
vec![
|
||||
&mut self.ratio_standard_deviation.dateindex,
|
||||
&mut self.ratio_p99_9.dateindex,
|
||||
&mut self.ratio_p99_5.dateindex,
|
||||
&mut self.ratio_p99.dateindex,
|
||||
&mut self.ratio_p1.dateindex,
|
||||
&mut self.ratio_p0_5.dateindex,
|
||||
&mut self.ratio_p0_1.dateindex,
|
||||
&mut self.ratio_p1sd.dateindex,
|
||||
&mut self.ratio_p2sd.dateindex,
|
||||
&mut self.ratio_p3sd.dateindex,
|
||||
&mut self.ratio_m1sd.dateindex,
|
||||
&mut self.ratio_m2sd.dateindex,
|
||||
&mut self.ratio_m3sd.dateindex,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.price.vecs(),
|
||||
self.ratio.vecs(),
|
||||
self.ratio_sma.vecs(),
|
||||
self.ratio_1w_sma.vecs(),
|
||||
self.ratio_1m_sma.vecs(),
|
||||
self.ratio_1y_sma.vecs(),
|
||||
self.ratio_1y_sma_momentum_oscillator.vecs(),
|
||||
self.ratio_standard_deviation.vecs(),
|
||||
self.ratio_p99_9.vecs(),
|
||||
self.ratio_p99_5.vecs(),
|
||||
self.ratio_p99.vecs(),
|
||||
self.ratio_p1.vecs(),
|
||||
self.ratio_p0_5.vecs(),
|
||||
self.ratio_p0_1.vecs(),
|
||||
self.ratio_p1sd.vecs(),
|
||||
self.ratio_p2sd.vecs(),
|
||||
self.ratio_p3sd.vecs(),
|
||||
self.ratio_m1sd.vecs(),
|
||||
self.ratio_m2sd.vecs(),
|
||||
self.ratio_m3sd.vecs(),
|
||||
self.ratio_p99_9_as_price.vecs(),
|
||||
self.ratio_p99_5_as_price.vecs(),
|
||||
self.ratio_p99_as_price.vecs(),
|
||||
self.ratio_p1_as_price.vecs(),
|
||||
self.ratio_p0_5_as_price.vecs(),
|
||||
self.ratio_p0_1_as_price.vecs(),
|
||||
self.ratio_p1sd_as_price.vecs(),
|
||||
self.ratio_p2sd_as_price.vecs(),
|
||||
self.ratio_p3sd_as_price.vecs(),
|
||||
self.ratio_m1sd_as_price.vecs(),
|
||||
self.ratio_m2sd_as_price.vecs(),
|
||||
self.ratio_m3sd_as_price.vecs(),
|
||||
self.ratio_zscore.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
+43
-34
@@ -3,13 +3,12 @@ use std::path::Path;
|
||||
use brk_core::{Bitcoin, Dollars, Height, Sats};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, StoredVec, Version};
|
||||
|
||||
use crate::storage::{
|
||||
EagerVec, marketprice,
|
||||
vecs::{Indexes, indexes},
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, CollectableVec, Compressed, EagerVec, Result, StoredVec, Version,
|
||||
};
|
||||
|
||||
use crate::vecs::{Indexes, fetched, indexes};
|
||||
|
||||
use super::{ComputedVecsFromHeight, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
@@ -66,7 +65,7 @@ impl ComputedValueVecsFromHeight {
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
mut compute: F,
|
||||
@@ -88,7 +87,8 @@ impl ComputedValueVecsFromHeight {
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.compute_rest(indexer, indexes, marketprices, starting_indexes, exit, None)?;
|
||||
let height: Option<&StoredVec<Height, Sats>> = None;
|
||||
self.compute_rest(indexer, indexes, fetched, starting_indexes, exit, height)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -97,38 +97,47 @@ impl ComputedValueVecsFromHeight {
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
marketprices: Option<&marketprice::Vecs>,
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
height: Option<&StoredVec<Height, Sats>>,
|
||||
height: Option<&impl CollectableVec<Height, Sats>>,
|
||||
) -> color_eyre::Result<()> {
|
||||
if let Some(height) = height.as_ref() {
|
||||
if let Some(height) = height {
|
||||
self.sats
|
||||
.compute_rest(indexes, starting_indexes, exit, Some(height))?;
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
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, None)?;
|
||||
.compute_rest(indexes, starting_indexes, exit, height)?;
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(
|
||||
starting_indexes.height,
|
||||
self.sats.height.as_ref().unwrap().as_ref(),
|
||||
exit,
|
||||
)
|
||||
},
|
||||
)?;
|
||||
}
|
||||
|
||||
let height = height.unwrap_or_else(|| self.sats.height.as_ref().unwrap().vec());
|
||||
|
||||
self.bitcoin.compute_all(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v, _, _, starting_indexes, exit| {
|
||||
v.compute_from_sats(starting_indexes.height, height, exit)
|
||||
},
|
||||
)?;
|
||||
|
||||
let txindex = self.bitcoin.height.as_ref().unwrap().vec();
|
||||
let price = marketprices
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.chainindexes_to_close
|
||||
.height
|
||||
.vec();
|
||||
let txindex = self.bitcoin.height.as_ref().unwrap().as_ref();
|
||||
let price = &fetched.as_ref().unwrap().chainindexes_to_close.height;
|
||||
|
||||
if let Some(dollars) = self.dollars.as_mut() {
|
||||
dollars.compute_all(
|
||||
@@ -145,11 +154,11 @@ impl ComputedValueVecsFromHeight {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.sats.any_vecs(),
|
||||
self.bitcoin.any_vecs(),
|
||||
self.dollars.as_ref().map_or(vec![], |v| v.any_vecs()),
|
||||
self.sats.vecs(),
|
||||
self.bitcoin.vecs(),
|
||||
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
use std::path::Path;
|
||||
|
||||
use brk_core::{Bitcoin, Close, Dollars, Height, Sats, TxIndex};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, BoxedAnyIterableVec, CloneableAnyIterableVec, CollectableVec, Compressed,
|
||||
Computation, ComputedVecFrom3, LazyVecFrom1, StoredIndex, StoredVec, Version,
|
||||
};
|
||||
|
||||
use crate::vecs::{Indexes, fetched, indexes};
|
||||
|
||||
use super::{ComputedVecsFromTxindex, StorableVecGeneatorOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedValueVecsFromTxindex {
|
||||
pub sats: ComputedVecsFromTxindex<Sats>,
|
||||
pub bitcoin_txindex: LazyVecFrom1<TxIndex, Bitcoin, TxIndex, Sats>,
|
||||
pub bitcoin: ComputedVecsFromTxindex<Bitcoin>,
|
||||
#[allow(clippy::type_complexity)]
|
||||
pub dollars_txindex: Option<
|
||||
ComputedVecFrom3<
|
||||
TxIndex,
|
||||
Dollars,
|
||||
TxIndex,
|
||||
Bitcoin,
|
||||
TxIndex,
|
||||
Height,
|
||||
Height,
|
||||
Close<Dollars>,
|
||||
>,
|
||||
>,
|
||||
pub dollars: Option<ComputedVecsFromTxindex<Dollars>>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ONE;
|
||||
|
||||
impl ComputedValueVecsFromTxindex {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
name: &str,
|
||||
indexes: &indexes::Vecs,
|
||||
source: Option<BoxedAnyIterableVec<TxIndex, Sats>>,
|
||||
version: Version,
|
||||
computation: Computation,
|
||||
compressed: Compressed,
|
||||
fetched: Option<&fetched::Vecs>,
|
||||
options: StorableVecGeneatorOptions,
|
||||
) -> color_eyre::Result<Self> {
|
||||
let compute_source = source.is_none();
|
||||
let compute_dollars = fetched.is_some();
|
||||
|
||||
let sats = ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
name,
|
||||
compute_source,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?;
|
||||
|
||||
let bitcoin_txindex = LazyVecFrom1::init(
|
||||
"txindex_to_{name}_in_btc",
|
||||
VERSION + version,
|
||||
source.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|
||||
|txindex: TxIndex, iter| {
|
||||
iter.next_at(txindex.unwrap_to_usize()).map(|(_, value)| {
|
||||
let sats = value.into_inner();
|
||||
Bitcoin::from(sats)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let bitcoin = ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_btc"),
|
||||
false,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)?;
|
||||
|
||||
let dollars_txindex = fetched.map(|fetched| {
|
||||
ComputedVecFrom3::forced_import_or_init_from_3(
|
||||
computation,
|
||||
path,
|
||||
"txindex_to_{name}_in_usd",
|
||||
VERSION + version,
|
||||
compressed,
|
||||
bitcoin_txindex.boxed_clone(),
|
||||
indexes.txindex_to_height.boxed_clone(),
|
||||
fetched.chainindexes_to_close.height.boxed_clone(),
|
||||
|txindex: TxIndex,
|
||||
txindex_to_btc_iter,
|
||||
txindex_to_height_iter,
|
||||
height_to_close_iter| {
|
||||
let txindex = txindex.unwrap_to_usize();
|
||||
txindex_to_btc_iter.next_at(txindex).and_then(|(_, value)| {
|
||||
let btc = value.into_inner();
|
||||
txindex_to_height_iter
|
||||
.next_at(txindex)
|
||||
.and_then(|(_, value)| {
|
||||
let height = value.into_inner();
|
||||
height_to_close_iter
|
||||
.next_at(height.unwrap_to_usize())
|
||||
.map(|(_, close)| *close.into_inner() * btc)
|
||||
})
|
||||
})
|
||||
},
|
||||
)
|
||||
.unwrap()
|
||||
});
|
||||
|
||||
Ok(Self {
|
||||
sats,
|
||||
bitcoin_txindex,
|
||||
bitcoin,
|
||||
dollars_txindex,
|
||||
dollars: compute_dollars.then(|| {
|
||||
ComputedVecsFromTxindex::forced_import(
|
||||
path,
|
||||
&format!("{name}_in_usd"),
|
||||
false,
|
||||
VERSION + version,
|
||||
compressed,
|
||||
options,
|
||||
)
|
||||
.unwrap()
|
||||
}),
|
||||
})
|
||||
}
|
||||
|
||||
// pub fn compute_all<F>(
|
||||
// &mut self,
|
||||
// indexer: &Indexer,
|
||||
// indexes: &indexes::Vecs,
|
||||
// fetched: Option<&marketprice::Vecs>,
|
||||
// starting_indexes: &Indexes,
|
||||
// exit: &Exit,
|
||||
// mut compute: F,
|
||||
// ) -> color_eyre::Result<()>
|
||||
// where
|
||||
// F: FnMut(
|
||||
// &mut EagerVec<TxIndex, Sats>,
|
||||
// &Indexer,
|
||||
// &indexes::Vecs,
|
||||
// &Indexes,
|
||||
// &Exit,
|
||||
// ) -> Result<()>,
|
||||
// {
|
||||
// compute(
|
||||
// self.sats.txindex.as_mut().unwrap(),
|
||||
// indexer,
|
||||
// indexes,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// )?;
|
||||
|
||||
// let txindex: Option<&StoredVec<TxIndex, Sats>> = None;
|
||||
// self.compute_rest(
|
||||
// indexer,
|
||||
// indexes,
|
||||
// fetched,
|
||||
// starting_indexes,
|
||||
// exit,
|
||||
// txindex,
|
||||
// )?;
|
||||
|
||||
// Ok(())
|
||||
// }
|
||||
|
||||
pub fn compute_rest(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
txindex: Option<&impl CollectableVec<TxIndex, Sats>>,
|
||||
) -> color_eyre::Result<()> {
|
||||
if let Some(txindex) = txindex {
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, Some(txindex))?;
|
||||
} else {
|
||||
let txindex: Option<&StoredVec<TxIndex, Sats>> = None;
|
||||
self.sats
|
||||
.compute_rest(indexer, indexes, starting_indexes, exit, txindex)?;
|
||||
}
|
||||
|
||||
self.bitcoin.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.bitcoin_txindex),
|
||||
)?;
|
||||
|
||||
if let Some(dollars) = self.dollars.as_mut() {
|
||||
let dollars_txindex = self.dollars_txindex.as_mut().unwrap();
|
||||
|
||||
dollars_txindex.compute_if_necessary(starting_indexes.txindex, exit)?;
|
||||
|
||||
dollars.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(dollars_txindex),
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.sats.vecs(),
|
||||
self.bitcoin.vecs(),
|
||||
self.dollars.as_ref().map_or(vec![], |v| v.vecs()),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
+22
-18
@@ -3,23 +3,27 @@ use std::{fs, path::Path};
|
||||
use brk_core::{DifficultyEpoch, HalvingEpoch, StoredF64};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{Compressed, Version};
|
||||
use brk_vec::{AnyCollectableVec, Compressed, Computation, VecIterator, Version};
|
||||
|
||||
use super::{
|
||||
Indexes,
|
||||
grouped::{ComputedVecsFromDateindex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub indexes_to_difficulty: ComputedVecsFromHeight<StoredF64>,
|
||||
pub indexes_to_difficultyepoch: ComputedVecsFromDateindex<DifficultyEpoch>,
|
||||
pub indexes_to_halvingepoch: ComputedVecsFromDateindex<HalvingEpoch>,
|
||||
pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex<DifficultyEpoch>,
|
||||
pub indexes_to_halvingepoch: ComputedVecsFromDateIndex<HalvingEpoch>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(path: &Path, compressed: Compressed) -> color_eyre::Result<Self> {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
_computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self {
|
||||
@@ -31,14 +35,14 @@ impl Vecs {
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
indexes_to_difficultyepoch: ComputedVecsFromDateindex::forced_import(
|
||||
indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"difficultyepoch",
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
indexes_to_halvingepoch: ComputedVecsFromDateindex::forced_import(
|
||||
indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import(
|
||||
path,
|
||||
"halvingepoch",
|
||||
Version::ZERO,
|
||||
@@ -55,17 +59,17 @@ impl Vecs {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let mut height_to_difficultyepoch_iter = indexes.height_to_difficultyepoch.iter();
|
||||
let mut height_to_difficultyepoch_iter = indexes.height_to_difficultyepoch.into_iter();
|
||||
self.indexes_to_difficultyepoch.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, indexes, starting_indexes, exit| {
|
||||
let mut height_count_iter = indexes.dateindex_to_height_count.iter();
|
||||
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
indexes.dateindex_to_first_height.vec(),
|
||||
&indexes.dateindex_to_first_height,
|
||||
|(di, height, ..)| {
|
||||
(
|
||||
di,
|
||||
@@ -79,17 +83,17 @@ impl Vecs {
|
||||
},
|
||||
)?;
|
||||
|
||||
let mut height_to_halvingepoch_iter = indexes.height_to_halvingepoch.iter();
|
||||
let mut height_to_halvingepoch_iter = indexes.height_to_halvingepoch.into_iter();
|
||||
self.indexes_to_halvingepoch.compute(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec, _, indexes, starting_indexes, exit| {
|
||||
let mut height_count_iter = indexes.dateindex_to_height_count.iter();
|
||||
let mut height_count_iter = indexes.dateindex_to_height_count.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
indexes.dateindex_to_first_height.vec(),
|
||||
&indexes.dateindex_to_first_height,
|
||||
|(di, height, ..)| {
|
||||
(
|
||||
di,
|
||||
@@ -107,17 +111,17 @@ impl Vecs {
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(indexer.vecs().height_to_difficulty.vec()),
|
||||
Some(&indexer.vecs().height_to_difficulty),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn brk_vec::AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.indexes_to_difficulty.any_vecs(),
|
||||
self.indexes_to_difficultyepoch.any_vecs(),
|
||||
self.indexes_to_halvingepoch.any_vecs(),
|
||||
self.indexes_to_difficulty.vecs(),
|
||||
self.indexes_to_difficultyepoch.vecs(),
|
||||
self.indexes_to_halvingepoch.vecs(),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
@@ -0,0 +1,128 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_exit::Exit;
|
||||
use brk_fetcher::Fetcher;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{AnyCollectableVec, Compressed, Computation};
|
||||
|
||||
pub mod blocks;
|
||||
pub mod constants;
|
||||
pub mod fetched;
|
||||
pub mod grouped;
|
||||
pub mod indexes;
|
||||
pub mod market;
|
||||
pub mod mining;
|
||||
pub mod transactions;
|
||||
pub mod utxos;
|
||||
|
||||
pub use indexes::Indexes;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub indexes: indexes::Vecs,
|
||||
pub constants: constants::Vecs,
|
||||
pub blocks: blocks::Vecs,
|
||||
pub mining: mining::Vecs,
|
||||
pub market: market::Vecs,
|
||||
pub transactions: transactions::Vecs,
|
||||
// pub utxos: utxos::Vecs,
|
||||
pub fetched: Option<fetched::Vecs>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn import(
|
||||
path: &Path,
|
||||
indexer: &Indexer,
|
||||
fetch: bool,
|
||||
computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
let indexes = indexes::Vecs::forced_import(path, indexer, computation, compressed)?;
|
||||
|
||||
let fetched =
|
||||
fetch.then(|| fetched::Vecs::forced_import(path, computation, compressed).unwrap());
|
||||
|
||||
Ok(Self {
|
||||
blocks: blocks::Vecs::forced_import(path, computation, compressed)?,
|
||||
mining: mining::Vecs::forced_import(path, computation, compressed)?,
|
||||
constants: constants::Vecs::forced_import(path, computation, compressed)?,
|
||||
market: market::Vecs::forced_import(path, computation, compressed)?,
|
||||
// utxos: utxos::Vecs::forced_import(path, computation, compressed)?,
|
||||
transactions: transactions::Vecs::forced_import(
|
||||
path,
|
||||
indexer,
|
||||
&indexes,
|
||||
computation,
|
||||
compressed,
|
||||
fetched.as_ref(),
|
||||
)?,
|
||||
indexes,
|
||||
fetched,
|
||||
})
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
fetcher: Option<&mut Fetcher>,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let starting_indexes = self.indexes.compute(indexer, starting_indexes, exit)?;
|
||||
|
||||
self.constants
|
||||
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
self.blocks
|
||||
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
self.mining
|
||||
.compute(indexer, &self.indexes, &starting_indexes, exit)?;
|
||||
|
||||
if let Some(fetched) = self.fetched.as_mut() {
|
||||
fetched.compute(
|
||||
indexer,
|
||||
&self.indexes,
|
||||
&starting_indexes,
|
||||
fetcher.unwrap(),
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.transactions.compute(
|
||||
indexer,
|
||||
&self.indexes,
|
||||
&starting_indexes,
|
||||
self.fetched.as_ref(),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
if let Some(fetched) = self.fetched.as_ref() {
|
||||
self.market.compute(
|
||||
indexer,
|
||||
&self.indexes,
|
||||
fetched,
|
||||
&mut self.transactions,
|
||||
&starting_indexes,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
[
|
||||
self.constants.vecs(),
|
||||
self.indexes.vecs(),
|
||||
self.blocks.vecs(),
|
||||
self.mining.vecs(),
|
||||
self.market.vecs(),
|
||||
self.transactions.vecs(),
|
||||
self.fetched.as_ref().map_or(vec![], |v| v.vecs()),
|
||||
]
|
||||
.concat()
|
||||
}
|
||||
}
|
||||
+501
-276
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,181 @@
|
||||
use std::{fs, path::Path};
|
||||
|
||||
use brk_core::{CheckedSub, Dollars, Height, Sats, StoredUsize};
|
||||
use brk_exit::Exit;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::{
|
||||
AnyCollectableVec, AnyVec, BaseVecIterator, Compressed, Computation, EagerVec, StoredIndex,
|
||||
VecIterator, Version,
|
||||
};
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
|
||||
use crate::states::{CohortStates, Outputs};
|
||||
|
||||
use super::{
|
||||
Indexes,
|
||||
grouped::{ComputedVecsFromHeight, StorableVecGeneatorOptions},
|
||||
indexes, transactions,
|
||||
};
|
||||
|
||||
#[derive(Clone, Deref, DerefMut)]
|
||||
pub struct Vecs(Outputs<Vecs_>);
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs_ {
|
||||
pub height_to_realized_cap: EagerVec<Height, Dollars>,
|
||||
pub indexes_to_realized_cap: ComputedVecsFromHeight<Dollars>,
|
||||
pub height_to_supply: EagerVec<Height, Sats>,
|
||||
pub indexes_to_supply: ComputedVecsFromHeight<Sats>,
|
||||
pub height_to_utxo_count: EagerVec<Height, StoredUsize>,
|
||||
pub indexes_to_utxo_count: ComputedVecsFromHeight<StoredUsize>,
|
||||
}
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
path: &Path,
|
||||
_computation: Computation,
|
||||
compressed: Compressed,
|
||||
) -> color_eyre::Result<Self> {
|
||||
fs::create_dir_all(path)?;
|
||||
|
||||
Ok(Self(Outputs {
|
||||
all: Vecs_ {
|
||||
height_to_realized_cap: EagerVec::forced_import(
|
||||
&path.join("height_to_realized_cap"),
|
||||
VERSION + Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
indexes_to_realized_cap: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"realized_cap",
|
||||
false,
|
||||
VERSION + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
height_to_supply: EagerVec::forced_import(
|
||||
&path.join("height_to_supply"),
|
||||
VERSION + Version::ZERO,
|
||||
compressed,
|
||||
)?,
|
||||
indexes_to_supply: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"supply",
|
||||
false,
|
||||
VERSION + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
height_to_utxo_count: EagerVec::forced_import(
|
||||
&path.join("height_to_utxo_count"),
|
||||
VERSION + Version::new(111),
|
||||
compressed,
|
||||
)?,
|
||||
indexes_to_utxo_count: ComputedVecsFromHeight::forced_import(
|
||||
path,
|
||||
"utxo_count",
|
||||
false,
|
||||
VERSION + Version::ZERO,
|
||||
compressed,
|
||||
StorableVecGeneatorOptions::default().add_last(),
|
||||
)?,
|
||||
},
|
||||
}))
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
transactions: &transactions::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> color_eyre::Result<()> {
|
||||
let indexer_vecs = indexer.vecs();
|
||||
|
||||
let height_to_first_outputindex = &indexer_vecs.height_to_first_outputindex;
|
||||
let height_to_first_inputindex = &indexer_vecs.height_to_first_inputindex;
|
||||
let height_to_output_count = transactions.indexes_to_output_count.height.unwrap_last();
|
||||
let height_to_input_count = transactions.indexes_to_input_count.height.unwrap_last();
|
||||
let inputindex_to_outputindex = &indexer_vecs.inputindex_to_outputindex;
|
||||
let outputindex_to_value = &indexer_vecs.outputindex_to_value;
|
||||
let txindex_to_height = &indexes.txindex_to_height;
|
||||
let outputindex_to_txindex = &indexes.outputindex_to_txindex;
|
||||
|
||||
let mut height_to_first_outputindex_iter = height_to_first_outputindex.into_iter();
|
||||
let mut height_to_first_inputindex_iter = height_to_first_inputindex.into_iter();
|
||||
let mut height_to_output_count_iter = height_to_output_count.into_iter();
|
||||
let mut height_to_input_count_iter = height_to_input_count.into_iter();
|
||||
let mut inputindex_to_outputindex_iter = inputindex_to_outputindex.into_iter();
|
||||
let mut outputindex_to_value_iter = outputindex_to_value.into_iter();
|
||||
let mut txindex_to_height_iter = txindex_to_height.into_iter();
|
||||
let mut outputindex_to_txindex_iter = outputindex_to_txindex.into_iter();
|
||||
|
||||
let base_version = Version::ZERO
|
||||
+ height_to_first_outputindex.version()
|
||||
+ height_to_first_inputindex.version()
|
||||
+ height_to_output_count.version()
|
||||
+ height_to_input_count.version()
|
||||
+ inputindex_to_outputindex.version()
|
||||
+ outputindex_to_value.version()
|
||||
+ txindex_to_height.version()
|
||||
+ outputindex_to_txindex.version();
|
||||
|
||||
let height_to_realized_cap = &mut self.0.all.height_to_realized_cap;
|
||||
let height_to_supply = &mut self.0.all.height_to_supply;
|
||||
let height_to_utxo_count = &mut self.0.all.height_to_utxo_count;
|
||||
|
||||
height_to_realized_cap.validate_computed_version_or_reset_file(
|
||||
base_version + height_to_realized_cap.inner_version(),
|
||||
)?;
|
||||
height_to_supply.validate_computed_version_or_reset_file(
|
||||
base_version + height_to_supply.inner_version(),
|
||||
)?;
|
||||
height_to_utxo_count.validate_computed_version_or_reset_file(
|
||||
base_version + height_to_utxo_count.inner_version(),
|
||||
)?;
|
||||
|
||||
let starting_height = [
|
||||
height_to_realized_cap.len(),
|
||||
height_to_supply.len(),
|
||||
height_to_utxo_count.len(),
|
||||
]
|
||||
.into_iter()
|
||||
.map(Height::from)
|
||||
.min()
|
||||
.unwrap()
|
||||
.min(starting_indexes.height);
|
||||
|
||||
let mut states = CohortStates::default();
|
||||
|
||||
if let Some(prev_height) = starting_height.checked_sub(Height::new(1)) {
|
||||
states.realized_cap = height_to_realized_cap
|
||||
.into_iter()
|
||||
.unwrap_get_inner(prev_height);
|
||||
states.supply = height_to_supply.into_iter().unwrap_get_inner(prev_height);
|
||||
states.utxo_count = height_to_utxo_count
|
||||
.into_iter()
|
||||
.unwrap_get_inner(prev_height);
|
||||
}
|
||||
|
||||
(starting_height.unwrap_to_usize()..height_to_first_outputindex_iter.len())
|
||||
.map(Height::from)
|
||||
.try_for_each(|height| -> color_eyre::Result<()> {
|
||||
let first_outputindex = height_to_first_outputindex_iter.unwrap_get_inner(height);
|
||||
let first_inputindex = height_to_first_inputindex_iter.unwrap_get_inner(height);
|
||||
let output_count = height_to_output_count_iter.unwrap_get_inner(height);
|
||||
let input_count = height_to_input_count_iter.unwrap_get_inner(height);
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
// [].concat()
|
||||
vec![]
|
||||
}
|
||||
}
|
||||
@@ -16,8 +16,10 @@ log = { workspace = true }
|
||||
rapidhash = "1.4.0"
|
||||
rlimit = "0.10.2"
|
||||
serde = { workspace = true }
|
||||
serde_derive = { workspace = true }
|
||||
serde_bytes = "0.11.17"
|
||||
zerocopy = { workspace = true }
|
||||
zerocopy-derive = { workspace = true }
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["serde_bytes"]
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::Add;
|
||||
|
||||
use byteview::ByteView;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use byteview::ByteView;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::Serialize;
|
||||
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
use zerocopy_derive::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
|
||||
use super::OutputType;
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ use bitcoin::{
|
||||
};
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
|
||||
@@ -2,7 +2,8 @@ use std::hash::Hasher;
|
||||
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::Error;
|
||||
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
use std::ops::{Add, Div, Mul};
|
||||
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Sats;
|
||||
use super::{Sats, StoredF64};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
@@ -53,6 +53,12 @@ impl From<f64> for Bitcoin {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StoredF64> for Bitcoin {
|
||||
fn from(value: StoredF64) -> Self {
|
||||
Self(*value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Bitcoin> for f64 {
|
||||
fn from(value: Bitcoin) -> Self {
|
||||
value.0
|
||||
|
||||
@@ -4,7 +4,7 @@ use bitcoin::hashes::Hash;
|
||||
use bitcoincore_rpc::{Client, RpcApi};
|
||||
use derive_deref::Deref;
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Height;
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Error, copy_first_8bytes};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::ops::{Add, Div};
|
||||
use std::ops::{Add, Div, Mul};
|
||||
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Dollars;
|
||||
|
||||
@@ -59,3 +59,32 @@ impl Div<usize> for Cents {
|
||||
Self(self.0 / rhs as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for Cents {
|
||||
fn from(value: u128) -> Self {
|
||||
if value > u64::MAX as u128 {
|
||||
panic!("u128 bigger than u64")
|
||||
}
|
||||
Self(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Cents> for u128 {
|
||||
fn from(value: Cents) -> Self {
|
||||
value.0 as u128
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<Cents> for Cents {
|
||||
type Output = Cents;
|
||||
fn mul(self, rhs: Cents) -> Self::Output {
|
||||
Self(self.0 * rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for Cents {
|
||||
type Output = Cents;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self(self.0 * rhs as u64)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use jiff::{Span, civil::Date as Date_, tz::TimeZone};
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{DateIndex, Timestamp};
|
||||
|
||||
@@ -14,6 +14,7 @@ impl Date {
|
||||
pub const INDEX_ZERO_: Date_ = Date_::constant(2009, 1, 3);
|
||||
pub const INDEX_ONE: Self = Self(20090109);
|
||||
pub const INDEX_ONE_: Date_ = Date_::constant(2009, 1, 9);
|
||||
pub const MIN_RATIO: Self = Self(20120101);
|
||||
|
||||
pub fn new(year: u16, month: u8, day: u8) -> Self {
|
||||
Self(year as u32 * 1_00_00 + month as u32 * 1_00 + day as u32)
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::Add;
|
||||
|
||||
use serde::Serialize;
|
||||
// use color_eyre::eyre::eyre;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{CheckedSub, Error};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{fmt::Debug, ops::Add};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
use std::ops::{Add, Div, Mul};
|
||||
use std::{
|
||||
f64,
|
||||
ops::{Add, Div, Mul},
|
||||
};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Bitcoin, Cents, Sats};
|
||||
use super::{Bitcoin, Cents, Close, Sats, StoredF32, StoredF64};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
@@ -22,6 +25,20 @@ use super::{Bitcoin, Cents, Sats};
|
||||
)]
|
||||
pub struct Dollars(f64);
|
||||
|
||||
impl Dollars {
|
||||
pub const ZERO: Self = Self(0.0);
|
||||
|
||||
pub const fn mint(dollars: f64) -> Self {
|
||||
Self(dollars)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f32> for Dollars {
|
||||
fn from(value: f32) -> Self {
|
||||
Self(value as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for Dollars {
|
||||
fn from(value: f64) -> Self {
|
||||
Self(value)
|
||||
@@ -34,12 +51,24 @@ impl From<Cents> for Dollars {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dollars> for f32 {
|
||||
fn from(value: Dollars) -> Self {
|
||||
value.0 as f32
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dollars> for f64 {
|
||||
fn from(value: Dollars) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Close<Dollars>> for Dollars {
|
||||
fn from(value: Close<Dollars>) -> Self {
|
||||
Self(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for Dollars {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as f64)
|
||||
@@ -53,6 +82,27 @@ impl Add for Dollars {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Dollars> for Dollars {
|
||||
type Output = StoredF64;
|
||||
fn div(self, rhs: Dollars) -> Self::Output {
|
||||
StoredF64::from(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Close<Dollars>> for Dollars {
|
||||
type Output = StoredF64;
|
||||
fn div(self, rhs: Close<Dollars>) -> Self::Output {
|
||||
StoredF64::from(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Dollars> for Close<Dollars> {
|
||||
type Output = StoredF64;
|
||||
fn div(self, rhs: Dollars) -> Self::Output {
|
||||
StoredF64::from(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<usize> for Dollars {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: usize) -> Self::Output {
|
||||
@@ -60,6 +110,13 @@ impl Div<usize> for Dollars {
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Bitcoin> for Dollars {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Bitcoin) -> Self::Output {
|
||||
Self(f64::from(self) / f64::from(rhs))
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for Dollars {}
|
||||
|
||||
#[allow(clippy::derive_ord_xor_partial_ord)]
|
||||
@@ -70,10 +127,46 @@ impl Ord for Dollars {
|
||||
}
|
||||
|
||||
impl Mul<Bitcoin> for Dollars {
|
||||
type Output = Dollars;
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: Bitcoin) -> Self::Output {
|
||||
Self::from(Cents::from(
|
||||
u64::from(Sats::from(rhs)) * u64::from(Cents::from(self)) / u64::from(Sats::ONE_BTC),
|
||||
u128::from(Sats::from(rhs)) * u128::from(Cents::from(self)) / u128::from(Sats::ONE_BTC),
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<StoredF32> for Dollars {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: StoredF32) -> Self::Output {
|
||||
if rhs.is_nan() {
|
||||
Self(f64::NAN)
|
||||
} else {
|
||||
Self::from(Cents::from(Self::from(self.0 * *rhs as f64)))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for Dollars {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self::from(Cents::from(self) * rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for Dollars {
|
||||
fn from(value: u128) -> Self {
|
||||
Self::from(Cents::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Close<Dollars>> for u128 {
|
||||
fn from(value: Close<Dollars>) -> Self {
|
||||
u128::from(*value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Dollars> for u128 {
|
||||
fn from(value: Dollars) -> Self {
|
||||
u128::from(Cents::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::ops::{Add, Div};
|
||||
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Sats, StoredUsize};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use std::{
|
||||
};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -5,7 +5,8 @@ use std::{
|
||||
|
||||
use bitcoincore_rpc::{Client, RpcApi};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ mod outputtypeindex;
|
||||
mod quarterindex;
|
||||
mod rawlocktime;
|
||||
mod sats;
|
||||
mod stored_f32;
|
||||
mod stored_f64;
|
||||
mod stored_u32;
|
||||
mod stored_u64;
|
||||
@@ -67,6 +68,7 @@ pub use outputtypeindex::*;
|
||||
pub use quarterindex::*;
|
||||
pub use rawlocktime::*;
|
||||
pub use sats::*;
|
||||
pub use stored_f32::*;
|
||||
pub use stored_f64::*;
|
||||
pub use stored_u8::*;
|
||||
pub use stored_u32::*;
|
||||
@@ -83,3 +85,5 @@ pub use vout::*;
|
||||
pub use weekindex::*;
|
||||
pub use weight::*;
|
||||
pub use yearindex::*;
|
||||
|
||||
pub use rlimit;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{fmt::Debug, ops::Add};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::{Serialize, Serializer, ser::SerializeTuple};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Cents, Dollars, Sats};
|
||||
|
||||
@@ -453,6 +453,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<f32> for Close<T>
|
||||
where
|
||||
T: From<f32>,
|
||||
{
|
||||
fn from(value: f32) -> Self {
|
||||
Self(T::from(value))
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<f64> for Close<T>
|
||||
where
|
||||
T: From<f64>,
|
||||
@@ -462,6 +471,15 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Close<T>> for f32
|
||||
where
|
||||
f32: From<T>,
|
||||
{
|
||||
fn from(value: Close<T>) -> Self {
|
||||
Self::from(value.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> From<Close<T>> for f64
|
||||
where
|
||||
f64: From<T>,
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign};
|
||||
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use bitcoin::{ScriptBuf, opcodes::all::OP_PUSHBYTES_2};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
use zerocopy_derive::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::ops::Add;
|
||||
use byteview::ByteView;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{CheckedSub, Error};
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{fmt::Debug, ops::Add};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use bitcoin::absolute::LockTime;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
use zerocopy_derive::{Immutable, IntoBytes, KnownLayout, TryFromBytes};
|
||||
|
||||
#[derive(Debug, Immutable, Clone, Copy, IntoBytes, KnownLayout, TryFromBytes, Serialize)]
|
||||
pub struct RawLockTime(u32);
|
||||
|
||||
@@ -5,7 +5,7 @@ use std::{
|
||||
|
||||
use bitcoin::Amount;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
@@ -156,3 +156,18 @@ impl From<Sats> for u64 {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl From<u128> for Sats {
|
||||
fn from(value: u128) -> Self {
|
||||
if value > u64::MAX as u128 {
|
||||
panic!("u128 bigger than u64")
|
||||
}
|
||||
Self(value as u64)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Sats> for u128 {
|
||||
fn from(value: Sats) -> Self {
|
||||
value.0 as u128
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,119 @@
|
||||
use std::ops::{Add, Div, Mul, Sub};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
use super::{Dollars, StoredF64};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Deref,
|
||||
Default,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
PartialOrd,
|
||||
FromBytes,
|
||||
Immutable,
|
||||
IntoBytes,
|
||||
KnownLayout,
|
||||
Serialize,
|
||||
)]
|
||||
pub struct StoredF32(f32);
|
||||
|
||||
impl From<f32> for StoredF32 {
|
||||
fn from(value: f32) -> Self {
|
||||
Self(value)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<f64> for StoredF32 {
|
||||
fn from(value: f64) -> Self {
|
||||
Self(value as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StoredF64> for StoredF32 {
|
||||
fn from(value: StoredF64) -> Self {
|
||||
Self(*value as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<usize> for StoredF32 {
|
||||
fn from(value: usize) -> Self {
|
||||
Self(value as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckedSub<StoredF32> for StoredF32 {
|
||||
fn checked_sub(self, rhs: Self) -> Option<Self> {
|
||||
Some(Self(self.0 - rhs.0))
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<usize> for StoredF32 {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: usize) -> Self::Output {
|
||||
Self(self.0 / rhs as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Add for StoredF32 {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: Self) -> Self::Output {
|
||||
Self(self.0 + rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StoredF32> for f32 {
|
||||
fn from(value: StoredF32) -> Self {
|
||||
value.0
|
||||
}
|
||||
}
|
||||
|
||||
impl Eq for StoredF32 {}
|
||||
|
||||
#[allow(clippy::derive_ord_xor_partial_ord)]
|
||||
impl Ord for StoredF32 {
|
||||
fn cmp(&self, other: &Self) -> std::cmp::Ordering {
|
||||
self.0.partial_cmp(&other.0).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<Dollars> for StoredF32 {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: Dollars) -> Self::Output {
|
||||
Self::from(self.0 as f64 / *rhs)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<StoredF32> for StoredF32 {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: StoredF32) -> Self::Output {
|
||||
Self::from(self.0 / rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for StoredF32 {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self(self.0 * rhs as f32)
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<StoredF32> for usize {
|
||||
type Output = StoredF32;
|
||||
fn mul(self, rhs: StoredF32) -> Self::Output {
|
||||
StoredF32(self as f32 * rhs.0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Sub<StoredF32> for StoredF32 {
|
||||
type Output = Self;
|
||||
fn sub(self, rhs: StoredF32) -> Self::Output {
|
||||
Self(self.0 - rhs.0)
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,15 @@
|
||||
use std::ops::{Add, Div};
|
||||
use std::ops::{Add, Div, Mul};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
Deref,
|
||||
Default,
|
||||
Clone,
|
||||
Copy,
|
||||
PartialEq,
|
||||
@@ -39,6 +40,13 @@ impl CheckedSub<StoredF64> for StoredF64 {
|
||||
}
|
||||
}
|
||||
|
||||
impl Mul<usize> for StoredF64 {
|
||||
type Output = Self;
|
||||
fn mul(self, rhs: usize) -> Self::Output {
|
||||
Self(self.0 * rhs as f64)
|
||||
}
|
||||
}
|
||||
|
||||
impl Div<usize> for StoredF64 {
|
||||
type Output = Self;
|
||||
fn div(self, rhs: usize) -> Self::Output {
|
||||
@@ -67,3 +75,9 @@ impl Ord for StoredF64 {
|
||||
self.0.partial_cmp(&other.0).unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
impl CheckedSub<usize> for StoredF64 {
|
||||
fn checked_sub(self, rhs: usize) -> Option<Self> {
|
||||
Some(Self(self.0 - rhs as f64))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -2,11 +2,14 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
pub type StoredPhantom = StoredU8;
|
||||
|
||||
#[derive(
|
||||
Default,
|
||||
Debug,
|
||||
Deref,
|
||||
Clone,
|
||||
@@ -77,3 +80,16 @@ impl From<StoredU8> for f64 {
|
||||
value.0 as f64
|
||||
}
|
||||
}
|
||||
|
||||
impl Add<usize> for StoredU8 {
|
||||
type Output = Self;
|
||||
fn add(self, rhs: usize) -> Self::Output {
|
||||
Self(self.0.checked_add(rhs as u8).unwrap())
|
||||
}
|
||||
}
|
||||
|
||||
impl From<StoredU8> for usize {
|
||||
fn from(value: StoredU8) -> Self {
|
||||
value.0 as usize
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
@@ -16,6 +16,7 @@ use super::{
|
||||
Debug,
|
||||
Deref,
|
||||
Clone,
|
||||
Default,
|
||||
Copy,
|
||||
PartialEq,
|
||||
Eq,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::{Add, Div};
|
||||
use derive_deref::Deref;
|
||||
use jiff::{civil::date, tz::TimeZone};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::{fmt, mem};
|
||||
use bitcoin::hashes::Hash;
|
||||
use derive_deref::Deref;
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(Debug, Deref, Clone, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes)]
|
||||
pub struct Txid([u8; 32]);
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Error, copy_first_8bytes};
|
||||
|
||||
|
||||
@@ -3,7 +3,8 @@ use std::ops::{Add, AddAssign};
|
||||
use byteview::ByteView;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{CheckedSub, Error};
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::StoredU8;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{fmt::Debug, ops::Add};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div};
|
||||
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use std::{fmt::Debug, ops::Add};
|
||||
|
||||
use serde::{Deserialize, Serialize};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::CheckedSub;
|
||||
|
||||
|
||||
@@ -4,7 +4,14 @@ use rlimit::{Resource, getrlimit};
|
||||
|
||||
pub fn setrlimit() -> io::Result<()> {
|
||||
let no_file_limit = getrlimit(Resource::NOFILE)?;
|
||||
rlimit::setrlimit(Resource::NOFILE, no_file_limit.0.max(210_000), no_file_limit.1)?;
|
||||
rlimit::setrlimit(
|
||||
Resource::NOFILE,
|
||||
no_file_limit.0.max(210_000),
|
||||
no_file_limit.1,
|
||||
)?;
|
||||
|
||||
// let no_stack = getrlimit(Resource::STACK)?;
|
||||
// rlimit::setrlimit(Resource::STACK, no_stack.1, no_stack.1)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -8,5 +8,5 @@ repository.workspace = true
|
||||
|
||||
[dependencies]
|
||||
brk_logger = { workspace = true }
|
||||
ctrlc = { version = "3.4.6", features = ["termination"] }
|
||||
ctrlc = { version = "3.4.7", features = ["termination"] }
|
||||
log = { workspace = true }
|
||||
|
||||
@@ -38,7 +38,7 @@ impl Kibo {
|
||||
.unwrap()
|
||||
.get(usize::from(height.checked_sub(key).unwrap()))
|
||||
.cloned()
|
||||
.ok_or(color_eyre::eyre::Error::msg("Couldn't find height in kibo"))
|
||||
.ok_or(eyre!("Couldn't find height in kibo"))
|
||||
}
|
||||
|
||||
fn fetch_height_prices(height: Height) -> color_eyre::Result<Vec<OHLCCents>> {
|
||||
|
||||
@@ -35,8 +35,14 @@ impl Fetcher {
|
||||
pub fn get_date(&mut self, date: Date) -> color_eyre::Result<OHLCCents> {
|
||||
self.kraken
|
||||
.get_from_1d(&date)
|
||||
.or_else(|_| self.binance.get_from_1d(&date))
|
||||
.or_else(|_| self.kibo.get_from_date(&date))
|
||||
.or_else(|e| {
|
||||
eprintln!("{e}");
|
||||
self.binance.get_from_1d(&date)
|
||||
})
|
||||
.or_else(|e| {
|
||||
eprintln!("{e}");
|
||||
self.kibo.get_from_date(&date)
|
||||
})
|
||||
}
|
||||
|
||||
pub fn get_height(
|
||||
@@ -56,10 +62,12 @@ impl Fetcher {
|
||||
let ohlc = self
|
||||
.kraken
|
||||
.get_from_1mn(timestamp, previous_timestamp)
|
||||
.unwrap_or_else(|_| {
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("{e}");
|
||||
self.binance
|
||||
.get_from_1mn(timestamp, previous_timestamp)
|
||||
.unwrap_or_else(|_| {
|
||||
.unwrap_or_else(|e| {
|
||||
eprintln!("{e}");
|
||||
self.kibo.get_from_height(height).unwrap_or_else(|e| {
|
||||
let date = Date::from(timestamp);
|
||||
eprintln!("{e}");
|
||||
|
||||
@@ -24,7 +24,7 @@ fn main() -> color_eyre::Result<()> {
|
||||
|
||||
let outputs = Path::new("../../_outputs");
|
||||
|
||||
let mut indexer = Indexer::new(outputs, false, true)?;
|
||||
let mut indexer = Indexer::new(outputs, false, false)?;
|
||||
|
||||
indexer.import_stores()?;
|
||||
indexer.import_vecs()?;
|
||||
|
||||
@@ -5,10 +5,10 @@ use brk_core::{
|
||||
P2SHIndex, P2TRIndex, P2WPKHIndex, P2WSHIndex, TxIndex, UnknownOutputIndex,
|
||||
};
|
||||
use brk_parser::NUMBER_OF_UNSAFE_BLOCKS;
|
||||
use brk_vec::{Result, StoredIndex, StoredType, Value};
|
||||
use brk_vec::{AnyIterableVec, AnyVec, IndexedVec, StoredIndex, StoredType};
|
||||
use color_eyre::eyre::ContextCompat;
|
||||
|
||||
use crate::{IndexedVec, Stores, Vecs};
|
||||
use crate::{Stores, Vecs};
|
||||
|
||||
#[derive(Debug, Default, Clone)]
|
||||
pub struct Indexes {
|
||||
@@ -107,115 +107,116 @@ impl TryFrom<(&mut Vecs, &Stores, &Client)> for Indexes {
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
vecs.height_to_blockhash.get(*height).map_or(true, |opt| {
|
||||
opt.is_none_or(|saved_blockhash| {
|
||||
vecs.height_to_blockhash
|
||||
.iter()
|
||||
.get(*height)
|
||||
.is_none_or(|saved_blockhash| {
|
||||
let b = &rpc_blockhash != saved_blockhash.as_ref();
|
||||
if b {
|
||||
dbg!(rpc_blockhash, saved_blockhash.as_ref());
|
||||
}
|
||||
b
|
||||
})
|
||||
})
|
||||
})
|
||||
.unwrap_or(starting_height);
|
||||
|
||||
Ok(Self {
|
||||
emptyoutputindex: *starting_index(
|
||||
emptyoutputindex: starting_index(
|
||||
&vecs.height_to_first_emptyoutputindex,
|
||||
&vecs.emptyoutputindex_to_txindex,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
height,
|
||||
p2msindex: *starting_index(
|
||||
p2msindex: starting_index(
|
||||
&vecs.height_to_first_p2msindex,
|
||||
&vecs.p2msindex_to_txindex,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
opreturnindex: *starting_index(
|
||||
opreturnindex: starting_index(
|
||||
&vecs.height_to_first_opreturnindex,
|
||||
&vecs.opreturnindex_to_txindex,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2pk33index: *starting_index(
|
||||
p2pk33index: starting_index(
|
||||
&vecs.height_to_first_p2pk33index,
|
||||
&vecs.p2pk33index_to_p2pk33bytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2pk65index: *starting_index(
|
||||
p2pk65index: starting_index(
|
||||
&vecs.height_to_first_p2pk65index,
|
||||
&vecs.p2pk65index_to_p2pk65bytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2pkhindex: *starting_index(
|
||||
p2pkhindex: starting_index(
|
||||
&vecs.height_to_first_p2pkhindex,
|
||||
&vecs.p2pkhindex_to_p2pkhbytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2shindex: *starting_index(
|
||||
p2shindex: starting_index(
|
||||
&vecs.height_to_first_p2shindex,
|
||||
&vecs.p2shindex_to_p2shbytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2trindex: *starting_index(
|
||||
p2trindex: starting_index(
|
||||
&vecs.height_to_first_p2trindex,
|
||||
&vecs.p2trindex_to_p2trbytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2wpkhindex: *starting_index(
|
||||
p2wpkhindex: starting_index(
|
||||
&vecs.height_to_first_p2wpkhindex,
|
||||
&vecs.p2wpkhindex_to_p2wpkhbytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2wshindex: *starting_index(
|
||||
p2wshindex: starting_index(
|
||||
&vecs.height_to_first_p2wshindex,
|
||||
&vecs.p2wshindex_to_p2wshbytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
p2aindex: *starting_index(
|
||||
p2aindex: starting_index(
|
||||
&vecs.height_to_first_p2aindex,
|
||||
&vecs.p2aindex_to_p2abytes,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
txindex: *starting_index(&vecs.height_to_first_txindex, &vecs.txindex_to_txid, height)?
|
||||
txindex: starting_index(&vecs.height_to_first_txindex, &vecs.txindex_to_txid, height)
|
||||
.context("")?,
|
||||
inputindex: *starting_index(
|
||||
inputindex: starting_index(
|
||||
&vecs.height_to_first_inputindex,
|
||||
&vecs.inputindex_to_outputindex,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
outputindex: *starting_index(
|
||||
outputindex: starting_index(
|
||||
&vecs.height_to_first_outputindex,
|
||||
&vecs.outputindex_to_value,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
unknownoutputindex: *starting_index(
|
||||
unknownoutputindex: starting_index(
|
||||
&vecs.height_to_first_unknownoutputindex,
|
||||
&vecs.unknownoutputindex_to_txindex,
|
||||
height,
|
||||
)?
|
||||
)
|
||||
.context("")?,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn starting_index<'a, I, T>(
|
||||
height_to_index: &'a IndexedVec<Height, I>,
|
||||
index_to_else: &'a IndexedVec<I, T>,
|
||||
pub fn starting_index<I, T>(
|
||||
height_to_index: &IndexedVec<Height, I>,
|
||||
index_to_else: &IndexedVec<I, T>,
|
||||
starting_height: Height,
|
||||
) -> Result<Option<Value<'a, I>>>
|
||||
) -> Option<I>
|
||||
where
|
||||
I: StoredType + StoredIndex + From<usize>,
|
||||
T: StoredType,
|
||||
@@ -224,8 +225,8 @@ where
|
||||
.height()
|
||||
.is_ok_and(|h| h + 1_u32 == starting_height)
|
||||
{
|
||||
Ok(Some(Value::Owned(I::from(index_to_else.len()))))
|
||||
Some(I::from(index_to_else.len()))
|
||||
} else {
|
||||
height_to_index.get(starting_height)
|
||||
height_to_index.iter().get_inner(starting_height)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,7 @@ pub use brk_parser::*;
|
||||
|
||||
use bitcoin::{Transaction, TxIn, TxOut};
|
||||
use brk_exit::Exit;
|
||||
use brk_vec::Compressed;
|
||||
use brk_vec::{AnyVec, Compressed, VecIterator};
|
||||
use color_eyre::eyre::{ContextCompat, eyre};
|
||||
use fjall::TransactionalKeyspace;
|
||||
use log::{error, info};
|
||||
@@ -242,7 +242,11 @@ impl Indexer {
|
||||
})
|
||||
});
|
||||
|
||||
|
||||
let input_source_vec_handle = scope.spawn(|| {
|
||||
let txindex_to_first_outputindex_mmap = vecs
|
||||
.txindex_to_first_outputindex.mmap().load();
|
||||
|
||||
inputs
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
@@ -273,13 +277,11 @@ impl Indexer {
|
||||
|
||||
let vout = Vout::from(outpoint.vout);
|
||||
|
||||
let outputindex = *vecs
|
||||
.txindex_to_first_outputindex
|
||||
.get(prev_txindex)?
|
||||
let outputindex = vecs.txindex_to_first_outputindex.get_or_read(prev_txindex, &txindex_to_first_outputindex_mmap)?
|
||||
.context("Expect outputindex to not be none")
|
||||
.inspect_err(|_| {
|
||||
dbg!(outpoint.txid, prev_txindex, vout);
|
||||
})?
|
||||
})?.into_inner()
|
||||
+ vout;
|
||||
|
||||
Ok((inputindex, InputSource::PreviousBlock((
|
||||
@@ -305,6 +307,16 @@ impl Indexer {
|
||||
});
|
||||
|
||||
let outputindex_to_txout_outputtype_addressbytes_res_addressindex_opt_handle = scope.spawn(|| {
|
||||
let p2pk65index_to_p2pk65bytes_mmap = vecs
|
||||
.p2pk65index_to_p2pk65bytes.mmap().load();
|
||||
let p2pk33index_to_p2pk33bytes_mmap = vecs.p2pk33index_to_p2pk33bytes.mmap().load();
|
||||
let p2pkhindex_to_p2pkhbytes_mmap = vecs.p2pkhindex_to_p2pkhbytes.mmap().load();
|
||||
let p2shindex_to_p2shbytes_mmap = vecs.p2shindex_to_p2shbytes.mmap().load();
|
||||
let p2wpkhindex_to_p2wpkhbytes_mmap = vecs.p2wpkhindex_to_p2wpkhbytes.mmap().load();
|
||||
let p2wshindex_to_p2wshbytes_mmap = vecs.p2wshindex_to_p2wshbytes.mmap().load();
|
||||
let p2trindex_to_p2trbytes_mmap = vecs.p2trindex_to_p2trbytes.mmap().load();
|
||||
let p2aindex_to_p2abytes_mmap = vecs.p2aindex_to_p2abytes.mmap().load();
|
||||
|
||||
outputs
|
||||
.into_par_iter()
|
||||
.enumerate()
|
||||
@@ -349,8 +361,43 @@ impl Indexer {
|
||||
if let Some(Some(outputtypeindex)) = check_collisions.then_some(outputtypeindex_opt) {
|
||||
let addressbytes = address_bytes_res.as_ref().unwrap();
|
||||
|
||||
let prev_addressbytes_opt =
|
||||
vecs.get_addressbytes(outputtype, outputtypeindex)?;
|
||||
let prev_addressbytes_opt = match outputtype {
|
||||
OutputType::P2PK65 => vecs
|
||||
.p2pk65index_to_p2pk65bytes
|
||||
.get_or_read(outputtypeindex.into(), &p2pk65index_to_p2pk65bytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2PK33 => vecs
|
||||
.p2pk33index_to_p2pk33bytes
|
||||
.get_or_read(outputtypeindex.into(), &p2pk33index_to_p2pk33bytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2PKH => vecs
|
||||
.p2pkhindex_to_p2pkhbytes
|
||||
.get_or_read(outputtypeindex.into(), &p2pkhindex_to_p2pkhbytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2SH => vecs
|
||||
.p2shindex_to_p2shbytes
|
||||
.get_or_read(outputtypeindex.into(), &p2shindex_to_p2shbytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2WPKH => vecs
|
||||
.p2wpkhindex_to_p2wpkhbytes
|
||||
.get_or_read(outputtypeindex.into(), &p2wpkhindex_to_p2wpkhbytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2WSH => vecs
|
||||
.p2wshindex_to_p2wshbytes
|
||||
.get_or_read(outputtypeindex.into(), &p2wshindex_to_p2wshbytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2TR => vecs
|
||||
.p2trindex_to_p2trbytes
|
||||
.get_or_read(outputtypeindex.into(), &p2trindex_to_p2trbytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2A => vecs
|
||||
.p2aindex_to_p2abytes
|
||||
.get_or_read(outputtypeindex.into(), &p2aindex_to_p2abytes_mmap)?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::Empty | OutputType::OpReturn | OutputType::P2MS | OutputType::Unknown => {
|
||||
unreachable!()
|
||||
}
|
||||
};
|
||||
let prev_addressbytes =
|
||||
prev_addressbytes_opt.as_ref().context("Expect to have addressbytes")?;
|
||||
|
||||
@@ -600,6 +647,9 @@ impl Indexer {
|
||||
|
||||
let mut txindex_to_tx_and_txid: BTreeMap<TxIndex, (&Transaction, Txid)> = BTreeMap::default();
|
||||
|
||||
let mut txindex_to_txid_iter = vecs
|
||||
.txindex_to_txid.into_iter();
|
||||
|
||||
txid_prefix_to_txid_and_block_txindex_and_prev_txindex
|
||||
.into_iter()
|
||||
.try_for_each(
|
||||
@@ -626,9 +676,8 @@ impl Indexer {
|
||||
|
||||
let len = vecs.txindex_to_txid.len();
|
||||
// Ok if `get` is not par as should happen only twice
|
||||
let prev_txid = vecs
|
||||
.txindex_to_txid
|
||||
.get(prev_txindex)?
|
||||
let prev_txid = txindex_to_txid_iter
|
||||
.get(prev_txindex)
|
||||
.context("To have txid for txindex")
|
||||
.inspect_err(|_| {
|
||||
dbg!(txindex, len);
|
||||
@@ -695,18 +744,10 @@ impl Indexer {
|
||||
self.vecs.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn mut_vecs(&mut self) -> &mut Vecs {
|
||||
self.vecs.as_mut().unwrap()
|
||||
}
|
||||
|
||||
pub fn stores(&self) -> &Stores {
|
||||
self.stores.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn mut_stores(&mut self) -> &mut Stores {
|
||||
self.stores.as_mut().unwrap()
|
||||
}
|
||||
|
||||
pub fn keyspace(&self) -> &TransactionalKeyspace {
|
||||
&self.stores().keyspace
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@ use brk_core::{
|
||||
AddressBytes, AddressBytesHash, BlockHashPrefix, Height, OutputType, OutputTypeIndex, TxIndex,
|
||||
TxidPrefix,
|
||||
};
|
||||
use brk_vec::{Value, Version};
|
||||
use brk_vec::{AnyIterableVec, Value, Version};
|
||||
use fjall::{PersistMode, TransactionalKeyspace};
|
||||
|
||||
use crate::Indexes;
|
||||
@@ -96,12 +96,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2pk65index
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2pk65index_to_p2pk65bytes
|
||||
.get(index)?
|
||||
let mut p2pk65index_to_p2pk65bytes_iter = vecs.p2pk65index_to_p2pk65bytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2pk65index_to_p2pk65bytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -113,12 +115,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2pk33index
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2pk33index_to_p2pk33bytes
|
||||
.get(index)?
|
||||
let mut p2pk33index_to_p2pk33bytes_iter = vecs.p2pk33index_to_p2pk33bytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2pk33index_to_p2pk33bytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -130,12 +134,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2pkhindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2pkhindex_to_p2pkhbytes
|
||||
.get(index)?
|
||||
let mut p2pkhindex_to_p2pkhbytes_iter = vecs.p2pkhindex_to_p2pkhbytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2pkhindex_to_p2pkhbytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -147,12 +153,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2shindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2shindex_to_p2shbytes
|
||||
.get(index)?
|
||||
let mut p2shindex_to_p2shbytes_iter = vecs.p2shindex_to_p2shbytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2shindex_to_p2shbytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -164,12 +172,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2trindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2trindex_to_p2trbytes
|
||||
.get(index)?
|
||||
let mut p2trindex_to_p2trbytes_iter = vecs.p2trindex_to_p2trbytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2trindex_to_p2trbytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -181,12 +191,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2wpkhindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2wpkhindex_to_p2wpkhbytes
|
||||
.get(index)?
|
||||
let mut p2wpkhindex_to_p2wpkhbytes_iter = vecs.p2wpkhindex_to_p2wpkhbytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2wpkhindex_to_p2wpkhbytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -198,12 +210,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2wshindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
while let Some(typedbytes) = vecs
|
||||
.p2wshindex_to_p2wshbytes
|
||||
.get(index)?
|
||||
let mut p2wshindex_to_p2wshbytes_iter = vecs.p2wshindex_to_p2wshbytes.iter();
|
||||
|
||||
while let Some(typedbytes) = p2wshindex_to_p2wshbytes_iter
|
||||
.get(index)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
@@ -215,11 +229,14 @@ impl Stores {
|
||||
|
||||
if let Some(mut index) = vecs
|
||||
.height_to_first_p2aindex
|
||||
.get(starting_indexes.height)?
|
||||
.iter()
|
||||
.get(starting_indexes.height)
|
||||
.map(Value::into_inner)
|
||||
{
|
||||
let mut p2aindex_to_p2abytes_iter = vecs.p2aindex_to_p2abytes.iter();
|
||||
|
||||
while let Some(typedbytes) =
|
||||
vecs.p2aindex_to_p2abytes.get(index)?.map(Value::into_inner)
|
||||
p2aindex_to_p2abytes_iter.get(index).map(Value::into_inner)
|
||||
{
|
||||
let bytes = AddressBytes::from(typedbytes);
|
||||
let hash = AddressBytesHash::from((&bytes, OutputType::P2A));
|
||||
|
||||
@@ -7,15 +7,11 @@ use brk_core::{
|
||||
P2WPKHBytes, P2WPKHIndex, P2WSHBytes, P2WSHIndex, RawLockTime, Sats, StoredF64, StoredU32,
|
||||
StoredUsize, Timestamp, TxIndex, TxVersion, Txid, UnknownOutputIndex, Weight,
|
||||
};
|
||||
use brk_vec::{AnyStoredVec, Compressed, Result, Version};
|
||||
use brk_vec::{AnyCollectableVec, AnyIndexedVec, Compressed, IndexedVec, Result, Version};
|
||||
use rayon::prelude::*;
|
||||
|
||||
use crate::Indexes;
|
||||
|
||||
mod base;
|
||||
|
||||
pub use base::*;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct Vecs {
|
||||
pub emptyoutputindex_to_txindex: IndexedVec<EmptyOutputIndex, TxIndex>,
|
||||
@@ -79,7 +75,7 @@ impl Vecs {
|
||||
height_to_blockhash: IndexedVec::forced_import(
|
||||
&path.join("height_to_blockhash"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
height_to_difficulty: IndexedVec::forced_import(
|
||||
&path.join("height_to_difficulty"),
|
||||
@@ -204,7 +200,7 @@ impl Vecs {
|
||||
p2aindex_to_p2abytes: IndexedVec::forced_import(
|
||||
&path.join("p2aindex_to_p2abytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2msindex_to_txindex: IndexedVec::forced_import(
|
||||
&path.join("p2msindex_to_txindex"),
|
||||
@@ -214,37 +210,37 @@ impl Vecs {
|
||||
p2pk33index_to_p2pk33bytes: IndexedVec::forced_import(
|
||||
&path.join("p2pk33index_to_p2pk33bytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2pk65index_to_p2pk65bytes: IndexedVec::forced_import(
|
||||
&path.join("p2pk65index_to_p2pk65bytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2pkhindex_to_p2pkhbytes: IndexedVec::forced_import(
|
||||
&path.join("p2pkhindex_to_p2pkhbytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2shindex_to_p2shbytes: IndexedVec::forced_import(
|
||||
&path.join("p2shindex_to_p2shbytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2trindex_to_p2trbytes: IndexedVec::forced_import(
|
||||
&path.join("p2trindex_to_p2trbytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2wpkhindex_to_p2wpkhbytes: IndexedVec::forced_import(
|
||||
&path.join("p2wpkhindex_to_p2wpkhbytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
p2wshindex_to_p2wshbytes: IndexedVec::forced_import(
|
||||
&path.join("p2wshindex_to_p2wshbytes"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
txindex_to_base_size: IndexedVec::forced_import(
|
||||
&path.join("txindex_to_base_size"),
|
||||
@@ -259,7 +255,7 @@ impl Vecs {
|
||||
txindex_to_first_outputindex: IndexedVec::forced_import(
|
||||
&path.join("txindex_to_first_outputindex"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
txindex_to_is_explicitly_rbf: IndexedVec::forced_import(
|
||||
&path.join("txindex_to_is_explicitly_rbf"),
|
||||
@@ -279,7 +275,7 @@ impl Vecs {
|
||||
txindex_to_txid: IndexedVec::forced_import(
|
||||
&path.join("txindex_to_txid"),
|
||||
Version::ZERO,
|
||||
compressed,
|
||||
Compressed::NO,
|
||||
)?,
|
||||
txindex_to_txversion: IndexedVec::forced_import(
|
||||
&path.join("txindex_to_txversion"),
|
||||
@@ -408,50 +404,6 @@ impl Vecs {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn get_addressbytes(
|
||||
&self,
|
||||
outputtype: OutputType,
|
||||
outputtypeindex: OutputTypeIndex,
|
||||
) -> brk_vec::Result<Option<AddressBytes>> {
|
||||
Ok(match outputtype {
|
||||
OutputType::P2PK65 => self
|
||||
.p2pk65index_to_p2pk65bytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2PK33 => self
|
||||
.p2pk33index_to_p2pk33bytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2PKH => self
|
||||
.p2pkhindex_to_p2pkhbytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2SH => self
|
||||
.p2shindex_to_p2shbytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2WPKH => self
|
||||
.p2wpkhindex_to_p2wpkhbytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2WSH => self
|
||||
.p2wshindex_to_p2wshbytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2TR => self
|
||||
.p2trindex_to_p2trbytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::P2A => self
|
||||
.p2aindex_to_p2abytes
|
||||
.get(outputtypeindex.into())?
|
||||
.map(|v| AddressBytes::from(v.into_inner())),
|
||||
OutputType::Empty | OutputType::OpReturn | OutputType::P2MS | OutputType::Unknown => {
|
||||
unreachable!()
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn push_bytes_if_needed(
|
||||
&mut self,
|
||||
index: OutputTypeIndex,
|
||||
@@ -486,69 +438,69 @@ impl Vecs {
|
||||
}
|
||||
|
||||
pub fn flush(&mut self, height: Height) -> Result<()> {
|
||||
self.as_mut_any_vecs()
|
||||
self.mut_vecs()
|
||||
.into_par_iter()
|
||||
.try_for_each(|vec| vec.flush(height))
|
||||
}
|
||||
|
||||
pub fn starting_height(&mut self) -> Height {
|
||||
self.as_mut_any_vecs()
|
||||
self.mut_vecs()
|
||||
.into_iter()
|
||||
.map(|vec| vec.height().map(Height::incremented).unwrap_or_default())
|
||||
.min()
|
||||
.unwrap()
|
||||
}
|
||||
|
||||
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStoredVec> {
|
||||
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
|
||||
vec![
|
||||
self.emptyoutputindex_to_txindex.any_vec(),
|
||||
self.height_to_blockhash.any_vec(),
|
||||
self.height_to_difficulty.any_vec(),
|
||||
self.height_to_first_emptyoutputindex.any_vec(),
|
||||
self.height_to_first_inputindex.any_vec(),
|
||||
self.height_to_first_opreturnindex.any_vec(),
|
||||
self.height_to_first_outputindex.any_vec(),
|
||||
self.height_to_first_p2aindex.any_vec(),
|
||||
self.height_to_first_p2msindex.any_vec(),
|
||||
self.height_to_first_p2pk33index.any_vec(),
|
||||
self.height_to_first_p2pk65index.any_vec(),
|
||||
self.height_to_first_p2pkhindex.any_vec(),
|
||||
self.height_to_first_p2shindex.any_vec(),
|
||||
self.height_to_first_p2trindex.any_vec(),
|
||||
self.height_to_first_p2wpkhindex.any_vec(),
|
||||
self.height_to_first_p2wshindex.any_vec(),
|
||||
self.height_to_first_txindex.any_vec(),
|
||||
self.height_to_first_unknownoutputindex.any_vec(),
|
||||
self.height_to_timestamp.any_vec(),
|
||||
self.height_to_total_size.any_vec(),
|
||||
self.height_to_weight.any_vec(),
|
||||
self.inputindex_to_outputindex.any_vec(),
|
||||
self.opreturnindex_to_txindex.any_vec(),
|
||||
self.outputindex_to_outputtype.any_vec(),
|
||||
self.outputindex_to_outputtypeindex.any_vec(),
|
||||
self.outputindex_to_value.any_vec(),
|
||||
self.p2aindex_to_p2abytes.any_vec(),
|
||||
self.p2msindex_to_txindex.any_vec(),
|
||||
self.p2pk33index_to_p2pk33bytes.any_vec(),
|
||||
self.p2pk65index_to_p2pk65bytes.any_vec(),
|
||||
self.p2pkhindex_to_p2pkhbytes.any_vec(),
|
||||
self.p2shindex_to_p2shbytes.any_vec(),
|
||||
self.p2trindex_to_p2trbytes.any_vec(),
|
||||
self.p2wpkhindex_to_p2wpkhbytes.any_vec(),
|
||||
self.p2wshindex_to_p2wshbytes.any_vec(),
|
||||
self.txindex_to_base_size.any_vec(),
|
||||
self.txindex_to_first_inputindex.any_vec(),
|
||||
self.txindex_to_first_outputindex.any_vec(),
|
||||
self.txindex_to_is_explicitly_rbf.any_vec(),
|
||||
self.txindex_to_rawlocktime.any_vec(),
|
||||
self.txindex_to_total_size.any_vec(),
|
||||
self.txindex_to_txid.any_vec(),
|
||||
self.txindex_to_txversion.any_vec(),
|
||||
self.unknownoutputindex_to_txindex.any_vec(),
|
||||
&self.emptyoutputindex_to_txindex,
|
||||
&self.height_to_blockhash,
|
||||
&self.height_to_difficulty,
|
||||
&self.height_to_first_emptyoutputindex,
|
||||
&self.height_to_first_inputindex,
|
||||
&self.height_to_first_opreturnindex,
|
||||
&self.height_to_first_outputindex,
|
||||
&self.height_to_first_p2aindex,
|
||||
&self.height_to_first_p2msindex,
|
||||
&self.height_to_first_p2pk33index,
|
||||
&self.height_to_first_p2pk65index,
|
||||
&self.height_to_first_p2pkhindex,
|
||||
&self.height_to_first_p2shindex,
|
||||
&self.height_to_first_p2trindex,
|
||||
&self.height_to_first_p2wpkhindex,
|
||||
&self.height_to_first_p2wshindex,
|
||||
&self.height_to_first_txindex,
|
||||
&self.height_to_first_unknownoutputindex,
|
||||
&self.height_to_timestamp,
|
||||
&self.height_to_total_size,
|
||||
&self.height_to_weight,
|
||||
&self.inputindex_to_outputindex,
|
||||
&self.opreturnindex_to_txindex,
|
||||
&self.outputindex_to_outputtype,
|
||||
&self.outputindex_to_outputtypeindex,
|
||||
&self.outputindex_to_value,
|
||||
&self.p2aindex_to_p2abytes,
|
||||
&self.p2msindex_to_txindex,
|
||||
&self.p2pk33index_to_p2pk33bytes,
|
||||
&self.p2pk65index_to_p2pk65bytes,
|
||||
&self.p2pkhindex_to_p2pkhbytes,
|
||||
&self.p2shindex_to_p2shbytes,
|
||||
&self.p2trindex_to_p2trbytes,
|
||||
&self.p2wpkhindex_to_p2wpkhbytes,
|
||||
&self.p2wshindex_to_p2wshbytes,
|
||||
&self.txindex_to_base_size,
|
||||
&self.txindex_to_first_inputindex,
|
||||
&self.txindex_to_first_outputindex,
|
||||
&self.txindex_to_is_explicitly_rbf,
|
||||
&self.txindex_to_rawlocktime,
|
||||
&self.txindex_to_total_size,
|
||||
&self.txindex_to_txid,
|
||||
&self.txindex_to_txversion,
|
||||
&self.unknownoutputindex_to_txindex,
|
||||
]
|
||||
}
|
||||
|
||||
fn as_mut_any_vecs(&mut self) -> Vec<&mut dyn AnyIndexedVec> {
|
||||
fn mut_vecs(&mut self) -> Vec<&mut dyn AnyIndexedVec> {
|
||||
vec![
|
||||
&mut self.emptyoutputindex_to_txindex,
|
||||
&mut self.height_to_blockhash,
|
||||
|
||||
@@ -84,9 +84,8 @@ impl Parser {
|
||||
thread::spawn(move || {
|
||||
let xor_bytes = xor_bytes;
|
||||
|
||||
blk_index_to_blk_path
|
||||
.range(blk_index..)
|
||||
.try_for_each(move |(blk_index, blk_path)| {
|
||||
let _ = blk_index_to_blk_path.range(blk_index..).try_for_each(
|
||||
move |(blk_index, blk_path)| {
|
||||
let mut xor_i = XORIndex::default();
|
||||
|
||||
let blk_index = *blk_index;
|
||||
@@ -139,7 +138,8 @@ impl Parser {
|
||||
}
|
||||
|
||||
ControlFlow::Continue(())
|
||||
});
|
||||
},
|
||||
);
|
||||
});
|
||||
|
||||
thread::spawn(move || {
|
||||
@@ -177,7 +177,7 @@ impl Parser {
|
||||
|
||||
// Sending in bulk to not lock threads in standby
|
||||
drain_and_send(&mut bulk)
|
||||
});
|
||||
})?;
|
||||
|
||||
drain_and_send(&mut bulk)
|
||||
});
|
||||
@@ -187,7 +187,7 @@ impl Parser {
|
||||
|
||||
let mut future_blocks = BTreeMap::default();
|
||||
|
||||
recv_block
|
||||
let _ = recv_block
|
||||
.iter()
|
||||
.try_for_each(|(blk_metadata, block)| -> ControlFlow<(), _> {
|
||||
let hash = block.block_hash();
|
||||
|
||||
@@ -11,6 +11,7 @@ brk_computer = { workspace = true }
|
||||
brk_indexer = { workspace = true }
|
||||
brk_vec = { workspace = true }
|
||||
clap = { workspace = true }
|
||||
clap_derive = { workspace = true }
|
||||
color-eyre = { workspace = true }
|
||||
derive_deref = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
|
||||
@@ -3,6 +3,7 @@ use std::path::Path;
|
||||
use brk_computer::Computer;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_query::{Index, Query};
|
||||
use brk_vec::Computation;
|
||||
|
||||
pub fn main() -> color_eyre::Result<()> {
|
||||
color_eyre::install()?;
|
||||
@@ -15,7 +16,7 @@ pub fn main() -> color_eyre::Result<()> {
|
||||
indexer.import_vecs()?;
|
||||
|
||||
let mut computer = Computer::new(outputs_dir, None, compressed);
|
||||
computer.import_vecs()?;
|
||||
computer.import_vecs(&indexer, Computation::Lazy)?;
|
||||
|
||||
let query = Query::build(&indexer, &computer);
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use clap::ValueEnum;
|
||||
use clap_derive::ValueEnum;
|
||||
use color_eyre::eyre::eyre;
|
||||
use serde::Deserialize;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
use brk_computer::Computer;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_vec::AnyStoredVec;
|
||||
use brk_vec::AnyCollectableVec;
|
||||
use tabled::settings::Style;
|
||||
|
||||
mod format;
|
||||
@@ -34,13 +34,12 @@ impl<'a> Query<'a> {
|
||||
|
||||
indexer
|
||||
.vecs()
|
||||
.as_any_vecs()
|
||||
.vecs()
|
||||
.into_iter()
|
||||
.for_each(|vec| vec_trees.insert(vec));
|
||||
|
||||
computer
|
||||
.vecs()
|
||||
.as_any_vecs()
|
||||
.into_iter()
|
||||
.for_each(|vec| vec_trees.insert(vec));
|
||||
|
||||
@@ -51,7 +50,7 @@ impl<'a> Query<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search(&self, index: Index, ids: &[&str]) -> Vec<(String, &&dyn AnyStoredVec)> {
|
||||
pub fn search(&self, index: Index, ids: &[&str]) -> Vec<(String, &&dyn AnyCollectableVec)> {
|
||||
let tuples = ids
|
||||
.iter()
|
||||
.flat_map(|s| {
|
||||
@@ -86,7 +85,7 @@ impl<'a> Query<'a> {
|
||||
|
||||
pub fn format(
|
||||
&self,
|
||||
vecs: Vec<(String, &&dyn AnyStoredVec)>,
|
||||
vecs: Vec<(String, &&dyn AnyCollectableVec)>,
|
||||
from: Option<i64>,
|
||||
to: Option<i64>,
|
||||
format: Option<Format>,
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user