space_partitioning/quadtree/
node.rs1use crate::quadtree::free_list;
2use std::fmt::{Debug, Formatter};
3
4pub type NodeElementCountType = u32;
5
6const NODE_IS_BRANCH: u32 = NodeElementCountType::MAX;
8
9#[derive(Copy, Clone)]
11pub struct Node {
12 pub first_child_or_element: free_list::IndexType,
20 pub element_count: NodeElementCountType,
23}
24
25impl Debug for Node {
26 fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
27 match (self.element_count, self.first_child_or_element) {
28 (NODE_IS_BRANCH, free_list::SENTINEL) => {
29 write!(f, "Branch, no child nodes")
30 }
31 (NODE_IS_BRANCH, child_index) => write!(
32 f,
33 "Branch, child nodes at {}+{}..={}",
34 child_index,
35 child_index + 1,
36 child_index + 4
37 ),
38 (0, free_list::SENTINEL) => write!(f, "Leaf, no elements"),
39 (count, free_list::SENTINEL) => {
40 panic!("Got {} child elements but no data pointer", count)
41 }
42 (count, element_index) => write!(
43 f,
44 "Leaf, elements {}..={}",
45 element_index,
46 element_index + count
47 ),
48 }
49 }
50}
51
52impl Default for Node {
53 #[inline]
54 fn default() -> Self {
55 let node = Self {
56 first_child_or_element: free_list::SENTINEL,
59 element_count: 0,
61 };
62 debug_assert!(node.is_leaf() && node.is_empty());
64 node
65 }
66}
67
68impl Node {
69 #[inline]
71 pub fn is_empty(&self) -> bool {
72 self.element_count == 0
73 }
74
75 #[inline]
80 pub fn is_branch(&self) -> bool {
81 self.element_count == NODE_IS_BRANCH
82 }
83
84 #[inline]
89 pub fn is_leaf(&self) -> bool {
90 debug_assert!(self.element_count > 0 || self.first_child_or_element == free_list::SENTINEL);
93
94 !self.is_branch()
95 }
96
97 #[inline]
99 pub fn get_first_child_node_index(&self) -> free_list::IndexType {
100 debug_assert!(self.is_branch());
101 self.first_child_or_element
102 }
103
104 #[inline]
106 pub fn get_first_element_node_index(&self) -> free_list::IndexType {
107 debug_assert!(self.is_leaf());
108 self.first_child_or_element
109 }
110
111 #[inline]
113 pub fn make_empty_leaf(&mut self) {
114 self.first_child_or_element = free_list::SENTINEL;
115 self.element_count = 0;
116 }
117
118 #[inline]
120 pub fn make_branch(&mut self, first_child: free_list::IndexType) {
121 self.first_child_or_element = first_child;
122 self.element_count = NODE_IS_BRANCH;
123 }
124}
125
126#[cfg(test)]
127mod test {
128 use super::*;
129
130 #[test]
131 fn quad_node_is_eight_bytes() {
132 assert_eq!(std::mem::size_of::<Node>(), 8);
133 }
134}