mirror of
https://github.com/bitcoinresearchkit/brk.git
synced 2026-04-25 07:09:59 -07:00
parser: add recap dataset
This commit is contained in:
@@ -4,24 +4,23 @@ use std::{
|
||||
};
|
||||
|
||||
use allocative::Allocative;
|
||||
use ordered_float::FloatCore;
|
||||
|
||||
use crate::{bitcoin::TARGET_BLOCKS_PER_DAY, utils::LossyFrom};
|
||||
|
||||
use super::{AnyDateMap, AnyHeightMap, AnyMap, Date, DateMap, Height, HeightMap, MapValue};
|
||||
|
||||
#[derive(Default, Allocative)]
|
||||
pub struct BiMap<T>
|
||||
pub struct BiMap<Value>
|
||||
where
|
||||
T: MapValue,
|
||||
Value: MapValue,
|
||||
{
|
||||
pub height: HeightMap<T>,
|
||||
pub date: DateMap<T>,
|
||||
pub height: HeightMap<Value>,
|
||||
pub date: DateMap<Value>,
|
||||
}
|
||||
|
||||
impl<T> BiMap<T>
|
||||
impl<Value> BiMap<Value>
|
||||
where
|
||||
T: MapValue,
|
||||
Value: MapValue,
|
||||
{
|
||||
pub fn new_bin(version: u32, path: &str) -> Self {
|
||||
Self {
|
||||
@@ -39,7 +38,7 @@ where
|
||||
|
||||
pub fn date_insert_sum_range(&mut self, date: Date, date_blocks_range: &RangeInclusive<u32>)
|
||||
where
|
||||
T: Sum,
|
||||
Value: Sum,
|
||||
{
|
||||
self.date
|
||||
.insert(date, self.height.sum_range(date_blocks_range));
|
||||
@@ -51,7 +50,7 @@ where
|
||||
first_height: &mut DateMap<Height>,
|
||||
last_height: &mut DateMap<Height>,
|
||||
) where
|
||||
T: Sum,
|
||||
Value: Sum,
|
||||
{
|
||||
dates.iter().for_each(|date| {
|
||||
let first_height = first_height.get_or_import(date).unwrap();
|
||||
@@ -62,7 +61,7 @@ where
|
||||
})
|
||||
}
|
||||
|
||||
pub fn multi_insert_const(&mut self, heights: &[Height], dates: &[Date], constant: T) {
|
||||
pub fn multi_insert_const(&mut self, heights: &[Height], dates: &[Date], constant: Value) {
|
||||
self.height.multi_insert_const(heights, constant);
|
||||
|
||||
self.date.multi_insert_const(dates, constant);
|
||||
@@ -75,8 +74,8 @@ where
|
||||
source: &mut BiMap<K>,
|
||||
transform: &F,
|
||||
) where
|
||||
T: Div<Output = T>,
|
||||
F: Fn(K) -> T,
|
||||
Value: Div<Output = Value>,
|
||||
F: Fn(K) -> Value,
|
||||
K: MapValue,
|
||||
{
|
||||
self.height
|
||||
@@ -95,8 +94,8 @@ where
|
||||
) where
|
||||
A: MapValue,
|
||||
B: MapValue,
|
||||
T: LossyFrom<A> + LossyFrom<B>,
|
||||
T: Add<Output = T>,
|
||||
Value: LossyFrom<A> + LossyFrom<B>,
|
||||
Value: Add<Output = Value>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_add(heights, &mut added.height, &mut adder.height);
|
||||
@@ -113,8 +112,8 @@ where
|
||||
) where
|
||||
A: MapValue,
|
||||
B: MapValue,
|
||||
T: LossyFrom<A> + LossyFrom<B>,
|
||||
T: Sub<Output = T>,
|
||||
Value: LossyFrom<A> + LossyFrom<B>,
|
||||
Value: Sub<Output = Value>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_subtract(heights, &mut subtracted.height, &mut subtracter.height);
|
||||
@@ -132,8 +131,8 @@ where
|
||||
) where
|
||||
A: MapValue,
|
||||
B: MapValue,
|
||||
T: LossyFrom<A> + LossyFrom<B>,
|
||||
T: Mul<Output = T>,
|
||||
Value: LossyFrom<A> + LossyFrom<B>,
|
||||
Value: Mul<Output = Value>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_multiply(heights, &mut multiplied.height, &mut multiplier.height);
|
||||
@@ -150,8 +149,8 @@ where
|
||||
) where
|
||||
A: MapValue,
|
||||
B: MapValue,
|
||||
T: LossyFrom<A> + LossyFrom<B>,
|
||||
T: Div<Output = T> + Mul<Output = T> + From<u8>,
|
||||
Value: LossyFrom<A> + LossyFrom<B>,
|
||||
Value: Div<Output = Value> + Mul<Output = Value> + From<u8>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_divide(heights, &mut divided.height, &mut divider.height);
|
||||
@@ -168,8 +167,8 @@ where
|
||||
) where
|
||||
A: MapValue,
|
||||
B: MapValue,
|
||||
T: LossyFrom<A> + LossyFrom<B>,
|
||||
T: Div<Output = T> + Mul<Output = T> + From<u8>,
|
||||
Value: LossyFrom<A> + LossyFrom<B>,
|
||||
Value: Div<Output = Value> + Mul<Output = Value> + From<u8>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_percentage(heights, &mut divided.height, &mut divider.height);
|
||||
@@ -184,8 +183,8 @@ where
|
||||
source: &mut BiMap<K>,
|
||||
) where
|
||||
K: MapValue,
|
||||
T: LossyFrom<K>,
|
||||
T: Add<Output = T> + Sub<Output = T>,
|
||||
Value: LossyFrom<K>,
|
||||
Value: Add<Output = Value> + Sub<Output = Value>,
|
||||
{
|
||||
self.height
|
||||
.multi_insert_cumulative(heights, &mut source.height);
|
||||
@@ -201,8 +200,8 @@ where
|
||||
days: usize,
|
||||
) where
|
||||
K: MapValue,
|
||||
T: LossyFrom<K>,
|
||||
T: Add<Output = T> + Sub<Output = T>,
|
||||
Value: LossyFrom<K>,
|
||||
Value: Add<Output = Value> + Sub<Output = Value>,
|
||||
{
|
||||
self.height.multi_insert_last_x_sum(
|
||||
heights,
|
||||
@@ -221,7 +220,7 @@ where
|
||||
source: &mut BiMap<K>,
|
||||
days: usize,
|
||||
) where
|
||||
T: Into<f32> + From<f32>,
|
||||
Value: Into<f32> + From<f32>,
|
||||
K: MapValue + Sum,
|
||||
f32: LossyFrom<K>,
|
||||
{
|
||||
@@ -238,10 +237,10 @@ where
|
||||
&mut self,
|
||||
heights: &[Height],
|
||||
dates: &[Date],
|
||||
source: &mut BiMap<T>,
|
||||
source: &mut BiMap<Value>,
|
||||
days: usize,
|
||||
) where
|
||||
T: Sub<Output = T>,
|
||||
Value: Sub<Output = Value>,
|
||||
{
|
||||
self.height.multi_insert_net_change(
|
||||
heights,
|
||||
@@ -256,10 +255,11 @@ where
|
||||
&mut self,
|
||||
heights: &[Height],
|
||||
dates: &[Date],
|
||||
source: &mut BiMap<T>,
|
||||
source: &mut BiMap<Value>,
|
||||
days: Option<usize>,
|
||||
) where
|
||||
T: FloatCore,
|
||||
Value: LossyFrom<f32>,
|
||||
f32: LossyFrom<Value>,
|
||||
{
|
||||
self.height.multi_insert_median(
|
||||
heights,
|
||||
@@ -274,10 +274,11 @@ where
|
||||
&mut self,
|
||||
heights: &[Height],
|
||||
dates: &[Date],
|
||||
mut map_and_percentiles: Vec<(&mut BiMap<T>, f32)>,
|
||||
mut map_and_percentiles: Vec<(&mut BiMap<Value>, f32)>,
|
||||
days: Option<usize>,
|
||||
) where
|
||||
T: FloatCore,
|
||||
Value: LossyFrom<f32>,
|
||||
f32: LossyFrom<Value>,
|
||||
{
|
||||
let mut date_map_and_percentiles = vec![];
|
||||
let mut height_map_and_percentiles = vec![];
|
||||
|
||||
@@ -35,6 +35,27 @@ pub trait AnyDateMap: AnyMap {
|
||||
fn as_any_mut_map(&mut self) -> &mut dyn AnyMap;
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn date_map_vec_to_any_date_map_vec<T>(
|
||||
vec: Vec<&DateMap<T>>,
|
||||
) -> impl Iterator<Item = &(dyn AnyDateMap + Send + Sync)>
|
||||
where
|
||||
T: MapValue,
|
||||
{
|
||||
vec.into_iter()
|
||||
.map(|map| map as &(dyn AnyDateMap + Send + Sync))
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn date_map_vec_to_mut_any_date_map_vec<T>(
|
||||
vec: Vec<&mut DateMap<T>>,
|
||||
) -> impl Iterator<Item = &mut (dyn AnyDateMap)>
|
||||
where
|
||||
T: MapValue,
|
||||
{
|
||||
vec.into_iter().map(|map| map as &mut dyn AnyDateMap)
|
||||
}
|
||||
|
||||
impl<T> AnyDateMap for DateMap<T>
|
||||
where
|
||||
T: MapValue,
|
||||
|
||||
@@ -11,10 +11,14 @@ use std::{
|
||||
use allocative::Allocative;
|
||||
use bincode::{Decode, Encode};
|
||||
use itertools::Itertools;
|
||||
use ordered_float::{FloatCore, OrderedFloat};
|
||||
use ordered_float::OrderedFloat;
|
||||
use serde::{de::DeserializeOwned, Serialize};
|
||||
|
||||
use crate::{log, utils::LossyFrom, Serialization};
|
||||
use crate::{
|
||||
log,
|
||||
utils::{get_percentile, LossyFrom},
|
||||
Serialization,
|
||||
};
|
||||
|
||||
use super::{AnyMap, MapValue};
|
||||
|
||||
@@ -693,28 +697,31 @@ where
|
||||
|
||||
pub fn multi_insert_percentage_change(&mut self, keys: &[Key], source: &mut Self, len: usize)
|
||||
where
|
||||
Value: Sub<Output = Value> + FloatCore,
|
||||
Value: Sub<Output = Value> + LossyFrom<f32>,
|
||||
f32: LossyFrom<Value>,
|
||||
{
|
||||
let one = Value::from(1.0).unwrap();
|
||||
let hundred = Value::from(100.0).unwrap();
|
||||
let one = 1.0;
|
||||
let hundred = 100.0;
|
||||
|
||||
keys.iter().for_each(|key| {
|
||||
let previous_value = key
|
||||
.checked_sub(len)
|
||||
.and_then(|previous_key| source.get_or_import(&previous_key))
|
||||
.unwrap_or_default();
|
||||
let previous_value = f32::lossy_from(
|
||||
key.checked_sub(len)
|
||||
.and_then(|previous_key| source.get_or_import(&previous_key))
|
||||
.unwrap_or_default(),
|
||||
);
|
||||
|
||||
let last_value = source.get_or_import(key).unwrap();
|
||||
let last_value = f32::lossy_from(source.get_or_import(key).unwrap());
|
||||
|
||||
let percentage_change = ((last_value / previous_value) - one) * hundred;
|
||||
|
||||
self.insert(*key, percentage_change);
|
||||
self.insert(*key, Value::lossy_from(percentage_change));
|
||||
});
|
||||
}
|
||||
|
||||
pub fn multi_insert_median(&mut self, keys: &[Key], source: &mut Self, len: Option<usize>)
|
||||
where
|
||||
Value: FloatCore,
|
||||
Value: LossyFrom<f32>,
|
||||
f32: LossyFrom<Value>,
|
||||
{
|
||||
source.multi_insert_percentile(keys, vec![(self, 0.5)], len);
|
||||
}
|
||||
@@ -725,7 +732,8 @@ where
|
||||
mut map_and_percentiles: Vec<(&mut Self, f32)>,
|
||||
len: Option<usize>,
|
||||
) where
|
||||
Value: FloatCore,
|
||||
Value: LossyFrom<f32>,
|
||||
f32: LossyFrom<Value>,
|
||||
{
|
||||
if len.map_or(false, |size| size < 3) {
|
||||
panic!("Computing a percentile for a size lower than 3 is useless");
|
||||
@@ -736,8 +744,7 @@ where
|
||||
|
||||
let min_percentile_key = Key::min_percentile_key();
|
||||
|
||||
let nan = Value::from(f32::NAN).unwrap();
|
||||
let two = Value::from(2.0).unwrap();
|
||||
let nan = Value::lossy_from(f32::NAN);
|
||||
|
||||
keys.iter().cloned().try_for_each(|key| {
|
||||
if key < min_percentile_key {
|
||||
@@ -753,8 +760,9 @@ where
|
||||
let mut vec = start
|
||||
.iter_up_to(&key)
|
||||
.flat_map(|key| self.get_or_import(&key))
|
||||
.map(|v| f32::lossy_from(v))
|
||||
.filter(|f| !f.is_nan())
|
||||
.map(|f| OrderedFloat(f))
|
||||
.map(OrderedFloat)
|
||||
.collect_vec();
|
||||
|
||||
if len.is_some() {
|
||||
@@ -765,7 +773,7 @@ where
|
||||
|
||||
sorted_vec.replace(vec);
|
||||
} else {
|
||||
let float_value = self.get_or_import(&key).unwrap();
|
||||
let float_value = f32::lossy_from(self.get_or_import(&key).unwrap());
|
||||
|
||||
if !float_value.is_nan() {
|
||||
let float_value = OrderedFloat(float_value);
|
||||
@@ -797,8 +805,6 @@ where
|
||||
|
||||
let vec = sorted_vec.as_ref().unwrap();
|
||||
|
||||
let len = vec.len();
|
||||
|
||||
map_and_percentiles
|
||||
.iter_mut()
|
||||
.for_each(|(map, percentile)| {
|
||||
@@ -806,47 +812,9 @@ where
|
||||
panic!("The percentile should be between 0.0 and 1.0");
|
||||
}
|
||||
|
||||
let value = {
|
||||
if len < 2 {
|
||||
nan
|
||||
} else {
|
||||
let index = (len - 1) as f32 * *percentile;
|
||||
let float_value = get_percentile::<OrderedFloat<f32>>(vec, *percentile).0;
|
||||
|
||||
let fract = index.fract();
|
||||
|
||||
if fract != 0.0 {
|
||||
(vec.get(index.ceil() as usize)
|
||||
.unwrap_or_else(|| {
|
||||
dbg!(vec, index, &self.path_all, &self.path_all, len);
|
||||
panic!()
|
||||
})
|
||||
.0
|
||||
+ vec
|
||||
.get(index as usize)
|
||||
.unwrap_or_else(|| {
|
||||
dbg!(
|
||||
vec,
|
||||
index,
|
||||
&self.path_all,
|
||||
&self.path_all,
|
||||
len
|
||||
);
|
||||
panic!()
|
||||
})
|
||||
.0)
|
||||
/ two
|
||||
} else {
|
||||
vec.get(index as usize)
|
||||
.unwrap_or_else(|| {
|
||||
dbg!(vec, index);
|
||||
panic!();
|
||||
})
|
||||
.0
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
(*map).insert(key, value);
|
||||
(*map).insert(key, Value::lossy_from(float_value));
|
||||
});
|
||||
} else {
|
||||
map_and_percentiles.iter_mut().for_each(|(map, _)| {
|
||||
|
||||
@@ -45,6 +45,12 @@ impl Height {
|
||||
pub fn is_safe(&self, block_count: usize) -> bool {
|
||||
**self < (block_count - NUMBER_OF_UNSAFE_BLOCKS) as u32
|
||||
}
|
||||
|
||||
pub fn iter_range_inclusive(first: Height, last: Height) -> impl Iterator<Item = Height> {
|
||||
let range = (*first)..=(*last);
|
||||
|
||||
range.into_iter().map(Height::new)
|
||||
}
|
||||
}
|
||||
|
||||
impl PartialEq<u64> for Height {
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user