global: snapshot

This commit is contained in:
nym21
2025-03-10 11:42:15 +01:00
parent f9f7172702
commit 9428beeae5
44 changed files with 1348 additions and 581 deletions

112
Cargo.lock generated
View File

@@ -415,6 +415,7 @@ version = "0.0.8"
dependencies = [ dependencies = [
"brk_core", "brk_core",
"brk_exit", "brk_exit",
"brk_fetcher",
"brk_indexer", "brk_indexer",
"brk_logger", "brk_logger",
"brk_parser", "brk_parser",
@@ -550,6 +551,7 @@ dependencies = [
name = "brk_vec" name = "brk_vec"
version = "0.0.8" version = "0.0.8"
dependencies = [ dependencies = [
"brk_core",
"brk_exit", "brk_exit",
"memmap2", "memmap2",
"rayon", "rayon",
@@ -1478,10 +1480,11 @@ checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
[[package]] [[package]]
name = "jiff" name = "jiff"
version = "0.2.1" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3590fea8e9e22d449600c9bbd481a8163bef223e4ff938e5f55899f8cf1adb93" checksum = "5c163c633eb184a4ad2a5e7a5dacf12a58c830d717a7963563d4eceb4ced079f"
dependencies = [ dependencies = [
"jiff-static",
"jiff-tzdb-platform", "jiff-tzdb-platform",
"log", "log",
"portable-atomic", "portable-atomic",
@@ -1491,10 +1494,21 @@ dependencies = [
] ]
[[package]] [[package]]
name = "jiff-tzdb" name = "jiff-static"
version = "0.1.2" version = "0.2.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf2cec2f5d266af45a071ece48b1fb89f3b00b2421ac3a5fe10285a6caaa60d3" checksum = "dbc3e0019b0f5f43038cf46471b1312136f29e36f54436c6042c8f155fec8789"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.99",
]
[[package]]
name = "jiff-tzdb"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "962e1dfe9b2d75a84536cf5bf5eaaa4319aa7906c7160134a22883ac316d5f31"
[[package]] [[package]]
name = "jiff-tzdb-platform" name = "jiff-tzdb-platform"
@@ -1774,9 +1788,9 @@ checksum = "1036865bb9422d3300cf723f657c2851d0e9ab12567854b1f4eba3d77decf564"
[[package]] [[package]]
name = "oxc" name = "oxc"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b4a5aba9c3f445db5401f9975266b23a5c5b49a8b4ccb1efa049132e96069dc" checksum = "cae6276febbc5abc1f1e4cf49167d54ab341818656ae4f622d5992b65fcdd371"
dependencies = [ dependencies = [
"oxc_allocator", "oxc_allocator",
"oxc_ast", "oxc_ast",
@@ -1817,9 +1831,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_allocator" name = "oxc_allocator"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7844c292ad3f79021bf3066538129c662a65bb4235a3450d124edd81bc9094df" checksum = "22cc5cd078806a1b7061fa146dc4228a57d0765da6c85e99500d069b86f57e94"
dependencies = [ dependencies = [
"allocator-api2", "allocator-api2",
"bumpalo", "bumpalo",
@@ -1830,9 +1844,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_ast" name = "oxc_ast"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c4005b2e219aa87cb0cbde495bcd6543748a4d77c8583ec573c6db2984bb249f" checksum = "e4722414ac21a2e28a16b76de8390672c01a39adcb703d405b848149cfaeeaf7"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cow-utils", "cow-utils",
@@ -1847,9 +1861,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_ast_macros" name = "oxc_ast_macros"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "93405fb1ad62247fa9296ad73265671b9c4aaa39dbbe142af00a6de415e61606" checksum = "8f1505d8622b2ea6ed0274f355bd5e4ee3f09df5d9b39c8a3a673f344d87b82a"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",
@@ -1858,9 +1872,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_ast_visit" name = "oxc_ast_visit"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f333b2ae5cbf1328986ce1eca317bc7f2f2e256c3d4a0f72b0d935a30c86b641" checksum = "cf45370c6da0dd142a70468e5b25127d6a34caa71056105c85087559c8ee9afb"
dependencies = [ dependencies = [
"oxc_allocator", "oxc_allocator",
"oxc_ast", "oxc_ast",
@@ -1870,9 +1884,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_cfg" name = "oxc_cfg"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775eee138628ad50d1d8f36bc7985659aed2f7457879ad3f493e1d705338d830" checksum = "96be30717d29eb7d1780758d033e92fcc208b8cce83b3b4869d2155fa4c9b7bd"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"itertools", "itertools",
@@ -1885,9 +1899,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_codegen" name = "oxc_codegen"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24b7b756b328a516af07e3d86d82c6431ca21c4ab8abd626c13cec4bb478c564" checksum = "e5fd891e06aa19c7d22e129d366e55644ffeed99167e3495dcaec8149a0631b3"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"cow-utils", "cow-utils",
@@ -1906,9 +1920,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_data_structures" name = "oxc_data_structures"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dfc814bebc24ca429f257fba498dee171a98fa2ef1ea0f9c9eb3d69f0993baa6" checksum = "cb49a2ee880952c2079b61851ecc35d7671d9d3509e306f5e704ccacd2783984"
dependencies = [ dependencies = [
"assert-unchecked", "assert-unchecked",
"ropey", "ropey",
@@ -1916,9 +1930,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_diagnostics" name = "oxc_diagnostics"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fd1f43ffbdabf86a563b48970c2abdbc0ac860e49558c83ab23a010b1a774f8" checksum = "ea83fe2415b0580980ac83364c1ae943f8ee9c00becf5395a89e800a9526a080"
dependencies = [ dependencies = [
"cow-utils", "cow-utils",
"oxc-miette", "oxc-miette",
@@ -1926,9 +1940,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_ecmascript" name = "oxc_ecmascript"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a23d0e112ff9ea0f39dd2c9c921f0938e313e26ee9e4022f60c8d81c561e518" checksum = "6c7e7bcc382cf901e93a16f86e70f2737c507aaa833656b0d8484d64f8ae358a"
dependencies = [ dependencies = [
"cow-utils", "cow-utils",
"num-bigint", "num-bigint",
@@ -1940,9 +1954,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_estree" name = "oxc_estree"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd9818707125125e32d25fd18c5331a4418fbde084e33c69dee123df5b2531d2" checksum = "1cb66484735d21f096b07c894badc96d89a0c6d31b4bdd46b33b3e44da9b97ac"
[[package]] [[package]]
name = "oxc_index" name = "oxc_index"
@@ -1952,9 +1966,9 @@ checksum = "2fa07b0cfa997730afed43705766ef27792873fdf5215b1391949fec678d2392"
[[package]] [[package]]
name = "oxc_mangler" name = "oxc_mangler"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d859623b93adfde62e5df257767c30f0f7d8b9427f9e3f94be695cf72d294e88" checksum = "8069aaf088ccaee383e008ff29d407c2c88b4ff8694f7e34a9d6aaf202c81e71"
dependencies = [ dependencies = [
"fixedbitset", "fixedbitset",
"itertools", "itertools",
@@ -1969,9 +1983,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_minifier" name = "oxc_minifier"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ba050a42f842dcf0628d46d1e817ee819661bd5283165b1784e924153912c32" checksum = "1db16b19f75f29b9502b651c6ffae09366d43fd91decf5535d80c634f8e7e21d"
dependencies = [ dependencies = [
"cow-utils", "cow-utils",
"oxc_allocator", "oxc_allocator",
@@ -1991,9 +2005,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_parser" name = "oxc_parser"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cce20364085569f8caebeb879aec455c5c8f6e5dcb5d0ecfb88208ae5e709331" checksum = "7a7414e779b9723b0bd2880fe69b0ee517e583f88c5118a7c9053cf3317b95b1"
dependencies = [ dependencies = [
"assert-unchecked", "assert-unchecked",
"bitflags", "bitflags",
@@ -2014,9 +2028,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_regular_expression" name = "oxc_regular_expression"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89e1f1e21ed9b3e4d1c6eb10dffc1c71202e8fe111968cf6636f5484ad443b0b" checksum = "d18196c212eac24a7faf613e373e5f9317d3542578a088d01dc1a548fa1e1cb3"
dependencies = [ dependencies = [
"oxc_allocator", "oxc_allocator",
"oxc_ast_macros", "oxc_ast_macros",
@@ -2030,9 +2044,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_semantic" name = "oxc_semantic"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6997bba036cadea531b817c440d87b1b489fca6db981a3953a98b7b23201a13" checksum = "4556f1c700baaec8589872ddf2af41d9a964db52fdbec9a5d07d7477dce45cf8"
dependencies = [ dependencies = [
"assert-unchecked", "assert-unchecked",
"itertools", "itertools",
@@ -2067,9 +2081,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_span" name = "oxc_span"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e59da8e765f44892357f6b75bdb16f486d61956c5bd92a345429ad704d4853fd" checksum = "318f925e26bd118adc082d290538d07611fe2434987a5c60cf5084381ecb42e6"
dependencies = [ dependencies = [
"compact_str", "compact_str",
"oxc-miette", "oxc-miette",
@@ -2080,9 +2094,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_syntax" name = "oxc_syntax"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47b8bd67fdd8df27cfddbec577b282f1a6601509ecd750697f590d7cdc2d88b7" checksum = "8cb68ceb7c6902f3043fe8fe49bb886826b1d7741dc2904337297d53692b1b9c"
dependencies = [ dependencies = [
"assert-unchecked", "assert-unchecked",
"bitflags", "bitflags",
@@ -2101,9 +2115,9 @@ dependencies = [
[[package]] [[package]]
name = "oxc_traverse" name = "oxc_traverse"
version = "0.56.0" version = "0.56.5"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a3b19901f8ad9760deb01757c062d059c8632f7ca8b869c06f2ca4c96bfcba10" checksum = "d8a090c9cd461d468f5faf3fe3f56378a4e27d80febe34ad39f2a04920f594d4"
dependencies = [ dependencies = [
"compact_str", "compact_str",
"itoa", "itoa",
@@ -2432,9 +2446,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]] [[package]]
name = "ring" name = "ring"
version = "0.17.12" version = "0.17.13"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" checksum = "70ac5d832aa16abd7d1def883a8545280c20a60f523a370aa3a9617c2b8550ee"
dependencies = [ dependencies = [
"cc", "cc",
"cfg-if", "cfg-if",
@@ -2477,9 +2491,9 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]] [[package]]
name = "rustix" name = "rustix"
version = "1.0.0" version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17f8dcd64f141950290e45c99f7710ede1b600297c91818bb30b3667c0f45dc0" checksum = "dade4812df5c384711475be5fcd8c162555352945401aed22a35bffeab61f657"
dependencies = [ dependencies = [
"bitflags", "bitflags",
"errno", "errno",
@@ -2943,9 +2957,9 @@ dependencies = [
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.43.0" version = "1.44.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" checksum = "9975ea0f48b5aa3972bf2d888c238182458437cc2a19374b81b25cdf1023fb3a"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",

View File

@@ -1,5 +1,5 @@
[workspace] [workspace]
resolver = "2" resolver = "3"
members = ["crates/*"] members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node" package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT" package.license = "MIT"
@@ -26,7 +26,7 @@ clap = { version = "4.5.31", features = ["derive", "string"] }
color-eyre = "0.6.3" color-eyre = "0.6.3"
derive_deref = "1.1.1" derive_deref = "1.1.1"
fjall = "2.6.7" fjall = "2.6.7"
jiff = "0.2.1" jiff = "0.2.3"
log = { version = "0.4.26" } log = { version = "0.4.26" }
minreq = { version = "2.13.2", features = ["https", "serde_json"] } minreq = { version = "2.13.2", features = ["https", "serde_json"] }
rayon = "1.10.0" rayon = "1.10.0"

View File

@@ -53,13 +53,11 @@ Pricing: `0.01 BTC / month` *or* `0.1 BTC / year`
## Donate ## Donate
<img width="159" alt="image" src="https://github.com/user-attachments/assets/8bbb759f-4874-46cb-b093-b30cb30f5828"> [`bc1q09 8zsm89 m7kgyz e338vf ejhpdt 92ua9p 3peuve`](bitcoin:bc1q098zsm89m7kgyze338vfejhpdt92ua9p3peuve)
[bc1q950q4ukpxxm6wjjkv6cpq8jzpazaxrrwftctkt](bitcoin:bc1q950q4ukpxxm6wjjkv6cpq8jzpazaxrrwftctkt)
<img width="159" alt="image" src="https://github.com/user-attachments/assets/745e39c7-be26-4f2a-90f2-54786e62ba35"> <img width="159" alt="image" src="https://github.com/user-attachments/assets/745e39c7-be26-4f2a-90f2-54786e62ba35">
[lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4](lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4) [`lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4`](lightning:lnurl1dp68gurn8ghj7ampd3kx2ar0veekzar0wd5xjtnrdakj7tnhv4kxctttdehhwm30d3h82unvwqhkxmmww3jkuar8d35kgetj8yuq363hv4)
[Geyser Fund](https://geyser.fund/project/brk) [Geyser Fund](https://geyser.fund/project/brk)

View File

@@ -9,6 +9,7 @@ repository.workspace = true
[dependencies] [dependencies]
brk_core = { workspace = true } brk_core = { workspace = true }
brk_exit = { workspace = true } brk_exit = { workspace = true }
brk_fetcher = { workspace = true }
brk_indexer = { workspace = true } brk_indexer = { workspace = true }
brk_logger = { workspace = true } brk_logger = { workspace = true }
brk_parser = { workspace = true } brk_parser = { workspace = true }

View File

@@ -1,6 +1,7 @@
use std::{path::Path, thread::sleep, time::Duration}; use std::{path::Path, thread::sleep, time::Duration};
use brk_computer::Computer; use brk_computer::Computer;
use brk_core::default_bitcoin_path;
use brk_exit::Exit; use brk_exit::Exit;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use brk_parser::{ use brk_parser::{
@@ -14,7 +15,8 @@ pub fn main() -> color_eyre::Result<()> {
brk_logger::init(Some(Path::new(".log"))); brk_logger::init(Some(Path::new(".log")));
let bitcoin_dir = Path::new("../../../bitcoin"); let bitcoin_dir = default_bitcoin_path();
let rpc = Box::leak(Box::new(rpc::Client::new( let rpc = Box::leak(Box::new(rpc::Client::new(
"http://localhost:8332", "http://localhost:8332",
rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")), rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")),

View File

@@ -11,7 +11,6 @@ pub use brk_parser::rpc;
mod storage; mod storage;
use brk_core::Date;
use log::info; use log::info;
use storage::{Stores, Vecs}; use storage::{Stores, Vecs};
@@ -53,101 +52,7 @@ impl Computer {
) -> color_eyre::Result<()> { ) -> color_eyre::Result<()> {
info!("Computing..."); info!("Computing...");
let height_count = indexer.vecs().height_to_size.len(); self.mut_vecs().compute(indexer, starting_indexes, exit)?;
let txindexes_count = indexer.vecs().txindex_to_txid.len();
let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// txinindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// &mut self.vecs.txindex_to_last_txinindex,
// exit,
// )?;
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// txoutindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// &mut self.vecs.txindex_to_last_txoutindex,
// exit,
// )?;
self.mut_vecs().height_to_height.compute_transform(
starting_indexes.height,
&mut indexer.mut_vecs().height_to_timestamp,
|_, height| height,
exit,
)?;
self.mut_vecs().height_to_date.compute_transform(
starting_indexes.height,
&mut indexer.mut_vecs().height_to_timestamp,
|timestamp, _| Date::from(*timestamp),
exit,
)?;
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// height_count,
// exit,
// )?;
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// &mut self.vecs.height_to_last_txindex,
// exit,
// )?;
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
// starting_indexes.txindex,
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// exit,
// )?;
// self.vecs.txindex_to_fee.compute_transform(
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// )?;
let date_count = self.vecs().height_to_date.len();
// self.vecs.height_to_dateindex.compute(...)
// self.vecs
// .dateindex_to_first_height
// .compute_inverse_more_to_less(&mut self.vecs.height_to_dateindex, exit)?;
// ---
// Date to X
// ---
// ...
// ---
// Month to X
// ---
// ...
// ---
// Year to X
// ---
// ...
Ok(()) Ok(())
} }

View File

@@ -1,175 +0,0 @@
use std::{fs, path::Path};
use brk_core::{
Addressindex, Cents, Close, Date, Dateindex, Dollars, Feerate, Height, High, Low, Open, Sats, Timestamp, Txindex,
Txinindex, Txoutindex,
};
use brk_vec::{AnyStorableVec, StorableVec, Version};
// mod base;
// use base::*;
#[derive(Clone)]
pub struct Vecs {
pub dateindex_to_first_height: StorableVec<Dateindex, Height>,
// pub dateindex_to_last_height: StorableVec<Dateindex, Height>,
// pub height_to_block_interval: StorableVec<Height, Timestamp>,
pub dateindex_to_close_in_cents: StorableVec<Dateindex, Close<Cents>>,
pub dateindex_to_close_in_dollars: StorableVec<Dateindex, Close<Dollars>>,
pub dateindex_to_high_in_cents: StorableVec<Dateindex, High<Cents>>,
pub dateindex_to_high_in_dollars: StorableVec<Dateindex, High<Dollars>>,
pub dateindex_to_low_in_cents: StorableVec<Dateindex, Low<Cents>>,
pub dateindex_to_low_in_dollars: StorableVec<Dateindex, Low<Dollars>>,
pub dateindex_to_open_in_cents: StorableVec<Dateindex, Open<Cents>>,
pub dateindex_to_open_in_dollars: StorableVec<Dateindex, Open<Dollars>>,
pub height_to_close_in_cents: StorableVec<Height, Close<Cents>>,
pub height_to_close_in_dollars: StorableVec<Height, Close<Dollars>>,
pub height_to_height: StorableVec<Height, Height>,
pub height_to_high_in_cents: StorableVec<Height, High<Cents>>,
pub height_to_high_in_dollars: StorableVec<Height, High<Dollars>>,
pub height_to_low_in_cents: StorableVec<Height, Low<Cents>>,
pub height_to_low_in_dollars: StorableVec<Height, Low<Dollars>>,
pub height_to_open_in_cents: StorableVec<Height, Open<Cents>>,
pub height_to_open_in_dollars: StorableVec<Height, Open<Dollars>>,
pub height_to_date: StorableVec<Height, Date>,
pub height_to_dateindex: StorableVec<Height, Dateindex>,
// pub height_to_fee: StorableVec<Txindex, Amount>,
// pub height_to_inputcount: StorableVec<Height, u32>,
// pub height_to_last_addressindex: StorableVec<Height, Addressindex>,
pub height_to_last_txindex: StorableVec<Height, Txindex>,
// pub height_to_last_txoutindex: StorableVec<Height, Txoutindex>,
// pub height_to_maxfeerate: StorableVec<Height, Feerate>,
// pub height_to_medianfeerate: StorableVec<Height, Feerate>,
// pub height_to_minfeerate: StorableVec<Height, Feerate>,
// pub height_to_outputcount: StorableVec<Height, u32>,
// pub height_to_subsidy: StorableVec<Height, u32>,
// pub height_to_totalfees: StorableVec<Height, Amount>,
// pub height_to_txcount: StorableVec<Height, u32>,
pub txindex_to_fee: StorableVec<Txindex, Sats>,
pub txindex_to_height: StorableVec<Txindex, Height>,
pub txindex_to_is_coinbase: StorableVec<Txindex, bool>,
// pub txindex_to_feerate: StorableVec<Txindex, Feerate>,
pub txindex_to_inputs_count: StorableVec<Txindex, u32>,
pub txindex_to_inputs_sum: StorableVec<Txindex, Sats>,
pub txindex_to_last_txinindex: StorableVec<Txindex, Txinindex>,
pub txindex_to_last_txoutindex: StorableVec<Txindex, Txoutindex>,
pub txindex_to_outputs_count: StorableVec<Txindex, u32>,
pub txindex_to_outputs_sum: StorableVec<Txindex, Sats>,
}
impl Vecs {
pub fn import(path: &Path) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
Ok(Self {
dateindex_to_first_height: StorableVec::forced_import(
&path.join("dateindex_to_first_height"),
Version::from(1),
)?,
// height_to_block_interval: StorableVec::forced_import(&path.join("height_to_block_interval"), Version::from(1))?,
dateindex_to_close_in_cents: StorableVec::import(
&path.join("dateindex_to_close_in_cents"),
Version::from(1),
)?,
dateindex_to_close_in_dollars: StorableVec::import(
&path.join("dateindex_to_close_in_dollars"),
Version::from(1),
)?,
dateindex_to_high_in_cents: StorableVec::import(
&path.join("dateindex_to_high_in_cents"),
Version::from(1),
)?,
dateindex_to_high_in_dollars: StorableVec::import(
&path.join("dateindex_to_high_in_dollars"),
Version::from(1),
)?,
dateindex_to_low_in_cents: StorableVec::import(&path.join("dateindex_to_low_in_cents"), Version::from(1))?,
dateindex_to_low_in_dollars: StorableVec::import(
&path.join("dateindex_to_low_in_dollars"),
Version::from(1),
)?,
dateindex_to_open_in_cents: StorableVec::import(
&path.join("dateindex_to_open_in_cents"),
Version::from(1),
)?,
dateindex_to_open_in_dollars: StorableVec::import(
&path.join("dateindex_to_open_in_dollars"),
Version::from(1),
)?,
height_to_close_in_cents: StorableVec::import(&path.join("height_to_close_in_cents"), Version::from(1))?,
height_to_close_in_dollars: StorableVec::import(
&path.join("height_to_close_in_dollars"),
Version::from(1),
)?,
height_to_height: StorableVec::import(&path.join("height_to_height"), Version::from(1))?,
height_to_high_in_cents: StorableVec::import(&path.join("height_to_high_in_cents"), Version::from(1))?,
height_to_high_in_dollars: StorableVec::import(&path.join("height_to_high_in_dollars"), Version::from(1))?,
height_to_low_in_cents: StorableVec::import(&path.join("height_to_low_in_cents"), Version::from(1))?,
height_to_low_in_dollars: StorableVec::import(&path.join("height_to_low_in_dollars"), Version::from(1))?,
height_to_open_in_cents: StorableVec::import(&path.join("height_to_open_in_cents"), Version::from(1))?,
height_to_open_in_dollars: StorableVec::import(&path.join("height_to_open_in_dollars"), Version::from(1))?,
height_to_date: StorableVec::forced_import(&path.join("height_to_date"), Version::from(1))?,
height_to_dateindex: StorableVec::forced_import(&path.join("height_to_dateindex"), Version::from(1))?,
// height_to_fee: StorableVec::forced_import(&path.join("height_to_fee"), Version::from(1))?,
// height_to_inputcount: StorableVec::forced_import(&path.join("height_to_inputcount"), Version::from(1))?,
// height_to_last_addressindex: StorableVec::forced_import(
// &path.join("height_to_last_addressindex"),
// Version::from(1),
// )?,
height_to_last_txindex: StorableVec::forced_import(&path.join("height_to_last_txindex"), Version::from(1))?,
// height_to_last_txoutindex: StorableVec::forced_import(&path.join("height_to_last_txoutindex"), Version::from(1))?,
// height_to_maxfeerate: StorableVec::forced_import(&path.join("height_to_maxfeerate"), Version::from(1))?,
// height_to_medianfeerate: StorableVec::forced_import(&path.join("height_to_medianfeerate"), Version::from(1))?,
// height_to_minfeerate: StorableVec::forced_import(&path.join("height_to_minfeerate"), Version::from(1))?,
// height_to_outputcount: StorableVec::forced_import(&path.join("height_to_outputcount"), Version::from(1))?,
// height_to_subsidy: StorableVec::forced_import(&path.join("height_to_subsidy"), Version::from(1))?,
// height_to_totalfees: StorableVec::forced_import(&path.join("height_to_totalfees"), Version::from(1))?,
// height_to_txcount: StorableVec::forced_import(&path.join("height_to_txcount"), Version::from(1))?,
txindex_to_fee: StorableVec::forced_import(&path.join("txindex_to_fee"), Version::from(1))?,
txindex_to_height: StorableVec::forced_import(&path.join("txindex_to_height"), Version::from(1))?,
txindex_to_is_coinbase: StorableVec::forced_import(&path.join("txindex_to_is_coinbase"), Version::from(1))?,
// txindex_to_feerate: StorableVec::forced_import(&path.join("txindex_to_feerate"), Version::from(1))?,
txindex_to_inputs_count: StorableVec::forced_import(
&path.join("txindex_to_inputs_count"),
Version::from(1),
)?,
txindex_to_inputs_sum: StorableVec::forced_import(&path.join("txindex_to_inputs_sum"), Version::from(1))?,
txindex_to_last_txinindex: StorableVec::forced_import(
&path.join("txindex_to_last_txinindex"),
Version::from(1),
)?,
txindex_to_last_txoutindex: StorableVec::forced_import(
&path.join("txindex_to_last_txoutindex"),
Version::from(1),
)?,
txindex_to_outputs_count: StorableVec::forced_import(
&path.join("txindex_to_outputs_count"),
Version::from(1),
)?,
txindex_to_outputs_sum: StorableVec::forced_import(&path.join("txindex_to_outputs_sum"), Version::from(1))?,
})
}
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
vec![
&self.height_to_date as &dyn AnyStorableVec,
&self.height_to_height,
// &self.dateindex_to_close_in_dollars,
// &self.dateindex_to_high_in_cents,
// &self.dateindex_to_high_in_dollars,
// &self.dateindex_to_low_in_cents,
// &self.dateindex_to_low_in_dollars,
// &self.dateindex_to_open_in_cents,
// &self.dateindex_to_open_in_dollars,
// &self.height_to_close_in_cents,
// &self.height_to_close_in_dollars,
// &self.height_to_high_in_cents,
// &self.height_to_high_in_dollars,
// &self.height_to_low_in_cents,
// &self.height_to_low_in_dollars,
// &self.height_to_open_in_cents,
// &self.height_to_open_in_dollars,
]
}
}

View File

@@ -0,0 +1,246 @@
use std::{fs, ops::Deref, path::Path};
use brk_core::{Date, Dateindex, Height};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyStorableVec, StorableVec, Value, Version};
#[derive(Clone)]
pub struct Vecs {
pub dateindex_to_date: StorableVec<Dateindex, Date>,
pub dateindex_to_dateindex: StorableVec<Dateindex, Dateindex>,
pub dateindex_to_first_height: StorableVec<Dateindex, Height>,
pub dateindex_to_last_height: StorableVec<Dateindex, Height>,
pub height_to_real_date: StorableVec<Height, Date>,
pub height_to_fixed_date: StorableVec<Height, Date>,
pub height_to_height: StorableVec<Height, Height>,
pub height_to_dateindex: StorableVec<Height, Dateindex>,
}
impl Vecs {
pub fn import(path: &Path) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
Ok(Self {
dateindex_to_date: StorableVec::forced_import(
&path.join("dateindex_to_date"),
Version::from(1),
)?,
dateindex_to_dateindex: StorableVec::forced_import(
&path.join("dateindex_to_dateindex"),
Version::from(1),
)?,
dateindex_to_first_height: StorableVec::forced_import(
&path.join("dateindex_to_first_height"),
Version::from(1),
)?,
dateindex_to_last_height: StorableVec::forced_import(
&path.join("dateindex_to_last_height"),
Version::from(1),
)?,
height_to_real_date: StorableVec::forced_import(
&path.join("height_to_real_date"),
Version::from(1),
)?,
height_to_fixed_date: StorableVec::forced_import(
&path.join("height_to_fixed_date"),
Version::from(1),
)?,
height_to_dateindex: StorableVec::forced_import(
&path.join("height_to_dateindex"),
Version::from(1),
)?,
height_to_height: StorableVec::forced_import(
&path.join("height_to_height"),
Version::from(1),
)?,
})
}
pub fn compute(
&mut self,
indexer: &mut Indexer,
starting_indexes: brk_indexer::Indexes,
exit: &Exit,
) -> color_eyre::Result<Indexes> {
self.height_to_height.compute_transform(
starting_indexes.height,
&mut indexer.mut_vecs().height_to_timestamp,
|(h, ..)| (h, h),
exit,
)?;
self.height_to_real_date.compute_transform(
starting_indexes.height,
&mut indexer.mut_vecs().height_to_timestamp,
|(h, t, ..)| (h, Date::from(*t)),
exit,
)?;
self.height_to_fixed_date.compute_transform(
starting_indexes.height,
&mut self.height_to_real_date,
|(h, d, s, ..)| {
let d = h
.decremented()
.and_then(|h| s.read(h).ok())
.flatten()
.map_or(*d, |prev_d| if prev_d > d { *prev_d } else { *d });
(h, d)
},
exit,
)?;
self.height_to_dateindex.compute_transform(
starting_indexes.height,
&mut self.height_to_fixed_date,
|(h, d, ..)| (h, Dateindex::try_from(*d).unwrap()),
exit,
)?;
let starting_dateindex = self
.height_to_dateindex
.get(starting_indexes.height.decremented().unwrap_or_default())?
.map(Value::into_inner)
.unwrap_or_default();
self.dateindex_to_first_height
.compute_inverse_more_to_less(
starting_indexes.height,
&mut self.height_to_dateindex,
exit,
)?;
let date_len = self.dateindex_to_first_height.len();
self.dateindex_to_last_height
.compute_last_index_from_first(
starting_dateindex,
&mut self.dateindex_to_first_height,
date_len,
exit,
)?;
self.dateindex_to_dateindex.compute_transform(
starting_dateindex,
&mut self.dateindex_to_first_height,
|(di, ..)| (di, di),
exit,
)?;
self.dateindex_to_date.compute_transform(
starting_dateindex,
&mut self.dateindex_to_dateindex,
|(di, ..)| (di, Date::from(di)),
exit,
)?;
// let height_count = indexer.vecs().height_to_size.len();
// let txindexes_count = indexer.vecs().txindex_to_txid.len();
// let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
// let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
// let date_count = self.vecs().height_to_date.len();
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// txinindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// &mut self.vecs.txindex_to_last_txinindex,
// exit,
// )?;
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// txoutindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// &mut self.vecs.txindex_to_last_txoutindex,
// exit,
// )?;
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// height_count,
// exit,
// )?;
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// &mut self.vecs.height_to_last_txindex,
// exit,
// )?;
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
// starting_indexes.txindex,
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// exit,
// )?;
// self.vecs.txindex_to_fee.compute_transform(
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// )?;
// self.vecs.height_to_dateindex.compute(...)
// ---
// Date to X
// ---
// ...
// ---
// Month to X
// ---
// ...
// ---
// Year to X
// ---
// ...
Ok(Indexes::from((starting_indexes, starting_dateindex)))
}
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
vec![
&self.dateindex_to_date as &dyn AnyStorableVec,
&self.dateindex_to_dateindex,
&self.dateindex_to_first_height,
&self.dateindex_to_last_height,
&self.height_to_real_date,
&self.height_to_fixed_date,
&self.height_to_height,
&self.height_to_dateindex,
]
}
}
pub struct Indexes {
indexes: brk_indexer::Indexes,
pub dateindex: Dateindex,
}
impl Deref for Indexes {
type Target = brk_indexer::Indexes;
fn deref(&self) -> &Self::Target {
&self.indexes
}
}
impl From<(brk_indexer::Indexes, Dateindex)> for Indexes {
fn from((indexes, dateindex): (brk_indexer::Indexes, Dateindex)) -> Self {
Self { indexes, dateindex }
}
}

View File

@@ -0,0 +1,302 @@
use std::{fs, path::Path};
use brk_core::{Cents, Close, Dateindex, Dollars, Height, High, Low, OHLCCents, OHLCDollars, Open};
use brk_exit::Exit;
use brk_fetcher::Fetcher;
use brk_indexer::Indexer;
use brk_vec::{AnyStorableVec, StorableVec, Value, Version};
use super::indexes::{self, Indexes};
#[derive(Clone)]
pub struct Vecs {
pub dateindex_to_ohlc_in_cents: StorableVec<Dateindex, OHLCCents>,
pub dateindex_to_ohlc: StorableVec<Dateindex, OHLCDollars>,
pub dateindex_to_close_in_cents: StorableVec<Dateindex, Close<Cents>>,
pub dateindex_to_close: StorableVec<Dateindex, Close<Dollars>>,
pub dateindex_to_high_in_cents: StorableVec<Dateindex, High<Cents>>,
pub dateindex_to_high: StorableVec<Dateindex, High<Dollars>>,
pub dateindex_to_low_in_cents: StorableVec<Dateindex, Low<Cents>>,
pub dateindex_to_low: StorableVec<Dateindex, Low<Dollars>>,
pub dateindex_to_open_in_cents: StorableVec<Dateindex, Open<Cents>>,
pub dateindex_to_open: StorableVec<Dateindex, Open<Dollars>>,
pub height_to_ohlc_in_cents: StorableVec<Height, OHLCCents>,
pub height_to_ohlc: StorableVec<Height, OHLCDollars>,
pub height_to_close_in_cents: StorableVec<Height, Close<Cents>>,
pub height_to_close: StorableVec<Height, Close<Dollars>>,
pub height_to_high_in_cents: StorableVec<Height, High<Cents>>,
pub height_to_high: StorableVec<Height, High<Dollars>>,
pub height_to_low_in_cents: StorableVec<Height, Low<Cents>>,
pub height_to_low: StorableVec<Height, Low<Dollars>>,
pub height_to_open_in_cents: StorableVec<Height, Open<Cents>>,
pub height_to_open: StorableVec<Height, Open<Dollars>>,
}
impl Vecs {
pub fn import(path: &Path) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
Ok(Self {
dateindex_to_ohlc_in_cents: StorableVec::import(
&path.join("dateindex_to_ohlc_in_cents"),
Version::from(1),
)?,
dateindex_to_ohlc: StorableVec::import(
&path.join("dateindex_to_ohlc"),
Version::from(1),
)?,
dateindex_to_close_in_cents: StorableVec::import(
&path.join("dateindex_to_close_in_cents"),
Version::from(1),
)?,
dateindex_to_close: StorableVec::import(
&path.join("dateindex_to_close"),
Version::from(1),
)?,
dateindex_to_high_in_cents: StorableVec::import(
&path.join("dateindex_to_high_in_cents"),
Version::from(1),
)?,
dateindex_to_high: StorableVec::import(
&path.join("dateindex_to_high"),
Version::from(1),
)?,
dateindex_to_low_in_cents: StorableVec::import(
&path.join("dateindex_to_low_in_cents"),
Version::from(1),
)?,
dateindex_to_low: StorableVec::import(
&path.join("dateindex_to_low"),
Version::from(1),
)?,
dateindex_to_open_in_cents: StorableVec::import(
&path.join("dateindex_to_open_in_cents"),
Version::from(1),
)?,
dateindex_to_open: StorableVec::import(
&path.join("dateindex_to_open"),
Version::from(1),
)?,
height_to_ohlc_in_cents: StorableVec::import(
&path.join("height_to_ohlc_in_cents"),
Version::from(1),
)?,
height_to_ohlc: StorableVec::import(&path.join("height_to_ohlc"), Version::from(1))?,
height_to_close_in_cents: StorableVec::import(
&path.join("height_to_close_in_cents"),
Version::from(1),
)?,
height_to_close: StorableVec::import(&path.join("height_to_close"), Version::from(1))?,
height_to_high_in_cents: StorableVec::import(
&path.join("height_to_high_in_cents"),
Version::from(1),
)?,
height_to_high: StorableVec::import(&path.join("height_to_high"), Version::from(1))?,
height_to_low_in_cents: StorableVec::import(
&path.join("height_to_low_in_cents"),
Version::from(1),
)?,
height_to_low: StorableVec::import(&path.join("height_to_low"), Version::from(1))?,
height_to_open_in_cents: StorableVec::import(
&path.join("height_to_open_in_cents"),
Version::from(1),
)?,
height_to_open: StorableVec::import(&path.join("height_to_open"), Version::from(1))?,
})
}
pub fn compute(
&mut self,
indexer: &mut Indexer,
indexes: &mut indexes::Vecs,
starting_indexes: Indexes,
exit: &Exit,
) -> color_eyre::Result<()> {
let mut fetcher = Fetcher::import(None)?;
self.height_to_ohlc_in_cents.compute_transform(
starting_indexes.height,
&mut indexer.mut_vecs().height_to_timestamp,
|(h, t, _, height_to_timestamp)| {
let ohlc = fetcher
.get_height(
h,
*t,
h.decremented().map(|prev_h| {
height_to_timestamp
.get(prev_h)
.unwrap()
.map(Value::into_inner)
.unwrap()
}),
)
.unwrap();
(h, ohlc)
},
exit,
)?;
self.height_to_open_in_cents.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.open),
exit,
)?;
self.height_to_high_in_cents.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.high),
exit,
)?;
self.height_to_low_in_cents.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.low),
exit,
)?;
self.height_to_close_in_cents.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.close),
exit,
)?;
self.height_to_ohlc.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, OHLCDollars::from(ohlc)),
exit,
)?;
self.height_to_open.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.open),
exit,
)?;
self.height_to_high.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.high),
exit,
)?;
self.height_to_low.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.low),
exit,
)?;
self.height_to_close.compute_transform(
starting_indexes.height,
&mut self.height_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.close),
exit,
)?;
self.dateindex_to_ohlc_in_cents.compute_transform(
starting_indexes.dateindex,
&mut indexes.dateindex_to_date,
|(di, d, ..)| {
let ohlc = fetcher.get_date(*d).unwrap();
(di, ohlc)
},
exit,
)?;
self.dateindex_to_open_in_cents.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.open),
exit,
)?;
self.dateindex_to_high_in_cents.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.high),
exit,
)?;
self.dateindex_to_low_in_cents.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.low),
exit,
)?;
self.dateindex_to_close_in_cents.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, ohlc.close),
exit,
)?;
self.dateindex_to_ohlc.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc_in_cents,
|(di, ohlc, ..)| (di, OHLCDollars::from(ohlc)),
exit,
)?;
self.dateindex_to_open.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.open),
exit,
)?;
self.dateindex_to_high.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.high),
exit,
)?;
self.dateindex_to_low.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.low),
exit,
)?;
self.dateindex_to_close.compute_transform(
starting_indexes.dateindex,
&mut self.dateindex_to_ohlc,
|(di, ohlc, ..)| (di, ohlc.close),
exit,
)?;
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
vec![
&self.dateindex_to_close as &dyn AnyStorableVec,
&self.dateindex_to_close_in_cents,
&self.dateindex_to_high,
&self.dateindex_to_high_in_cents,
&self.dateindex_to_low,
&self.dateindex_to_low_in_cents,
&self.dateindex_to_ohlc,
&self.dateindex_to_ohlc_in_cents,
&self.dateindex_to_open,
&self.dateindex_to_open_in_cents,
&self.height_to_close,
&self.height_to_close_in_cents,
&self.height_to_high,
&self.height_to_high_in_cents,
&self.height_to_low,
&self.height_to_low_in_cents,
&self.height_to_ohlc,
&self.height_to_ohlc_in_cents,
&self.height_to_open,
&self.height_to_open_in_cents,
]
}
}

View File

@@ -0,0 +1,202 @@
use std::{fs, path::Path};
use brk_core::{Height, Sats, Txindex, Txinindex, Txoutindex};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyStorableVec, StorableVec, Version};
mod indexes;
mod marketprice;
#[derive(Clone)]
pub struct Vecs {
pub indexes: indexes::Vecs,
pub marketprice: marketprice::Vecs,
// pub height_to_block_interval: StorableVec<Height, Timestamp>,
// pub height_to_fee: StorableVec<Txindex, Amount>,
// pub height_to_inputcount: StorableVec<Height, u32>,
// pub height_to_last_addressindex: StorableVec<Height, Addressindex>,
pub height_to_last_txindex: StorableVec<Height, Txindex>,
// pub height_to_last_txoutindex: StorableVec<Height, Txoutindex>,
// pub height_to_maxfeerate: StorableVec<Height, Feerate>,
// pub height_to_medianfeerate: StorableVec<Height, Feerate>,
// pub height_to_minfeerate: StorableVec<Height, Feerate>,
// pub height_to_outputcount: StorableVec<Height, u32>,
// pub height_to_subsidy: StorableVec<Height, u32>,
// pub height_to_totalfees: StorableVec<Height, Amount>,
// pub height_to_txcount: StorableVec<Height, u32>,
pub txindex_to_fee: StorableVec<Txindex, Sats>,
pub txindex_to_height: StorableVec<Txindex, Height>,
pub txindex_to_is_coinbase: StorableVec<Txindex, bool>,
// pub txindex_to_feerate: StorableVec<Txindex, Feerate>,
pub txindex_to_inputs_count: StorableVec<Txindex, u32>,
pub txindex_to_inputs_sum: StorableVec<Txindex, Sats>,
pub txindex_to_last_txinindex: StorableVec<Txindex, Txinindex>,
pub txindex_to_last_txoutindex: StorableVec<Txindex, Txoutindex>,
pub txindex_to_outputs_count: StorableVec<Txindex, u32>,
pub txindex_to_outputs_sum: StorableVec<Txindex, Sats>,
}
impl Vecs {
pub fn import(path: &Path) -> color_eyre::Result<Self> {
fs::create_dir_all(path)?;
Ok(Self {
// height_to_block_interval: StorableVec::forced_import(&path.join("height_to_block_interval"), Version::from(1))?,
indexes: indexes::Vecs::import(path)?,
marketprice: marketprice::Vecs::import(path)?,
// height_to_fee: StorableVec::forced_import(&path.join("height_to_fee"), Version::from(1))?,
// height_to_inputcount: StorableVec::forced_import(&path.join("height_to_inputcount"), Version::from(1))?,
// height_to_last_addressindex: StorableVec::forced_import(
// &path.join("height_to_last_addressindex"),
// Version::from(1),
// )?,
height_to_last_txindex: StorableVec::forced_import(
&path.join("height_to_last_txindex"),
Version::from(1),
)?,
// height_to_last_txoutindex: StorableVec::forced_import(&path.join("height_to_last_txoutindex"), Version::from(1))?,
// height_to_maxfeerate: StorableVec::forced_import(&path.join("height_to_maxfeerate"), Version::from(1))?,
// height_to_medianfeerate: StorableVec::forced_import(&path.join("height_to_medianfeerate"), Version::from(1))?,
// height_to_minfeerate: StorableVec::forced_import(&path.join("height_to_minfeerate"), Version::from(1))?,
// height_to_outputcount: StorableVec::forced_import(&path.join("height_to_outputcount"), Version::from(1))?,
// height_to_subsidy: StorableVec::forced_import(&path.join("height_to_subsidy"), Version::from(1))?,
// height_to_totalfees: StorableVec::forced_import(&path.join("height_to_totalfees"), Version::from(1))?,
// height_to_txcount: StorableVec::forced_import(&path.join("height_to_txcount"), Version::from(1))?,
txindex_to_fee: StorableVec::forced_import(
&path.join("txindex_to_fee"),
Version::from(1),
)?,
txindex_to_height: StorableVec::forced_import(
&path.join("txindex_to_height"),
Version::from(1),
)?,
txindex_to_is_coinbase: StorableVec::forced_import(
&path.join("txindex_to_is_coinbase"),
Version::from(1),
)?,
// txindex_to_feerate: StorableVec::forced_import(&path.join("txindex_to_feerate"), Version::from(1))?,
txindex_to_inputs_count: StorableVec::forced_import(
&path.join("txindex_to_inputs_count"),
Version::from(1),
)?,
txindex_to_inputs_sum: StorableVec::forced_import(
&path.join("txindex_to_inputs_sum"),
Version::from(1),
)?,
txindex_to_last_txinindex: StorableVec::forced_import(
&path.join("txindex_to_last_txinindex"),
Version::from(1),
)?,
txindex_to_last_txoutindex: StorableVec::forced_import(
&path.join("txindex_to_last_txoutindex"),
Version::from(1),
)?,
txindex_to_outputs_count: StorableVec::forced_import(
&path.join("txindex_to_outputs_count"),
Version::from(1),
)?,
txindex_to_outputs_sum: StorableVec::forced_import(
&path.join("txindex_to_outputs_sum"),
Version::from(1),
)?,
})
}
pub fn compute(
&mut self,
indexer: &mut Indexer,
starting_indexes: brk_indexer::Indexes,
exit: &Exit,
) -> color_eyre::Result<()> {
let starting_indexes = self.indexes.compute(indexer, starting_indexes, exit)?;
self.marketprice
.compute(indexer, &mut self.indexes, starting_indexes, exit)?;
// self.mut_vecs().height_to_ohlc
// let height_count = indexer.vecs().height_to_size.len();
// let txindexes_count = indexer.vecs().txindex_to_txid.len();
// let txinindexes_count = indexer.vecs().txinindex_to_txoutindex.len();
// let txoutindexes_count = indexer.vecs().txoutindex_to_addressindex.len();
// let date_count = self.vecs().height_to_date.len();
// self.vecs.txindex_to_last_txinindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// txinindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_inputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txinindex,
// &mut self.vecs.txindex_to_last_txinindex,
// exit,
// )?;
// self.vecs.txindex_to_last_txoutindex.compute_last_index_from_first(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// txoutindexes_count,
// exit,
// )?;
// self.vecs.txindex_to_outputs_count.compute_count_from_indexes(
// starting_indexes.txindex,
// &mut indexer.vecs().txindex_to_first_txoutindex,
// &mut self.vecs.txindex_to_last_txoutindex,
// exit,
// )?;
// self.vecs.height_to_last_txindex.compute_last_index_from_first(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// height_count,
// exit,
// )?;
// self.vecs.txindex_to_height.compute_inverse_less_to_more(
// starting_indexes.height,
// &mut indexer.vecs().height_to_first_txindex,
// &mut self.vecs.height_to_last_txindex,
// exit,
// )?;
// self.vecs.txindex_to_is_coinbase.compute_is_first_ordered(
// starting_indexes.txindex,
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// exit,
// )?;
// self.vecs.txindex_to_fee.compute_transform(
// &mut self.vecs.txindex_to_height,
// &mut indexer.vecs().height_to_first_txindex,
// )?;
// self.vecs.height_to_dateindex.compute(...)
// ---
// Date to X
// ---
// ...
// ---
// Month to X
// ---
// ...
// ---
// Year to X
// ---
// ...
Ok(())
}
pub fn as_any_vecs(&self) -> Vec<&dyn AnyStorableVec> {
[self.indexes.as_any_vecs(), self.marketprice.as_any_vecs()].concat()
}
}

View File

@@ -1,7 +1,6 @@
use std::ops::Add; use std::ops::Add;
use byteview::ByteView; use byteview::ByteView;
use derive_deref::{Deref, DerefMut};
use serde::Serialize; use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -15,8 +14,6 @@ use crate::Error;
Ord, Ord,
Clone, Clone,
Copy, Copy,
Deref,
DerefMut,
Default, Default,
FromBytes, FromBytes,
Immutable, Immutable,
@@ -29,16 +26,12 @@ pub struct Addressindex(u32);
impl Addressindex { impl Addressindex {
pub const BYTES: usize = size_of::<Self>(); pub const BYTES: usize = size_of::<Self>();
pub fn decremented(self) -> Self {
Self(*self - 1)
}
pub fn increment(&mut self) { pub fn increment(&mut self) {
self.0 += 1; self.0 += 1;
} }
pub fn incremented(self) -> Self { pub fn incremented(self) -> Self {
Self(*self + 1) Self(self.0 + 1)
} }
} }

View File

@@ -12,8 +12,6 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
Ord, Ord,
Clone, Clone,
Copy, Copy,
Deref,
DerefMut,
Default, Default,
FromBytes, FromBytes,
Immutable, Immutable,
@@ -24,16 +22,12 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
pub struct Addresstypeindex(u32); pub struct Addresstypeindex(u32);
impl Addresstypeindex { impl Addresstypeindex {
pub fn decremented(self) -> Self {
Self(*self - 1)
}
pub fn increment(&mut self) { pub fn increment(&mut self) {
self.0 += 1; self.0 += 1;
} }
pub fn incremented(self) -> Self { pub fn incremented(self) -> Self {
Self(*self + 1) Self(self.0 + 1)
} }
pub fn copy_then_increment(&mut self) -> Self { pub fn copy_then_increment(&mut self) -> Self {

View File

@@ -9,6 +9,6 @@ impl Bitcoin {
impl From<Sats> for Bitcoin { impl From<Sats> for Bitcoin {
fn from(value: Sats) -> Self { fn from(value: Sats) -> Self {
Self((*value as f64) / Self::ONE.0) Self(f64::from(value) / Self::ONE.0)
} }
} }

View File

@@ -1,4 +1,3 @@
use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -13,7 +12,6 @@ use super::Dollars;
Eq, Eq,
PartialOrd, PartialOrd,
Ord, Ord,
Deref,
FromBytes, FromBytes,
Immutable, Immutable,
IntoBytes, IntoBytes,
@@ -27,3 +25,9 @@ impl From<Dollars> for Cents {
Self((*value * 100.0).floor() as u64) Self((*value * 100.0).floor() as u64)
} }
} }
impl From<Cents> for f64 {
fn from(value: Cents) -> Self {
value.0 as f64
}
}

View File

@@ -60,11 +60,15 @@ impl From<Timestamp> for Date {
impl From<Dateindex> for Date { impl From<Dateindex> for Date {
fn from(value: Dateindex) -> Self { fn from(value: Dateindex) -> Self {
Self::from( if value == Dateindex::default() {
Self::INDEX_ZERO_ Date::INDEX_ZERO
.checked_add(Span::new().days(i64::from(value))) } else {
.unwrap(), Self::from(
) Self::INDEX_ONE_
.checked_add(Span::new().days(i64::from(value) - 1))
.unwrap(),
)
}
} }
} }

View File

@@ -9,10 +9,26 @@ use crate::Error;
use super::Date; use super::Date;
#[derive( #[derive(
Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize, Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)] )]
pub struct Dateindex(u16); pub struct Dateindex(u16);
impl Dateindex {
pub const BYTES: usize = size_of::<Self>();
}
impl From<Dateindex> for usize { impl From<Dateindex> for usize {
fn from(value: Dateindex) -> Self { fn from(value: Dateindex) -> Self {
value.0 as usize value.0 as usize

View File

@@ -4,7 +4,9 @@ use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Cents; use super::Cents;
#[derive(Debug, Default, Clone, Copy, Deref, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)] #[derive(
Debug, Default, Clone, Copy, Deref, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize,
)]
pub struct Dollars(f64); pub struct Dollars(f64);
impl From<f64> for Dollars { impl From<f64> for Dollars {
@@ -15,6 +17,12 @@ impl From<f64> for Dollars {
impl From<Cents> for Dollars { impl From<Cents> for Dollars {
fn from(value: Cents) -> Self { fn from(value: Cents) -> Self {
Self((*value as f64) / 100.0) Self(f64::from(value) / 100.0)
}
}
impl From<Dollars> for f64 {
fn from(value: Dollars) -> Self {
value.0
} }
} }

View File

@@ -1,4 +1,2 @@
use derive_deref::Deref; #[derive(Debug, Clone, Copy)]
#[derive(Debug, Deref, Clone, Copy)]
pub struct Feerate(f32); pub struct Feerate(f32);

View File

@@ -1,19 +1,18 @@
use std::{ use std::{
fmt::{self, Debug}, fmt::{self, Debug},
ops::{Add, AddAssign, Rem, Sub}, ops::{Add, AddAssign, Rem},
}; };
use bitcoincore_rpc::{Client, RpcApi}; use bitcoincore_rpc::{Client, RpcApi};
use derive_deref::{Deref, DerefMut};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::CheckedSub;
#[derive( #[derive(
Debug, Debug,
Clone, Clone,
Copy, Copy,
Deref,
DerefMut,
PartialEq, PartialEq,
Eq, Eq,
PartialOrd, PartialOrd,
@@ -49,11 +48,11 @@ impl Height {
} }
pub fn decrement(&mut self) { pub fn decrement(&mut self) {
self.0 -= 1; *self = self.decremented().unwrap();
} }
pub fn decremented(self) -> Self { pub fn decremented(self) -> Option<Self> {
Self(self.0.checked_sub(1).unwrap_or_default()) self.checked_sub(1_u32)
} }
pub fn is_zero(self) -> bool { pub fn is_zero(self) -> bool {
@@ -63,7 +62,7 @@ impl Height {
impl PartialEq<u64> for Height { impl PartialEq<u64> for Height {
fn eq(&self, other: &u64) -> bool { fn eq(&self, other: &u64) -> bool {
**self == *other as u32 self.0 == *other as u32
} }
} }
@@ -87,35 +86,25 @@ impl Add<usize> for Height {
type Output = Height; type Output = Height;
fn add(self, rhs: usize) -> Self::Output { fn add(self, rhs: usize) -> Self::Output {
Self::from(*self + rhs as u32) Self::from(self.0 + rhs as u32)
} }
} }
impl Sub<Height> for Height { impl CheckedSub<Height> for Height {
type Output = Height; fn checked_sub(self, rhs: Height) -> Option<Self> {
fn sub(self, rhs: Height) -> Self::Output { self.0.checked_sub(rhs.0).map(Height::from)
Self::from(*self - *rhs)
} }
} }
impl Sub<i32> for Height { impl CheckedSub<u32> for Height {
type Output = Height; fn checked_sub(self, rhs: u32) -> Option<Self> {
fn sub(self, rhs: i32) -> Self::Output { self.0.checked_sub(rhs).map(Height::from)
Self::from(*self - rhs as u32)
} }
} }
impl Sub<u32> for Height { impl CheckedSub<usize> for Height {
type Output = Height; fn checked_sub(self, rhs: usize) -> Option<Self> {
fn sub(self, rhs: u32) -> Self::Output { self.0.checked_sub(rhs as u32).map(Height::from)
Self::from(*self - rhs)
}
}
impl Sub<usize> for Height {
type Output = Height;
fn sub(self, rhs: usize) -> Self::Output {
Self::from(*self - rhs as u32)
} }
} }
@@ -141,7 +130,7 @@ impl Rem<usize> for Height {
impl fmt::Display for Height { impl fmt::Display for Height {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "{}", **self) write!(f, "{}", self.0)
} }
} }
@@ -168,6 +157,11 @@ impl From<Height> for usize {
} }
} }
impl From<Height> for u32 {
fn from(value: Height) -> Self {
value.0
}
}
impl From<Height> for u64 { impl From<Height> for u64 {
fn from(value: Height) -> Self { fn from(value: Height) -> Self {
value.0 as u64 value.0 as u64
@@ -189,7 +183,7 @@ impl From<bitcoin::locktime::absolute::Height> for Height {
impl From<Height> for bitcoin::locktime::absolute::Height { impl From<Height> for bitcoin::locktime::absolute::Height {
fn from(value: Height) -> Self { fn from(value: Height) -> Self {
bitcoin::locktime::absolute::Height::from_consensus(*value).unwrap() bitcoin::locktime::absolute::Height::from_consensus(value.0).unwrap()
} }
} }

View File

@@ -5,6 +5,7 @@ use super::{Height, Timestamp};
#[derive(Debug, Immutable, Clone, Copy, IntoBytes, KnownLayout, TryFromBytes, Serialize)] #[derive(Debug, Immutable, Clone, Copy, IntoBytes, KnownLayout, TryFromBytes, Serialize)]
#[repr(C)] #[repr(C)]
#[allow(warnings)]
pub enum LockTime { pub enum LockTime {
Height(Height), Height(Height),
Timestamp(Timestamp), Timestamp(Timestamp),

View File

@@ -2,9 +2,86 @@ use derive_deref::Deref;
use serde::Serialize; use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
use super::Cents; use super::{Cents, Dollars};
pub type OHLCCents = (Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>); #[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
#[repr(C)]
pub struct OHLCCents {
pub open: Open<Cents>,
pub high: High<Cents>,
pub low: Low<Cents>,
pub close: Close<Cents>,
}
impl From<(Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>)> for OHLCCents {
fn from(value: (Open<Cents>, High<Cents>, Low<Cents>, Close<Cents>)) -> Self {
Self {
open: value.0,
high: value.1,
low: value.2,
close: value.3,
}
}
}
impl From<Close<Cents>> for OHLCCents {
fn from(value: Close<Cents>) -> Self {
Self {
open: Open::from(value),
high: High::from(value),
low: Low::from(value),
close: value,
}
}
}
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
#[repr(C)]
pub struct OHLCDollars {
pub open: Open<Dollars>,
pub high: High<Dollars>,
pub low: Low<Dollars>,
pub close: Close<Dollars>,
}
impl From<(Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)> for OHLCDollars {
fn from(value: (Open<Dollars>, High<Dollars>, Low<Dollars>, Close<Dollars>)) -> Self {
Self {
open: value.0,
high: value.1,
low: value.2,
close: value.3,
}
}
}
impl From<Close<Dollars>> for OHLCDollars {
fn from(value: Close<Dollars>) -> Self {
Self {
open: Open::from(value),
high: High::from(value),
low: Low::from(value),
close: value,
}
}
}
impl From<OHLCCents> for OHLCDollars {
fn from(value: OHLCCents) -> Self {
Self::from(&value)
}
}
impl From<&OHLCCents> for OHLCDollars {
fn from(value: &OHLCCents) -> Self {
Self {
open: value.open.into(),
high: value.high.into(),
low: value.low.into(),
close: value.close.into(),
}
}
}
#[derive( #[derive(
Debug, Debug,
@@ -39,6 +116,12 @@ where
} }
} }
impl From<Open<Cents>> for Open<Dollars> {
fn from(value: Open<Cents>) -> Self {
Self(Dollars::from(*value))
}
}
#[derive( #[derive(
Debug, Debug,
Default, Default,
@@ -72,6 +155,12 @@ where
} }
} }
impl From<High<Cents>> for High<Dollars> {
fn from(value: High<Cents>) -> Self {
Self(Dollars::from(*value))
}
}
#[derive( #[derive(
Debug, Debug,
Default, Default,
@@ -105,6 +194,12 @@ where
} }
} }
impl From<Low<Cents>> for Low<Dollars> {
fn from(value: Low<Cents>) -> Self {
Self(Dollars::from(*value))
}
}
#[derive( #[derive(
Debug, Debug,
Default, Default,
@@ -128,3 +223,9 @@ impl<T> From<T> for Close<T> {
Self(value) Self(value)
} }
} }
impl From<Close<Cents>> for Close<Dollars> {
fn from(value: Close<Cents>) -> Self {
Self(Dollars::from(*value))
}
}

View File

@@ -4,7 +4,6 @@ use std::{
}; };
use bitcoin::Amount; use bitcoin::Amount;
use derive_deref::{Deref, DerefMut};
use serde::Serialize; use serde::Serialize;
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout}; use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -18,8 +17,6 @@ use super::Height;
Ord, Ord,
Clone, Clone,
Copy, Copy,
Deref,
DerefMut,
Default, Default,
FromBytes, FromBytes,
Immutable, Immutable,
@@ -40,7 +37,7 @@ impl Sats {
impl Add for Sats { impl Add for Sats {
type Output = Sats; type Output = Sats;
fn add(self, rhs: Sats) -> Self::Output { fn add(self, rhs: Sats) -> Self::Output {
Sats::from(*self + *rhs) Sats::from(self.0 + rhs.0)
} }
} }
@@ -53,7 +50,7 @@ impl AddAssign for Sats {
impl Sub for Sats { impl Sub for Sats {
type Output = Sats; type Output = Sats;
fn sub(self, rhs: Sats) -> Self::Output { fn sub(self, rhs: Sats) -> Self::Output {
Sats::from(*self - *rhs) Sats::from(self.0 - rhs.0)
} }
} }
@@ -66,27 +63,27 @@ impl SubAssign for Sats {
impl Mul<Sats> for Sats { impl Mul<Sats> for Sats {
type Output = Sats; type Output = Sats;
fn mul(self, rhs: Sats) -> Self::Output { fn mul(self, rhs: Sats) -> Self::Output {
Sats::from(*self * *rhs) Sats::from(self.0 * rhs.0)
} }
} }
impl Mul<u64> for Sats { impl Mul<u64> for Sats {
type Output = Sats; type Output = Sats;
fn mul(self, rhs: u64) -> Self::Output { fn mul(self, rhs: u64) -> Self::Output {
Sats::from(*self * rhs) Sats::from(self.0 * rhs)
} }
} }
impl Mul<Height> for Sats { impl Mul<Height> for Sats {
type Output = Sats; type Output = Sats;
fn mul(self, rhs: Height) -> Self::Output { fn mul(self, rhs: Height) -> Self::Output {
Sats::from(*self * *rhs as u64) Sats::from(self.0 * u64::from(rhs))
} }
} }
impl Sum for Sats { impl Sum for Sats {
fn sum<I: Iterator<Item = Self>>(iter: I) -> Self { fn sum<I: Iterator<Item = Self>>(iter: I) -> Self {
let sats: u64 = iter.map(|sats| *sats).sum(); let sats: u64 = iter.map(|sats| sats.0).sum();
Sats::from(sats) Sats::from(sats)
} }
} }
@@ -107,3 +104,9 @@ impl From<Sats> for Amount {
Self::from_sat(value.0) Self::from_sat(value.0)
} }
} }
impl From<Sats> for f64 {
fn from(value: Sats) -> Self {
value.0 as f64
}
}

View File

@@ -30,10 +30,6 @@ impl Txindex {
pub fn incremented(self) -> Self { pub fn incremented(self) -> Self {
Self(*self + 1) Self(*self + 1)
} }
pub fn decremented(self) -> Self {
Self(*self - 1)
}
} }
impl Add<Txindex> for Txindex { impl Add<Txindex> for Txindex {

View File

@@ -29,10 +29,6 @@ impl Txinindex {
pub fn incremented(self) -> Self { pub fn incremented(self) -> Self {
Self(*self + 1) Self(*self + 1)
} }
pub fn decremented(self) -> Self {
Self(*self - 1)
}
} }
impl Add<Txinindex> for Txinindex { impl Add<Txinindex> for Txinindex {

View File

@@ -32,10 +32,6 @@ impl Txoutindex {
Self(*self + 1) Self(*self + 1)
} }
pub fn decremented(self) -> Self {
Self(*self - 1)
}
pub fn is_coinbase(self) -> bool { pub fn is_coinbase(self) -> bool {
self == Self::COINBASE self == Self::COINBASE
} }

View File

@@ -0,0 +1,3 @@
pub trait CheckedSub<Rhs = Self>: Sized {
fn checked_sub(self, rhs: Rhs) -> Option<Self>;
}

View File

@@ -1,7 +1,9 @@
mod checked_sub;
mod paths; mod paths;
mod pause; mod pause;
mod rlimit; mod rlimit;
pub use checked_sub::*;
pub use paths::*; pub use paths::*;
pub use pause::*; pub use pause::*;
pub use rlimit::*; pub use rlimit::*;

View File

@@ -1,4 +1,7 @@
use std::path::{Path, PathBuf}; use std::{
env,
path::{Path, PathBuf},
};
pub fn path_dot_brk() -> PathBuf { pub fn path_dot_brk() -> PathBuf {
let home = std::env::var("HOME").unwrap(); let home = std::env::var("HOME").unwrap();
@@ -8,3 +11,26 @@ pub fn path_dot_brk() -> PathBuf {
pub fn path_dot_brk_log() -> PathBuf { pub fn path_dot_brk_log() -> PathBuf {
path_dot_brk().join("log") path_dot_brk().join("log")
} }
pub fn default_brk() -> PathBuf {
path_dot_brk()
}
pub fn default_bitcoin_path() -> PathBuf {
if env::consts::OS == "macos" {
default_mac_bitcoin_path()
} else {
default_linux_bitcoin_path()
}
}
fn default_linux_bitcoin_path() -> PathBuf {
Path::new(&std::env::var("HOME").unwrap()).join(".bitcoin")
}
fn default_mac_bitcoin_path() -> PathBuf {
Path::new(&std::env::var("HOME").unwrap())
.join("Library")
.join("Application Support")
.join("Bitcoin")
}

View File

@@ -10,7 +10,7 @@ fn main() -> color_eyre::Result<()> {
dbg!(fetcher.get_date(Date::new(2025, 1, 1))?); dbg!(fetcher.get_date(Date::new(2025, 1, 1))?);
dbg!(fetcher.get_height( dbg!(fetcher.get_height(
880_000_u32.into(), 881_000_u32.into(),
1740683986.into(), 1740683986.into(),
Some(1740683000.into()) Some(1740683000.into())
)?); )?);

View File

@@ -1,7 +1,7 @@
use std::{collections::BTreeMap, str::FromStr}; use std::{collections::BTreeMap, str::FromStr};
use brk_core::{Date, Height, OHLCCents}; use brk_core::{CheckedSub, Date, Height, OHLCCents};
use color_eyre::eyre::ContextCompat; use color_eyre::eyre::{ContextCompat, eyre};
use log::info; use log::info;
use serde_json::Value; use serde_json::Value;
@@ -14,56 +14,43 @@ pub struct Kibo {
} }
const KIBO_OFFICIAL_URL: &str = "https://kibo.money/api"; const KIBO_OFFICIAL_URL: &str = "https://kibo.money/api";
const KIBO_OFFICIAL_BACKUP_URL: &str = "https://backup.kibo.money/api";
const RETRIES: usize = 10; const RETRIES: usize = 10;
impl Kibo { impl Kibo {
fn get_base_url(try_index: usize) -> &'static str {
if try_index < RETRIES / 2 {
KIBO_OFFICIAL_URL
} else {
KIBO_OFFICIAL_BACKUP_URL
}
}
pub fn get_from_height(&mut self, height: Height) -> color_eyre::Result<OHLCCents> { pub fn get_from_height(&mut self, height: Height) -> color_eyre::Result<OHLCCents> {
let key = height.checked_sub(height % 10_000).unwrap_or_default();
#[allow(clippy::map_entry)] #[allow(clippy::map_entry)]
if !self.height_to_ohlc_vec.contains_key(&height) if !self.height_to_ohlc_vec.contains_key(&key)
|| ((usize::from(height) + self.height_to_ohlc_vec.get(&height).unwrap().len()) || ((key + self.height_to_ohlc_vec.get(&key).unwrap().len()) <= height)
<= usize::from(height))
{ {
self.height_to_ohlc_vec.insert( self.height_to_ohlc_vec.insert(
height, key,
Self::fetch_height_prices(height).inspect_err(|e| { Self::fetch_height_prices(key).inspect_err(|e| {
dbg!(e); dbg!(e);
})?, })?,
); );
} }
dbg!(&self.height_to_ohlc_vec.keys());
self.height_to_ohlc_vec self.height_to_ohlc_vec
.get(&height) .get(&key)
.unwrap() .unwrap()
.get(usize::from(height)) .get(usize::from(height.checked_sub(key).unwrap()))
.cloned() .cloned()
.ok_or(color_eyre::eyre::Error::msg("Couldn't find height in kibo")) .ok_or(color_eyre::eyre::Error::msg("Couldn't find height in kibo"))
} }
fn fetch_height_prices(height: Height) -> color_eyre::Result<Vec<OHLCCents>> { fn fetch_height_prices(height: Height) -> color_eyre::Result<Vec<OHLCCents>> {
info!("Fetching Kibo height prices..."); info!("Fetching Kibo height {height} prices...");
retry( retry(
|try_index| { |_| {
let base_url = Self::get_base_url(try_index); let url = format!("{KIBO_OFFICIAL_URL}/height-to-price?chunk={}", height);
let url = format!("{base_url}/height-to-price?chunk={}", height);
let body: Value = minreq::get(url).send()?.json()?; let body: Value = minreq::get(url).send()?.json()?;
let vec = body body.as_object()
.as_object()
.context("Expect to be an object")? .context("Expect to be an object")?
.get("dataset") .get("dataset")
.context("Expect object to have dataset")? .context("Expect object to have dataset")?
@@ -75,9 +62,7 @@ impl Kibo {
.context("Expect to be an array")? .context("Expect to be an array")?
.iter() .iter()
.map(Self::value_to_ohlc) .map(Self::value_to_ohlc)
.collect::<Result<Vec<_>, _>>()?; .collect::<Result<Vec<_>, _>>()
Ok(vec)
}, },
30, 30,
RETRIES, RETRIES,
@@ -107,19 +92,21 @@ impl Kibo {
.unwrap() .unwrap()
.get(date) .get(date)
.cloned() .cloned()
.ok_or(color_eyre::eyre::Error::msg("Couldn't find date in kibo")) .ok_or({
dbg!(date);
eyre!("Couldn't find date in kibo")
})
} }
fn fetch_date_prices(year: u16) -> color_eyre::Result<BTreeMap<Date, OHLCCents>> { fn fetch_date_prices(year: u16) -> color_eyre::Result<BTreeMap<Date, OHLCCents>> {
info!("Fetching Kibo date prices..."); info!("Fetching Kibo date {year} prices...");
retry( retry(
|try_index| { |_| {
let base_url = Self::get_base_url(try_index); let body: Value =
minreq::get(format!("{KIBO_OFFICIAL_URL}/date-to-price?chunk={}", year))
let body: Value = minreq::get(format!("{base_url}/date-to-price?chunk={}", year)) .send()?
.send()? .json()?;
.json()?;
body.as_object() body.as_object()
.context("Expect to be an object")? .context("Expect to be an object")?
@@ -156,11 +143,11 @@ impl Kibo {
))) )))
}; };
Ok(( Ok(OHLCCents::from((
Open::from(get_value("open")?), Open::from(get_value("open")?),
High::from(get_value("high")?), High::from(get_value("high")?),
Low::from(get_value("low")?), Low::from(get_value("low")?),
Close::from(get_value("close")?), Close::from(get_value("close")?),
)) )))
} }
} }

View File

@@ -106,12 +106,7 @@ impl Fetcher {
let previous_ohlc = previous_ohlc.unwrap(); let previous_ohlc = previous_ohlc.unwrap();
let mut final_ohlc = ( let mut final_ohlc = OHLCCents::from(previous_ohlc.close);
Open::from(previous_ohlc.3),
High::from(previous_ohlc.3),
Low::from(previous_ohlc.3),
previous_ohlc.3,
);
let start = previous_timestamp.unwrap_or(Timestamp::from(0)); let start = previous_timestamp.unwrap_or(Timestamp::from(0));
let end = timestamp; let end = timestamp;
@@ -119,15 +114,15 @@ impl Fetcher {
// Otherwise it's a re-org // Otherwise it's a re-org
if start < end { if start < end {
tree.range(start..=end).skip(1).for_each(|(_, ohlc)| { tree.range(start..=end).skip(1).for_each(|(_, ohlc)| {
if ohlc.1 > final_ohlc.1 { if ohlc.high > final_ohlc.high {
final_ohlc.1 = ohlc.1 final_ohlc.high = ohlc.high
} }
if ohlc.2 < final_ohlc.2 { if ohlc.low < final_ohlc.low {
final_ohlc.2 = ohlc.2 final_ohlc.low = ohlc.low
} }
final_ohlc.3 = ohlc.3; final_ohlc.close = ohlc.close;
}); });
} }

View File

@@ -1,5 +1,6 @@
use std::{path::Path, thread::sleep, time::Duration}; use std::{path::Path, thread::sleep, time::Duration};
use brk_core::default_bitcoin_path;
use brk_exit::Exit; use brk_exit::Exit;
use brk_indexer::{Indexer, rpc::RpcApi}; use brk_indexer::{Indexer, rpc::RpcApi};
use brk_parser::{ use brk_parser::{
@@ -13,7 +14,8 @@ fn main() -> color_eyre::Result<()> {
brk_logger::init(Some(Path::new(".log"))); brk_logger::init(Some(Path::new(".log")));
let bitcoin_dir = Path::new("../../../bitcoin"); let bitcoin_dir = default_bitcoin_path();
let rpc = Box::leak(Box::new(rpc::Client::new( let rpc = Box::leak(Box::new(rpc::Client::new(
"http://localhost:8332", "http://localhost:8332",
rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")), rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")),

View File

@@ -1,7 +1,8 @@
use bitcoincore_rpc::Client; use bitcoincore_rpc::Client;
use brk_core::{ use brk_core::{
Addressindex, BlockHash, Emptyindex, Height, Multisigindex, Opreturnindex, P2PK33index, P2PK65index, P2PKHindex, Addressindex, BlockHash, CheckedSub, Emptyindex, Height, Multisigindex, Opreturnindex,
P2SHindex, P2TRindex, P2WPKHindex, P2WSHindex, Pushonlyindex, Txindex, Txinindex, Txoutindex, Unknownindex, P2PK33index, P2PK65index, P2PKHindex, P2SHindex, P2TRindex, P2WPKHindex, P2WSHindex,
Pushonlyindex, Txindex, Txinindex, Txoutindex, Unknownindex,
}; };
use brk_parser::NUMBER_OF_UNSAFE_BLOCKS; use brk_parser::NUMBER_OF_UNSAFE_BLOCKS;
use color_eyre::eyre::ContextCompat; use color_eyre::eyre::ContextCompat;
@@ -32,8 +33,10 @@ pub struct Indexes {
impl Indexes { impl Indexes {
pub fn push_if_needed(&self, vecs: &mut Vecs) -> brk_vec::Result<()> { pub fn push_if_needed(&self, vecs: &mut Vecs) -> brk_vec::Result<()> {
let height = self.height; let height = self.height;
vecs.height_to_first_txindex.push_if_needed(height, self.txindex)?; vecs.height_to_first_txindex
vecs.height_to_first_txinindex.push_if_needed(height, self.txinindex)?; .push_if_needed(height, self.txindex)?;
vecs.height_to_first_txinindex
.push_if_needed(height, self.txinindex)?;
vecs.height_to_first_txoutindex vecs.height_to_first_txoutindex
.push_if_needed(height, self.txoutindex)?; .push_if_needed(height, self.txoutindex)?;
vecs.height_to_first_addressindex vecs.height_to_first_addressindex
@@ -54,8 +57,10 @@ impl Indexes {
.push_if_needed(height, self.p2pk65index)?; .push_if_needed(height, self.p2pk65index)?;
vecs.height_to_first_p2pkhindex vecs.height_to_first_p2pkhindex
.push_if_needed(height, self.p2pkhindex)?; .push_if_needed(height, self.p2pkhindex)?;
vecs.height_to_first_p2shindex.push_if_needed(height, self.p2shindex)?; vecs.height_to_first_p2shindex
vecs.height_to_first_p2trindex.push_if_needed(height, self.p2trindex)?; .push_if_needed(height, self.p2shindex)?;
vecs.height_to_first_p2trindex
.push_if_needed(height, self.p2trindex)?;
vecs.height_to_first_p2wpkhindex vecs.height_to_first_p2wpkhindex
.push_if_needed(height, self.p2wpkhindex)?; .push_if_needed(height, self.p2wpkhindex)?;
vecs.height_to_first_p2wshindex vecs.height_to_first_p2wshindex
@@ -77,9 +82,11 @@ impl TryFrom<(&mut Vecs, &Stores, &Client)> for Indexes {
// Height at which we wanna start: min last saved + 1 or 0 // Height at which we wanna start: min last saved + 1 or 0
let starting_height = vecs.starting_height().min(stores.starting_height()); let starting_height = vecs.starting_height().min(stores.starting_height());
let range = starting_height let range = u32::from(
.checked_sub(NUMBER_OF_UNSAFE_BLOCKS as u32) starting_height
.unwrap_or_default()..*starting_height; .checked_sub(NUMBER_OF_UNSAFE_BLOCKS as u32)
.unwrap_or_default(),
)..u32::from(starting_height);
// But we also need to check the chain and start earlier in case of a reorg // But we also need to check the chain and start earlier in case of a reorg
let height = range // ..= because of last saved + 1 let height = range // ..= because of last saved + 1
@@ -107,8 +114,14 @@ impl TryFrom<(&mut Vecs, &Stores, &Client)> for Indexes {
addressindex: *vecs.height_to_first_addressindex.get(height)?.context("")?, addressindex: *vecs.height_to_first_addressindex.get(height)?.context("")?,
emptyindex: *vecs.height_to_first_emptyindex.get(height)?.context("")?, emptyindex: *vecs.height_to_first_emptyindex.get(height)?.context("")?,
height, height,
multisigindex: *vecs.height_to_first_multisigindex.get(height)?.context("")?, multisigindex: *vecs
opreturnindex: *vecs.height_to_first_opreturnindex.get(height)?.context("")?, .height_to_first_multisigindex
.get(height)?
.context("")?,
opreturnindex: *vecs
.height_to_first_opreturnindex
.get(height)?
.context("")?,
p2pk33index: *vecs.height_to_first_p2pk33index.get(height)?.context("")?, p2pk33index: *vecs.height_to_first_p2pk33index.get(height)?.context("")?,
p2pk65index: *vecs.height_to_first_p2pk65index.get(height)?.context("")?, p2pk65index: *vecs.height_to_first_p2pk65index.get(height)?.context("")?,
p2pkhindex: *vecs.height_to_first_p2pkhindex.get(height)?.context("")?, p2pkhindex: *vecs.height_to_first_p2pkhindex.get(height)?.context("")?,
@@ -116,7 +129,10 @@ impl TryFrom<(&mut Vecs, &Stores, &Client)> for Indexes {
p2trindex: *vecs.height_to_first_p2trindex.get(height)?.context("")?, p2trindex: *vecs.height_to_first_p2trindex.get(height)?.context("")?,
p2wpkhindex: *vecs.height_to_first_p2wpkhindex.get(height)?.context("")?, p2wpkhindex: *vecs.height_to_first_p2wpkhindex.get(height)?.context("")?,
p2wshindex: *vecs.height_to_first_p2wshindex.get(height)?.context("")?, p2wshindex: *vecs.height_to_first_p2wshindex.get(height)?.context("")?,
pushonlyindex: *vecs.height_to_first_pushonlyindex.get(height)?.context("")?, pushonlyindex: *vecs
.height_to_first_pushonlyindex
.get(height)?
.context("")?,
txindex: *vecs.height_to_first_txindex.get(height)?.context("")?, txindex: *vecs.height_to_first_txindex.get(height)?.context("")?,
txinindex: *vecs.height_to_first_txinindex.get(height)?.context("")?, txinindex: *vecs.height_to_first_txinindex.get(height)?.context("")?,
txoutindex: *vecs.height_to_first_txoutindex.get(height)?.context("")?, txoutindex: *vecs.height_to_first_txoutindex.get(height)?.context("")?,

View File

@@ -83,7 +83,7 @@ impl Indexer {
self.stores self.stores
.as_mut() .as_mut()
.unwrap() .unwrap()
.rollback_if_needed(self.vecs.as_ref().unwrap(), &starting_indexes)?; .rollback_if_needed(self.vecs.as_mut().unwrap(), &starting_indexes)?;
self.vecs self.vecs
.as_mut() .as_mut()
.unwrap() .unwrap()

View File

@@ -1,6 +1,9 @@
use std::{path::Path, thread}; use std::{path::Path, thread};
use brk_core::{AddressHash, Addressbytes, Addressindex, Addresstype, BlockHashPrefix, Height, TxidPrefix, Txindex}; use brk_core::{
AddressHash, Addressbytes, Addressindex, Addresstype, BlockHashPrefix, Height, TxidPrefix,
Txindex,
};
use brk_vec::{Value, Version}; use brk_vec::{Value, Version};
use crate::Indexes; use crate::Indexes;
@@ -23,12 +26,14 @@ pub struct Stores {
impl Stores { impl Stores {
pub fn import(path: &Path) -> color_eyre::Result<Self> { pub fn import(path: &Path) -> color_eyre::Result<Self> {
thread::scope(|scope| { thread::scope(|scope| {
let addresshash_to_addressindex = let addresshash_to_addressindex = scope.spawn(|| {
scope.spawn(|| Store::import(&path.join("addresshash_to_addressindex"), Version::from(1))); Store::import(&path.join("addresshash_to_addressindex"), Version::from(1))
let blockhash_prefix_to_height = });
scope.spawn(|| Store::import(&path.join("blockhash_prefix_to_height"), Version::from(1))); let blockhash_prefix_to_height = scope.spawn(|| {
let txid_prefix_to_txindex = Store::import(&path.join("blockhash_prefix_to_height"), Version::from(1))
scope.spawn(|| Store::import(&path.join("txid_prefix_to_txindex"), Version::from(1))); });
let txid_prefix_to_txindex = scope
.spawn(|| Store::import(&path.join("txid_prefix_to_txindex"), Version::from(1)));
Ok(Self { Ok(Self {
addresshash_to_addressindex: addresshash_to_addressindex.join().unwrap()?, addresshash_to_addressindex: addresshash_to_addressindex.join().unwrap()?,
@@ -38,22 +43,29 @@ impl Stores {
}) })
} }
pub fn rollback_if_needed(&mut self, vecs: &Vecs, starting_indexes: &Indexes) -> color_eyre::Result<()> { pub fn rollback_if_needed(
&mut self,
vecs: &mut Vecs,
starting_indexes: &Indexes,
) -> color_eyre::Result<()> {
vecs.height_to_blockhash vecs.height_to_blockhash
.iter_from(starting_indexes.height, |(_, blockhash)| { .iter_from(starting_indexes.height, |(_, blockhash, ..)| {
let blockhash_prefix = BlockHashPrefix::from(blockhash); let blockhash_prefix = BlockHashPrefix::from(blockhash);
self.blockhash_prefix_to_height.remove(blockhash_prefix); self.blockhash_prefix_to_height.remove(blockhash_prefix);
Ok(()) Ok(())
})?; })?;
vecs.txindex_to_txid vecs.txindex_to_txid
.iter_from(starting_indexes.txindex, |(_txindex, txid)| { .iter_from(starting_indexes.txindex, |(_txindex, txid, ..)| {
let txid_prefix = TxidPrefix::from(txid); let txid_prefix = TxidPrefix::from(txid);
self.txid_prefix_to_txindex.remove(txid_prefix); self.txid_prefix_to_txindex.remove(txid_prefix);
Ok(()) Ok(())
})?; })?;
if let Some(index) = vecs.height_to_first_p2pk65index.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2pk65index
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs while let Some(typedbytes) = vecs
.p2pk65index_to_p2pk65addressbytes .p2pk65index_to_p2pk65addressbytes
@@ -67,7 +79,10 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2pk33index.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2pk33index
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs while let Some(typedbytes) = vecs
.p2pk33index_to_p2pk33addressbytes .p2pk33index_to_p2pk33addressbytes
@@ -81,9 +96,16 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2pkhindex.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2pkhindex
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs.p2pkhindex_to_p2pkhaddressbytes.get(index)?.map(Value::into_inner) { while let Some(typedbytes) = vecs
.p2pkhindex_to_p2pkhaddressbytes
.get(index)?
.map(Value::into_inner)
{
let bytes = Addressbytes::from(typedbytes); let bytes = Addressbytes::from(typedbytes);
let hash = AddressHash::from((&bytes, Addresstype::P2PKH)); let hash = AddressHash::from((&bytes, Addresstype::P2PKH));
self.addresshash_to_addressindex.remove(hash); self.addresshash_to_addressindex.remove(hash);
@@ -91,9 +113,16 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2shindex.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2shindex
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs.p2shindex_to_p2shaddressbytes.get(index)?.map(Value::into_inner) { while let Some(typedbytes) = vecs
.p2shindex_to_p2shaddressbytes
.get(index)?
.map(Value::into_inner)
{
let bytes = Addressbytes::from(typedbytes); let bytes = Addressbytes::from(typedbytes);
let hash = AddressHash::from((&bytes, Addresstype::P2SH)); let hash = AddressHash::from((&bytes, Addresstype::P2SH));
self.addresshash_to_addressindex.remove(hash); self.addresshash_to_addressindex.remove(hash);
@@ -101,9 +130,16 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2trindex.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2trindex
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs.p2trindex_to_p2traddressbytes.get(index)?.map(Value::into_inner) { while let Some(typedbytes) = vecs
.p2trindex_to_p2traddressbytes
.get(index)?
.map(Value::into_inner)
{
let bytes = Addressbytes::from(typedbytes); let bytes = Addressbytes::from(typedbytes);
let hash = AddressHash::from((&bytes, Addresstype::P2TR)); let hash = AddressHash::from((&bytes, Addresstype::P2TR));
self.addresshash_to_addressindex.remove(hash); self.addresshash_to_addressindex.remove(hash);
@@ -111,7 +147,10 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2wpkhindex.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2wpkhindex
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs while let Some(typedbytes) = vecs
.p2wpkhindex_to_p2wpkhaddressbytes .p2wpkhindex_to_p2wpkhaddressbytes
@@ -125,9 +164,16 @@ impl Stores {
} }
} }
if let Some(index) = vecs.height_to_first_p2wshindex.get(starting_indexes.height)? { if let Some(index) = vecs
.height_to_first_p2wshindex
.get(starting_indexes.height)?
{
let mut index = index.into_inner(); let mut index = index.into_inner();
while let Some(typedbytes) = vecs.p2wshindex_to_p2wshaddressbytes.get(index)?.map(Value::into_inner) { while let Some(typedbytes) = vecs
.p2wshindex_to_p2wshaddressbytes
.get(index)?
.map(Value::into_inner)
{
let bytes = Addressbytes::from(typedbytes); let bytes = Addressbytes::from(typedbytes);
let hash = AddressHash::from((&bytes, Addresstype::P2WSH)); let hash = AddressHash::from((&bytes, Addresstype::P2WSH));
self.addresshash_to_addressindex.remove(hash); self.addresshash_to_addressindex.remove(hash);
@@ -135,7 +181,7 @@ impl Stores {
} }
} }
self.commit(starting_indexes.height.decremented())?; self.commit(starting_indexes.height.decremented().unwrap())?;
Ok(()) Ok(())
} }
@@ -158,7 +204,8 @@ impl Stores {
scope.spawn(|| self.addresshash_to_addressindex.commit(height)); scope.spawn(|| self.addresshash_to_addressindex.commit(height));
let blockhash_prefix_to_height_commit_handle = let blockhash_prefix_to_height_commit_handle =
scope.spawn(|| self.blockhash_prefix_to_height.commit(height)); scope.spawn(|| self.blockhash_prefix_to_height.commit(height));
let txid_prefix_to_txindex_commit_handle = scope.spawn(|| self.txid_prefix_to_txindex.commit(height)); let txid_prefix_to_txindex_commit_handle =
scope.spawn(|| self.txid_prefix_to_txindex.commit(height));
addresshash_to_addressindex_commit_handle.join().unwrap()?; addresshash_to_addressindex_commit_handle.join().unwrap()?;
blockhash_prefix_to_height_commit_handle.join().unwrap()?; blockhash_prefix_to_height_commit_handle.join().unwrap()?;

View File

@@ -1,10 +1,11 @@
use std::{fs, io, path::Path}; use std::{fs, io, path::Path};
use brk_core::{ use brk_core::{
Addressbytes, Addressindex, Addresstype, Addresstypeindex, BlockHash, Emptyindex, Height, LockTime, Multisigindex, Addressbytes, Addressindex, Addresstype, Addresstypeindex, BlockHash, Emptyindex, Height,
Opreturnindex, P2PK33AddressBytes, P2PK33index, P2PK65AddressBytes, P2PK65index, P2PKHAddressBytes, P2PKHindex, LockTime, Multisigindex, Opreturnindex, P2PK33AddressBytes, P2PK33index, P2PK65AddressBytes,
P2SHAddressBytes, P2SHindex, P2TRAddressBytes, P2TRindex, P2WPKHAddressBytes, P2WPKHindex, P2WSHAddressBytes, P2PK65index, P2PKHAddressBytes, P2PKHindex, P2SHAddressBytes, P2SHindex, P2TRAddressBytes,
P2WSHindex, Pushonlyindex, Sats, Timestamp, TxVersion, Txid, Txindex, Txinindex, Txoutindex, Unknownindex, Weight, P2TRindex, P2WPKHAddressBytes, P2WPKHindex, P2WSHAddressBytes, P2WSHindex, Pushonlyindex, Sats,
Timestamp, TxVersion, Txid, Txindex, Txinindex, Txoutindex, Unknownindex, Weight,
}; };
use brk_vec::{AnyStorableVec, Version}; use brk_vec::{AnyStorableVec, Version};
use rayon::prelude::*; use rayon::prelude::*;
@@ -75,9 +76,18 @@ impl Vecs {
&path.join("addressindex_to_addresstypeindex"), &path.join("addressindex_to_addresstypeindex"),
Version::from(1), Version::from(1),
)?, )?,
addressindex_to_height: StorableVec::import(&path.join("addressindex_to_height"), Version::from(1))?, addressindex_to_height: StorableVec::import(
height_to_blockhash: StorableVec::import(&path.join("height_to_blockhash"), Version::from(1))?, &path.join("addressindex_to_height"),
height_to_difficulty: StorableVec::import(&path.join("height_to_difficulty"), Version::from(1))?, Version::from(1),
)?,
height_to_blockhash: StorableVec::import(
&path.join("height_to_blockhash"),
Version::from(1),
)?,
height_to_difficulty: StorableVec::import(
&path.join("height_to_difficulty"),
Version::from(1),
)?,
height_to_first_addressindex: StorableVec::import( height_to_first_addressindex: StorableVec::import(
&path.join("height_to_first_addressindex"), &path.join("height_to_first_addressindex"),
Version::from(1), Version::from(1),
@@ -98,8 +108,14 @@ impl Vecs {
&path.join("height_to_first_pushonlyindex"), &path.join("height_to_first_pushonlyindex"),
Version::from(1), Version::from(1),
)?, )?,
height_to_first_txindex: StorableVec::import(&path.join("height_to_first_txindex"), Version::from(1))?, height_to_first_txindex: StorableVec::import(
height_to_first_txinindex: StorableVec::import(&path.join("height_to_first_txinindex"), Version::from(1))?, &path.join("height_to_first_txindex"),
Version::from(1),
)?,
height_to_first_txinindex: StorableVec::import(
&path.join("height_to_first_txinindex"),
Version::from(1),
)?,
height_to_first_txoutindex: StorableVec::import( height_to_first_txoutindex: StorableVec::import(
&path.join("height_to_first_txoutindex"), &path.join("height_to_first_txoutindex"),
Version::from(1), Version::from(1),
@@ -120,8 +136,14 @@ impl Vecs {
&path.join("height_to_first_p2pkhindex"), &path.join("height_to_first_p2pkhindex"),
Version::from(1), Version::from(1),
)?, )?,
height_to_first_p2shindex: StorableVec::import(&path.join("height_to_first_p2shindex"), Version::from(1))?, height_to_first_p2shindex: StorableVec::import(
height_to_first_p2trindex: StorableVec::import(&path.join("height_to_first_p2trindex"), Version::from(1))?, &path.join("height_to_first_p2shindex"),
Version::from(1),
)?,
height_to_first_p2trindex: StorableVec::import(
&path.join("height_to_first_p2trindex"),
Version::from(1),
)?,
height_to_first_p2wpkhindex: StorableVec::import( height_to_first_p2wpkhindex: StorableVec::import(
&path.join("height_to_first_p2wpkhindex"), &path.join("height_to_first_p2wpkhindex"),
Version::from(1), Version::from(1),
@@ -131,8 +153,14 @@ impl Vecs {
Version::from(1), Version::from(1),
)?, )?,
height_to_size: StorableVec::import(&path.join("height_to_size"), Version::from(1))?, height_to_size: StorableVec::import(&path.join("height_to_size"), Version::from(1))?,
height_to_timestamp: StorableVec::import(&path.join("height_to_timestamp"), Version::from(1))?, height_to_timestamp: StorableVec::import(
height_to_weight: StorableVec::import(&path.join("height_to_weight"), Version::from(1))?, &path.join("height_to_timestamp"),
Version::from(1),
)?,
height_to_weight: StorableVec::import(
&path.join("height_to_weight"),
Version::from(1),
)?,
p2pk33index_to_p2pk33addressbytes: StorableVec::import( p2pk33index_to_p2pk33addressbytes: StorableVec::import(
&path.join("p2pk33index_to_p2pk33addressbytes"), &path.join("p2pk33index_to_p2pk33addressbytes"),
Version::from(1), Version::from(1),
@@ -169,27 +197,48 @@ impl Vecs {
&path.join("txindex_to_first_txoutindex"), &path.join("txindex_to_first_txoutindex"),
Version::from(1), Version::from(1),
)?, )?,
txindex_to_height: StorableVec::import(&path.join("txindex_to_height"), Version::from(1))?, txindex_to_height: StorableVec::import(
txindex_to_locktime: StorableVec::import(&path.join("txindex_to_locktime"), Version::from(1))?, &path.join("txindex_to_height"),
Version::from(1),
)?,
txindex_to_locktime: StorableVec::import(
&path.join("txindex_to_locktime"),
Version::from(1),
)?,
txindex_to_txid: StorableVec::import(&path.join("txindex_to_txid"), Version::from(1))?, txindex_to_txid: StorableVec::import(&path.join("txindex_to_txid"), Version::from(1))?,
txindex_to_base_size: StorableVec::import(&path.join("txindex_to_base_size"), Version::from(1))?, txindex_to_base_size: StorableVec::import(
txindex_to_total_size: StorableVec::import(&path.join("txindex_to_total_size"), Version::from(1))?, &path.join("txindex_to_base_size"),
Version::from(1),
)?,
txindex_to_total_size: StorableVec::import(
&path.join("txindex_to_total_size"),
Version::from(1),
)?,
txindex_to_is_explicitly_rbf: StorableVec::import( txindex_to_is_explicitly_rbf: StorableVec::import(
&path.join("txindex_to_is_explicitly_rbf"), &path.join("txindex_to_is_explicitly_rbf"),
Version::from(1), Version::from(1),
)?, )?,
txindex_to_txversion: StorableVec::import(&path.join("txindex_to_txversion"), Version::from(1))?, txindex_to_txversion: StorableVec::import(
txinindex_to_txoutindex: StorableVec::import(&path.join("txinindex_to_txoutindex"), Version::from(1))?, &path.join("txindex_to_txversion"),
Version::from(1),
)?,
txinindex_to_txoutindex: StorableVec::import(
&path.join("txinindex_to_txoutindex"),
Version::from(1),
)?,
txoutindex_to_addressindex: StorableVec::import( txoutindex_to_addressindex: StorableVec::import(
&path.join("txoutindex_to_addressindex"), &path.join("txoutindex_to_addressindex"),
Version::from(1), Version::from(1),
)?, )?,
txoutindex_to_value: StorableVec::import(&path.join("txoutindex_to_value"), Version::from(1))?, txoutindex_to_value: StorableVec::import(
&path.join("txoutindex_to_value"),
Version::from(1),
)?,
}) })
} }
pub fn rollback_if_needed(&mut self, starting_indexes: &Indexes) -> brk_vec::Result<()> { pub fn rollback_if_needed(&mut self, starting_indexes: &Indexes) -> brk_vec::Result<()> {
let saved_height = starting_indexes.height.decremented(); let saved_height = starting_indexes.height.decremented().unwrap_or_default();
// We don't want to override the starting indexes so we cut from n + 1 // We don't want to override the starting indexes so we cut from n + 1
let height = starting_indexes.height.incremented(); let height = starting_indexes.height.incremented();
@@ -218,7 +267,8 @@ impl Vecs {
.truncate_if_needed(height, saved_height)?; .truncate_if_needed(height, saved_height)?;
self.height_to_first_pushonlyindex self.height_to_first_pushonlyindex
.truncate_if_needed(height, saved_height)?; .truncate_if_needed(height, saved_height)?;
self.height_to_first_txindex.truncate_if_needed(height, saved_height)?; self.height_to_first_txindex
.truncate_if_needed(height, saved_height)?;
self.height_to_first_txinindex self.height_to_first_txinindex
.truncate_if_needed(height, saved_height)?; .truncate_if_needed(height, saved_height)?;
self.height_to_first_txoutindex self.height_to_first_txoutindex
@@ -243,11 +293,16 @@ impl Vecs {
.. ..
} = starting_indexes; } = starting_indexes;
self.height_to_blockhash.truncate_if_needed(height, saved_height)?; self.height_to_blockhash
self.height_to_difficulty.truncate_if_needed(height, saved_height)?; .truncate_if_needed(height, saved_height)?;
self.height_to_size.truncate_if_needed(height, saved_height)?; self.height_to_difficulty
self.height_to_timestamp.truncate_if_needed(height, saved_height)?; .truncate_if_needed(height, saved_height)?;
self.height_to_weight.truncate_if_needed(height, saved_height)?; self.height_to_size
.truncate_if_needed(height, saved_height)?;
self.height_to_timestamp
.truncate_if_needed(height, saved_height)?;
self.height_to_weight
.truncate_if_needed(height, saved_height)?;
self.addressindex_to_addresstype self.addressindex_to_addresstype
.truncate_if_needed(addressindex, saved_height)?; .truncate_if_needed(addressindex, saved_height)?;
@@ -275,12 +330,18 @@ impl Vecs {
.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
self.txindex_to_first_txoutindex self.txindex_to_first_txoutindex
.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
self.txindex_to_height.truncate_if_needed(txindex, saved_height)?; self.txindex_to_height
self.txindex_to_locktime.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
self.txindex_to_txid.truncate_if_needed(txindex, saved_height)?; self.txindex_to_locktime
self.txindex_to_txversion.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
self.txindex_to_base_size.truncate_if_needed(txindex, saved_height)?; self.txindex_to_txid
self.txindex_to_total_size.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
self.txindex_to_txversion
.truncate_if_needed(txindex, saved_height)?;
self.txindex_to_base_size
.truncate_if_needed(txindex, saved_height)?;
self.txindex_to_total_size
.truncate_if_needed(txindex, saved_height)?;
self.txindex_to_is_explicitly_rbf self.txindex_to_is_explicitly_rbf
.truncate_if_needed(txindex, saved_height)?; .truncate_if_needed(txindex, saved_height)?;
@@ -289,7 +350,8 @@ impl Vecs {
self.txoutindex_to_addressindex self.txoutindex_to_addressindex
.truncate_if_needed(txoutindex, saved_height)?; .truncate_if_needed(txoutindex, saved_height)?;
self.txoutindex_to_value.truncate_if_needed(txoutindex, saved_height)?; self.txoutindex_to_value
.truncate_if_needed(txoutindex, saved_height)?;
Ok(()) Ok(())
} }
@@ -351,13 +413,21 @@ impl Vecs {
Addressbytes::P2PK33(bytes) => self Addressbytes::P2PK33(bytes) => self
.p2pk33index_to_p2pk33addressbytes .p2pk33index_to_p2pk33addressbytes
.push_if_needed(index.into(), bytes), .push_if_needed(index.into(), bytes),
Addressbytes::P2PKH(bytes) => self.p2pkhindex_to_p2pkhaddressbytes.push_if_needed(index.into(), bytes), Addressbytes::P2PKH(bytes) => self
Addressbytes::P2SH(bytes) => self.p2shindex_to_p2shaddressbytes.push_if_needed(index.into(), bytes), .p2pkhindex_to_p2pkhaddressbytes
.push_if_needed(index.into(), bytes),
Addressbytes::P2SH(bytes) => self
.p2shindex_to_p2shaddressbytes
.push_if_needed(index.into(), bytes),
Addressbytes::P2WPKH(bytes) => self Addressbytes::P2WPKH(bytes) => self
.p2wpkhindex_to_p2wpkhaddressbytes .p2wpkhindex_to_p2wpkhaddressbytes
.push_if_needed(index.into(), bytes), .push_if_needed(index.into(), bytes),
Addressbytes::P2WSH(bytes) => self.p2wshindex_to_p2wshaddressbytes.push_if_needed(index.into(), bytes), Addressbytes::P2WSH(bytes) => self
Addressbytes::P2TR(bytes) => self.p2trindex_to_p2traddressbytes.push_if_needed(index.into(), bytes), .p2wshindex_to_p2wshaddressbytes
.push_if_needed(index.into(), bytes),
Addressbytes::P2TR(bytes) => self
.p2trindex_to_p2traddressbytes
.push_if_needed(index.into(), bytes),
} }
} }

View File

@@ -1,13 +1,12 @@
use std::path::Path;
use bitcoincore_rpc::{Auth, Client}; use bitcoincore_rpc::{Auth, Client};
use brk_core::Height; use brk_core::{Height, default_bitcoin_path};
use brk_parser::Parser; use brk_parser::Parser;
fn main() { fn main() {
let i = std::time::Instant::now(); let i = std::time::Instant::now();
let bitcoin_dir = Path::new("../../../bitcoin"); let bitcoin_dir = default_bitcoin_path();
let rpc = Box::leak(Box::new( let rpc = Box::leak(Box::new(
Client::new( Client::new(
"http://localhost:8332", "http://localhost:8332",

View File

@@ -23,8 +23,8 @@ use tree::VecIdToIndexToVec;
pub struct Query<'a> { pub struct Query<'a> {
pub vecid_to_index_to_vec: VecIdToIndexToVec<'a>, pub vecid_to_index_to_vec: VecIdToIndexToVec<'a>,
indexer: &'a Indexer, _indexer: &'a Indexer,
computer: &'a Computer, _computer: &'a Computer,
} }
impl<'a> Query<'a> { impl<'a> Query<'a> {
@@ -45,8 +45,8 @@ impl<'a> Query<'a> {
Self { Self {
vecid_to_index_to_vec: vecs, vecid_to_index_to_vec: vecs,
indexer, _indexer: indexer,
computer, _computer: computer,
} }
} }

View File

@@ -21,9 +21,9 @@ color-eyre = { workspace = true }
jiff = { workspace = true } jiff = { workspace = true }
log = { workspace = true } log = { workspace = true }
minreq = { workspace = true } minreq = { workspace = true }
oxc = { version = "0.56.0", features = ["codegen", "minifier"] } oxc = { version = "0.56.5", features = ["codegen", "minifier"] }
serde = { workspace = true } serde = { workspace = true }
serde_json = { workspace = true } serde_json = { workspace = true }
tokio = { version = "1.43.0", features = ["full"] } tokio = { version = "1.44.0", features = ["full"] }
tower-http = { version = "0.6.2", features = ["compression-full"] } tower-http = { version = "0.6.2", features = ["compression-full"] }
zip = "2.2.3" zip = "2.2.3"

View File

@@ -1,6 +1,7 @@
use std::{path::Path, thread::sleep, time::Duration}; use std::{path::Path, thread::sleep, time::Duration};
use brk_computer::Computer; use brk_computer::Computer;
use brk_core::default_bitcoin_path;
use brk_exit::Exit; use brk_exit::Exit;
use brk_indexer::Indexer; use brk_indexer::Indexer;
use brk_parser::{ use brk_parser::{
@@ -15,9 +16,10 @@ pub fn main() -> color_eyre::Result<()> {
brk_logger::init(Some(Path::new(".log"))); brk_logger::init(Some(Path::new(".log")));
let process = false; let process = true;
let bitcoin_dir = default_bitcoin_path();
let bitcoin_dir = Path::new("../../../bitcoin");
let rpc = Box::leak(Box::new(rpc::Client::new( let rpc = Box::leak(Box::new(rpc::Client::new(
"http://localhost:8332", "http://localhost:8332",
rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")), rpc::Auth::CookieFile(bitcoin_dir.join(".cookie")),

View File

@@ -9,6 +9,7 @@ license.workspace = true
repository.workspace = true repository.workspace = true
[dependencies] [dependencies]
brk_core = { workspace = true }
brk_exit = { workspace = true } brk_exit = { workspace = true }
memmap2 = "0.9.5" memmap2 = "0.9.5"
rayon = { workspace = true } rayon = { workspace = true }

View File

@@ -16,6 +16,7 @@ use std::{
sync::OnceLock, sync::OnceLock,
}; };
use brk_core::CheckedSub;
use brk_exit::Exit; use brk_exit::Exit;
pub use memmap2; pub use memmap2;
use rayon::prelude::*; use rayon::prelude::*;
@@ -258,6 +259,17 @@ where
} }
#[inline] #[inline]
pub fn read_(&mut self, index: usize) -> Result<Option<&T>> { pub fn read_(&mut self, index: usize) -> Result<Option<&T>> {
match self.index_to_pushed_index(index) {
Ok(index) => {
if let Some(index) = index {
return Ok(self.pushed.get(index));
}
}
Err(Error::IndexTooHigh) => return Ok(None),
Err(Error::IndexTooLow) => {}
Err(error) => return Err(error),
}
let byte_index = Self::index_to_byte_index(index); let byte_index = Self::index_to_byte_index(index);
if self.file_position != byte_index { if self.file_position != byte_index {
self.file_position = self.seek(Self::index_to_byte_index(index))?; self.file_position = self.seek(Self::index_to_byte_index(index))?;
@@ -279,21 +291,20 @@ where
self.read_(len - 1) self.read_(len - 1)
} }
pub fn iter<F>(&self, f: F) -> Result<()> pub fn iter<F>(&mut self, f: F) -> Result<()>
where where
F: FnMut((I, &T)) -> Result<()>, F: FnMut((I, &T, &mut Self)) -> Result<()>,
{ {
self.iter_from(I::default(), f) self.iter_from(I::default(), f)
} }
pub fn iter_from<F>(&self, mut index: I, mut f: F) -> Result<()> pub fn iter_from<F>(&mut self, mut index: I, mut f: F) -> Result<()>
where where
F: FnMut((I, &T)) -> Result<()>, F: FnMut((I, &T, &mut Self)) -> Result<()>,
{ {
let mut file = self.open_file()?; let mut file = self.open_file()?;
let disk_len = I::from(Self::read_disk_len_(&file)?); let disk_len = I::from(Self::read_disk_len_(&file)?);
let pushed_len = I::from(self.pushed_len());
Self::seek_( Self::seek_(
&mut file, &mut file,
@@ -303,18 +314,12 @@ where
let mut buf = Self::create_buffer(); let mut buf = Self::create_buffer();
while index < disk_len { while index < disk_len {
f((index, Self::read_exact(&mut file, &mut buf)?))?; f((index, Self::read_exact(&mut file, &mut buf)?, self))?;
index = index + 1; index = index + 1;
} }
let disk_len = Self::i_to_usize(disk_len)?; if self.pushed_len() != 0 {
let mut i = I::default(); unreachable!();
while i < pushed_len {
f((
i + disk_len,
self.pushed.get(Self::i_to_usize(i)?).as_ref().unwrap(),
))?;
i = i + 1;
} }
Ok(()) Ok(())
@@ -573,24 +578,26 @@ where
std::any::type_name::<I>() std::any::type_name::<I>()
} }
pub fn compute_transform<A, F>( pub fn compute_transform<A, B, F>(
&mut self, &mut self,
max_from: I, max_from: A,
other: &mut StorableVec<I, A>, other: &mut StorableVec<A, B>,
t: F, mut t: F,
exit: &Exit, exit: &Exit,
) -> Result<()> ) -> Result<()>
where where
A: StoredType, A: StoredIndex,
F: Fn(&A, I) -> T, B: StoredType,
F: FnMut((A, &B, &mut Self, &mut StorableVec<A, B>)) -> (I, T),
{ {
self.validate_computed_version_or_reset_file( self.validate_computed_version_or_reset_file(
Version::from(0) + self.version + other.version, Version::from(0) + self.version + other.version,
)?; )?;
let index = max_from.min(I::from(self.len())); let index = max_from.min(A::from(self.len()));
other.iter_from(index, |(i, a)| { other.iter_from(index, |(a, b, other)| {
self.push_and_flush_if_needed(i, t(a, i), exit) let (i, v) = t((a, b, self, other));
self.push_and_flush_if_needed(i, v, exit)
})?; })?;
Ok(self.safe_flush(exit)?) Ok(self.safe_flush(exit)?)
@@ -611,7 +618,14 @@ where
)?; )?;
let index = max_from.min(self.read_last()?.cloned().unwrap_or_default()); let index = max_from.min(self.read_last()?.cloned().unwrap_or_default());
other.iter_from(index, |(v, i)| self.push_and_flush_if_needed(*i, v, exit))?; other.iter_from(index, |(v, i, ..)| {
let i = *i;
if self.read(i).unwrap().is_none_or(|old_v| *old_v > v) {
self.push_and_flush_if_needed(i, v, exit)
} else {
Ok(())
}
})?;
Ok(self.safe_flush(exit)?) Ok(self.safe_flush(exit)?)
} }
@@ -632,7 +646,7 @@ where
)?; )?;
let index = max_from.min(T::from(self.len())); let index = max_from.min(T::from(self.len()));
first_indexes.iter_from(index, |(value, first_index)| { first_indexes.iter_from(index, |(value, first_index, ..)| {
let first_index = Self::i_to_usize(*first_index)?; let first_index = Self::i_to_usize(*first_index)?;
let last_index = Self::i_to_usize(*last_indexes.read(value)?.unwrap())?; let last_index = Self::i_to_usize(*last_indexes.read(value)?.unwrap())?;
(first_index..last_index) (first_index..last_index)
@@ -650,7 +664,7 @@ where
exit: &Exit, exit: &Exit,
) -> Result<()> ) -> Result<()>
where where
T: Copy + From<usize> + Sub<T, Output = T> + StoredIndex, T: Copy + From<usize> + CheckedSub<T> + StoredIndex,
{ {
self.validate_computed_version_or_reset_file( self.validate_computed_version_or_reset_file(
Version::from(0) + self.version + first_indexes.version, Version::from(0) + self.version + first_indexes.version,
@@ -659,15 +673,19 @@ where
let index = max_from.min(I::from(self.len())); let index = max_from.min(I::from(self.len()));
let one = T::from(1); let one = T::from(1);
let mut prev_index: Option<I> = None; let mut prev_index: Option<I> = None;
first_indexes.iter_from(index, |(i, v)| { first_indexes.iter_from(index, |(i, v, ..)| {
if let Some(prev_index) = prev_index { if let Some(prev_index) = prev_index {
self.push_and_flush_if_needed(prev_index, *v - one, exit)?; self.push_and_flush_if_needed(prev_index, v.checked_sub(one).unwrap(), exit)?;
} }
prev_index.replace(i); prev_index.replace(i);
Ok(()) Ok(())
})?; })?;
if let Some(prev_index) = prev_index { if let Some(prev_index) = prev_index {
self.push_and_flush_if_needed(prev_index, T::from(final_len) - one, exit)?; self.push_and_flush_if_needed(
prev_index,
T::from(final_len).checked_sub(one).unwrap(),
exit,
)?;
} }
Ok(self.safe_flush(exit)?) Ok(self.safe_flush(exit)?)
@@ -690,7 +708,7 @@ where
)?; )?;
let index = max_from.min(I::from(self.len())); let index = max_from.min(I::from(self.len()));
first_indexes.iter_from(index, |(i, first_index)| { first_indexes.iter_from(index, |(i, first_index, ..)| {
let last_index = last_indexes.read(i)?.unwrap(); let last_index = last_indexes.read(i)?.unwrap();
let count = *last_index + 1_usize - *first_index; let count = *last_index + 1_usize - *first_index;
self.push_and_flush_if_needed(i, count.into(), exit) self.push_and_flush_if_needed(i, count.into(), exit)
@@ -716,7 +734,7 @@ where
)?; )?;
let index = max_from.min(I::from(self.len())); let index = max_from.min(I::from(self.len()));
self_to_other.iter_from(index, |(i, other)| { self_to_other.iter_from(index, |(i, other, ..)| {
self.push_and_flush_if_needed( self.push_and_flush_if_needed(
i, i,
T::from(other_to_self.read(*other)?.unwrap() == &i), T::from(other_to_self.read(*other)?.unwrap() == &i),
@@ -745,7 +763,7 @@ where
)?; )?;
let index = max_from.min(I::from(self.len())); let index = max_from.min(I::from(self.len()));
first_indexes.iter_from(index, |(index, first_index)| { first_indexes.iter_from(index, |(index, first_index, ..)| {
let last_index = last_indexes.read(index)?.unwrap(); let last_index = last_indexes.read(index)?.unwrap();
let count = *last_index + 1_usize - *first_index; let count = *last_index + 1_usize - *first_index;
self.push_and_flush_if_needed(index, count.into(), exit) self.push_and_flush_if_needed(index, count.into(), exit)