brk_state/
transacted.rs

1use std::{
2    collections::BTreeMap,
3    mem,
4    ops::{Add, AddAssign},
5};
6
7use brk_core::{OutputType, Sats};
8
9use super::{OutputsByType, SupplyState};
10
11#[derive(Default, Debug)]
12pub struct Transacted {
13    pub spendable_supply: SupplyState,
14    pub by_type: OutputsByType<SupplyState>,
15    pub by_size_group: BTreeMap<usize, SupplyState>,
16}
17
18impl Transacted {
19    #[allow(clippy::inconsistent_digit_grouping)]
20    pub fn iterate(&mut self, value: Sats, _type: OutputType) {
21        let supply = SupplyState { utxos: 1, value };
22
23        *self.by_type.get_mut(_type) += &supply;
24
25        if _type.is_unspendable() {
26            return;
27        }
28
29        self.spendable_supply += &supply;
30
31        let _value = usize::from(value);
32
33        // Need to be in sync with by_size !! but plenty fast (I think)
34        if _value == 0 {
35            *self.by_size_group.entry(0).or_default() += &supply;
36        } else if _value < 10 {
37            *self.by_size_group.entry(1).or_default() += &supply;
38        } else if _value < 100 {
39            *self.by_size_group.entry(10).or_default() += &supply;
40        } else if _value < 1_000 {
41            *self.by_size_group.entry(100).or_default() += &supply;
42        } else if _value < 10_000 {
43            *self.by_size_group.entry(1_000).or_default() += &supply;
44        } else if _value < 100_000 {
45            *self.by_size_group.entry(10_000).or_default() += &supply;
46        } else if _value < 1_000_000 {
47            *self.by_size_group.entry(100_000).or_default() += &supply;
48        } else if _value < 10_000_000 {
49            *self.by_size_group.entry(1_000_000).or_default() += &supply;
50        } else if _value < 1_00_000_000 {
51            *self.by_size_group.entry(10_000_000).or_default() += &supply;
52        } else if _value < 10_00_000_000 {
53            *self.by_size_group.entry(1_00_000_000).or_default() += &supply;
54        } else if _value < 100_00_000_000 {
55            *self.by_size_group.entry(10_00_000_000).or_default() += &supply;
56        } else if _value < 1_000_00_000_000 {
57            *self.by_size_group.entry(100_00_000_000).or_default() += &supply;
58        } else if _value < 10_000_00_000_000 {
59            *self.by_size_group.entry(1_000_00_000_000).or_default() += &supply;
60        } else if _value < 100_000_00_000_000 {
61            *self.by_size_group.entry(10_000_00_000_000).or_default() += &supply;
62        } else {
63            *self.by_size_group.entry(100_000_00_000_000).or_default() += &supply;
64        }
65    }
66
67    fn merge_by_size(
68        first: BTreeMap<usize, SupplyState>,
69        second: BTreeMap<usize, SupplyState>,
70    ) -> BTreeMap<usize, SupplyState> {
71        let (mut source, to_consume) = if first.len() > second.len() {
72            (first, second)
73        } else {
74            (second, first)
75        };
76        to_consume.into_iter().for_each(|(k, v)| {
77            *source.entry(k).or_default() += &v;
78        });
79        source
80    }
81}
82
83impl Add for Transacted {
84    type Output = Self;
85    fn add(self, rhs: Self) -> Self::Output {
86        Self {
87            spendable_supply: self.spendable_supply + rhs.spendable_supply,
88            by_type: self.by_type + rhs.by_type,
89            by_size_group: Self::merge_by_size(self.by_size_group, rhs.by_size_group),
90        }
91    }
92}
93
94impl AddAssign for Transacted {
95    fn add_assign(&mut self, rhs: Self) {
96        self.by_size_group =
97            Self::merge_by_size(mem::take(&mut self.by_size_group), rhs.by_size_group);
98        self.spendable_supply += &rhs.spendable_supply;
99        self.by_type += rhs.by_type;
100    }
101}