mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
interface: create super fast searcher
This commit is contained in:
105
Cargo.lock
generated
105
Cargo.lock
generated
@@ -651,7 +651,6 @@ dependencies = [
|
||||
"serde",
|
||||
"vecdb",
|
||||
"zerocopy",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -663,7 +662,7 @@ dependencies = [
|
||||
"fjall",
|
||||
"jiff",
|
||||
"minreq",
|
||||
"sonic-rs 0.5.5",
|
||||
"sonic-rs",
|
||||
"vecdb",
|
||||
"zerocopy",
|
||||
]
|
||||
@@ -677,7 +676,7 @@ dependencies = [
|
||||
"brk_structs",
|
||||
"log",
|
||||
"minreq",
|
||||
"sonic-rs 0.5.5",
|
||||
"sonic-rs",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -721,8 +720,8 @@ dependencies = [
|
||||
"brk_structs",
|
||||
"brk_traversable",
|
||||
"derive_deref",
|
||||
"nucleo-matcher",
|
||||
"quick_cache",
|
||||
"rustc-hash",
|
||||
"schemars",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -1181,7 +1180,7 @@ dependencies = [
|
||||
"quick_cache",
|
||||
"schemars",
|
||||
"serde",
|
||||
"sonic-rs 0.5.5",
|
||||
"sonic-rs",
|
||||
"tokio",
|
||||
"tower-http",
|
||||
"tracing",
|
||||
@@ -1234,7 +1233,6 @@ dependencies = [
|
||||
"strum",
|
||||
"vecdb",
|
||||
"zerocopy",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1314,9 +1312,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.2.40"
|
||||
version = "1.2.41"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e1d05d92f4b1fd76aad469d46cdd858ca761576082cd37df81416691e50199fb"
|
||||
checksum = "ac9fe6cdbb24b6ade63616c0a0688e45bb56732262c158df3c0c4bea4ca47cb7"
|
||||
dependencies = [
|
||||
"find-msvc-tools",
|
||||
"jobserver",
|
||||
@@ -1945,9 +1943,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "find-msvc-tools"
|
||||
version = "0.1.3"
|
||||
version = "0.1.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0399f9d26e5191ce32c498bebd31e7a3ceabc2745f0ac54af3f335126c3f24b3"
|
||||
checksum = "52051878f80a721bb68ebfbc930e07b65ba72f2da88968ea5c06fd6ca3d3a127"
|
||||
|
||||
[[package]]
|
||||
name = "fixedbitset"
|
||||
@@ -2149,12 +2147,13 @@ checksum = "17e2ac29387b1aa07a1e448f7bb4f35b500787971e965b02842b900afa5c8f6f"
|
||||
|
||||
[[package]]
|
||||
name = "half"
|
||||
version = "2.6.0"
|
||||
version = "2.7.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "459196ed295495a68f7d7fe1d84f6c4b7ff0e21fe3017b2f283c6fac3ad803c9"
|
||||
checksum = "e54c115d4f30f52c67202f079c5f9d8b49db4691f460fdb0b4c2e838261b2ba5"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"crunchy",
|
||||
"zerocopy",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2640,9 +2639,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe"
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.176"
|
||||
version = "0.2.177"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "58f929b4d672ea937a23a1ab494143d968337a5f47e56d0815df1e0890ddf174"
|
||||
checksum = "2874a2af47a2325c2001a6e6fad9b16a53b802102b528163885171cf92b15976"
|
||||
|
||||
[[package]]
|
||||
name = "libredox"
|
||||
@@ -2872,16 +2871,6 @@ dependencies = [
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "nucleo-matcher"
|
||||
version = "0.3.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bf33f538733d1a5a3494b836ba913207f14d9d4a1d3cd67030c5061bdd2cac85"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"unicode-segmentation",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "num-bigint"
|
||||
version = "0.4.6"
|
||||
@@ -4216,9 +4205,9 @@ checksum = "1bc711410fbe7399f390ca1c3b60ad0f53f80e95c5eb935e52268a0e2cd49acc"
|
||||
|
||||
[[package]]
|
||||
name = "seqdb"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f4b5a103ae4ceaaf11b372ffcc267d9236e33d0d515dca7b5813579511e3f6c9"
|
||||
checksum = "e1f2a11472b8979fde0e6c181fef50e36633491ff154ee19f481d8135fb9dd6a"
|
||||
dependencies = [
|
||||
"allocative",
|
||||
"libc",
|
||||
@@ -4227,7 +4216,6 @@ dependencies = [
|
||||
"parking_lot 0.12.5",
|
||||
"rayon",
|
||||
"zerocopy",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4321,9 +4309,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "serde_spanned"
|
||||
version = "1.0.2"
|
||||
version = "1.0.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5417783452c2be558477e104686f7de5dae53dba813c28435e0e70f82d9b04ee"
|
||||
checksum = "e24345aa0fe688594e73770a5f6d1b216508b4f93484c0026d521acd30134392"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
@@ -4421,26 +4409,6 @@ dependencies = [
|
||||
"cfg-if",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sonic-rs"
|
||||
version = "0.3.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0275f9f2f07d47556fe60c2759da8bc4be6083b047b491b2d476aa0bfa558eb1"
|
||||
dependencies = [
|
||||
"bumpalo",
|
||||
"bytes",
|
||||
"cfg-if",
|
||||
"faststr",
|
||||
"itoa",
|
||||
"ref-cast",
|
||||
"ryu",
|
||||
"serde",
|
||||
"simdutf8",
|
||||
"sonic-number",
|
||||
"sonic-simd",
|
||||
"thiserror 2.0.17",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sonic-rs"
|
||||
version = "0.5.5"
|
||||
@@ -4486,9 +4454,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "stable_deref_trait"
|
||||
version = "1.2.0"
|
||||
version = "1.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8f112729512f8e442d81f95a8a7ddf2b7c6b8a1a6f509a95864142b30cab2d3"
|
||||
checksum = "6ce2be8dc25455e1f91df71bfa12ad37d7af1092ae736f3a6cd0e37bc7810596"
|
||||
|
||||
[[package]]
|
||||
name = "static_assertions"
|
||||
@@ -4761,9 +4729,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.9.7"
|
||||
version = "0.9.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "00e5e5d9bf2475ac9d4f0d9edab68cc573dc2fd644b0dba36b0c30a92dd9eaa0"
|
||||
checksum = "f0dc8b1fb61449e27716ec0e1bdf0f6b8f3e8f6b05391e8497b8b6d7804ea6d8"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"serde_core",
|
||||
@@ -4776,18 +4744,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_datetime"
|
||||
version = "0.7.2"
|
||||
version = "0.7.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32f1085dec27c2b6632b04c80b3bb1b4300d6495d1e129693bdda7d91e72eec1"
|
||||
checksum = "f2cdb639ebbc97961c51720f858597f7f24c4fc295327923af55b74c3c724533"
|
||||
dependencies = [
|
||||
"serde_core",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.23.6"
|
||||
version = "0.23.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f3effe7c0e86fdff4f69cdd2ccc1b96f933e24811c5441d44904e8683e27184b"
|
||||
checksum = "6485ef6d0d9b5d0ec17244ff7eb05310113c3f316f2d14200d4de56b3cb98f8d"
|
||||
dependencies = [
|
||||
"indexmap",
|
||||
"toml_datetime",
|
||||
@@ -4797,18 +4765,18 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_parser"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4cf893c33be71572e0e9aa6dd15e6677937abd686b066eac3f8cd3531688a627"
|
||||
checksum = "c0cbe268d35bdb4bb5a56a2de88d0ad0eb70af5384a99d648cd4b3d04039800e"
|
||||
dependencies = [
|
||||
"winnow",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "toml_writer"
|
||||
version = "1.0.3"
|
||||
version = "1.0.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d163a63c116ce562a22cda521fcc4d79152e7aba014456fb5eb442f6d6a10109"
|
||||
checksum = "df8b2b54733674ad286d16267dcfc7a71ed5c776e4ac7aa3c3e2561f7c637bf2"
|
||||
|
||||
[[package]]
|
||||
name = "tower"
|
||||
@@ -5107,9 +5075,9 @@ checksum = "8f54a172d0620933a27a4360d3db3e2ae0dd6cceae9730751a036bbf182c4b23"
|
||||
|
||||
[[package]]
|
||||
name = "vecdb"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "46ec3679b15875862bb8133094dbc6adc80089e651b739198e4a6b4dddcd4e7a"
|
||||
checksum = "f4bc53cae8d59e2201d5553b351b124feeed236b6bd31645b6dda8f8dcf95e9a"
|
||||
dependencies = [
|
||||
"allocative",
|
||||
"ctrlc",
|
||||
@@ -5120,17 +5088,16 @@ dependencies = [
|
||||
"serde",
|
||||
"serde_derive",
|
||||
"serde_json",
|
||||
"sonic-rs 0.3.17",
|
||||
"sonic-rs",
|
||||
"vecdb_derive",
|
||||
"zerocopy",
|
||||
"zerocopy-derive",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "vecdb_derive"
|
||||
version = "0.2.16"
|
||||
version = "0.2.17"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2e97a132b0d890f90bced783a546be84ba0fb0abfa868628cbc19a506739c761"
|
||||
checksum = "b0e16806c42dff3018dfeec2920f701975dd35ff7f6d31f3dde3ea7d91860960"
|
||||
dependencies = [
|
||||
"quote",
|
||||
"syn 2.0.106",
|
||||
@@ -5701,9 +5668,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "zip"
|
||||
version = "5.1.1"
|
||||
version = "6.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2f852905151ac8d4d06fdca66520a661c09730a74c6d4e2b0f27b436b382e532"
|
||||
checksum = "eb2a05c7c36fde6c09b08576c9f7fb4cda705990f73b58fe011abf7dfb24168b"
|
||||
dependencies = [
|
||||
"arbitrary",
|
||||
"crc32fast",
|
||||
|
||||
@@ -80,9 +80,8 @@ serde_json = { version = "1.0.145", features = ["float_roundtrip"] }
|
||||
sonic-rs = "0.5.5"
|
||||
tokio = { version = "1.47.1", features = ["rt-multi-thread"] }
|
||||
# vecdb = { path = "../seqdb/crates/vecdb", features = ["derive"] }
|
||||
vecdb = { version = "0.2.16", features = ["derive"] }
|
||||
zerocopy = "0.8.27"
|
||||
zerocopy-derive = "0.8.27"
|
||||
vecdb = { version = "0.2.17", features = ["derive"] }
|
||||
zerocopy = { version = "0.8.27", features = ["derive"] }
|
||||
|
||||
[workspace.metadata.release]
|
||||
shared-version = true
|
||||
|
||||
0
crates/brk_binder/src/rust.rs
Normal file
0
crates/brk_binder/src/rust.rs
Normal file
@@ -28,8 +28,8 @@ log = { workspace = true }
|
||||
minreq = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
toml = "0.9.7"
|
||||
zip = { version = "5.1.1", default-features = false, features = ["deflate"] }
|
||||
toml = "0.9.8"
|
||||
zip = { version = "6.0.0", default-features = false, features = ["deflate"] }
|
||||
|
||||
[[bin]]
|
||||
name = "brk"
|
||||
|
||||
@@ -29,4 +29,3 @@ rayon = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
vecdb = { workspace = true }
|
||||
zerocopy = { workspace = true }
|
||||
zerocopy-derive = { workspace = true }
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, AddAssign, SubAssign};
|
||||
|
||||
use brk_structs::{CheckedSub, LoadedAddressData, Sats};
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(Debug, Default, Clone, FromBytes, Immutable, IntoBytes, KnownLayout, Serialize)]
|
||||
pub struct SupplyState {
|
||||
|
||||
@@ -24,4 +24,4 @@ quick_cache = { workspace = true }
|
||||
schemars = { workspace = true }
|
||||
serde = { workspace = true }
|
||||
serde_json = { workspace = true }
|
||||
nucleo-matcher = "0.3.1"
|
||||
rustc-hash = "2.1.1"
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
#![doc = include_str!("../README.md")]
|
||||
|
||||
use std::{collections::BTreeMap, sync::OnceLock};
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use brk_computer::Computer;
|
||||
use brk_error::{Error, Result};
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_parser::Parser;
|
||||
use brk_structs::{
|
||||
@@ -11,11 +11,6 @@ use brk_structs::{
|
||||
TxidPath,
|
||||
};
|
||||
use brk_traversable::TreeNode;
|
||||
use nucleo_matcher::{
|
||||
Config, Matcher,
|
||||
pattern::{AtomKind, CaseMatching, Normalization, Pattern},
|
||||
};
|
||||
use quick_cache::sync::Cache;
|
||||
use vecdb::{AnyCollectableVec, AnyStoredVec};
|
||||
|
||||
mod chain;
|
||||
@@ -23,6 +18,7 @@ mod deser;
|
||||
mod metrics;
|
||||
mod pagination;
|
||||
mod params;
|
||||
mod searcher;
|
||||
mod vecs;
|
||||
|
||||
pub use metrics::{Output, Value};
|
||||
@@ -35,10 +31,10 @@ use crate::{
|
||||
vecs::{IndexToVec, MetricToVec},
|
||||
};
|
||||
|
||||
pub fn cached_errors() -> &'static Cache<String, String> {
|
||||
static CACHE: OnceLock<Cache<String, String>> = OnceLock::new();
|
||||
CACHE.get_or_init(|| Cache::new(1000))
|
||||
}
|
||||
// pub fn cached_errors() -> &'static Cache<String, String> {
|
||||
// static CACHE: OnceLock<Cache<String, String>> = OnceLock::new();
|
||||
// CACHE.get_or_init(|| Cache::new(1000))
|
||||
// }
|
||||
|
||||
#[allow(dead_code)]
|
||||
pub struct Interface<'a> {
|
||||
@@ -75,64 +71,56 @@ impl<'a> Interface<'a> {
|
||||
get_transaction_info(txid, self)
|
||||
}
|
||||
|
||||
pub fn search(&self, params: &Params) -> Result<Vec<(String, &&dyn AnyCollectableVec)>> {
|
||||
let metrics = ¶ms.metrics;
|
||||
let index = params.index;
|
||||
pub fn search_metric(&self, metric: &str, limit: usize) -> Vec<&str> {
|
||||
self.vecs.search(metric, limit)
|
||||
}
|
||||
|
||||
let ids_to_vec = self
|
||||
.vecs
|
||||
.index_to_metric_to_vec
|
||||
.get(&index)
|
||||
.ok_or(Error::String(format!(
|
||||
"Index \"{}\" isn't a valid index",
|
||||
index
|
||||
)))?;
|
||||
pub fn search_metric_with_index(
|
||||
&self,
|
||||
metric: &str,
|
||||
index: Index,
|
||||
// params: &Params,
|
||||
) -> Result<Vec<(String, &&dyn AnyCollectableVec)>> {
|
||||
todo!();
|
||||
|
||||
metrics.iter()
|
||||
.map(|metric| {
|
||||
let vec = ids_to_vec.get(metric.as_str()).ok_or_else(|| {
|
||||
let cached_errors = cached_errors();
|
||||
// let all_metrics = &self.vecs.metrics;
|
||||
// let metrics = ¶ms.metrics;
|
||||
// let index = params.index;
|
||||
|
||||
if let Some(message) = cached_errors.get(metric) {
|
||||
return Error::String(message)
|
||||
}
|
||||
// let ids_to_vec = self
|
||||
// .vecs
|
||||
// .index_to_metric_to_vec
|
||||
// .get(&index)
|
||||
// .ok_or(Error::String(format!(
|
||||
// "Index \"{}\" isn't a valid index",
|
||||
// index
|
||||
// )))?;
|
||||
|
||||
let mut message = format!(
|
||||
"No vec named \"{}\" indexed by \"{}\" found.\n",
|
||||
metric,
|
||||
index
|
||||
);
|
||||
// metrics
|
||||
// .iter()
|
||||
// .map(|metric| {
|
||||
// let vec = ids_to_vec.get(metric.as_str()).ok_or_else(|| {
|
||||
// let matches: Vec<&str> = MATCHER.with(|matcher| {
|
||||
// let matcher = matcher.borrow();
|
||||
// let mut scored: Vec<(&str, i64)> = all_metrics
|
||||
// .iter()
|
||||
// .filter_map(|m| matcher.fuzzy_match(m, metric).map(|s| (*m, s)))
|
||||
// .collect();
|
||||
|
||||
let mut matcher = Matcher::new(Config::DEFAULT);
|
||||
// scored.sort_unstable_by_key(|&(_, s)| std::cmp::Reverse(s));
|
||||
// scored.into_iter().take(5).map(|(m, _)| m).collect()
|
||||
// });
|
||||
|
||||
let matches = Pattern::new(
|
||||
metric.as_str(),
|
||||
CaseMatching::Ignore,
|
||||
Normalization::Smart,
|
||||
AtomKind::Fuzzy,
|
||||
)
|
||||
.match_list(ids_to_vec.keys(), &mut matcher)
|
||||
.into_iter()
|
||||
.take(10)
|
||||
.map(|(s, _)| s)
|
||||
.collect::<Vec<_>>();
|
||||
// let mut message = format!("No vec \"{metric}\" for index \"{index}\".\n");
|
||||
// if !matches.is_empty() {
|
||||
// message += &format!("\nDid you mean: {matches:?}\n");
|
||||
// }
|
||||
|
||||
if !matches.is_empty() {
|
||||
message +=
|
||||
&format!("\nMaybe you meant one of the following: {matches:#?} ?\n");
|
||||
}
|
||||
|
||||
if let Some(index_to_vec) = self.metric_to_index_to_vec().get(metric.as_str()) {
|
||||
message += &format!("\nBut there is a vec named {metric} which supports the following indexes: {:#?}\n", index_to_vec.keys());
|
||||
}
|
||||
|
||||
cached_errors.insert(metric.clone(), message.clone());
|
||||
|
||||
Error::String(message)
|
||||
});
|
||||
vec.map(|vec| (metric.clone(), vec))
|
||||
})
|
||||
.collect::<Result<Vec<_>>>()
|
||||
// Error::String(message)
|
||||
// });
|
||||
// vec.map(|vec| (metric.clone(), vec))
|
||||
// })
|
||||
// .collect::<Result<Vec<_>>>()
|
||||
}
|
||||
|
||||
pub fn format(
|
||||
@@ -227,7 +215,8 @@ impl<'a> Interface<'a> {
|
||||
}
|
||||
|
||||
pub fn search_and_format(&self, params: Params) -> Result<Output> {
|
||||
self.format(self.search(¶ms)?, ¶ms.rest)
|
||||
todo!()
|
||||
// self.format(self.search(¶ms)?, ¶ms.rest)
|
||||
}
|
||||
|
||||
pub fn metric_to_index_to_vec(&self) -> &BTreeMap<&str, IndexToVec<'_>> {
|
||||
@@ -262,7 +251,7 @@ impl<'a> Interface<'a> {
|
||||
}
|
||||
|
||||
pub fn get_metrics_catalog(&self) -> &TreeNode {
|
||||
self.vecs.catalog.as_ref().unwrap()
|
||||
self.vecs.catalog()
|
||||
}
|
||||
|
||||
pub fn get_index_to_vecids(&self, paginated_index: PaginatedIndexParam) -> Vec<&str> {
|
||||
|
||||
200
crates/brk_interface/src/searcher.rs
Normal file
200
crates/brk_interface/src/searcher.rs
Normal file
@@ -0,0 +1,200 @@
|
||||
use std::{marker::PhantomData, ops::Neg, ptr};
|
||||
|
||||
use rustc_hash::{FxHashMap, FxHashSet};
|
||||
|
||||
const MAX_TRIGRAMS: usize = 9;
|
||||
|
||||
pub struct NgramSearcher<'a> {
|
||||
max_word_count: usize,
|
||||
max_word_len: usize,
|
||||
max_query_len: usize,
|
||||
word_index: FxHashMap<String, FxHashSet<*const str>>,
|
||||
trigram_index: FxHashMap<[char; 3], FxHashSet<*const str>>,
|
||||
_phantom: PhantomData<&'a str>,
|
||||
}
|
||||
|
||||
unsafe impl<'a> Send for NgramSearcher<'a> {}
|
||||
unsafe impl<'a> Sync for NgramSearcher<'a> {}
|
||||
|
||||
const SEPARATORS: &[char] = &['_', '-', ' '];
|
||||
|
||||
impl<'a> NgramSearcher<'a> {
|
||||
pub fn new(items: &[&'a str]) -> Self {
|
||||
let mut word_index: FxHashMap<String, FxHashSet<*const str>> = FxHashMap::default();
|
||||
let mut trigram_index: FxHashMap<[char; 3], FxHashSet<*const str>> = FxHashMap::default();
|
||||
let mut max_word_len = 0;
|
||||
let mut max_query_len = 0;
|
||||
let mut max_words = 0;
|
||||
|
||||
for &item in items {
|
||||
max_query_len = max_query_len.max(item.len());
|
||||
let mut word_count = 0;
|
||||
for word in item.split(SEPARATORS) {
|
||||
word_count += 1;
|
||||
if word.is_empty() {
|
||||
continue;
|
||||
}
|
||||
|
||||
max_word_len = max_word_len.max(item.len());
|
||||
|
||||
word_index.entry(word.to_string()).or_default().insert(item);
|
||||
|
||||
if word.len() >= 3 {
|
||||
let chars = word.chars().collect::<Vec<_>>();
|
||||
for window in chars.windows(3) {
|
||||
trigram_index
|
||||
.entry(unsafe { ptr::read(window.as_ptr() as *const [char; 3]) })
|
||||
.or_default()
|
||||
.insert(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
max_words = max_words.max(word_count);
|
||||
}
|
||||
|
||||
Self {
|
||||
max_query_len: max_query_len + 6,
|
||||
max_word_len: max_word_len + 4,
|
||||
max_word_count: max_word_len + 2,
|
||||
word_index,
|
||||
trigram_index,
|
||||
_phantom: PhantomData,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn search(&self, query: &str, limit: usize) -> Vec<&'a str> {
|
||||
let query_lower = query.to_lowercase();
|
||||
let query_len = query_lower.len();
|
||||
|
||||
if query.is_empty() || query_len > self.max_query_len {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let words: FxHashSet<&str> = query_lower
|
||||
.split(SEPARATORS)
|
||||
.filter(|w| !w.is_empty() && w.len() <= self.max_word_len)
|
||||
.collect();
|
||||
|
||||
if words.is_empty() || words.len() > self.max_word_count {
|
||||
return vec![];
|
||||
}
|
||||
|
||||
let min_len = query_len.saturating_sub(3);
|
||||
|
||||
let mut pool: Option<FxHashSet<*const str>> = None;
|
||||
let mut unknown_words = Vec::new();
|
||||
|
||||
let mut words_to_intersect = vec![];
|
||||
for word in words {
|
||||
match self.word_index.get(word) {
|
||||
Some(items) => words_to_intersect.push(items),
|
||||
None => unknown_words.push(word),
|
||||
}
|
||||
}
|
||||
|
||||
if !words_to_intersect.is_empty() {
|
||||
words_to_intersect.sort_unstable_by_key(|set| (set.len() as i64).neg());
|
||||
|
||||
let mut intersect = words_to_intersect.pop().cloned().unwrap();
|
||||
|
||||
for other_set in words_to_intersect.iter().rev() {
|
||||
intersect.retain(|ptr| other_set.contains(ptr));
|
||||
if intersect.is_empty() {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
pool = Some(intersect);
|
||||
}
|
||||
let some_pool = pool.is_some();
|
||||
|
||||
if some_pool && unknown_words.is_empty() {
|
||||
let mut results: Vec<_> = pool
|
||||
.unwrap()
|
||||
.into_iter()
|
||||
.map(|item| unsafe { &*item as &str })
|
||||
.collect();
|
||||
// Partial sort - only sort what we need
|
||||
if results.len() > limit {
|
||||
results.select_nth_unstable_by_key(limit, |item| item.len());
|
||||
results.truncate(limit);
|
||||
}
|
||||
results.sort_unstable_by_key(|item| item.len());
|
||||
return results;
|
||||
}
|
||||
|
||||
// Score candidates
|
||||
let mut scores: FxHashMap<*const str, usize> = FxHashMap::default();
|
||||
scores.reserve(256);
|
||||
if let Some(pool) = &pool {
|
||||
for &item in pool {
|
||||
scores.insert(item, 1);
|
||||
}
|
||||
}
|
||||
let mut trigram_count = 0;
|
||||
'outer: for word in unknown_words {
|
||||
if word.len() < 3 || trigram_count >= MAX_TRIGRAMS {
|
||||
continue;
|
||||
}
|
||||
|
||||
let mut chars = word.chars();
|
||||
let mut a = chars.next().unwrap();
|
||||
let mut b = chars.next().unwrap();
|
||||
|
||||
for c in chars {
|
||||
if trigram_count >= MAX_TRIGRAMS {
|
||||
break 'outer;
|
||||
}
|
||||
trigram_count += 1;
|
||||
|
||||
let trigram = [a, b, c];
|
||||
|
||||
let Some(items) = self.trigram_index.get(&trigram) else {
|
||||
continue;
|
||||
};
|
||||
|
||||
if some_pool {
|
||||
for &item in items {
|
||||
if let Some(score) = scores.get_mut(&item) {
|
||||
*score += 1;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for &item in items {
|
||||
let len = unsafe { &*item }.len();
|
||||
if len >= min_len {
|
||||
*scores.entry(item).or_default() += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Slide window
|
||||
a = b;
|
||||
b = c;
|
||||
}
|
||||
}
|
||||
|
||||
// Filter by minimum score
|
||||
let min_score = trigram_count.div_ceil(2);
|
||||
let mut results: Vec<_> = scores
|
||||
.into_iter()
|
||||
.filter(|(_, s)| *s >= min_score)
|
||||
.map(|(item, score)| (unsafe { &*item as &str }, score))
|
||||
.collect();
|
||||
|
||||
if results.len() > limit {
|
||||
results.select_nth_unstable_by(limit, |a, b| {
|
||||
b.1.cmp(&a.1).then_with(|| a.0.len().cmp(&b.0.len()))
|
||||
});
|
||||
results.truncate(limit);
|
||||
}
|
||||
|
||||
results.sort_unstable_by(|a, b| b.1.cmp(&a.1).then_with(|| a.0.len().cmp(&b.0.len())));
|
||||
|
||||
results
|
||||
.into_iter()
|
||||
.take(limit)
|
||||
.map(|(item, _)| item)
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,10 @@ use brk_traversable::{Traversable, TreeNode};
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use vecdb::AnyCollectableVec;
|
||||
|
||||
use crate::pagination::{PaginatedIndexParam, PaginatedMetrics, PaginationParam};
|
||||
use crate::{
|
||||
pagination::{PaginatedIndexParam, PaginatedMetrics, PaginationParam},
|
||||
searcher::NgramSearcher,
|
||||
};
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct Vecs<'a> {
|
||||
@@ -17,7 +20,9 @@ pub struct Vecs<'a> {
|
||||
pub indexes: Vec<IndexInfo>,
|
||||
pub distinct_metric_count: usize,
|
||||
pub total_metric_count: usize,
|
||||
pub catalog: Option<TreeNode>,
|
||||
pub longest_metric_len: usize,
|
||||
catalog: Option<TreeNode>,
|
||||
searcher: Option<NgramSearcher<'a>>,
|
||||
metric_to_indexes: BTreeMap<&'a str, Vec<Index>>,
|
||||
index_to_metrics: BTreeMap<Index, Vec<&'a str>>,
|
||||
}
|
||||
@@ -55,6 +60,12 @@ impl<'a> Vecs<'a> {
|
||||
sort_ids(&mut ids);
|
||||
|
||||
this.metrics = ids;
|
||||
this.longest_metric_len = this
|
||||
.metrics
|
||||
.iter()
|
||||
.map(|s| s.len())
|
||||
.max()
|
||||
.unwrap_or_default();
|
||||
this.distinct_metric_count = this.metric_to_index_to_vec.keys().count();
|
||||
this.total_metric_count = this
|
||||
.index_to_metric_to_vec
|
||||
@@ -95,6 +106,7 @@ impl<'a> Vecs<'a> {
|
||||
.simplify()
|
||||
.unwrap(),
|
||||
);
|
||||
this.searcher = Some(NgramSearcher::new(&this.metrics));
|
||||
|
||||
this
|
||||
}
|
||||
@@ -157,6 +169,18 @@ impl<'a> Vecs<'a> {
|
||||
|
||||
vec.iter().skip(start).take(end).cloned().collect()
|
||||
}
|
||||
|
||||
pub fn catalog(&self) -> &TreeNode {
|
||||
self.catalog.as_ref().unwrap()
|
||||
}
|
||||
|
||||
pub fn search(&self, metric: &str, limit: usize) -> Vec<&'_ str> {
|
||||
self.searcher().search(metric, limit)
|
||||
}
|
||||
|
||||
fn searcher(&self) -> &NgramSearcher<'_> {
|
||||
self.searcher.as_ref().unwrap()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
|
||||
@@ -34,6 +34,3 @@ sonic-rs = { workspace = true }
|
||||
tokio = { workspace = true }
|
||||
tower-http = { version = "0.6.6", features = ["compression-full", "trace"] }
|
||||
tracing = "0.1.41"
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["clap"]
|
||||
|
||||
@@ -44,82 +44,84 @@ fn req_to_response_res(
|
||||
interface, cache, ..
|
||||
}: AppState,
|
||||
) -> Result<Response> {
|
||||
let vecs = interface.search(¶ms)?;
|
||||
todo!();
|
||||
|
||||
if vecs.is_empty() {
|
||||
return Ok(Json(vec![] as Vec<usize>).into_response());
|
||||
}
|
||||
// let vecs = interface.search(¶ms)?;
|
||||
|
||||
let from = params.from();
|
||||
let to = params.to();
|
||||
let format = params.format();
|
||||
// if vecs.is_empty() {
|
||||
// return Ok(Json(vec![] as Vec<usize>).into_response());
|
||||
// }
|
||||
|
||||
// TODO: From and to should be capped here
|
||||
// let from = params.from();
|
||||
// let to = params.to();
|
||||
// let format = params.format();
|
||||
|
||||
let weight = vecs
|
||||
.iter()
|
||||
.map(|(_, v)| v.range_weight(from, to))
|
||||
.sum::<usize>();
|
||||
// // TODO: From and to should be capped here
|
||||
|
||||
if weight > MAX_WEIGHT {
|
||||
return Err(Error::String(format!(
|
||||
"Request is too heavy, max weight is {MAX_WEIGHT} bytes"
|
||||
)));
|
||||
}
|
||||
// let weight = vecs
|
||||
// .iter()
|
||||
// .map(|(_, v)| v.range_weight(from, to))
|
||||
// .sum::<usize>();
|
||||
|
||||
// TODO: height should be from vec, but good enough for now
|
||||
let etag = vecs
|
||||
.first()
|
||||
.unwrap()
|
||||
.1
|
||||
.etag(Stamp::from(interface.get_height()), to);
|
||||
// if weight > MAX_WEIGHT {
|
||||
// return Err(Error::String(format!(
|
||||
// "Request is too heavy, max weight is {MAX_WEIGHT} bytes"
|
||||
// )));
|
||||
// }
|
||||
|
||||
if headers
|
||||
.get_if_none_match()
|
||||
.is_some_and(|prev_etag| etag == prev_etag)
|
||||
{
|
||||
return Ok(Response::new_not_modified());
|
||||
}
|
||||
// // TODO: height should be from vec, but good enough for now
|
||||
// let etag = vecs
|
||||
// .first()
|
||||
// .unwrap()
|
||||
// .1
|
||||
// .etag(Stamp::from(interface.get_height()), to);
|
||||
|
||||
let guard_res = cache.get_value_or_guard(
|
||||
&format!("{}{}{etag}", uri.path(), uri.query().unwrap_or("")),
|
||||
Some(Duration::from_millis(50)),
|
||||
);
|
||||
// if headers
|
||||
// .get_if_none_match()
|
||||
// .is_some_and(|prev_etag| etag == prev_etag)
|
||||
// {
|
||||
// return Ok(Response::new_not_modified());
|
||||
// }
|
||||
|
||||
let mut response = if let GuardResult::Value(v) = guard_res {
|
||||
Response::new(Body::from(v))
|
||||
} else {
|
||||
match interface.format(vecs, ¶ms.rest)? {
|
||||
Output::CSV(s) => {
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
let _ = g.insert(s.clone().into());
|
||||
}
|
||||
s.into_response()
|
||||
}
|
||||
Output::Json(v) => {
|
||||
let json = v.to_vec();
|
||||
if let GuardResult::Guard(g) = guard_res {
|
||||
let _ = g.insert(json.clone().into());
|
||||
}
|
||||
json.into_response()
|
||||
}
|
||||
}
|
||||
};
|
||||
// let guard_res = cache.get_value_or_guard(
|
||||
// &format!("{}{}{etag}", uri.path(), uri.query().unwrap_or("")),
|
||||
// Some(Duration::from_millis(50)),
|
||||
// );
|
||||
|
||||
let headers = response.headers_mut();
|
||||
// let mut response = if let GuardResult::Value(v) = guard_res {
|
||||
// Response::new(Body::from(v))
|
||||
// } else {
|
||||
// match interface.format(vecs, ¶ms.rest)? {
|
||||
// Output::CSV(s) => {
|
||||
// if let GuardResult::Guard(g) = guard_res {
|
||||
// let _ = g.insert(s.clone().into());
|
||||
// }
|
||||
// s.into_response()
|
||||
// }
|
||||
// Output::Json(v) => {
|
||||
// let json = v.to_vec();
|
||||
// if let GuardResult::Guard(g) = guard_res {
|
||||
// let _ = g.insert(json.clone().into());
|
||||
// }
|
||||
// json.into_response()
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
headers.insert_cors();
|
||||
// let headers = response.headers_mut();
|
||||
|
||||
headers.insert_etag(&etag);
|
||||
headers.insert_cache_control_must_revalidate();
|
||||
// headers.insert_cors();
|
||||
|
||||
match format {
|
||||
Format::CSV => {
|
||||
headers.insert_content_disposition_attachment();
|
||||
headers.insert_content_type_text_csv()
|
||||
}
|
||||
Format::JSON => headers.insert_content_type_application_json(),
|
||||
}
|
||||
// headers.insert_etag(&etag);
|
||||
// headers.insert_cache_control_must_revalidate();
|
||||
|
||||
Ok(response)
|
||||
// match format {
|
||||
// Format::CSV => {
|
||||
// headers.insert_content_disposition_attachment();
|
||||
// headers.insert_content_type_text_csv()
|
||||
// }
|
||||
// Format::JSON => headers.insert_content_type_application_json(),
|
||||
// }
|
||||
|
||||
// Ok(response)
|
||||
}
|
||||
|
||||
@@ -111,17 +111,44 @@ impl ApiMetricsRoutes for ApiRouter<AppState> {
|
||||
},
|
||||
),
|
||||
)
|
||||
// TODO:
|
||||
// .route(
|
||||
// "/api/metrics/search",
|
||||
// get(
|
||||
// async |State(app_state): State<AppState>,
|
||||
// Query(pagination): Query<PaginationParam>|
|
||||
// -> Response {
|
||||
// Json(app_state.interface.get_metrics(pagination)).into_response()
|
||||
// },
|
||||
// ),
|
||||
// )
|
||||
.api_route(
|
||||
"/api/search/{metric}",
|
||||
get_with(
|
||||
async |
|
||||
headers: HeaderMap,
|
||||
State(app_state): State<AppState>,
|
||||
Path(MetricPath { metric }): Path<MetricPath>
|
||||
| {
|
||||
let etag = VERSION;
|
||||
|
||||
if headers
|
||||
.get_if_none_match()
|
||||
.is_some_and(|prev_etag| etag == prev_etag)
|
||||
{
|
||||
return Response::new_not_modified();
|
||||
}
|
||||
|
||||
let bytes = sonic_rs::to_vec(&app_state.interface.search_metric(&metric, usize::MAX)).unwrap();
|
||||
|
||||
let mut response = Response::new_json_from_bytes(bytes);
|
||||
|
||||
let headers = response.headers_mut();
|
||||
headers.insert_cors();
|
||||
headers.insert_etag(etag);
|
||||
|
||||
response
|
||||
},
|
||||
|op| {
|
||||
op.tag("Metrics")
|
||||
.summary("Metric search")
|
||||
.description(
|
||||
"Search metrics based on a query"
|
||||
)
|
||||
.with_ok_response::<Vec<String>, _>(|res| res)
|
||||
.with_not_modified()
|
||||
},
|
||||
),
|
||||
)
|
||||
.api_route(
|
||||
"/api/metrics/{metric}",
|
||||
get_with(
|
||||
|
||||
@@ -27,7 +27,6 @@ serde_bytes = { workspace = true }
|
||||
strum = { version = "0.27", features = ["derive"] }
|
||||
vecdb = { workspace = true }
|
||||
zerocopy = { workspace = true }
|
||||
zerocopy-derive = { workspace = true }
|
||||
|
||||
[package.metadata.cargo-machete]
|
||||
ignored = ["serde_bytes"]
|
||||
|
||||
@@ -9,7 +9,7 @@ use bitcoin::{
|
||||
use brk_error::Error;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::OutputType;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{AddressBytes, OutputType};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{EmptyAddressIndex, LoadedAddressIndex, TypeIndex};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Sats, StoredF64};
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::Add;
|
||||
|
||||
use serde::Serialize;
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug, Clone, Copy, Serialize, FromBytes, Immutable, IntoBytes, KnownLayout, StoredCompressed,
|
||||
|
||||
@@ -4,7 +4,7 @@ use bitcoin::hashes::Hash;
|
||||
use bitcoincore_rpc::{Client, RpcApi};
|
||||
use derive_deref::Deref;
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Height;
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::copy_first_8bytes;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use std::ops::{Add, Div, Mul};
|
||||
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Dollars;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use jiff::{Span, Zoned, civil::Date as Date_, tz::TimeZone};
|
||||
use serde::{Serialize, Serializer};
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::ONE_DAY_IN_SEC_F64;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use brk_error::Error;
|
||||
use jiff::Span;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, FromCoarserIndex, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{DecadeIndex, MonthIndex, QuarterIndex, SemesterIndex, WeekIndex, YearIndex};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Date, DateIndex, YearIndex};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Height;
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ use derive_deref::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Low, Open};
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
use serde::Serialize;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{LoadedAddressData, Sats};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::Serialize;
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Sats, StoredU64};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Height;
|
||||
|
||||
|
||||
@@ -9,8 +9,7 @@ use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, Stamp, StoredCompressed};
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{BLOCKS_PER_DIFF_EPOCHS, BLOCKS_PER_HALVING, copy_first_4bytes};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Vin;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use brk_error::{Error, Result};
|
||||
use serde::Serialize;
|
||||
use vecdb::CheckedSub;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Bitcoin, Dollars, EmptyAddressData, Sats};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Date, DateIndex, YearIndex};
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use allocative::Allocative;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::{Serialize, Serializer, ser::SerializeTuple};
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::StoredF64;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::copy_first_8bytes;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use brk_error::Error;
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use strum::Display;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use allocative::Allocative;
|
||||
use num_enum::{FromPrimitive, IntoPrimitive};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use strum::Display;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
// Created from the list in `pools.rs`
|
||||
// Can be used as index for said list
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::MonthIndex;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use bitcoin::{absolute::LockTime, locktime::absolute::LOCK_TIME_THRESHOLD};
|
||||
use serde::Serialize;
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug, Immutable, Clone, Copy, IntoBytes, KnownLayout, FromBytes, Serialize, StoredCompressed,
|
||||
|
||||
@@ -9,7 +9,7 @@ use derive_deref::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::StoredF64;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::MonthIndex;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -10,7 +10,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Close, StoredU32};
|
||||
|
||||
|
||||
@@ -9,7 +9,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::{Bitcoin, Dollars};
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::{Add, AddAssign, Div};
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{
|
||||
EmptyOutputIndex, OpReturnIndex, P2AAddressIndex, P2MSOutputIndex, P2PK33AddressIndex,
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{
|
||||
EmptyOutputIndex, OpReturnIndex, P2AAddressIndex, P2MSOutputIndex, P2PK33AddressIndex,
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{
|
||||
DateIndex, EmptyOutputIndex, Height, InputIndex, MonthIndex, OpReturnIndex, OutputIndex,
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::{Add, AddAssign, Div};
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
pub type StoredPhantom = StoredU8;
|
||||
|
||||
|
||||
@@ -5,7 +5,7 @@ use derive_deref::Deref;
|
||||
use jiff::{civil::date, tz::TimeZone};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::Date;
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use bitcoin::hashes::Hash;
|
||||
use derive_deref::Deref;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Serialize, Serializer};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug, Deref, Clone, PartialEq, Eq, Immutable, IntoBytes, KnownLayout, FromBytes, JsonSchema,
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
use byteview::ByteView;
|
||||
use derive_deref::Deref;
|
||||
use zerocopy::{FromBytes, IntoBytes};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::copy_first_8bytes;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use derive_deref::{Deref, DerefMut};
|
||||
use schemars::JsonSchema;
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::copy_first_4bytes;
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::StoredU16;
|
||||
|
||||
|
||||
@@ -4,8 +4,7 @@ use byteview::ByteView;
|
||||
use schemars::JsonSchema;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, StoredCompressed};
|
||||
use zerocopy::IntoBytes;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::copy_first_4bytes;
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ use std::ops::Add;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
use serde::Serialize;
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use crate::TypeIndex;
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Date, DateIndex};
|
||||
|
||||
|
||||
@@ -4,7 +4,7 @@ use allocative::Allocative;
|
||||
use derive_deref::Deref;
|
||||
use serde::Serialize;
|
||||
use vecdb::StoredCompressed;
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
#[derive(
|
||||
Debug,
|
||||
|
||||
@@ -6,7 +6,7 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use vecdb::{CheckedSub, PrintableIndex, StoredCompressed};
|
||||
use zerocopy_derive::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout};
|
||||
|
||||
use super::{Date, DateIndex, MonthIndex};
|
||||
|
||||
|
||||
Reference in New Issue
Block a user