mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-24 06:39:58 -07:00
crates: snapshot
This commit is contained in:
@@ -67,12 +67,26 @@ fn update_package_json_version(package_json_path: &Path) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Convert only top-level object keys to camelCase (for consistency with tree field names)
|
||||
/// Nested values (including id fields) are left unchanged for URL paths
|
||||
fn camel_case_top_level_keys(value: Value) -> Value {
|
||||
match value {
|
||||
Value::Object(map) => {
|
||||
let new_map: serde_json::Map<String, Value> = map
|
||||
.into_iter()
|
||||
.map(|(k, v)| (to_camel_case(&k), v))
|
||||
.collect();
|
||||
Value::Object(new_map)
|
||||
}
|
||||
other => other,
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_static_constants(output: &mut String) {
|
||||
use serde::Serialize;
|
||||
|
||||
fn static_const<T: Serialize>(output: &mut String, name: &str, value: &T) {
|
||||
fn instance_const<T: Serialize>(output: &mut String, name: &str, value: &T) {
|
||||
let json = serde_json::to_string_pretty(value).unwrap();
|
||||
// Indent the JSON for proper formatting inside the class
|
||||
let indented = json
|
||||
.lines()
|
||||
.enumerate()
|
||||
@@ -87,23 +101,23 @@ fn generate_static_constants(output: &mut String) {
|
||||
.join("\n");
|
||||
writeln!(
|
||||
output,
|
||||
" static {} = /** @type {{const}} */ ({});\n",
|
||||
" {} = /** @type {{const}} */ ({});\n",
|
||||
name, indented
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
fn static_const_raw(output: &mut String, name: &str, value: &str) {
|
||||
writeln!(output, " static {} = {};\n", name, value).unwrap();
|
||||
fn instance_const_raw(output: &mut String, name: &str, value: &str) {
|
||||
writeln!(output, " {} = {};\n", name, value).unwrap();
|
||||
}
|
||||
|
||||
// VERSION
|
||||
static_const_raw(output, "VERSION", &format!("\"v{}\"", VERSION));
|
||||
instance_const_raw(output, "VERSION", &format!("\"v{}\"", VERSION));
|
||||
|
||||
// INDEXES
|
||||
let indexes = Index::all();
|
||||
let indexes_json: Vec<&'static str> = indexes.iter().map(|i| i.serialize_long()).collect();
|
||||
static_const(output, "INDEXES", &indexes_json);
|
||||
instance_const(output, "INDEXES", &indexes_json);
|
||||
|
||||
// POOL_ID_TO_POOL_NAME
|
||||
let pools = pools();
|
||||
@@ -111,19 +125,43 @@ fn generate_static_constants(output: &mut String) {
|
||||
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
||||
let pool_map: std::collections::BTreeMap<PoolSlug, &'static str> =
|
||||
sorted_pools.iter().map(|p| (p.slug(), p.name)).collect();
|
||||
static_const(output, "POOL_ID_TO_POOL_NAME", &pool_map);
|
||||
instance_const(output, "POOL_ID_TO_POOL_NAME", &pool_map);
|
||||
|
||||
// Cohort names
|
||||
static_const(output, "TERM_NAMES", &TERM_NAMES);
|
||||
static_const(output, "EPOCH_NAMES", &EPOCH_NAMES);
|
||||
static_const(output, "YEAR_NAMES", &YEAR_NAMES);
|
||||
static_const(output, "SPENDABLE_TYPE_NAMES", &SPENDABLE_TYPE_NAMES);
|
||||
static_const(output, "AGE_RANGE_NAMES", &AGE_RANGE_NAMES);
|
||||
static_const(output, "MAX_AGE_NAMES", &MAX_AGE_NAMES);
|
||||
static_const(output, "MIN_AGE_NAMES", &MIN_AGE_NAMES);
|
||||
static_const(output, "AMOUNT_RANGE_NAMES", &AMOUNT_RANGE_NAMES);
|
||||
static_const(output, "GE_AMOUNT_NAMES", &GE_AMOUNT_NAMES);
|
||||
static_const(output, "LT_AMOUNT_NAMES", <_AMOUNT_NAMES);
|
||||
// Cohort names - top-level keys converted to camelCase to match tree field names
|
||||
fn instance_const_camel<T: Serialize>(output: &mut String, name: &str, value: &T) {
|
||||
let json_value: Value = serde_json::to_value(value).unwrap();
|
||||
let camel_value = camel_case_top_level_keys(json_value);
|
||||
let json = serde_json::to_string_pretty(&camel_value).unwrap();
|
||||
let indented = json
|
||||
.lines()
|
||||
.enumerate()
|
||||
.map(|(i, line)| {
|
||||
if i == 0 {
|
||||
line.to_string()
|
||||
} else {
|
||||
format!(" {}", line)
|
||||
}
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
writeln!(
|
||||
output,
|
||||
" {} = /** @type {{const}} */ ({});\n",
|
||||
name, indented
|
||||
)
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
instance_const_camel(output, "TERM_NAMES", &TERM_NAMES);
|
||||
instance_const_camel(output, "EPOCH_NAMES", &EPOCH_NAMES);
|
||||
instance_const_camel(output, "YEAR_NAMES", &YEAR_NAMES);
|
||||
instance_const_camel(output, "SPENDABLE_TYPE_NAMES", &SPENDABLE_TYPE_NAMES);
|
||||
instance_const_camel(output, "AGE_RANGE_NAMES", &AGE_RANGE_NAMES);
|
||||
instance_const_camel(output, "MAX_AGE_NAMES", &MAX_AGE_NAMES);
|
||||
instance_const_camel(output, "MIN_AGE_NAMES", &MIN_AGE_NAMES);
|
||||
instance_const_camel(output, "AMOUNT_RANGE_NAMES", &AMOUNT_RANGE_NAMES);
|
||||
instance_const_camel(output, "GE_AMOUNT_NAMES", &GE_AMOUNT_NAMES);
|
||||
instance_const_camel(output, "LT_AMOUNT_NAMES", <_AMOUNT_NAMES);
|
||||
}
|
||||
|
||||
fn generate_type_definitions(output: &mut String, schemas: &TypeSchemas) {
|
||||
|
||||
@@ -1,240 +0,0 @@
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
fs, io,
|
||||
path::Path,
|
||||
};
|
||||
|
||||
use brk_query::Query;
|
||||
use brk_types::{Index, pools};
|
||||
|
||||
use crate::VERSION;
|
||||
|
||||
const AUTO_GENERATED_DISCLAIMER: &str = "//
|
||||
// File auto-generated, any modifications will be overwritten
|
||||
//";
|
||||
|
||||
pub fn generate_js_files(query: &Query, modules_path: &Path) -> io::Result<()> {
|
||||
let path = modules_path.join("brk-client");
|
||||
|
||||
if !fs::exists(&path)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
let path = path.join("generated");
|
||||
fs::create_dir_all(&path)?;
|
||||
|
||||
generate_version_file(&path)?;
|
||||
generate_metrics_file(query, &path)?;
|
||||
generate_pools_file(&path)
|
||||
}
|
||||
|
||||
fn generate_version_file(parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("version.js"));
|
||||
|
||||
let contents = format!(
|
||||
"{AUTO_GENERATED_DISCLAIMER}
|
||||
|
||||
export const VERSION = \"v{VERSION}\";
|
||||
"
|
||||
);
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn generate_pools_file(parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("pools.js"));
|
||||
|
||||
let pools = pools();
|
||||
|
||||
let mut contents = format!("{AUTO_GENERATED_DISCLAIMER}\n");
|
||||
|
||||
contents += "
|
||||
/**
|
||||
* @typedef {typeof POOL_ID_TO_POOL_NAME} PoolIdToPoolName
|
||||
* @typedef {keyof PoolIdToPoolName} PoolId
|
||||
*/
|
||||
|
||||
export const POOL_ID_TO_POOL_NAME = /** @type {const} */ ({
|
||||
";
|
||||
|
||||
let mut sorted_pools: Vec<_> = pools.iter().collect();
|
||||
sorted_pools.sort_by(|a, b| a.name.to_lowercase().cmp(&b.name.to_lowercase()));
|
||||
|
||||
contents += &sorted_pools
|
||||
.iter()
|
||||
.map(|pool| {
|
||||
let slug = pool.slug();
|
||||
format!(" {slug}: \"{}\",", pool.name)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
|
||||
contents += "\n});\n";
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn generate_metrics_file(query: &Query, parent: &Path) -> io::Result<()> {
|
||||
let path = parent.join(Path::new("metrics.js"));
|
||||
|
||||
let indexes = Index::all();
|
||||
|
||||
let mut contents = format!(
|
||||
"{AUTO_GENERATED_DISCLAIMER}
|
||||
|
||||
export const INDEXES = /** @type {{const}} */ ([
|
||||
{}
|
||||
]);
|
||||
|
||||
/**
|
||||
* @typedef {{typeof INDEXES[number]}} IndexName
|
||||
*/
|
||||
",
|
||||
indexes
|
||||
.iter()
|
||||
.map(|i| format!(" \"{}\"", i.serialize_long()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(",\n")
|
||||
);
|
||||
|
||||
// contents += &indexes
|
||||
// .iter()
|
||||
// .map(|i| format!(" * @typedef {{\"{}\"}} {i}", i.serialize_long()))
|
||||
// .collect::<Vec<_>>()
|
||||
// .join("\n");
|
||||
|
||||
// contents += &format!(
|
||||
// "
|
||||
// * @typedef {{{}}} Index
|
||||
// */
|
||||
// ",
|
||||
// indexes
|
||||
// .iter()
|
||||
// .map(|i| i.to_string())
|
||||
// .collect::<Vec<_>>()
|
||||
// .join(" | ")
|
||||
// );
|
||||
|
||||
let mut unique_index_groups = BTreeMap::new();
|
||||
|
||||
let mut word_to_freq: BTreeMap<_, usize> = BTreeMap::new();
|
||||
query.metric_to_index_to_vec().keys().for_each(|metric| {
|
||||
metric.split("_").for_each(|word| {
|
||||
*word_to_freq.entry(word).or_default() += 1;
|
||||
});
|
||||
});
|
||||
let mut word_to_freq = word_to_freq.into_iter().collect::<Vec<_>>();
|
||||
word_to_freq.sort_unstable_by(|a, b| b.1.cmp(&a.1).then(a.0.cmp(b.0)));
|
||||
let words = word_to_freq
|
||||
.into_iter()
|
||||
.map(|(str, _)| str)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
contents += &format!(
|
||||
"
|
||||
export const INDEX_TO_WORD = [
|
||||
{}
|
||||
];
|
||||
|
||||
",
|
||||
words
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(index, word)| format!("\"{word}\", // {}", index_to_letters(index)))
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n ")
|
||||
);
|
||||
|
||||
let word_to_base62 = words
|
||||
.into_iter()
|
||||
.enumerate()
|
||||
.map(|(i, w)| (w, index_to_letters(i)))
|
||||
.collect::<HashMap<_, _>>();
|
||||
|
||||
let mut ser_metric_to_indexes = "
|
||||
/** @type {Record<string, IndexName[]>} */
|
||||
export const COMPRESSED_METRIC_TO_INDEXES = {
|
||||
"
|
||||
.to_string();
|
||||
|
||||
query
|
||||
.metric_to_index_to_vec()
|
||||
.iter()
|
||||
.for_each(|(metric, index_to_vec)| {
|
||||
let indexes = index_to_vec
|
||||
.keys()
|
||||
.map(|i| format!("\"{}\"", i.serialize_long()))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ");
|
||||
let indexes = format!("[{indexes}]");
|
||||
let unique = unique_index_groups.len();
|
||||
let index = index_to_letters(*unique_index_groups.entry(indexes).or_insert(unique));
|
||||
|
||||
let compressed_metric = metric.split('_').fold(String::new(), |mut acc, w| {
|
||||
if !acc.is_empty() {
|
||||
acc.push('_');
|
||||
}
|
||||
acc.push_str(&word_to_base62[w]);
|
||||
acc
|
||||
});
|
||||
|
||||
ser_metric_to_indexes += &format!(" {compressed_metric}: {index},\n");
|
||||
});
|
||||
|
||||
ser_metric_to_indexes += "};
|
||||
";
|
||||
|
||||
let mut sorted_groups: Vec<_> = unique_index_groups.into_iter().collect();
|
||||
sorted_groups.sort_by_key(|(_, index)| *index);
|
||||
sorted_groups.into_iter().for_each(|(group, index)| {
|
||||
let index = index_to_letters(index);
|
||||
contents += &format!("/** @type {{IndexName[]}} */\nconst {index} = {group};\n");
|
||||
});
|
||||
|
||||
contents += &ser_metric_to_indexes;
|
||||
|
||||
fs::write(path, contents)
|
||||
}
|
||||
|
||||
fn index_to_letters(mut index: usize) -> String {
|
||||
if index < 52 {
|
||||
return (index_to_char(index) as char).to_string();
|
||||
}
|
||||
let mut result = [0u8; 8];
|
||||
let mut pos = 8;
|
||||
loop {
|
||||
pos -= 1;
|
||||
result[pos] = index_to_char(index % 52);
|
||||
index /= 52;
|
||||
if index == 0 {
|
||||
break;
|
||||
}
|
||||
index -= 1;
|
||||
}
|
||||
unsafe { String::from_utf8_unchecked(result[pos..].to_vec()) }
|
||||
}
|
||||
|
||||
fn index_to_char(index: usize) -> u8 {
|
||||
match index {
|
||||
0..=25 => b'A' + index as u8,
|
||||
26..=51 => b'a' + (index - 26) as u8,
|
||||
_ => unreachable!(),
|
||||
}
|
||||
}
|
||||
|
||||
// fn letters_to_index(s: &str) -> usize {
|
||||
// let mut result = 0;
|
||||
// for byte in s.bytes() {
|
||||
// let value = char_to_index(byte) as usize;
|
||||
// result = result * 52 + value + 1;
|
||||
// }
|
||||
// result - 1
|
||||
// }
|
||||
|
||||
// fn char_to_index(byte: u8) -> u8 {
|
||||
// match byte {
|
||||
// b'A'..=b'Z' => byte - b'A',
|
||||
// b'a'..=b'z' => byte - b'a' + 26,
|
||||
// _ => 255, // Invalid
|
||||
// }
|
||||
// }
|
||||
@@ -23,7 +23,8 @@ pub fn generate_rust_client(
|
||||
writeln!(output, "#![allow(non_camel_case_types)]").unwrap();
|
||||
writeln!(output, "#![allow(dead_code)]").unwrap();
|
||||
writeln!(output, "#![allow(unused_variables)]").unwrap();
|
||||
writeln!(output, "#![allow(clippy::useless_format)]\n").unwrap();
|
||||
writeln!(output, "#![allow(clippy::useless_format)]").unwrap();
|
||||
writeln!(output, "#![allow(clippy::unnecessary_to_owned)]\n").unwrap();
|
||||
|
||||
generate_imports(&mut output);
|
||||
generate_base_client(&mut output);
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -30,7 +30,7 @@ fn run() -> Result<()> {
|
||||
|
||||
let computer = Computer::forced_import(&outputs_dir, &indexer, Some(fetcher))?;
|
||||
|
||||
let _a = dbg!(computer.chain.txindex_to_fee.region().meta());
|
||||
let _a = dbg!(computer.chain.transaction.txindex_to_fee.region().meta());
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
139
crates/brk_computer/src/chain/block/compute.rs
Normal file
139
crates/brk_computer/src/chain/block/compute.rs
Normal file
@@ -0,0 +1,139 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{CheckedSub, Height, StoredU32, StoredU64, Timestamp};
|
||||
use vecdb::{Exit, TypedVecIterator};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{Indexes, indexes};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let mut height_to_timestamp_fixed_iter =
|
||||
indexes.block.height_to_timestamp_fixed.into_iter();
|
||||
let mut prev = Height::ZERO;
|
||||
self.height_to_24h_block_count.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexes.block.height_to_timestamp_fixed,
|
||||
|(h, t, ..)| {
|
||||
while t.difference_in_days_between(height_to_timestamp_fixed_iter.get_unwrap(prev))
|
||||
> 0
|
||||
{
|
||||
prev.increment();
|
||||
if prev > h {
|
||||
unreachable!()
|
||||
}
|
||||
}
|
||||
(h, StoredU32::from(*h + 1 - *prev))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_range(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
|h| (h, StoredU32::from(1_u32)),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_1w_block_count
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_block_count.dateindex.unwrap_sum(),
|
||||
7,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_1m_block_count
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_block_count.dateindex.unwrap_sum(),
|
||||
30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_1y_block_count
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_block_count.dateindex.unwrap_sum(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let mut height_to_timestamp_iter = indexer.vecs.block.height_to_timestamp.iter()?;
|
||||
self.height_to_interval.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_timestamp,
|
||||
|(height, timestamp, ..)| {
|
||||
let interval = height.decremented().map_or(Timestamp::ZERO, |prev_h| {
|
||||
let prev_timestamp = height_to_timestamp_iter.get_unwrap(prev_h);
|
||||
timestamp
|
||||
.checked_sub(prev_timestamp)
|
||||
.unwrap_or(Timestamp::ZERO)
|
||||
});
|
||||
(height, interval)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_interval.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.height_to_interval),
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_weight.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&indexer.vecs.block.height_to_weight),
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_size.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&indexer.vecs.block.height_to_total_size),
|
||||
)?;
|
||||
|
||||
self.height_to_vbytes.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
|(h, w, ..)| {
|
||||
(
|
||||
h,
|
||||
StoredU64::from(bitcoin::Weight::from(w).to_vbytes_floor()),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_block_vbytes.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.height_to_vbytes),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
171
crates/brk_computer/src/chain/block/import.rs
Normal file
171
crates/brk_computer/src/chain/block/import.rs
Normal file
@@ -0,0 +1,171 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{StoredU64, Version};
|
||||
use vecdb::{Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom1};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
use crate::chain::{
|
||||
TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DECADE, TARGET_BLOCKS_PER_MONTH,
|
||||
TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK,
|
||||
TARGET_BLOCKS_PER_YEAR,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative();
|
||||
let stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
};
|
||||
let full_stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
};
|
||||
|
||||
let dateindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.dateindex_to_dateindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DAY)),
|
||||
);
|
||||
let weekindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.weekindex_to_weekindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_WEEK)),
|
||||
);
|
||||
let monthindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.monthindex_to_monthindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_MONTH)),
|
||||
);
|
||||
let quarterindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.quarterindex_to_quarterindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_QUARTER)),
|
||||
);
|
||||
let semesterindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.semesterindex_to_semesterindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_SEMESTER)),
|
||||
);
|
||||
let yearindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.yearindex_to_yearindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_YEAR)),
|
||||
);
|
||||
let decadeindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + v0,
|
||||
indexes.time.decadeindex_to_decadeindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DECADE)),
|
||||
);
|
||||
|
||||
let height_to_interval = EagerVec::forced_import(db, "interval", version + v0)?;
|
||||
let height_to_vbytes = EagerVec::forced_import(db, "vbytes", version + v0)?;
|
||||
|
||||
Ok(Self {
|
||||
dateindex_to_block_count_target,
|
||||
weekindex_to_block_count_target,
|
||||
monthindex_to_block_count_target,
|
||||
quarterindex_to_block_count_target,
|
||||
semesterindex_to_block_count_target,
|
||||
yearindex_to_block_count_target,
|
||||
decadeindex_to_block_count_target,
|
||||
height_to_interval: height_to_interval.clone(),
|
||||
height_to_24h_block_count: EagerVec::forced_import(
|
||||
db,
|
||||
"24h_block_count",
|
||||
version + v0,
|
||||
)?,
|
||||
height_to_vbytes: height_to_vbytes.clone(),
|
||||
indexes_to_block_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"block_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
sum_cum(),
|
||||
)?,
|
||||
indexes_to_1w_block_count: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1w_block_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_1m_block_count: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1m_block_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_1y_block_count: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1y_block_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_block_interval: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"block_interval",
|
||||
Source::Vec(height_to_interval.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
stats(),
|
||||
)?,
|
||||
indexes_to_block_size: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"block_size",
|
||||
Source::Vec(indexer.vecs.block.height_to_total_size.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_block_vbytes: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"block_vbytes",
|
||||
Source::Vec(height_to_vbytes.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_block_weight: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"block_weight",
|
||||
Source::Vec(indexer.vecs.block.height_to_weight.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/block/mod.rs
Normal file
5
crates/brk_computer/src/chain/block/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
35
crates/brk_computer/src/chain/block/vecs.rs
Normal file
35
crates/brk_computer/src/chain/block/vecs.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
DateIndex, DecadeIndex, Height, MonthIndex, QuarterIndex, SemesterIndex, StoredU32, StoredU64,
|
||||
Timestamp, WeekIndex, Weight, YearIndex,
|
||||
};
|
||||
use vecdb::{EagerVec, LazyVecFrom1, PcoVec};
|
||||
|
||||
use crate::grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight};
|
||||
|
||||
/// Block-related metrics: count, interval, size, weight, vbytes
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub dateindex_to_block_count_target: LazyVecFrom1<DateIndex, StoredU64, DateIndex, DateIndex>,
|
||||
pub weekindex_to_block_count_target: LazyVecFrom1<WeekIndex, StoredU64, WeekIndex, WeekIndex>,
|
||||
pub monthindex_to_block_count_target:
|
||||
LazyVecFrom1<MonthIndex, StoredU64, MonthIndex, MonthIndex>,
|
||||
pub quarterindex_to_block_count_target:
|
||||
LazyVecFrom1<QuarterIndex, StoredU64, QuarterIndex, QuarterIndex>,
|
||||
pub semesterindex_to_block_count_target:
|
||||
LazyVecFrom1<SemesterIndex, StoredU64, SemesterIndex, SemesterIndex>,
|
||||
pub yearindex_to_block_count_target: LazyVecFrom1<YearIndex, StoredU64, YearIndex, YearIndex>,
|
||||
pub decadeindex_to_block_count_target:
|
||||
LazyVecFrom1<DecadeIndex, StoredU64, DecadeIndex, DecadeIndex>,
|
||||
pub height_to_interval: EagerVec<PcoVec<Height, Timestamp>>,
|
||||
pub height_to_24h_block_count: EagerVec<PcoVec<Height, StoredU32>>,
|
||||
pub height_to_vbytes: EagerVec<PcoVec<Height, StoredU64>>,
|
||||
pub indexes_to_block_count: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_1w_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_1m_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_1y_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_block_interval: ComputedVecsFromHeight<Timestamp>,
|
||||
pub indexes_to_block_size: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_block_vbytes: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_block_weight: ComputedVecsFromHeight<Weight>,
|
||||
}
|
||||
225
crates/brk_computer/src/chain/coinbase/compute.rs
Normal file
225
crates/brk_computer/src/chain/coinbase/compute.rs
Normal file
@@ -0,0 +1,225 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{CheckedSub, Dollars, HalvingEpoch, Height, Sats, StoredF32, TxOutIndex};
|
||||
use vecdb::{Exit, IterableVec, TypedVecIterator, VecIndex};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
Indexes,
|
||||
chain::{block, transaction},
|
||||
indexes, price,
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
block_vecs: &block::Vecs,
|
||||
transaction_vecs: &transaction::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
price: Option<&price::Vecs>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.indexes_to_coinbase
|
||||
.compute_all(indexes, price, starting_indexes, exit, |vec| {
|
||||
let mut txindex_to_first_txoutindex_iter =
|
||||
indexer.vecs.tx.txindex_to_first_txoutindex.iter()?;
|
||||
let mut txindex_to_output_count_iter =
|
||||
indexes.transaction.txindex_to_output_count.iter();
|
||||
let mut txoutindex_to_value_iter = indexer.vecs.txout.txoutindex_to_value.iter()?;
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
|(height, txindex, ..)| {
|
||||
let first_txoutindex = txindex_to_first_txoutindex_iter
|
||||
.get_unwrap(txindex)
|
||||
.to_usize();
|
||||
let output_count = txindex_to_output_count_iter.get_unwrap(txindex);
|
||||
let mut sats = Sats::ZERO;
|
||||
(first_txoutindex..first_txoutindex + usize::from(output_count)).for_each(
|
||||
|txoutindex| {
|
||||
sats += txoutindex_to_value_iter
|
||||
.get_unwrap(TxOutIndex::from(txoutindex));
|
||||
},
|
||||
);
|
||||
(height, sats)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let mut height_to_coinbase_iter = self
|
||||
.indexes_to_coinbase
|
||||
.sats
|
||||
.height
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.into_iter();
|
||||
self.height_to_24h_coinbase_sum.compute_transform(
|
||||
starting_indexes.height,
|
||||
&block_vecs.height_to_24h_block_count,
|
||||
|(h, count, ..)| {
|
||||
let range = *h - (*count - 1)..=*h;
|
||||
let sum = range
|
||||
.map(Height::from)
|
||||
.map(|h| height_to_coinbase_iter.get_unwrap(h))
|
||||
.sum::<Sats>();
|
||||
(h, sum)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
drop(height_to_coinbase_iter);
|
||||
|
||||
if let Some(mut height_to_coinbase_iter) = self
|
||||
.indexes_to_coinbase
|
||||
.dollars
|
||||
.as_ref()
|
||||
.map(|c| c.height.u().into_iter())
|
||||
{
|
||||
self.height_to_24h_coinbase_usd_sum.compute_transform(
|
||||
starting_indexes.height,
|
||||
&block_vecs.height_to_24h_block_count,
|
||||
|(h, count, ..)| {
|
||||
let range = *h - (*count - 1)..=*h;
|
||||
let sum = range
|
||||
.map(Height::from)
|
||||
.map(|h| height_to_coinbase_iter.get_unwrap(h))
|
||||
.sum::<Dollars>();
|
||||
(h, sum)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
|
||||
self.indexes_to_subsidy
|
||||
.compute_all(indexes, price, starting_indexes, exit, |vec| {
|
||||
vec.compute_transform2(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_coinbase.sats.height.u(),
|
||||
transaction_vecs.indexes_to_fee.sats.height.unwrap_sum(),
|
||||
|(height, coinbase, fees, ..)| {
|
||||
(
|
||||
height,
|
||||
coinbase.checked_sub(fees).unwrap_or_else(|| {
|
||||
dbg!(height, coinbase, fees);
|
||||
panic!()
|
||||
}),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_unclaimed_rewards.compute_all(
|
||||
indexes,
|
||||
price,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|vec| {
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_subsidy.sats.height.u(),
|
||||
|(height, subsidy, ..)| {
|
||||
let halving = HalvingEpoch::from(height);
|
||||
let expected = Sats::FIFTY_BTC / 2_usize.pow(halving.to_usize() as u32);
|
||||
(height, expected.checked_sub(subsidy).unwrap())
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_inflation_rate
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_subsidy.sats.dateindex.unwrap_sum(),
|
||||
self.indexes_to_subsidy.sats.dateindex.unwrap_cumulative(),
|
||||
|(i, subsidy_1d_sum, subsidy_cumulative, ..)| {
|
||||
(
|
||||
i,
|
||||
(365.0 * *subsidy_1d_sum as f64 / *subsidy_cumulative as f64 * 100.0)
|
||||
.into(),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.dateindex_to_fee_dominance.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
transaction_vecs.indexes_to_fee.sats.dateindex.unwrap_sum(),
|
||||
self.indexes_to_coinbase.sats.dateindex.unwrap_sum(),
|
||||
|(i, fee, coinbase, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF32::from(u64::from(fee) as f64 / u64::from(coinbase) as f64 * 100.0),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_subsidy_dominance.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_subsidy.sats.dateindex.unwrap_sum(),
|
||||
self.indexes_to_coinbase.sats.dateindex.unwrap_sum(),
|
||||
|(i, subsidy, coinbase, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF32::from(u64::from(subsidy) as f64 / u64::from(coinbase) as f64 * 100.0),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
if self.indexes_to_subsidy_usd_1y_sma.is_some() {
|
||||
let date_to_coinbase_usd_sum = self
|
||||
.indexes_to_coinbase
|
||||
.dollars
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.dateindex
|
||||
.unwrap_sum();
|
||||
|
||||
self.indexes_to_subsidy_usd_1y_sma
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
date_to_coinbase_usd_sum,
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_puell_multiple
|
||||
.as_mut()
|
||||
.unwrap()
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_divide(
|
||||
starting_indexes.dateindex,
|
||||
date_to_coinbase_usd_sum,
|
||||
self.indexes_to_subsidy_usd_1y_sma
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
109
crates/brk_computer/src/chain/coinbase/import.rs
Normal file
109
crates/brk_computer/src/chain/coinbase/import.rs
Normal file
@@ -0,0 +1,109 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
compute_dollars: bool,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
|
||||
Ok(Self {
|
||||
height_to_24h_coinbase_sum: EagerVec::forced_import(
|
||||
db,
|
||||
"24h_coinbase_sum",
|
||||
version + v0,
|
||||
)?,
|
||||
height_to_24h_coinbase_usd_sum: EagerVec::forced_import(
|
||||
db,
|
||||
"24h_coinbase_usd_sum",
|
||||
version + v0,
|
||||
)?,
|
||||
indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import(
|
||||
db,
|
||||
"coinbase",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
VecBuilderOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_percentiles()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import(
|
||||
db,
|
||||
"subsidy",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
VecBuilderOptions::default()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight::forced_import(
|
||||
db,
|
||||
"unclaimed_rewards",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
VecBuilderOptions::default().add_sum().add_cumulative(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
dateindex_to_fee_dominance: EagerVec::forced_import(db, "fee_dominance", version + v0)?,
|
||||
dateindex_to_subsidy_dominance: EagerVec::forced_import(
|
||||
db,
|
||||
"subsidy_dominance",
|
||||
version + v0,
|
||||
)?,
|
||||
indexes_to_subsidy_usd_1y_sma: compute_dollars
|
||||
.then(|| {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"subsidy_usd_1y_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)
|
||||
})
|
||||
.transpose()?,
|
||||
indexes_to_puell_multiple: compute_dollars
|
||||
.then(|| {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"puell_multiple",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)
|
||||
})
|
||||
.transpose()?,
|
||||
indexes_to_inflation_rate: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"inflation_rate",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/coinbase/mod.rs
Normal file
5
crates/brk_computer/src/chain/coinbase/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
20
crates/brk_computer/src/chain/coinbase/vecs.rs
Normal file
20
crates/brk_computer/src/chain/coinbase/vecs.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{DateIndex, Dollars, Height, Sats, StoredF32};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
use crate::grouped::{ComputedValueVecsFromHeight, ComputedVecsFromDateIndex};
|
||||
|
||||
/// Coinbase/subsidy/rewards metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub height_to_24h_coinbase_sum: EagerVec<PcoVec<Height, Sats>>,
|
||||
pub height_to_24h_coinbase_usd_sum: EagerVec<PcoVec<Height, Dollars>>,
|
||||
pub indexes_to_coinbase: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_subsidy: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight,
|
||||
pub dateindex_to_fee_dominance: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub dateindex_to_subsidy_dominance: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub indexes_to_subsidy_usd_1y_sma: Option<ComputedVecsFromDateIndex<Dollars>>,
|
||||
pub indexes_to_puell_multiple: Option<ComputedVecsFromDateIndex<StoredF32>>,
|
||||
pub indexes_to_inflation_rate: ComputedVecsFromDateIndex<StoredF32>,
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
85
crates/brk_computer/src/chain/epoch/compute.rs
Normal file
85
crates/brk_computer/src/chain/epoch/compute.rs
Normal file
@@ -0,0 +1,85 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::Timestamp;
|
||||
use vecdb::{Exit, TypedVecIterator};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{Indexes, indexes};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.timeindexes_to_timestamp
|
||||
.compute_all(starting_indexes, exit, |vec| {
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&indexes.time.dateindex_to_date,
|
||||
|(di, d, ..)| (di, Timestamp::from(d)),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let mut height_to_timestamp_iter = indexer.vecs.block.height_to_timestamp.iter()?;
|
||||
|
||||
self.difficultyepoch_to_timestamp.compute_transform(
|
||||
starting_indexes.difficultyepoch,
|
||||
&indexes.block.difficultyepoch_to_first_height,
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_timestamp.compute_transform(
|
||||
starting_indexes.halvingepoch,
|
||||
&indexes.block.halvingepoch_to_first_height,
|
||||
|(i, h, ..)| (i, height_to_timestamp_iter.get_unwrap(h)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let mut height_to_difficultyepoch_iter =
|
||||
indexes.block.height_to_difficultyepoch.into_iter();
|
||||
self.indexes_to_difficultyepoch
|
||||
.compute_all(starting_indexes, exit, |vec| {
|
||||
let mut height_count_iter = indexes.time.dateindex_to_height_count.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&indexes.time.dateindex_to_first_height,
|
||||
|(di, height, ..)| {
|
||||
(
|
||||
di,
|
||||
height_to_difficultyepoch_iter
|
||||
.get_unwrap(height + (*height_count_iter.get_unwrap(di) - 1)),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
let mut height_to_halvingepoch_iter = indexes.block.height_to_halvingepoch.into_iter();
|
||||
self.indexes_to_halvingepoch
|
||||
.compute_all(starting_indexes, exit, |vec| {
|
||||
let mut height_count_iter = indexes.time.dateindex_to_height_count.into_iter();
|
||||
vec.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
&indexes.time.dateindex_to_first_height,
|
||||
|(di, height, ..)| {
|
||||
(
|
||||
di,
|
||||
height_to_halvingepoch_iter
|
||||
.get_unwrap(height + (*height_count_iter.get_unwrap(di) - 1)),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
45
crates/brk_computer/src/chain/epoch/import.rs
Normal file
45
crates/brk_computer/src/chain/epoch/import.rs
Normal file
@@ -0,0 +1,45 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedVecsFromDateIndex, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
|
||||
Ok(Self {
|
||||
difficultyepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?,
|
||||
halvingepoch_to_timestamp: EagerVec::forced_import(db, "timestamp", version + v0)?,
|
||||
timeindexes_to_timestamp: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"timestamp",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
VecBuilderOptions::default().add_first(),
|
||||
)?,
|
||||
indexes_to_difficultyepoch: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"difficultyepoch",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_halvingepoch: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"halvingepoch",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/epoch/mod.rs
Normal file
5
crates/brk_computer/src/chain/epoch/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
15
crates/brk_computer/src/chain/epoch/vecs.rs
Normal file
15
crates/brk_computer/src/chain/epoch/vecs.rs
Normal file
@@ -0,0 +1,15 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{DifficultyEpoch, HalvingEpoch, Timestamp};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
use crate::grouped::ComputedVecsFromDateIndex;
|
||||
|
||||
/// Epoch and timestamp metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub difficultyepoch_to_timestamp: EagerVec<PcoVec<DifficultyEpoch, Timestamp>>,
|
||||
pub halvingepoch_to_timestamp: EagerVec<PcoVec<HalvingEpoch, Timestamp>>,
|
||||
pub timeindexes_to_timestamp: ComputedVecsFromDateIndex<Timestamp>,
|
||||
pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex<DifficultyEpoch>,
|
||||
pub indexes_to_halvingepoch: ComputedVecsFromDateIndex<HalvingEpoch>,
|
||||
}
|
||||
@@ -3,24 +3,14 @@ use std::path::Path;
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{StoredBool, StoredU64, TxIndex, Version, Weight};
|
||||
use vecdb::{
|
||||
Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom1, LazyVecFrom2, PAGE_SIZE,
|
||||
VecIndex,
|
||||
};
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, PAGE_SIZE};
|
||||
|
||||
use crate::{
|
||||
grouped::{
|
||||
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex,
|
||||
ComputedVecsFromHeight, ComputedVecsFromTxindex, Source, VecBuilderOptions,
|
||||
},
|
||||
indexes, price,
|
||||
};
|
||||
use crate::{indexes, price};
|
||||
|
||||
use super::{
|
||||
TARGET_BLOCKS_PER_DAY, TARGET_BLOCKS_PER_DECADE, TARGET_BLOCKS_PER_MONTH,
|
||||
TARGET_BLOCKS_PER_QUARTER, TARGET_BLOCKS_PER_SEMESTER, TARGET_BLOCKS_PER_WEEK,
|
||||
TARGET_BLOCKS_PER_YEAR, Vecs,
|
||||
BlockVecs, CoinbaseVecs, EpochVecs, MiningVecs, OutputTypeVecs, TransactionVecs, Vecs,
|
||||
VolumeVecs,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
@@ -35,470 +25,25 @@ impl Vecs {
|
||||
db.set_min_len(PAGE_SIZE * 50_000_000)?;
|
||||
|
||||
let version = parent_version + Version::ZERO;
|
||||
|
||||
let compute_dollars = price.is_some();
|
||||
let v0 = Version::ZERO;
|
||||
let v2 = Version::TWO;
|
||||
let v4 = Version::new(4);
|
||||
let v5 = Version::new(5);
|
||||
|
||||
macro_rules! eager {
|
||||
($name:expr) => {
|
||||
EagerVec::forced_import(&db, $name, version + v0)?
|
||||
};
|
||||
($name:expr, $v:expr) => {
|
||||
EagerVec::forced_import(&db, $name, version + $v)?
|
||||
};
|
||||
}
|
||||
macro_rules! computed_h {
|
||||
($name:expr, $source:expr, $opts:expr) => {
|
||||
ComputedVecsFromHeight::forced_import(
|
||||
&db,
|
||||
$name,
|
||||
$source,
|
||||
version + v0,
|
||||
indexes,
|
||||
$opts,
|
||||
)?
|
||||
};
|
||||
($name:expr, $source:expr, $v:expr, $opts:expr) => {
|
||||
ComputedVecsFromHeight::forced_import(
|
||||
&db,
|
||||
$name,
|
||||
$source,
|
||||
version + $v,
|
||||
indexes,
|
||||
$opts,
|
||||
)?
|
||||
};
|
||||
}
|
||||
macro_rules! computed_di {
|
||||
($name:expr, $opts:expr) => {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
&db,
|
||||
$name,
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
$opts,
|
||||
)?
|
||||
};
|
||||
($name:expr, $v:expr, $opts:expr) => {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
&db,
|
||||
$name,
|
||||
Source::Compute,
|
||||
version + $v,
|
||||
indexes,
|
||||
$opts,
|
||||
)?
|
||||
};
|
||||
}
|
||||
macro_rules! computed_tx {
|
||||
($name:expr, $source:expr, $opts:expr) => {
|
||||
ComputedVecsFromTxindex::forced_import(
|
||||
&db,
|
||||
$name,
|
||||
$source,
|
||||
version + v0,
|
||||
indexes,
|
||||
$opts,
|
||||
)?
|
||||
};
|
||||
}
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
let sum = || VecBuilderOptions::default().add_sum();
|
||||
let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative();
|
||||
let stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
};
|
||||
let full_stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
};
|
||||
|
||||
let txindex_to_weight = LazyVecFrom2::init(
|
||||
"weight",
|
||||
version + Version::ZERO,
|
||||
indexer.vecs.tx.txindex_to_base_size.boxed_clone(),
|
||||
indexer.vecs.tx.txindex_to_total_size.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_base_size_iter, txindex_to_total_size_iter| {
|
||||
let index = index.to_usize();
|
||||
txindex_to_base_size_iter.get_at(index).map(|base_size| {
|
||||
let total_size = txindex_to_total_size_iter.get_at_unwrap(index);
|
||||
|
||||
// This is the exact definition of a weight unit, as defined by BIP-141 (quote above).
|
||||
let wu = usize::from(base_size) * 3 + usize::from(total_size);
|
||||
|
||||
Weight::from(bitcoin::Weight::from_wu_usize(wu))
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let txindex_to_vsize = LazyVecFrom1::init(
|
||||
"vsize",
|
||||
version + Version::ZERO,
|
||||
txindex_to_weight.boxed_clone(),
|
||||
|index: TxIndex, iter| iter.get(index).map(brk_types::VSize::from),
|
||||
);
|
||||
|
||||
let txindex_to_is_coinbase = LazyVecFrom2::init(
|
||||
"is_coinbase",
|
||||
version + Version::ZERO,
|
||||
indexer.vecs.tx.txindex_to_height.boxed_clone(),
|
||||
indexer.vecs.tx.height_to_first_txindex.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_height_iter, height_to_first_txindex_iter| {
|
||||
txindex_to_height_iter.get(index).map(|height| {
|
||||
let txindex = height_to_first_txindex_iter.get_unwrap(height);
|
||||
StoredBool::from(index == txindex)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let txindex_to_input_value = eager!("input_value");
|
||||
let txindex_to_output_value = eager!("output_value");
|
||||
let txindex_to_fee = eager!("fee");
|
||||
let txindex_to_fee_rate = eager!("fee_rate");
|
||||
|
||||
let dateindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.dateindex_to_dateindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DAY)),
|
||||
);
|
||||
let weekindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.weekindex_to_weekindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_WEEK)),
|
||||
);
|
||||
let monthindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.monthindex_to_monthindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_MONTH)),
|
||||
);
|
||||
let quarterindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.quarterindex_to_quarterindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_QUARTER)),
|
||||
);
|
||||
let semesterindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.semesterindex_to_semesterindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_SEMESTER)),
|
||||
);
|
||||
let yearindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.yearindex_to_yearindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_YEAR)),
|
||||
);
|
||||
let decadeindex_to_block_count_target = LazyVecFrom1::init(
|
||||
"block_count_target",
|
||||
version + Version::ZERO,
|
||||
indexes.decadeindex_to_decadeindex.boxed_clone(),
|
||||
|_, _| Some(StoredU64::from(TARGET_BLOCKS_PER_DECADE)),
|
||||
);
|
||||
|
||||
let height_to_interval = eager!("interval");
|
||||
let height_to_vbytes = eager!("vbytes");
|
||||
let block = BlockVecs::forced_import(&db, version, indexer, indexes)?;
|
||||
let epoch = EpochVecs::forced_import(&db, version, indexes)?;
|
||||
let mining = MiningVecs::forced_import(&db, version, indexer, indexes)?;
|
||||
let coinbase = CoinbaseVecs::forced_import(&db, version, indexes, compute_dollars)?;
|
||||
let transaction = TransactionVecs::forced_import(&db, version, indexer, indexes, price)?;
|
||||
let output_type = OutputTypeVecs::forced_import(&db, version, indexes)?;
|
||||
let volume = VolumeVecs::forced_import(&db, version, indexes, compute_dollars)?;
|
||||
|
||||
let this = Self {
|
||||
dateindex_to_block_count_target,
|
||||
weekindex_to_block_count_target,
|
||||
monthindex_to_block_count_target,
|
||||
quarterindex_to_block_count_target,
|
||||
semesterindex_to_block_count_target,
|
||||
yearindex_to_block_count_target,
|
||||
decadeindex_to_block_count_target,
|
||||
timeindexes_to_timestamp: computed_di!(
|
||||
"timestamp",
|
||||
VecBuilderOptions::default().add_first()
|
||||
),
|
||||
indexes_to_block_interval: computed_h!(
|
||||
"block_interval",
|
||||
Source::Vec(height_to_interval.boxed_clone()),
|
||||
stats()
|
||||
),
|
||||
indexes_to_block_count: computed_h!("block_count", Source::Compute, sum_cum()),
|
||||
indexes_to_1w_block_count: computed_di!("1w_block_count", last()),
|
||||
indexes_to_1m_block_count: computed_di!("1m_block_count", last()),
|
||||
indexes_to_1y_block_count: computed_di!("1y_block_count", last()),
|
||||
indexes_to_block_weight: computed_h!(
|
||||
"block_weight",
|
||||
Source::Vec(indexer.vecs.block.height_to_weight.boxed_clone()),
|
||||
full_stats()
|
||||
),
|
||||
indexes_to_block_size: computed_h!(
|
||||
"block_size",
|
||||
Source::Vec(indexer.vecs.block.height_to_total_size.boxed_clone()),
|
||||
full_stats()
|
||||
),
|
||||
height_to_24h_block_count: eager!("24h_block_count"),
|
||||
height_to_24h_coinbase_sum: eager!("24h_coinbase_sum"),
|
||||
height_to_24h_coinbase_usd_sum: eager!("24h_coinbase_usd_sum"),
|
||||
indexes_to_block_vbytes: computed_h!(
|
||||
"block_vbytes",
|
||||
Source::Vec(height_to_vbytes.boxed_clone()),
|
||||
full_stats()
|
||||
),
|
||||
difficultyepoch_to_timestamp: eager!("timestamp"),
|
||||
halvingepoch_to_timestamp: eager!("timestamp"),
|
||||
|
||||
dateindex_to_fee_dominance: eager!("fee_dominance"),
|
||||
dateindex_to_subsidy_dominance: eager!("subsidy_dominance"),
|
||||
indexes_to_difficulty: computed_h!(
|
||||
"difficulty",
|
||||
Source::Vec(indexer.vecs.block.height_to_difficulty.boxed_clone()),
|
||||
last()
|
||||
),
|
||||
height_to_interval,
|
||||
height_to_vbytes,
|
||||
indexes_to_difficultyepoch: computed_di!("difficultyepoch", last()),
|
||||
indexes_to_halvingepoch: computed_di!("halvingepoch", last()),
|
||||
indexes_to_tx_count: computed_h!("tx_count", Source::Compute, full_stats()),
|
||||
indexes_to_input_count: computed_tx!(
|
||||
"input_count",
|
||||
Source::Vec(indexes.txindex_to_input_count.boxed_clone()),
|
||||
full_stats()
|
||||
),
|
||||
indexes_to_output_count: computed_tx!(
|
||||
"output_count",
|
||||
Source::Vec(indexes.txindex_to_output_count.boxed_clone()),
|
||||
full_stats()
|
||||
),
|
||||
indexes_to_tx_v1: computed_h!("tx_v1", Source::Compute, sum_cum()),
|
||||
indexes_to_tx_v2: computed_h!("tx_v2", Source::Compute, sum_cum()),
|
||||
indexes_to_tx_v3: computed_h!("tx_v3", Source::Compute, sum_cum()),
|
||||
indexes_to_sent_sum: ComputedValueVecsFromHeight::forced_import(
|
||||
&db,
|
||||
"sent_sum",
|
||||
Source::Compute,
|
||||
version + Version::ZERO,
|
||||
VecBuilderOptions::default().add_sum(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_fee: ComputedValueVecsFromTxindex::forced_import(
|
||||
&db,
|
||||
"fee",
|
||||
indexer,
|
||||
indexes,
|
||||
Source::Vec(txindex_to_fee.boxed_clone()),
|
||||
version + Version::ZERO,
|
||||
price,
|
||||
VecBuilderOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_percentiles()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
)?,
|
||||
indexes_to_fee_rate: computed_tx!(
|
||||
"fee_rate",
|
||||
Source::Vec(txindex_to_fee_rate.boxed_clone()),
|
||||
stats()
|
||||
),
|
||||
indexes_to_tx_vsize: computed_tx!(
|
||||
"tx_vsize",
|
||||
Source::Vec(txindex_to_vsize.boxed_clone()),
|
||||
stats()
|
||||
),
|
||||
indexes_to_tx_weight: computed_tx!(
|
||||
"tx_weight",
|
||||
Source::Vec(txindex_to_weight.boxed_clone()),
|
||||
stats()
|
||||
),
|
||||
indexes_to_subsidy: ComputedValueVecsFromHeight::forced_import(
|
||||
&db,
|
||||
"subsidy",
|
||||
Source::Compute,
|
||||
version + Version::ZERO,
|
||||
VecBuilderOptions::default()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_coinbase: ComputedValueVecsFromHeight::forced_import(
|
||||
&db,
|
||||
"coinbase",
|
||||
Source::Compute,
|
||||
version + Version::ZERO,
|
||||
VecBuilderOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_percentiles()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight::forced_import(
|
||||
&db,
|
||||
"unclaimed_rewards",
|
||||
Source::Compute,
|
||||
version + Version::ZERO,
|
||||
VecBuilderOptions::default().add_sum().add_cumulative(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_p2a_count: computed_h!("p2a_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2ms_count: computed_h!("p2ms_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2pk33_count: computed_h!("p2pk33_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2pk65_count: computed_h!("p2pk65_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2pkh_count: computed_h!("p2pkh_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2sh_count: computed_h!("p2sh_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2tr_count: computed_h!("p2tr_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2wpkh_count: computed_h!("p2wpkh_count", Source::Compute, full_stats()),
|
||||
indexes_to_p2wsh_count: computed_h!("p2wsh_count", Source::Compute, full_stats()),
|
||||
indexes_to_opreturn_count: computed_h!("opreturn_count", Source::Compute, full_stats()),
|
||||
indexes_to_unknownoutput_count: computed_h!(
|
||||
"unknownoutput_count",
|
||||
Source::Compute,
|
||||
full_stats()
|
||||
),
|
||||
indexes_to_emptyoutput_count: computed_h!(
|
||||
"emptyoutput_count",
|
||||
Source::Compute,
|
||||
full_stats()
|
||||
),
|
||||
indexes_to_exact_utxo_count: computed_h!("exact_utxo_count", Source::Compute, last()),
|
||||
indexes_to_subsidy_usd_1y_sma: compute_dollars
|
||||
.then(|| {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
&db,
|
||||
"subsidy_usd_1y_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)
|
||||
})
|
||||
.transpose()?,
|
||||
indexes_to_puell_multiple: compute_dollars
|
||||
.then(|| {
|
||||
ComputedVecsFromDateIndex::forced_import(
|
||||
&db,
|
||||
"puell_multiple",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)
|
||||
})
|
||||
.transpose()?,
|
||||
indexes_to_hash_rate: computed_h!("hash_rate", Source::Compute, v5, last()),
|
||||
indexes_to_hash_rate_1w_sma: computed_di!("hash_rate_1w_sma", last()),
|
||||
indexes_to_hash_rate_1m_sma: computed_di!("hash_rate_1m_sma", last()),
|
||||
indexes_to_hash_rate_2m_sma: computed_di!("hash_rate_2m_sma", last()),
|
||||
indexes_to_hash_rate_1y_sma: computed_di!("hash_rate_1y_sma", last()),
|
||||
indexes_to_difficulty_as_hash: computed_h!(
|
||||
"difficulty_as_hash",
|
||||
Source::Compute,
|
||||
last()
|
||||
),
|
||||
indexes_to_difficulty_adjustment: computed_h!(
|
||||
"difficulty_adjustment",
|
||||
Source::Compute,
|
||||
sum()
|
||||
),
|
||||
indexes_to_blocks_before_next_difficulty_adjustment: computed_h!(
|
||||
"blocks_before_next_difficulty_adjustment",
|
||||
Source::Compute,
|
||||
v2,
|
||||
last()
|
||||
),
|
||||
indexes_to_days_before_next_difficulty_adjustment: computed_h!(
|
||||
"days_before_next_difficulty_adjustment",
|
||||
Source::Compute,
|
||||
v2,
|
||||
last()
|
||||
),
|
||||
indexes_to_blocks_before_next_halving: computed_h!(
|
||||
"blocks_before_next_halving",
|
||||
Source::Compute,
|
||||
v2,
|
||||
last()
|
||||
),
|
||||
indexes_to_days_before_next_halving: computed_h!(
|
||||
"days_before_next_halving",
|
||||
Source::Compute,
|
||||
v2,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_price_ths: computed_h!("hash_price_ths", Source::Compute, v4, last()),
|
||||
indexes_to_hash_price_phs: computed_h!("hash_price_phs", Source::Compute, v4, last()),
|
||||
indexes_to_hash_value_ths: computed_h!("hash_value_ths", Source::Compute, v4, last()),
|
||||
indexes_to_hash_value_phs: computed_h!("hash_value_phs", Source::Compute, v4, last()),
|
||||
indexes_to_hash_price_ths_min: computed_h!(
|
||||
"hash_price_ths_min",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_price_phs_min: computed_h!(
|
||||
"hash_price_phs_min",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_price_rebound: computed_h!(
|
||||
"hash_price_rebound",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_value_ths_min: computed_h!(
|
||||
"hash_value_ths_min",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_value_phs_min: computed_h!(
|
||||
"hash_value_phs_min",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_hash_value_rebound: computed_h!(
|
||||
"hash_value_rebound",
|
||||
Source::Compute,
|
||||
v4,
|
||||
last()
|
||||
),
|
||||
indexes_to_inflation_rate: computed_di!("inflation_rate", last()),
|
||||
indexes_to_annualized_volume: computed_di!("annualized_volume", last()),
|
||||
indexes_to_annualized_volume_btc: computed_di!("annualized_volume_btc", last()),
|
||||
indexes_to_annualized_volume_usd: computed_di!("annualized_volume_usd", last()),
|
||||
indexes_to_tx_btc_velocity: computed_di!("tx_btc_velocity", last()),
|
||||
indexes_to_tx_usd_velocity: computed_di!("tx_usd_velocity", last()),
|
||||
indexes_to_tx_per_sec: computed_di!("tx_per_sec", v2, last()),
|
||||
indexes_to_outputs_per_sec: computed_di!("outputs_per_sec", v2, last()),
|
||||
indexes_to_inputs_per_sec: computed_di!("inputs_per_sec", v2, last()),
|
||||
|
||||
txindex_to_is_coinbase,
|
||||
txindex_to_input_value,
|
||||
txindex_to_output_value,
|
||||
txindex_to_fee,
|
||||
txindex_to_fee_rate,
|
||||
txindex_to_vsize,
|
||||
txindex_to_weight,
|
||||
|
||||
db,
|
||||
block,
|
||||
epoch,
|
||||
mining,
|
||||
coinbase,
|
||||
transaction,
|
||||
output_type,
|
||||
volume,
|
||||
};
|
||||
|
||||
this.db.retain_regions(
|
||||
|
||||
301
crates/brk_computer/src/chain/mining/compute.rs
Normal file
301
crates/brk_computer/src/chain/mining/compute.rs
Normal file
@@ -0,0 +1,301 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{StoredF32, StoredF64, StoredU32};
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
chain::{block, coinbase, ONE_TERA_HASH, TARGET_BLOCKS_PER_DAY_F32, TARGET_BLOCKS_PER_DAY_F64},
|
||||
indexes,
|
||||
utils::OptionExt,
|
||||
Indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
block_vecs: &block::Vecs,
|
||||
coinbase_vecs: &coinbase::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.indexes_to_difficulty.compute_rest(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&indexer.vecs.block.height_to_difficulty),
|
||||
)?;
|
||||
|
||||
self.indexes_to_difficulty_as_hash
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
let multiplier = 2.0_f64.powi(32) / 600.0;
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_difficulty,
|
||||
|(i, v, ..)| (i, StoredF32::from(*v * multiplier)),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_rate
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&block_vecs.height_to_24h_block_count,
|
||||
self.indexes_to_difficulty_as_hash.height.u(),
|
||||
|(i, block_count_sum, difficulty_as_hash, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF64::from(
|
||||
(f64::from(block_count_sum) / TARGET_BLOCKS_PER_DAY_F64)
|
||||
* f64::from(difficulty_as_hash),
|
||||
),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_rate_1w_sma
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_hash_rate.dateindex.unwrap_last(),
|
||||
7,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_rate_1m_sma
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_hash_rate.dateindex.unwrap_last(),
|
||||
30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_rate_2m_sma
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_hash_rate.dateindex.unwrap_last(),
|
||||
2 * 30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_rate_1y_sma
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_hash_rate.dateindex.unwrap_last(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_difficulty_adjustment.compute_all(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v| {
|
||||
v.compute_percentage_change(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_difficulty,
|
||||
1,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_blocks_before_next_difficulty_adjustment
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexes.block.height_to_height,
|
||||
|(h, ..)| (h, StoredU32::from(h.left_before_next_diff_adj())),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_days_before_next_difficulty_adjustment
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_blocks_before_next_difficulty_adjustment
|
||||
.height
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
|(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_blocks_before_next_halving.compute_all(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexes.block.height_to_height,
|
||||
|(h, ..)| (h, StoredU32::from(h.left_before_next_halving())),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_days_before_next_halving.compute_all(
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
|v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_blocks_before_next_halving
|
||||
.height
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
|(h, blocks, ..)| (h, (*blocks as f32 / TARGET_BLOCKS_PER_DAY_F32).into()),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
self.indexes_to_hash_price_ths
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&coinbase_vecs.height_to_24h_coinbase_usd_sum,
|
||||
self.indexes_to_hash_rate.height.u(),
|
||||
|(i, coinbase_sum, hashrate, ..)| {
|
||||
(i, (*coinbase_sum / (*hashrate / ONE_TERA_HASH)).into())
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_price_phs
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_price_ths.height.u(),
|
||||
|(i, price, ..)| (i, (*price * 1000.0).into()),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_value_ths
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.height,
|
||||
&coinbase_vecs.height_to_24h_coinbase_sum,
|
||||
self.indexes_to_hash_rate.height.u(),
|
||||
|(i, coinbase_sum, hashrate, ..)| {
|
||||
(
|
||||
i,
|
||||
(*coinbase_sum as f64 / (*hashrate / ONE_TERA_HASH)).into(),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_value_phs
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_value_ths.height.u(),
|
||||
|(i, value, ..)| (i, (*value * 1000.0).into()),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_price_ths_min
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_price_ths.height.u(),
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_price_phs_min
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_price_phs.height.u(),
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_value_ths_min
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_value_ths.height.u(),
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_value_phs_min
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_all_time_low_(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_value_phs.height.u(),
|
||||
exit,
|
||||
true,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_price_rebound
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_percentage_difference(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_price_phs.height.u(),
|
||||
self.indexes_to_hash_price_phs_min.height.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_hash_value_rebound
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_percentage_difference(
|
||||
starting_indexes.height,
|
||||
self.indexes_to_hash_value_phs.height.u(),
|
||||
self.indexes_to_hash_value_phs_min.height.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
208
crates/brk_computer/src/chain/mining/import.rs
Normal file
208
crates/brk_computer/src/chain/mining/import.rs
Normal file
@@ -0,0 +1,208 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, IterableCloneableVec};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let v2 = Version::TWO;
|
||||
let v4 = Version::new(4);
|
||||
let v5 = Version::new(5);
|
||||
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
let sum = || VecBuilderOptions::default().add_sum();
|
||||
|
||||
Ok(Self {
|
||||
indexes_to_hash_rate: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_rate",
|
||||
Source::Compute,
|
||||
version + v5,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"hash_rate_1w_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"hash_rate_1m_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"hash_rate_2m_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"hash_rate_1y_sma",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_price_ths: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_price_ths",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_price_ths_min: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_price_ths_min",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_price_phs: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_price_phs",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_price_phs_min: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_price_phs_min",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_price_rebound: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_price_rebound",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_value_ths: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_value_ths",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_value_ths_min: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_value_ths_min",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_value_phs: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_value_phs",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_value_phs_min: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_value_phs_min",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_hash_value_rebound: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"hash_value_rebound",
|
||||
Source::Compute,
|
||||
version + v4,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_difficulty: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"difficulty",
|
||||
Source::Vec(indexer.vecs.block.height_to_difficulty.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_difficulty_as_hash: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"difficulty_as_hash",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_difficulty_adjustment: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"difficulty_adjustment",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
sum(),
|
||||
)?,
|
||||
indexes_to_blocks_before_next_difficulty_adjustment:
|
||||
ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"blocks_before_next_difficulty_adjustment",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_days_before_next_difficulty_adjustment:
|
||||
ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"days_before_next_difficulty_adjustment",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_blocks_before_next_halving: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"blocks_before_next_halving",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_days_before_next_halving: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"days_before_next_halving",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/mining/mod.rs
Normal file
5
crates/brk_computer/src/chain/mining/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
31
crates/brk_computer/src/chain/mining/vecs.rs
Normal file
31
crates/brk_computer/src/chain/mining/vecs.rs
Normal file
@@ -0,0 +1,31 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{StoredF32, StoredF64, StoredU32};
|
||||
|
||||
use crate::grouped::{ComputedVecsFromDateIndex, ComputedVecsFromHeight};
|
||||
|
||||
/// Mining-related metrics: hash rate, hash price, hash value, difficulty
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub indexes_to_hash_rate: ComputedVecsFromHeight<StoredF64>,
|
||||
pub indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_price_ths: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_ths_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_phs: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_phs_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_rebound: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_ths: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_ths_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_phs: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_phs_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_rebound: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_difficulty: ComputedVecsFromHeight<StoredF64>,
|
||||
pub indexes_to_difficulty_as_hash: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_difficulty_adjustment: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_days_before_next_halving: ComputedVecsFromHeight<StoredF32>,
|
||||
}
|
||||
@@ -1,18 +1,23 @@
|
||||
pub mod block;
|
||||
pub mod coinbase;
|
||||
mod compute;
|
||||
pub mod epoch;
|
||||
mod import;
|
||||
pub mod mining;
|
||||
pub mod output_type;
|
||||
pub mod transaction;
|
||||
pub mod volume;
|
||||
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Bitcoin, DateIndex, DecadeIndex, DifficultyEpoch, Dollars, FeeRate, HalvingEpoch, Height,
|
||||
MonthIndex, QuarterIndex, Sats, SemesterIndex, StoredBool, StoredF32, StoredF64, StoredU32,
|
||||
StoredU64, Timestamp, TxIndex, VSize, WeekIndex, Weight, YearIndex,
|
||||
};
|
||||
use vecdb::{Database, EagerVec, LazyVecFrom1, LazyVecFrom2, PcoVec};
|
||||
use vecdb::Database;
|
||||
|
||||
use crate::grouped::{
|
||||
ComputedValueVecsFromHeight, ComputedValueVecsFromTxindex, ComputedVecsFromDateIndex,
|
||||
ComputedVecsFromHeight, ComputedVecsFromTxindex,
|
||||
};
|
||||
pub use block::Vecs as BlockVecs;
|
||||
pub use coinbase::Vecs as CoinbaseVecs;
|
||||
pub use epoch::Vecs as EpochVecs;
|
||||
pub use mining::Vecs as MiningVecs;
|
||||
pub use output_type::Vecs as OutputTypeVecs;
|
||||
pub use transaction::Vecs as TransactionVecs;
|
||||
pub use volume::Vecs as VolumeVecs;
|
||||
|
||||
pub const DB_NAME: &str = "chain";
|
||||
|
||||
@@ -27,107 +32,16 @@ pub(crate) const TARGET_BLOCKS_PER_YEAR: u64 = 2 * TARGET_BLOCKS_PER_SEMESTER;
|
||||
pub(crate) const TARGET_BLOCKS_PER_DECADE: u64 = 10 * TARGET_BLOCKS_PER_YEAR;
|
||||
pub(crate) const ONE_TERA_HASH: f64 = 1_000_000_000_000.0;
|
||||
|
||||
/// Main chain metrics struct composed of sub-modules
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
#[traversable(skip)]
|
||||
pub(crate) db: Database,
|
||||
|
||||
pub dateindex_to_block_count_target: LazyVecFrom1<DateIndex, StoredU64, DateIndex, DateIndex>,
|
||||
pub weekindex_to_block_count_target: LazyVecFrom1<WeekIndex, StoredU64, WeekIndex, WeekIndex>,
|
||||
pub monthindex_to_block_count_target:
|
||||
LazyVecFrom1<MonthIndex, StoredU64, MonthIndex, MonthIndex>,
|
||||
pub quarterindex_to_block_count_target:
|
||||
LazyVecFrom1<QuarterIndex, StoredU64, QuarterIndex, QuarterIndex>,
|
||||
pub semesterindex_to_block_count_target:
|
||||
LazyVecFrom1<SemesterIndex, StoredU64, SemesterIndex, SemesterIndex>,
|
||||
pub yearindex_to_block_count_target: LazyVecFrom1<YearIndex, StoredU64, YearIndex, YearIndex>,
|
||||
pub decadeindex_to_block_count_target:
|
||||
LazyVecFrom1<DecadeIndex, StoredU64, DecadeIndex, DecadeIndex>,
|
||||
pub height_to_interval: EagerVec<PcoVec<Height, Timestamp>>,
|
||||
pub height_to_24h_block_count: EagerVec<PcoVec<Height, StoredU32>>,
|
||||
pub height_to_24h_coinbase_sum: EagerVec<PcoVec<Height, Sats>>,
|
||||
pub height_to_24h_coinbase_usd_sum: EagerVec<PcoVec<Height, Dollars>>,
|
||||
pub height_to_vbytes: EagerVec<PcoVec<Height, StoredU64>>,
|
||||
pub difficultyepoch_to_timestamp: EagerVec<PcoVec<DifficultyEpoch, Timestamp>>,
|
||||
pub halvingepoch_to_timestamp: EagerVec<PcoVec<HalvingEpoch, Timestamp>>,
|
||||
pub timeindexes_to_timestamp: ComputedVecsFromDateIndex<Timestamp>,
|
||||
pub indexes_to_block_count: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_1w_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_1m_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_1y_block_count: ComputedVecsFromDateIndex<StoredU32>,
|
||||
pub indexes_to_block_interval: ComputedVecsFromHeight<Timestamp>,
|
||||
pub indexes_to_block_size: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_block_vbytes: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_block_weight: ComputedVecsFromHeight<Weight>,
|
||||
pub indexes_to_difficulty: ComputedVecsFromHeight<StoredF64>,
|
||||
pub indexes_to_difficultyepoch: ComputedVecsFromDateIndex<DifficultyEpoch>,
|
||||
pub indexes_to_halvingepoch: ComputedVecsFromDateIndex<HalvingEpoch>,
|
||||
pub indexes_to_coinbase: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_emptyoutput_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_fee: ComputedValueVecsFromTxindex,
|
||||
pub indexes_to_fee_rate: ComputedVecsFromTxindex<FeeRate>,
|
||||
/// Value == 0 when Coinbase
|
||||
pub txindex_to_input_value: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub indexes_to_sent_sum: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_opreturn_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub txindex_to_output_value: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub indexes_to_p2a_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2ms_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pk33_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pk65_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pkh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2sh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2tr_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2wpkh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2wsh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_subsidy: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_unclaimed_rewards: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_tx_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v1: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v2: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v3: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_vsize: ComputedVecsFromTxindex<VSize>,
|
||||
pub indexes_to_tx_weight: ComputedVecsFromTxindex<Weight>,
|
||||
pub indexes_to_unknownoutput_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_input_count: ComputedVecsFromTxindex<StoredU64>,
|
||||
pub txindex_to_is_coinbase: LazyVecFrom2<TxIndex, StoredBool, TxIndex, Height, Height, TxIndex>,
|
||||
pub indexes_to_output_count: ComputedVecsFromTxindex<StoredU64>,
|
||||
pub txindex_to_vsize: LazyVecFrom1<TxIndex, VSize, TxIndex, Weight>,
|
||||
pub txindex_to_weight: LazyVecFrom2<TxIndex, Weight, TxIndex, StoredU32, TxIndex, StoredU32>,
|
||||
pub txindex_to_fee: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub txindex_to_fee_rate: EagerVec<PcoVec<TxIndex, FeeRate>>,
|
||||
pub indexes_to_exact_utxo_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub dateindex_to_fee_dominance: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub dateindex_to_subsidy_dominance: EagerVec<PcoVec<DateIndex, StoredF32>>,
|
||||
pub indexes_to_subsidy_usd_1y_sma: Option<ComputedVecsFromDateIndex<Dollars>>,
|
||||
pub indexes_to_puell_multiple: Option<ComputedVecsFromDateIndex<StoredF32>>,
|
||||
pub indexes_to_hash_rate: ComputedVecsFromHeight<StoredF64>,
|
||||
pub indexes_to_hash_rate_1w_sma: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_hash_rate_1m_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_rate_2m_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_rate_1y_sma: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_hash_price_ths: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_ths_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_phs: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_phs_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_price_rebound: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_ths: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_ths_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_phs: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_phs_min: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_hash_value_rebound: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_difficulty_as_hash: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_difficulty_adjustment: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_blocks_before_next_difficulty_adjustment: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_days_before_next_difficulty_adjustment: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_blocks_before_next_halving: ComputedVecsFromHeight<StoredU32>,
|
||||
pub indexes_to_days_before_next_halving: ComputedVecsFromHeight<StoredF32>,
|
||||
pub indexes_to_inflation_rate: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_annualized_volume: ComputedVecsFromDateIndex<Sats>,
|
||||
pub indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex<Bitcoin>,
|
||||
pub indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_tx_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_outputs_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_inputs_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub block: BlockVecs,
|
||||
pub epoch: EpochVecs,
|
||||
pub mining: MiningVecs,
|
||||
pub coinbase: CoinbaseVecs,
|
||||
pub transaction: TransactionVecs,
|
||||
pub output_type: OutputTypeVecs,
|
||||
pub volume: VolumeVecs,
|
||||
}
|
||||
|
||||
203
crates/brk_computer/src/chain/output_type/compute.rs
Normal file
203
crates/brk_computer/src/chain/output_type/compute.rs
Normal file
@@ -0,0 +1,203 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{Height, StoredU64};
|
||||
use vecdb::{Exit, TypedVecIterator};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{chain::transaction, indexes, Indexes};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
transaction_vecs: &transaction::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.indexes_to_p2a_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2aaddressindex,
|
||||
&indexer.vecs.address.p2aaddressindex_to_p2abytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2ms_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.output.height_to_first_p2msoutputindex,
|
||||
&indexer.vecs.output.p2msoutputindex_to_txindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2pk33_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2pk33addressindex,
|
||||
&indexer.vecs.address.p2pk33addressindex_to_p2pk33bytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2pk65_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2pk65addressindex,
|
||||
&indexer.vecs.address.p2pk65addressindex_to_p2pk65bytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2pkh_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2pkhaddressindex,
|
||||
&indexer.vecs.address.p2pkhaddressindex_to_p2pkhbytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2sh_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2shaddressindex,
|
||||
&indexer.vecs.address.p2shaddressindex_to_p2shbytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2tr_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2traddressindex,
|
||||
&indexer.vecs.address.p2traddressindex_to_p2trbytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2wpkh_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2wpkhaddressindex,
|
||||
&indexer.vecs.address.p2wpkhaddressindex_to_p2wpkhbytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_p2wsh_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.address.height_to_first_p2wshaddressindex,
|
||||
&indexer.vecs.address.p2wshaddressindex_to_p2wshbytes,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_opreturn_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.output.height_to_first_opreturnindex,
|
||||
&indexer.vecs.output.opreturnindex_to_txindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_unknownoutput_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.output.height_to_first_unknownoutputindex,
|
||||
&indexer.vecs.output.unknownoutputindex_to_txindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_emptyoutput_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.output.height_to_first_emptyoutputindex,
|
||||
&indexer.vecs.output.emptyoutputindex_to_txindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_exact_utxo_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
let mut input_count_iter = transaction_vecs
|
||||
.indexes_to_input_count
|
||||
.height
|
||||
.unwrap_cumulative()
|
||||
.into_iter();
|
||||
let mut opreturn_count_iter = self
|
||||
.indexes_to_opreturn_count
|
||||
.height_extra
|
||||
.unwrap_cumulative()
|
||||
.into_iter();
|
||||
v.compute_transform(
|
||||
starting_indexes.height,
|
||||
transaction_vecs
|
||||
.indexes_to_output_count
|
||||
.height
|
||||
.unwrap_cumulative(),
|
||||
|(h, output_count, ..)| {
|
||||
let input_count = input_count_iter.get_unwrap(h);
|
||||
let opreturn_count = opreturn_count_iter.get_unwrap(h);
|
||||
let block_count = u64::from(h + 1_usize);
|
||||
// -1 > genesis output is unspendable
|
||||
let mut utxo_count =
|
||||
*output_count - (*input_count - block_count) - *opreturn_count - 1;
|
||||
|
||||
// txid dup: e3bf3d07d4b0375638d5f1db5255fe07ba2c4cb067cd81b84ee974b6585fb468
|
||||
// Block 91_722 https://mempool.space/block/00000000000271a2dc26e7667f8419f2e15416dc6955e5a6c6cdf3f2574dd08e
|
||||
// Block 91_880 https://mempool.space/block/00000000000743f190a18c5577a3c2d2a1f610ae9601ac046a38084ccb7cd721
|
||||
//
|
||||
// txid dup: d5d27987d2a3dfc724e359870c6644b40e497bdc0589a033220fe15429d88599
|
||||
// Block 91_812 https://mempool.space/block/00000000000af0aed4792b1acee3d966af36cf5def14935db8de83d6f9306f2f
|
||||
// Block 91_842 https://mempool.space/block/00000000000a4d0a398161ffc163c503763b1f4360639393e0e4c8e300e0caec
|
||||
//
|
||||
// Warning: Dups invalidate the previous coinbase according to
|
||||
// https://chainquery.com/bitcoin-cli/gettxoutsetinfo
|
||||
|
||||
if h >= Height::new(91_842) {
|
||||
utxo_count -= 1;
|
||||
}
|
||||
if h >= Height::new(91_880) {
|
||||
utxo_count -= 1;
|
||||
}
|
||||
|
||||
(h, StoredU64::from(utxo_count))
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
131
crates/brk_computer/src/chain/output_type/import.rs
Normal file
131
crates/brk_computer/src/chain/output_type/import.rs
Normal file
@@ -0,0 +1,131 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedVecsFromHeight, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version, indexes: &indexes::Vecs) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
let full_stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
};
|
||||
|
||||
Ok(Self {
|
||||
indexes_to_p2a_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2a_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2ms_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2ms_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2pk33_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2pk33_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2pk65_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2pk65_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2pkh_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2pkh_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2sh_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2sh_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2tr_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2tr_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2wpkh_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2wpkh_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_p2wsh_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"p2wsh_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_opreturn_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"opreturn_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_emptyoutput_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"emptyoutput_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_unknownoutput_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"unknownoutput_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_exact_utxo_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"exact_utxo_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/output_type/mod.rs
Normal file
5
crates/brk_computer/src/chain/output_type/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
22
crates/brk_computer/src/chain/output_type/vecs.rs
Normal file
22
crates/brk_computer/src/chain/output_type/vecs.rs
Normal file
@@ -0,0 +1,22 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::StoredU64;
|
||||
|
||||
use crate::grouped::ComputedVecsFromHeight;
|
||||
|
||||
/// Output type count metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub indexes_to_p2a_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2ms_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pk33_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pk65_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2pkh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2sh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2tr_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2wpkh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_p2wsh_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_opreturn_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_emptyoutput_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_unknownoutput_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_exact_utxo_count: ComputedVecsFromHeight<StoredU64>,
|
||||
}
|
||||
141
crates/brk_computer/src/chain/transaction/compute.rs
Normal file
141
crates/brk_computer/src/chain/transaction/compute.rs
Normal file
@@ -0,0 +1,141 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{FeeRate, Sats, StoredU64, TxVersion};
|
||||
use vecdb::{Exit, TypedVecIterator, unlikely};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{Indexes, grouped::ComputedVecsFromHeight, indexes, price, txins};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
txins: &txins::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
price: Option<&price::Vecs>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.indexes_to_tx_count
|
||||
.compute_all(indexes, starting_indexes, exit, |v| {
|
||||
v.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexer.vecs.tx.txindex_to_txid,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_input_count.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&indexes.transaction.txindex_to_input_count),
|
||||
)?;
|
||||
|
||||
self.indexes_to_output_count.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&indexes.transaction.txindex_to_output_count),
|
||||
)?;
|
||||
|
||||
let compute_indexes_to_tx_vany =
|
||||
|indexes_to_tx_vany: &mut ComputedVecsFromHeight<StoredU64>, txversion: TxVersion| {
|
||||
let mut txindex_to_txversion_iter = indexer.vecs.tx.txindex_to_txversion.iter()?;
|
||||
indexes_to_tx_vany.compute_all(indexes, starting_indexes, exit, |vec| {
|
||||
vec.compute_filtered_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexer.vecs.tx.txindex_to_txid,
|
||||
|txindex| {
|
||||
let v = txindex_to_txversion_iter.get_unwrap(txindex);
|
||||
v == txversion
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})
|
||||
};
|
||||
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v1, TxVersion::ONE)?;
|
||||
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v2, TxVersion::TWO)?;
|
||||
compute_indexes_to_tx_vany(&mut self.indexes_to_tx_v3, TxVersion::THREE)?;
|
||||
|
||||
self.txindex_to_input_value.compute_sum_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txinindex,
|
||||
&indexes.transaction.txindex_to_input_count,
|
||||
&txins.txinindex_to_value,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_output_value.compute_sum_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txoutindex,
|
||||
&indexes.transaction.txindex_to_output_count,
|
||||
&indexer.vecs.txout.txoutindex_to_value,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_fee.compute_transform2(
|
||||
starting_indexes.txindex,
|
||||
&self.txindex_to_input_value,
|
||||
&self.txindex_to_output_value,
|
||||
|(i, input, output, ..)| {
|
||||
let fee = if unlikely(input.is_max()) {
|
||||
Sats::ZERO
|
||||
} else {
|
||||
input - output
|
||||
};
|
||||
(i, fee)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_fee_rate.compute_transform2(
|
||||
starting_indexes.txindex,
|
||||
&self.txindex_to_fee,
|
||||
&self.txindex_to_vsize,
|
||||
|(txindex, fee, vsize, ..)| (txindex, FeeRate::from((fee, vsize))),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_fee.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.txindex_to_fee),
|
||||
price,
|
||||
)?;
|
||||
|
||||
self.indexes_to_fee_rate.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.txindex_to_fee_rate),
|
||||
)?;
|
||||
|
||||
self.indexes_to_tx_weight.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.txindex_to_weight),
|
||||
)?;
|
||||
|
||||
self.indexes_to_tx_vsize.compute_rest(
|
||||
indexer,
|
||||
indexes,
|
||||
starting_indexes,
|
||||
exit,
|
||||
Some(&self.txindex_to_vsize),
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
180
crates/brk_computer/src/chain/transaction/import.rs
Normal file
180
crates/brk_computer/src/chain/transaction/import.rs
Normal file
@@ -0,0 +1,180 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{StoredBool, TxIndex, VSize, Version, Weight};
|
||||
use vecdb::{
|
||||
Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom1, LazyVecFrom2, VecIndex,
|
||||
};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{
|
||||
ComputedValueVecsFromTxindex, ComputedVecsFromHeight, ComputedVecsFromTxindex, Source,
|
||||
VecBuilderOptions,
|
||||
},
|
||||
indexes, price,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
price: Option<&price::Vecs>,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
|
||||
let stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
};
|
||||
let full_stats = || {
|
||||
VecBuilderOptions::default()
|
||||
.add_average()
|
||||
.add_minmax()
|
||||
.add_percentiles()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
};
|
||||
let sum_cum = || VecBuilderOptions::default().add_sum().add_cumulative();
|
||||
|
||||
let txindex_to_weight = LazyVecFrom2::init(
|
||||
"weight",
|
||||
version + v0,
|
||||
indexer.vecs.tx.txindex_to_base_size.boxed_clone(),
|
||||
indexer.vecs.tx.txindex_to_total_size.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_base_size_iter, txindex_to_total_size_iter| {
|
||||
let index = index.to_usize();
|
||||
txindex_to_base_size_iter.get_at(index).map(|base_size| {
|
||||
let total_size = txindex_to_total_size_iter.get_at_unwrap(index);
|
||||
let wu = usize::from(base_size) * 3 + usize::from(total_size);
|
||||
Weight::from(bitcoin::Weight::from_wu_usize(wu))
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let txindex_to_vsize = LazyVecFrom1::init(
|
||||
"vsize",
|
||||
version + v0,
|
||||
txindex_to_weight.boxed_clone(),
|
||||
|index: TxIndex, iter| iter.get(index).map(VSize::from),
|
||||
);
|
||||
|
||||
let txindex_to_is_coinbase = LazyVecFrom2::init(
|
||||
"is_coinbase",
|
||||
version + v0,
|
||||
indexer.vecs.tx.txindex_to_height.boxed_clone(),
|
||||
indexer.vecs.tx.height_to_first_txindex.boxed_clone(),
|
||||
|index: TxIndex, txindex_to_height_iter, height_to_first_txindex_iter| {
|
||||
txindex_to_height_iter.get(index).map(|height| {
|
||||
let txindex = height_to_first_txindex_iter.get_unwrap(height);
|
||||
StoredBool::from(index == txindex)
|
||||
})
|
||||
},
|
||||
);
|
||||
|
||||
let txindex_to_input_value = EagerVec::forced_import(db, "input_value", version + v0)?;
|
||||
let txindex_to_output_value = EagerVec::forced_import(db, "output_value", version + v0)?;
|
||||
let txindex_to_fee = EagerVec::forced_import(db, "fee", version + v0)?;
|
||||
let txindex_to_fee_rate = EagerVec::forced_import(db, "fee_rate", version + v0)?;
|
||||
|
||||
Ok(Self {
|
||||
indexes_to_tx_count: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"tx_count",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_tx_v1: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"tx_v1",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
sum_cum(),
|
||||
)?,
|
||||
indexes_to_tx_v2: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"tx_v2",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
sum_cum(),
|
||||
)?,
|
||||
indexes_to_tx_v3: ComputedVecsFromHeight::forced_import(
|
||||
db,
|
||||
"tx_v3",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
sum_cum(),
|
||||
)?,
|
||||
indexes_to_tx_vsize: ComputedVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"tx_vsize",
|
||||
Source::Vec(txindex_to_vsize.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
stats(),
|
||||
)?,
|
||||
indexes_to_tx_weight: ComputedVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"tx_weight",
|
||||
Source::Vec(txindex_to_weight.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
stats(),
|
||||
)?,
|
||||
indexes_to_input_count: ComputedVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"input_count",
|
||||
Source::Vec(indexes.transaction.txindex_to_input_count.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
indexes_to_output_count: ComputedVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"output_count",
|
||||
Source::Vec(indexes.transaction.txindex_to_output_count.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
full_stats(),
|
||||
)?,
|
||||
txindex_to_is_coinbase,
|
||||
txindex_to_vsize,
|
||||
txindex_to_weight,
|
||||
txindex_to_input_value,
|
||||
txindex_to_output_value,
|
||||
txindex_to_fee: txindex_to_fee.clone(),
|
||||
txindex_to_fee_rate: txindex_to_fee_rate.clone(),
|
||||
indexes_to_fee: ComputedValueVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"fee",
|
||||
indexer,
|
||||
indexes,
|
||||
Source::Vec(txindex_to_fee.boxed_clone()),
|
||||
version + v0,
|
||||
price,
|
||||
VecBuilderOptions::default()
|
||||
.add_sum()
|
||||
.add_cumulative()
|
||||
.add_percentiles()
|
||||
.add_minmax()
|
||||
.add_average(),
|
||||
)?,
|
||||
indexes_to_fee_rate: ComputedVecsFromTxindex::forced_import(
|
||||
db,
|
||||
"fee_rate",
|
||||
Source::Vec(txindex_to_fee_rate.boxed_clone()),
|
||||
version + v0,
|
||||
indexes,
|
||||
stats(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/transaction/mod.rs
Normal file
5
crates/brk_computer/src/chain/transaction/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
28
crates/brk_computer/src/chain/transaction/vecs.rs
Normal file
28
crates/brk_computer/src/chain/transaction/vecs.rs
Normal file
@@ -0,0 +1,28 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{FeeRate, Height, Sats, StoredBool, StoredU32, StoredU64, TxIndex, VSize, Weight};
|
||||
use vecdb::{EagerVec, LazyVecFrom1, LazyVecFrom2, PcoVec};
|
||||
|
||||
use crate::grouped::{ComputedValueVecsFromTxindex, ComputedVecsFromHeight, ComputedVecsFromTxindex};
|
||||
|
||||
/// Transaction-related metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub indexes_to_tx_count: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v1: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v2: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_v3: ComputedVecsFromHeight<StoredU64>,
|
||||
pub indexes_to_tx_vsize: ComputedVecsFromTxindex<VSize>,
|
||||
pub indexes_to_tx_weight: ComputedVecsFromTxindex<Weight>,
|
||||
pub indexes_to_input_count: ComputedVecsFromTxindex<StoredU64>,
|
||||
pub indexes_to_output_count: ComputedVecsFromTxindex<StoredU64>,
|
||||
pub txindex_to_is_coinbase: LazyVecFrom2<TxIndex, StoredBool, TxIndex, Height, Height, TxIndex>,
|
||||
pub txindex_to_vsize: LazyVecFrom1<TxIndex, VSize, TxIndex, Weight>,
|
||||
pub txindex_to_weight: LazyVecFrom2<TxIndex, Weight, TxIndex, StoredU32, TxIndex, StoredU32>,
|
||||
/// Value == 0 when Coinbase
|
||||
pub txindex_to_input_value: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub txindex_to_output_value: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub txindex_to_fee: EagerVec<PcoVec<TxIndex, Sats>>,
|
||||
pub txindex_to_fee_rate: EagerVec<PcoVec<TxIndex, FeeRate>>,
|
||||
pub indexes_to_fee: ComputedValueVecsFromTxindex,
|
||||
pub indexes_to_fee_rate: ComputedVecsFromTxindex<FeeRate>,
|
||||
}
|
||||
169
crates/brk_computer/src/chain/volume/compute.rs
Normal file
169
crates/brk_computer/src/chain/volume/compute.rs
Normal file
@@ -0,0 +1,169 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::ONE_DAY_IN_SEC_F64;
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
chain::{coinbase, transaction},
|
||||
indexes, price, Indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
indexes: &indexes::Vecs,
|
||||
transaction_vecs: &transaction::Vecs,
|
||||
coinbase_vecs: &coinbase::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
price: Option<&price::Vecs>,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.indexes_to_sent_sum
|
||||
.compute_all(indexes, price, starting_indexes, exit, |v| {
|
||||
v.compute_filtered_sum_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexes.block.height_to_txindex_count,
|
||||
&transaction_vecs.txindex_to_input_value,
|
||||
|sats| !sats.is_max(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_annualized_volume
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_sent_sum.sats.dateindex.unwrap_sum(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_annualized_volume_btc
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_sent_sum.bitcoin.dateindex.unwrap_sum(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_tx_btc_velocity
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_divide(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_annualized_volume_btc
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
coinbase_vecs
|
||||
.indexes_to_subsidy
|
||||
.bitcoin
|
||||
.dateindex
|
||||
.unwrap_cumulative(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
if let Some(indexes_to_sent_sum) = self.indexes_to_sent_sum.dollars.as_ref() {
|
||||
self.indexes_to_annualized_volume_usd
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
indexes_to_sent_sum.dateindex.unwrap_sum(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_tx_usd_velocity
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_divide(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_annualized_volume_usd
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.unwrap(),
|
||||
coinbase_vecs
|
||||
.indexes_to_subsidy
|
||||
.dollars
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
.dateindex
|
||||
.unwrap_cumulative(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
self.indexes_to_tx_per_sec
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
transaction_vecs.indexes_to_tx_count.dateindex.unwrap_sum(),
|
||||
&indexes.time.dateindex_to_date,
|
||||
|(i, tx_count, date, ..)| {
|
||||
(
|
||||
i,
|
||||
(*tx_count as f64 / (date.completion() * ONE_DAY_IN_SEC_F64)).into(),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_inputs_per_sec
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
transaction_vecs
|
||||
.indexes_to_input_count
|
||||
.dateindex
|
||||
.unwrap_sum(),
|
||||
&indexes.time.dateindex_to_date,
|
||||
|(i, tx_count, date, ..)| {
|
||||
(
|
||||
i,
|
||||
(*tx_count as f64 / (date.completion() * ONE_DAY_IN_SEC_F64)).into(),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_outputs_per_sec
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_transform2(
|
||||
starting_indexes.dateindex,
|
||||
transaction_vecs
|
||||
.indexes_to_output_count
|
||||
.dateindex
|
||||
.unwrap_sum(),
|
||||
&indexes.time.dateindex_to_date,
|
||||
|(i, tx_count, date, ..)| {
|
||||
(
|
||||
i,
|
||||
(*tx_count as f64 / (date.completion() * ONE_DAY_IN_SEC_F64)).into(),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
98
crates/brk_computer/src/chain/volume/import.rs
Normal file
98
crates/brk_computer/src/chain/volume/import.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{ComputedValueVecsFromHeight, ComputedVecsFromDateIndex, Source, VecBuilderOptions},
|
||||
indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
compute_dollars: bool,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let v2 = Version::TWO;
|
||||
let last = || VecBuilderOptions::default().add_last();
|
||||
|
||||
Ok(Self {
|
||||
indexes_to_sent_sum: ComputedValueVecsFromHeight::forced_import(
|
||||
db,
|
||||
"sent_sum",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
VecBuilderOptions::default().add_sum(),
|
||||
compute_dollars,
|
||||
indexes,
|
||||
)?,
|
||||
indexes_to_annualized_volume: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"annualized_volume",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"annualized_volume_btc",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"annualized_volume_usd",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"tx_btc_velocity",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"tx_usd_velocity",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_tx_per_sec: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"tx_per_sec",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_outputs_per_sec: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"outputs_per_sec",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
indexes_to_inputs_per_sec: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"inputs_per_sec",
|
||||
Source::Compute,
|
||||
version + v2,
|
||||
indexes,
|
||||
last(),
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/chain/volume/mod.rs
Normal file
5
crates/brk_computer/src/chain/volume/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
18
crates/brk_computer/src/chain/volume/vecs.rs
Normal file
18
crates/brk_computer/src/chain/volume/vecs.rs
Normal file
@@ -0,0 +1,18 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Dollars, Sats, StoredF32, StoredF64};
|
||||
|
||||
use crate::grouped::{ComputedValueVecsFromHeight, ComputedVecsFromDateIndex};
|
||||
|
||||
/// Volume and velocity metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub indexes_to_sent_sum: ComputedValueVecsFromHeight,
|
||||
pub indexes_to_annualized_volume: ComputedVecsFromDateIndex<Sats>,
|
||||
pub indexes_to_annualized_volume_btc: ComputedVecsFromDateIndex<Bitcoin>,
|
||||
pub indexes_to_annualized_volume_usd: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub indexes_to_tx_btc_velocity: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_tx_usd_velocity: ComputedVecsFromDateIndex<StoredF64>,
|
||||
pub indexes_to_tx_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_outputs_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub indexes_to_inputs_per_sec: ComputedVecsFromDateIndex<StoredF32>,
|
||||
}
|
||||
@@ -341,7 +341,7 @@ impl Vecs {
|
||||
self.indexes_to_activity_to_vaultedness_ratio
|
||||
.dateindex
|
||||
.unwrap_last(),
|
||||
chain.indexes_to_inflation_rate.dateindex.u(),
|
||||
chain.coinbase.indexes_to_inflation_rate.dateindex.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -354,7 +354,7 @@ impl Vecs {
|
||||
self.indexes_to_activity_to_vaultedness_ratio
|
||||
.dateindex
|
||||
.unwrap_last(),
|
||||
chain.indexes_to_tx_btc_velocity.dateindex.u(),
|
||||
chain.volume.indexes_to_tx_btc_velocity.dateindex.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
@@ -383,7 +383,7 @@ impl Vecs {
|
||||
vec.compute_transform(
|
||||
starting_indexes.height,
|
||||
chain
|
||||
.indexes_to_subsidy
|
||||
.coinbase.indexes_to_subsidy
|
||||
.dollars
|
||||
.as_ref()
|
||||
.unwrap()
|
||||
@@ -575,7 +575,7 @@ impl Vecs {
|
||||
self.indexes_to_activity_to_vaultedness_ratio
|
||||
.dateindex
|
||||
.unwrap_last(),
|
||||
chain.indexes_to_tx_usd_velocity.dateindex.u(),
|
||||
chain.volume.indexes_to_tx_usd_velocity.dateindex.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
|
||||
@@ -108,6 +108,7 @@ impl Vecs {
|
||||
.get_unwrap(prev_i)
|
||||
}));
|
||||
indexes
|
||||
.time
|
||||
.dateindex_to_date
|
||||
.iter()
|
||||
.enumerate()
|
||||
|
||||
@@ -9,7 +9,7 @@ use vecdb::{
|
||||
|
||||
use crate::utils::{OptionExt, get_percentile};
|
||||
|
||||
use super::ComputedVecValue;
|
||||
use super::super::ComputedVecValue;
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
@@ -6,7 +6,7 @@ use vecdb::{FromCoarserIndex, IterableBoxedVec, IterableCloneableVec, LazyVecFro
|
||||
use crate::grouped::{EagerVecsBuilder, VecBuilderOptions};
|
||||
use crate::utils::OptionExt;
|
||||
|
||||
use super::ComputedVecValue;
|
||||
use super::super::ComputedVecValue;
|
||||
|
||||
#[allow(clippy::type_complexity)]
|
||||
#[derive(Clone, Traversable)]
|
||||
9
crates/brk_computer/src/grouped/builder/mod.rs
Normal file
9
crates/brk_computer/src/grouped/builder/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod eager;
|
||||
mod lazy;
|
||||
mod transform;
|
||||
mod transform2;
|
||||
|
||||
pub use eager::*;
|
||||
pub use lazy::*;
|
||||
pub use transform::*;
|
||||
pub use transform2::*;
|
||||
@@ -3,7 +3,11 @@ use brk_types::Version;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{IterableCloneableVec, LazyVecFrom1, UnaryTransform, VecIndex};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, LazyVecsBuilder};
|
||||
use super::{
|
||||
super::ComputedVecValue,
|
||||
eager::EagerVecsBuilder,
|
||||
lazy::LazyVecsBuilder,
|
||||
};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
@@ -3,7 +3,11 @@ use brk_types::Version;
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{BinaryTransform, IterableCloneableVec, LazyVecFrom2, VecIndex};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, LazyVecsBuilder};
|
||||
use super::{
|
||||
super::ComputedVecValue,
|
||||
eager::EagerVecsBuilder,
|
||||
lazy::LazyVecsBuilder,
|
||||
};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
@@ -11,7 +11,7 @@ use vecdb::{
|
||||
|
||||
use crate::{Indexes, grouped::LazyVecsBuilder, indexes, utils::OptionExt};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, Source, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecValue, EagerVecsBuilder, Source, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromDateIndex<T>
|
||||
@@ -64,7 +64,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.weekindex_to_weekindex.boxed_clone(),
|
||||
indexes.time.weekindex_to_weekindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
monthindex: LazyVecsBuilder::forced_import(
|
||||
@@ -72,7 +72,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.monthindex_to_monthindex.boxed_clone(),
|
||||
indexes.time.monthindex_to_monthindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
quarterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -80,7 +80,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.quarterindex_to_quarterindex.boxed_clone(),
|
||||
indexes.time.quarterindex_to_quarterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
semesterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -88,7 +88,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.semesterindex_to_semesterindex.boxed_clone(),
|
||||
indexes.time.semesterindex_to_semesterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
yearindex: LazyVecsBuilder::forced_import(
|
||||
@@ -96,7 +96,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.yearindex_to_yearindex.boxed_clone(),
|
||||
indexes.time.yearindex_to_yearindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
decadeindex: LazyVecsBuilder::forced_import(
|
||||
@@ -104,7 +104,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
dateindex_source.clone(),
|
||||
&dateindex_extra,
|
||||
indexes.decadeindex_to_decadeindex.boxed_clone(),
|
||||
indexes.time.decadeindex_to_decadeindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
dateindex,
|
||||
@@ -0,0 +1,5 @@
|
||||
mod standard;
|
||||
mod strict;
|
||||
|
||||
pub use standard::*;
|
||||
pub use strict::*;
|
||||
@@ -18,7 +18,7 @@ use crate::{
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromHeight<T>
|
||||
@@ -78,7 +78,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.weekindex_to_weekindex.boxed_clone(),
|
||||
indexes.time.weekindex_to_weekindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
monthindex: LazyVecsBuilder::forced_import(
|
||||
@@ -86,7 +86,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.monthindex_to_monthindex.boxed_clone(),
|
||||
indexes.time.monthindex_to_monthindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
quarterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -94,7 +94,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.quarterindex_to_quarterindex.boxed_clone(),
|
||||
indexes.time.quarterindex_to_quarterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
semesterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -102,7 +102,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.semesterindex_to_semesterindex.boxed_clone(),
|
||||
indexes.time.semesterindex_to_semesterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
yearindex: LazyVecsBuilder::forced_import(
|
||||
@@ -110,7 +110,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.yearindex_to_yearindex.boxed_clone(),
|
||||
indexes.time.yearindex_to_yearindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
decadeindex: LazyVecsBuilder::forced_import(
|
||||
@@ -118,7 +118,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.decadeindex_to_decadeindex.boxed_clone(),
|
||||
indexes.time.decadeindex_to_decadeindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
// halvingepoch: StorableVecGeneator::forced_import(db, name, version + VERSION + Version::ZERO, format, options)?,
|
||||
@@ -127,7 +127,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
height_source,
|
||||
&height_extra,
|
||||
indexes.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
indexes.block.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
height,
|
||||
@@ -166,8 +166,8 @@ where
|
||||
self.dateindex.compute(
|
||||
starting_indexes.dateindex,
|
||||
height,
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
&indexes.time.dateindex_to_first_height,
|
||||
&indexes.time.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
} else {
|
||||
@@ -179,8 +179,8 @@ where
|
||||
self.dateindex.compute(
|
||||
starting_indexes.dateindex,
|
||||
height,
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
&indexes.time.dateindex_to_first_height,
|
||||
&indexes.time.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
@@ -9,7 +9,7 @@ use vecdb::{
|
||||
|
||||
use crate::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, LazyVecsBuilder, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecValue, EagerVecsBuilder, LazyVecsBuilder, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromHeightStrict<T>
|
||||
@@ -53,7 +53,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
Some(height.boxed_clone()),
|
||||
&height_extra,
|
||||
indexes.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
indexes.block.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
height,
|
||||
@@ -18,7 +18,7 @@ use crate::{
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
use super::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecValue, EagerVecsBuilder, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct ComputedVecsFromTxindex<T>
|
||||
@@ -72,7 +72,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.weekindex_to_weekindex.boxed_clone(),
|
||||
indexes.time.weekindex_to_weekindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
difficultyepoch: LazyVecsBuilder::forced_import(
|
||||
@@ -80,7 +80,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&height,
|
||||
indexes.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
indexes.block.difficultyepoch_to_difficultyepoch.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
monthindex: LazyVecsBuilder::forced_import(
|
||||
@@ -88,7 +88,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.monthindex_to_monthindex.boxed_clone(),
|
||||
indexes.time.monthindex_to_monthindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
quarterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -96,7 +96,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.quarterindex_to_quarterindex.boxed_clone(),
|
||||
indexes.time.quarterindex_to_quarterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
semesterindex: LazyVecsBuilder::forced_import(
|
||||
@@ -104,7 +104,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.semesterindex_to_semesterindex.boxed_clone(),
|
||||
indexes.time.semesterindex_to_semesterindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
yearindex: LazyVecsBuilder::forced_import(
|
||||
@@ -112,7 +112,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.yearindex_to_yearindex.boxed_clone(),
|
||||
indexes.time.yearindex_to_yearindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
decadeindex: LazyVecsBuilder::forced_import(
|
||||
@@ -120,7 +120,7 @@ where
|
||||
version + VERSION + Version::ZERO,
|
||||
None,
|
||||
&dateindex,
|
||||
indexes.decadeindex_to_decadeindex.boxed_clone(),
|
||||
indexes.time.decadeindex_to_decadeindex.boxed_clone(),
|
||||
options.into(),
|
||||
),
|
||||
|
||||
@@ -175,7 +175,7 @@ where
|
||||
starting_indexes.height,
|
||||
txindex,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexes.height_to_txindex_count,
|
||||
&indexes.block.height_to_txindex_count,
|
||||
exit,
|
||||
)?;
|
||||
} else {
|
||||
@@ -185,7 +185,7 @@ where
|
||||
starting_indexes.height,
|
||||
txindex,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexes.height_to_txindex_count,
|
||||
&indexes.block.height_to_txindex_count,
|
||||
exit,
|
||||
)?;
|
||||
}
|
||||
@@ -202,8 +202,8 @@ where
|
||||
self.dateindex.from_aligned(
|
||||
starting_indexes.dateindex,
|
||||
&self.height,
|
||||
&indexes.dateindex_to_first_height,
|
||||
&indexes.dateindex_to_height_count,
|
||||
&indexes.time.dateindex_to_first_height,
|
||||
&indexes.time.dateindex_to_height_count,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
9
crates/brk_computer/src/grouped/computed/mod.rs
Normal file
9
crates/brk_computer/src/grouped/computed/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod from_dateindex;
|
||||
mod from_height;
|
||||
mod from_txindex;
|
||||
mod traits;
|
||||
|
||||
pub use from_dateindex::*;
|
||||
pub use from_height::*;
|
||||
pub use from_txindex::*;
|
||||
pub use traits::*;
|
||||
@@ -5,7 +5,7 @@ use brk_types::{
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyExportableVec, BinaryTransform, IterableCloneableVec, LazyVecFrom2};
|
||||
|
||||
use super::{ComputedVecValue, ComputedVecsFromDateIndex, ComputedVecsFromHeight, LazyTransform2Builder};
|
||||
use crate::grouped::{ComputedVecValue, ComputedVecsFromDateIndex, ComputedVecsFromHeight, LazyTransform2Builder};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
@@ -6,7 +6,7 @@ use brk_types::{
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyExportableVec, BinaryTransform, IterableBoxedVec, LazyVecFrom2};
|
||||
|
||||
use super::{ComputedVecValue, ComputedVecsFromHeight, LazyTransform2Builder};
|
||||
use crate::grouped::{ComputedVecValue, ComputedVecsFromHeight, LazyTransform2Builder};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
5
crates/brk_computer/src/grouped/lazy/binary/mod.rs
Normal file
5
crates/brk_computer/src/grouped/lazy/binary/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod from_dateindex;
|
||||
mod from_height;
|
||||
|
||||
pub use from_dateindex::*;
|
||||
pub use from_height::*;
|
||||
@@ -5,7 +5,7 @@ use brk_types::{
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyExportableVec, IterableBoxedVec, LazyVecFrom1, UnaryTransform};
|
||||
|
||||
use super::{ComputedVecValue, ComputedVecsFromDateIndex, LazyTransformBuilder};
|
||||
use crate::grouped::{ComputedVecValue, ComputedVecsFromDateIndex, LazyTransformBuilder};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
@@ -6,7 +6,7 @@ use brk_types::{
|
||||
use schemars::JsonSchema;
|
||||
use vecdb::{AnyExportableVec, IterableBoxedVec, LazyVecFrom1, UnaryTransform};
|
||||
|
||||
use super::{ComputedVecValue, ComputedVecsFromHeight, LazyTransformBuilder};
|
||||
use crate::grouped::{ComputedVecValue, ComputedVecsFromHeight, LazyTransformBuilder};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
7
crates/brk_computer/src/grouped/lazy/mod.rs
Normal file
7
crates/brk_computer/src/grouped/lazy/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
mod binary;
|
||||
mod from_dateindex;
|
||||
mod from_height;
|
||||
|
||||
pub use binary::*;
|
||||
pub use from_dateindex::*;
|
||||
pub use from_height::*;
|
||||
@@ -1,57 +1,15 @@
|
||||
mod builder_eager;
|
||||
mod builder_lazy;
|
||||
mod builder_transform;
|
||||
mod builder_transform2;
|
||||
mod builder;
|
||||
mod computed;
|
||||
mod constant;
|
||||
mod computed_from_dateindex;
|
||||
mod computed_from_height;
|
||||
mod computed_from_height_strict;
|
||||
mod computed_from_txindex;
|
||||
mod lazy2_from_dateindex;
|
||||
mod lazy2_from_height;
|
||||
mod lazy_from_dateindex;
|
||||
mod lazy_from_height;
|
||||
mod lazy_value_from_dateindex;
|
||||
mod lazy_value_height;
|
||||
mod lazy_value2_from_height;
|
||||
// mod lazy_from_height_strict;
|
||||
// mod lazy_from_txindex;
|
||||
mod price_percentiles;
|
||||
mod ratio_from_dateindex;
|
||||
mod sd_from_dateindex;
|
||||
mod lazy;
|
||||
mod source;
|
||||
mod specialized;
|
||||
mod transforms;
|
||||
mod value_from_dateindex;
|
||||
mod value_from_height;
|
||||
mod value_from_txindex;
|
||||
mod value_height;
|
||||
mod value;
|
||||
|
||||
pub use builder_eager::*;
|
||||
pub use builder_lazy::*;
|
||||
pub use builder_transform::*;
|
||||
pub use builder_transform2::*;
|
||||
use computed::*;
|
||||
pub use constant::*;
|
||||
pub use computed_from_dateindex::*;
|
||||
pub use computed_from_height::*;
|
||||
pub use computed_from_height_strict::*;
|
||||
pub use computed_from_txindex::*;
|
||||
pub use lazy_from_dateindex::*;
|
||||
pub use lazy_from_height::*;
|
||||
pub use lazy_value_from_dateindex::*;
|
||||
pub use lazy_value_height::*;
|
||||
pub use lazy_value2_from_height::*;
|
||||
pub use lazy2_from_dateindex::*;
|
||||
pub use lazy2_from_height::*;
|
||||
// pub use lazy_from_height_strict::*;
|
||||
// pub use lazy_from_txindex::*;
|
||||
pub use price_percentiles::*;
|
||||
pub use ratio_from_dateindex::*;
|
||||
pub use sd_from_dateindex::*;
|
||||
pub use builder::*;
|
||||
pub use computed::*;
|
||||
pub use lazy::*;
|
||||
pub use source::*;
|
||||
pub use specialized::*;
|
||||
pub use transforms::*;
|
||||
pub use value_from_dateindex::*;
|
||||
pub use value_from_height::*;
|
||||
pub use value_from_txindex::*;
|
||||
pub use value_height::*;
|
||||
pub use value::*;
|
||||
|
||||
@@ -43,42 +43,42 @@ impl<T: VecValue + Formattable + Serialize + JsonSchema> ConstantVecs<T> {
|
||||
height: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.height_to_height.boxed_clone(),
|
||||
indexes.block.height_to_height.boxed_clone(),
|
||||
),
|
||||
dateindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.dateindex_to_dateindex.boxed_clone(),
|
||||
indexes.time.dateindex_to_dateindex.boxed_clone(),
|
||||
),
|
||||
weekindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.weekindex_to_weekindex.boxed_clone(),
|
||||
indexes.time.weekindex_to_weekindex.boxed_clone(),
|
||||
),
|
||||
monthindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.monthindex_to_monthindex.boxed_clone(),
|
||||
indexes.time.monthindex_to_monthindex.boxed_clone(),
|
||||
),
|
||||
quarterindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.quarterindex_to_quarterindex.boxed_clone(),
|
||||
indexes.time.quarterindex_to_quarterindex.boxed_clone(),
|
||||
),
|
||||
semesterindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.semesterindex_to_semesterindex.boxed_clone(),
|
||||
indexes.time.semesterindex_to_semesterindex.boxed_clone(),
|
||||
),
|
||||
yearindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.yearindex_to_yearindex.boxed_clone(),
|
||||
indexes.time.yearindex_to_yearindex.boxed_clone(),
|
||||
),
|
||||
decadeindex: LazyVecFrom1::transformed::<F>(
|
||||
name,
|
||||
version,
|
||||
indexes.decadeindex_to_decadeindex.boxed_clone(),
|
||||
indexes.time.decadeindex_to_decadeindex.boxed_clone(),
|
||||
),
|
||||
}
|
||||
}
|
||||
9
crates/brk_computer/src/grouped/specialized/mod.rs
Normal file
9
crates/brk_computer/src/grouped/specialized/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod constant;
|
||||
mod percentiles;
|
||||
mod ratio;
|
||||
mod stddev;
|
||||
|
||||
pub use constant::*;
|
||||
pub use percentiles::*;
|
||||
pub use ratio::*;
|
||||
pub use stddev::*;
|
||||
@@ -8,7 +8,7 @@ use vecdb::{
|
||||
|
||||
use crate::{Indexes, indexes};
|
||||
|
||||
use super::{ComputedVecsFromDateIndex, Source, VecBuilderOptions};
|
||||
use super::super::{ComputedVecsFromDateIndex, Source, VecBuilderOptions};
|
||||
|
||||
pub const PERCENTILES: [u8; 19] = [
|
||||
5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 65, 70, 75, 80, 85, 90, 95,
|
||||
@@ -16,7 +16,7 @@ use crate::{
|
||||
utils::{OptionExt, get_percentile},
|
||||
};
|
||||
|
||||
use super::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions};
|
||||
use super::super::{ComputedVecsFromDateIndex, ComputedVecsFromHeight, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedRatioVecsFromDateIndex {
|
||||
@@ -10,7 +10,7 @@ use vecdb::{
|
||||
|
||||
use crate::{Indexes, grouped::source::Source, indexes, price, utils::OptionExt};
|
||||
|
||||
use super::{
|
||||
use super::super::{
|
||||
ClosePriceTimesRatio, ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, VecBuilderOptions,
|
||||
};
|
||||
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
use super::{Source, VecBuilderOptions};
|
||||
use crate::grouped::{Source, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedValueVecsFromDateIndex {
|
||||
@@ -11,7 +11,7 @@ use crate::{
|
||||
utils::OptionExt,
|
||||
};
|
||||
|
||||
use super::{ComputedVecsFromHeight, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecsFromHeight, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedValueVecsFromHeight {
|
||||
@@ -9,7 +9,7 @@ use vecdb::{
|
||||
|
||||
use crate::{Indexes, grouped::Source, indexes, price, utils::OptionExt};
|
||||
|
||||
use super::{ComputedVecsFromTxindex, VecBuilderOptions};
|
||||
use crate::grouped::{ComputedVecsFromTxindex, VecBuilderOptions};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct ComputedValueVecsFromTxindex {
|
||||
7
crates/brk_computer/src/grouped/value/computed/mod.rs
Normal file
7
crates/brk_computer/src/grouped/value/computed/mod.rs
Normal file
@@ -0,0 +1,7 @@
|
||||
mod from_dateindex;
|
||||
mod from_height;
|
||||
mod from_txindex;
|
||||
|
||||
pub use from_dateindex::*;
|
||||
pub use from_height::*;
|
||||
pub use from_txindex::*;
|
||||
@@ -2,7 +2,7 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Dollars, Height, Sats, Version};
|
||||
use vecdb::{BinaryTransform, IterableBoxedVec, IterableCloneableVec};
|
||||
|
||||
use super::{ComputedValueVecsFromHeight, LazyVecsFrom2FromHeight};
|
||||
use crate::grouped::{ComputedValueVecsFromHeight, LazyVecsFrom2FromHeight};
|
||||
|
||||
/// Lazy value vecs computed from two `ComputedValueVecsFromHeight` sources via binary transforms.
|
||||
/// Used for computing coinbase = subsidy + fee.
|
||||
@@ -2,7 +2,7 @@ use brk_traversable::Traversable;
|
||||
use brk_types::{Bitcoin, Dollars, Sats, Version};
|
||||
use vecdb::{IterableCloneableVec, UnaryTransform};
|
||||
|
||||
use super::{ComputedValueVecsFromDateIndex, LazyVecsFromDateIndex};
|
||||
use crate::grouped::{ComputedValueVecsFromDateIndex, LazyVecsFromDateIndex};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
|
||||
9
crates/brk_computer/src/grouped/value/lazy/mod.rs
Normal file
9
crates/brk_computer/src/grouped/value/lazy/mod.rs
Normal file
@@ -0,0 +1,9 @@
|
||||
mod binary_from_height;
|
||||
mod from_dateindex;
|
||||
mod height;
|
||||
mod value_height;
|
||||
|
||||
pub use binary_from_height::*;
|
||||
pub use from_dateindex::*;
|
||||
pub use height::*;
|
||||
pub use value_height::*;
|
||||
5
crates/brk_computer/src/grouped/value/mod.rs
Normal file
5
crates/brk_computer/src/grouped/value/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod computed;
|
||||
mod lazy;
|
||||
|
||||
pub use computed::*;
|
||||
pub use lazy::*;
|
||||
@@ -1,667 +0,0 @@
|
||||
use std::{ops::Deref, path::Path};
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Date, DateIndex, DecadeIndex, DifficultyEpoch, EmptyOutputIndex, HalvingEpoch, Height,
|
||||
MonthIndex, OpReturnIndex, OutPoint, P2AAddressIndex, P2ABytes, P2MSOutputIndex,
|
||||
P2PK33AddressIndex, P2PK33Bytes, P2PK65AddressIndex, P2PK65Bytes, P2PKHAddressIndex,
|
||||
P2PKHBytes, P2SHAddressIndex, P2SHBytes, P2TRAddressIndex, P2TRBytes, P2WPKHAddressIndex,
|
||||
P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, QuarterIndex, Sats, SemesterIndex, StoredU64,
|
||||
Timestamp, TxInIndex, TxIndex, TxOutIndex, Txid, UnknownOutputIndex, Version, WeekIndex,
|
||||
YearIndex,
|
||||
};
|
||||
use vecdb::{
|
||||
Database, EagerVec, Exit, ImportableVec, IterableCloneableVec, LazyVecFrom1, PAGE_SIZE, PcoVec,
|
||||
TypedVecIterator,
|
||||
};
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
pub const DB_NAME: &str = "indexes";
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
db: Database,
|
||||
|
||||
pub dateindex_to_date: EagerVec<PcoVec<DateIndex, Date>>,
|
||||
pub dateindex_to_dateindex: EagerVec<PcoVec<DateIndex, DateIndex>>,
|
||||
pub dateindex_to_first_height: EagerVec<PcoVec<DateIndex, Height>>,
|
||||
pub dateindex_to_height_count: EagerVec<PcoVec<DateIndex, StoredU64>>,
|
||||
pub dateindex_to_monthindex: EagerVec<PcoVec<DateIndex, MonthIndex>>,
|
||||
pub dateindex_to_weekindex: EagerVec<PcoVec<DateIndex, WeekIndex>>,
|
||||
pub decadeindex_to_decadeindex: EagerVec<PcoVec<DecadeIndex, DecadeIndex>>,
|
||||
pub decadeindex_to_first_yearindex: EagerVec<PcoVec<DecadeIndex, YearIndex>>,
|
||||
pub decadeindex_to_yearindex_count: EagerVec<PcoVec<DecadeIndex, StoredU64>>,
|
||||
pub difficultyepoch_to_difficultyepoch: EagerVec<PcoVec<DifficultyEpoch, DifficultyEpoch>>,
|
||||
pub difficultyepoch_to_first_height: EagerVec<PcoVec<DifficultyEpoch, Height>>,
|
||||
pub difficultyepoch_to_height_count: EagerVec<PcoVec<DifficultyEpoch, StoredU64>>,
|
||||
pub emptyoutputindex_to_emptyoutputindex:
|
||||
LazyVecFrom1<EmptyOutputIndex, EmptyOutputIndex, EmptyOutputIndex, TxIndex>,
|
||||
pub halvingepoch_to_first_height: EagerVec<PcoVec<HalvingEpoch, Height>>,
|
||||
pub halvingepoch_to_halvingepoch: EagerVec<PcoVec<HalvingEpoch, HalvingEpoch>>,
|
||||
pub height_to_date: EagerVec<PcoVec<Height, Date>>,
|
||||
pub height_to_date_fixed: EagerVec<PcoVec<Height, Date>>,
|
||||
pub height_to_dateindex: EagerVec<PcoVec<Height, DateIndex>>,
|
||||
pub height_to_difficultyepoch: EagerVec<PcoVec<Height, DifficultyEpoch>>,
|
||||
pub height_to_halvingepoch: EagerVec<PcoVec<Height, HalvingEpoch>>,
|
||||
pub height_to_height: EagerVec<PcoVec<Height, Height>>,
|
||||
pub height_to_timestamp_fixed: EagerVec<PcoVec<Height, Timestamp>>,
|
||||
pub height_to_txindex_count: EagerVec<PcoVec<Height, StoredU64>>,
|
||||
pub monthindex_to_dateindex_count: EagerVec<PcoVec<MonthIndex, StoredU64>>,
|
||||
pub monthindex_to_first_dateindex: EagerVec<PcoVec<MonthIndex, DateIndex>>,
|
||||
pub monthindex_to_monthindex: EagerVec<PcoVec<MonthIndex, MonthIndex>>,
|
||||
pub monthindex_to_quarterindex: EagerVec<PcoVec<MonthIndex, QuarterIndex>>,
|
||||
pub monthindex_to_semesterindex: EagerVec<PcoVec<MonthIndex, SemesterIndex>>,
|
||||
pub monthindex_to_yearindex: EagerVec<PcoVec<MonthIndex, YearIndex>>,
|
||||
pub opreturnindex_to_opreturnindex:
|
||||
LazyVecFrom1<OpReturnIndex, OpReturnIndex, OpReturnIndex, TxIndex>,
|
||||
pub p2aaddressindex_to_p2aaddressindex:
|
||||
LazyVecFrom1<P2AAddressIndex, P2AAddressIndex, P2AAddressIndex, P2ABytes>,
|
||||
pub p2msoutputindex_to_p2msoutputindex:
|
||||
LazyVecFrom1<P2MSOutputIndex, P2MSOutputIndex, P2MSOutputIndex, TxIndex>,
|
||||
pub p2pk33addressindex_to_p2pk33addressindex:
|
||||
LazyVecFrom1<P2PK33AddressIndex, P2PK33AddressIndex, P2PK33AddressIndex, P2PK33Bytes>,
|
||||
pub p2pk65addressindex_to_p2pk65addressindex:
|
||||
LazyVecFrom1<P2PK65AddressIndex, P2PK65AddressIndex, P2PK65AddressIndex, P2PK65Bytes>,
|
||||
pub p2pkhaddressindex_to_p2pkhaddressindex:
|
||||
LazyVecFrom1<P2PKHAddressIndex, P2PKHAddressIndex, P2PKHAddressIndex, P2PKHBytes>,
|
||||
pub p2shaddressindex_to_p2shaddressindex:
|
||||
LazyVecFrom1<P2SHAddressIndex, P2SHAddressIndex, P2SHAddressIndex, P2SHBytes>,
|
||||
pub p2traddressindex_to_p2traddressindex:
|
||||
LazyVecFrom1<P2TRAddressIndex, P2TRAddressIndex, P2TRAddressIndex, P2TRBytes>,
|
||||
pub p2wpkhaddressindex_to_p2wpkhaddressindex:
|
||||
LazyVecFrom1<P2WPKHAddressIndex, P2WPKHAddressIndex, P2WPKHAddressIndex, P2WPKHBytes>,
|
||||
pub p2wshaddressindex_to_p2wshaddressindex:
|
||||
LazyVecFrom1<P2WSHAddressIndex, P2WSHAddressIndex, P2WSHAddressIndex, P2WSHBytes>,
|
||||
pub quarterindex_to_first_monthindex: EagerVec<PcoVec<QuarterIndex, MonthIndex>>,
|
||||
pub quarterindex_to_monthindex_count: EagerVec<PcoVec<QuarterIndex, StoredU64>>,
|
||||
pub quarterindex_to_quarterindex: EagerVec<PcoVec<QuarterIndex, QuarterIndex>>,
|
||||
pub semesterindex_to_first_monthindex: EagerVec<PcoVec<SemesterIndex, MonthIndex>>,
|
||||
pub semesterindex_to_monthindex_count: EagerVec<PcoVec<SemesterIndex, StoredU64>>,
|
||||
pub semesterindex_to_semesterindex: EagerVec<PcoVec<SemesterIndex, SemesterIndex>>,
|
||||
pub txindex_to_input_count: EagerVec<PcoVec<TxIndex, StoredU64>>,
|
||||
pub txindex_to_output_count: EagerVec<PcoVec<TxIndex, StoredU64>>,
|
||||
pub txindex_to_txindex: LazyVecFrom1<TxIndex, TxIndex, TxIndex, Txid>,
|
||||
pub txinindex_to_txinindex: LazyVecFrom1<TxInIndex, TxInIndex, TxInIndex, OutPoint>,
|
||||
pub txoutindex_to_txoutindex: LazyVecFrom1<TxOutIndex, TxOutIndex, TxOutIndex, Sats>,
|
||||
pub unknownoutputindex_to_unknownoutputindex:
|
||||
LazyVecFrom1<UnknownOutputIndex, UnknownOutputIndex, UnknownOutputIndex, TxIndex>,
|
||||
pub weekindex_to_dateindex_count: EagerVec<PcoVec<WeekIndex, StoredU64>>,
|
||||
pub weekindex_to_first_dateindex: EagerVec<PcoVec<WeekIndex, DateIndex>>,
|
||||
pub weekindex_to_weekindex: EagerVec<PcoVec<WeekIndex, WeekIndex>>,
|
||||
pub yearindex_to_decadeindex: EagerVec<PcoVec<YearIndex, DecadeIndex>>,
|
||||
pub yearindex_to_first_monthindex: EagerVec<PcoVec<YearIndex, MonthIndex>>,
|
||||
pub yearindex_to_monthindex_count: EagerVec<PcoVec<YearIndex, StoredU64>>,
|
||||
pub yearindex_to_yearindex: EagerVec<PcoVec<YearIndex, YearIndex>>,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
parent: &Path,
|
||||
parent_version: Version,
|
||||
indexer: &Indexer,
|
||||
) -> Result<Self> {
|
||||
let db = Database::open(&parent.join(DB_NAME))?;
|
||||
db.set_min_len(PAGE_SIZE * 10_000_000)?;
|
||||
|
||||
let version = parent_version + VERSION;
|
||||
|
||||
macro_rules! eager {
|
||||
($name:expr) => {
|
||||
EagerVec::forced_import(&db, $name, version)?
|
||||
};
|
||||
}
|
||||
macro_rules! lazy {
|
||||
($name:expr, $source:expr) => {
|
||||
LazyVecFrom1::init($name, version, $source.boxed_clone(), |index, _| {
|
||||
Some(index)
|
||||
})
|
||||
};
|
||||
}
|
||||
|
||||
let this = Self {
|
||||
txoutindex_to_txoutindex: lazy!("txoutindex", indexer.vecs.txout.txoutindex_to_value),
|
||||
txinindex_to_txinindex: lazy!("txinindex", indexer.vecs.txin.txinindex_to_outpoint),
|
||||
p2pk33addressindex_to_p2pk33addressindex: lazy!(
|
||||
"p2pk33addressindex",
|
||||
indexer.vecs.address.p2pk33addressindex_to_p2pk33bytes
|
||||
),
|
||||
p2pk65addressindex_to_p2pk65addressindex: lazy!(
|
||||
"p2pk65addressindex",
|
||||
indexer.vecs.address.p2pk65addressindex_to_p2pk65bytes
|
||||
),
|
||||
p2pkhaddressindex_to_p2pkhaddressindex: lazy!(
|
||||
"p2pkhaddressindex",
|
||||
indexer.vecs.address.p2pkhaddressindex_to_p2pkhbytes
|
||||
),
|
||||
p2shaddressindex_to_p2shaddressindex: lazy!(
|
||||
"p2shaddressindex",
|
||||
indexer.vecs.address.p2shaddressindex_to_p2shbytes
|
||||
),
|
||||
p2traddressindex_to_p2traddressindex: lazy!(
|
||||
"p2traddressindex",
|
||||
indexer.vecs.address.p2traddressindex_to_p2trbytes
|
||||
),
|
||||
p2wpkhaddressindex_to_p2wpkhaddressindex: lazy!(
|
||||
"p2wpkhaddressindex",
|
||||
indexer.vecs.address.p2wpkhaddressindex_to_p2wpkhbytes
|
||||
),
|
||||
p2wshaddressindex_to_p2wshaddressindex: lazy!(
|
||||
"p2wshaddressindex",
|
||||
indexer.vecs.address.p2wshaddressindex_to_p2wshbytes
|
||||
),
|
||||
p2aaddressindex_to_p2aaddressindex: lazy!(
|
||||
"p2aaddressindex",
|
||||
indexer.vecs.address.p2aaddressindex_to_p2abytes
|
||||
),
|
||||
p2msoutputindex_to_p2msoutputindex: lazy!(
|
||||
"p2msoutputindex",
|
||||
indexer.vecs.output.p2msoutputindex_to_txindex
|
||||
),
|
||||
emptyoutputindex_to_emptyoutputindex: lazy!(
|
||||
"emptyoutputindex",
|
||||
indexer.vecs.output.emptyoutputindex_to_txindex
|
||||
),
|
||||
unknownoutputindex_to_unknownoutputindex: lazy!(
|
||||
"unknownoutputindex",
|
||||
indexer.vecs.output.unknownoutputindex_to_txindex
|
||||
),
|
||||
opreturnindex_to_opreturnindex: lazy!(
|
||||
"opreturnindex",
|
||||
indexer.vecs.output.opreturnindex_to_txindex
|
||||
),
|
||||
txindex_to_txindex: lazy!("txindex", indexer.vecs.tx.txindex_to_txid),
|
||||
txindex_to_input_count: eager!("input_count"),
|
||||
txindex_to_output_count: eager!("output_count"),
|
||||
dateindex_to_date: eager!("date"),
|
||||
dateindex_to_dateindex: eager!("dateindex"),
|
||||
dateindex_to_first_height: eager!("first_height"),
|
||||
dateindex_to_monthindex: eager!("monthindex"),
|
||||
dateindex_to_weekindex: eager!("weekindex"),
|
||||
decadeindex_to_decadeindex: eager!("decadeindex"),
|
||||
decadeindex_to_first_yearindex: eager!("first_yearindex"),
|
||||
difficultyepoch_to_difficultyepoch: eager!("difficultyepoch"),
|
||||
difficultyepoch_to_first_height: eager!("first_height"),
|
||||
halvingepoch_to_first_height: eager!("first_height"),
|
||||
halvingepoch_to_halvingepoch: eager!("halvingepoch"),
|
||||
height_to_date: eager!("date"),
|
||||
height_to_difficultyepoch: eager!("difficultyepoch"),
|
||||
height_to_halvingepoch: eager!("halvingepoch"),
|
||||
height_to_height: eager!("height"),
|
||||
monthindex_to_first_dateindex: eager!("first_dateindex"),
|
||||
monthindex_to_monthindex: eager!("monthindex"),
|
||||
monthindex_to_quarterindex: eager!("quarterindex"),
|
||||
monthindex_to_semesterindex: eager!("semesterindex"),
|
||||
monthindex_to_yearindex: eager!("yearindex"),
|
||||
quarterindex_to_first_monthindex: eager!("first_monthindex"),
|
||||
semesterindex_to_first_monthindex: eager!("first_monthindex"),
|
||||
weekindex_to_first_dateindex: eager!("first_dateindex"),
|
||||
yearindex_to_first_monthindex: eager!("first_monthindex"),
|
||||
quarterindex_to_quarterindex: eager!("quarterindex"),
|
||||
semesterindex_to_semesterindex: eager!("semesterindex"),
|
||||
weekindex_to_weekindex: eager!("weekindex"),
|
||||
yearindex_to_decadeindex: eager!("decadeindex"),
|
||||
yearindex_to_yearindex: eager!("yearindex"),
|
||||
height_to_date_fixed: eager!("date_fixed"),
|
||||
height_to_dateindex: eager!("dateindex"),
|
||||
height_to_timestamp_fixed: eager!("timestamp_fixed"),
|
||||
height_to_txindex_count: eager!("txindex_count"),
|
||||
dateindex_to_height_count: eager!("height_count"),
|
||||
weekindex_to_dateindex_count: eager!("dateindex_count"),
|
||||
difficultyepoch_to_height_count: eager!("height_count"),
|
||||
monthindex_to_dateindex_count: eager!("dateindex_count"),
|
||||
quarterindex_to_monthindex_count: eager!("monthindex_count"),
|
||||
semesterindex_to_monthindex_count: eager!("monthindex_count"),
|
||||
yearindex_to_monthindex_count: eager!("monthindex_count"),
|
||||
decadeindex_to_yearindex_count: eager!("yearindex_count"),
|
||||
db,
|
||||
};
|
||||
|
||||
this.db.retain_regions(
|
||||
this.iter_any_exportable()
|
||||
.flat_map(|v| v.region_names())
|
||||
.collect(),
|
||||
)?;
|
||||
this.db.compact()?;
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<Indexes> {
|
||||
let indexes = self.compute_(indexer, starting_indexes, exit)?;
|
||||
let _lock = exit.lock();
|
||||
self.db.compact()?;
|
||||
Ok(indexes)
|
||||
}
|
||||
|
||||
fn compute_(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<Indexes> {
|
||||
self.txindex_to_input_count.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txinindex,
|
||||
&indexer.vecs.txin.txinindex_to_outpoint,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_output_count.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txoutindex,
|
||||
&indexer.vecs.txout.txoutindex_to_value,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_txindex_count.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexer.vecs.tx.txindex_to_txid,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_height.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_timestamp,
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let mut prev_timestamp_fixed = None;
|
||||
self.height_to_timestamp_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_timestamp,
|
||||
|(h, timestamp, height_to_timestamp_fixed_iter)| {
|
||||
if prev_timestamp_fixed.is_none()
|
||||
&& let Some(prev_h) = h.decremented()
|
||||
{
|
||||
prev_timestamp_fixed.replace(
|
||||
height_to_timestamp_fixed_iter
|
||||
.into_iter()
|
||||
.get_unwrap(prev_h),
|
||||
);
|
||||
}
|
||||
let timestamp_fixed =
|
||||
prev_timestamp_fixed.map_or(timestamp, |prev_d| prev_d.max(timestamp));
|
||||
prev_timestamp_fixed.replace(timestamp_fixed);
|
||||
(h, timestamp_fixed)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.height_to_timestamp_fixed,
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let decremented_starting_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
let starting_dateindex = self
|
||||
.height_to_dateindex
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_dateindex.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.height_to_date_fixed,
|
||||
|(h, d, ..)| (h, DateIndex::try_from(d).unwrap()),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_dateindex = if let Some(dateindex) = self
|
||||
.height_to_dateindex
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
{
|
||||
starting_dateindex.min(dateindex)
|
||||
} else {
|
||||
starting_dateindex
|
||||
};
|
||||
|
||||
self.dateindex_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&self.height_to_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_dateindex.compute_from_index(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_date.compute_from_index(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_height_count.compute_count_from_indexes(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_weekindex = self
|
||||
.dateindex_to_weekindex
|
||||
.into_iter()
|
||||
.get(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_weekindex.compute_range(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_dateindex,
|
||||
|i| (i, WeekIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_first_dateindex.compute_coarser(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_weekindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_weekindex.compute_from_index(
|
||||
starting_weekindex,
|
||||
&self.weekindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_dateindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_weekindex,
|
||||
&self.weekindex_to_first_dateindex,
|
||||
&self.dateindex_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_difficultyepoch = self
|
||||
.height_to_difficultyepoch
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_difficultyepoch.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&self.height_to_difficultyepoch,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_difficultyepoch.compute_from_index(
|
||||
starting_difficultyepoch,
|
||||
&self.difficultyepoch_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_height_count
|
||||
.compute_count_from_indexes(
|
||||
starting_difficultyepoch,
|
||||
&self.difficultyepoch_to_first_height,
|
||||
&self.height_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_monthindex = self
|
||||
.dateindex_to_monthindex
|
||||
.into_iter()
|
||||
.get(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_monthindex.compute_range(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_dateindex,
|
||||
|i| (i, MonthIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_first_dateindex.compute_coarser(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_monthindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_dateindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
&self.dateindex_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_quarterindex = self
|
||||
.monthindex_to_quarterindex
|
||||
.into_iter()
|
||||
.get(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_quarterindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_first_monthindex.compute_coarser(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_quarterindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// let quarter_count = self.quarterindex_to_first_monthindex.len();
|
||||
|
||||
self.quarterindex_to_quarterindex.compute_from_index(
|
||||
starting_quarterindex,
|
||||
&self.quarterindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_monthindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_quarterindex,
|
||||
&self.quarterindex_to_first_monthindex,
|
||||
&self.monthindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_semesterindex = self
|
||||
.monthindex_to_semesterindex
|
||||
.into_iter()
|
||||
.get(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_coarser(
|
||||
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,
|
||||
)?;
|
||||
|
||||
let starting_yearindex = self
|
||||
.monthindex_to_yearindex
|
||||
.into_iter()
|
||||
.get(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_yearindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_first_monthindex.compute_coarser(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_yearindex.compute_from_index(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_monthindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
&self.monthindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_halvingepoch = self
|
||||
.height_to_halvingepoch
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_halvingepoch.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&self.height_to_halvingepoch,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_halvingepoch.compute_from_index(
|
||||
starting_halvingepoch,
|
||||
&self.halvingepoch_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_decadeindex = self
|
||||
.yearindex_to_decadeindex
|
||||
.into_iter()
|
||||
.get(starting_yearindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.yearindex_to_decadeindex.compute_from_index(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_first_yearindex.compute_coarser(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_decadeindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_decadeindex.compute_from_index(
|
||||
starting_decadeindex,
|
||||
&self.decadeindex_to_first_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_yearindex_count
|
||||
.compute_count_from_indexes(
|
||||
starting_decadeindex,
|
||||
&self.decadeindex_to_first_yearindex,
|
||||
&self.yearindex_to_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(Indexes {
|
||||
indexes: starting_indexes,
|
||||
dateindex: starting_dateindex,
|
||||
weekindex: starting_weekindex,
|
||||
monthindex: starting_monthindex,
|
||||
quarterindex: starting_quarterindex,
|
||||
semesterindex: starting_semesterindex,
|
||||
yearindex: starting_yearindex,
|
||||
decadeindex: starting_decadeindex,
|
||||
difficultyepoch: starting_difficultyepoch,
|
||||
halvingepoch: starting_halvingepoch,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Indexes {
|
||||
indexes: brk_indexer::Indexes,
|
||||
pub dateindex: DateIndex,
|
||||
pub weekindex: WeekIndex,
|
||||
pub monthindex: MonthIndex,
|
||||
pub quarterindex: QuarterIndex,
|
||||
pub semesterindex: SemesterIndex,
|
||||
pub yearindex: YearIndex,
|
||||
pub decadeindex: DecadeIndex,
|
||||
pub difficultyepoch: DifficultyEpoch,
|
||||
pub halvingepoch: HalvingEpoch,
|
||||
}
|
||||
|
||||
impl Indexes {
|
||||
pub fn update_from_height(&mut self, height: Height, indexes: &Vecs) {
|
||||
self.indexes.height = height;
|
||||
self.dateindex =
|
||||
DateIndex::try_from(indexes.height_to_date_fixed.into_iter().get_unwrap(height))
|
||||
.unwrap();
|
||||
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);
|
||||
self.halvingepoch = HalvingEpoch::from(self.height);
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Indexes {
|
||||
type Target = brk_indexer::Indexes;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.indexes
|
||||
}
|
||||
}
|
||||
84
crates/brk_computer/src/indexes/address/import.rs
Normal file
84
crates/brk_computer/src/indexes/address/import.rs
Normal file
@@ -0,0 +1,84 @@
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::Version;
|
||||
use vecdb::{IterableCloneableVec, LazyVecFrom1};
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(version: Version, indexer: &Indexer) -> Self {
|
||||
Self {
|
||||
p2pk33addressindex_to_p2pk33addressindex: LazyVecFrom1::init(
|
||||
"p2pk33addressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2pk33addressindex_to_p2pk33bytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2pk65addressindex_to_p2pk65addressindex: LazyVecFrom1::init(
|
||||
"p2pk65addressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2pk65addressindex_to_p2pk65bytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2pkhaddressindex_to_p2pkhaddressindex: LazyVecFrom1::init(
|
||||
"p2pkhaddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2pkhaddressindex_to_p2pkhbytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2shaddressindex_to_p2shaddressindex: LazyVecFrom1::init(
|
||||
"p2shaddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2shaddressindex_to_p2shbytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2traddressindex_to_p2traddressindex: LazyVecFrom1::init(
|
||||
"p2traddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2traddressindex_to_p2trbytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2wpkhaddressindex_to_p2wpkhaddressindex: LazyVecFrom1::init(
|
||||
"p2wpkhaddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2wpkhaddressindex_to_p2wpkhbytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2wshaddressindex_to_p2wshaddressindex: LazyVecFrom1::init(
|
||||
"p2wshaddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2wshaddressindex_to_p2wshbytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2aaddressindex_to_p2aaddressindex: LazyVecFrom1::init(
|
||||
"p2aaddressindex",
|
||||
version,
|
||||
indexer.vecs.address.p2aaddressindex_to_p2abytes.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
p2msoutputindex_to_p2msoutputindex: LazyVecFrom1::init(
|
||||
"p2msoutputindex",
|
||||
version,
|
||||
indexer.vecs.output.p2msoutputindex_to_txindex.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
emptyoutputindex_to_emptyoutputindex: LazyVecFrom1::init(
|
||||
"emptyoutputindex",
|
||||
version,
|
||||
indexer.vecs.output.emptyoutputindex_to_txindex.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
unknownoutputindex_to_unknownoutputindex: LazyVecFrom1::init(
|
||||
"unknownoutputindex",
|
||||
version,
|
||||
indexer.vecs.output.unknownoutputindex_to_txindex.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
opreturnindex_to_opreturnindex: LazyVecFrom1::init(
|
||||
"opreturnindex",
|
||||
version,
|
||||
indexer.vecs.output.opreturnindex_to_txindex.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
}
|
||||
}
|
||||
}
|
||||
4
crates/brk_computer/src/indexes/address/mod.rs
Normal file
4
crates/brk_computer/src/indexes/address/mod.rs
Normal file
@@ -0,0 +1,4 @@
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
36
crates/brk_computer/src/indexes/address/vecs.rs
Normal file
36
crates/brk_computer/src/indexes/address/vecs.rs
Normal file
@@ -0,0 +1,36 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
EmptyOutputIndex, OpReturnIndex, P2AAddressIndex, P2ABytes, P2MSOutputIndex,
|
||||
P2PK33AddressIndex, P2PK33Bytes, P2PK65AddressIndex, P2PK65Bytes, P2PKHAddressIndex,
|
||||
P2PKHBytes, P2SHAddressIndex, P2SHBytes, P2TRAddressIndex, P2TRBytes, P2WPKHAddressIndex,
|
||||
P2WPKHBytes, P2WSHAddressIndex, P2WSHBytes, TxIndex, UnknownOutputIndex,
|
||||
};
|
||||
use vecdb::LazyVecFrom1;
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub emptyoutputindex_to_emptyoutputindex:
|
||||
LazyVecFrom1<EmptyOutputIndex, EmptyOutputIndex, EmptyOutputIndex, TxIndex>,
|
||||
pub opreturnindex_to_opreturnindex:
|
||||
LazyVecFrom1<OpReturnIndex, OpReturnIndex, OpReturnIndex, TxIndex>,
|
||||
pub p2aaddressindex_to_p2aaddressindex:
|
||||
LazyVecFrom1<P2AAddressIndex, P2AAddressIndex, P2AAddressIndex, P2ABytes>,
|
||||
pub p2msoutputindex_to_p2msoutputindex:
|
||||
LazyVecFrom1<P2MSOutputIndex, P2MSOutputIndex, P2MSOutputIndex, TxIndex>,
|
||||
pub p2pk33addressindex_to_p2pk33addressindex:
|
||||
LazyVecFrom1<P2PK33AddressIndex, P2PK33AddressIndex, P2PK33AddressIndex, P2PK33Bytes>,
|
||||
pub p2pk65addressindex_to_p2pk65addressindex:
|
||||
LazyVecFrom1<P2PK65AddressIndex, P2PK65AddressIndex, P2PK65AddressIndex, P2PK65Bytes>,
|
||||
pub p2pkhaddressindex_to_p2pkhaddressindex:
|
||||
LazyVecFrom1<P2PKHAddressIndex, P2PKHAddressIndex, P2PKHAddressIndex, P2PKHBytes>,
|
||||
pub p2shaddressindex_to_p2shaddressindex:
|
||||
LazyVecFrom1<P2SHAddressIndex, P2SHAddressIndex, P2SHAddressIndex, P2SHBytes>,
|
||||
pub p2traddressindex_to_p2traddressindex:
|
||||
LazyVecFrom1<P2TRAddressIndex, P2TRAddressIndex, P2TRAddressIndex, P2TRBytes>,
|
||||
pub p2wpkhaddressindex_to_p2wpkhaddressindex:
|
||||
LazyVecFrom1<P2WPKHAddressIndex, P2WPKHAddressIndex, P2WPKHAddressIndex, P2WPKHBytes>,
|
||||
pub p2wshaddressindex_to_p2wshaddressindex:
|
||||
LazyVecFrom1<P2WSHAddressIndex, P2WSHAddressIndex, P2WSHAddressIndex, P2WSHBytes>,
|
||||
pub unknownoutputindex_to_unknownoutputindex:
|
||||
LazyVecFrom1<UnknownOutputIndex, UnknownOutputIndex, UnknownOutputIndex, TxIndex>,
|
||||
}
|
||||
149
crates/brk_computer/src/indexes/block/compute.rs
Normal file
149
crates/brk_computer/src/indexes/block/compute.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{Date, DateIndex, DifficultyEpoch, HalvingEpoch};
|
||||
use vecdb::{Exit, TypedVecIterator};
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: &brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<(DateIndex, DifficultyEpoch, HalvingEpoch)> {
|
||||
self.height_to_txindex_count.compute_count_from_indexes(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.tx.height_to_first_txindex,
|
||||
&indexer.vecs.tx.txindex_to_txid,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_height.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_timestamp,
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let mut prev_timestamp_fixed = None;
|
||||
self.height_to_timestamp_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_timestamp,
|
||||
|(h, timestamp, height_to_timestamp_fixed_iter)| {
|
||||
if prev_timestamp_fixed.is_none()
|
||||
&& let Some(prev_h) = h.decremented()
|
||||
{
|
||||
prev_timestamp_fixed.replace(
|
||||
height_to_timestamp_fixed_iter
|
||||
.into_iter()
|
||||
.get_unwrap(prev_h),
|
||||
);
|
||||
}
|
||||
let timestamp_fixed =
|
||||
prev_timestamp_fixed.map_or(timestamp, |prev_d| prev_d.max(timestamp));
|
||||
prev_timestamp_fixed.replace(timestamp_fixed);
|
||||
(h, timestamp_fixed)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_date_fixed.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.height_to_timestamp_fixed,
|
||||
|(h, t, ..)| (h, Date::from(t)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let decremented_starting_height = starting_indexes.height.decremented().unwrap_or_default();
|
||||
|
||||
// DateIndex (computed before time module needs it)
|
||||
let starting_dateindex = self
|
||||
.height_to_dateindex
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_dateindex.compute_transform(
|
||||
starting_indexes.height,
|
||||
&self.height_to_date_fixed,
|
||||
|(h, d, ..)| (h, DateIndex::try_from(d).unwrap()),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
let starting_dateindex = if let Some(dateindex) = self
|
||||
.height_to_dateindex
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
{
|
||||
starting_dateindex.min(dateindex)
|
||||
} else {
|
||||
starting_dateindex
|
||||
};
|
||||
|
||||
// Difficulty epoch
|
||||
let starting_difficultyepoch = self
|
||||
.height_to_difficultyepoch
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_difficultyepoch.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&self.height_to_difficultyepoch,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_difficultyepoch.compute_from_index(
|
||||
starting_difficultyepoch,
|
||||
&self.difficultyepoch_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.difficultyepoch_to_height_count.compute_count_from_indexes(
|
||||
starting_difficultyepoch,
|
||||
&self.difficultyepoch_to_first_height,
|
||||
&self.height_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Halving epoch
|
||||
let starting_halvingepoch = self
|
||||
.height_to_halvingepoch
|
||||
.into_iter()
|
||||
.get(decremented_starting_height)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.height_to_halvingepoch.compute_from_index(
|
||||
starting_indexes.height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&self.height_to_halvingepoch,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.halvingepoch_to_halvingepoch.compute_from_index(
|
||||
starting_halvingepoch,
|
||||
&self.halvingepoch_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok((starting_dateindex, starting_difficultyepoch, starting_halvingepoch))
|
||||
}
|
||||
}
|
||||
25
crates/brk_computer/src/indexes/block/import.rs
Normal file
25
crates/brk_computer/src/indexes/block/import.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec};
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
height_to_date: EagerVec::forced_import(db, "date", version)?,
|
||||
height_to_date_fixed: EagerVec::forced_import(db, "date_fixed", version)?,
|
||||
height_to_dateindex: EagerVec::forced_import(db, "dateindex", version)?,
|
||||
height_to_difficultyepoch: EagerVec::forced_import(db, "difficultyepoch", version)?,
|
||||
height_to_halvingepoch: EagerVec::forced_import(db, "halvingepoch", version)?,
|
||||
height_to_height: EagerVec::forced_import(db, "height", version)?,
|
||||
height_to_timestamp_fixed: EagerVec::forced_import(db, "timestamp_fixed", version)?,
|
||||
height_to_txindex_count: EagerVec::forced_import(db, "txindex_count", version)?,
|
||||
difficultyepoch_to_difficultyepoch: EagerVec::forced_import(db, "difficultyepoch", version)?,
|
||||
difficultyepoch_to_first_height: EagerVec::forced_import(db, "first_height", version)?,
|
||||
difficultyepoch_to_height_count: EagerVec::forced_import(db, "height_count", version)?,
|
||||
halvingepoch_to_first_height: EagerVec::forced_import(db, "first_height", version)?,
|
||||
halvingepoch_to_halvingepoch: EagerVec::forced_import(db, "halvingepoch", version)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/indexes/block/mod.rs
Normal file
5
crates/brk_computer/src/indexes/block/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
20
crates/brk_computer/src/indexes/block/vecs.rs
Normal file
20
crates/brk_computer/src/indexes/block/vecs.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Date, DateIndex, DifficultyEpoch, HalvingEpoch, Height, StoredU64, Timestamp};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub height_to_date: EagerVec<PcoVec<Height, Date>>,
|
||||
pub height_to_date_fixed: EagerVec<PcoVec<Height, Date>>,
|
||||
pub height_to_dateindex: EagerVec<PcoVec<Height, DateIndex>>,
|
||||
pub height_to_difficultyepoch: EagerVec<PcoVec<Height, DifficultyEpoch>>,
|
||||
pub height_to_halvingepoch: EagerVec<PcoVec<Height, HalvingEpoch>>,
|
||||
pub height_to_height: EagerVec<PcoVec<Height, Height>>,
|
||||
pub height_to_timestamp_fixed: EagerVec<PcoVec<Height, Timestamp>>,
|
||||
pub height_to_txindex_count: EagerVec<PcoVec<Height, StoredU64>>,
|
||||
pub difficultyepoch_to_difficultyepoch: EagerVec<PcoVec<DifficultyEpoch, DifficultyEpoch>>,
|
||||
pub difficultyepoch_to_first_height: EagerVec<PcoVec<DifficultyEpoch, Height>>,
|
||||
pub difficultyepoch_to_height_count: EagerVec<PcoVec<DifficultyEpoch, StoredU64>>,
|
||||
pub halvingepoch_to_first_height: EagerVec<PcoVec<HalvingEpoch, Height>>,
|
||||
pub halvingepoch_to_halvingepoch: EagerVec<PcoVec<HalvingEpoch, HalvingEpoch>>,
|
||||
}
|
||||
149
crates/brk_computer/src/indexes/mod.rs
Normal file
149
crates/brk_computer/src/indexes/mod.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
mod address;
|
||||
mod block;
|
||||
mod time;
|
||||
mod transaction;
|
||||
|
||||
use std::{ops::Deref, path::Path};
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
DateIndex, DecadeIndex, DifficultyEpoch, HalvingEpoch, Height, MonthIndex, QuarterIndex,
|
||||
SemesterIndex, Version, WeekIndex, YearIndex,
|
||||
};
|
||||
use vecdb::{Database, Exit, PAGE_SIZE, TypedVecIterator};
|
||||
|
||||
pub use address::Vecs as AddressVecs;
|
||||
pub use block::Vecs as BlockVecs;
|
||||
pub use time::Vecs as TimeVecs;
|
||||
pub use transaction::Vecs as TransactionVecs;
|
||||
|
||||
const VERSION: Version = Version::ZERO;
|
||||
pub const DB_NAME: &str = "indexes";
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
db: Database,
|
||||
pub address: AddressVecs,
|
||||
pub block: BlockVecs,
|
||||
pub time: TimeVecs,
|
||||
pub transaction: TransactionVecs,
|
||||
}
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
parent: &Path,
|
||||
parent_version: Version,
|
||||
indexer: &Indexer,
|
||||
) -> Result<Self> {
|
||||
let db = Database::open(&parent.join(DB_NAME))?;
|
||||
db.set_min_len(PAGE_SIZE * 10_000_000)?;
|
||||
|
||||
let version = parent_version + VERSION;
|
||||
|
||||
let this = Self {
|
||||
address: AddressVecs::forced_import(version, indexer),
|
||||
block: BlockVecs::forced_import(&db, version)?,
|
||||
time: TimeVecs::forced_import(&db, version)?,
|
||||
transaction: TransactionVecs::forced_import(&db, version, indexer)?,
|
||||
db,
|
||||
};
|
||||
|
||||
this.db.retain_regions(
|
||||
this.iter_any_exportable()
|
||||
.flat_map(|v| v.region_names())
|
||||
.collect(),
|
||||
)?;
|
||||
this.db.compact()?;
|
||||
|
||||
Ok(this)
|
||||
}
|
||||
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<Indexes> {
|
||||
let indexes = self.compute_(indexer, starting_indexes, exit)?;
|
||||
let _lock = exit.lock();
|
||||
self.db.compact()?;
|
||||
Ok(indexes)
|
||||
}
|
||||
|
||||
fn compute_(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: brk_indexer::Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<Indexes> {
|
||||
// Transaction indexes
|
||||
self.transaction.compute(indexer, &starting_indexes, exit)?;
|
||||
|
||||
// Block indexes (height, dateindex, difficultyepoch, halvingepoch)
|
||||
let (starting_dateindex, starting_difficultyepoch, starting_halvingepoch) =
|
||||
self.block.compute(indexer, &starting_indexes, exit)?;
|
||||
|
||||
// Time indexes (depends on block.height_to_dateindex)
|
||||
let time_indexes = self
|
||||
.time
|
||||
.compute(indexer, &starting_indexes, starting_dateindex, &self.block, exit)?;
|
||||
|
||||
Ok(Indexes {
|
||||
indexes: starting_indexes,
|
||||
dateindex: time_indexes.dateindex,
|
||||
weekindex: time_indexes.weekindex,
|
||||
monthindex: time_indexes.monthindex,
|
||||
quarterindex: time_indexes.quarterindex,
|
||||
semesterindex: time_indexes.semesterindex,
|
||||
yearindex: time_indexes.yearindex,
|
||||
decadeindex: time_indexes.decadeindex,
|
||||
difficultyepoch: starting_difficultyepoch,
|
||||
halvingepoch: starting_halvingepoch,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Indexes {
|
||||
indexes: brk_indexer::Indexes,
|
||||
pub dateindex: DateIndex,
|
||||
pub weekindex: WeekIndex,
|
||||
pub monthindex: MonthIndex,
|
||||
pub quarterindex: QuarterIndex,
|
||||
pub semesterindex: SemesterIndex,
|
||||
pub yearindex: YearIndex,
|
||||
pub decadeindex: DecadeIndex,
|
||||
pub difficultyepoch: DifficultyEpoch,
|
||||
pub halvingepoch: HalvingEpoch,
|
||||
}
|
||||
|
||||
impl Indexes {
|
||||
pub fn update_from_height(&mut self, height: Height, indexes: &Vecs) {
|
||||
self.indexes.height = height;
|
||||
self.dateindex = DateIndex::try_from(
|
||||
indexes
|
||||
.block
|
||||
.height_to_date_fixed
|
||||
.into_iter()
|
||||
.get_unwrap(height),
|
||||
)
|
||||
.unwrap();
|
||||
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);
|
||||
self.halvingepoch = HalvingEpoch::from(self.height);
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Indexes {
|
||||
type Target = brk_indexer::Indexes;
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.indexes
|
||||
}
|
||||
}
|
||||
246
crates/brk_computer/src/indexes/time/compute.rs
Normal file
246
crates/brk_computer/src/indexes/time/compute.rs
Normal file
@@ -0,0 +1,246 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::{DateIndex, MonthIndex, WeekIndex};
|
||||
use vecdb::{Exit, TypedVecIterator};
|
||||
|
||||
use super::{super::block, vecs::StartingTimeIndexes, Vecs};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
indexer: &Indexer,
|
||||
starting_indexes: &brk_indexer::Indexes,
|
||||
starting_dateindex: DateIndex,
|
||||
block_vecs: &block::Vecs,
|
||||
exit: &Exit,
|
||||
) -> Result<StartingTimeIndexes> {
|
||||
self.dateindex_to_first_height.compute_coarser(
|
||||
starting_indexes.height,
|
||||
&block_vecs.height_to_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_dateindex.compute_from_index(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_date.compute_from_index(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_height_count.compute_count_from_indexes(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_first_height,
|
||||
&indexer.vecs.block.height_to_weight,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Week
|
||||
let starting_weekindex = self
|
||||
.dateindex_to_weekindex
|
||||
.into_iter()
|
||||
.get(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_weekindex.compute_range(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_dateindex,
|
||||
|i| (i, WeekIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_first_dateindex.compute_coarser(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_weekindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_weekindex.compute_from_index(
|
||||
starting_weekindex,
|
||||
&self.weekindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.weekindex_to_dateindex_count.compute_count_from_indexes(
|
||||
starting_weekindex,
|
||||
&self.weekindex_to_first_dateindex,
|
||||
&self.dateindex_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Month
|
||||
let starting_monthindex = self
|
||||
.dateindex_to_monthindex
|
||||
.into_iter()
|
||||
.get(starting_dateindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.dateindex_to_monthindex.compute_range(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_dateindex,
|
||||
|i| (i, MonthIndex::from(i)),
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_first_dateindex.compute_coarser(
|
||||
starting_dateindex,
|
||||
&self.dateindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_monthindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.monthindex_to_dateindex_count.compute_count_from_indexes(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
&self.dateindex_to_date,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Quarter
|
||||
let starting_quarterindex = self
|
||||
.monthindex_to_quarterindex
|
||||
.into_iter()
|
||||
.get(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_quarterindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_first_monthindex.compute_coarser(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_quarterindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_quarterindex.compute_from_index(
|
||||
starting_quarterindex,
|
||||
&self.quarterindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.quarterindex_to_monthindex_count.compute_count_from_indexes(
|
||||
starting_quarterindex,
|
||||
&self.quarterindex_to_first_monthindex,
|
||||
&self.monthindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Semester
|
||||
let starting_semesterindex = self
|
||||
.monthindex_to_semesterindex
|
||||
.into_iter()
|
||||
.get(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_coarser(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_semesterindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
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,
|
||||
)?;
|
||||
|
||||
// Year
|
||||
let starting_yearindex = self
|
||||
.monthindex_to_yearindex
|
||||
.into_iter()
|
||||
.get(starting_monthindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.monthindex_to_yearindex.compute_from_index(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_first_dateindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_first_monthindex.compute_coarser(
|
||||
starting_monthindex,
|
||||
&self.monthindex_to_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_yearindex.compute_from_index(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.yearindex_to_monthindex_count.compute_count_from_indexes(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
&self.monthindex_to_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
// Decade
|
||||
let starting_decadeindex = self
|
||||
.yearindex_to_decadeindex
|
||||
.into_iter()
|
||||
.get(starting_yearindex)
|
||||
.unwrap_or_default();
|
||||
|
||||
self.yearindex_to_decadeindex.compute_from_index(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_first_monthindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_first_yearindex.compute_coarser(
|
||||
starting_yearindex,
|
||||
&self.yearindex_to_decadeindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_decadeindex.compute_from_index(
|
||||
starting_decadeindex,
|
||||
&self.decadeindex_to_first_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.decadeindex_to_yearindex_count.compute_count_from_indexes(
|
||||
starting_decadeindex,
|
||||
&self.decadeindex_to_first_yearindex,
|
||||
&self.yearindex_to_yearindex,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(StartingTimeIndexes {
|
||||
dateindex: starting_dateindex,
|
||||
weekindex: starting_weekindex,
|
||||
monthindex: starting_monthindex,
|
||||
quarterindex: starting_quarterindex,
|
||||
semesterindex: starting_semesterindex,
|
||||
yearindex: starting_yearindex,
|
||||
decadeindex: starting_decadeindex,
|
||||
})
|
||||
}
|
||||
}
|
||||
40
crates/brk_computer/src/indexes/time/import.rs
Normal file
40
crates/brk_computer/src/indexes/time/import.rs
Normal file
@@ -0,0 +1,40 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec};
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version) -> Result<Self> {
|
||||
Ok(Self {
|
||||
dateindex_to_date: EagerVec::forced_import(db, "date", version)?,
|
||||
dateindex_to_dateindex: EagerVec::forced_import(db, "dateindex", version)?,
|
||||
dateindex_to_first_height: EagerVec::forced_import(db, "first_height", version)?,
|
||||
dateindex_to_height_count: EagerVec::forced_import(db, "height_count", version)?,
|
||||
dateindex_to_monthindex: EagerVec::forced_import(db, "monthindex", version)?,
|
||||
dateindex_to_weekindex: EagerVec::forced_import(db, "weekindex", version)?,
|
||||
weekindex_to_dateindex_count: EagerVec::forced_import(db, "dateindex_count", version)?,
|
||||
weekindex_to_first_dateindex: EagerVec::forced_import(db, "first_dateindex", version)?,
|
||||
weekindex_to_weekindex: EagerVec::forced_import(db, "weekindex", version)?,
|
||||
monthindex_to_dateindex_count: EagerVec::forced_import(db, "dateindex_count", version)?,
|
||||
monthindex_to_first_dateindex: EagerVec::forced_import(db, "first_dateindex", version)?,
|
||||
monthindex_to_monthindex: EagerVec::forced_import(db, "monthindex", version)?,
|
||||
monthindex_to_quarterindex: EagerVec::forced_import(db, "quarterindex", version)?,
|
||||
monthindex_to_semesterindex: EagerVec::forced_import(db, "semesterindex", version)?,
|
||||
monthindex_to_yearindex: EagerVec::forced_import(db, "yearindex", version)?,
|
||||
quarterindex_to_first_monthindex: EagerVec::forced_import(db, "first_monthindex", version)?,
|
||||
quarterindex_to_monthindex_count: EagerVec::forced_import(db, "monthindex_count", version)?,
|
||||
quarterindex_to_quarterindex: EagerVec::forced_import(db, "quarterindex", version)?,
|
||||
semesterindex_to_first_monthindex: EagerVec::forced_import(db, "first_monthindex", version)?,
|
||||
semesterindex_to_monthindex_count: EagerVec::forced_import(db, "monthindex_count", version)?,
|
||||
semesterindex_to_semesterindex: EagerVec::forced_import(db, "semesterindex", version)?,
|
||||
yearindex_to_decadeindex: EagerVec::forced_import(db, "decadeindex", version)?,
|
||||
yearindex_to_first_monthindex: EagerVec::forced_import(db, "first_monthindex", version)?,
|
||||
yearindex_to_monthindex_count: EagerVec::forced_import(db, "monthindex_count", version)?,
|
||||
yearindex_to_yearindex: EagerVec::forced_import(db, "yearindex", version)?,
|
||||
decadeindex_to_decadeindex: EagerVec::forced_import(db, "decadeindex", version)?,
|
||||
decadeindex_to_first_yearindex: EagerVec::forced_import(db, "first_yearindex", version)?,
|
||||
decadeindex_to_yearindex_count: EagerVec::forced_import(db, "yearindex_count", version)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/indexes/time/mod.rs
Normal file
5
crates/brk_computer/src/indexes/time/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
48
crates/brk_computer/src/indexes/time/vecs.rs
Normal file
48
crates/brk_computer/src/indexes/time/vecs.rs
Normal file
@@ -0,0 +1,48 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{
|
||||
Date, DateIndex, DecadeIndex, Height, MonthIndex, QuarterIndex, SemesterIndex, StoredU64,
|
||||
WeekIndex, YearIndex,
|
||||
};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub dateindex_to_date: EagerVec<PcoVec<DateIndex, Date>>,
|
||||
pub dateindex_to_dateindex: EagerVec<PcoVec<DateIndex, DateIndex>>,
|
||||
pub dateindex_to_first_height: EagerVec<PcoVec<DateIndex, Height>>,
|
||||
pub dateindex_to_height_count: EagerVec<PcoVec<DateIndex, StoredU64>>,
|
||||
pub dateindex_to_monthindex: EagerVec<PcoVec<DateIndex, MonthIndex>>,
|
||||
pub dateindex_to_weekindex: EagerVec<PcoVec<DateIndex, WeekIndex>>,
|
||||
pub weekindex_to_dateindex_count: EagerVec<PcoVec<WeekIndex, StoredU64>>,
|
||||
pub weekindex_to_first_dateindex: EagerVec<PcoVec<WeekIndex, DateIndex>>,
|
||||
pub weekindex_to_weekindex: EagerVec<PcoVec<WeekIndex, WeekIndex>>,
|
||||
pub monthindex_to_dateindex_count: EagerVec<PcoVec<MonthIndex, StoredU64>>,
|
||||
pub monthindex_to_first_dateindex: EagerVec<PcoVec<MonthIndex, DateIndex>>,
|
||||
pub monthindex_to_monthindex: EagerVec<PcoVec<MonthIndex, MonthIndex>>,
|
||||
pub monthindex_to_quarterindex: EagerVec<PcoVec<MonthIndex, QuarterIndex>>,
|
||||
pub monthindex_to_semesterindex: EagerVec<PcoVec<MonthIndex, SemesterIndex>>,
|
||||
pub monthindex_to_yearindex: EagerVec<PcoVec<MonthIndex, YearIndex>>,
|
||||
pub quarterindex_to_first_monthindex: EagerVec<PcoVec<QuarterIndex, MonthIndex>>,
|
||||
pub quarterindex_to_monthindex_count: EagerVec<PcoVec<QuarterIndex, StoredU64>>,
|
||||
pub quarterindex_to_quarterindex: EagerVec<PcoVec<QuarterIndex, QuarterIndex>>,
|
||||
pub semesterindex_to_first_monthindex: EagerVec<PcoVec<SemesterIndex, MonthIndex>>,
|
||||
pub semesterindex_to_monthindex_count: EagerVec<PcoVec<SemesterIndex, StoredU64>>,
|
||||
pub semesterindex_to_semesterindex: EagerVec<PcoVec<SemesterIndex, SemesterIndex>>,
|
||||
pub yearindex_to_decadeindex: EagerVec<PcoVec<YearIndex, DecadeIndex>>,
|
||||
pub yearindex_to_first_monthindex: EagerVec<PcoVec<YearIndex, MonthIndex>>,
|
||||
pub yearindex_to_monthindex_count: EagerVec<PcoVec<YearIndex, StoredU64>>,
|
||||
pub yearindex_to_yearindex: EagerVec<PcoVec<YearIndex, YearIndex>>,
|
||||
pub decadeindex_to_decadeindex: EagerVec<PcoVec<DecadeIndex, DecadeIndex>>,
|
||||
pub decadeindex_to_first_yearindex: EagerVec<PcoVec<DecadeIndex, YearIndex>>,
|
||||
pub decadeindex_to_yearindex_count: EagerVec<PcoVec<DecadeIndex, StoredU64>>,
|
||||
}
|
||||
|
||||
pub struct StartingTimeIndexes {
|
||||
pub dateindex: DateIndex,
|
||||
pub weekindex: WeekIndex,
|
||||
pub monthindex: MonthIndex,
|
||||
pub quarterindex: QuarterIndex,
|
||||
pub semesterindex: SemesterIndex,
|
||||
pub yearindex: YearIndex,
|
||||
pub decadeindex: DecadeIndex,
|
||||
}
|
||||
25
crates/brk_computer/src/indexes/transaction/compute.rs
Normal file
25
crates/brk_computer/src/indexes/transaction/compute.rs
Normal file
@@ -0,0 +1,25 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(&mut self, indexer: &Indexer, starting_indexes: &brk_indexer::Indexes, exit: &Exit) -> Result<()> {
|
||||
self.txindex_to_input_count.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txinindex,
|
||||
&indexer.vecs.txin.txinindex_to_outpoint,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.txindex_to_output_count.compute_count_from_indexes(
|
||||
starting_indexes.txindex,
|
||||
&indexer.vecs.tx.txindex_to_first_txoutindex,
|
||||
&indexer.vecs.txout.txoutindex_to_value,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
33
crates/brk_computer/src/indexes/transaction/import.rs
Normal file
33
crates/brk_computer/src/indexes/transaction/import.rs
Normal file
@@ -0,0 +1,33 @@
|
||||
use brk_error::Result;
|
||||
use brk_indexer::Indexer;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec, IterableCloneableVec, LazyVecFrom1};
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(db: &Database, version: Version, indexer: &Indexer) -> Result<Self> {
|
||||
Ok(Self {
|
||||
txindex_to_input_count: EagerVec::forced_import(db, "input_count", version)?,
|
||||
txindex_to_output_count: EagerVec::forced_import(db, "output_count", version)?,
|
||||
txindex_to_txindex: LazyVecFrom1::init(
|
||||
"txindex",
|
||||
version,
|
||||
indexer.vecs.tx.txindex_to_txid.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
txinindex_to_txinindex: LazyVecFrom1::init(
|
||||
"txinindex",
|
||||
version,
|
||||
indexer.vecs.txin.txinindex_to_outpoint.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
txoutindex_to_txoutindex: LazyVecFrom1::init(
|
||||
"txoutindex",
|
||||
version,
|
||||
indexer.vecs.txout.txoutindex_to_value.boxed_clone(),
|
||||
|index, _| Some(index),
|
||||
),
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/indexes/transaction/mod.rs
Normal file
5
crates/brk_computer/src/indexes/transaction/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
12
crates/brk_computer/src/indexes/transaction/vecs.rs
Normal file
12
crates/brk_computer/src/indexes/transaction/vecs.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{OutPoint, Sats, StoredU64, TxInIndex, TxIndex, TxOutIndex, Txid};
|
||||
use vecdb::{EagerVec, LazyVecFrom1, PcoVec};
|
||||
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub txindex_to_input_count: EagerVec<PcoVec<TxIndex, StoredU64>>,
|
||||
pub txindex_to_output_count: EagerVec<PcoVec<TxIndex, StoredU64>>,
|
||||
pub txindex_to_txindex: LazyVecFrom1<TxIndex, TxIndex, TxIndex, Txid>,
|
||||
pub txinindex_to_txinindex: LazyVecFrom1<TxInIndex, TxInIndex, TxInIndex, OutPoint>,
|
||||
pub txoutindex_to_txoutindex: LazyVecFrom1<TxOutIndex, TxOutIndex, TxOutIndex, Sats>,
|
||||
}
|
||||
93
crates/brk_computer/src/market/ath/compute.rs
Normal file
93
crates/brk_computer/src/market/ath/compute.rs
Normal file
@@ -0,0 +1,93 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::StoredU16;
|
||||
use vecdb::{Exit, GenericStoredVec, TypedVecIterator, VecIndex};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{Indexes, price, traits::ComputeDrawdown, utils::OptionExt};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
price: &price::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.height_to_price_ath.compute_all_time_high(
|
||||
starting_indexes.height,
|
||||
&price.chainindexes_to_price_high.height,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.height_to_price_drawdown.compute_drawdown(
|
||||
starting_indexes.height,
|
||||
&price.chainindexes_to_price_close.height,
|
||||
&self.height_to_price_ath,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_price_ath
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_all_time_high(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_days_since_price_ath
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
let mut high_iter = price.timeindexes_to_price_high.dateindex.u().into_iter();
|
||||
let mut prev = None;
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_price_ath.dateindex.u(),
|
||||
|(i, ath, slf)| {
|
||||
if prev.is_none() {
|
||||
let i = i.to_usize();
|
||||
prev.replace(if i > 0 {
|
||||
slf.get_pushed_or_read_at_unwrap_once(i - 1)
|
||||
} else {
|
||||
StoredU16::default()
|
||||
});
|
||||
}
|
||||
let days = if *high_iter.get_unwrap(i) == ath {
|
||||
StoredU16::default()
|
||||
} else {
|
||||
prev.unwrap() + StoredU16::new(1)
|
||||
};
|
||||
prev.replace(days);
|
||||
(i, days)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_max_days_between_price_aths
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
let mut prev = None;
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_days_since_price_ath.dateindex.u(),
|
||||
|(i, days, slf)| {
|
||||
if prev.is_none() {
|
||||
let i = i.to_usize();
|
||||
prev.replace(if i > 0 {
|
||||
slf.get_pushed_or_read_at_unwrap_once(i - 1)
|
||||
} else {
|
||||
StoredU16::ZERO
|
||||
});
|
||||
}
|
||||
let max = prev.unwrap().max(days);
|
||||
prev.replace(max);
|
||||
(i, max)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
78
crates/brk_computer/src/market/ath/import.rs
Normal file
78
crates/brk_computer/src/market/ath/import.rs
Normal file
@@ -0,0 +1,78 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::{Database, EagerVec, ImportableVec, IterableCloneableVec};
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{
|
||||
ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, LazyVecsFromDateIndex,
|
||||
PercentageDiffCloseDollars, Source, StoredU16ToYears, VecBuilderOptions,
|
||||
},
|
||||
indexes, price,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
price: &price::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = VecBuilderOptions::default().add_last();
|
||||
|
||||
let indexes_to_price_ath = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_ath",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
let indexes_to_max_days_between_price_aths = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"max_days_between_price_aths",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
let indexes_to_max_years_between_price_aths =
|
||||
LazyVecsFromDateIndex::from_computed::<StoredU16ToYears>(
|
||||
"max_years_between_price_aths",
|
||||
version + v0,
|
||||
indexes_to_max_days_between_price_aths
|
||||
.dateindex
|
||||
.as_ref()
|
||||
.map(|v| v.boxed_clone()),
|
||||
&indexes_to_max_days_between_price_aths,
|
||||
);
|
||||
|
||||
let indexes_to_price_drawdown =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"price_drawdown",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&indexes_to_price_ath,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
height_to_price_ath: EagerVec::forced_import(db, "price_ath", version + v0)?,
|
||||
height_to_price_drawdown: EagerVec::forced_import(db, "price_drawdown", version + v0)?,
|
||||
indexes_to_price_ath,
|
||||
indexes_to_price_drawdown,
|
||||
indexes_to_days_since_price_ath: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"days_since_price_ath",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
indexes_to_max_days_between_price_aths,
|
||||
indexes_to_max_years_between_price_aths,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/market/ath/mod.rs
Normal file
5
crates/brk_computer/src/market/ath/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
19
crates/brk_computer/src/market/ath/vecs.rs
Normal file
19
crates/brk_computer/src/market/ath/vecs.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Close, Dollars, Height, StoredF32, StoredU16};
|
||||
use vecdb::{EagerVec, PcoVec};
|
||||
|
||||
use crate::grouped::{
|
||||
ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, LazyVecsFromDateIndex,
|
||||
};
|
||||
|
||||
/// All-time high related metrics
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
pub height_to_price_ath: EagerVec<PcoVec<Height, Dollars>>,
|
||||
pub height_to_price_drawdown: EagerVec<PcoVec<Height, StoredF32>>,
|
||||
pub indexes_to_price_ath: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub indexes_to_price_drawdown: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub indexes_to_days_since_price_ath: ComputedVecsFromDateIndex<StoredU16>,
|
||||
pub indexes_to_max_days_between_price_aths: ComputedVecsFromDateIndex<StoredU16>,
|
||||
pub indexes_to_max_years_between_price_aths: LazyVecsFromDateIndex<StoredF32, StoredU16>,
|
||||
}
|
||||
@@ -1,14 +1,8 @@
|
||||
use std::thread;
|
||||
|
||||
use brk_error::Result;
|
||||
use brk_types::{Date, DateIndex, StoredF32, StoredU16};
|
||||
use vecdb::{Exit, GenericStoredVec, TypedVecIterator, VecIndex};
|
||||
use vecdb::Exit;
|
||||
|
||||
use crate::{
|
||||
Indexes, price,
|
||||
traits::{ComputeDCAAveragePriceViaLen, ComputeDCAStackViaLen, ComputeDrawdown},
|
||||
utils::OptionExt,
|
||||
};
|
||||
use crate::{price, Indexes};
|
||||
use crate::utils::OptionExt;
|
||||
|
||||
use super::Vecs;
|
||||
|
||||
@@ -19,636 +13,30 @@ impl Vecs {
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.compute_(price, starting_indexes, exit)?;
|
||||
// ATH metrics (independent)
|
||||
self.ath.compute(price, starting_indexes, exit)?;
|
||||
|
||||
// History metrics (independent)
|
||||
self.history.compute(price, starting_indexes, exit)?;
|
||||
|
||||
// Volatility metrics (depends on history._1d_price_returns)
|
||||
self.volatility.compute(
|
||||
starting_indexes,
|
||||
exit,
|
||||
self.history._1d_price_returns.dateindex.u(),
|
||||
)?;
|
||||
|
||||
// Range metrics (independent)
|
||||
self.range.compute(price, starting_indexes, exit)?;
|
||||
|
||||
// Moving average metrics (independent)
|
||||
self.moving_average.compute(price, starting_indexes, exit)?;
|
||||
|
||||
// DCA metrics
|
||||
self.dca.compute(price, starting_indexes, exit)?;
|
||||
|
||||
let _lock = exit.lock();
|
||||
self.db.compact()?;
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn compute_(
|
||||
&mut self,
|
||||
price: &price::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
self.height_to_price_ath.compute_all_time_high(
|
||||
starting_indexes.height,
|
||||
&price.chainindexes_to_price_high.height,
|
||||
exit,
|
||||
)?;
|
||||
self.height_to_price_drawdown.compute_drawdown(
|
||||
starting_indexes.height,
|
||||
&price.chainindexes_to_price_close.height,
|
||||
&self.height_to_price_ath,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_price_ath
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_all_time_high(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_days_since_price_ath
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
let mut high_iter = price.timeindexes_to_price_high.dateindex.u().into_iter();
|
||||
let mut prev = None;
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_price_ath.dateindex.u(),
|
||||
|(i, ath, slf)| {
|
||||
if prev.is_none() {
|
||||
let i = i.to_usize();
|
||||
prev.replace(if i > 0 {
|
||||
slf.get_pushed_or_read_at_unwrap_once(i - 1)
|
||||
} else {
|
||||
StoredU16::default()
|
||||
});
|
||||
}
|
||||
let days = if *high_iter.get_unwrap(i) == ath {
|
||||
StoredU16::default()
|
||||
} else {
|
||||
prev.unwrap() + StoredU16::new(1)
|
||||
};
|
||||
prev.replace(days);
|
||||
(i, days)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_max_days_between_price_aths
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
let mut prev = None;
|
||||
v.compute_transform(
|
||||
starting_indexes.dateindex,
|
||||
self.indexes_to_days_since_price_ath.dateindex.u(),
|
||||
|(i, days, slf)| {
|
||||
if prev.is_none() {
|
||||
let i = i.to_usize();
|
||||
prev.replace(if i > 0 {
|
||||
slf.get_pushed_or_read_at_unwrap_once(i - 1)
|
||||
} else {
|
||||
StoredU16::ZERO
|
||||
});
|
||||
}
|
||||
let max = prev.unwrap().max(days);
|
||||
prev.replace(max);
|
||||
(i, max)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
[
|
||||
(1, &mut self.price_1d_ago, &self._1d_price_returns, None),
|
||||
(7, &mut self.price_1w_ago, &self._1w_price_returns, None),
|
||||
(30, &mut self.price_1m_ago, &self._1m_price_returns, None),
|
||||
(
|
||||
3 * 30,
|
||||
&mut self.price_3m_ago,
|
||||
&self._3m_price_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
6 * 30,
|
||||
&mut self.price_6m_ago,
|
||||
&self._6m_price_returns,
|
||||
None,
|
||||
),
|
||||
(365, &mut self.price_1y_ago, &self._1y_price_returns, None),
|
||||
(
|
||||
2 * 365,
|
||||
&mut self.price_2y_ago,
|
||||
&self._2y_price_returns,
|
||||
Some(&mut self._2y_cagr),
|
||||
),
|
||||
(
|
||||
3 * 365,
|
||||
&mut self.price_3y_ago,
|
||||
&self._3y_price_returns,
|
||||
Some(&mut self._3y_cagr),
|
||||
),
|
||||
(
|
||||
4 * 365,
|
||||
&mut self.price_4y_ago,
|
||||
&self._4y_price_returns,
|
||||
Some(&mut self._4y_cagr),
|
||||
),
|
||||
(
|
||||
5 * 365,
|
||||
&mut self.price_5y_ago,
|
||||
&self._5y_price_returns,
|
||||
Some(&mut self._5y_cagr),
|
||||
),
|
||||
(
|
||||
6 * 365,
|
||||
&mut self.price_6y_ago,
|
||||
&self._6y_price_returns,
|
||||
Some(&mut self._6y_cagr),
|
||||
),
|
||||
(
|
||||
8 * 365,
|
||||
&mut self.price_8y_ago,
|
||||
&self._8y_price_returns,
|
||||
Some(&mut self._8y_cagr),
|
||||
),
|
||||
(
|
||||
10 * 365,
|
||||
&mut self.price_10y_ago,
|
||||
&self._10y_price_returns,
|
||||
Some(&mut self._10y_cagr),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.try_for_each(|(days, ago, returns, cagr)| -> Result<()> {
|
||||
ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_close.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
if let Some(cagr) = cagr {
|
||||
cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
returns.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
[
|
||||
(
|
||||
7,
|
||||
&mut self._1w_dca_stack,
|
||||
&mut self._1w_dca_avg_price,
|
||||
&self._1w_dca_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
30,
|
||||
&mut self._1m_dca_stack,
|
||||
&mut self._1m_dca_avg_price,
|
||||
&self._1m_dca_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
3 * 30,
|
||||
&mut self._3m_dca_stack,
|
||||
&mut self._3m_dca_avg_price,
|
||||
&self._3m_dca_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
6 * 30,
|
||||
&mut self._6m_dca_stack,
|
||||
&mut self._6m_dca_avg_price,
|
||||
&self._6m_dca_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
365,
|
||||
&mut self._1y_dca_stack,
|
||||
&mut self._1y_dca_avg_price,
|
||||
&self._1y_dca_returns,
|
||||
None,
|
||||
),
|
||||
(
|
||||
2 * 365,
|
||||
&mut self._2y_dca_stack,
|
||||
&mut self._2y_dca_avg_price,
|
||||
&self._2y_dca_returns,
|
||||
Some(&mut self._2y_dca_cagr),
|
||||
),
|
||||
(
|
||||
3 * 365,
|
||||
&mut self._3y_dca_stack,
|
||||
&mut self._3y_dca_avg_price,
|
||||
&self._3y_dca_returns,
|
||||
Some(&mut self._3y_dca_cagr),
|
||||
),
|
||||
(
|
||||
4 * 365,
|
||||
&mut self._4y_dca_stack,
|
||||
&mut self._4y_dca_avg_price,
|
||||
&self._4y_dca_returns,
|
||||
Some(&mut self._4y_dca_cagr),
|
||||
),
|
||||
(
|
||||
5 * 365,
|
||||
&mut self._5y_dca_stack,
|
||||
&mut self._5y_dca_avg_price,
|
||||
&self._5y_dca_returns,
|
||||
Some(&mut self._5y_dca_cagr),
|
||||
),
|
||||
(
|
||||
6 * 365,
|
||||
&mut self._6y_dca_stack,
|
||||
&mut self._6y_dca_avg_price,
|
||||
&self._6y_dca_returns,
|
||||
Some(&mut self._6y_dca_cagr),
|
||||
),
|
||||
(
|
||||
8 * 365,
|
||||
&mut self._8y_dca_stack,
|
||||
&mut self._8y_dca_avg_price,
|
||||
&self._8y_dca_returns,
|
||||
Some(&mut self._8y_dca_cagr),
|
||||
),
|
||||
(
|
||||
10 * 365,
|
||||
&mut self._10y_dca_stack,
|
||||
&mut self._10y_dca_avg_price,
|
||||
&self._10y_dca_returns,
|
||||
Some(&mut self._10y_dca_cagr),
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.try_for_each(
|
||||
|(days, dca_stack, dca_avg_price, dca_returns, dca_cagr)| -> Result<()> {
|
||||
dca_stack.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_close.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
dca_avg_price.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
dca_stack.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
if let Some(dca_cagr) = dca_cagr {
|
||||
dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
dca_returns.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
},
|
||||
)?;
|
||||
|
||||
[
|
||||
(
|
||||
2015,
|
||||
&mut self.dca_class_2015_avg_price,
|
||||
&mut self.dca_class_2015_stack,
|
||||
),
|
||||
(
|
||||
2016,
|
||||
&mut self.dca_class_2016_avg_price,
|
||||
&mut self.dca_class_2016_stack,
|
||||
),
|
||||
(
|
||||
2017,
|
||||
&mut self.dca_class_2017_avg_price,
|
||||
&mut self.dca_class_2017_stack,
|
||||
),
|
||||
(
|
||||
2018,
|
||||
&mut self.dca_class_2018_avg_price,
|
||||
&mut self.dca_class_2018_stack,
|
||||
),
|
||||
(
|
||||
2019,
|
||||
&mut self.dca_class_2019_avg_price,
|
||||
&mut self.dca_class_2019_stack,
|
||||
),
|
||||
(
|
||||
2020,
|
||||
&mut self.dca_class_2020_avg_price,
|
||||
&mut self.dca_class_2020_stack,
|
||||
),
|
||||
(
|
||||
2021,
|
||||
&mut self.dca_class_2021_avg_price,
|
||||
&mut self.dca_class_2021_stack,
|
||||
),
|
||||
(
|
||||
2022,
|
||||
&mut self.dca_class_2022_avg_price,
|
||||
&mut self.dca_class_2022_stack,
|
||||
),
|
||||
(
|
||||
2023,
|
||||
&mut self.dca_class_2023_avg_price,
|
||||
&mut self.dca_class_2023_stack,
|
||||
),
|
||||
(
|
||||
2024,
|
||||
&mut self.dca_class_2024_avg_price,
|
||||
&mut self.dca_class_2024_stack,
|
||||
),
|
||||
(
|
||||
2025,
|
||||
&mut self.dca_class_2025_avg_price,
|
||||
&mut self.dca_class_2025_stack,
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.try_for_each(|(year, avg_price, stack)| -> Result<()> {
|
||||
let dateindex = DateIndex::try_from(Date::new(year, 1, 1)).unwrap();
|
||||
|
||||
stack.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_from(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_close.dateindex.u(),
|
||||
dateindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
avg_price.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_from(
|
||||
starting_indexes.dateindex,
|
||||
stack.dateindex.u(),
|
||||
dateindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
thread::scope(|s| -> Result<()> {
|
||||
[
|
||||
(
|
||||
&mut self.indexes_to_price_1w_sma,
|
||||
&mut self.indexes_to_price_1w_ema,
|
||||
7,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_8d_sma,
|
||||
&mut self.indexes_to_price_8d_ema,
|
||||
8,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_13d_sma,
|
||||
&mut self.indexes_to_price_13d_ema,
|
||||
13,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_21d_sma,
|
||||
&mut self.indexes_to_price_21d_ema,
|
||||
21,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_1m_sma,
|
||||
&mut self.indexes_to_price_1m_ema,
|
||||
30,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_34d_sma,
|
||||
&mut self.indexes_to_price_34d_ema,
|
||||
34,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_55d_sma,
|
||||
&mut self.indexes_to_price_55d_ema,
|
||||
55,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_89d_sma,
|
||||
&mut self.indexes_to_price_89d_ema,
|
||||
89,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_144d_sma,
|
||||
&mut self.indexes_to_price_144d_ema,
|
||||
144,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_200d_sma,
|
||||
&mut self.indexes_to_price_200d_ema,
|
||||
200,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_1y_sma,
|
||||
&mut self.indexes_to_price_1y_ema,
|
||||
365,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_2y_sma,
|
||||
&mut self.indexes_to_price_2y_ema,
|
||||
2 * 365,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_200w_sma,
|
||||
&mut self.indexes_to_price_200w_ema,
|
||||
200 * 7,
|
||||
),
|
||||
(
|
||||
&mut self.indexes_to_price_4y_sma,
|
||||
&mut self.indexes_to_price_4y_ema,
|
||||
4 * 365,
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.for_each(|(sma, ema, days)| {
|
||||
s.spawn(move || -> Result<()> {
|
||||
sma.compute_all(price, starting_indexes, exit, |v| {
|
||||
v.compute_sma(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_close.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
ema.compute_all(price, starting_indexes, exit, |v| {
|
||||
v.compute_ema(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_close.dateindex.u(),
|
||||
days,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})
|
||||
});
|
||||
});
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_1d_returns_1w_sd.compute_all(
|
||||
starting_indexes,
|
||||
exit,
|
||||
self._1d_price_returns.dateindex.u(),
|
||||
)?;
|
||||
self.indexes_to_1d_returns_1m_sd.compute_all(
|
||||
starting_indexes,
|
||||
exit,
|
||||
self._1d_price_returns.dateindex.u(),
|
||||
)?;
|
||||
self.indexes_to_1d_returns_1y_sd.compute_all(
|
||||
starting_indexes,
|
||||
exit,
|
||||
self._1d_price_returns.dateindex.u(),
|
||||
)?;
|
||||
|
||||
self.dateindex_to_price_true_range.compute_transform3(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_open.dateindex.u(),
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
price.timeindexes_to_price_low.dateindex.u(),
|
||||
|(i, open, high, low, ..)| {
|
||||
let high_min_low = **high - **low;
|
||||
let high_min_open = (**high - **open).abs();
|
||||
let low_min_open = (**low - **open).abs();
|
||||
(i, high_min_low.max(high_min_open).max(low_min_open).into())
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.dateindex_to_price_true_range_2w_sum.compute_sum(
|
||||
starting_indexes.dateindex,
|
||||
&self.dateindex_to_price_true_range,
|
||||
14,
|
||||
exit,
|
||||
)?;
|
||||
|
||||
self.indexes_to_price_1w_max
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_max(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
7,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_1w_min
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_min(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_low.dateindex.u(),
|
||||
7,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_2w_max
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_max(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
14,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_2w_min
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_min(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_low.dateindex.u(),
|
||||
14,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_1m_max
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_max(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_1m_min
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_min(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_low.dateindex.u(),
|
||||
30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_1y_max
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_max(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_high.dateindex.u(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_1y_min
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_min(
|
||||
starting_indexes.dateindex,
|
||||
price.timeindexes_to_price_low.dateindex.u(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.indexes_to_price_2w_choppiness_index
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
let n = 14;
|
||||
let log10n = (n as f32).log10();
|
||||
v.compute_transform3(
|
||||
starting_indexes.dateindex,
|
||||
&self.dateindex_to_price_true_range_2w_sum,
|
||||
self.indexes_to_price_2w_max.dateindex.u(),
|
||||
self.indexes_to_price_2w_min.dateindex.u(),
|
||||
|(i, tr_sum, max, min, ..)| {
|
||||
(
|
||||
i,
|
||||
StoredF32::from(
|
||||
100.0 * (*tr_sum / (*max - *min) as f32).log10() / log10n,
|
||||
),
|
||||
)
|
||||
},
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
364
crates/brk_computer/src/market/dca/compute.rs
Normal file
364
crates/brk_computer/src/market/dca/compute.rs
Normal file
@@ -0,0 +1,364 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::{Date, DateIndex};
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
price,
|
||||
traits::{ComputeDCAAveragePriceViaLen, ComputeDCAStackViaLen},
|
||||
utils::OptionExt,
|
||||
Indexes,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
price: &price::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let close = price.timeindexes_to_price_close.dateindex.u();
|
||||
|
||||
// DCA by period - stack and avg_price
|
||||
self._1w_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 7, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._1w_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._1w_dca_stack.dateindex.u(),
|
||||
7,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._1m_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._1m_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._1m_dca_stack.dateindex.u(),
|
||||
30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._3m_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 3 * 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._3m_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._3m_dca_stack.dateindex.u(),
|
||||
3 * 30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._6m_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 6 * 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._6m_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._6m_dca_stack.dateindex.u(),
|
||||
6 * 30,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._1y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._1y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._1y_dca_stack.dateindex.u(),
|
||||
365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._2y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 2 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._2y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._2y_dca_stack.dateindex.u(),
|
||||
2 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._3y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 3 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._3y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._3y_dca_stack.dateindex.u(),
|
||||
3 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._4y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 4 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._4y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._4y_dca_stack.dateindex.u(),
|
||||
4 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._5y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 5 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._5y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._5y_dca_stack.dateindex.u(),
|
||||
5 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._6y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 6 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._6y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._6y_dca_stack.dateindex.u(),
|
||||
6 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._8y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 8 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._8y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._8y_dca_stack.dateindex.u(),
|
||||
8 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self._10y_dca_stack
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_len(starting_indexes.dateindex, close, 10 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._10y_dca_avg_price
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_len(
|
||||
starting_indexes.dateindex,
|
||||
self._10y_dca_stack.dateindex.u(),
|
||||
10 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// DCA by period - CAGR (computed from returns)
|
||||
self._2y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._2y_dca_returns.dateindex.u(),
|
||||
2 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._3y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._3y_dca_returns.dateindex.u(),
|
||||
3 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._4y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._4y_dca_returns.dateindex.u(),
|
||||
4 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._5y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._5y_dca_returns.dateindex.u(),
|
||||
5 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._6y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._6y_dca_returns.dateindex.u(),
|
||||
6 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._8y_dca_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._8y_dca_returns.dateindex.u(),
|
||||
8 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._10y_dca_cagr
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._10y_dca_returns.dateindex.u(),
|
||||
10 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// DCA by year class - stack and avg_price
|
||||
// Each year class computes DCA from Jan 1 of that year
|
||||
[
|
||||
(
|
||||
2025,
|
||||
&mut self.dca_class_2025_stack,
|
||||
&mut self.dca_class_2025_avg_price,
|
||||
),
|
||||
(
|
||||
2024,
|
||||
&mut self.dca_class_2024_stack,
|
||||
&mut self.dca_class_2024_avg_price,
|
||||
),
|
||||
(
|
||||
2023,
|
||||
&mut self.dca_class_2023_stack,
|
||||
&mut self.dca_class_2023_avg_price,
|
||||
),
|
||||
(
|
||||
2022,
|
||||
&mut self.dca_class_2022_stack,
|
||||
&mut self.dca_class_2022_avg_price,
|
||||
),
|
||||
(
|
||||
2021,
|
||||
&mut self.dca_class_2021_stack,
|
||||
&mut self.dca_class_2021_avg_price,
|
||||
),
|
||||
(
|
||||
2020,
|
||||
&mut self.dca_class_2020_stack,
|
||||
&mut self.dca_class_2020_avg_price,
|
||||
),
|
||||
(
|
||||
2019,
|
||||
&mut self.dca_class_2019_stack,
|
||||
&mut self.dca_class_2019_avg_price,
|
||||
),
|
||||
(
|
||||
2018,
|
||||
&mut self.dca_class_2018_stack,
|
||||
&mut self.dca_class_2018_avg_price,
|
||||
),
|
||||
(
|
||||
2017,
|
||||
&mut self.dca_class_2017_stack,
|
||||
&mut self.dca_class_2017_avg_price,
|
||||
),
|
||||
(
|
||||
2016,
|
||||
&mut self.dca_class_2016_stack,
|
||||
&mut self.dca_class_2016_avg_price,
|
||||
),
|
||||
(
|
||||
2015,
|
||||
&mut self.dca_class_2015_stack,
|
||||
&mut self.dca_class_2015_avg_price,
|
||||
),
|
||||
]
|
||||
.into_iter()
|
||||
.try_for_each(|(year, stack, avg_price)| -> Result<()> {
|
||||
let dateindex = DateIndex::try_from(Date::new(year, 1, 1)).unwrap();
|
||||
|
||||
stack.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_stack_via_from(starting_indexes.dateindex, close, dateindex, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
avg_price.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_dca_avg_price_via_from(
|
||||
starting_indexes.dateindex,
|
||||
stack.dateindex.u(),
|
||||
dateindex,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
697
crates/brk_computer/src/market/dca/import.rs
Normal file
697
crates/brk_computer/src/market/dca/import.rs
Normal file
@@ -0,0 +1,697 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{
|
||||
ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, PercentageDiffCloseDollars, Source,
|
||||
VecBuilderOptions,
|
||||
},
|
||||
indexes, price,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
price: &price::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = VecBuilderOptions::default().add_last();
|
||||
|
||||
// DCA by period - stack
|
||||
let _1w_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1w_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _1m_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1m_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _3m_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3m_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _6m_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6m_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _1y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _2y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"2y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _3y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _4y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"4y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _5y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"5y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _6y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _8y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"8y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _10y_dca_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"10y_dca_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
// DCA by period - avg price
|
||||
let _1w_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1w_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _1m_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1m_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _3m_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3m_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _6m_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6m_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _1y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"1y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _2y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"2y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _3y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _4y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"4y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _5y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"5y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _6y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _8y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"8y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _10y_dca_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"10y_dca_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
// DCA by period - returns (lazy)
|
||||
let _1w_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1w_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_1w_dca_avg_price,
|
||||
);
|
||||
let _1m_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1m_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_1m_dca_avg_price,
|
||||
);
|
||||
let _3m_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"3m_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_3m_dca_avg_price,
|
||||
);
|
||||
let _6m_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"6m_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_6m_dca_avg_price,
|
||||
);
|
||||
let _1y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_1y_dca_avg_price,
|
||||
);
|
||||
let _2y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"2y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_2y_dca_avg_price,
|
||||
);
|
||||
let _3y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"3y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_3y_dca_avg_price,
|
||||
);
|
||||
let _4y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"4y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_4y_dca_avg_price,
|
||||
);
|
||||
let _5y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"5y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_5y_dca_avg_price,
|
||||
);
|
||||
let _6y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"6y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_6y_dca_avg_price,
|
||||
);
|
||||
let _8y_dca_returns = LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"8y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_8y_dca_avg_price,
|
||||
);
|
||||
let _10y_dca_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"10y_dca_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&_10y_dca_avg_price,
|
||||
);
|
||||
|
||||
// DCA by period - CAGR
|
||||
let _2y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"2y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _3y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _4y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"4y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _5y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"5y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _6y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _8y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"8y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let _10y_dca_cagr = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"10y_dca_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
// DCA by year class - stack
|
||||
let dca_class_2025_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2025_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2024_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2024_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2023_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2023_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2022_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2022_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2021_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2021_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2020_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2020_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2019_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2019_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2018_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2018_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2017_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2017_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2016_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2016_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2015_stack = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2015_stack",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
// DCA by year class - avg price
|
||||
let dca_class_2025_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2025_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2024_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2024_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2023_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2023_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2022_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2022_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2021_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2021_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2020_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2020_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2019_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2019_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2018_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2018_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2017_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2017_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2016_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2016_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let dca_class_2015_avg_price = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"dca_class_2015_avg_price",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
// DCA by year class - returns (lazy)
|
||||
let dca_class_2025_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2025_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2025_avg_price,
|
||||
);
|
||||
let dca_class_2024_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2024_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2024_avg_price,
|
||||
);
|
||||
let dca_class_2023_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2023_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2023_avg_price,
|
||||
);
|
||||
let dca_class_2022_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2022_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2022_avg_price,
|
||||
);
|
||||
let dca_class_2021_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2021_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2021_avg_price,
|
||||
);
|
||||
let dca_class_2020_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2020_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2020_avg_price,
|
||||
);
|
||||
let dca_class_2019_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2019_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2019_avg_price,
|
||||
);
|
||||
let dca_class_2018_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2018_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2018_avg_price,
|
||||
);
|
||||
let dca_class_2017_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2017_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2017_avg_price,
|
||||
);
|
||||
let dca_class_2016_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2016_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2016_avg_price,
|
||||
);
|
||||
let dca_class_2015_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"dca_class_2015_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&dca_class_2015_avg_price,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
_1w_dca_stack,
|
||||
_1m_dca_stack,
|
||||
_3m_dca_stack,
|
||||
_6m_dca_stack,
|
||||
_1y_dca_stack,
|
||||
_2y_dca_stack,
|
||||
_3y_dca_stack,
|
||||
_4y_dca_stack,
|
||||
_5y_dca_stack,
|
||||
_6y_dca_stack,
|
||||
_8y_dca_stack,
|
||||
_10y_dca_stack,
|
||||
|
||||
_1w_dca_avg_price,
|
||||
_1m_dca_avg_price,
|
||||
_3m_dca_avg_price,
|
||||
_6m_dca_avg_price,
|
||||
_1y_dca_avg_price,
|
||||
_2y_dca_avg_price,
|
||||
_3y_dca_avg_price,
|
||||
_4y_dca_avg_price,
|
||||
_5y_dca_avg_price,
|
||||
_6y_dca_avg_price,
|
||||
_8y_dca_avg_price,
|
||||
_10y_dca_avg_price,
|
||||
|
||||
_1w_dca_returns,
|
||||
_1m_dca_returns,
|
||||
_3m_dca_returns,
|
||||
_6m_dca_returns,
|
||||
_1y_dca_returns,
|
||||
_2y_dca_returns,
|
||||
_3y_dca_returns,
|
||||
_4y_dca_returns,
|
||||
_5y_dca_returns,
|
||||
_6y_dca_returns,
|
||||
_8y_dca_returns,
|
||||
_10y_dca_returns,
|
||||
|
||||
_2y_dca_cagr,
|
||||
_3y_dca_cagr,
|
||||
_4y_dca_cagr,
|
||||
_5y_dca_cagr,
|
||||
_6y_dca_cagr,
|
||||
_8y_dca_cagr,
|
||||
_10y_dca_cagr,
|
||||
|
||||
dca_class_2025_stack,
|
||||
dca_class_2024_stack,
|
||||
dca_class_2023_stack,
|
||||
dca_class_2022_stack,
|
||||
dca_class_2021_stack,
|
||||
dca_class_2020_stack,
|
||||
dca_class_2019_stack,
|
||||
dca_class_2018_stack,
|
||||
dca_class_2017_stack,
|
||||
dca_class_2016_stack,
|
||||
dca_class_2015_stack,
|
||||
|
||||
dca_class_2025_avg_price,
|
||||
dca_class_2024_avg_price,
|
||||
dca_class_2023_avg_price,
|
||||
dca_class_2022_avg_price,
|
||||
dca_class_2021_avg_price,
|
||||
dca_class_2020_avg_price,
|
||||
dca_class_2019_avg_price,
|
||||
dca_class_2018_avg_price,
|
||||
dca_class_2017_avg_price,
|
||||
dca_class_2016_avg_price,
|
||||
dca_class_2015_avg_price,
|
||||
|
||||
dca_class_2025_returns,
|
||||
dca_class_2024_returns,
|
||||
dca_class_2023_returns,
|
||||
dca_class_2022_returns,
|
||||
dca_class_2021_returns,
|
||||
dca_class_2020_returns,
|
||||
dca_class_2019_returns,
|
||||
dca_class_2018_returns,
|
||||
dca_class_2017_returns,
|
||||
dca_class_2016_returns,
|
||||
dca_class_2015_returns,
|
||||
})
|
||||
}
|
||||
}
|
||||
5
crates/brk_computer/src/market/dca/mod.rs
Normal file
5
crates/brk_computer/src/market/dca/mod.rs
Normal file
@@ -0,0 +1,5 @@
|
||||
mod compute;
|
||||
mod import;
|
||||
mod vecs;
|
||||
|
||||
pub use vecs::Vecs;
|
||||
98
crates/brk_computer/src/market/dca/vecs.rs
Normal file
98
crates/brk_computer/src/market/dca/vecs.rs
Normal file
@@ -0,0 +1,98 @@
|
||||
use brk_traversable::Traversable;
|
||||
use brk_types::{Close, Dollars, Sats, StoredF32};
|
||||
|
||||
use crate::grouped::{ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex};
|
||||
|
||||
/// Dollar-cost averaging metrics by time period and year class
|
||||
#[derive(Clone, Traversable)]
|
||||
pub struct Vecs {
|
||||
// DCA by period - stack
|
||||
pub _1w_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _1m_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _3m_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _6m_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _1y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _2y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _3y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _4y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _5y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _6y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _8y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub _10y_dca_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
|
||||
// DCA by period - avg price
|
||||
pub _1w_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _1m_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _3m_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _6m_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _1y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _2y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _3y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _4y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _5y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _6y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _8y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub _10y_dca_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
|
||||
// DCA by period - returns (lazy)
|
||||
pub _1w_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _1m_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _3m_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _6m_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _1y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _2y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _3y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _4y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _5y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _6y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _8y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub _10y_dca_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
|
||||
// DCA by period - CAGR
|
||||
pub _2y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _3y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _4y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _5y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _6y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _8y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
pub _10y_dca_cagr: ComputedVecsFromDateIndex<StoredF32>,
|
||||
|
||||
// DCA by year class - stack
|
||||
pub dca_class_2025_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2024_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2023_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2022_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2021_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2020_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2019_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2018_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2017_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2016_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
pub dca_class_2015_stack: ComputedVecsFromDateIndex<Sats>,
|
||||
|
||||
// DCA by year class - avg price
|
||||
pub dca_class_2025_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2024_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2023_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2022_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2021_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2020_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2019_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2018_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2017_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2016_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
pub dca_class_2015_avg_price: ComputedVecsFromDateIndex<Dollars>,
|
||||
|
||||
// DCA by year class - returns (lazy)
|
||||
pub dca_class_2025_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2024_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2023_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2022_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2021_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2020_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2019_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2018_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2017_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2016_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
pub dca_class_2015_returns: LazyVecsFrom2FromDateIndex<StoredF32, Close<Dollars>, Dollars>,
|
||||
}
|
||||
149
crates/brk_computer/src/market/history/compute.rs
Normal file
149
crates/brk_computer/src/market/history/compute.rs
Normal file
@@ -0,0 +1,149 @@
|
||||
use brk_error::Result;
|
||||
use vecdb::Exit;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{price, utils::OptionExt, Indexes};
|
||||
|
||||
impl Vecs {
|
||||
pub fn compute(
|
||||
&mut self,
|
||||
price: &price::Vecs,
|
||||
starting_indexes: &Indexes,
|
||||
exit: &Exit,
|
||||
) -> Result<()> {
|
||||
let close = price.timeindexes_to_price_close.dateindex.u();
|
||||
|
||||
self.price_1d_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 1, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_1w_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 7, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_1m_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_3m_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 3 * 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_6m_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 6 * 30, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_1y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_2y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 2 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_3y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 3 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_4y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 4 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_5y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 5 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_6y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 6 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_8y_ago.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 8 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
self.price_10y_ago
|
||||
.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_previous_value(starting_indexes.dateindex, close, 10 * 365, exit)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
// CAGR computed from returns
|
||||
self._2y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._2y_price_returns.dateindex.u(),
|
||||
2 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._3y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._3y_price_returns.dateindex.u(),
|
||||
3 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._4y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._4y_price_returns.dateindex.u(),
|
||||
4 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._5y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._5y_price_returns.dateindex.u(),
|
||||
5 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._6y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._6y_price_returns.dateindex.u(),
|
||||
6 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._8y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._8y_price_returns.dateindex.u(),
|
||||
8 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
self._10y_cagr.compute_all(starting_indexes, exit, |v| {
|
||||
v.compute_cagr(
|
||||
starting_indexes.dateindex,
|
||||
self._10y_price_returns.dateindex.u(),
|
||||
10 * 365,
|
||||
exit,
|
||||
)?;
|
||||
Ok(())
|
||||
})?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
308
crates/brk_computer/src/market/history/import.rs
Normal file
308
crates/brk_computer/src/market/history/import.rs
Normal file
@@ -0,0 +1,308 @@
|
||||
use brk_error::Result;
|
||||
use brk_types::Version;
|
||||
use vecdb::Database;
|
||||
|
||||
use super::Vecs;
|
||||
use crate::{
|
||||
grouped::{
|
||||
ComputedVecsFromDateIndex, LazyVecsFrom2FromDateIndex, PercentageDiffCloseDollars, Source,
|
||||
VecBuilderOptions,
|
||||
},
|
||||
indexes, price,
|
||||
};
|
||||
|
||||
impl Vecs {
|
||||
pub fn forced_import(
|
||||
db: &Database,
|
||||
version: Version,
|
||||
indexes: &indexes::Vecs,
|
||||
price: &price::Vecs,
|
||||
) -> Result<Self> {
|
||||
let v0 = Version::ZERO;
|
||||
let last = VecBuilderOptions::default().add_last();
|
||||
|
||||
let price_1d_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_1d_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_1w_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_1w_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_1m_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_1m_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_3m_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_3m_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_6m_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_6m_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_1y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_1y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_2y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_2y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_3y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_3y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_4y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_4y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_5y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_5y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_6y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_6y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_8y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_8y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
let price_10y_ago = ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"price_10y_ago",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?;
|
||||
|
||||
let _1d_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1d_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_1d_ago,
|
||||
);
|
||||
let _1w_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1w_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_1w_ago,
|
||||
);
|
||||
let _1m_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1m_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_1m_ago,
|
||||
);
|
||||
let _3m_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"3m_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_3m_ago,
|
||||
);
|
||||
let _6m_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"6m_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_6m_ago,
|
||||
);
|
||||
let _1y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"1y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_1y_ago,
|
||||
);
|
||||
let _2y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"2y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_2y_ago,
|
||||
);
|
||||
let _3y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"3y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_3y_ago,
|
||||
);
|
||||
let _4y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"4y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_4y_ago,
|
||||
);
|
||||
let _5y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"5y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_5y_ago,
|
||||
);
|
||||
let _6y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"6y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_6y_ago,
|
||||
);
|
||||
let _8y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"8y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_8y_ago,
|
||||
);
|
||||
let _10y_price_returns =
|
||||
LazyVecsFrom2FromDateIndex::from_computed::<PercentageDiffCloseDollars>(
|
||||
"10y_price_returns",
|
||||
version + v0,
|
||||
&price.timeindexes_to_price_close,
|
||||
&price_10y_ago,
|
||||
);
|
||||
|
||||
Ok(Self {
|
||||
price_1d_ago,
|
||||
price_1w_ago,
|
||||
price_1m_ago,
|
||||
price_3m_ago,
|
||||
price_6m_ago,
|
||||
price_1y_ago,
|
||||
price_2y_ago,
|
||||
price_3y_ago,
|
||||
price_4y_ago,
|
||||
price_5y_ago,
|
||||
price_6y_ago,
|
||||
price_8y_ago,
|
||||
price_10y_ago,
|
||||
|
||||
_1d_price_returns,
|
||||
_1w_price_returns,
|
||||
_1m_price_returns,
|
||||
_3m_price_returns,
|
||||
_6m_price_returns,
|
||||
_1y_price_returns,
|
||||
_2y_price_returns,
|
||||
_3y_price_returns,
|
||||
_4y_price_returns,
|
||||
_5y_price_returns,
|
||||
_6y_price_returns,
|
||||
_8y_price_returns,
|
||||
_10y_price_returns,
|
||||
|
||||
_2y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"2y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_3y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"3y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_4y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"4y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_5y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"5y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_6y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"6y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_8y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"8y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
_10y_cagr: ComputedVecsFromDateIndex::forced_import(
|
||||
db,
|
||||
"10y_cagr",
|
||||
Source::Compute,
|
||||
version + v0,
|
||||
indexes,
|
||||
last,
|
||||
)?,
|
||||
})
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user