1use crate::{compaction::Compactor, digits::Digits, Cell};
2
3#[derive(Clone, Debug, PartialEq, Eq)]
4#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
5#[repr(align(64))]
6pub(crate) enum Node<V> {
7 Parent([Option<Box<Node<V>>>; 7]),
8 Leaf(V),
9}
10
11impl<V> Node<V> {
12 pub(crate) fn new() -> Self {
13 Self::Parent([None, None, None, None, None, None, None])
14 }
15
16 pub(crate) fn len(&self) -> usize {
17 match self {
18 Self::Leaf(_) => 1,
19 Self::Parent(children) => children.iter().flatten().map(|child| child.len()).sum(),
20 }
21 }
22
23 pub(crate) fn insert<C>(
24 &mut self,
25 cell: Cell,
26 res: u8,
27 mut digits: Digits,
28 value: V,
29 compactor: &mut C,
30 ) where
31 C: Compactor<V>,
32 {
33 match digits.next() {
34 None => *self = Self::Leaf(value),
35 Some(digit) => match self {
36 Self::Leaf(_) => {
37 return;
38 }
39 Self::Parent(children) => {
40 match children[digit as usize].as_mut() {
41 Some(node) => node.insert(cell, res + 1, digits, value, compactor),
42 None => {
43 let mut node = Node::new();
44 node.insert(cell, res + 1, digits, value, compactor);
45 children[digit as usize] = Some(Box::new(node));
46 }
47 };
48 }
49 },
50 };
51 self.coalesce(cell.to_parent(res).unwrap(), compactor);
52 }
53
54 pub(crate) fn coalesce<C>(&mut self, cell: Cell, compactor: &mut C)
55 where
56 C: Compactor<V>,
57 {
58 if let Self::Parent(children) = self {
59 if children
60 .iter()
61 .any(|n| matches!(n.as_ref().map(|n| n.as_ref()), Some(Self::Parent(_))))
62 {
63 return;
64 }
65 let mut arr: [Option<&V>; 7] = [None, None, None, None, None, None, None];
66 for (v, n) in arr.iter_mut().zip(children.iter()) {
67 *v = n.as_ref().map(|n| n.as_ref()).and_then(Node::value);
68 }
69 if let Some(value) = compactor.compact(cell, arr) {
70 *self = Self::Leaf(value)
71 }
72 };
73 }
74
75 pub(crate) fn value(&self) -> Option<&V> {
76 match self {
77 Self::Leaf(value) => Some(value),
78 _ => None,
79 }
80 }
81
82 #[inline]
83 pub(crate) fn contains(&self, mut digits: Digits) -> bool {
84 match (digits.next(), self) {
85 (_, Self::Leaf(_)) => true,
86 (Some(digit), Self::Parent(children)) => {
87 match &children.as_slice()[digit as usize] {
89 Some(node) => node.contains(digits),
90 None => false,
91 }
92 }
93 (None, Self::Parent(_)) => false,
96 }
97 }
98
99 #[inline]
100 pub(crate) fn get(&self, res: u8, cell: Cell, mut digits: Digits) -> Option<(Cell, &Node<V>)> {
101 match (digits.next(), self) {
102 (None, _) => Some((cell, self)),
103 (Some(_), Self::Leaf(_)) => {
104 Some((cell.to_parent(res).expect("invalid condition"), self))
105 }
106 (Some(digit), Self::Parent(children)) => match &children.as_slice()[digit as usize] {
107 Some(node) => node.get(res + 1, cell, digits),
108 None => None,
109 },
110 }
111 }
112
113 #[inline]
114 pub(crate) fn get_mut(
115 &mut self,
116 res: u8,
117 cell: Cell,
118 mut digits: Digits,
119 ) -> Option<(Cell, &mut Node<V>)> {
120 match (digits.next(), self) {
121 (None, s) => Some((cell, s)),
122 (Some(_), s @ Self::Leaf(_)) => {
123 Some((cell.to_parent(res).expect("invalid condition"), s))
124 }
125 (Some(digit), Self::Parent(ref mut children)) => {
126 match children.as_mut_slice()[digit as usize].as_deref_mut() {
127 Some(node) => node.get_mut(res + 1, cell, digits),
128 None => None,
129 }
130 }
131 }
132 }
133}