Compare commits

..

78 Commits

Author SHA1 Message Date
nym21 11911c1898 release: v0.0.83 2025-07-26 23:35:43 +02:00
nym21 4814c1971d vecs: add linux punch hole impl 2025-07-26 23:35:23 +02:00
nym21 be9569f3fb release: v0.0.82 2025-07-26 22:09:21 +02:00
nym21 900e72f95a cargo: cleanup deps 2025-07-26 14:28:26 +02:00
nym21 d2827f188b computer: temp remove rayon 2025-07-26 14:24:06 +02:00
nym21 cf9903b759 computer: init file with min length and regions 2025-07-26 08:57:13 +02:00
nym21 23f96461f4 computer: remove libc dep 2025-07-26 08:42:33 +02:00
nym21 9f2fd26e98 computer: fixes 2025-07-26 08:41:19 +02:00
nym21 78d837c080 computer: flush + punch 2025-07-26 01:04:36 +02:00
nym21 241b9312b7 cli: config changes 2025-07-26 00:46:35 +02:00
nym21 ed70ad7378 indexer: take readers before last export 2025-07-25 22:45:41 +02:00
nym21 00213176d8 indexer: small changes 2025-07-25 22:38:15 +02:00
nym21 406650a45a vec: removed 2025-07-25 20:38:57 +02:00
nym21 56750ccf3c vecs: part 11 2025-07-25 20:27:15 +02:00
nym21 dfc286b393 vecs: part 10 2025-07-25 20:22:54 +02:00
nym21 49a66f72fc crates: update rapidhash 2025-07-24 17:32:38 +02:00
nym21 3f237689da vecs: part 9 2025-07-24 17:19:05 +02:00
nym21 cf1fb483b3 vecs: part 8 2025-07-24 16:48:50 +02:00
nym21 b10f5e3f67 vecs: part 7 2025-07-23 23:55:13 +02:00
nym21 c4fc24c513 vecs: part 6 2025-07-23 09:17:26 +02:00
nym21 3ac9c2d95e vecs: part 5 2025-07-22 21:26:50 +02:00
nym21 e5ab4dafc0 vecs: part 4 2025-07-22 17:36:34 +02:00
nym21 10ae1911c3 vecs: part 3 2025-07-22 15:10:07 +02:00
nym21 73ebcdf0d6 vecs: part 2 2025-07-22 13:19:19 +02:00
nym21 5347523921 vecs: init 2025-07-21 11:02:25 +02:00
nym21 7ef70b953b vec: lazy: remove unneeded phantoms 2025-07-19 17:47:25 +02:00
nym21 ccaca524fe computer: libc sync 2025-07-19 10:10:01 +02:00
nym21 dd51f91cab computer: final fix for external disks crashing 2025-07-18 16:29:53 +02:00
nym21 537d98b41b release: v0.0.81 2025-07-17 23:45:01 +02:00
nym21 9c4cadfc04 vec: fix holes export 2025-07-17 17:29:53 +02:00
nym21 2001370441 mcp: use rust-rmcp instead of brk-rmcp 2025-07-17 16:34:29 +02:00
nym21 cc87b22757 computer: perf improvements 2025-07-17 16:17:21 +02:00
nym21 c0a65b30ad indexer: update example 2025-07-17 11:39:25 +02:00
nym21 c07e66c086 computer: fix stateful 2025-07-17 11:35:40 +02:00
nym21 a0cfc1be2b computer: convert stores to vecs part 2 2025-07-16 16:23:40 +02:00
nym21 1505454793 computer: convert stores to vecs part 1 2025-07-15 22:47:46 +02:00
nym21 e1dff66283 pr: merge #21 from deadmanoz/dockerize
Add Docker support
2025-07-15 15:51:32 +00:00
deadmanoz 5be801a086 Merge branch 'main' into dockerize 2025-07-15 08:50:22 -07:00
deadmanoz 94d4b05c29 Address review feedback 2025-07-15 08:48:39 -07:00
nym21 cebb889f7e cargo: update 2025-07-14 16:00:31 +02:00
nym21 c4ed6ed034 store: remove rotate_memtable as could be the root cause of the issue 2025-07-14 15:48:19 +02:00
nym21 ec960bfefa release: v0.0.80 2025-07-13 21:20:40 +02:00
nym21 79f689dde1 mcp: remove claude results examples due to dead links 2025-07-13 21:20:02 +02:00
nym21 3b3654df56 vec: add local and shared stored_len to raw variant 2025-07-13 19:30:50 +02:00
nym21 c66f008f07 release: v0.0.79 2025-07-13 17:18:14 +02:00
nym21 37d9498d90 crates: upgrade 2025-07-13 17:18:02 +02:00
nym21 1ff67093db website: apply datasets changes to charts 2025-07-13 17:14:34 +02:00
nym21 daed37ccb8 stores: forgot some files 2025-07-13 16:52:19 +02:00
nym21 d41d807b4f stores: bloom filters back to default due to slow reads, v3 will bring down the needed RAM 2025-07-13 16:49:45 +02:00
nym21 d6fa5c8a55 vec: fix header reading of existing file 2025-07-13 16:31:22 +02:00
nym21 2dd608dfed vec: don't store mmap in struct anymore 2025-07-13 11:50:34 +02:00
nym21 a98546f605 release: v0.0.78 2025-07-13 02:05:28 +02:00
nym21 3567559d4e release: v0.0.77 2025-07-13 01:54:51 +02:00
nym21 216476ee45 computer: reduce number of ratio datasets for some cohorts 2025-07-13 01:25:45 +02:00
nym21 3fc28c07fb computer: missed a file 2025-07-13 00:23:32 +02:00
nym21 85f6ef063d computer: perf again 2025-07-13 00:21:20 +02:00
nym21 1e71e2d68f computer: perf 2025-07-12 16:17:29 +02:00
nym21 b24a29895f global: perf + resource imprv 2025-07-12 15:07:02 +02:00
nym21 0167a2ae59 global: fixes 2025-07-12 11:18:51 +02:00
nym21 2c867103ca computer: remove dbg 2025-07-11 14:23:26 +02:00
nym21 8c289df336 computer: stateful: perf improvements 2025-07-11 11:43:53 +02:00
nym21 4489920cbf computer: fix coarse lazy indexes 2025-07-11 01:51:04 +02:00
nym21 029a85081b global: snapshot 2025-07-10 22:32:04 +02:00
nym21 1bc739d07f vec + comp: small changes 2025-07-10 18:35:54 +02:00
nym21 c229e218f6 global: adding semester + making coarser intervals computed instead of eager 2025-07-10 17:44:19 +02:00
nym21 a66f4ad4bd release: v0.0.76 2025-07-09 13:41:42 +02:00
nym21 1dd687dab7 bundler: upgrade rolldown dep 2025-07-09 13:41:31 +02:00
nym21 50ff6e2745 release: v0.0.75 2025-07-09 12:33:06 +02:00
nym21 811dec713b computer: reduce even more the number of par threads for compute_rest_part2 2025-07-09 12:32:50 +02:00
nym21 617d6f4bd7 release: v0.0.74 2025-07-09 11:51:24 +02:00
nym21 57cd2d6252 computer: fix par compute_rest_part2 crashing external drives 2025-07-09 11:48:41 +02:00
deadmanoz 5de9757d46 Remove services from docker 2025-07-04 16:37:39 +08:00
deadmanoz f89276d7b8 Remove redundant services 2025-07-04 15:51:28 +08:00
deadmanoz 30ba034206 Move docker artefacts into /docker directory 2025-07-04 13:00:12 +08:00
deadmanoz fa1e5aaa7f Make Parser::new the only entrypoint 2025-07-04 12:15:32 +08:00
deadmanoz 870c70180f Back to a single image/container setup 2025-07-04 11:40:37 +08:00
deadmanoz d83a833b4d Switch to multiple container setup 2025-06-27 12:56:25 +08:00
deadmanoz ec3a2f29f0 Docker functionality, change location of 'blk_index_to_blk_recap.json' 2025-06-27 12:56:03 +08:00
208 changed files with 13063 additions and 7855 deletions
+11
View File
@@ -18,3 +18,14 @@ _*
# Logs
.log
# Environment variables/configs
.env
# Profiling
profile.json.gz
flamegraph.svg
*.trace
# AI
CLAUDE.md
Generated
+229 -187
View File
@@ -144,12 +144,6 @@ dependencies = [
"derive_arbitrary",
]
[[package]]
name = "arc-swap"
version = "1.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457"
[[package]]
name = "arcstr"
version = "1.2.0"
@@ -170,9 +164,9 @@ checksum = "7c02d123df017efcdfbd739ef81735b36c5ba83ec3c59c80a9d7ecc718f92e50"
[[package]]
name = "async-compression"
version = "0.4.25"
version = "0.4.27"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4"
checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8"
dependencies = [
"brotli",
"flate2",
@@ -477,7 +471,7 @@ dependencies = [
[[package]]
name = "brk"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_bundler",
"brk_cli",
@@ -492,12 +486,12 @@ dependencies = [
"brk_parser",
"brk_server",
"brk_store",
"brk_vec",
"brk_vecs",
]
[[package]]
name = "brk_bundler"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_rolldown",
"log",
@@ -508,7 +502,7 @@ dependencies = [
[[package]]
name = "brk_cli"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"bitcoincore-rpc",
"brk_computer",
@@ -519,7 +513,7 @@ dependencies = [
"brk_logger",
"brk_parser",
"brk_server",
"brk_vec",
"brk_vecs",
"clap",
"clap_derive",
"color-eyre",
@@ -531,7 +525,7 @@ dependencies = [
[[package]]
name = "brk_computer"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"bincode",
"bitcoin",
@@ -542,12 +536,9 @@ dependencies = [
"brk_indexer",
"brk_logger",
"brk_parser",
"brk_store",
"brk_vec",
"brk_vecs",
"color-eyre",
"derive_deref",
"fjall",
"jiff",
"log",
"rayon",
"serde",
@@ -557,7 +548,7 @@ dependencies = [
[[package]]
name = "brk_core"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"bincode",
"bitcoin",
@@ -578,16 +569,17 @@ dependencies = [
[[package]]
name = "brk_exit"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_logger",
"ctrlc",
"log",
"parking_lot",
]
[[package]]
name = "brk_fetcher"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_core",
"brk_logger",
@@ -599,7 +591,7 @@ dependencies = [
[[package]]
name = "brk_indexer"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"bitcoin",
"bitcoincore-rpc",
@@ -608,7 +600,7 @@ dependencies = [
"brk_logger",
"brk_parser",
"brk_store",
"brk_vec",
"brk_vecs",
"color-eyre",
"fjall",
"log",
@@ -617,15 +609,15 @@ dependencies = [
[[package]]
name = "brk_interface"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_computer",
"brk_core",
"brk_indexer",
"brk_rmcp",
"brk_vec",
"brk_vecs",
"color-eyre",
"derive_deref",
"rmcp",
"schemars 1.0.4",
"serde",
"serde_json",
@@ -635,7 +627,7 @@ dependencies = [
[[package]]
name = "brk_logger"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"color-eyre",
"env_logger",
@@ -645,17 +637,17 @@ dependencies = [
[[package]]
name = "brk_mcp"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"axum",
"brk_interface",
"brk_rmcp",
"log",
"rmcp",
]
[[package]]
name = "brk_parser"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"bitcoin",
"bitcoincore-rpc",
@@ -668,54 +660,11 @@ dependencies = [
"zerocopy",
]
[[package]]
name = "brk_rmcp"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0dde96460b07f97f8522cef62fa5e9d5271a5183b13e6d75379ab43c1fb0b106"
dependencies = [
"base64 0.22.1",
"brk_rmcp-macros",
"bytes",
"chrono",
"futures",
"http",
"http-body",
"http-body-util",
"paste",
"pin-project-lite",
"rand 0.9.1",
"schemars 1.0.4",
"serde",
"serde_json",
"sse-stream",
"thiserror 2.0.12",
"tokio",
"tokio-stream",
"tokio-util",
"tower-service",
"tracing",
"uuid",
]
[[package]]
name = "brk_rmcp-macros"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48a3cb1aadff2f3aaaed76d17e71d6b828cafbd3fe9fbaba07d31b8ed10e63c2"
dependencies = [
"darling",
"proc-macro2",
"quote",
"serde_json",
"syn 2.0.104",
]
[[package]]
name = "brk_rolldown"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2d183b16c52419ff7fb0f6f83fa06e125f7c9ec9ce7867b8d11de569adcebde8"
checksum = "e84c9b257b6d6e15e6598f320fbe6dcc8615827dbd207aa73378a86723485e9f"
dependencies = [
"anyhow",
"append-only-vec",
@@ -760,9 +709,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_common"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b3ebe13a90609e4b5f10db4aa5656994b6a6f3e00e15bcba080a7d99059e8fe0"
checksum = "ca6da445ded7b4b07e9b48fd1855091ca87ee83777ae49326644019c0255278b"
dependencies = [
"anyhow",
"arcstr",
@@ -793,9 +742,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_debug"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7339046fd38b2727597b407577f872540d5283a5431b066f603f8113b5be155f"
checksum = "a554a589c6027241dc5735ed2f9387ca4e6771b5a3c68b974b086cde857475a9"
dependencies = [
"blake3",
"brk_rolldown_debug_action",
@@ -809,9 +758,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_debug_action"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "255823c7e4d226c20cb51b467462023514f63202cf81da64a7ffaebe16696ab3"
checksum = "4f0f12e60c7f66ff8efe64dfb47da84ce6216e9c969442f70fb0edf4f3d7d5d1"
dependencies = [
"serde",
"ts-rs",
@@ -819,9 +768,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_ecmascript"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f598679b4c80d73830682acdc3346cf31200fc05c9dc4c3488b05760c7f211d"
checksum = "d0e6d41996222d97ada7efb7f00be28becae01fd6dd68ced9b2d659f9811f3ff"
dependencies = [
"arcstr",
"brk_rolldown_error",
@@ -832,9 +781,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_ecmascript_utils"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a529bbaaf1850e8694ebaf752a3a0e7119de1bf40425d44935de6bdf7a75041a"
checksum = "43216eb0cd76628bfc878a34c26f8deaba7f1ab2a3afed3912670c53eae67c25"
dependencies = [
"brk_rolldown_common",
"oxc",
@@ -843,9 +792,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_error"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "52d474d15e41f5fed2e5edead30b0fe25d1bfb6591d49e2b3d7a8509c328a6bd"
checksum = "744db025ff88c465df4d4faed5e3c8f3ef91ae9b3183bbc80c62d41dc636c4f5"
dependencies = [
"anyhow",
"arcstr",
@@ -863,9 +812,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_fs"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2a5882bedde49617620fb7f805ba5f97e98d835cd5010d87e6d1eaee3a632c8"
checksum = "9c38de0fd6c358c873e4a70e0054b65b6e08262f0676c47394c4f9f392f11c42"
dependencies = [
"oxc_resolver",
"vfs",
@@ -873,9 +822,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_plugin"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4070a9556dff16f432862c418d59ca117a67a76220f0a0e7a5d2302860a4ae8d"
checksum = "66b3739b2e98ee755130b5d624135d2a8623051341a1b942ac1aed4fe65d5a95"
dependencies = [
"anyhow",
"arcstr",
@@ -903,9 +852,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_plugin_data_uri"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b56d0794cde76a0aeb8e9719c8f6a898a6ae261c4b23baf936517b46a8f28a25"
checksum = "36f094093ec33d62c17012772db763bd1f3b9d8ee5bcbc374e6f8e9d66555279"
dependencies = [
"arcstr",
"base64-simd",
@@ -917,9 +866,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_plugin_hmr"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "18123805fe6655cfa5cf1f3a00dbd453ce0ab4021585a1dceb148dc72fcbc115"
checksum = "37ed61d459d0aa300b568ac2cf2153c7c4e5c510f901b9efce744f0d5134cc7f"
dependencies = [
"arcstr",
"brk_rolldown_common",
@@ -929,9 +878,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_resolver"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f101abf724d5eafd4dafa54d5f6b837ecaabf97a3480cb0433687456970b5d73"
checksum = "65ae763e1c514bcfec0dd87be351f5000658feb0e4b1bcb5f199c60e6cbe7150"
dependencies = [
"arcstr",
"brk_rolldown_common",
@@ -945,18 +894,18 @@ dependencies = [
[[package]]
name = "brk_rolldown_rstr"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8f7364e946414a025a72bb42e19840d25f0d0b456cc57e9c367a996079b40ba2"
checksum = "a251b8c38c8b6c177319a5d1f1fb609a120f35e73a52af575792f94dfd42fd1a"
dependencies = [
"oxc",
]
[[package]]
name = "brk_rolldown_sourcemap"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "be25fa71e8ede71edeb4261ac3f1588b66b6f1a44ea7be172c3d3870f27ec9de"
checksum = "a5465d4ebe0e0801f163d19779bf9858051aff2c291efc64fa6dde83d2e3238d"
dependencies = [
"brk_rolldown_utils",
"memchr",
@@ -967,18 +916,18 @@ dependencies = [
[[package]]
name = "brk_rolldown_std_utils"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d49fde6b6ae1ac6ef1936f35f3414caff18caed00e82b25ed0beae92f1073ef0"
checksum = "50a28045a4b7ec4c5f8ff06a170d21e0c9a1d41e2baecc8348241f4d3d69a165"
dependencies = [
"regex",
]
[[package]]
name = "brk_rolldown_tracing"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5370886723348f90cd2b1b771feaba03e0ac18c97ea142a1a266b2bd38ce5a58"
checksum = "35845acebabca843c6b2c3e1928c393c588ff0ba4bb4bcfcd571c1cc11b13d89"
dependencies = [
"tracing",
"tracing-chrome",
@@ -987,9 +936,9 @@ dependencies = [
[[package]]
name = "brk_rolldown_utils"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "da6270ab2386f2c0669c37a13d099a0b8700c00fc3495de16fa04498d8d37a98"
checksum = "22e3b2a75f83b012138bc63c16e238dfebd9484f99fb77a35fe96a10ff6ef437"
dependencies = [
"anyhow",
"arcstr",
@@ -1024,7 +973,7 @@ dependencies = [
[[package]]
name = "brk_server"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"axum",
"bitcoincore-rpc",
@@ -1038,7 +987,7 @@ dependencies = [
"brk_logger",
"brk_mcp",
"brk_parser",
"brk_vec",
"brk_vecs",
"clap",
"clap_derive",
"color-eyre",
@@ -1046,6 +995,7 @@ dependencies = [
"log",
"minreq",
"serde",
"serde_json",
"tokio",
"tower-http",
"tracing",
@@ -1054,7 +1004,7 @@ dependencies = [
[[package]]
name = "brk_store"
version = "0.0.73"
version = "0.0.83"
dependencies = [
"brk_core",
"byteview",
@@ -1064,9 +1014,9 @@ dependencies = [
[[package]]
name = "brk_string_wizard"
version = "0.1.0"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "66e8cc17586b31359186c2f3c2faa30c4f9fb02dc4594ed903a64b86596955bb"
checksum = "a3e6948e03baceed9fc3e8b3274bf9fefdf56bcdd517a6ff4ecf1843a59178f7"
dependencies = [
"oxc_index",
"oxc_sourcemap",
@@ -1075,16 +1025,17 @@ dependencies = [
]
[[package]]
name = "brk_vec"
version = "0.0.73"
name = "brk_vecs"
version = "0.0.83"
dependencies = [
"arc-swap",
"brk_core",
"brk_exit",
"clap",
"clap_derive",
"libc",
"log",
"memmap2",
"parking_lot",
"rayon",
"serde",
"serde_json",
@@ -1149,37 +1100,27 @@ checksum = "6236364b88b9b6d0bc181ba374cf1ab55ba3ef97a1cb6f8cddad48a273767fb5"
[[package]]
name = "bzip2"
version = "0.5.2"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "49ecfb22d906f800d4fe833b6282cf4dc1c298f5057ca0b5445e5c209735ca47"
checksum = "bea8dcd42434048e4f7a304411d9273a411f647446c1234a65ce0554923f4cff"
dependencies = [
"bzip2-sys",
]
[[package]]
name = "bzip2-sys"
version = "0.1.13+1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "225bff33b2141874fe80d71e07d6eec4f85c5c216453dd96388240f96e1acc14"
dependencies = [
"cc",
"pkg-config",
"libbz2-rs-sys",
]
[[package]]
name = "castaway"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0abae9be0aaf9ea96a3b1b8b1b55c602ca751eba1b1500220cea4ecbafe7c0d5"
checksum = "dec551ab6e7578819132c713a93c022a05d60159dc86e7a7050223577484c55a"
dependencies = [
"rustversion",
]
[[package]]
name = "cc"
version = "1.2.29"
version = "1.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c1599538de2394445747c8cf7935946e3cc27e9625f889d979bfb2aaf569362"
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
dependencies = [
"jobserver",
"libc",
@@ -1236,18 +1177,18 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f"
checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e"
checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d"
dependencies = [
"anstream",
"anstyle",
@@ -1257,9 +1198,9 @@ dependencies = [
[[package]]
name = "clap_derive"
version = "4.5.40"
version = "4.5.41"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce"
checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491"
dependencies = [
"heck",
"proc-macro2",
@@ -1380,9 +1321,9 @@ dependencies = [
[[package]]
name = "crc32fast"
version = "1.4.2"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3"
checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511"
dependencies = [
"cfg-if",
]
@@ -1488,8 +1429,18 @@ version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee"
dependencies = [
"darling_core",
"darling_macro",
"darling_core 0.20.11",
"darling_macro 0.20.11",
]
[[package]]
name = "darling"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a79c4acb1fd5fa3d9304be4c76e031c54d2e92d172a393e24b19a14fe8532fe9"
dependencies = [
"darling_core 0.21.0",
"darling_macro 0.21.0",
]
[[package]]
@@ -1506,13 +1457,38 @@ dependencies = [
"syn 2.0.104",
]
[[package]]
name = "darling_core"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74875de90daf30eb59609910b84d4d368103aaec4c924824c6799b28f77d6a1d"
dependencies = [
"fnv",
"ident_case",
"proc-macro2",
"quote",
"strsim",
"syn 2.0.104",
]
[[package]]
name = "darling_macro"
version = "0.20.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead"
dependencies = [
"darling_core",
"darling_core 0.20.11",
"quote",
"syn 2.0.104",
]
[[package]]
name = "darling_macro"
version = "0.21.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e79f8e61677d5df9167cd85265f8e5f64b215cdea3fb55eebc3e622e44c7a146"
dependencies = [
"darling_core 0.21.0",
"quote",
"syn 2.0.104",
]
@@ -1738,9 +1714,9 @@ checksum = "1d674e81391d1e1ab681a28d99df07927c6d4aa5b027d7da16ba32d1d21ecd99"
[[package]]
name = "fjall"
version = "2.11.1"
version = "2.11.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f5cb653019268f6dc8de3b254b633a2d233a775054349b804b9cfbf18bbe3426"
checksum = "0b25ad44cd4360a0448a9b5a0a6f1c7a621101cca4578706d43c9a821418aebc"
dependencies = [
"byteorder",
"byteview",
@@ -1911,11 +1887,9 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "26145e563e54f2cadc477553f1ec5ee650b00862f0a58bcd12cbdc5f0ea2d2f4"
dependencies = [
"cfg-if",
"js-sys",
"libc",
"r-efi",
"wasi 0.14.2+wasi-0.2.4",
"wasm-bindgen",
]
[[package]]
@@ -2056,9 +2030,9 @@ dependencies = [
[[package]]
name = "hyper-util"
version = "0.1.15"
version = "0.1.16"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f66d5bd4c6f02bf0542fad85d626775bab9258cf795a4256dcaf3161114d1df"
checksum = "8d9b05277c7e8da2c93a568989bb6207bef0112e8d17df7a6eda4a3cf143bc5e"
dependencies = [
"bytes",
"futures-core",
@@ -2177,9 +2151,9 @@ dependencies = [
[[package]]
name = "io-uring"
version = "0.7.8"
version = "0.7.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b86e202f00093dcba4275d4636b93ef9dd75d025ae560d2521b45ea28ab49013"
checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4"
dependencies = [
"bitflags 2.9.1",
"cfg-if",
@@ -2315,6 +2289,12 @@ version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
[[package]]
name = "libbz2-rs-sys"
version = "0.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "775bf80d5878ab7c2b1080b5351a48b2f737d9f6f8b383574eebcc22be0dfccb"
[[package]]
name = "libc"
version = "0.2.174"
@@ -2343,9 +2323,9 @@ dependencies = [
[[package]]
name = "libredox"
version = "0.1.4"
version = "0.1.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1580801010e535496706ba011c15f8532df6b42297d2e471fec38ceadd8c0638"
checksum = "4488594b9328dee448adb906d8b126d9b7deb7cf5c22161ee591610bb1be83c0"
dependencies = [
"bitflags 2.9.1",
"libc",
@@ -2385,9 +2365,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "lsm-tree"
version = "2.10.1"
version = "2.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1d2bd4cdc451a8dcf11329190afb9b78eb8988bed07a3da29b8d73d2e0c731ff"
checksum = "55b6d7475a8dd22e749186968daacf8e2a77932b061b1bd263157987bbfc0c6c"
dependencies = [
"byteorder",
"crossbeam-skiplist",
@@ -2436,9 +2416,9 @@ checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "memmap2"
version = "0.9.5"
version = "0.9.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd3f7eed9d3848f8b98834af67102b720745c4ec028fcd0aa0239277e7de374f"
checksum = "483758ad303d734cec05e5c12b41d7e93e6a6390c5e9dae6bdeb7c1259012d28"
dependencies = [
"libc",
]
@@ -2653,10 +2633,11 @@ dependencies = [
[[package]]
name = "oxc-browserslist"
version = "2.0.9"
version = "2.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5b4d0b44c7165e123b48802d48ca15cfa510584014e4751956ba7fc26c1f2800"
checksum = "20605046d78dbba8ed6c1c10b5ee21a83d265825943bce8bc40d17b4c48d5aca"
dependencies = [
"bincode",
"nom",
"rustc-hash",
"serde",
@@ -3117,6 +3098,16 @@ dependencies = [
"unicode-width",
]
[[package]]
name = "parking_lot"
version = "0.12.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "70d58bf43669b5795d1576d0641cfb6fbb2057bf629506267a92807158584a13"
dependencies = [
"lock_api",
"parking_lot_core",
]
[[package]]
name = "parking_lot_core"
version = "0.9.11"
@@ -3316,6 +3307,12 @@ version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391"
[[package]]
name = "ppmd-rust"
version = "1.2.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c834641d8ad1b348c9ee86dec3b9840d805acd5f24daa5f90c788951a52ff59b"
[[package]]
name = "ppv-lite86"
version = "0.2.21"
@@ -3358,9 +3355,9 @@ dependencies = [
[[package]]
name = "quick_cache"
version = "0.6.14"
version = "0.6.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b450dad8382b1b95061d5ca1eb792081fb082adf48c678791fe917509596d5f"
checksum = "8565e62e02af316570d4b492f17af1481d6c07cea60f4e7edd71700da5052ba9"
dependencies = [
"equivalent",
"hashbrown 0.15.4",
@@ -3404,9 +3401,9 @@ dependencies = [
[[package]]
name = "rand"
version = "0.9.1"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97"
checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1"
dependencies = [
"rand_chacha 0.9.0",
"rand_core 0.9.3",
@@ -3452,9 +3449,9 @@ dependencies = [
[[package]]
name = "rapidhash"
version = "1.4.0"
version = "2.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9813f789f95ee4fe6b4d01834404d7cccacbc3f6c029343af910b3c2835eb9f1"
checksum = "2297bf4643b32dc85bf5f622c9a41a268db6c6a6a2a2e3b405958a5b014ad9e1"
[[package]]
name = "rayon"
@@ -3478,9 +3475,9 @@ dependencies = [
[[package]]
name = "redox_syscall"
version = "0.5.13"
version = "0.5.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6"
checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec"
dependencies = [
"bitflags 2.9.1",
]
@@ -3551,9 +3548,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
[[package]]
name = "regress"
version = "0.10.3"
version = "0.10.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ef7fa9ed0256d64a688a3747d0fef7a88851c18a5e1d57f115f38ec2e09366"
checksum = "145bb27393fe455dd64d6cbc8d059adfa392590a45eadf079c01b11857e7b010"
dependencies = [
"hashbrown 0.15.4",
"memchr",
@@ -3582,6 +3579,49 @@ dependencies = [
"libc",
]
[[package]]
name = "rmcp"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b008b927a85d514699ff304be84c5084598596e6cad4a6f5bc67207715fafe5f"
dependencies = [
"base64 0.22.1",
"bytes",
"chrono",
"futures",
"http",
"http-body",
"http-body-util",
"paste",
"pin-project-lite",
"rand 0.9.2",
"rmcp-macros",
"schemars 1.0.4",
"serde",
"serde_json",
"sse-stream",
"thiserror 2.0.12",
"tokio",
"tokio-stream",
"tokio-util",
"tower-service",
"tracing",
"uuid",
]
[[package]]
name = "rmcp-macros"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7465280d5f73f2c5c99017a04af407b2262455a149f255ad22f2b0b29087695c"
dependencies = [
"darling 0.21.0",
"proc-macro2",
"quote",
"serde_json",
"syn 2.0.104",
]
[[package]]
name = "rolldown-ariadne"
version = "0.5.2"
@@ -3616,15 +3656,15 @@ checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d"
[[package]]
name = "rustix"
version = "1.0.7"
version = "1.0.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266"
checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8"
dependencies = [
"bitflags 2.9.1",
"errno",
"libc",
"linux-raw-sys",
"windows-sys 0.59.0",
"windows-sys 0.60.2",
]
[[package]]
@@ -3694,6 +3734,7 @@ version = "1.0.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "82d20c4491bc164fa2f6c5d44565947a52ad80b9505d8e36f8d54c27c739fcd0"
dependencies = [
"chrono",
"dyn-clone",
"ref-cast",
"schemars_derive",
@@ -3814,9 +3855,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.140"
version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
"indexmap 2.10.0",
"itoa",
@@ -3882,7 +3923,7 @@ version = "3.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "de90945e6565ce0d9a25098082ed4ee4002e047cb59892c318d66821e14bb30f"
dependencies = [
"darling",
"darling 0.20.11",
"proc-macro2",
"quote",
"syn 2.0.104",
@@ -4238,9 +4279,9 @@ dependencies = [
[[package]]
name = "toml"
version = "0.9.0"
version = "0.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f271e09bde39ab52250160a67e88577e0559ad77e9085de6e9051a2c4353f8f8"
checksum = "ed0aee96c12fa71097902e0bb061a5e1ebd766a6636bb605ba401c45c1650eac"
dependencies = [
"indexmap 2.10.0",
"serde",
@@ -4262,18 +4303,18 @@ dependencies = [
[[package]]
name = "toml_parser"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b5c1c469eda89749d2230d8156a5969a69ffe0d6d01200581cdc6110674d293e"
checksum = "97200572db069e74c512a14117b296ba0a80a30123fbbb5aa1f4a348f639ca30"
dependencies = [
"winnow",
]
[[package]]
name = "toml_writer"
version = "1.0.0"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b679217f2848de74cabd3e8fc5e6d66f40b7da40f8e1954d92054d9010690fd5"
checksum = "fcc842091f2def52017664b53082ecbbeb5c7731092bad69d2c63050401dfd64"
[[package]]
name = "tower"
@@ -4572,9 +4613,9 @@ checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
[[package]]
name = "vfs"
version = "0.12.1"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ec343ec20aa715908fd028a4b8e7c99a349d13143224222e4d61c316d1e7f0a"
checksum = "9e723b9e1c02a3cf9f9d0de6a4ddb8cdc1df859078902fe0ae0589d615711ae6"
dependencies = [
"filetime",
]
@@ -4927,9 +4968,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486"
[[package]]
name = "winnow"
version = "0.7.11"
version = "0.7.12"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd"
checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95"
[[package]]
name = "wit-bindgen-rt"
@@ -4994,9 +5035,9 @@ dependencies = [
[[package]]
name = "zip"
version = "4.2.0"
version = "4.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "95ab361742de920c5535880f89bbd611ee62002bf11341d16a5f057bb8ba6899"
checksum = "9aed4ac33e8eb078c89e6cbb1d5c4c7703ec6d299fc3e7c3695af8f8b423468b"
dependencies = [
"aes",
"arbitrary",
@@ -5011,6 +5052,7 @@ dependencies = [
"liblzma",
"memchr",
"pbkdf2",
"ppmd-rust",
"sha1",
"time",
"zeroize",
+26 -22
View File
@@ -4,9 +4,10 @@ members = ["crates/*"]
package.description = "The Bitcoin Research Kit is a suite of tools designed to extract, compute and display data stored on a Bitcoin Core node"
package.license = "MIT"
package.edition = "2024"
package.version = "0.0.73"
package.version = "0.0.83"
package.homepage = "https://bitcoinresearchkit.org"
package.repository = "https://github.com/bitcoinresearchkit/brk"
package.readme = "README.md"
[profile.release]
lto = "fat"
@@ -21,42 +22,45 @@ debug = true
inherits = "release"
[workspace.dependencies]
arc-swap = "1.7.1"
axum = "0.8.4"
bincode = { version = "2.0.1", features = ["serde"] }
bitcoin = { version = "0.32.6", features = ["serde"] }
bitcoincore-rpc = "0.19.0"
brk_bundler = { version = "0.0.73", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.73", path = "crates/brk_cli" }
brk_computer = { version = "0.0.73", path = "crates/brk_computer" }
brk_core = { version = "0.0.73", path = "crates/brk_core" }
brk_exit = { version = "0.0.73", path = "crates/brk_exit" }
brk_fetcher = { version = "0.0.73", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.73", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.73", path = "crates/brk_interface" }
brk_logger = { version = "0.0.73", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.73", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.73", path = "crates/brk_parser" }
brk_rmcp = { version = "0.2.1", features = ["transport-streamable-http-server", "transport-worker"]}
# brk_rmcp = { path = "../rust-sdk/crates/rmcp", features = ["transport-streamable-http-server", "transport-worker"]}
brk_server = { version = "0.0.73", path = "crates/brk_server" }
brk_store = { version = "0.0.73", path = "crates/brk_store" }
brk_vec = { version = "0.0.73", path = "crates/brk_vec" }
brk_bundler = { version = "0.0.83", path = "crates/brk_bundler" }
brk_cli = { version = "0.0.83", path = "crates/brk_cli" }
brk_computer = { version = "0.0.83", path = "crates/brk_computer" }
brk_core = { version = "0.0.83", path = "crates/brk_core" }
brk_exit = { version = "0.0.83", path = "crates/brk_exit" }
brk_fetcher = { version = "0.0.83", path = "crates/brk_fetcher" }
brk_indexer = { version = "0.0.83", path = "crates/brk_indexer" }
brk_interface = { version = "0.0.83", path = "crates/brk_interface" }
brk_logger = { version = "0.0.83", path = "crates/brk_logger" }
brk_mcp = { version = "0.0.83", path = "crates/brk_mcp" }
brk_parser = { version = "0.0.83", path = "crates/brk_parser" }
brk_server = { version = "0.0.83", path = "crates/brk_server" }
brk_store = { version = "0.0.83", path = "crates/brk_store" }
brk_vecs = { version = "0.0.83", path = "crates/brk_vecs" }
byteview = "=0.6.1"
clap = { version = "4.5.40", features = ["string"] }
clap_derive = "4.5.40"
clap = { version = "4.5.41", features = ["string"] }
clap_derive = "4.5.41"
color-eyre = "0.6.5"
derive_deref = "1.1.1"
fjall = "2.11.1"
fjall = "2.11.2"
jiff = "0.2.15"
libc = "0.2.174"
log = { version = "0.4.27" }
minreq = { version = "2.14.0", features = ["https", "serde_json"] }
parking_lot = "0.12.4"
rayon = "1.10.0"
rmcp = { version = "0.3.0", features = [
"transport-worker",
"transport-streamable-http-server",
] }
schemars = "1.0.4"
serde = { version = "1.0.219" }
serde_bytes = "0.11.17"
serde_derive = "1.0.219"
serde_json = { version = "1.0.140", features = ["float_roundtrip"] }
serde_json = { version = "1.0.141", features = ["float_roundtrip"] }
tabled = "0.20.0"
tokio = { version = "1.46.1", features = ["rt-multi-thread"] }
zerocopy = { version = "0.8.26" }
+3 -4
View File
@@ -40,14 +40,13 @@ The toolkit can be used in various ways to accommodate as many needs as possible
- **[Website](https://bitcoinresearchkit.org)** \
Everyone is welcome to visit the official instance and showcase of the suite's capabilities. \
It has a wide range of functionalities including charts, tables and simulations which you can visit for free and without the need for an account. \
Also available at: [kibo.money](https://kibo.money) // [satonomics.xyz](https://satonomics.xyz)
Also available at: [brekit.org](https://brekit.org) // [kibo.money](https://kibo.money) // [satonomics.xyz](https://satonomics.xyz)
- **[API](https://github.com/bitcoinresearchkit/brk/tree/main/crates/brk_server#brk-server)** \
Researchers and developers are free to use BRK's public API with ![Datasets variant count](https://img.shields.io/badge/dynamic/json?url=https%3A%2F%2Fbitcoinresearchkit.org%2Fapi%2Fvecs%2Fvec-count&query=%24&style=flat&label=%20&color=white) dataset variants at their disposal. \
Just like the website, it's entirely free, with no authentication or rate-limiting.
- **[AI](https://github.com/bitcoinresearchkit/brk/blob/main/crates/brk_mcp/README.md#brk-mcp)** \
LLMs have to possibility to connect to BRK's backend through a [MCP](https://modelcontextprotocol.io/introduction). \
It will give them access to the same tools as the API, with no restrictions, and allow you to have your very own data analysts. \
One-shot output examples: [Document](https://claude.ai/public/artifacts/71194d29-f965-417c-ba09-fdf0e4ecb1d5) // [Dashboard](https://claude.ai/public/artifacts/beef143f-399a-4ed4-b8bf-c986b776de42) // [Dashboard 2](https://claude.ai/public/artifacts/5430ae49-bb3d-4fc1-ab24-f1e33deb40dc)
It will give them access to the same tools as the API, with no restrictions, and allow you to have your very own data analysts.
- **[CLI](https://crates.io/crates/brk_cli)** \
Node runners are strongly encouraged to try out and self-host their own instance using BRK's command line interface. \
The CLI has multiple cogs available for users to tweak to adapt to all situations with even the possibility for web developers to create their own custom website which could later on be added as an alternative front-end.
@@ -74,7 +73,7 @@ In contrast, existing alternatives tend to be either [very costly](https://studi
- [`brk_interface`](https://crates.io/crates/brk_interface): An interface to BRK's engine
- [`brk_server`](https://crates.io/crates/brk_server): A server that serves Bitcoin data and swappable front-ends, built on top of `brk_indexer`, `brk_fetcher` and `brk_computer`
- [`brk_store`](https://crates.io/crates/brk_store): A thin wrapper around [`fjall`](https://crates.io/crates/fjall)
- [`brk_vec`](https://crates.io/crates/brk_vec): A push-only, truncable, compressable, saveable Vec
- [`brk_vec`](https://crates.io/crates/brk_vec): A storeable vec
- [`brk_bundler`](https://crates.io/crates/brk_bundler): A thin wrapper around [`rolldown`](https://rolldown.rs/)
## Hosting as a service
+14 -2
View File
@@ -10,21 +10,30 @@
- pull latest version and notify is out of date
- _computer_
- **add rollback of states (in stateful)**
- remove configurable format (raw/compressed) and chose sane ones instead
- linear reads: compressed (height/date/... + txindex_to_height + txindex_to_version + ...)
- random reads: raw (outputindex_to_value + ...)
- add prices paid by percentile (percentile cost basis) back
- add support for per index computation
- fix feerate which is always ZERO due to coinbase transaction
- fix min feerate which is always ZERO due to coinbase transaction
- before computing multiple sources check their length, panic if not equal
- add oracle price dataset (https://utxo.live/oracle/UTXOracle.py)
- add address counts relative to all datasets
- make decade, quarter, year datasets `computed` instead of `eager`
- add 6 months (semester) interval datasets to builder
- some datasets in `indexes` can probably be removed
- add revived/sent supply datasets
- add `in-sats` version of all price datasets (average and co)
- add `p2pk` group (sum of `p2pk33` and `p2pk65`)
- add chopiness datasets
- add utxo count, address count, supply data for by reused addresses in groups by address type
- add more date ranges (3-6 months and more)
- add puell multiple dataset
- add pi cycle dataset
- add ema of price
- add emas of price
- add 7d and 30d ema to sell side risk ratio and sopr
- don't compute everything for all cohorts as some datasets combinations are irrelevant
- addresses/utxos by amount don't need mvrvz for example
- add all possible charts from:
- https://mainnet.observer
- https://glassnode.com
@@ -50,6 +59,8 @@
- api
- add extensions support (.json .csv …)
- if format instead of extension then don't download file
- add support for https (rustls)
- lru cache
- _vec_
- add native lock file support (once it's available in stable rust)
- improve compressed mode (slow reads)
@@ -73,6 +84,7 @@
- remove `sum` series when it's a duplicate of the `base` (in subsidy for example)
- selected unit sometimes changes when going back end forth
- add support for custom charts
- separate z-score charts from "realized price" (with their own prices), have 4y, 2y and 1y
- price scale format depends on unit, hide digits for sats for example (if/when possible)
- table
- pagination
-2
View File
@@ -1,2 +0,0 @@
profile.json.gz
flamegraph.svg
+3 -3
View File
@@ -22,7 +22,7 @@ full = [
"interface",
"server",
"store",
"vec",
"vecs",
]
bundler = ["brk_bundler"]
core = ["brk_core"]
@@ -36,7 +36,7 @@ parser = ["brk_parser"]
interface = ["brk_interface"]
server = ["brk_server"]
store = ["brk_store"]
vec = ["brk_vec"]
vecs = ["brk_vecs"]
[dependencies]
brk_bundler = { workspace = true, optional = true }
@@ -52,7 +52,7 @@ brk_parser = { workspace = true, optional = true }
brk_interface = { workspace = true, optional = true }
brk_server = { workspace = true, optional = true }
brk_store = { workspace = true, optional = true }
brk_vec = { workspace = true, optional = true }
brk_vecs = { workspace = true, optional = true }
[package.metadata.docs.rs]
all-features = true
+1 -2
View File
@@ -1,2 +1 @@
cargo build --profile profiling
flamegraph -- ../../target/profiling/brk
sudo cargo flamegraph --profile profiling --root
+2 -2
View File
@@ -51,6 +51,6 @@ pub use brk_server as server;
#[doc(inline)]
pub use brk_store as store;
#[cfg(feature = "vec")]
#[cfg(feature = "vecs")]
#[doc(inline)]
pub use brk_vec as vec;
pub use brk_vecs as vecs;
+1 -1
View File
@@ -10,7 +10,7 @@ repository.workspace = true
[dependencies]
log = { workspace = true }
notify = "8.1.0"
brk_rolldown = "0.1.0"
brk_rolldown = "0.1.1"
# brk_rolldown = { path = "../../../rolldown/crates/rolldown"}
sugar_path = "1.2.0"
tokio = { workspace = true }
+2 -2
View File
@@ -17,14 +17,14 @@ brk_indexer = { workspace = true }
brk_logger = { workspace = true }
brk_parser = { workspace = true }
brk_server = { workspace = true }
brk_vec = { workspace = true }
brk_vecs = { workspace = true }
clap = { workspace = true }
clap_derive = { workspace = true }
color-eyre = { workspace = true }
log = { workspace = true }
serde = { workspace = true }
tokio = { workspace = true }
toml = "0.9.0"
toml = "0.9.2"
[[bin]]
name = "brk"
+2 -27
View File
@@ -7,14 +7,12 @@ use bitcoincore_rpc::{self, Auth, Client};
use brk_core::{default_bitcoin_path, default_brk_path, default_on_error, dot_brk_path};
use brk_fetcher::Fetcher;
use brk_server::Website;
use brk_vec::{Computation, Format};
use brk_vecs::{Computation, Format};
use clap::Parser;
use clap_derive::Parser;
use color_eyre::eyre::eyre;
use serde::{Deserialize, Serialize};
use crate::services::Services;
#[derive(Parser, Debug, Default, PartialEq, Eq, PartialOrd, Ord, Deserialize, Serialize)]
#[command(version, about)]
pub struct Config {
@@ -33,11 +31,6 @@ pub struct Config {
#[arg(long, value_name = "PATH")]
brkdir: Option<String>,
/// Activated services, default: all, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(short, long)]
services: Option<Services>,
/// Computation of computed datasets, `lazy` computes data whenever requested without saving it, `eager` computes the data once and saves it to disk, default: `lazy`, saved
#[serde(default, deserialize_with = "default_on_error")]
#[arg(short, long)]
@@ -129,10 +122,6 @@ impl Config {
config_saved.brkdir = Some(brkdir);
}
if let Some(services) = config_args.services.take() {
config_saved.services = Some(services);
}
if let Some(computation) = config_args.computation.take() {
config_saved.computation = Some(computation);
}
@@ -298,22 +287,8 @@ impl Config {
.map_or_else(default_brk_path, |s| Self::fix_user_path(s.as_ref()))
}
pub fn outputsdir(&self) -> PathBuf {
self.brkdir().join("outputs")
}
pub fn harsdir(&self) -> PathBuf {
self.outputsdir().join("hars")
}
pub fn process(&self) -> bool {
self.services
.is_none_or(|m| m == Services::All || m == Services::Processor)
}
pub fn serve(&self) -> bool {
self.services
.is_none_or(|m| m == Services::All || m == Services::Server)
self.brkdir().join("hars")
}
fn path_cookiefile(&self) -> PathBuf {
+2 -1
View File
@@ -1,10 +1,11 @@
#![doc = include_str!("../README.md")]
use std::{fs, thread};
use brk_core::{dot_brk_log_path, dot_brk_path};
mod config;
mod run;
mod services;
use run::*;
+27 -42
View File
@@ -13,18 +13,16 @@ pub fn run() -> color_eyre::Result<()> {
let config = Config::import()?;
let rpc = config.rpc()?;
let exit = Exit::new();
let parser = brk_parser::Parser::new(config.blocksdir(), rpc);
let parser = brk_parser::Parser::new(config.blocksdir(), config.brkdir(), rpc);
let format = config.format();
let mut indexer = Indexer::forced_import(&config.outputsdir())?;
let mut indexer = Indexer::forced_import(&config.brkdir())?;
let wait_for_synced_node = || -> color_eyre::Result<()> {
let wait_for_synced_node = |rpc_client: &bitcoincore_rpc::Client| -> color_eyre::Result<()> {
let is_synced = || -> color_eyre::Result<bool> {
let info = rpc.get_blockchain_info()?;
let info = rpc_client.get_blockchain_info()?;
Ok(info.headers == info.blocks)
};
@@ -39,7 +37,7 @@ pub fn run() -> color_eyre::Result<()> {
};
let mut computer = Computer::forced_import(
&config.outputsdir(),
&config.brkdir(),
&indexer,
config.computation(),
config.fetcher(),
@@ -50,54 +48,41 @@ pub fn run() -> color_eyre::Result<()> {
.enable_all()
.build()?
.block_on(async {
let server = if config.serve() {
let served_indexer = indexer.clone();
let served_computer = computer.clone();
let served_indexer = indexer.clone();
let served_computer = computer.clone();
let server = Server::new(served_indexer, served_computer, config.website())?;
let server = Server::new(served_indexer, served_computer, config.website())?;
let watch = config.watch();
let mcp = config.mcp();
let opt = Some(tokio::spawn(async move {
server.serve(watch, mcp).await.unwrap();
}));
let watch = config.watch();
let mcp = config.mcp();
sleep(Duration::from_secs(1));
tokio::spawn(async move {
server.serve(watch, mcp).await.unwrap();
});
opt
} else {
None
};
sleep(Duration::from_secs(1));
if config.process() {
loop {
wait_for_synced_node()?;
loop {
wait_for_synced_node(rpc)?;
let block_count = rpc.get_block_count()?;
let block_count = rpc.get_block_count()?;
info!("{} blocks found.", block_count + 1);
info!("{} blocks found.", block_count + 1);
let starting_indexes =
indexer.index(&parser, rpc, &exit, config.check_collisions())?;
let starting_indexes =
indexer.index(&parser, rpc, &exit, config.check_collisions())?;
computer.compute(&mut indexer, starting_indexes, &exit)?;
computer.compute(&mut indexer, starting_indexes, &exit)?;
if let Some(delay) = config.delay() {
sleep(Duration::from_secs(delay))
}
if let Some(delay) = config.delay() {
sleep(Duration::from_secs(delay))
}
info!("Waiting for new blocks...");
info!("Waiting for new blocks...");
while block_count == rpc.get_block_count()? {
sleep(Duration::from_secs(1))
}
while block_count == rpc.get_block_count()? {
sleep(Duration::from_secs(1))
}
}
if let Some(handle) = server {
handle.await.unwrap();
}
Ok(())
})
}
-23
View File
@@ -1,23 +0,0 @@
use clap_derive::{Parser, ValueEnum};
use serde::{Deserialize, Serialize};
#[derive(
Default,
Debug,
Clone,
Copy,
Parser,
ValueEnum,
Serialize,
Deserialize,
PartialEq,
Eq,
PartialOrd,
Ord,
)]
pub enum Services {
#[default]
All,
Processor,
Server,
}
+1 -4
View File
@@ -17,12 +17,9 @@ brk_fetcher = { workspace = true }
brk_indexer = { workspace = true }
brk_logger = { workspace = true }
brk_parser = { workspace = true }
brk_store = { workspace = true }
brk_vec = { workspace = true }
brk_vecs = { workspace = true }
color-eyre = { workspace = true }
derive_deref = { workspace = true }
fjall = { workspace = true }
jiff = { workspace = true }
log = { workspace = true }
rayon = { workspace = true }
serde = { workspace = true }
+10 -6
View File
@@ -1,19 +1,19 @@
use std::{path::Path, thread};
use brk_computer::Computer;
use brk_core::{default_bitcoin_path, default_brk_path};
use brk_exit::Exit;
use brk_fetcher::Fetcher;
use brk_indexer::Indexer;
use brk_parser::Parser;
use brk_vec::{Computation, Format};
use brk_vecs::{Computation, Format};
pub fn main() -> color_eyre::Result<()> {
color_eyre::install()?;
brk_logger::init(Some(Path::new(".log")));
let bitcoin_dir = default_bitcoin_path();
// let bitcoin_dir = brk_core::default_bitcoin_path();
let bitcoin_dir = Path::new("/Volumes/WD_BLACK/bitcoin");
let rpc = Box::leak(Box::new(bitcoincore_rpc::Client::new(
"http://localhost:8332",
@@ -23,11 +23,15 @@ pub fn main() -> color_eyre::Result<()> {
// Can't increase main thread's stack programatically, thus we need to use another thread
thread::Builder::new()
.stack_size(32 * 1024 * 1024)
.stack_size(256 * 1024 * 1024)
.spawn(move || -> color_eyre::Result<()> {
let parser = Parser::new(bitcoin_dir.join("blocks"), rpc);
let parser = Parser::new(
bitcoin_dir.join("blocks"),
brk_core::default_brk_path(),
rpc,
);
let _outputs_dir = default_brk_path().join("outputs");
let _outputs_dir = Path::new("/Volumes/WD_BLACK/brk").join("outputs");
let outputs_dir = _outputs_dir.as_path();
// let outputs_dir = Path::new("../../_outputs");
+2
View File
@@ -0,0 +1,2 @@
cargo build --profile profiling
flamegraph -- ../../target/profiling/examples/main
+2
View File
@@ -0,0 +1,2 @@
cargo build --example main --profile profiling
samply record ../../target/profiling/examples/main
@@ -1,26 +1,15 @@
use std::path::Path;
use std::{path::Path, sync::Arc};
use brk_core::Version;
use brk_exit::Exit;
use brk_fetcher::Fetcher;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, Computation, Format};
pub mod blocks;
pub mod cointime;
pub mod constants;
pub mod fetched;
pub mod grouped;
pub mod indexes;
pub mod market;
pub mod mining;
pub mod stateful;
pub mod transactions;
pub use indexes::Indexes;
use brk_vecs::{AnyCollectableVec, Computation, File, Format};
use log::info;
use crate::stores::Stores;
use crate::{blocks, cointime, constants, fetched, indexes, market, mining, transactions};
use super::stateful;
const VERSION: Version = Version::ONE;
@@ -38,16 +27,19 @@ pub struct Vecs {
}
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn import(
path: &Path,
file: &Arc<File>,
version: Version,
indexer: &Indexer,
fetch: bool,
computation: Computation,
format: Format,
fetched_file: &Arc<File>,
states_path: &Path,
) -> color_eyre::Result<Self> {
let indexes = indexes::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
indexer,
computation,
@@ -56,48 +48,56 @@ impl Vecs {
let fetched = fetch.then(|| {
fetched::Vecs::forced_import(
path,
file,
fetched_file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
)
.unwrap()
});
Ok(Self {
blocks: blocks::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
)?,
mining: mining::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
)?,
constants: constants::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
)?,
market: market::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
)?,
stateful: stateful::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
fetched.as_ref(),
states_path,
)?,
transactions: transactions::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
indexer,
&indexes,
@@ -106,10 +106,11 @@ impl Vecs {
fetched.as_ref(),
)?,
cointime: cointime::Vecs::forced_import(
path,
file,
version + VERSION + Version::ZERO,
computation,
format,
&indexes,
fetched.as_ref(),
)?,
indexes,
@@ -123,7 +124,6 @@ impl Vecs {
starting_indexes: brk_indexer::Indexes,
fetcher: Option<&mut Fetcher>,
exit: &Exit,
stores: &mut Stores,
) -> color_eyre::Result<()> {
info!("Computing indexes...");
let mut starting_indexes = self.indexes.compute(indexer, starting_indexes, exit)?;
@@ -181,7 +181,6 @@ impl Vecs {
&self.market,
&mut starting_indexes,
exit,
stores,
)?;
self.cointime.compute(
@@ -1,4 +1,4 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
CheckedSub, DifficultyEpoch, HalvingEpoch, Height, StoredU32, StoredU64, StoredUsize,
@@ -6,11 +6,13 @@ use brk_core::{
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec, Computation, EagerVec, Format};
use brk_vecs::{AnyCollectableVec, AnyIterableVec, Computation, EagerVec, File, Format};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions},
indexes,
};
@@ -32,91 +34,96 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
_computation: Computation,
computation: Computation,
format: Format,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
Ok(Self {
height_to_interval: EagerVec::forced_import(
path,
file,
"interval",
version + VERSION + Version::ZERO,
format,
)?,
timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import(
path,
file,
"timestamp",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_first(),
computation,
indexes,
VecBuilderOptions::default().add_first(),
)?,
indexes_to_block_interval: ComputedVecsFromHeight::forced_import(
path,
file,
"block_interval",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_block_count: ComputedVecsFromHeight::forced_import(
path,
file,
"block_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_block_weight: ComputedVecsFromHeight::forced_import(
path,
file,
"block_weight",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_block_size: ComputedVecsFromHeight::forced_import(
path,
file,
"block_size",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
height_to_vbytes: EagerVec::forced_import(
path,
file,
"vbytes",
version + VERSION + Version::ZERO,
format,
)?,
indexes_to_block_vbytes: ComputedVecsFromHeight::forced_import(
path,
file,
"block_vbytes",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
difficultyepoch_to_timestamp: EagerVec::forced_import(
path,
file,
"timestamp",
version + VERSION + Version::ZERO,
format,
)?,
halvingepoch_to_timestamp: EagerVec::forced_import(
path,
file,
"timestamp",
version + VERSION + Version::ZERO,
format,
@@ -1,20 +1,17 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{Bitcoin, CheckedSub, Dollars, StoredF64, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, Computation, Format, VecIterator};
use crate::vecs::{
fetched,
grouped::{ComputedRatioVecsFromDateIndex, ComputedValueVecsFromHeight},
stateful, transactions,
};
use brk_vecs::{AnyCollectableVec, Computation, File, Format, VecIterator};
use super::{
Indexes,
grouped::{ComputedVecsFromHeight, StorableVecGeneatorOptions},
indexes,
Indexes, fetched,
grouped::{
ComputedRatioVecsFromDateIndex, ComputedValueVecsFromHeight, ComputedVecsFromHeight,
Source, VecBuilderOptions,
},
indexes, stateful, transactions,
};
const VERSION: Version = Version::ZERO;
@@ -49,206 +46,247 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
_computation: Computation,
computation: Computation,
format: Format,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
) -> color_eyre::Result<Self> {
let compute_dollars = fetched.is_some();
Ok(Self {
indexes_to_coinblocks_created: ComputedVecsFromHeight::forced_import(
path,
file,
"coinblocks_created",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_coinblocks_stored: ComputedVecsFromHeight::forced_import(
path,
file,
"coinblocks_stored",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_liveliness: ComputedVecsFromHeight::forced_import(
path,
file,
"liveliness",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_vaultedness: ComputedVecsFromHeight::forced_import(
path,
file,
"vaultedness",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_activity_to_vaultedness_ratio: ComputedVecsFromHeight::forced_import(
path,
file,
"activity_to_vaultedness_ratio",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_vaulted_supply: ComputedValueVecsFromHeight::forced_import(
path,
file,
"vaulted_supply",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
)?,
indexes_to_active_supply: ComputedValueVecsFromHeight::forced_import(
path,
file,
"active_supply",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
VecBuilderOptions::default().add_last(),
compute_dollars,
indexes,
)?,
indexes_to_thermo_cap: ComputedVecsFromHeight::forced_import(
path,
file,
"thermo_cap",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_investor_cap: ComputedVecsFromHeight::forced_import(
path,
file,
"investor_cap",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_vaulted_cap: ComputedVecsFromHeight::forced_import(
path,
file,
"vaulted_cap",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_active_cap: ComputedVecsFromHeight::forced_import(
path,
file,
"active_cap",
true,
Source::Compute,
version + VERSION + Version::ONE,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_vaulted_price: ComputedVecsFromHeight::forced_import(
path,
file,
"vaulted_price",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_vaulted_price_ratio: ComputedRatioVecsFromDateIndex::forced_import(
path,
file,
"vaulted_price",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
computation,
indexes,
true,
)?,
indexes_to_active_price: ComputedVecsFromHeight::forced_import(
path,
file,
"active_price",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_active_price_ratio: ComputedRatioVecsFromDateIndex::forced_import(
path,
file,
"active_price",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
computation,
indexes,
true,
)?,
indexes_to_true_market_mean: ComputedVecsFromHeight::forced_import(
path,
file,
"true_market_mean",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_true_market_mean_ratio: ComputedRatioVecsFromDateIndex::forced_import(
path,
file,
"true_market_mean",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
computation,
indexes,
true,
)?,
indexes_to_cointime_value_destroyed: ComputedVecsFromHeight::forced_import(
path,
file,
"cointime_value_destroyed",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_cointime_value_created: ComputedVecsFromHeight::forced_import(
path,
file,
"cointime_value_created",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_cointime_value_stored: ComputedVecsFromHeight::forced_import(
path,
file,
"cointime_value_stored",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_cointime_price: ComputedVecsFromHeight::forced_import(
path,
file,
"cointime_price",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_cointime_cap: ComputedVecsFromHeight::forced_import(
path,
file,
"cointime_cap",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_cointime_price_ratio: ComputedRatioVecsFromDateIndex::forced_import(
path,
file,
"cointime_price",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
computation,
indexes,
true,
)?,
})
}
@@ -264,7 +302,7 @@ impl Vecs {
stateful: &stateful::Vecs,
exit: &Exit,
) -> color_eyre::Result<()> {
let circulating_supply = &stateful.utxo_vecs.all.1.height_to_supply;
let circulating_supply = &stateful.utxo_cohorts.all.1.height_to_supply;
self.indexes_to_coinblocks_created.compute_all(
indexer,
@@ -282,7 +320,7 @@ impl Vecs {
)?;
let indexes_to_coinblocks_destroyed =
&stateful.utxo_vecs.all.1.indexes_to_coinblocks_destroyed;
&stateful.utxo_cohorts.all.1.indexes_to_coinblocks_destroyed;
self.indexes_to_coinblocks_stored.compute_all(
indexer,
@@ -392,7 +430,7 @@ impl Vecs {
if let Some(fetched) = fetched {
let realized_cap = stateful
.utxo_vecs
.utxo_cohorts
.all
.1
.height_to_realized_cap
@@ -400,7 +438,7 @@ impl Vecs {
.unwrap();
let realized_price = stateful
.utxo_vecs
.utxo_cohorts
.all
.1
.indexes_to_realized_price
@@ -1,13 +1,15 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{StoredU8, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyVec, Computation, Format};
use brk_vecs::{AnyCollectableVec, AnyVec, Computation, File, Format};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{ComputedVecsFromHeight, StorableVecGeneatorOptions},
grouped::{ComputedVecsFromHeight, VecBuilderOptions},
indexes,
};
@@ -23,43 +25,52 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
_computation: Computation,
computation: Computation,
format: Format,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
Ok(Self {
constant_0: ComputedVecsFromHeight::forced_import(
path,
file,
"constant_0",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_1: ComputedVecsFromHeight::forced_import(
path,
file,
"constant_1",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_50: ComputedVecsFromHeight::forced_import(
path,
file,
"constant_50",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
constant_100: ComputedVecsFromHeight::forced_import(
path,
file,
"constant_100",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
})
}
@@ -1,19 +1,23 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
Cents, Close, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, High, Low, MonthIndex,
OHLCCents, OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, Version, WeekIndex, YearIndex,
OHLCCents, OHLCDollars, OHLCSats, Open, QuarterIndex, Sats, SemesterIndex, Version, WeekIndex,
YearIndex,
};
use brk_exit::Exit;
use brk_fetcher::Fetcher;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec, Computation, EagerVec, Format, StoredIndex};
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, AnyVec, Computation, EagerVec, File, Format, StoredIndex,
VecIterator,
};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{
ComputedVecsFromDateIndex, ComputedVecsFromHeightStrict, StorableVecGeneatorOptions,
},
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeightStrict, VecBuilderOptions},
indexes,
};
@@ -57,6 +61,8 @@ pub struct Vecs {
pub monthindex_to_ohlc_in_sats: EagerVec<MonthIndex, OHLCSats>,
pub quarterindex_to_ohlc: EagerVec<QuarterIndex, OHLCDollars>,
pub quarterindex_to_ohlc_in_sats: EagerVec<QuarterIndex, OHLCSats>,
pub semesterindex_to_ohlc: EagerVec<SemesterIndex, OHLCDollars>,
pub semesterindex_to_ohlc_in_sats: EagerVec<SemesterIndex, OHLCSats>,
pub yearindex_to_ohlc: EagerVec<YearIndex, OHLCDollars>,
pub yearindex_to_ohlc_in_sats: EagerVec<YearIndex, OHLCSats>,
// pub halvingepoch_to_ohlc: StorableVec<Halvingepoch, OHLCDollars>,
@@ -70,290 +76,316 @@ const VERSION_IN_SATS: Version = Version::ZERO;
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
fetched_file: &Arc<File>,
version: Version,
_computation: Computation,
computation: Computation,
format: Format,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
let mut fetched_path = path.to_owned();
fetched_path.pop();
fetched_path = fetched_path.join("fetched");
Ok(Self {
dateindex_to_ohlc_in_cents: EagerVec::forced_import(
&fetched_path,
fetched_file,
"ohlc_in_cents",
version + VERSION + Version::ZERO,
version + Version::ZERO,
format,
)?,
dateindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
dateindex_to_close_in_cents: EagerVec::forced_import(
path,
file,
"close_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_high_in_cents: EagerVec::forced_import(
path,
file,
"high_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_low_in_cents: EagerVec::forced_import(
path,
file,
"low_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_open_in_cents: EagerVec::forced_import(
path,
file,
"open_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
height_to_ohlc_in_cents: EagerVec::forced_import(
&fetched_path,
fetched_file,
"ohlc_in_cents",
version + VERSION + Version::ZERO,
version + Version::ZERO,
format,
)?,
height_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
height_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
height_to_close_in_cents: EagerVec::forced_import(
path,
file,
"close_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
height_to_high_in_cents: EagerVec::forced_import(
path,
file,
"high_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
height_to_low_in_cents: EagerVec::forced_import(
path,
file,
"low_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
height_to_open_in_cents: EagerVec::forced_import(
path,
file,
"open_in_cents",
version + VERSION + Version::ZERO,
format,
)?,
timeindexes_to_open: ComputedVecsFromDateIndex::forced_import(
path,
file,
"open",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_first(),
computation,
indexes,
VecBuilderOptions::default().add_first(),
)?,
timeindexes_to_high: ComputedVecsFromDateIndex::forced_import(
path,
file,
"high",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_max(),
computation,
indexes,
VecBuilderOptions::default().add_max(),
)?,
timeindexes_to_low: ComputedVecsFromDateIndex::forced_import(
path,
file,
"low",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_min(),
computation,
indexes,
VecBuilderOptions::default().add_min(),
)?,
timeindexes_to_close: ComputedVecsFromDateIndex::forced_import(
path,
file,
"close",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
timeindexes_to_open_in_sats: ComputedVecsFromDateIndex::forced_import(
path,
file,
"open_in_sats",
true,
Source::Compute,
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_first(),
computation,
indexes,
VecBuilderOptions::default().add_first(),
)?,
timeindexes_to_high_in_sats: ComputedVecsFromDateIndex::forced_import(
path,
file,
"high_in_sats",
true,
Source::Compute,
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_max(),
computation,
indexes,
VecBuilderOptions::default().add_max(),
)?,
timeindexes_to_low_in_sats: ComputedVecsFromDateIndex::forced_import(
path,
file,
"low_in_sats",
true,
Source::Compute,
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_min(),
computation,
indexes,
VecBuilderOptions::default().add_min(),
)?,
timeindexes_to_close_in_sats: ComputedVecsFromDateIndex::forced_import(
path,
file,
"close_in_sats",
true,
Source::Compute,
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
chainindexes_to_open: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"open",
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_first(),
VecBuilderOptions::default().add_first(),
)?,
chainindexes_to_high: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"high",
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_max(),
VecBuilderOptions::default().add_max(),
)?,
chainindexes_to_low: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"low",
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_min(),
VecBuilderOptions::default().add_min(),
)?,
chainindexes_to_close: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"close",
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
VecBuilderOptions::default().add_last(),
)?,
chainindexes_to_open_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"open_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_first(),
VecBuilderOptions::default().add_first(),
)?,
chainindexes_to_high_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"high_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_max(),
VecBuilderOptions::default().add_max(),
)?,
chainindexes_to_low_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"low_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_min(),
VecBuilderOptions::default().add_min(),
)?,
chainindexes_to_close_in_sats: ComputedVecsFromHeightStrict::forced_import(
path,
file,
"close_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
VecBuilderOptions::default().add_last(),
)?,
weekindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
weekindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
difficultyepoch_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
difficultyepoch_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
monthindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
quarterindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
quarterindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
semesterindex_to_ohlc: EagerVec::forced_import(
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
semesterindex_to_ohlc_in_sats: EagerVec::forced_import(
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
yearindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
yearindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
)?,
// halvingepoch_to_ohlc: StorableVec::forced_import(path,
// halvingepoch_to_ohlc: StorableVec::forced_import(file,
// "halvingepoch_to_ohlc"), version + VERSION + Version::ZERO, format)?,
decadeindex_to_ohlc: EagerVec::forced_import(
path,
file,
"ohlc",
version + VERSION + Version::ZERO,
format,
)?,
decadeindex_to_ohlc_in_sats: EagerVec::forced_import(
path,
file,
"ohlc_in_sats",
version + VERSION + VERSION_IN_SATS + Version::ZERO,
format,
@@ -422,27 +454,34 @@ impl Vecs {
exit,
)?;
let mut prev = None;
self.dateindex_to_ohlc_in_cents.compute_transform(
starting_indexes.dateindex,
&indexes.dateindex_to_date,
|(di, d, this)| {
let mut ohlc = fetcher.get_date(d).unwrap_or_else(|_| {
this.get_or_read(di, &this.mmap().load())
.unwrap()
.unwrap()
.into_owned()
});
if prev.is_none() {
let i = di.unwrap_to_usize();
prev.replace(if i > 0 {
this.into_iter().unwrap_get_inner_(i - 1)
} else {
OHLCCents::default()
});
}
if let Some(prev) = di.decremented() {
let prev_open = *this
.get_or_read(prev, &this.mmap().load())
.unwrap()
.unwrap()
.close;
let ohlc = if di.unwrap_to_usize() + 100 >= this.len()
&& let Ok(mut ohlc) = fetcher.get_date(d)
{
let prev_open = *prev.as_ref().unwrap().close;
*ohlc.open = prev_open;
*ohlc.high = (*ohlc.high).max(prev_open);
*ohlc.low = (*ohlc.low).min(prev_open);
}
ohlc
} else {
prev.clone().unwrap()
};
prev.replace(ohlc.clone());
(di, ohlc)
},
exit,
@@ -610,12 +649,15 @@ impl Vecs {
starting_indexes.weekindex,
self.timeindexes_to_close.weekindex.unwrap_last(),
|(i, close, ..)| {
let open = weekindex_first_iter.unwrap_get_inner(i);
let high = weekindex_max_iter.unwrap_get_inner(i);
let low = weekindex_min_iter.unwrap_get_inner(i);
(
i,
OHLCDollars {
open: weekindex_first_iter.unwrap_get_inner(i),
high: weekindex_max_iter.unwrap_get_inner(i),
low: weekindex_min_iter.unwrap_get_inner(i),
open,
high,
low,
close,
},
)
@@ -693,6 +735,27 @@ impl Vecs {
exit,
)?;
let mut semesterindex_first_iter =
self.timeindexes_to_open.semesterindex.unwrap_first().iter();
let mut semesterindex_max_iter = self.timeindexes_to_high.semesterindex.unwrap_max().iter();
let mut semesterindex_min_iter = self.timeindexes_to_low.semesterindex.unwrap_min().iter();
self.semesterindex_to_ohlc.compute_transform(
starting_indexes.semesterindex,
self.timeindexes_to_close.semesterindex.unwrap_last(),
|(i, close, ..)| {
(
i,
OHLCDollars {
open: semesterindex_first_iter.unwrap_get_inner(i),
high: semesterindex_max_iter.unwrap_get_inner(i),
low: semesterindex_min_iter.unwrap_get_inner(i),
close,
},
)
},
exit,
)?;
let mut yearindex_first_iter = self.timeindexes_to_open.yearindex.unwrap_first().iter();
let mut yearindex_max_iter = self.timeindexes_to_high.yearindex.unwrap_max().iter();
let mut yearindex_min_iter = self.timeindexes_to_low.yearindex.unwrap_min().iter();
@@ -1044,6 +1107,40 @@ impl Vecs {
exit,
)?;
let mut semesterindex_first_iter = self
.timeindexes_to_open_in_sats
.semesterindex
.unwrap_first()
.iter();
let mut semesterindex_max_iter = self
.timeindexes_to_high_in_sats
.semesterindex
.unwrap_max()
.iter();
let mut semesterindex_min_iter = self
.timeindexes_to_low_in_sats
.semesterindex
.unwrap_min()
.iter();
self.semesterindex_to_ohlc_in_sats.compute_transform(
starting_indexes.semesterindex,
self.timeindexes_to_close_in_sats
.semesterindex
.unwrap_last(),
|(i, close, ..)| {
(
i,
OHLCSats {
open: semesterindex_first_iter.unwrap_get_inner(i),
high: semesterindex_max_iter.unwrap_get_inner(i),
low: semesterindex_min_iter.unwrap_get_inner(i),
close,
},
)
},
exit,
)?;
let mut yearindex_first_iter = self
.timeindexes_to_open_in_sats
.yearindex
@@ -1133,6 +1230,7 @@ impl Vecs {
&self.difficultyepoch_to_ohlc,
&self.monthindex_to_ohlc,
&self.quarterindex_to_ohlc,
&self.semesterindex_to_ohlc,
&self.yearindex_to_ohlc,
// &self.halvingepoch_to_ohlc,
&self.decadeindex_to_ohlc,
@@ -1142,6 +1240,7 @@ impl Vecs {
&self.difficultyepoch_to_ohlc_in_sats,
&self.monthindex_to_ohlc_in_sats,
&self.quarterindex_to_ohlc_in_sats,
&self.semesterindex_to_ohlc_in_sats,
&self.yearindex_to_ohlc_in_sats,
// &self.halvingepoch_to_ohlc_in_sats,
&self.decadeindex_to_ohlc_in_sats,
@@ -0,0 +1,474 @@
use std::sync::Arc;
use brk_core::{FromCoarserIndex, Result, Version};
use brk_exit::Exit;
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, BoxedAnyIterableVec, CloneableAnyIterableVec, Computation,
ComputedVec, ComputedVecFrom2, File, Format, StoredIndex,
};
use crate::grouped::{EagerVecBuilder, VecBuilderOptions};
use super::ComputedType;
#[allow(clippy::type_complexity)]
#[derive(Clone)]
pub struct ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType,
S2T: ComputedType,
{
pub first: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub average: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub sum: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub max: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub min: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub last: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
pub cumulative: Option<Box<ComputedVecFrom2<I, T, S1I, T, I, S2T>>>,
}
const VERSION: Version = Version::ZERO;
impl<I, T, S1I, S2T> ComputedVecBuilder<I, T, S1I, S2T>
where
I: StoredIndex,
T: ComputedType + 'static,
S1I: StoredIndex + 'static + FromCoarserIndex<I>,
S2T: ComputedType,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
file: &Arc<File>,
name: &str,
version: Version,
format: Format,
computation: Computation,
source: Option<BoxedAnyIterableVec<S1I, T>>,
source_extra: &EagerVecBuilder<S1I, T>,
len_source: BoxedAnyIterableVec<I, S2T>,
options: ComputedVecBuilderOptions,
) -> color_eyre::Result<Self> {
let only_one_active = options.is_only_one_active();
let suffix = |s: &str| format!("{name}_{s}");
let maybe_suffix = |s: &str| {
if only_one_active {
name.to_string()
} else {
suffix(s)
}
};
Ok(Self {
first: options.first.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&maybe_suffix("first"),
version + VERSION + Version::ZERO,
format,
source_extra
.first
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::min_from(i))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
last: options.last.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
name,
version + VERSION + Version::ZERO,
format,
source_extra.last.as_ref().map_or_else(
|| {
source
.as_ref()
.unwrap_or_else(|| {
dbg!(file, name, I::to_string());
panic!()
})
.clone()
},
|v| v.clone(),
),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
min: options.min.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&maybe_suffix("min"),
version + VERSION + Version::ZERO,
format,
source_extra
.min
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.min()
},
)
.unwrap(),
)
}),
max: options.max.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&maybe_suffix("max"),
version + VERSION + Version::ZERO,
format,
source_extra
.max
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.max()
},
)
.unwrap(),
)
}),
average: options.average.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&maybe_suffix("average"),
version + VERSION + Version::ZERO,
format,
source_extra
.average
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
let len = vec.len();
vec.into_iter().for_each(|v| sum += v);
Some(sum / len)
},
)
.unwrap(),
)
}),
sum: options.sum.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&(if !options.last && !options.average && !options.min && !options.max {
name.to_string()
} else {
maybe_suffix("sum")
}),
version + VERSION + Version::ZERO,
format,
source_extra
.sum
.as_ref()
.map_or_else(|| source.as_ref().unwrap().clone(), |v| v.clone()),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
let vec = S1I::inclusive_range_from(i, source.len())
.flat_map(|i| source.next_at(i).map(|(_, cow)| cow.into_owned()))
.collect::<Vec<_>>();
if vec.is_empty() {
return None;
}
let mut sum = T::from(0);
vec.into_iter().for_each(|v| sum += v);
Some(sum)
},
)
.unwrap(),
)
}),
cumulative: options.cumulative.then(|| {
Box::new(
ComputedVec::forced_import_or_init_from_2(
computation,
file,
&suffix("cumulative"),
version + VERSION + Version::ZERO,
format,
source_extra.cumulative.as_ref().unwrap().boxed_clone(),
len_source.clone(),
|i: I, source, len_source| {
if i.unwrap_to_usize() >= len_source.len() {
return None;
}
source
.next_at(S1I::max_from(i, source.len()))
.map(|(_, cow)| cow.into_owned())
},
)
.unwrap(),
)
}),
})
}
pub fn compute_if_necessary<T2>(
&mut self,
max_from: I,
len_source: &impl AnyIterableVec<I, T2>,
exit: &Exit,
) -> Result<()> {
if let Some(first) = self.first.as_mut() {
first.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(last) = self.last.as_mut() {
last.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(min) = self.min.as_mut() {
min.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(max) = self.max.as_mut() {
max.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(average) = self.average.as_mut() {
average.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(sum) = self.sum.as_mut() {
sum.compute_if_necessary(max_from, len_source, exit)?;
}
if let Some(cumulative) = self.cumulative.as_mut() {
cumulative.compute_if_necessary(max_from, len_source, exit)?;
}
Ok(())
}
pub fn starting_index(&self, max_from: I) -> I {
max_from.min(I::from(
self.vecs().into_iter().map(|v| v.len()).min().unwrap(),
))
}
pub fn unwrap_first(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.first.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_average(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.average.as_ref().unwrap()
}
pub fn unwrap_sum(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.sum.as_ref().unwrap()
}
pub fn unwrap_max(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.max.as_ref().unwrap()
}
pub fn unwrap_min(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.min.as_ref().unwrap()
}
pub fn unwrap_last(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.last.as_ref().unwrap()
}
#[allow(unused)]
pub fn unwrap_cumulative(&self) -> &ComputedVecFrom2<I, T, S1I, T, I, S2T> {
self.cumulative.as_ref().unwrap()
}
pub fn vecs(&self) -> Vec<&dyn AnyCollectableVec> {
let mut v: Vec<&dyn AnyCollectableVec> = vec![];
if let Some(first) = self.first.as_ref() {
v.push(first.as_ref());
}
if let Some(last) = self.last.as_ref() {
v.push(last.as_ref());
}
if let Some(min) = self.min.as_ref() {
v.push(min.as_ref());
}
if let Some(max) = self.max.as_ref() {
v.push(max.as_ref());
}
if let Some(average) = self.average.as_ref() {
v.push(average.as_ref());
}
if let Some(sum) = self.sum.as_ref() {
v.push(sum.as_ref());
}
if let Some(cumulative) = self.cumulative.as_ref() {
v.push(cumulative.as_ref());
}
v
}
}
#[derive(Default, Clone, Copy)]
pub struct ComputedVecBuilderOptions {
average: bool,
sum: bool,
max: bool,
min: bool,
first: bool,
last: bool,
cumulative: bool,
}
impl From<VecBuilderOptions> for ComputedVecBuilderOptions {
fn from(value: VecBuilderOptions) -> Self {
Self {
average: value.average(),
sum: value.sum(),
max: value.max(),
min: value.min(),
first: value.first(),
last: value.last(),
cumulative: value.cumulative(),
}
}
}
impl ComputedVecBuilderOptions {
pub fn add_first(mut self) -> Self {
self.first = true;
self
}
pub fn add_last(mut self) -> Self {
self.last = true;
self
}
pub fn add_min(mut self) -> Self {
self.min = true;
self
}
pub fn add_max(mut self) -> Self {
self.max = true;
self
}
pub fn add_average(mut self) -> Self {
self.average = true;
self
}
pub fn add_sum(mut self) -> Self {
self.sum = true;
self
}
pub fn add_cumulative(mut self) -> Self {
self.cumulative = true;
self
}
#[allow(unused)]
pub fn rm_min(mut self) -> Self {
self.min = false;
self
}
#[allow(unused)]
pub fn rm_max(mut self) -> Self {
self.max = false;
self
}
#[allow(unused)]
pub fn rm_average(mut self) -> Self {
self.average = false;
self
}
#[allow(unused)]
pub fn rm_sum(mut self) -> Self {
self.sum = false;
self
}
#[allow(unused)]
pub fn rm_cumulative(mut self) -> Self {
self.cumulative = false;
self
}
pub fn add_minmax(mut self) -> Self {
self.min = true;
self.max = true;
self
}
pub fn is_only_one_active(&self) -> bool {
[
self.average,
self.sum,
self.max,
self.min,
self.first,
self.last,
self.cumulative,
]
.iter()
.filter(|b| **b)
.count()
== 1
}
pub fn copy_self_extra(&self) -> Self {
Self {
cumulative: self.cumulative,
..Self::default()
}
}
}
@@ -1,8 +1,10 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{CheckedSub, Result, StoredUsize, Version};
use brk_exit::Exit;
use brk_vec::{AnyCollectableVec, AnyIterableVec, EagerVec, Format, StoredIndex, StoredType};
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, AnyVec, EagerVec, File, Format, StoredIndex, StoredType,
};
use color_eyre::eyre::ContextCompat;
use crate::utils::get_percentile;
@@ -10,7 +12,7 @@ use crate::utils::get_percentile;
use super::ComputedType;
#[derive(Clone, Debug)]
pub struct ComputedVecBuilder<I, T>
pub struct EagerVecBuilder<I, T>
where
I: StoredIndex,
T: ComputedType,
@@ -31,17 +33,17 @@ where
const VERSION: Version = Version::ZERO;
impl<I, T> ComputedVecBuilder<I, T>
impl<I, T> EagerVecBuilder<I, T>
where
I: StoredIndex,
T: ComputedType,
{
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let only_one_active = options.is_only_one_active();
@@ -59,7 +61,7 @@ where
first: options.first.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("first"),
version + VERSION + Version::ZERO,
format,
@@ -69,13 +71,13 @@ where
}),
last: options.last.then(|| {
Box::new(
EagerVec::forced_import(path, name, version + Version::ZERO, format).unwrap(),
EagerVec::forced_import(file, name, version + Version::ZERO, format).unwrap(),
)
}),
min: options.min.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("min"),
version + VERSION + Version::ZERO,
format,
@@ -86,7 +88,7 @@ where
max: options.max.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("max"),
version + VERSION + Version::ZERO,
format,
@@ -97,7 +99,7 @@ where
median: options.median.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("median"),
version + VERSION + Version::ZERO,
format,
@@ -108,7 +110,7 @@ where
average: options.average.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("average"),
version + VERSION + Version::ZERO,
format,
@@ -119,7 +121,7 @@ where
sum: options.sum.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&(if !options.last && !options.average && !options.min && !options.max {
name.to_string()
} else {
@@ -134,7 +136,7 @@ where
cumulative: options.cumulative.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&suffix("cumulative"),
version + VERSION + Version::ZERO,
format,
@@ -145,7 +147,7 @@ where
_90p: options._90p.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("90p"),
version + VERSION + Version::ZERO,
format,
@@ -156,7 +158,7 @@ where
_75p: options._75p.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("75p"),
version + VERSION + Version::ZERO,
format,
@@ -167,7 +169,7 @@ where
_25p: options._25p.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("25p"),
version + VERSION + Version::ZERO,
format,
@@ -178,7 +180,7 @@ where
_10p: options._10p.then(|| {
Box::new(
EagerVec::forced_import(
path,
file,
&maybe_suffix("10p"),
version + VERSION + Version::ZERO,
format,
@@ -309,7 +311,7 @@ where
.inspect_err(|_| {
dbg!(
&values,
max.path(),
max.name(),
first_indexes.name(),
first_index,
count_indexes.name(),
@@ -384,7 +386,7 @@ where
pub fn from_aligned<I2>(
&mut self,
max_from: I,
source: &ComputedVecBuilder<I2, T>,
source: &EagerVecBuilder<I2, T>,
first_indexes: &impl AnyIterableVec<I, I2>,
count_indexes: &impl AnyIterableVec<I, StoredUsize>,
exit: &Exit,
@@ -706,7 +708,7 @@ where
}
#[derive(Default, Clone, Copy)]
pub struct StorableVecGeneatorOptions {
pub struct VecBuilderOptions {
average: bool,
sum: bool,
max: bool,
@@ -721,7 +723,55 @@ pub struct StorableVecGeneatorOptions {
cumulative: bool,
}
impl StorableVecGeneatorOptions {
impl VecBuilderOptions {
pub fn average(&self) -> bool {
self.average
}
pub fn sum(&self) -> bool {
self.sum
}
pub fn max(&self) -> bool {
self.max
}
pub fn _90p(&self) -> bool {
self._90p
}
pub fn _75p(&self) -> bool {
self._75p
}
pub fn median(&self) -> bool {
self.median
}
pub fn _25p(&self) -> bool {
self._25p
}
pub fn _10p(&self) -> bool {
self._10p
}
pub fn min(&self) -> bool {
self.min
}
pub fn first(&self) -> bool {
self.first
}
pub fn last(&self) -> bool {
self.last
}
pub fn cumulative(&self) -> bool {
self.cumulative
}
pub fn add_first(mut self) -> Self {
self.first = true;
self
@@ -1,15 +1,18 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, Result, Version, WeekIndex, YearIndex,
DateIndex, DecadeIndex, MonthIndex, QuarterIndex, Result, SemesterIndex, Version, WeekIndex,
YearIndex,
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec, EagerVec, Format};
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, CloneableAnyIterableVec, Computation, EagerVec, File, Format,
};
use crate::vecs::{Indexes, indexes};
use crate::{Indexes, grouped::ComputedVecBuilder, indexes};
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
use super::{ComputedType, EagerVecBuilder, Source, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromDateIndex<T>
@@ -17,34 +20,38 @@ where
T: ComputedType + PartialOrd,
{
pub dateindex: Option<EagerVec<DateIndex, T>>,
pub dateindex_extra: ComputedVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T>,
pub monthindex: ComputedVecBuilder<MonthIndex, T>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T>,
pub yearindex: ComputedVecBuilder<YearIndex, T>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T>,
pub dateindex_extra: EagerVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T, DateIndex, WeekIndex>,
pub monthindex: ComputedVecBuilder<MonthIndex, T, DateIndex, MonthIndex>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T, DateIndex, QuarterIndex>,
pub semesterindex: ComputedVecBuilder<SemesterIndex, T, DateIndex, SemesterIndex>,
pub yearindex: ComputedVecBuilder<YearIndex, T, DateIndex, YearIndex>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T, DateIndex, DecadeIndex>,
}
const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromDateIndex<T>
where
T: ComputedType,
T: ComputedType + 'static,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<DateIndex, T>,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
computation: Computation,
indexes: &indexes::Vecs,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let dateindex = compute_source.then(|| {
EagerVec::forced_import(path, name, version + VERSION + Version::ZERO, format).unwrap()
let dateindex = source.is_compute().then(|| {
EagerVec::forced_import(file, name, version + VERSION + Version::ZERO, format).unwrap()
});
let dateindex_extra = ComputedVecBuilder::forced_import(
path,
let dateindex_extra = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
@@ -53,44 +60,77 @@ where
let options = options.remove_percentiles();
let dateindex_source = source.vec().or(dateindex.as_ref().map(|v| v.boxed_clone()));
Ok(Self {
dateindex,
dateindex_extra,
weekindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
computation,
dateindex_source.clone(),
&dateindex_extra,
indexes.weekindex_to_weekindex.boxed_clone(),
options.into(),
)?,
monthindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
dateindex_source.clone(),
&dateindex_extra,
indexes.monthindex_to_monthindex.boxed_clone(),
options.into(),
)?,
quarterindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
dateindex_source.clone(),
&dateindex_extra,
indexes.quarterindex_to_quarterindex.boxed_clone(),
options.into(),
)?,
semesterindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
dateindex_source.clone(),
&dateindex_extra,
indexes.semesterindex_to_semesterindex.boxed_clone(),
options.into(),
)?,
yearindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
dateindex_source.clone(),
&dateindex_extra,
indexes.yearindex_to_yearindex.boxed_clone(),
options.into(),
)?,
decadeindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
dateindex_source.clone(),
&dateindex_extra,
indexes.decadeindex_to_decadeindex.boxed_clone(),
options.into(),
)?,
dateindex,
dateindex_extra,
})
}
@@ -133,65 +173,45 @@ where
if let Some(dateindex) = dateindex {
self.dateindex_extra
.extend(starting_indexes.dateindex, dateindex, exit)?;
self.weekindex.compute(
starting_indexes.weekindex,
dateindex,
&indexes.weekindex_to_first_dateindex,
&indexes.weekindex_to_dateindex_count,
exit,
)?;
self.monthindex.compute(
starting_indexes.monthindex,
dateindex,
&indexes.monthindex_to_first_dateindex,
&indexes.monthindex_to_dateindex_count,
exit,
)?;
} else {
let dateindex = self.dateindex.as_ref().unwrap();
self.dateindex_extra
.extend(starting_indexes.dateindex, dateindex, exit)?;
self.weekindex.compute(
starting_indexes.weekindex,
dateindex,
&indexes.weekindex_to_first_dateindex,
&indexes.weekindex_to_dateindex_count,
exit,
)?;
self.monthindex.compute(
starting_indexes.monthindex,
dateindex,
&indexes.monthindex_to_first_dateindex,
&indexes.monthindex_to_dateindex_count,
exit,
)?;
}
self.quarterindex.from_aligned(
self.weekindex.compute_if_necessary(
starting_indexes.weekindex,
&indexes.weekindex_to_dateindex_count,
exit,
)?;
self.monthindex.compute_if_necessary(
starting_indexes.monthindex,
&indexes.monthindex_to_dateindex_count,
exit,
)?;
self.quarterindex.compute_if_necessary(
starting_indexes.quarterindex,
&self.monthindex,
&indexes.quarterindex_to_first_monthindex,
&indexes.quarterindex_to_monthindex_count,
exit,
)?;
self.yearindex.from_aligned(
self.semesterindex.compute_if_necessary(
starting_indexes.semesterindex,
&indexes.semesterindex_to_monthindex_count,
exit,
)?;
self.yearindex.compute_if_necessary(
starting_indexes.yearindex,
&self.monthindex,
&indexes.yearindex_to_first_monthindex,
&indexes.yearindex_to_monthindex_count,
exit,
)?;
self.decadeindex.from_aligned(
self.decadeindex.compute_if_necessary(
starting_indexes.decadeindex,
&self.yearindex,
&indexes.decadeindex_to_first_yearindex,
&indexes.decadeindex_to_yearindex_count,
exit,
)?;
@@ -208,6 +228,7 @@ where
self.weekindex.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
self.decadeindex.vecs(),
]
@@ -1,16 +1,22 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, Result, Version,
WeekIndex, YearIndex,
DateIndex, DecadeIndex, DifficultyEpoch, Height, MonthIndex, QuarterIndex, Result,
SemesterIndex, Version, WeekIndex, YearIndex,
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec, EagerVec, Format};
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, CloneableAnyIterableVec, Computation, EagerVec, File, Format,
};
use crate::vecs::{Indexes, indexes};
use crate::{
Indexes,
grouped::{ComputedVecBuilder, Source},
indexes,
};
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromHeight<T>
@@ -18,47 +24,50 @@ where
T: ComputedType + PartialOrd,
{
pub height: Option<EagerVec<Height, T>>,
pub height_extra: ComputedVecBuilder<Height, T>,
pub dateindex: ComputedVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T>,
pub difficultyepoch: ComputedVecBuilder<DifficultyEpoch, T>,
pub monthindex: ComputedVecBuilder<MonthIndex, T>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T>,
// 6 months
pub yearindex: ComputedVecBuilder<YearIndex, T>,
pub height_extra: EagerVecBuilder<Height, T>,
pub dateindex: EagerVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T, DateIndex, WeekIndex>,
pub difficultyepoch: EagerVecBuilder<DifficultyEpoch, T>,
pub monthindex: ComputedVecBuilder<MonthIndex, T, DateIndex, MonthIndex>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T, DateIndex, QuarterIndex>,
pub semesterindex: ComputedVecBuilder<SemesterIndex, T, DateIndex, SemesterIndex>,
pub yearindex: ComputedVecBuilder<YearIndex, T, DateIndex, YearIndex>,
// TODO: pub halvingepoch: StorableVecGeneator<Halvingepoch, T>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T, DateIndex, DecadeIndex>,
}
const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromHeight<T>
where
T: ComputedType + Ord + From<f64>,
T: ComputedType + Ord + From<f64> + 'static,
f64: From<T>,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<Height, T>,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
computation: Computation,
indexes: &indexes::Vecs,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let height = compute_source.then(|| {
EagerVec::forced_import(path, name, version + VERSION + Version::ZERO, format).unwrap()
let height = source.is_compute().then(|| {
EagerVec::forced_import(file, name, version + VERSION + Version::ZERO, format).unwrap()
});
let height_extra = ComputedVecBuilder::forced_import(
path,
let height_extra = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
options.copy_self_extra(),
)?;
let dateindex = ComputedVecBuilder::forced_import(
path,
let dateindex = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
@@ -68,47 +77,78 @@ where
let options = options.remove_percentiles();
Ok(Self {
weekindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
computation,
None,
&dateindex,
indexes.weekindex_to_weekindex.boxed_clone(),
options.into(),
)?,
monthindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.monthindex_to_monthindex.boxed_clone(),
options.into(),
)?,
quarterindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.quarterindex_to_quarterindex.boxed_clone(),
options.into(),
)?,
semesterindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.semesterindex_to_semesterindex.boxed_clone(),
options.into(),
)?,
yearindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.yearindex_to_yearindex.boxed_clone(),
options.into(),
)?,
decadeindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.decadeindex_to_decadeindex.boxed_clone(),
options.into(),
)?,
// halvingepoch: StorableVecGeneator::forced_import(file, name, version + VERSION + Version::ZERO, format, options)?,
height,
height_extra,
dateindex,
weekindex: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
difficultyepoch: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
monthindex: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
quarterindex: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
yearindex: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
// halvingepoch: StorableVecGeneator::forced_import(path, name, version + VERSION + Version::ZERO, format, options)?,
decadeindex: ComputedVecBuilder::forced_import(
path,
difficultyepoch: EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
@@ -189,42 +229,38 @@ where
)?;
}
self.weekindex.from_aligned(
self.weekindex.compute_if_necessary(
starting_indexes.weekindex,
&self.dateindex,
&indexes.weekindex_to_first_dateindex,
&indexes.weekindex_to_dateindex_count,
exit,
)?;
self.monthindex.from_aligned(
self.monthindex.compute_if_necessary(
starting_indexes.monthindex,
&self.dateindex,
&indexes.monthindex_to_first_dateindex,
&indexes.monthindex_to_dateindex_count,
exit,
)?;
self.quarterindex.from_aligned(
self.quarterindex.compute_if_necessary(
starting_indexes.quarterindex,
&self.monthindex,
&indexes.quarterindex_to_first_monthindex,
&indexes.quarterindex_to_monthindex_count,
exit,
)?;
self.yearindex.from_aligned(
self.semesterindex.compute_if_necessary(
starting_indexes.semesterindex,
&indexes.semesterindex_to_monthindex_count,
exit,
)?;
self.yearindex.compute_if_necessary(
starting_indexes.yearindex,
&self.monthindex,
&indexes.yearindex_to_first_monthindex,
&indexes.yearindex_to_monthindex_count,
exit,
)?;
self.decadeindex.from_aligned(
self.decadeindex.compute_if_necessary(
starting_indexes.decadeindex,
&self.yearindex,
&indexes.decadeindex_to_first_yearindex,
&indexes.decadeindex_to_yearindex_count,
exit,
)?;
@@ -243,6 +279,7 @@ where
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
@@ -1,13 +1,13 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{DifficultyEpoch, Height, Result, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, EagerVec, Format};
use brk_vecs::{AnyCollectableVec, EagerVec, File, Format};
use crate::vecs::{indexes, Indexes};
use crate::{Indexes, indexes};
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromHeightStrict<T>
@@ -15,8 +15,8 @@ where
T: ComputedType + PartialOrd,
{
pub height: EagerVec<Height, T>,
pub height_extra: ComputedVecBuilder<Height, T>,
pub difficultyepoch: ComputedVecBuilder<DifficultyEpoch, T>,
pub height_extra: EagerVecBuilder<Height, T>,
pub difficultyepoch: EagerVecBuilder<DifficultyEpoch, T>,
// TODO: pub halvingepoch: StorableVecGeneator<Halvingepoch, T>,
}
@@ -28,17 +28,17 @@ where
f64: From<T>,
{
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let height =
EagerVec::forced_import(path, name, version + VERSION + Version::ZERO, format)?;
EagerVec::forced_import(file, name, version + VERSION + Version::ZERO, format)?;
let height_extra = ComputedVecBuilder::forced_import(
path,
let height_extra = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
@@ -50,14 +50,14 @@ where
Ok(Self {
height,
height_extra,
difficultyepoch: ComputedVecBuilder::forced_import(
path,
difficultyepoch: EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
// halvingepoch: StorableVecGeneator::forced_import(path, name, version + VERSION + Version::ZERO, format, options)?,
// halvingepoch: StorableVecGeneator::forced_import(file, name, version + VERSION + Version::ZERO, format, options)?,
})
}
@@ -1,18 +1,23 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
Bitcoin, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, Height, MonthIndex, QuarterIndex,
Result, Sats, TxIndex, Version, WeekIndex, YearIndex,
Result, Sats, SemesterIndex, TxIndex, Version, WeekIndex, YearIndex,
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{
AnyCollectableVec, AnyVec, CollectableVec, EagerVec, Format, StoredIndex, VecIterator,
use brk_vecs::{
AnyCollectableVec, AnyVec, CloneableAnyIterableVec, CollectableVec, Computation, EagerVec,
File, Format, StoredIndex, VecIterator,
};
use crate::vecs::{Indexes, fetched, indexes};
use crate::{
Indexes, fetched,
grouped::{ComputedVecBuilder, Source},
indexes,
};
use super::{ComputedType, ComputedVecBuilder, StorableVecGeneatorOptions};
use super::{ComputedType, EagerVecBuilder, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedVecsFromTxindex<T>
@@ -20,41 +25,45 @@ where
T: ComputedType + PartialOrd,
{
pub txindex: Option<Box<EagerVec<TxIndex, T>>>,
pub height: ComputedVecBuilder<Height, T>,
pub dateindex: ComputedVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T>,
pub difficultyepoch: ComputedVecBuilder<DifficultyEpoch, T>,
pub monthindex: ComputedVecBuilder<MonthIndex, T>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T>,
pub yearindex: ComputedVecBuilder<YearIndex, T>,
pub height: EagerVecBuilder<Height, T>,
pub dateindex: EagerVecBuilder<DateIndex, T>,
pub weekindex: ComputedVecBuilder<WeekIndex, T, DateIndex, WeekIndex>,
pub difficultyepoch: EagerVecBuilder<DifficultyEpoch, T>,
pub monthindex: ComputedVecBuilder<MonthIndex, T, DateIndex, MonthIndex>,
pub quarterindex: ComputedVecBuilder<QuarterIndex, T, DateIndex, QuarterIndex>,
pub semesterindex: ComputedVecBuilder<SemesterIndex, T, DateIndex, SemesterIndex>,
pub yearindex: ComputedVecBuilder<YearIndex, T, DateIndex, YearIndex>,
// TODO: pub halvingepoch: StorableVecGeneator<Halvingepoch, T>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T>,
pub decadeindex: ComputedVecBuilder<DecadeIndex, T, DateIndex, DecadeIndex>,
}
const VERSION: Version = Version::ZERO;
impl<T> ComputedVecsFromTxindex<T>
where
T: ComputedType + Ord + From<f64>,
T: ComputedType + Ord + From<f64> + 'static,
f64: From<T>,
{
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<TxIndex, T>,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
computation: Computation,
indexes: &indexes::Vecs,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let txindex = compute_source.then(|| {
let txindex = source.is_compute().then(|| {
Box::new(
EagerVec::forced_import(path, name, version + VERSION + Version::ZERO, format)
EagerVec::forced_import(file, name, version + VERSION + Version::ZERO, format)
.unwrap(),
)
});
let height = ComputedVecBuilder::forced_import(
path,
let height = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
@@ -63,59 +72,93 @@ where
let options = options.remove_percentiles();
let dateindex = EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
options,
)?;
Ok(Self {
txindex,
height,
dateindex: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
weekindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
difficultyepoch: ComputedVecBuilder::forced_import(
path,
name,
version + VERSION + Version::ZERO,
format,
options,
computation,
None,
&dateindex,
indexes.weekindex_to_weekindex.boxed_clone(),
options.into(),
)?,
monthindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
None,
&dateindex,
indexes.monthindex_to_monthindex.boxed_clone(),
options.into(),
)?,
quarterindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
None,
&dateindex,
indexes.quarterindex_to_quarterindex.boxed_clone(),
options.into(),
)?,
semesterindex: ComputedVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.semesterindex_to_semesterindex.boxed_clone(),
options.into(),
)?,
yearindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
options,
Computation::Lazy,
None,
&dateindex,
indexes.yearindex_to_yearindex.boxed_clone(),
options.into(),
)?,
// halvingepoch: StorableVecGeneator::forced_import(path, name, version + VERSION + Version::ZERO, format, options)?,
decadeindex: ComputedVecBuilder::forced_import(
path,
file,
name,
version + VERSION + Version::ZERO,
format,
Computation::Lazy,
None,
&dateindex,
indexes.decadeindex_to_decadeindex.boxed_clone(),
options.into(),
)?,
txindex,
height,
dateindex,
difficultyepoch: EagerVecBuilder::forced_import(
file,
name,
version + VERSION + Version::ZERO,
format,
options,
)?,
// halvingepoch: StorableVecGeneator::forced_import(file, name, version + VERSION + Version::ZERO, format, options)?,
})
}
@@ -196,42 +239,38 @@ where
exit,
)?;
self.weekindex.from_aligned(
self.weekindex.compute_if_necessary(
starting_indexes.weekindex,
&self.dateindex,
&indexes.weekindex_to_first_dateindex,
&indexes.weekindex_to_dateindex_count,
exit,
)?;
self.monthindex.from_aligned(
self.monthindex.compute_if_necessary(
starting_indexes.monthindex,
&self.dateindex,
&indexes.monthindex_to_first_dateindex,
&indexes.monthindex_to_dateindex_count,
exit,
)?;
self.quarterindex.from_aligned(
self.quarterindex.compute_if_necessary(
starting_indexes.quarterindex,
&self.monthindex,
&indexes.quarterindex_to_first_monthindex,
&indexes.quarterindex_to_monthindex_count,
exit,
)?;
self.yearindex.from_aligned(
self.semesterindex.compute_if_necessary(
starting_indexes.semesterindex,
&indexes.semesterindex_to_monthindex_count,
exit,
)?;
self.yearindex.compute_if_necessary(
starting_indexes.yearindex,
&self.monthindex,
&indexes.yearindex_to_first_monthindex,
&indexes.yearindex_to_monthindex_count,
exit,
)?;
self.decadeindex.from_aligned(
self.decadeindex.compute_if_necessary(
starting_indexes.decadeindex,
&self.yearindex,
&indexes.decadeindex_to_first_yearindex,
&indexes.decadeindex_to_yearindex_count,
exit,
)?;
@@ -258,6 +297,7 @@ where
self.difficultyepoch.vecs(),
self.monthindex.vecs(),
self.quarterindex.vecs(),
self.semesterindex.vecs(),
self.yearindex.vecs(),
// self.halvingepoch.vecs(),
self.decadeindex.vecs(),
@@ -1,21 +1,25 @@
mod builder;
mod builder_computed;
mod builder_eager;
mod from_dateindex;
mod from_height;
mod from_height_strict;
mod from_txindex;
mod ratio_from_dateindex;
mod source;
mod r#type;
mod value_from_dateindex;
mod value_from_height;
mod value_from_txindex;
mod value_height;
pub use builder::*;
pub use builder_computed::*;
pub use builder_eager::*;
pub use from_dateindex::*;
pub use from_height::*;
pub use from_height_strict::*;
pub use from_txindex::*;
pub use ratio_from_dateindex::*;
pub use source::*;
use r#type::*;
pub use value_from_dateindex::*;
pub use value_from_height::*;
File diff suppressed because it is too large Load Diff
+51
View File
@@ -0,0 +1,51 @@
use brk_vecs::BoxedAnyIterableVec;
#[derive(Clone)]
pub enum Source<I, T> {
Compute,
None,
Vec(BoxedAnyIterableVec<I, T>),
}
impl<I, T> Source<I, T> {
pub fn is_compute(&self) -> bool {
matches!(self, Self::Compute)
}
pub fn is_none(&self) -> bool {
matches!(self, Self::None)
}
pub fn is_vec(&self) -> bool {
matches!(self, Self::Vec(_))
}
pub fn vec(self) -> Option<BoxedAnyIterableVec<I, T>> {
match self {
Self::Vec(v) => Some(v),
_ => None,
}
}
}
impl<I, T> From<bool> for Source<I, T> {
fn from(value: bool) -> Self {
if value { Self::Compute } else { Self::None }
}
}
impl<I, T> From<BoxedAnyIterableVec<I, T>> for Source<I, T> {
fn from(value: BoxedAnyIterableVec<I, T>) -> Self {
Self::Vec(value)
}
}
impl<I, T> From<Option<BoxedAnyIterableVec<I, T>>> for Source<I, T> {
fn from(value: Option<BoxedAnyIterableVec<I, T>>) -> Self {
if let Some(v) = value {
Self::Vec(v)
} else {
Self::None
}
}
}
+14
View File
@@ -0,0 +1,14 @@
use std::ops::{Add, AddAssign, Div};
use brk_vecs::StoredType;
pub trait ComputedType
where
Self:
StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + AddAssign + Ord,
{
}
impl<T> ComputedType for T where
T: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + AddAssign + Ord
{
}
@@ -1,13 +1,13 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{Bitcoin, DateIndex, Dollars, Result, Sats, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format, StoredVec};
use brk_vecs::{AnyCollectableVec, CollectableVec, Computation, EagerVec, File, Format, StoredVec};
use crate::vecs::{Indexes, fetched, grouped::ComputedVecsFromDateIndex, indexes};
use crate::{Indexes, fetched, grouped::ComputedVecsFromDateIndex, indexes};
use super::StorableVecGeneatorOptions;
use super::{Source, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedValueVecsFromDateIndex {
@@ -19,39 +19,48 @@ pub struct ComputedValueVecsFromDateIndex {
const VERSION: Version = Version::ZERO;
impl ComputedValueVecsFromDateIndex {
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<DateIndex, Sats>,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
computation: Computation,
options: VecBuilderOptions,
compute_dollars: bool,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
Ok(Self {
sats: ComputedVecsFromDateIndex::forced_import(
path,
file,
name,
compute_source,
source,
version + VERSION,
format,
computation,
indexes,
options,
)?,
bitcoin: ComputedVecsFromDateIndex::forced_import(
path,
file,
&format!("{name}_in_btc"),
true,
Source::Compute,
version + VERSION,
format,
computation,
indexes,
options,
)?,
dollars: compute_dollars.then(|| {
ComputedVecsFromDateIndex::forced_import(
path,
file,
&format!("{name}_in_usd"),
true,
Source::Compute,
version + VERSION,
format,
computation,
indexes,
options,
)
.unwrap()
@@ -1,13 +1,13 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{Bitcoin, Dollars, Height, Result, Sats, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format, StoredVec};
use brk_vecs::{AnyCollectableVec, CollectableVec, Computation, EagerVec, File, Format, StoredVec};
use crate::vecs::{Indexes, fetched, indexes};
use crate::{Indexes, fetched, grouped::Source, indexes};
use super::{ComputedVecsFromHeight, StorableVecGeneatorOptions};
use super::{ComputedVecsFromHeight, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedValueVecsFromHeight {
@@ -19,39 +19,48 @@ pub struct ComputedValueVecsFromHeight {
const VERSION: Version = Version::ZERO;
impl ComputedValueVecsFromHeight {
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<Height, Sats>,
version: Version,
format: Format,
options: StorableVecGeneatorOptions,
computation: Computation,
options: VecBuilderOptions,
compute_dollars: bool,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
Ok(Self {
sats: ComputedVecsFromHeight::forced_import(
path,
file,
name,
compute_source,
source,
version + VERSION,
format,
computation,
indexes,
options,
)?,
bitcoin: ComputedVecsFromHeight::forced_import(
path,
file,
&format!("{name}_in_btc"),
true,
Source::Compute,
version + VERSION,
format,
computation,
indexes,
options,
)?,
dollars: compute_dollars.then(|| {
ComputedVecsFromHeight::forced_import(
path,
file,
&format!("{name}_in_usd"),
true,
Source::Compute,
version + VERSION,
format,
computation,
indexes,
options,
)
.unwrap()
@@ -1,16 +1,16 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{Bitcoin, Close, Dollars, Height, Sats, TxIndex, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{
AnyCollectableVec, BoxedAnyIterableVec, CloneableAnyIterableVec, CollectableVec, Computation,
ComputedVecFrom3, Format, LazyVecFrom1, StoredIndex, StoredVec,
use brk_vecs::{
AnyCollectableVec, CloneableAnyIterableVec, CollectableVec, Computation, ComputedVecFrom3,
File, Format, LazyVecFrom1, StoredIndex, StoredVec,
};
use crate::vecs::{Indexes, fetched, indexes};
use crate::{Indexes, fetched, grouped::Source, indexes};
use super::{ComputedVecsFromTxindex, StorableVecGeneatorOptions};
use super::{ComputedVecsFromTxindex, VecBuilderOptions};
#[derive(Clone)]
pub struct ComputedValueVecsFromTxindex {
@@ -38,35 +38,38 @@ const VERSION: Version = Version::ZERO;
impl ComputedValueVecsFromTxindex {
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
indexes: &indexes::Vecs,
source: Option<BoxedAnyIterableVec<TxIndex, Sats>>,
source: Source<TxIndex, Sats>,
version: Version,
computation: Computation,
format: Format,
fetched: Option<&fetched::Vecs>,
options: StorableVecGeneatorOptions,
options: VecBuilderOptions,
) -> color_eyre::Result<Self> {
let compute_source = source.is_none();
let compute_dollars = fetched.is_some();
let name_in_btc = format!("{name}_in_btc");
let name_in_usd = format!("{name}_in_usd");
let sats = ComputedVecsFromTxindex::forced_import(
path,
file,
name,
compute_source,
source.clone(),
version + VERSION,
format,
computation,
indexes,
options,
)?;
let source_vec = source.vec();
let bitcoin_txindex = LazyVecFrom1::init(
&name_in_btc,
version + VERSION,
source.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
source_vec.map_or_else(|| sats.txindex.as_ref().unwrap().boxed_clone(), |s| s),
|txindex: TxIndex, iter| {
iter.next_at(txindex.unwrap_to_usize()).map(|(_, value)| {
let sats = value.into_owned();
@@ -76,18 +79,20 @@ impl ComputedValueVecsFromTxindex {
);
let bitcoin = ComputedVecsFromTxindex::forced_import(
path,
file,
&name_in_btc,
false,
Source::None,
version + VERSION,
format,
computation,
indexes,
options,
)?;
let dollars_txindex = fetched.map(|fetched| {
ComputedVecFrom3::forced_import_or_init_from_3(
computation,
path,
file,
&name_in_usd,
version + VERSION,
format,
@@ -122,11 +127,13 @@ impl ComputedValueVecsFromTxindex {
dollars_txindex,
dollars: compute_dollars.then(|| {
ComputedVecsFromTxindex::forced_import(
path,
file,
&name_in_usd,
false,
Source::None,
version + VERSION,
format,
computation,
indexes,
options,
)
.unwrap()
@@ -1,11 +1,11 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{Bitcoin, Dollars, Height, Result, Sats, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, CollectableVec, EagerVec, Format, StoredVec};
use brk_vecs::{AnyCollectableVec, CollectableVec, EagerVec, File, Format, StoredVec};
use crate::vecs::{Indexes, fetched, indexes};
use crate::{Indexes, fetched, grouped::Source, indexes};
#[derive(Clone)]
pub struct ComputedHeightValueVecs {
@@ -18,27 +18,27 @@ const VERSION: Version = Version::ZERO;
impl ComputedHeightValueVecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
name: &str,
compute_source: bool,
source: Source<Height, Sats>,
version: Version,
format: Format,
compute_dollars: bool,
) -> color_eyre::Result<Self> {
Ok(Self {
sats: compute_source.then(|| {
EagerVec::forced_import(path, name, version + VERSION + Version::ZERO, format)
sats: source.is_compute().then(|| {
EagerVec::forced_import(file, name, version + VERSION + Version::ZERO, format)
.unwrap()
}),
bitcoin: EagerVec::forced_import(
path,
file,
&format!("{name}_in_btc"),
version + VERSION + Version::ZERO,
format,
)?,
dollars: compute_dollars.then(|| {
EagerVec::forced_import(
path,
file,
&format!("{name}_in_usd"),
version + VERSION + Version::ZERO,
format,
@@ -1,22 +1,20 @@
use std::{ops::Deref, path::Path};
use std::{ops::Deref, sync::Arc};
use brk_core::{
Date, DateIndex, DecadeIndex, DifficultyEpoch, EmptyOutputIndex, HalvingEpoch, Height,
InputIndex, MonthIndex, OpReturnIndex, OutputIndex, P2AAddressIndex, P2ABytes, P2MSOutputIndex,
P2PK33AddressIndex, P2PK33Bytes, P2PK65AddressIndex, P2PK65Bytes, P2PKHAddressIndex,
P2PKHBytes, P2SHAddressIndex, P2SHBytes, P2TRAddressIndex, P2TRBytes, P2WPKHAddressIndex,
P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, QuarterIndex, Sats, StoredUsize, Timestamp,
TxIndex, Txid, UnknownOutputIndex, Version, WeekIndex, YearIndex,
P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, QuarterIndex, Sats, SemesterIndex, StoredUsize,
Timestamp, TxIndex, Txid, UnknownOutputIndex, Version, WeekIndex, YearIndex,
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{
use brk_vecs::{
AnyCollectableVec, CloneableAnyIterableVec, Computation, ComputedVec, ComputedVecFrom1,
ComputedVecFrom2, EagerVec, Format, StoredIndex, VecIterator,
ComputedVecFrom2, EagerVec, File, Format, StoredIndex, VecIterator,
};
use crate::vecs::indexes;
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
@@ -50,6 +48,7 @@ pub struct Vecs {
pub monthindex_to_first_dateindex: EagerVec<MonthIndex, DateIndex>,
pub monthindex_to_monthindex: EagerVec<MonthIndex, MonthIndex>,
pub monthindex_to_quarterindex: EagerVec<MonthIndex, QuarterIndex>,
pub monthindex_to_semesterindex: EagerVec<MonthIndex, SemesterIndex>,
pub monthindex_to_yearindex: EagerVec<MonthIndex, YearIndex>,
pub opreturnindex_to_opreturnindex:
ComputedVecFrom1<OpReturnIndex, OpReturnIndex, OpReturnIndex, TxIndex>,
@@ -76,6 +75,9 @@ pub struct Vecs {
pub quarterindex_to_first_monthindex: EagerVec<QuarterIndex, MonthIndex>,
pub quarterindex_to_monthindex_count: EagerVec<QuarterIndex, StoredUsize>,
pub quarterindex_to_quarterindex: EagerVec<QuarterIndex, QuarterIndex>,
pub semesterindex_to_first_monthindex: EagerVec<SemesterIndex, MonthIndex>,
pub semesterindex_to_monthindex_count: EagerVec<SemesterIndex, StoredUsize>,
pub semesterindex_to_semesterindex: EagerVec<SemesterIndex, SemesterIndex>,
pub txindex_to_height: EagerVec<TxIndex, Height>,
pub txindex_to_input_count:
ComputedVecFrom2<TxIndex, StoredUsize, TxIndex, InputIndex, InputIndex, OutputIndex>,
@@ -95,7 +97,7 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
indexer: &Indexer,
computation: Computation,
@@ -103,7 +105,7 @@ impl Vecs {
) -> color_eyre::Result<Self> {
let outputindex_to_outputindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"outputindex",
version + VERSION + Version::ZERO,
format,
@@ -113,7 +115,7 @@ impl Vecs {
let inputindex_to_inputindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"inputindex",
version + VERSION + Version::ZERO,
format,
@@ -123,7 +125,7 @@ impl Vecs {
let txindex_to_txindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"txindex",
version + VERSION + Version::ZERO,
format,
@@ -133,7 +135,7 @@ impl Vecs {
let txindex_to_input_count = ComputedVec::forced_import_or_init_from_2(
computation,
path,
file,
"input_count",
version + VERSION + Version::ZERO,
format,
@@ -156,7 +158,7 @@ impl Vecs {
let txindex_to_output_count = ComputedVec::forced_import_or_init_from_2(
computation,
path,
file,
"output_count",
version + VERSION + Version::ZERO,
format,
@@ -179,7 +181,7 @@ impl Vecs {
let p2pk33addressindex_to_p2pk33addressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2pk33addressindex",
version + VERSION + Version::ZERO,
format,
@@ -188,7 +190,7 @@ impl Vecs {
)?;
let p2pk65addressindex_to_p2pk65addressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2pk65addressindex",
version + VERSION + Version::ZERO,
format,
@@ -197,7 +199,7 @@ impl Vecs {
)?;
let p2pkhaddressindex_to_p2pkhaddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2pkhaddressindex",
version + VERSION + Version::ZERO,
format,
@@ -206,7 +208,7 @@ impl Vecs {
)?;
let p2shaddressindex_to_p2shaddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2shaddressindex",
version + VERSION + Version::ZERO,
format,
@@ -215,7 +217,7 @@ impl Vecs {
)?;
let p2traddressindex_to_p2traddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2traddressindex",
version + VERSION + Version::ZERO,
format,
@@ -224,7 +226,7 @@ impl Vecs {
)?;
let p2wpkhaddressindex_to_p2wpkhaddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2wpkhaddressindex",
version + VERSION + Version::ZERO,
format,
@@ -233,7 +235,7 @@ impl Vecs {
)?;
let p2wshaddressindex_to_p2wshaddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2wshaddressindex",
version + VERSION + Version::ZERO,
format,
@@ -242,7 +244,7 @@ impl Vecs {
)?;
let p2aaddressindex_to_p2aaddressindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2aaddressindex",
version + VERSION + Version::ZERO,
format,
@@ -251,7 +253,7 @@ impl Vecs {
)?;
let p2msoutputindex_to_p2msoutputindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"p2msoutputindex",
version + VERSION + Version::ZERO,
format,
@@ -260,7 +262,7 @@ impl Vecs {
)?;
let emptyoutputindex_to_emptyoutputindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"emptyoutputindex",
version + VERSION + Version::ZERO,
format,
@@ -269,7 +271,7 @@ impl Vecs {
)?;
let unknownoutputindex_to_unknownoutputindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"unknownoutputindex",
version + VERSION + Version::ZERO,
format,
@@ -278,7 +280,7 @@ impl Vecs {
)?;
let opreturnindex_to_opreturnindex = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"opreturnindex",
version + VERSION + Version::ZERO,
format,
@@ -306,235 +308,259 @@ impl Vecs {
unknownoutputindex_to_unknownoutputindex,
dateindex_to_date: EagerVec::forced_import(
path,
file,
"date",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_dateindex: EagerVec::forced_import(
path,
file,
"dateindex",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_first_height: EagerVec::forced_import(
path,
file,
"first_height",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_monthindex: EagerVec::forced_import(
path,
file,
"monthindex",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_weekindex: EagerVec::forced_import(
path,
file,
"weekindex",
version + VERSION + Version::ZERO,
format,
)?,
decadeindex_to_decadeindex: EagerVec::forced_import(
path,
file,
"decadeindex",
version + VERSION + Version::ZERO,
format,
)?,
decadeindex_to_first_yearindex: EagerVec::forced_import(
path,
file,
"first_yearindex",
version + VERSION + Version::ZERO,
format,
)?,
difficultyepoch_to_difficultyepoch: EagerVec::forced_import(
path,
file,
"difficultyepoch",
version + VERSION + Version::ZERO,
format,
)?,
difficultyepoch_to_first_height: EagerVec::forced_import(
path,
file,
"first_height",
version + VERSION + Version::ZERO,
format,
)?,
halvingepoch_to_first_height: EagerVec::forced_import(
path,
file,
"first_height",
version + VERSION + Version::ZERO,
format,
)?,
halvingepoch_to_halvingepoch: EagerVec::forced_import(
path,
file,
"halvingepoch",
version + VERSION + Version::ZERO,
format,
)?,
height_to_date: EagerVec::forced_import(
path,
file,
"date",
version + VERSION + Version::ZERO,
format,
)?,
height_to_difficultyepoch: EagerVec::forced_import(
path,
file,
"difficultyepoch",
version + VERSION + Version::ZERO,
format,
)?,
height_to_halvingepoch: EagerVec::forced_import(
path,
file,
"halvingepoch",
version + VERSION + Version::ZERO,
format,
)?,
height_to_height: EagerVec::forced_import(
path,
file,
"height",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_first_dateindex: EagerVec::forced_import(
path,
file,
"first_dateindex",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_monthindex: EagerVec::forced_import(
path,
file,
"monthindex",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_quarterindex: EagerVec::forced_import(
path,
file,
"quarterindex",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_semesterindex: EagerVec::forced_import(
file,
"semesterindex",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_yearindex: EagerVec::forced_import(
path,
file,
"yearindex",
version + VERSION + Version::ZERO,
format,
)?,
quarterindex_to_first_monthindex: EagerVec::forced_import(
path,
file,
"first_monthindex",
version + VERSION + Version::ZERO,
format,
)?,
semesterindex_to_first_monthindex: EagerVec::forced_import(
file,
"first_monthindex",
version + VERSION + Version::ZERO,
format,
)?,
weekindex_to_first_dateindex: EagerVec::forced_import(
path,
file,
"first_dateindex",
version + VERSION + Version::ZERO,
format,
)?,
yearindex_to_first_monthindex: EagerVec::forced_import(
path,
file,
"first_monthindex",
version + VERSION + Version::ZERO,
format,
)?,
quarterindex_to_quarterindex: EagerVec::forced_import(
path,
file,
"quarterindex",
version + VERSION + Version::ZERO,
format,
)?,
semesterindex_to_semesterindex: EagerVec::forced_import(
file,
"semesterindex",
version + VERSION + Version::ZERO,
format,
)?,
weekindex_to_weekindex: EagerVec::forced_import(
path,
file,
"weekindex",
version + VERSION + Version::ZERO,
format,
)?,
yearindex_to_decadeindex: EagerVec::forced_import(
path,
file,
"decadeindex",
version + VERSION + Version::ZERO,
format,
)?,
yearindex_to_yearindex: EagerVec::forced_import(
path,
file,
"yearindex",
version + VERSION + Version::ZERO,
format,
)?,
height_to_date_fixed: EagerVec::forced_import(
path,
file,
"date_fixed",
version + VERSION + Version::ZERO,
format,
)?,
height_to_dateindex: EagerVec::forced_import(
path,
file,
"dateindex",
version + VERSION + Version::ZERO,
format,
)?,
txindex_to_height: EagerVec::forced_import(
path,
file,
"height",
version + VERSION + Version::ZERO,
format,
)?,
height_to_timestamp_fixed: EagerVec::forced_import(
path,
file,
"timestamp_fixed",
version + VERSION + Version::ZERO,
format,
)?,
height_to_txindex_count: EagerVec::forced_import(
path,
file,
"txindex_count",
version + VERSION + Version::ZERO,
format,
)?,
dateindex_to_height_count: EagerVec::forced_import(
path,
file,
"height_count",
version + VERSION + Version::ZERO,
format,
)?,
weekindex_to_dateindex_count: EagerVec::forced_import(
path,
file,
"dateindex_count",
version + VERSION + Version::ZERO,
format,
)?,
difficultyepoch_to_height_count: EagerVec::forced_import(
path,
file,
"height_count",
version + VERSION + Version::ZERO,
format,
)?,
monthindex_to_dateindex_count: EagerVec::forced_import(
path,
file,
"dateindex_count",
version + VERSION + Version::ZERO,
format,
)?,
quarterindex_to_monthindex_count: EagerVec::forced_import(
path,
file,
"monthindex_count",
version + VERSION + Version::ZERO,
format,
)?,
semesterindex_to_monthindex_count: EagerVec::forced_import(
file,
"monthindex_count",
version + VERSION + Version::ZERO,
format,
)?,
yearindex_to_monthindex_count: EagerVec::forced_import(
path,
file,
"monthindex_count",
version + VERSION + Version::ZERO,
format,
)?,
decadeindex_to_yearindex_count: EagerVec::forced_import(
path,
file,
"yearindex_count",
version + VERSION + Version::ZERO,
format,
)?,
outputindex_to_txindex: EagerVec::forced_import(
path,
file,
"txindex",
version + VERSION + Version::ZERO,
format,
@@ -943,6 +969,45 @@ impl Vecs {
exit,
)?;
// ---
// SemesterIndex
// ---
let starting_semesterindex = self
.monthindex_to_semesterindex
.into_iter()
.get_inner(starting_monthindex)
.unwrap_or_default();
self.monthindex_to_semesterindex.compute_from_index(
starting_monthindex,
&self.monthindex_to_first_dateindex,
exit,
)?;
self.semesterindex_to_first_monthindex
.compute_inverse_more_to_less(
starting_monthindex,
&self.monthindex_to_semesterindex,
exit,
)?;
// let semester_count = self.semesterindex_to_first_monthindex.len();
self.semesterindex_to_semesterindex.compute_from_index(
starting_semesterindex,
&self.semesterindex_to_first_monthindex,
exit,
)?;
self.semesterindex_to_monthindex_count
.compute_count_from_indexes(
starting_semesterindex,
&self.semesterindex_to_first_monthindex,
&self.monthindex_to_monthindex,
exit,
)?;
// ---
// YearIndex
// ---
@@ -1051,6 +1116,7 @@ impl Vecs {
weekindex: starting_weekindex,
monthindex: starting_monthindex,
quarterindex: starting_quarterindex,
semesterindex: starting_semesterindex,
yearindex: starting_yearindex,
decadeindex: starting_decadeindex,
difficultyepoch: starting_difficultyepoch,
@@ -1088,6 +1154,7 @@ impl Vecs {
&self.monthindex_to_first_dateindex,
&self.monthindex_to_monthindex,
&self.monthindex_to_quarterindex,
&self.monthindex_to_semesterindex,
&self.monthindex_to_yearindex,
&self.opreturnindex_to_opreturnindex,
&self.outputindex_to_outputindex,
@@ -1103,6 +1170,9 @@ impl Vecs {
&self.quarterindex_to_first_monthindex,
&self.quarterindex_to_monthindex_count,
&self.quarterindex_to_quarterindex,
&self.semesterindex_to_first_monthindex,
&self.semesterindex_to_monthindex_count,
&self.semesterindex_to_semesterindex,
&self.txindex_to_height,
&self.txindex_to_txindex,
&self.txindex_to_input_count,
@@ -1126,6 +1196,7 @@ pub struct Indexes {
pub weekindex: WeekIndex,
pub monthindex: MonthIndex,
pub quarterindex: QuarterIndex,
pub semesterindex: SemesterIndex,
pub yearindex: YearIndex,
pub decadeindex: DecadeIndex,
pub difficultyepoch: DifficultyEpoch,
@@ -1133,7 +1204,7 @@ pub struct Indexes {
}
impl Indexes {
pub fn update_from_height(&mut self, height: Height, indexes: &indexes::Vecs) {
pub fn update_from_height(&mut self, height: Height, indexes: &Vecs) {
self.indexes.height = height;
self.dateindex = DateIndex::try_from(
indexes
@@ -1145,6 +1216,7 @@ impl Indexes {
self.weekindex = WeekIndex::from(self.dateindex);
self.monthindex = MonthIndex::from(self.dateindex);
self.quarterindex = QuarterIndex::from(self.monthindex);
self.semesterindex = SemesterIndex::from(self.monthindex);
self.yearindex = YearIndex::from(self.monthindex);
self.decadeindex = DecadeIndex::from(self.dateindex);
self.difficultyepoch = DifficultyEpoch::from(self.height);
+36 -24
View File
@@ -3,29 +3,38 @@
#![doc = include_str!("../examples/main.rs")]
#![doc = "```"]
use std::path::Path;
use std::{path::Path, sync::Arc};
use brk_core::Version;
use brk_exit::Exit;
use brk_fetcher::Fetcher;
use brk_indexer::Indexer;
use brk_vec::{Computation, Format};
use brk_vecs::{Computation, File, Format, PAGE_SIZE};
use log::info;
mod all;
mod blocks;
mod cointime;
mod constants;
mod fetched;
mod grouped;
mod indexes;
mod market;
mod mining;
mod stateful;
mod states;
mod stores;
mod transactions;
mod utils;
mod vecs;
use indexes::Indexes;
use states::*;
use stores::Stores;
use vecs::Vecs;
#[derive(Clone)]
pub struct Computer {
file: Arc<File>,
fetcher: Option<Fetcher>,
pub vecs: Vecs,
pub stores: Stores,
pub vecs: all::Vecs,
}
const VERSION: Version = Version::ONE;
@@ -39,23 +48,28 @@ impl Computer {
fetcher: Option<Fetcher>,
format: Format,
) -> color_eyre::Result<Self> {
let computed_path = outputs_dir.join("computed");
let states_path = computed_path.join("states");
let file = Arc::new(File::open(&computed_path.join("vecs"))?);
file.set_min_len(PAGE_SIZE * 100_000_000)?;
file.set_min_regions(50_000)?;
let file_fetched = Arc::new(File::open(&outputs_dir.join("fetched/vecs"))?);
Ok(Self {
vecs: Vecs::import(
// TODO: Give self.path, join inside import
&outputs_dir.join("vecs/computed"),
vecs: all::Vecs::import(
&file,
VERSION + Version::ZERO,
indexer,
fetcher.is_some(),
computation,
format,
)?,
stores: Stores::import(
// TODO: Give self.path, join inside import
&outputs_dir.join("stores"),
VERSION + Version::ZERO,
&indexer.stores.keyspace,
&file_fetched,
&states_path,
)?,
fetcher,
file,
})
}
}
@@ -68,12 +82,10 @@ impl Computer {
exit: &Exit,
) -> color_eyre::Result<()> {
info!("Computing...");
self.vecs.compute(
indexer,
starting_indexes,
self.fetcher.as_mut(),
exit,
&mut self.stores,
)
self.vecs
.compute(indexer, starting_indexes, self.fetcher.as_mut(), exit)?;
self.file.flush()?;
self.file.punch_holes()?;
Ok(())
}
}
File diff suppressed because it is too large Load Diff
@@ -1,13 +1,15 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{DifficultyEpoch, HalvingEpoch, StoredF64, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, Computation, Format, VecIterator};
use brk_vecs::{AnyCollectableVec, Computation, File, Format, VecIterator};
use crate::grouped::Source;
use super::{
Indexes,
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, StorableVecGeneatorOptions},
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions},
indexes,
};
@@ -22,35 +24,42 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
_computation: Computation,
computation: Computation,
format: Format,
indexes: &indexes::Vecs,
) -> color_eyre::Result<Self> {
Ok(Self {
indexes_to_difficulty: ComputedVecsFromHeight::forced_import(
path,
file,
"difficulty",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import(
path,
file,
"difficultyepoch",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import(
path,
file,
"halvingepoch",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
})
}
@@ -1,23 +1,21 @@
use std::{ops::Deref, path::Path};
use std::{ops::Deref, path::Path, sync::Arc};
use brk_core::{Bitcoin, DateIndex, Dollars, Height, Result, StoredUsize, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{
AnyCollectableVec, AnyIterableVec, AnyVec, Computation, EagerVec, Format, VecIterator,
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, AnyVec, Computation, EagerVec, File, Format, VecIterator,
};
use crate::{
states::AddressCohortState,
vecs::{
Indexes, fetched,
grouped::{ComputedVecsFromHeight, StorableVecGeneatorOptions},
indexes, market,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
},
Indexes, fetched,
grouped::{ComputedVecsFromHeight, Source, VecBuilderOptions},
indexes, market,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
},
states::AddressCohortState,
};
const VERSION: Version = Version::ZERO;
@@ -37,11 +35,12 @@ pub struct Vecs {
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
cohort_name: Option<&str>,
computation: Computation,
format: Format,
version: Version,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
states_path: &Path,
compute_relative_to_all: bool,
@@ -58,27 +57,31 @@ impl Vecs {
compute_dollars,
)?,
height_to_address_count: EagerVec::forced_import(
path,
file,
&suffix("address_count"),
version + VERSION + Version::ZERO,
format,
)?,
indexes_to_address_count: ComputedVecsFromHeight::forced_import(
path,
file,
&suffix("address_count"),
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
inner: common::Vecs::forced_import(
path,
file,
cohort_name,
computation,
format,
version,
indexes,
fetched,
compute_relative_to_all,
false,
)?,
})
}
@@ -1,16 +1,16 @@
use std::path::Path;
use std::{path::Path, sync::Arc};
use brk_core::{
AddressGroups, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, GroupFilter, Height,
Result, Version,
AddressGroups, Bitcoin, ByAmountRange, ByGreatEqualAmount, ByLowerThanAmount, DateIndex,
Dollars, GroupFilter, Height, Result, Version,
};
use brk_exit::Exit;
use brk_vec::{Computation, Format};
use brk_indexer::Indexer;
use brk_vecs::{AnyIterableVec, Computation, File, Format};
use derive_deref::{Deref, DerefMut};
use rayon::prelude::*;
use crate::vecs::{
Indexes, fetched,
use crate::{
Indexes, fetched, indexes, market,
stateful::{
address_cohort,
r#trait::{CohortVecs, DynCohortVecs},
@@ -24,10 +24,11 @@ pub struct Vecs(AddressGroups<(GroupFilter, address_cohort::Vecs)>);
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
_computation: Computation,
format: Format,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
states_path: &Path,
) -> color_eyre::Result<Self> {
@@ -35,151 +36,166 @@ impl Vecs {
AddressGroups {
amount_range: ByAmountRange {
_0sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_with_0sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1sat_to_10sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1sat_under_10sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10sats_to_100sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10sats_under_100sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100sats_to_1k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100sats_under_1k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_sats_to_10k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1k_sats_under_10k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_sats_to_100k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10k_sats_under_100k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100k_sats_to_1m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100k_sats_under_1m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1m_sats_to_10m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1m_sats_under_10m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10m_sats_to_1btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10m_sats_under_1btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1btc_to_10btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1btc_under_10btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10btc_to_100btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10btc_under_100btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100btc_to_1k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100btc_under_1k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_btc_to_10k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1k_btc_under_10k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_btc_to_100k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10k_btc_under_100k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100k_btc_or_more: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
@@ -187,131 +203,144 @@ impl Vecs {
},
lt_amount: ByLowerThanAmount {
_10sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_10sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_100sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_1k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_10k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_100k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_1m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_10m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_1btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_10btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_100btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_1k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_10k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_under_100k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
@@ -319,131 +348,144 @@ impl Vecs {
},
ge_amount: ByGreatEqualAmount {
_1sat: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1sat"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100k_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100k_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10m_sats: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10m_sats"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_100btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_100btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_1k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_1k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
)?,
_10k_btc: address_cohort::Vecs::forced_import(
path,
file,
Some("addrs_above_10k_btc"),
_computation,
format,
version + VERSION + Version::ZERO,
indexes,
fetched,
states_path,
true,
@@ -493,16 +535,61 @@ impl Vecs {
})
.collect::<Vec<_>>(),
]
.into_par_iter()
.into_iter()
.flatten()
.try_for_each(|(vecs, stateful)| {
vecs.compute_from_stateful(starting_indexes, &stateful, exit)
})
}
pub fn compute_rest_part1(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
starting_indexes: &Indexes,
exit: &Exit,
) -> color_eyre::Result<()> {
self.as_mut_vecs().into_iter().try_for_each(|(_, v)| {
v.compute_rest_part1(indexer, indexes, fetched, starting_indexes, exit)
})
}
#[allow(clippy::too_many_arguments)]
pub fn compute_rest_part2(
&mut self,
indexer: &Indexer,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
starting_indexes: &Indexes,
market: &market::Vecs,
height_to_supply: &impl AnyIterableVec<Height, Bitcoin>,
dateindex_to_supply: &impl AnyIterableVec<DateIndex, Bitcoin>,
height_to_realized_cap: Option<&impl AnyIterableVec<Height, Dollars>>,
dateindex_to_realized_cap: Option<&impl AnyIterableVec<DateIndex, Dollars>>,
exit: &Exit,
) -> color_eyre::Result<()> {
self.0.as_boxed_mut_vecs().into_iter().try_for_each(|v| {
v.into_iter().try_for_each(|(_, v)| {
v.compute_rest_part2(
indexer,
indexes,
fetched,
starting_indexes,
market,
height_to_supply,
dateindex_to_supply,
height_to_realized_cap,
dateindex_to_realized_cap,
exit,
)
})
})
}
pub fn safe_flush_stateful_vecs(&mut self, height: Height, exit: &Exit) -> Result<()> {
self.as_mut_separate_vecs()
.par_iter_mut()
.into_iter()
.try_for_each(|(_, v)| v.safe_flush_stateful_vecs(height, exit))
}
}
@@ -1,8 +1,8 @@
use brk_core::{ByAddressType, Height};
use brk_vec::VecIterator;
use brk_vecs::VecIterator;
use derive_deref::{Deref, DerefMut};
use crate::vecs::stateful::addresstype_to_height_to_addresscount::AddressTypeToHeightToAddressCount;
use crate::stateful::addresstype_to_height_to_addresscount::AddressTypeToHeightToAddressCount;
#[derive(Debug, Default, Deref, DerefMut)]
pub struct AddressTypeToAddressCount(ByAddressType<usize>);
@@ -1,9 +1,9 @@
use brk_core::{ByAddressType, Height, Result, StoredUsize};
use brk_exit::Exit;
use brk_vec::EagerVec;
use brk_vecs::EagerVec;
use derive_deref::{Deref, DerefMut};
use crate::vecs::stateful::addresstype_to_addresscount::AddressTypeToAddressCount;
use crate::stateful::addresstype_to_addresscount::AddressTypeToAddressCount;
#[derive(Debug, Clone, Deref, DerefMut)]
pub struct AddressTypeToHeightToAddressCount(ByAddressType<EagerVec<Height, StoredUsize>>);
@@ -1,9 +1,9 @@
use brk_core::{ByAddressType, StoredUsize};
use brk_exit::Exit;
use brk_vec::AnyCollectableVec;
use brk_vecs::AnyCollectableVec;
use derive_deref::{Deref, DerefMut};
use crate::vecs::{
use crate::{
Indexes, grouped::ComputedVecsFromHeight, indexes,
stateful::addresstype_to_height_to_addresscount::AddressTypeToHeightToAddressCount,
};
@@ -0,0 +1,24 @@
use std::collections::BTreeSet;
use brk_core::TypeIndex;
use derive_deref::{Deref, DerefMut};
use super::ByAddressType;
#[derive(Debug, Deref, DerefMut)]
pub struct AddressTypeToTypeIndexSet(ByAddressType<BTreeSet<TypeIndex>>);
impl Default for AddressTypeToTypeIndexSet {
fn default() -> Self {
Self(ByAddressType {
p2pk65: BTreeSet::default(),
p2pk33: BTreeSet::default(),
p2pkh: BTreeSet::default(),
p2sh: BTreeSet::default(),
p2wpkh: BTreeSet::default(),
p2wsh: BTreeSet::default(),
p2tr: BTreeSet::default(),
p2a: BTreeSet::default(),
})
}
}
@@ -9,7 +9,7 @@ use super::ByAddressType;
pub struct AddressTypeToTypeIndexTree<T>(ByAddressType<BTreeMap<TypeIndex, T>>);
impl<T> AddressTypeToTypeIndexTree<T> {
pub fn merge(&mut self, mut other: Self) {
pub fn merge(mut self, mut other: Self) -> Self {
Self::merge_(&mut self.p2pk65, &mut other.p2pk65);
Self::merge_(&mut self.p2pk33, &mut other.p2pk33);
Self::merge_(&mut self.p2pkh, &mut other.p2pkh);
@@ -18,6 +18,7 @@ impl<T> AddressTypeToTypeIndexTree<T> {
Self::merge_(&mut self.p2wsh, &mut other.p2wsh);
Self::merge_(&mut self.p2tr, &mut other.p2tr);
Self::merge_(&mut self.p2a, &mut other.p2a);
self
}
fn merge_(own: &mut BTreeMap<TypeIndex, T>, other: &mut BTreeMap<TypeIndex, T>) {
@@ -28,10 +29,6 @@ impl<T> AddressTypeToTypeIndexTree<T> {
mem::swap(own, other);
}
}
pub fn unwrap(self) -> ByAddressType<BTreeMap<TypeIndex, T>> {
self.0
}
}
impl<T> Default for AddressTypeToTypeIndexTree<T> {
@@ -0,0 +1,57 @@
use std::mem;
use derive_deref::{Deref, DerefMut};
use super::ByAddressType;
#[derive(Debug, Deref, DerefMut)]
pub struct AddressTypeToVec<T>(ByAddressType<Vec<T>>);
impl<T> AddressTypeToVec<T> {
pub fn merge(mut self, mut other: Self) -> Self {
Self::merge_(&mut self.p2pk65, &mut other.p2pk65);
Self::merge_(&mut self.p2pk33, &mut other.p2pk33);
Self::merge_(&mut self.p2pkh, &mut other.p2pkh);
Self::merge_(&mut self.p2sh, &mut other.p2sh);
Self::merge_(&mut self.p2wpkh, &mut other.p2wpkh);
Self::merge_(&mut self.p2wsh, &mut other.p2wsh);
Self::merge_(&mut self.p2tr, &mut other.p2tr);
Self::merge_(&mut self.p2a, &mut other.p2a);
self
}
pub fn merge_mut(&mut self, mut other: Self) {
Self::merge_(&mut self.p2pk65, &mut other.p2pk65);
Self::merge_(&mut self.p2pk33, &mut other.p2pk33);
Self::merge_(&mut self.p2pkh, &mut other.p2pkh);
Self::merge_(&mut self.p2sh, &mut other.p2sh);
Self::merge_(&mut self.p2wpkh, &mut other.p2wpkh);
Self::merge_(&mut self.p2wsh, &mut other.p2wsh);
Self::merge_(&mut self.p2tr, &mut other.p2tr);
Self::merge_(&mut self.p2a, &mut other.p2a);
}
fn merge_(own: &mut Vec<T>, other: &mut Vec<T>) {
if own.len() >= other.len() {
own.append(other);
} else {
other.append(own);
mem::swap(own, other);
}
}
}
impl<T> Default for AddressTypeToVec<T> {
fn default() -> Self {
Self(ByAddressType {
p2pk65: vec![],
p2pk33: vec![],
p2pkh: vec![],
p2sh: vec![],
p2wpkh: vec![],
p2wsh: vec![],
p2tr: vec![],
p2a: vec![],
})
}
}
@@ -0,0 +1,9 @@
use std::collections::BTreeMap;
use brk_core::Height;
use derive_deref::{Deref, DerefMut};
use crate::stateful::AddressTypeToVec;
#[derive(Debug, Default, Deref, DerefMut)]
pub struct HeightToAddressTypeToVec<T>(pub BTreeMap<Height, AddressTypeToVec<T>>);
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,35 @@
use std::collections::BTreeMap;
use brk_vecs::{StampedVec, StoredIndex, StoredType};
#[derive(Debug)]
pub struct RangeMap<I, T>(BTreeMap<I, T>);
impl<I, T> RangeMap<I, T>
where
I: StoredIndex,
T: StoredIndex,
{
pub fn get(&self, key: I) -> Option<&T> {
self.0.range(..=key).next_back().map(|(&min, value)| {
if min > key {
unreachable!()
}
value
})
}
}
impl<I, T> From<&StampedVec<I, T>> for RangeMap<T, I>
where
I: StoredIndex,
T: StoredIndex + StoredType,
{
fn from(vec: &StampedVec<I, T>) -> Self {
Self(
vec.into_iter()
.map(|(i, v)| (v.into_owned(), i))
.collect::<BTreeMap<_, _>>(),
)
}
}
@@ -1,9 +1,9 @@
use brk_core::{Bitcoin, DateIndex, Dollars, Height, Result, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec};
use brk_vecs::{AnyCollectableVec, AnyIterableVec};
use crate::vecs::{Indexes, fetched, indexes, market};
use crate::{Indexes, fetched, indexes, market};
pub trait DynCohortVecs: Send + Sync {
fn starting_height(&self) -> Height;
@@ -1,18 +1,15 @@
use std::{ops::Deref, path::Path};
use std::{ops::Deref, path::Path, sync::Arc};
use brk_core::{Bitcoin, DateIndex, Dollars, Height, Result, Version};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{AnyCollectableVec, AnyIterableVec, Computation, Format};
use brk_vecs::{AnyCollectableVec, AnyIterableVec, Computation, File, Format};
use crate::{
UTXOCohortState,
vecs::{
Indexes, fetched, indexes, market,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
},
Indexes, UTXOCohortState, fetched, indexes, market,
stateful::{
common,
r#trait::{CohortVecs, DynCohortVecs},
},
};
@@ -28,14 +25,16 @@ pub struct Vecs {
impl Vecs {
#[allow(clippy::too_many_arguments)]
pub fn forced_import(
path: &Path,
file: &Arc<File>,
cohort_name: Option<&str>,
computation: Computation,
format: Format,
version: Version,
indexes: &indexes::Vecs,
fetched: Option<&fetched::Vecs>,
states_path: &Path,
compute_relative_to_all: bool,
ratio_extended: bool,
) -> color_eyre::Result<Self> {
let compute_dollars = fetched.is_some();
@@ -49,13 +48,15 @@ impl Vecs {
)?,
inner: common::Vecs::forced_import(
path,
file,
cohort_name,
computation,
format,
version,
indexes,
fetched,
compute_relative_to_all,
ratio_extended,
)?,
})
}
@@ -0,0 +1,54 @@
use brk_core::{EmptyAddressData, EmptyAddressIndex, LoadedAddressData, LoadedAddressIndex};
#[derive(Debug)]
pub enum WithAddressDataSource<T> {
New(T),
FromLoadedAddressDataVec((LoadedAddressIndex, T)),
FromEmptyAddressDataVec((EmptyAddressIndex, T)),
}
impl<T> WithAddressDataSource<T> {
pub fn is_new(&self) -> bool {
matches!(self, Self::New(_))
}
pub fn is_from_emptyaddressdata(&self) -> bool {
matches!(self, Self::FromEmptyAddressDataVec(_))
}
pub fn deref_mut(&mut self) -> &mut T {
match self {
Self::New(v) => v,
Self::FromLoadedAddressDataVec((_, v)) => v,
Self::FromEmptyAddressDataVec((_, v)) => v,
}
}
}
impl From<WithAddressDataSource<EmptyAddressData>> for WithAddressDataSource<LoadedAddressData> {
fn from(value: WithAddressDataSource<EmptyAddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),
WithAddressDataSource::FromLoadedAddressDataVec((i, v)) => {
Self::FromLoadedAddressDataVec((i, v.into()))
}
WithAddressDataSource::FromEmptyAddressDataVec((i, v)) => {
Self::FromEmptyAddressDataVec((i, v.into()))
}
}
}
}
impl From<WithAddressDataSource<LoadedAddressData>> for WithAddressDataSource<EmptyAddressData> {
fn from(value: WithAddressDataSource<LoadedAddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),
WithAddressDataSource::FromLoadedAddressDataVec((i, v)) => {
Self::FromLoadedAddressDataVec((i, v.into()))
}
WithAddressDataSource::FromEmptyAddressDataVec((i, v)) => {
Self::FromEmptyAddressDataVec((i, v.into()))
}
}
}
}
@@ -1,6 +1,6 @@
use std::path::Path;
use brk_core::{AddressData, Dollars, Height, Result, Sats};
use brk_core::{Dollars, Height, LoadedAddressData, Result, Sats};
use crate::SupplyState;
@@ -35,7 +35,7 @@ impl AddressCohortState {
#[allow(clippy::too_many_arguments)]
pub fn send(
&mut self,
addressdata: &mut AddressData,
addressdata: &mut LoadedAddressData,
value: Sats,
current_price: Option<Dollars>,
prev_price: Option<Dollars>,
@@ -72,7 +72,12 @@ impl AddressCohortState {
Ok(())
}
pub fn receive(&mut self, address_data: &mut AddressData, value: Sats, price: Option<Dollars>) {
pub fn receive(
&mut self,
address_data: &mut LoadedAddressData,
value: Sats,
price: Option<Dollars>,
) {
let compute_price = price.is_some();
let prev_realized_price = compute_price.then(|| address_data.realized_price());
@@ -96,7 +101,7 @@ impl AddressCohortState {
);
}
pub fn add(&mut self, addressdata: &AddressData) {
pub fn add(&mut self, addressdata: &LoadedAddressData) {
self.address_count += 1;
self.inner.increment_(
&addressdata.into(),
@@ -105,7 +110,7 @@ impl AddressCohortState {
);
}
pub fn subtract(&mut self, addressdata: &AddressData) {
pub fn subtract(&mut self, addressdata: &LoadedAddressData) {
self.address_count = self.address_count.checked_sub(1).unwrap();
self.inner.decrement_(
&addressdata.into(),
@@ -223,17 +223,15 @@ impl CohortState {
let update_state =
|price: Dollars, current_price: Dollars, sats: Sats, state: &mut UnrealizedState| {
match price.cmp(&current_price) {
Ordering::Equal => {
state.supply_even += sats;
}
Ordering::Less => {
state.supply_in_profit += sats;
if price > Dollars::ZERO && current_price > Dollars::ZERO {
let diff = current_price.checked_sub(price).unwrap();
if diff <= Dollars::ZERO {
dbg!(price, current_price, diff, sats);
panic!();
}
// Add back once in a while to verify, but generally not needed
// if diff <= Dollars::ZERO {
// dbg!(price, current_price, diff, sats);
// panic!();
// }
state.unrealized_profit += diff * sats;
}
}
@@ -241,13 +239,17 @@ impl CohortState {
state.supply_in_loss += sats;
if price > Dollars::ZERO && current_price > Dollars::ZERO {
let diff = price.checked_sub(current_price).unwrap();
if diff <= Dollars::ZERO {
dbg!(price, current_price, diff, sats);
panic!();
}
// Add back once in a while to verify, but generally not needed
// if diff <= Dollars::ZERO {
// dbg!(price, current_price, diff, sats);
// panic!();
// }
state.unrealized_loss += diff * sats;
}
}
Ordering::Equal => {
state.supply_even += sats;
}
}
};
@@ -87,12 +87,12 @@ impl PriceToAmount {
self.height = Some(height);
height.write(&self.path_height())?;
let config = config::standard();
let file = File::create(self.path_state()).inspect_err(|_| {
dbg!(self.path_state());
})?;
let mut writer = BufWriter::new(file);
encode_into_std_write(&self.state, &mut writer, config)?;
encode_into_std_write(&self.state, &mut writer, config::standard())?;
Ok(())
}
+3 -3
View File
@@ -1,6 +1,6 @@
use std::ops::{Add, AddAssign, SubAssign};
use brk_core::{AddressData, CheckedSub, Sats};
use brk_core::{CheckedSub, LoadedAddressData, Sats};
use serde::Serialize;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -40,8 +40,8 @@ impl SubAssign<&SupplyState> for SupplyState {
}
}
impl From<&AddressData> for SupplyState {
fn from(value: &AddressData) -> Self {
impl From<&LoadedAddressData> for SupplyState {
fn from(value: &LoadedAddressData) -> Self {
Self {
utxos: value.outputs_len as usize,
value: value.amount(),
-647
View File
@@ -1,647 +0,0 @@
use std::{path::Path, thread};
use brk_core::{
AddressData, ByAddressType, EmptyAddressData, Height, OutputType, P2AAddressIndex,
P2PK33AddressIndex, P2PK65AddressIndex, P2PKHAddressIndex, P2SHAddressIndex, P2TRAddressIndex,
P2WPKHAddressIndex, P2WSHAddressIndex, Result, TypeIndex, Version,
};
use brk_store::{AnyStore, Store};
use fjall::{PersistMode, TransactionalKeyspace};
use log::info;
use crate::vecs::stateful::{AddressTypeToTypeIndexTree, WithAddressDataSource};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
pub struct Stores {
keyspace: TransactionalKeyspace,
pub p2aaddressindex_to_addressdata: Store<P2AAddressIndex, AddressData>,
pub p2aaddressindex_to_emptyaddressdata: Store<P2AAddressIndex, EmptyAddressData>,
pub p2pk33addressindex_to_addressdata: Store<P2PK33AddressIndex, AddressData>,
pub p2pk33addressindex_to_emptyaddressdata: Store<P2PK33AddressIndex, EmptyAddressData>,
pub p2pk65addressindex_to_addressdata: Store<P2PK65AddressIndex, AddressData>,
pub p2pk65addressindex_to_emptyaddressdata: Store<P2PK65AddressIndex, EmptyAddressData>,
pub p2pkhaddressindex_to_addressdata: Store<P2PKHAddressIndex, AddressData>,
pub p2pkhaddressindex_to_emptyaddressdata: Store<P2PKHAddressIndex, EmptyAddressData>,
pub p2shaddressindex_to_addressdata: Store<P2SHAddressIndex, AddressData>,
pub p2shaddressindex_to_emptyaddressdata: Store<P2SHAddressIndex, EmptyAddressData>,
pub p2traddressindex_to_addressdata: Store<P2TRAddressIndex, AddressData>,
pub p2traddressindex_to_emptyaddressdata: Store<P2TRAddressIndex, EmptyAddressData>,
pub p2wpkhaddressindex_to_addressdata: Store<P2WPKHAddressIndex, AddressData>,
pub p2wpkhaddressindex_to_emptyaddressdata: Store<P2WPKHAddressIndex, EmptyAddressData>,
pub p2wshaddressindex_to_addressdata: Store<P2WSHAddressIndex, AddressData>,
pub p2wshaddressindex_to_emptyaddressdata: Store<P2WSHAddressIndex, EmptyAddressData>,
}
impl Stores {
pub fn import(
path: &Path,
version: Version,
keyspace: &TransactionalKeyspace,
) -> color_eyre::Result<Self> {
let (
(p2aaddressindex_to_addressdata, p2aaddressindex_to_emptyaddressdata),
(p2pk33addressindex_to_addressdata, p2pk33addressindex_to_emptyaddressdata),
(p2pk65addressindex_to_addressdata, p2pk65addressindex_to_emptyaddressdata),
(p2pkhaddressindex_to_addressdata, p2pkhaddressindex_to_emptyaddressdata),
(p2shaddressindex_to_addressdata, p2shaddressindex_to_emptyaddressdata),
(p2traddressindex_to_addressdata, p2traddressindex_to_emptyaddressdata),
(p2wpkhaddressindex_to_addressdata, p2wpkhaddressindex_to_emptyaddressdata),
(p2wshaddressindex_to_addressdata, p2wshaddressindex_to_emptyaddressdata),
) = thread::scope(|scope| {
let p2a = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2aaddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2aaddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2pk33 = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2pk33addressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2pk33addressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2pk65 = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2pk65addressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2pk65addressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2pkh = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2pkhaddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2pkhaddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2sh = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2shaddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2shaddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2tr = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2traddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2traddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2wpkh = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2wpkhaddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2wpkhaddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
let p2wsh = scope.spawn(|| {
(
Store::import(
keyspace,
path,
"p2wshaddressindex_to_addressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
Store::import(
keyspace,
path,
"p2wshaddressindex_to_emptyaddressdata",
version + VERSION + Version::ZERO,
None,
)
.unwrap(),
)
});
(
p2a.join().unwrap(),
p2pk33.join().unwrap(),
p2pk65.join().unwrap(),
p2pkh.join().unwrap(),
p2sh.join().unwrap(),
p2tr.join().unwrap(),
p2wpkh.join().unwrap(),
p2wsh.join().unwrap(),
)
});
Ok(Self {
keyspace: keyspace.clone(),
p2aaddressindex_to_addressdata,
p2aaddressindex_to_emptyaddressdata,
p2pk33addressindex_to_addressdata,
p2pk33addressindex_to_emptyaddressdata,
p2pk65addressindex_to_addressdata,
p2pk65addressindex_to_emptyaddressdata,
p2pkhaddressindex_to_addressdata,
p2pkhaddressindex_to_emptyaddressdata,
p2shaddressindex_to_addressdata,
p2shaddressindex_to_emptyaddressdata,
p2traddressindex_to_addressdata,
p2traddressindex_to_emptyaddressdata,
p2wpkhaddressindex_to_addressdata,
p2wpkhaddressindex_to_emptyaddressdata,
p2wshaddressindex_to_addressdata,
p2wshaddressindex_to_emptyaddressdata,
})
}
pub fn starting_height(&self) -> Height {
self.as_slice()
.into_iter()
.map(|store| store.height().map(Height::incremented).unwrap_or_default())
.min()
.unwrap()
}
pub fn reset(&mut self) -> Result<()> {
info!("Resetting stores...");
info!("> If it gets stuck here, stop the program and start it again");
self.as_mut_slice()
.into_iter()
.try_for_each(|store| store.reset())?;
self.keyspace
.persist(PersistMode::SyncAll)
.map_err(|e| e.into())
}
pub fn get_addressdata(
&self,
address_type: OutputType,
type_index: TypeIndex,
) -> Result<Option<AddressData>> {
Ok(match address_type {
OutputType::P2A => self
.p2aaddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PK33 => self
.p2pk33addressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PK65 => self
.p2pk65addressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PKH => self
.p2pkhaddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2SH => self
.p2shaddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2TR => self
.p2traddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2WPKH => self
.p2wpkhaddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2WSH => self
.p2wshaddressindex_to_addressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
_ => unreachable!(),
})
}
pub fn get_emptyaddressdata(
&self,
address_type: OutputType,
type_index: TypeIndex,
) -> Result<Option<EmptyAddressData>> {
Ok(match address_type {
OutputType::P2A => self
.p2aaddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PK33 => self
.p2pk33addressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PK65 => self
.p2pk65addressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2PKH => self
.p2pkhaddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2SH => self
.p2shaddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2TR => self
.p2traddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2WPKH => self
.p2wpkhaddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
OutputType::P2WSH => self
.p2wshaddressindex_to_emptyaddressdata
.get(&type_index.into())?
.map(|c| c.into_owned()),
_ => unreachable!(),
})
}
pub fn commit(
&mut self,
height: Height,
addresstype_to_typeindex_to_addressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<AddressData>,
>,
addresstype_to_typeindex_to_emptyaddressdata: AddressTypeToTypeIndexTree<
WithAddressDataSource<EmptyAddressData>,
>,
) -> Result<()> {
let ByAddressType {
p2pk65,
p2pk33,
p2pkh,
p2sh,
p2wpkh,
p2wsh,
p2tr,
p2a,
} = addresstype_to_typeindex_to_addressdata.unwrap();
let ByAddressType {
p2pk65: empty_p2pk65,
p2pk33: empty_p2pk33,
p2pkh: empty_p2pkh,
p2sh: empty_p2sh,
p2wpkh: empty_p2wpkh,
p2wsh: empty_p2wsh,
p2tr: empty_p2tr,
p2a: empty_p2a,
} = addresstype_to_typeindex_to_emptyaddressdata.unwrap();
thread::scope(|s| {
s.spawn(|| {
self.p2aaddressindex_to_addressdata.commit_(
height,
empty_p2a
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2a.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2pk33addressindex_to_addressdata.commit_(
height,
empty_p2pk33
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2pk33.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2pk65addressindex_to_addressdata.commit_(
height,
empty_p2pk65
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2pk65.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2pkhaddressindex_to_addressdata.commit_(
height,
empty_p2pkh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2pkh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2shaddressindex_to_addressdata.commit_(
height,
empty_p2sh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2sh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2traddressindex_to_addressdata.commit_(
height,
empty_p2tr
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2tr.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2wpkhaddressindex_to_addressdata.commit_(
height,
empty_p2wpkh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2wpkh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
s.spawn(|| {
self.p2wshaddressindex_to_addressdata.commit_(
height,
empty_p2wsh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_addressdata())
.map(|(typeindex, _)| (*typeindex).into()),
p2wsh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
});
thread::scope(|scope| {
scope.spawn(|| {
self.p2aaddressindex_to_emptyaddressdata.commit_(
height,
p2a.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2a.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2pk33addressindex_to_emptyaddressdata.commit_(
height,
p2pk33
.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2pk33.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2pk65addressindex_to_emptyaddressdata.commit_(
height,
p2pk65
.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2pk65.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2pkhaddressindex_to_emptyaddressdata.commit_(
height,
p2pkh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2pkh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2shaddressindex_to_emptyaddressdata.commit_(
height,
p2sh.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2sh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2traddressindex_to_emptyaddressdata.commit_(
height,
p2tr.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2tr.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2wpkhaddressindex_to_emptyaddressdata.commit_(
height,
p2wpkh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2wpkh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
scope.spawn(|| {
self.p2wshaddressindex_to_emptyaddressdata.commit_(
height,
p2wsh
.iter()
.filter(|(_, addressdata)| addressdata.is_from_emptyaddressdata())
.map(|(typeindex, _)| (*typeindex).into()),
empty_p2wsh.iter().map(|(typeindex, addressdata)| {
((*typeindex).into(), addressdata.deref().clone())
}),
)
});
});
self.keyspace
.persist(PersistMode::SyncAll)
.map_err(|e| e.into())
}
pub fn rotate_memtables(&self) {
self.as_slice()
.into_iter()
.for_each(|store| store.rotate_memtable());
}
pub fn as_slice(&self) -> [&(dyn AnyStore + Send + Sync); 16] {
[
&self.p2aaddressindex_to_addressdata,
&self.p2aaddressindex_to_emptyaddressdata,
&self.p2pk33addressindex_to_addressdata,
&self.p2pk33addressindex_to_emptyaddressdata,
&self.p2pk65addressindex_to_addressdata,
&self.p2pk65addressindex_to_emptyaddressdata,
&self.p2pkhaddressindex_to_addressdata,
&self.p2pkhaddressindex_to_emptyaddressdata,
&self.p2shaddressindex_to_addressdata,
&self.p2shaddressindex_to_emptyaddressdata,
&self.p2traddressindex_to_addressdata,
&self.p2traddressindex_to_emptyaddressdata,
&self.p2wpkhaddressindex_to_addressdata,
&self.p2wpkhaddressindex_to_emptyaddressdata,
&self.p2wshaddressindex_to_addressdata,
&self.p2wshaddressindex_to_emptyaddressdata,
]
}
fn as_mut_slice(&mut self) -> [&mut (dyn AnyStore + Send + Sync); 16] {
[
&mut self.p2aaddressindex_to_addressdata,
&mut self.p2aaddressindex_to_emptyaddressdata,
&mut self.p2pk33addressindex_to_addressdata,
&mut self.p2pk33addressindex_to_emptyaddressdata,
&mut self.p2pk65addressindex_to_addressdata,
&mut self.p2pk65addressindex_to_emptyaddressdata,
&mut self.p2pkhaddressindex_to_addressdata,
&mut self.p2pkhaddressindex_to_emptyaddressdata,
&mut self.p2shaddressindex_to_addressdata,
&mut self.p2shaddressindex_to_emptyaddressdata,
&mut self.p2traddressindex_to_addressdata,
&mut self.p2traddressindex_to_emptyaddressdata,
&mut self.p2wpkhaddressindex_to_addressdata,
&mut self.p2wpkhaddressindex_to_emptyaddressdata,
&mut self.p2wshaddressindex_to_addressdata,
&mut self.p2wshaddressindex_to_emptyaddressdata,
]
}
}
@@ -1,4 +1,4 @@
use std::path::Path;
use std::sync::Arc;
use brk_core::{
CheckedSub, Feerate, HalvingEpoch, Height, InputIndex, OutputIndex, Sats, StoredU32,
@@ -6,20 +6,18 @@ use brk_core::{
};
use brk_exit::Exit;
use brk_indexer::Indexer;
use brk_vec::{
use brk_vecs::{
AnyCollectableVec, AnyIterableVec, CloneableAnyIterableVec, Computation, ComputedVec,
ComputedVecFrom1, ComputedVecFrom2, ComputedVecFrom3, Format, StoredIndex, VecIterator,
ComputedVecFrom1, ComputedVecFrom2, ComputedVecFrom3, File, Format, StoredIndex, VecIterator,
};
use super::{
Indexes, fetched,
grouped::{
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromHeight,
ComputedVecsFromTxindex, StorableVecGeneatorOptions,
},
indexes,
use crate::grouped::{
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromHeight,
ComputedVecsFromTxindex, Source, VecBuilderOptions,
};
use super::{Indexes, fetched, indexes};
const VERSION: Version = Version::ZERO;
#[derive(Clone)]
@@ -88,7 +86,7 @@ pub struct Vecs {
impl Vecs {
pub fn forced_import(
path: &Path,
file: &Arc<File>,
version: Version,
indexer: &Indexer,
indexes: &indexes::Vecs,
@@ -100,7 +98,7 @@ impl Vecs {
let inputindex_to_value = ComputedVec::forced_import_or_init_from_2(
computation,
path,
file,
"value",
version + VERSION + Version::ZERO,
format,
@@ -127,7 +125,7 @@ impl Vecs {
let txindex_to_weight = ComputedVec::forced_import_or_init_from_2(
computation,
path,
file,
"weight",
version + VERSION + Version::ZERO,
format,
@@ -155,7 +153,7 @@ impl Vecs {
let txindex_to_vsize = ComputedVec::forced_import_or_init_from_1(
computation,
path,
file,
"vsize",
version + VERSION + Version::ZERO,
format,
@@ -172,7 +170,7 @@ impl Vecs {
let txindex_to_is_coinbase = ComputedVec::forced_import_or_init_from_2(
computation,
path,
file,
"is_coinbase",
version + VERSION + Version::ZERO,
format,
@@ -196,7 +194,7 @@ impl Vecs {
let txindex_to_input_value = ComputedVec::forced_import_or_init_from_3(
computation,
path,
file,
"input_value",
version + VERSION + Version::ZERO,
format,
@@ -232,12 +230,13 @@ impl Vecs {
// let indexes_to_input_value: ComputedVecsFromTxindex<Sats> =
// ComputedVecsFromTxindex::forced_import(
// path,
// file,
// "input_value",
// true,
// version + VERSION + Version::ZERO,
// format,
// StorableVecGeneatorOptions::default()
// computation,
// StorableVecGeneatorOptions::default()
// .add_average()
// .add_sum()
// .add_cumulative(),
@@ -245,7 +244,7 @@ impl Vecs {
let txindex_to_output_value = ComputedVec::forced_import_or_init_from_3(
computation,
path,
file,
"output_value",
version + VERSION + Version::ZERO,
format,
@@ -281,12 +280,13 @@ impl Vecs {
// let indexes_to_output_value: ComputedVecsFromTxindex<Sats> =
// ComputedVecsFromTxindex::forced_import(
// path,
// file,
// "output_value",
// true,
// version + VERSION + Version::ZERO,
// format,
// StorableVecGeneatorOptions::default()
// computation,
// StorableVecGeneatorOptions::default()
// .add_average()
// .add_sum()
// .add_cumulative(),
@@ -294,7 +294,7 @@ impl Vecs {
let txindex_to_fee = ComputedVecFrom2::forced_import_or_init_from_2(
computation,
path,
file,
"fee",
version + VERSION + Version::ZERO,
format,
@@ -317,7 +317,7 @@ impl Vecs {
let txindex_to_feerate = ComputedVecFrom2::forced_import_or_init_from_2(
computation,
path,
file,
"feerate",
version + VERSION + Version::ZERO,
format,
@@ -337,12 +337,14 @@ impl Vecs {
Ok(Self {
indexes_to_tx_count: ComputedVecsFromHeight::forced_import(
path,
file,
"tx_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -350,12 +352,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_input_count: ComputedVecsFromTxindex::forced_import(
path,
file,
"input_count",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -363,12 +367,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_output_count: ComputedVecsFromTxindex::forced_import(
path,
file,
"output_count",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -376,45 +382,45 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_tx_v1: ComputedVecsFromHeight::forced_import(
path,
file,
"tx_v1",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_tx_v2: ComputedVecsFromHeight::forced_import(
path,
file,
"tx_v2",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_tx_v3: ComputedVecsFromHeight::forced_import(
path,
file,
"tx_v3",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
indexes,
VecBuilderOptions::default().add_sum().add_cumulative(),
)?,
indexes_to_fee: ComputedValueVecsFromTxindex::forced_import(
path,
file,
"fee",
indexes,
Some(txindex_to_fee.boxed_clone()),
Source::Vec(txindex_to_fee.boxed_clone()),
version + VERSION + Version::ZERO,
computation,
format,
fetched,
StorableVecGeneatorOptions::default()
VecBuilderOptions::default()
.add_sum()
.add_cumulative()
.add_percentiles()
@@ -422,84 +428,96 @@ impl Vecs {
.add_average(),
)?,
indexes_to_feerate: ComputedVecsFromTxindex::forced_import(
path,
file,
"feerate",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_tx_vsize: ComputedVecsFromTxindex::forced_import(
path,
file,
"tx_vsize",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_tx_weight: ComputedVecsFromTxindex::forced_import(
path,
file,
"tx_weight",
false,
Source::None,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_percentiles()
.add_minmax()
.add_average(),
)?,
indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import(
path,
file,
"subsidy",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
VecBuilderOptions::default()
.add_percentiles()
.add_sum()
.add_cumulative()
.add_minmax()
.add_average(),
compute_dollars,
indexes,
)?,
indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import(
path,
file,
"coinbase",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
VecBuilderOptions::default()
.add_sum()
.add_cumulative()
.add_percentiles()
.add_minmax()
.add_average(),
compute_dollars,
indexes,
)?,
indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight::forced_import(
path,
file,
"unclaimed_rewards",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
.add_sum()
.add_cumulative(),
computation,
VecBuilderOptions::default().add_sum().add_cumulative(),
compute_dollars,
indexes,
)?,
indexes_to_p2a_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2a_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -507,12 +525,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2ms_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2ms_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -520,12 +540,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2pk33_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2pk33_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -533,12 +555,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2pk65_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2pk65_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -546,12 +570,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2pkh_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2pkh_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -559,12 +585,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2sh_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2sh_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -572,12 +600,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2tr_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2tr_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -585,12 +615,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2wpkh_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2wpkh_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -598,12 +630,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_p2wsh_count: ComputedVecsFromHeight::forced_import(
path,
file,
"p2wsh_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -611,12 +645,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_opreturn_count: ComputedVecsFromHeight::forced_import(
path,
file,
"opreturn_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -624,12 +660,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_unknownoutput_count: ComputedVecsFromHeight::forced_import(
path,
file,
"unknownoutput_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -637,12 +675,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_emptyoutput_count: ComputedVecsFromHeight::forced_import(
path,
file,
"emptyoutput_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default()
computation,
indexes,
VecBuilderOptions::default()
.add_average()
.add_minmax()
.add_percentiles()
@@ -650,12 +690,14 @@ impl Vecs {
.add_cumulative(),
)?,
indexes_to_exact_utxo_count: ComputedVecsFromHeight::forced_import(
path,
file,
"exact_utxo_count",
true,
Source::Compute,
version + VERSION + Version::ZERO,
format,
StorableVecGeneatorOptions::default().add_last(),
computation,
indexes,
VecBuilderOptions::default().add_last(),
)?,
txindex_to_is_coinbase,
inputindex_to_value,
File diff suppressed because it is too large Load Diff
@@ -1,13 +0,0 @@
use std::ops::{Add, Div};
use brk_vec::StoredType;
pub trait ComputedType
where
Self: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + Ord,
{
}
impl<T> ComputedType for T where
T: StoredType + From<usize> + Div<usize, Output = Self> + Add<Output = Self> + Ord
{
}
@@ -1,30 +0,0 @@
use std::mem;
use derive_deref::{Deref, DerefMut};
use super::ByAddressType;
#[derive(Debug, Default, Deref, DerefMut)]
pub struct AddressTypeToVec<T>(ByAddressType<Vec<T>>);
impl<T> AddressTypeToVec<T> {
pub fn merge(&mut self, mut other: Self) {
Self::merge_(&mut self.p2pk65, &mut other.p2pk65);
Self::merge_(&mut self.p2pk33, &mut other.p2pk33);
Self::merge_(&mut self.p2pkh, &mut other.p2pkh);
Self::merge_(&mut self.p2sh, &mut other.p2sh);
Self::merge_(&mut self.p2wpkh, &mut other.p2wpkh);
Self::merge_(&mut self.p2wsh, &mut other.p2wsh);
Self::merge_(&mut self.p2tr, &mut other.p2tr);
Self::merge_(&mut self.p2a, &mut other.p2a);
}
fn merge_(own: &mut Vec<T>, other: &mut Vec<T>) {
if own.len() >= other.len() {
own.append(other);
} else {
other.append(own);
mem::swap(own, other);
}
}
}
File diff suppressed because it is too large Load Diff
@@ -1,62 +0,0 @@
use brk_core::{AddressData, EmptyAddressData};
#[derive(Debug)]
pub enum WithAddressDataSource<T> {
New(T),
FromAddressDataStore(T),
FromEmptyAddressDataStore(T),
}
impl<T> WithAddressDataSource<T> {
pub fn is_new(&self) -> bool {
matches!(self, Self::New(_))
}
pub fn is_from_addressdata(&self) -> bool {
matches!(self, Self::FromAddressDataStore(_))
}
pub fn is_from_emptyaddressdata(&self) -> bool {
matches!(self, Self::FromEmptyAddressDataStore(_))
}
pub fn deref(&self) -> &T {
match self {
Self::New(v) => v,
Self::FromAddressDataStore(v) => v,
Self::FromEmptyAddressDataStore(v) => v,
}
}
pub fn deref_mut(&mut self) -> &mut T {
match self {
Self::New(v) => v,
Self::FromAddressDataStore(v) => v,
Self::FromEmptyAddressDataStore(v) => v,
}
}
}
impl From<WithAddressDataSource<EmptyAddressData>> for WithAddressDataSource<AddressData> {
fn from(value: WithAddressDataSource<EmptyAddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),
WithAddressDataSource::FromAddressDataStore(v) => Self::FromAddressDataStore(v.into()),
WithAddressDataSource::FromEmptyAddressDataStore(v) => {
Self::FromEmptyAddressDataStore(v.into())
}
}
}
}
impl From<WithAddressDataSource<AddressData>> for WithAddressDataSource<EmptyAddressData> {
fn from(value: WithAddressDataSource<AddressData>) -> Self {
match value {
WithAddressDataSource::New(v) => Self::New(v.into()),
WithAddressDataSource::FromAddressDataStore(v) => Self::FromAddressDataStore(v.into()),
WithAddressDataSource::FromEmptyAddressDataStore(v) => {
Self::FromEmptyAddressDataStore(v.into())
}
}
}
}
+1 -1
View File
@@ -16,7 +16,7 @@ derive_deref = { workspace = true }
fjall = { workspace = true }
jiff = { workspace = true }
log = { workspace = true }
rapidhash = "1.4.0"
rapidhash = "2.0.2"
rlimit = "0.10.2"
serde = { workspace = true }
serde_bytes = { workspace = true }
+3 -1
View File
@@ -35,7 +35,8 @@ pub enum Error {
WrongAddressType,
UnindexableDate,
String(&'static str),
Str(&'static str),
String(String),
}
impl From<time::SystemTimeError> for Error {
@@ -134,6 +135,7 @@ impl fmt::Display for Error {
"Date cannot be indexed, must be 2009-01-03, 2009-01-09 or greater"
),
Error::Str(s) => write!(f, "{s}"),
Error::String(s) => write!(f, "{s}"),
}
}
+8
View File
@@ -8,6 +8,14 @@ pub struct AddressGroups<T> {
}
impl<T> AddressGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
self.ge_amount
.as_mut_vec()
@@ -19,6 +19,10 @@ pub struct ByAddressType<T> {
}
impl<T> ByAddressType<T> {
pub fn get_unwrap(&self, address_type: OutputType) -> &T {
self.get(address_type).unwrap()
}
pub fn get(&self, address_type: OutputType) -> Option<&T> {
match address_type {
OutputType::P2PK65 => Some(&self.p2pk65),
@@ -167,3 +171,11 @@ where
self.p2a += rhs.p2a;
}
}
impl<T> ByAddressType<Option<T>> {
pub fn take(&mut self) {
self.as_mut_vec().into_iter().for_each(|opt| {
opt.take();
});
}
}
@@ -0,0 +1,12 @@
#[derive(Debug, Default)]
pub struct ByAnyAddress<T> {
pub loaded: T,
pub empty: T,
}
impl<T> ByAnyAddress<Option<T>> {
pub fn take(&mut self) {
self.loaded.take();
self.empty.take();
}
}
+12 -15
View File
@@ -15,12 +15,11 @@ pub enum GroupFilter {
impl GroupFilter {
pub fn contains(&self, value: usize) -> bool {
match self {
GroupFilter::All => true,
GroupFilter::Range(r) => r.contains(&value),
GroupFilter::LowerThan(max) => *max > value,
GroupFilter::GreaterOrEqual(min) => *min <= value,
GroupFilter::Range(r) => r.contains(&value),
GroupFilter::Epoch(_) => false,
GroupFilter::Type(_) => false,
GroupFilter::All => true,
GroupFilter::Epoch(_) | GroupFilter::Type(_) => false,
}
}
@@ -28,24 +27,22 @@ impl GroupFilter {
match self {
GroupFilter::All => true,
GroupFilter::LowerThan(max) => match other {
GroupFilter::All => false,
GroupFilter::LowerThan(max2) => max >= max2,
GroupFilter::Range(range) => range.end <= *max,
GroupFilter::GreaterOrEqual(_) => false,
GroupFilter::Epoch(_) => false,
GroupFilter::Type(_) => false,
GroupFilter::All
| GroupFilter::GreaterOrEqual(_)
| GroupFilter::Epoch(_)
| GroupFilter::Type(_) => false,
},
GroupFilter::GreaterOrEqual(min) => match other {
GroupFilter::All => false,
GroupFilter::LowerThan(_) => false,
GroupFilter::Range(range) => range.start >= *min,
GroupFilter::GreaterOrEqual(min2) => min <= min2,
GroupFilter::Epoch(_) => false,
GroupFilter::Type(_) => false,
GroupFilter::All
| GroupFilter::LowerThan(_)
| GroupFilter::Epoch(_)
| GroupFilter::Type(_) => false,
},
GroupFilter::Range(_) => false,
GroupFilter::Epoch(_) => false,
GroupFilter::Type(_) => false,
GroupFilter::Range(_) | GroupFilter::Epoch(_) | GroupFilter::Type(_) => false,
}
}
}
+2
View File
@@ -2,6 +2,7 @@ mod address;
mod by_address_type;
mod by_age_range;
mod by_amount_range;
mod by_any_address;
mod by_epoch;
mod by_ge_amount;
mod by_lt_amount;
@@ -18,6 +19,7 @@ pub use address::*;
pub use by_address_type::*;
pub use by_age_range::*;
pub use by_amount_range::*;
pub use by_any_address::*;
pub use by_epoch::*;
pub use by_ge_amount::*;
pub use by_lt_amount::*;
+15
View File
@@ -18,6 +18,21 @@ pub struct UTXOGroups<T> {
}
impl<T> UTXOGroups<T> {
pub fn as_boxed_mut_vecs(&mut self) -> Vec<Box<[&mut T]>> {
vec![
Box::new([&mut self.all]),
Box::new(self.term.as_mut_vec()),
Box::new(self.max_age.as_mut_vec()),
Box::new(self.min_age.as_mut_vec()),
Box::new(self.ge_amount.as_mut_vec()),
Box::new(self.age_range.as_mut_vec()),
Box::new(self.epoch.as_mut_vec()),
Box::new(self.amount_range.as_mut_vec()),
Box::new(self.lt_amount.as_mut_vec()),
Box::new(self._type.as_mut_vec()),
]
}
pub fn as_mut_vecs(&mut self) -> Vec<&mut T> {
[&mut self.all]
.into_iter()
@@ -1,5 +1,3 @@
use std::hash::Hasher;
use byteview::ByteView;
use derive_deref::Deref;
use zerocopy::{FromBytes, IntoBytes};
@@ -25,9 +23,7 @@ pub struct AddressBytesHash([u8; 8]);
impl From<(&AddressBytes, OutputType)> for AddressBytesHash {
fn from((address_bytes, outputtype): (&AddressBytes, OutputType)) -> Self {
let mut hasher = rapidhash::RapidHasher::default();
hasher.write(address_bytes.as_slice());
let mut slice = hasher.finish().to_le_bytes();
let mut slice = rapidhash::v3::rapidhash_v3(address_bytes.as_slice()).to_le_bytes();
slice[0] = slice[0].wrapping_add(outputtype as u8);
Self(slice)
}
@@ -0,0 +1,61 @@
use serde::Serialize;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{
TypeIndex,
structs::{EmptyAddressIndex, LoadedAddressIndex},
};
const MIN_EMPTY_INDEX: u32 = u32::MAX - 4_000_000_000;
#[derive(
Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy, FromBytes, Immutable, IntoBytes, KnownLayout,
)]
pub struct AnyAddressIndex(TypeIndex);
impl AnyAddressIndex {
pub fn to_enum(&self) -> AnyAddressDataIndexEnum {
AnyAddressDataIndexEnum::from(*self)
}
}
impl From<LoadedAddressIndex> for AnyAddressIndex {
fn from(value: LoadedAddressIndex) -> Self {
if u32::from(value) >= MIN_EMPTY_INDEX {
panic!("")
}
Self(*value)
}
}
impl From<EmptyAddressIndex> for AnyAddressIndex {
fn from(value: EmptyAddressIndex) -> Self {
Self(*value + MIN_EMPTY_INDEX)
}
}
impl Serialize for AnyAddressIndex {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
self.to_enum().serialize(serializer)
}
}
#[derive(Debug, Serialize)]
pub enum AnyAddressDataIndexEnum {
Loaded(LoadedAddressIndex),
Empty(EmptyAddressIndex),
}
impl From<AnyAddressIndex> for AnyAddressDataIndexEnum {
fn from(value: AnyAddressIndex) -> Self {
let uvalue = u32::from(value.0);
if uvalue >= MIN_EMPTY_INDEX {
Self::Empty(EmptyAddressIndex::from(uvalue - MIN_EMPTY_INDEX))
} else {
Self::Loaded(LoadedAddressIndex::from(value.0))
}
}
}
+7 -1
View File
@@ -1,6 +1,6 @@
use std::{
cmp::Ordering,
ops::{Add, Div, Mul},
ops::{Add, AddAssign, Div, Mul},
};
use serde::Serialize;
@@ -20,6 +20,12 @@ impl Add for Bitcoin {
}
}
impl AddAssign for Bitcoin {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs
}
}
impl Mul for Bitcoin {
type Output = Self;
fn mul(self, rhs: Self) -> Self::Output {
+18
View File
@@ -24,10 +24,28 @@ use super::Dollars;
)]
pub struct Cents(i64);
const SIGNIFICANT_DIGITS: i32 = 4;
impl Cents {
pub const fn mint(value: i64) -> Self {
Self(value)
}
pub fn round_to_4_digits(self) -> Self {
let v = self.0;
let ilog10 = v.checked_ilog10().unwrap_or(0) as i32;
Self::from(if ilog10 >= SIGNIFICANT_DIGITS {
let log_diff = ilog10 - SIGNIFICANT_DIGITS + 1;
let pow = 10.0_f64.powi(log_diff);
((v as f64 / pow).round() * pow) as i64
} else {
v
})
}
}
impl From<Dollars> for Cents {
+4
View File
@@ -31,6 +31,10 @@ impl Date {
pub fn day(&self) -> u8 {
(self.0 % 1_00) as u8
}
pub fn into_jiff(self) -> Date_ {
self.into()
}
}
impl Default for Date {
+137 -2
View File
@@ -3,11 +3,14 @@ use std::{
ops::{Add, Rem},
};
use jiff::Span;
use serde::Serialize;
// use color_eyre::eyre::eyre;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{CheckedSub, Error, Printable};
use crate::{
CheckedSub, DecadeIndex, Error, FromCoarserIndex, MonthIndex, Printable, QuarterIndex,
SemesterIndex, WeekIndex, YearIndex,
};
use super::Date;
@@ -103,3 +106,135 @@ impl Printable for DateIndex {
&["d", "date", "dateindex"]
}
}
impl FromCoarserIndex<WeekIndex> for DateIndex {
fn min_from(coarser: WeekIndex) -> usize {
let coarser = usize::from(coarser);
if coarser == 0 {
0
} else if coarser == 1 {
1
} else {
4 + (coarser - 2) * 7
}
}
fn max_from_(coarser: WeekIndex) -> usize {
let coarser = usize::from(coarser);
if coarser == 0 {
0
} else if coarser == 1 {
3
} else {
3 + (coarser - 1) * 7
}
}
}
impl FromCoarserIndex<MonthIndex> for DateIndex {
fn min_from(coarser: MonthIndex) -> usize {
let coarser = u16::from(coarser);
if coarser == 0 {
0
} else {
let d = Date::new(2009, 1, 1)
.into_jiff()
.checked_add(Span::new().months(coarser))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
fn max_from_(coarser: MonthIndex) -> usize {
let d = Date::new(2009, 1, 31)
.into_jiff()
.checked_add(Span::new().months(u16::from(coarser)))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
impl FromCoarserIndex<QuarterIndex> for DateIndex {
fn min_from(coarser: QuarterIndex) -> usize {
let coarser = u16::from(coarser);
if coarser == 0 {
0
} else {
let d = Date::new(2009, 1, 1)
.into_jiff()
.checked_add(Span::new().months(3 * coarser))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
fn max_from_(coarser: QuarterIndex) -> usize {
let d = Date::new(2009, 3, 31)
.into_jiff()
.checked_add(Span::new().months(3 * u16::from(coarser)))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
impl FromCoarserIndex<SemesterIndex> for DateIndex {
fn min_from(coarser: SemesterIndex) -> usize {
let coarser = u16::from(coarser);
if coarser == 0 {
0
} else {
let d = Date::new(2009, 1, 1)
.into_jiff()
.checked_add(Span::new().months(6 * coarser))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
fn max_from_(coarser: SemesterIndex) -> usize {
let d = Date::new(2009, 5, 31)
.into_jiff()
.checked_add(Span::new().months(1 + 6 * u16::from(coarser)))
.unwrap();
DateIndex::try_from(Date::from(d)).unwrap().into()
}
}
impl FromCoarserIndex<YearIndex> for DateIndex {
fn min_from(coarser: YearIndex) -> usize {
let coarser = u16::from(coarser);
if coarser == 0 {
0
} else {
Self::try_from(Date::new(2009 + coarser, 1, 1))
.unwrap()
.into()
}
}
fn max_from_(coarser: YearIndex) -> usize {
Self::try_from(Date::new(2009 + u16::from(coarser), 12, 31))
.unwrap()
.into()
}
}
impl FromCoarserIndex<DecadeIndex> for DateIndex {
fn min_from(coarser: DecadeIndex) -> usize {
let coarser = u16::from(coarser);
if coarser == 0 {
0
} else {
Self::try_from(Date::new(2000 + 10 * coarser, 1, 1))
.unwrap()
.into()
}
}
fn max_from_(coarser: DecadeIndex) -> usize {
let coarser = u16::from(coarser);
Self::try_from(Date::new(2009 + (10 * coarser), 12, 31))
.unwrap()
.into()
}
}
+37 -1
View File
@@ -1,4 +1,7 @@
use std::{fmt::Debug, ops::Add};
use std::{
fmt::Debug,
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -31,6 +34,18 @@ impl From<u8> for DecadeIndex {
}
}
impl From<DecadeIndex> for u8 {
fn from(value: DecadeIndex) -> Self {
value.0
}
}
impl From<DecadeIndex> for u16 {
fn from(value: DecadeIndex) -> Self {
value.0 as u16
}
}
impl From<usize> for DecadeIndex {
fn from(value: usize) -> Self {
Self(value as u8)
@@ -51,6 +66,27 @@ impl Add<usize> for DecadeIndex {
}
}
impl Add<DecadeIndex> for DecadeIndex {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
impl AddAssign for DecadeIndex {
fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0)
}
}
impl Div<usize> for DecadeIndex {
type Output = Self;
fn div(self, _: usize) -> Self::Output {
unreachable!()
}
}
impl From<DateIndex> for DecadeIndex {
fn from(value: DateIndex) -> Self {
Self::from(Date::from(value))
@@ -1,6 +1,6 @@
use std::{
fmt::Debug,
ops::{Add, Div},
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
@@ -54,6 +54,12 @@ impl Add for DifficultyEpoch {
}
}
impl AddAssign for DifficultyEpoch {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs
}
}
impl Add<usize> for DifficultyEpoch {
type Output = Self;
+5 -1
View File
@@ -42,6 +42,10 @@ impl Dollars {
pub fn round_nearest_cent(self) -> Self {
Dollars((self.0 * 100.0).round() / 100.0)
}
pub fn round_to_4_digits(self) -> Self {
Self::from(Cents::from(self).round_to_4_digits())
}
}
impl From<f32> for Dollars {
@@ -239,7 +243,7 @@ impl Mul<Sats> for Dollars {
self
} else {
Self::from(Cents::from(
u128::from(rhs) * u128::from(Cents::from(self)) / u128::from(Sats::ONE_BTC),
u128::from(rhs) * u128::from(Cents::from(self)) / Sats::ONE_BTC_U128,
))
}
}
@@ -1,22 +1,23 @@
use byteview::ByteView;
use serde::Serialize;
use zerocopy::{FromBytes, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{AddressData, Sats};
use crate::{LoadedAddressData, Sats};
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout)]
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
pub struct EmptyAddressData {
pub transfered: Sats,
}
impl From<AddressData> for EmptyAddressData {
fn from(value: AddressData) -> Self {
impl From<LoadedAddressData> for EmptyAddressData {
fn from(value: LoadedAddressData) -> Self {
Self::from(&value)
}
}
impl From<&AddressData> for EmptyAddressData {
fn from(value: &AddressData) -> Self {
impl From<&LoadedAddressData> for EmptyAddressData {
fn from(value: &LoadedAddressData) -> Self {
if value.sent != value.received {
dbg!(&value);
panic!("Trying to convert not empty wallet to empty !");
@@ -0,0 +1,69 @@
use std::ops::Add;
use derive_deref::Deref;
use serde::Serialize;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{CheckedSub, Printable, TypeIndex};
#[derive(
Debug,
Default,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Deref,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct EmptyAddressIndex(TypeIndex);
impl From<TypeIndex> for EmptyAddressIndex {
fn from(value: TypeIndex) -> Self {
Self(value)
}
}
impl From<usize> for EmptyAddressIndex {
fn from(value: usize) -> Self {
Self(TypeIndex::from(value))
}
}
impl From<u32> for EmptyAddressIndex {
fn from(value: u32) -> Self {
Self(TypeIndex::from(value))
}
}
impl From<EmptyAddressIndex> for usize {
fn from(value: EmptyAddressIndex) -> Self {
usize::from(value.0)
}
}
impl Add<usize> for EmptyAddressIndex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}
impl CheckedSub<EmptyAddressIndex> for EmptyAddressIndex {
fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
}
impl Printable for EmptyAddressIndex {
fn to_string() -> &'static str {
"emptyaddressindex"
}
fn to_possible_strings() -> &'static [&'static str] {
&["emptyaddr", "emptyaddressindex"]
}
}
@@ -31,7 +31,7 @@ impl From<TypeIndex> for EmptyOutputIndex {
}
impl From<EmptyOutputIndex> for usize {
fn from(value: EmptyOutputIndex) -> Self {
Self::from(*value)
Self::from(value.0)
}
}
impl From<usize> for EmptyOutputIndex {
@@ -42,7 +42,7 @@ impl From<usize> for EmptyOutputIndex {
impl Add<usize> for EmptyOutputIndex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(*self + rhs)
Self(self.0 + rhs)
}
}
impl CheckedSub<EmptyOutputIndex> for EmptyOutputIndex {
+7 -1
View File
@@ -1,6 +1,6 @@
use std::{
cmp::Ordering,
ops::{Add, Div},
ops::{Add, AddAssign, Div},
};
use serde::Serialize;
@@ -35,6 +35,12 @@ impl Add for Feerate {
}
}
impl AddAssign for Feerate {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs
}
}
impl Div<usize> for Feerate {
type Output = Self;
fn div(self, rhs: usize) -> Self::Output {
+7 -1
View File
@@ -1,6 +1,6 @@
use std::{
fmt::Debug,
ops::{Add, Div},
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
@@ -60,6 +60,12 @@ impl Add for HalvingEpoch {
}
}
impl AddAssign for HalvingEpoch {
fn add_assign(&mut self, rhs: Self) {
*self = *self + rhs
}
}
impl Add<usize> for HalvingEpoch {
type Output = Self;
+1 -1
View File
@@ -35,7 +35,7 @@ impl Height {
pub const ZERO: Self = Self(0);
pub const MAX: Self = Self(u32::MAX);
pub fn new(height: u32) -> Self {
pub const fn new(height: u32) -> Self {
Self(height)
}
@@ -1,32 +1,35 @@
use byteview::ByteView;
use serde::Serialize;
use zerocopy::{FromBytes, IntoBytes};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{Bitcoin, CheckedSub, Dollars, EmptyAddressData, Error, Result, Sats};
#[derive(Debug, Default, Clone)]
#[derive(Debug, Default, Clone, Serialize, FromBytes, Immutable, IntoBytes, KnownLayout)]
#[repr(C)]
pub struct AddressData {
pub struct LoadedAddressData {
pub sent: Sats,
pub received: Sats,
pub realized_cap: Dollars,
pub outputs_len: u32,
padding: u32,
}
impl AddressData {
impl LoadedAddressData {
pub fn amount(&self) -> Sats {
(u64::from(self.received) - u64::from(self.sent)).into()
}
pub fn realized_price(&self) -> Dollars {
(self.realized_cap / Bitcoin::from(self.amount())).round_nearest_cent()
(self.realized_cap / Bitcoin::from(self.amount())).round_to_4_digits()
}
#[inline(always)]
#[inline]
pub fn has_0_sats(&self) -> bool {
self.amount() == Sats::ZERO
}
#[inline(always)]
#[inline]
pub fn has_0_utxos(&self) -> bool {
self.outputs_len == 0
}
@@ -41,7 +44,7 @@ impl AddressData {
pub fn send(&mut self, amount: Sats, previous_price: Option<Dollars>) -> Result<()> {
if self.amount() < amount {
return Err(Error::String("Previous_amount smaller than sent amount"));
return Err(Error::Str("Previous_amount smaller than sent amount"));
}
self.sent += amount;
self.outputs_len -= 1;
@@ -55,23 +58,24 @@ impl AddressData {
}
}
impl From<EmptyAddressData> for AddressData {
impl From<EmptyAddressData> for LoadedAddressData {
fn from(value: EmptyAddressData) -> Self {
Self::from(&value)
}
}
impl From<&EmptyAddressData> for AddressData {
impl From<&EmptyAddressData> for LoadedAddressData {
fn from(value: &EmptyAddressData) -> Self {
Self {
sent: value.transfered,
received: value.transfered,
realized_cap: Dollars::ZERO,
outputs_len: 0,
padding: 0,
}
}
}
impl From<ByteView> for AddressData {
impl From<ByteView> for LoadedAddressData {
fn from(value: ByteView) -> Self {
Self {
// MUST be same order as impl From<&AddressData> for ByteView
@@ -79,16 +83,17 @@ impl From<ByteView> for AddressData {
received: Sats::read_from_bytes(&value[8..16]).unwrap(),
realized_cap: Dollars::read_from_bytes(&value[16..24]).unwrap(),
outputs_len: u32::read_from_bytes(&value[24..]).unwrap(),
padding: 0,
}
}
}
impl From<AddressData> for ByteView {
fn from(value: AddressData) -> Self {
impl From<LoadedAddressData> for ByteView {
fn from(value: LoadedAddressData) -> Self {
Self::from(&value)
}
}
impl From<&AddressData> for ByteView {
fn from(value: &AddressData) -> Self {
impl From<&LoadedAddressData> for ByteView {
fn from(value: &LoadedAddressData) -> Self {
Self::new(
&[
value.sent.as_bytes(),
@@ -0,0 +1,67 @@
use std::ops::Add;
use derive_deref::Deref;
use serde::Serialize;
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{CheckedSub, Printable, TypeIndex};
#[derive(
Debug,
PartialEq,
Eq,
PartialOrd,
Ord,
Clone,
Copy,
Deref,
Default,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
Serialize,
)]
pub struct LoadedAddressIndex(TypeIndex);
impl From<TypeIndex> for LoadedAddressIndex {
fn from(value: TypeIndex) -> Self {
Self(value)
}
}
impl From<usize> for LoadedAddressIndex {
fn from(value: usize) -> Self {
Self(TypeIndex::from(value))
}
}
impl From<LoadedAddressIndex> for usize {
fn from(value: LoadedAddressIndex) -> Self {
usize::from(value.0)
}
}
impl From<LoadedAddressIndex> for u32 {
fn from(value: LoadedAddressIndex) -> Self {
u32::from(value.0)
}
}
impl Add<usize> for LoadedAddressIndex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self(self.0 + rhs)
}
}
impl CheckedSub<LoadedAddressIndex> for LoadedAddressIndex {
fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
}
impl Printable for LoadedAddressIndex {
fn to_string() -> &'static str {
"loadedaddressindex"
}
fn to_possible_strings() -> &'static [&'static str] {
&["loadedaddr", "loadedaddressindex"]
}
}
+10 -2
View File
@@ -1,6 +1,6 @@
mod addressbytes;
mod addressbyteshash;
mod addressdata;
mod anyaddressindex;
mod bitcoin;
mod blockhash;
mod blockhashprefix;
@@ -11,11 +11,14 @@ mod decadeindex;
mod difficultyepoch;
mod dollars;
mod emptyaddressdata;
mod emptyaddressindex;
mod emptyoutputindex;
mod feerate;
mod halvingepoch;
mod height;
mod inputindex;
mod loadedaddressdata;
mod loadedaddressindex;
mod monthindex;
mod ohlc;
mod opreturnindex;
@@ -33,6 +36,7 @@ mod p2wshaddressindex;
mod quarterindex;
mod rawlocktime;
mod sats;
mod semesterindex;
mod stored_f32;
mod stored_f64;
mod stored_u32;
@@ -57,7 +61,7 @@ mod yearindex;
pub use addressbytes::*;
pub use addressbyteshash::*;
pub use addressdata::*;
pub use anyaddressindex::*;
pub use bitcoin::*;
pub use blockhash::*;
pub use blockhashprefix::*;
@@ -68,11 +72,14 @@ pub use decadeindex::*;
pub use difficultyepoch::*;
pub use dollars::*;
pub use emptyaddressdata::*;
pub use emptyaddressindex::*;
pub use emptyoutputindex::*;
pub use feerate::*;
pub use halvingepoch::*;
pub use height::*;
pub use inputindex::*;
pub use loadedaddressdata::*;
pub use loadedaddressindex::*;
pub use monthindex::*;
pub use ohlc::*;
pub use opreturnindex::*;
@@ -90,6 +97,7 @@ pub use p2wshaddressindex::*;
pub use quarterindex::*;
pub use rawlocktime::*;
pub use sats::*;
pub use semesterindex::*;
pub use stored_f32::*;
pub use stored_f64::*;
pub use stored_u8::*;
+31 -1
View File
@@ -1,4 +1,7 @@
use std::{fmt::Debug, ops::Add};
use std::{
fmt::Debug,
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -31,6 +34,12 @@ impl From<u16> for MonthIndex {
}
}
impl From<MonthIndex> for u16 {
fn from(value: MonthIndex) -> Self {
value.0
}
}
impl From<usize> for MonthIndex {
fn from(value: usize) -> Self {
Self(value as u16)
@@ -51,6 +60,27 @@ impl Add<usize> for MonthIndex {
}
}
impl Add<MonthIndex> for MonthIndex {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
impl AddAssign for MonthIndex {
fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0)
}
}
impl Div<usize> for MonthIndex {
type Output = Self;
fn div(self, _: usize) -> Self::Output {
unreachable!()
}
}
impl From<DateIndex> for MonthIndex {
fn from(value: DateIndex) -> Self {
Self::from(Date::from(value))
+37 -1
View File
@@ -1,4 +1,4 @@
use std::ops::{Add, Div};
use std::ops::{Add, AddAssign, Div};
use derive_deref::{Deref, DerefMut};
use serde::{Serialize, Serializer, ser::SerializeTuple};
@@ -236,6 +236,15 @@ where
}
}
impl<T> AddAssign for Open<T>
where
T: Add<Output = T> + Clone,
{
fn add_assign(&mut self, rhs: Self) {
**self = self.0.clone() + rhs.0
}
}
impl<T> Div<usize> for Open<T>
where
T: Div<usize, Output = T>,
@@ -324,6 +333,15 @@ where
}
}
impl<T> AddAssign for High<T>
where
T: Add<Output = T> + Clone,
{
fn add_assign(&mut self, rhs: Self) {
**self = self.0.clone() + rhs.0
}
}
impl<T> Div<usize> for High<T>
where
T: Div<usize, Output = T>,
@@ -412,6 +430,15 @@ where
}
}
impl<T> AddAssign for Low<T>
where
T: Add<Output = T> + Clone,
{
fn add_assign(&mut self, rhs: Self) {
**self = self.0.clone() + rhs.0
}
}
impl<T> Div<usize> for Low<T>
where
T: Div<usize, Output = T>,
@@ -515,6 +542,15 @@ where
}
}
impl<T> AddAssign for Close<T>
where
T: Add<Output = T> + Clone,
{
fn add_assign(&mut self, rhs: Self) {
**self = self.0.clone() + rhs.0
}
}
impl<T> Div<usize> for Close<T>
where
T: Div<usize, Output = T>,
+31 -1
View File
@@ -1,4 +1,7 @@
use std::{fmt::Debug, ops::Add};
use std::{
fmt::Debug,
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
@@ -37,6 +40,12 @@ impl From<usize> for QuarterIndex {
}
}
impl From<QuarterIndex> for u16 {
fn from(value: QuarterIndex) -> Self {
value.0
}
}
impl From<QuarterIndex> for usize {
fn from(value: QuarterIndex) -> Self {
value.0 as usize
@@ -51,6 +60,27 @@ impl Add<usize> for QuarterIndex {
}
}
impl Add<QuarterIndex> for QuarterIndex {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
impl AddAssign for QuarterIndex {
fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0)
}
}
impl Div<usize> for QuarterIndex {
type Output = Self;
fn div(self, _: usize) -> Self::Output {
unreachable!()
}
}
impl From<MonthIndex> for QuarterIndex {
fn from(value: MonthIndex) -> Self {
Self((usize::from(value) / 3) as u16)
+1
View File
@@ -53,6 +53,7 @@ impl Sats {
pub const ONE_BTC: Self = Self(1_00_000_000);
pub const MAX: Self = Self(u64::MAX);
pub const FIFTY_BTC: Self = Self(50_00_000_000);
pub const ONE_BTC_U128: u128 = 1_00_000_000;
pub fn new(sats: u64) -> Self {
Self(sats)
@@ -0,0 +1,104 @@
use std::{
fmt::Debug,
ops::{Add, AddAssign, Div},
};
use serde::{Deserialize, Serialize};
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
use crate::{CheckedSub, Printable};
use super::MonthIndex;
#[derive(
Debug,
Clone,
Copy,
PartialEq,
Eq,
PartialOrd,
Ord,
Default,
Serialize,
Deserialize,
FromBytes,
Immutable,
IntoBytes,
KnownLayout,
)]
pub struct SemesterIndex(u16);
impl From<u16> for SemesterIndex {
fn from(value: u16) -> Self {
Self(value)
}
}
impl From<usize> for SemesterIndex {
fn from(value: usize) -> Self {
Self(value as u16)
}
}
impl From<SemesterIndex> for u16 {
fn from(value: SemesterIndex) -> Self {
value.0
}
}
impl From<SemesterIndex> for usize {
fn from(value: SemesterIndex) -> Self {
value.0 as usize
}
}
impl Add<usize> for SemesterIndex {
type Output = Self;
fn add(self, rhs: usize) -> Self::Output {
Self::from(self.0 + rhs as u16)
}
}
impl Add<SemesterIndex> for SemesterIndex {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self::from(self.0 + rhs.0)
}
}
impl AddAssign for SemesterIndex {
fn add_assign(&mut self, rhs: Self) {
*self = Self(self.0 + rhs.0)
}
}
impl Div<usize> for SemesterIndex {
type Output = Self;
fn div(self, _: usize) -> Self::Output {
unreachable!()
}
}
impl From<MonthIndex> for SemesterIndex {
fn from(value: MonthIndex) -> Self {
Self((usize::from(value) / 6) as u16)
}
}
impl CheckedSub for SemesterIndex {
fn checked_sub(self, rhs: Self) -> Option<Self> {
self.0.checked_sub(rhs.0).map(Self)
}
}
impl Printable for SemesterIndex {
fn to_string() -> &'static str {
"semesterindex"
}
fn to_possible_strings() -> &'static [&'static str] {
&["s", "semester", "semesterindex"]
}
}

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