use brk_types::{Cents, CentsCompact, Height, PartsPerMillion32, Version};
use vecdb::{
AnyVec, BinaryTransform, CachedReadableVec, CachedVec, LazyVec, ReadableCloneableVec, VecIndex,
};
use crate::{
indexes,
internal::{LazyIndexedVec, LazyPerBlock, Price, PriceTimesRatio},
};
#[derive(Clone)]
pub(super) struct CachedComponentPrice {
cache: CachedVec<LazyVec<Height, CentsCompact, Height, Cents>>,
}
impl CachedComponentPrice {
pub(super) fn new(
name: &str,
version: Version,
source: &(impl ReadableCloneableVec<Height, Cents> + 'static),
) -> Self {
let compact = LazyVec::init(
&format!("{name}_cached_price"),
version,
source.read_only_boxed_clone(),
|_, value| CentsCompact::from(value),
);
Self {
cache: CachedVec::wrap(compact),
}
}
pub(super) fn price_for_ratio(
&self,
name: &str,
version: Version,
ratio: &(impl ReadableCloneableVec<Height, PartsPerMillion32> + 'static),
indexes: &indexes::Vecs,
) -> Price<LazyPerBlock<Cents>> {
let source = LazyIndexedVec::new(
&format!("{name}_cents_source"),
version,
ratio.read_only_boxed_clone(),
self.cache.cached_boxed_clone(),
|_, ratio, price| {
PriceTimesRatio::<PartsPerMillion32>::apply(Cents::from(price), ratio)
},
);
Price::from_uncached_height_source(name, version, source, indexes)
}
pub(super) fn clear_if_recomputed_from(&self, height: Height) {
if height.to_usize() < self.cache.len() {
self.cache.clear();
}
}
}