1use elastic_array::ElasticArray36;
18use nibbleslice::NibbleSlice;
19use nibblevec::NibbleVec;
20use super::DBValue;
21
22pub type NodeKey = ElasticArray36<u8>;
24
25#[derive(Eq, PartialEq, Debug, Clone)]
27pub enum Node<'a> {
28 Empty,
30 Leaf(NibbleSlice<'a>, &'a [u8]),
32 Extension(NibbleSlice<'a>, &'a [u8]),
34 Branch([&'a [u8]; 16], Option<&'a [u8]>),
36}
37
38#[derive(Eq, PartialEq, Debug, Clone)]
40pub struct Branch {
41 data: Vec<u8>,
42 ubounds: [usize; 18],
43 has_value: bool,
44}
45
46impl Branch {
47 fn new(a: [&[u8]; 16], value: Option<&[u8]>) -> Self {
48 let mut data = Vec::with_capacity(a.iter().map(|inner| inner.len()).sum());
49 let mut ubounds = [0; 18];
50 for (inner, ub) in a.iter().zip(ubounds.iter_mut().skip(1)) {
51 data.extend_from_slice(inner);
52 *ub = data.len();
53 }
54 if let Some(value) = value {
55 data.extend(value);
56 ubounds[17] = data.len();
57 }
58 Branch { data, ubounds, has_value: value.is_some() }
59 }
60
61 pub fn get_value(&self) -> Option<&[u8]> {
63 if self.has_value {
64 Some(&self.data[self.ubounds[16]..self.ubounds[17]])
65 } else {
66 None
67 }
68 }
69
70 pub fn has_value(&self) -> bool {
72 self.has_value
73 }
74}
75
76impl ::std::ops::Index<usize> for Branch {
77 type Output = [u8];
78 fn index(&self, index: usize) -> &[u8] {
79 assert!(index < 16);
80 &self.data[self.ubounds[index]..self.ubounds[index + 1]]
81 }
82}
83
84#[derive(Debug, PartialEq, Eq)]
86pub enum OwnedNode {
87 Empty,
89 Leaf(NibbleVec, DBValue),
91 Extension(NibbleVec, DBValue),
93 Branch(Branch),
95}
96
97impl<'a> From<Node<'a>> for OwnedNode {
98 fn from(node: Node<'a>) -> Self {
99 match node {
100 Node::Empty => OwnedNode::Empty,
101 Node::Leaf(k, v) => OwnedNode::Leaf(k.into(), DBValue::from_slice(v)),
102 Node::Extension(k, child) => OwnedNode::Extension(k.into(), DBValue::from_slice(child)),
103 Node::Branch(c, val) => OwnedNode::Branch(Branch::new(c, val)),
104 }
105 }
106}