1use alloc::collections::{BTreeMap, BTreeSet};
2
3use alloc::vec::Vec;
4use anyhow::Result;
5use borsh::{BorshDeserialize, BorshSerialize};
6#[cfg(any(test))]
7use proptest_derive::Arbitrary;
8
9use crate::{
10    node_type::{Node, NodeKey},
11    types::Version,
12    KeyHash, OwnedValue,
13};
14
15pub trait TreeWriter {
19    fn write_node_batch(&self, node_batch: &NodeBatch) -> Result<()>;
21}
22
23#[derive(Debug, Clone, PartialEq, Default, Eq, borsh::BorshSerialize, borsh::BorshDeserialize)]
25pub struct NodeBatch {
26    nodes: BTreeMap<NodeKey, Node>,
27    values: BTreeMap<(Version, KeyHash), Option<OwnedValue>>,
28}
29
30impl NodeBatch {
31    pub fn new(
33        nodes: BTreeMap<NodeKey, Node>,
34        values: BTreeMap<(Version, KeyHash), Option<OwnedValue>>,
35    ) -> Self {
36        NodeBatch { nodes, values }
37    }
38
39    pub fn clear(&mut self) {
41        self.nodes.clear();
42        self.values.clear()
43    }
44
45    pub fn get_node(&self, node_key: &NodeKey) -> Option<&Node> {
47        self.nodes.get(node_key)
48    }
49
50    pub fn nodes(&self) -> &BTreeMap<NodeKey, Node> {
52        &self.nodes
53    }
54
55    pub fn insert_node(&mut self, node_key: NodeKey, node: Node) -> Option<Node> {
57        self.nodes.insert(node_key, node)
58    }
59
60    pub fn insert_value(&mut self, version: Version, key_hash: KeyHash, value: OwnedValue) {
62        self.values.insert((version, key_hash), Some(value));
63    }
64
65    pub fn values(&self) -> &BTreeMap<(Version, KeyHash), core::option::Option<Vec<u8>>> {
67        &self.values
68    }
69
70    pub fn extend(
72        &mut self,
73        nodes: impl IntoIterator<Item = (NodeKey, Node)>,
74        values: impl IntoIterator<Item = ((Version, KeyHash), Option<OwnedValue>)>,
75    ) {
76        self.nodes.extend(nodes);
77        self.values.extend(values);
78    }
79
80    pub fn merge(&mut self, rhs: Self) {
82        self.extend(rhs.nodes, rhs.values)
83    }
84
85    pub fn is_empty(&self) -> bool {
87        self.nodes.is_empty() && self.values.is_empty()
88    }
89}
90pub type StaleNodeIndexBatch = BTreeSet<StaleNodeIndex>;
93
94#[derive(Clone, Debug, Default, Eq, PartialEq, borsh::BorshSerialize, borsh::BorshDeserialize)]
95pub struct NodeStats {
96    pub new_nodes: usize,
97    pub new_leaves: usize,
98    pub stale_nodes: usize,
99    pub stale_leaves: usize,
100}
101
102#[derive(Clone, Debug, Eq, Hash, Ord, PartialEq, PartialOrd, BorshDeserialize, BorshSerialize)]
104#[cfg_attr(any(test), derive(Arbitrary))]
105pub struct StaleNodeIndex {
106    pub stale_since_version: Version,
108    pub node_key: NodeKey,
111}
112
113#[derive(Clone, Debug, Default, Eq, PartialEq, BorshSerialize, BorshDeserialize)]
118pub struct TreeUpdateBatch {
119    pub node_batch: NodeBatch,
120    pub stale_node_index_batch: StaleNodeIndexBatch,
121    pub node_stats: Vec<NodeStats>,
122}