use std::{
collections::BTreeMap,
mem,
ops::{Add, AddAssign},
};
use brk_core::{OutputType, Sats};
use super::{OutputsByType, SupplyState};
#[derive(Default, Debug)]
pub struct Transacted {
pub spendable_supply: SupplyState,
pub by_type: OutputsByType<SupplyState>,
pub by_size_group: BTreeMap<usize, SupplyState>,
}
impl Transacted {
#[allow(clippy::inconsistent_digit_grouping)]
pub fn iterate(&mut self, value: Sats, _type: OutputType) {
let supply = SupplyState { utxos: 1, value };
*self.by_type.get_mut(_type) += &supply;
if _type.is_unspendable() {
return;
}
self.spendable_supply += &supply;
let _value = usize::from(value);
if _value == 0 {
*self.by_size_group.entry(0).or_default() += &supply;
} else if _value < 10 {
*self.by_size_group.entry(1).or_default() += &supply;
} else if _value < 100 {
*self.by_size_group.entry(10).or_default() += &supply;
} else if _value < 1_000 {
*self.by_size_group.entry(100).or_default() += &supply;
} else if _value < 10_000 {
*self.by_size_group.entry(1_000).or_default() += &supply;
} else if _value < 100_000 {
*self.by_size_group.entry(10_000).or_default() += &supply;
} else if _value < 1_000_000 {
*self.by_size_group.entry(100_000).or_default() += &supply;
} else if _value < 10_000_000 {
*self.by_size_group.entry(1_000_000).or_default() += &supply;
} else if _value < 1_00_000_000 {
*self.by_size_group.entry(10_000_000).or_default() += &supply;
} else if _value < 10_00_000_000 {
*self.by_size_group.entry(1_00_000_000).or_default() += &supply;
} else if _value < 100_00_000_000 {
*self.by_size_group.entry(10_00_000_000).or_default() += &supply;
} else if _value < 1_000_00_000_000 {
*self.by_size_group.entry(100_00_000_000).or_default() += &supply;
} else if _value < 10_000_00_000_000 {
*self.by_size_group.entry(1_000_00_000_000).or_default() += &supply;
} else if _value < 100_000_00_000_000 {
*self.by_size_group.entry(10_000_00_000_000).or_default() += &supply;
} else {
*self.by_size_group.entry(100_000_00_000_000).or_default() += &supply;
}
}
fn merge_by_size(
first: BTreeMap<usize, SupplyState>,
second: BTreeMap<usize, SupplyState>,
) -> BTreeMap<usize, SupplyState> {
let (mut source, to_consume) = if first.len() > second.len() {
(first, second)
} else {
(second, first)
};
to_consume.into_iter().for_each(|(k, v)| {
*source.entry(k).or_default() += &v;
});
source
}
}
impl Add for Transacted {
type Output = Self;
fn add(self, rhs: Self) -> Self::Output {
Self {
spendable_supply: self.spendable_supply + rhs.spendable_supply,
by_type: self.by_type + rhs.by_type,
by_size_group: Self::merge_by_size(self.by_size_group, rhs.by_size_group),
}
}
}
impl AddAssign for Transacted {
fn add_assign(&mut self, rhs: Self) {
self.by_size_group =
Self::merge_by_size(mem::take(&mut self.by_size_group), rhs.by_size_group);
self.spendable_supply += &rhs.spendable_supply;
self.by_type += rhs.by_type;
}
}