mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-07-27 10:48:11 -07:00
global: snapshot
This commit is contained in:
@@ -19,6 +19,7 @@ pub enum Index {
|
||||
Txoutindex,
|
||||
Weekindex,
|
||||
Monthindex,
|
||||
Quarterindex,
|
||||
Yearindex,
|
||||
Decadeindex,
|
||||
Difficultyepoch,
|
||||
@@ -26,11 +27,18 @@ pub enum Index {
|
||||
}
|
||||
|
||||
impl Index {
|
||||
pub fn all() -> [Self; 19] {
|
||||
pub fn all() -> [Self; 20] {
|
||||
[
|
||||
Self::Addressindex,
|
||||
Self::Dateindex,
|
||||
Self::Height,
|
||||
Self::Dateindex,
|
||||
Self::Weekindex,
|
||||
Self::Difficultyepoch,
|
||||
Self::Monthindex,
|
||||
Self::Quarterindex,
|
||||
Self::Yearindex,
|
||||
Self::Decadeindex,
|
||||
Self::Halvingepoch,
|
||||
Self::Addressindex,
|
||||
Self::P2PK33index,
|
||||
Self::P2PK65index,
|
||||
Self::P2PKHindex,
|
||||
@@ -41,37 +49,32 @@ impl Index {
|
||||
Self::Txindex,
|
||||
Self::Txinindex,
|
||||
Self::Txoutindex,
|
||||
Self::Weekindex,
|
||||
Self::Monthindex,
|
||||
Self::Yearindex,
|
||||
Self::Decadeindex,
|
||||
Self::Difficultyepoch,
|
||||
Self::Halvingepoch,
|
||||
]
|
||||
}
|
||||
|
||||
pub fn possible_values(&self) -> &[&str] {
|
||||
// Always have the "correct" id at the end
|
||||
match self {
|
||||
Self::Dateindex => &["d", "date", "di", "dateindex"],
|
||||
Self::Height => &["h", "height"],
|
||||
Self::Txindex => &["txi", "txindex"],
|
||||
Self::Txinindex => &["txini", "txinindex"],
|
||||
Self::Txoutindex => &["txouti", "txoutindex"],
|
||||
Self::Addressindex => &["addri", "addressindex"],
|
||||
Self::P2PK33index => &["p2pk33i", "p2pk33index"],
|
||||
Self::P2PK65index => &["p2pk65i", "p2pk65index"],
|
||||
Self::P2PKHindex => &["p2pkhi", "p2pkhindex"],
|
||||
Self::P2SHindex => &["p2shi", "p2shindex"],
|
||||
Self::P2TRindex => &["p2tri", "p2trindex"],
|
||||
Self::P2WPKHindex => &["p2wpkhi", "p2wpkhindex"],
|
||||
Self::P2WSHindex => &["p2wshi", "p2wshindex"],
|
||||
Self::Weekindex => &["w", "wi", "week", "weekindex"],
|
||||
Self::Monthindex => &["m", "mi", "month", "monthindex"],
|
||||
Self::Yearindex => &["y", "yi", "year", "yearindex"],
|
||||
Self::Decadeindex => &["decade", "decadeindex"],
|
||||
Self::Dateindex => &["d", "date", "dateindex"],
|
||||
Self::Weekindex => &["w", "week", "weekindex"],
|
||||
Self::Difficultyepoch => &["difficulty", "difficultyepoch"],
|
||||
Self::Halvingepoch => &["halving", "halvingepoch"],
|
||||
Self::Monthindex => &["m", "month", "monthindex"],
|
||||
Self::Quarterindex => &["q", "quarter", "quarterindex"],
|
||||
Self::Yearindex => &["y", "year", "yearindex"],
|
||||
Self::Decadeindex => &["decade", "decadeindex"],
|
||||
Self::Halvingepoch => &["h", "halving", "halvingepoch"],
|
||||
Self::Txindex => &["tx", "txindex"],
|
||||
Self::Txinindex => &["txin", "txinindex"],
|
||||
Self::Txoutindex => &["txout", "txoutindex"],
|
||||
Self::Addressindex => &["a", "address", "addressindex"],
|
||||
Self::P2PK33index => &["p2pk33", "p2pk33index"],
|
||||
Self::P2PK65index => &["p2pk65", "p2pk65index"],
|
||||
Self::P2PKHindex => &["p2pkh", "p2pkhindex"],
|
||||
Self::P2SHindex => &["p2sh", "p2shindex"],
|
||||
Self::P2TRindex => &["p2tr", "p2trindex"],
|
||||
Self::P2WPKHindex => &["p2wpkh", "p2wpkhindex"],
|
||||
Self::P2WSHindex => &["p2wsh", "p2wshindex"],
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,6 +84,18 @@ impl Index {
|
||||
.flat_map(|i| i.possible_values().iter().map(|s| s.to_string()))
|
||||
.collect::<Vec<_>>()
|
||||
}
|
||||
|
||||
pub fn serialize_short(&self) -> String {
|
||||
self.possible_values()
|
||||
.iter()
|
||||
.find(|str| str.len() > 1)
|
||||
.unwrap()
|
||||
.to_string()
|
||||
}
|
||||
|
||||
pub fn serialize_long(&self) -> String {
|
||||
self.possible_values().last().unwrap().to_string()
|
||||
}
|
||||
}
|
||||
|
||||
impl TryFrom<&str> for Index {
|
||||
@@ -106,6 +121,7 @@ impl TryFrom<&str> for Index {
|
||||
v if (Self::Decadeindex).possible_values().contains(&v) => Self::Decadeindex,
|
||||
v if (Self::Difficultyepoch).possible_values().contains(&v) => Self::Difficultyepoch,
|
||||
v if (Self::Halvingepoch).possible_values().contains(&v) => Self::Halvingepoch,
|
||||
v if (Self::Quarterindex).possible_values().contains(&v) => Self::Quarterindex,
|
||||
_ => return Err(eyre!("Bad index")),
|
||||
})
|
||||
}
|
||||
|
||||
@@ -13,39 +13,39 @@ mod index;
|
||||
mod output;
|
||||
mod params;
|
||||
mod table;
|
||||
mod tree;
|
||||
mod vec_trees;
|
||||
|
||||
pub use format::Format;
|
||||
pub use index::Index;
|
||||
pub use output::{Output, Value};
|
||||
pub use params::Params;
|
||||
pub use table::Tabled;
|
||||
use tree::VecIdToIndexToVec;
|
||||
use vec_trees::VecTrees;
|
||||
|
||||
pub struct Query<'a> {
|
||||
pub vecid_to_index_to_vec: VecIdToIndexToVec<'a>,
|
||||
pub vec_trees: VecTrees<'a>,
|
||||
_indexer: &'a Indexer,
|
||||
_computer: &'a Computer,
|
||||
}
|
||||
|
||||
impl<'a> Query<'a> {
|
||||
pub fn build(indexer: &'a Indexer, computer: &'a Computer) -> Self {
|
||||
let mut vecs = VecIdToIndexToVec::default();
|
||||
let mut vec_trees = VecTrees::default();
|
||||
|
||||
indexer
|
||||
.vecs()
|
||||
.as_any_vecs()
|
||||
.into_iter()
|
||||
.for_each(|vec| vecs.insert(vec));
|
||||
.for_each(|vec| vec_trees.insert(vec));
|
||||
|
||||
computer
|
||||
.vecs()
|
||||
.as_any_vecs()
|
||||
.into_iter()
|
||||
.for_each(|vec| vecs.insert(vec));
|
||||
.for_each(|vec| vec_trees.insert(vec));
|
||||
|
||||
Self {
|
||||
vecid_to_index_to_vec: vecs,
|
||||
vec_trees,
|
||||
_indexer: indexer,
|
||||
_computer: computer,
|
||||
}
|
||||
@@ -65,11 +65,11 @@ impl<'a> Query<'a> {
|
||||
.collect::<Vec<_>>()
|
||||
})
|
||||
.map(|mut id| {
|
||||
let mut res = self.vecid_to_index_to_vec.get(&id);
|
||||
let mut res = self.vec_trees.id_to_index_to_vec.get(&id);
|
||||
if res.is_none() {
|
||||
if let Ok(index) = Index::try_from(id.as_str()) {
|
||||
id = index.possible_values().last().unwrap().to_string();
|
||||
res = self.vecid_to_index_to_vec.get(&id)
|
||||
res = self.vec_trees.id_to_index_to_vec.get(&id)
|
||||
}
|
||||
}
|
||||
(id, res)
|
||||
|
||||
@@ -1,44 +0,0 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use brk_vec::AnyStorableVec;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
|
||||
use super::index::Index;
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
pub struct VecIdToIndexToVec<'a>(BTreeMap<String, IndexToVec<'a>>);
|
||||
|
||||
impl<'a> VecIdToIndexToVec<'a> {
|
||||
// Not the most performant or type safe but only built once so that's okay
|
||||
pub fn insert(&mut self, vec: &'a dyn AnyStorableVec) {
|
||||
let file_name = vec.file_name();
|
||||
let split = file_name.split("_to_").collect::<Vec<_>>();
|
||||
if split.len() != 2 {
|
||||
panic!();
|
||||
}
|
||||
let str = vec
|
||||
.index_type_to_string()
|
||||
.split("::")
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_lowercase();
|
||||
let index = Index::try_from(str.as_str())
|
||||
.inspect_err(|_| {
|
||||
dbg!(&str);
|
||||
})
|
||||
.unwrap();
|
||||
if split[0] != index.to_string().to_lowercase() {
|
||||
dbg!(&file_name, split[0], index.to_string());
|
||||
panic!();
|
||||
}
|
||||
let key = split[1].to_string().replace("_", "-");
|
||||
let prev = self.entry(key.clone()).or_default().insert(index, vec);
|
||||
if prev.is_some() {
|
||||
dbg!(&key, str, file_name);
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
pub struct IndexToVec<'a>(BTreeMap<Index, &'a dyn AnyStorableVec>);
|
||||
@@ -0,0 +1,93 @@
|
||||
use std::collections::BTreeMap;
|
||||
|
||||
use brk_vec::AnyStorableVec;
|
||||
use derive_deref::{Deref, DerefMut};
|
||||
|
||||
use super::index::Index;
|
||||
|
||||
#[derive(Default)]
|
||||
pub struct VecTrees<'a> {
|
||||
pub id_to_index_to_vec: BTreeMap<String, IndexToVec<'a>>,
|
||||
pub index_to_id_to_vec: BTreeMap<Index, IdToVec<'a>>,
|
||||
}
|
||||
|
||||
impl<'a> VecTrees<'a> {
|
||||
// Not the most performant or type safe but only built once so that's okay
|
||||
pub fn insert(&mut self, vec: &'a dyn AnyStorableVec) {
|
||||
let file_name = vec.file_name();
|
||||
let split = file_name.split("_to_").collect::<Vec<_>>();
|
||||
if split.len() != 2 {
|
||||
panic!();
|
||||
}
|
||||
let str = vec
|
||||
.index_type_to_string()
|
||||
.split("::")
|
||||
.last()
|
||||
.unwrap()
|
||||
.to_lowercase();
|
||||
let index = Index::try_from(str.as_str())
|
||||
.inspect_err(|_| {
|
||||
dbg!(&str);
|
||||
})
|
||||
.unwrap();
|
||||
if split[0] != index.to_string().to_lowercase() {
|
||||
dbg!(&file_name, split[0], index.to_string());
|
||||
panic!();
|
||||
}
|
||||
let key = split[1].to_string().replace("_", "-");
|
||||
let prev = self
|
||||
.id_to_index_to_vec
|
||||
.entry(key.clone())
|
||||
.or_default()
|
||||
.insert(index.clone(), vec);
|
||||
if prev.is_some() {
|
||||
dbg!(&key, str, file_name);
|
||||
panic!()
|
||||
}
|
||||
let prev = self
|
||||
.index_to_id_to_vec
|
||||
.entry(index)
|
||||
.or_default()
|
||||
.insert(key.clone(), vec);
|
||||
if prev.is_some() {
|
||||
dbg!(&key, str, file_name);
|
||||
panic!()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn serialize_id_to_index_to_vec(&self) -> BTreeMap<String, Vec<String>> {
|
||||
self.id_to_index_to_vec
|
||||
.iter()
|
||||
.map(|(id, index_to_vec)| {
|
||||
(
|
||||
id.to_string(),
|
||||
index_to_vec
|
||||
.keys()
|
||||
.map(|i| i.serialize_long())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn serialize_index_to_id_to_vec(&self) -> BTreeMap<String, Vec<String>> {
|
||||
self.index_to_id_to_vec
|
||||
.iter()
|
||||
.map(|(index, id_to_vec)| {
|
||||
(
|
||||
index.serialize_long(),
|
||||
id_to_vec
|
||||
.keys()
|
||||
.map(|id| id.to_string())
|
||||
.collect::<Vec<_>>(),
|
||||
)
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
pub struct IndexToVec<'a>(BTreeMap<Index, &'a dyn AnyStorableVec>);
|
||||
|
||||
#[derive(Default, Deref, DerefMut)]
|
||||
pub struct IdToVec<'a>(BTreeMap<String, &'a dyn AnyStorableVec>);
|
||||
Reference in New Issue
Block a user