1use nodedb_types::BoundingBox;
6
7use super::node::{Node, NodeKind, RTreeEntry};
8use super::search::NnResult;
9use nodedb_mem::ScopedMemory;
10
11pub struct RTree {
21 pub(crate) nodes: Vec<Node>,
22 pub(crate) root: usize,
23 pub(crate) len: usize,
24 pub(crate) memory: ScopedMemory,
27}
28
29impl RTree {
30 pub fn new(memory: ScopedMemory) -> Self {
31 Self {
32 nodes: vec![Node::new_leaf()],
33 root: 0,
34 len: 0,
35 memory,
36 }
37 }
38
39 pub(crate) fn memory(&self) -> &ScopedMemory {
41 &self.memory
42 }
43
44 pub fn len(&self) -> usize {
45 self.len
46 }
47
48 pub fn is_empty(&self) -> bool {
49 self.len == 0
50 }
51
52 pub fn search(&self, query: &BoundingBox) -> Vec<&RTreeEntry> {
54 let mut results = Vec::new();
55 super::search::search_node(&self.nodes, self.root, query, &mut results);
56 results
57 }
58
59 pub fn search_owned(&self, query: &BoundingBox) -> Vec<RTreeEntry> {
61 self.search(query).into_iter().cloned().collect()
62 }
63
64 pub fn nearest(&self, query_lng: f64, query_lat: f64, k: usize) -> Vec<NnResult> {
66 super::search::nearest(
67 &self.nodes,
68 self.root,
69 query_lng,
70 query_lat,
71 k,
72 self.is_empty(),
73 )
74 }
75
76 pub fn entries(&self) -> Vec<&RTreeEntry> {
78 let bytes = self.len * std::mem::size_of::<*const RTreeEntry>();
79 let _guard = self.memory().reserve(bytes).ok();
80 let mut result = Vec::with_capacity(self.len);
81 collect_entries(&self.nodes, self.root, &mut result);
82 result
83 }
84
85 pub(crate) fn find_parent(&self, current: usize, target: usize) -> Option<usize> {
87 if let NodeKind::Internal { children } = &self.nodes[current].kind {
88 for child in children {
89 if child.node_idx == target {
90 return Some(current);
91 }
92 if let Some(p) = self.find_parent(child.node_idx, target) {
93 return Some(p);
94 }
95 }
96 }
97 None
98 }
99
100 pub(crate) fn condense_root(&mut self) {
102 if let NodeKind::Internal { children } = &self.nodes[self.root].kind
103 && children.len() == 1
104 {
105 self.root = children[0].node_idx;
106 }
107 }
108}
109
110fn collect_entries<'a>(nodes: &'a [Node], node_idx: usize, result: &mut Vec<&'a RTreeEntry>) {
111 match &nodes[node_idx].kind {
112 NodeKind::Leaf { entries } => result.extend(entries.iter()),
113 NodeKind::Internal { children } => {
114 for child in children {
115 collect_entries(nodes, child.node_idx, result);
116 }
117 }
118 }
119}
120
121pub(crate) fn collect_entries_owned(nodes: &[Node], node_idx: usize, result: &mut Vec<RTreeEntry>) {
122 match &nodes[node_idx].kind {
123 NodeKind::Leaf { entries } => result.extend(entries.iter().cloned()),
124 NodeKind::Internal { children } => {
125 for child in children {
126 collect_entries_owned(nodes, child.node_idx, result);
127 }
128 }
129 }
130}
131
132#[cfg(test)]
133mod tests {
134 use super::super::node::LEAF_CAPACITY;
135 use super::*;
136 use crate::test_support::test_memory;
137
138 fn make_entry(id: u64, lng: f64, lat: f64) -> RTreeEntry {
139 RTreeEntry {
140 id,
141 bbox: BoundingBox::from_point(lng, lat),
142 }
143 }
144
145 fn make_rect(id: u64, min_lng: f64, min_lat: f64, max_lng: f64, max_lat: f64) -> RTreeEntry {
146 RTreeEntry {
147 id,
148 bbox: BoundingBox::new(min_lng, min_lat, max_lng, max_lat),
149 }
150 }
151
152 #[test]
153 fn empty_tree() {
154 let tree = RTree::new(test_memory());
155 assert!(tree.is_empty());
156 assert!(
157 tree.search(&BoundingBox::new(-180.0, -90.0, 180.0, 90.0))
158 .is_empty()
159 );
160 }
161
162 #[test]
163 fn insert_and_search_single() {
164 let mut tree = RTree::new(test_memory());
165 tree.insert(make_entry(1, 10.0, 20.0));
166 assert_eq!(tree.len(), 1);
167 assert_eq!(
168 tree.search(&BoundingBox::new(5.0, 15.0, 15.0, 25.0)).len(),
169 1
170 );
171 assert!(
172 tree.search(&BoundingBox::new(50.0, 50.0, 60.0, 60.0))
173 .is_empty()
174 );
175 }
176
177 #[test]
178 fn insert_many_and_search() {
179 let mut tree = RTree::new(test_memory());
180 for i in 0..200 {
181 tree.insert(make_entry(
182 i,
183 (i as f64) * 0.5 - 50.0,
184 (i as f64) * 0.3 - 30.0,
185 ));
186 }
187 assert_eq!(tree.len(), 200);
188 let all = tree.search(&BoundingBox::new(-180.0, -90.0, 180.0, 90.0));
189 assert_eq!(all.len(), 200);
190 }
191
192 #[test]
193 fn delete_entry() {
194 let mut tree = RTree::new(test_memory());
195 for i in 0..50 {
196 tree.insert(make_entry(i, i as f64, i as f64));
197 }
198 assert!(tree.delete(25));
199 assert_eq!(tree.len(), 49);
200 let all = tree.search(&BoundingBox::new(-1.0, -1.0, 100.0, 100.0));
201 assert!(all.iter().all(|e| e.id != 25));
202 assert!(!tree.delete(999));
203 }
204
205 #[test]
206 fn nearest_neighbor() {
207 let mut tree = RTree::new(test_memory());
208 tree.insert(make_entry(1, 0.0, 0.0));
209 tree.insert(make_entry(2, 10.0, 10.0));
210 tree.insert(make_entry(3, 5.0, 5.0));
211 let nn = tree.nearest(4.0, 4.0, 2);
212 assert_eq!(nn.len(), 2);
213 assert_eq!(nn[0].entry_id, 3);
214 assert_eq!(nn[1].entry_id, 1);
215 }
216
217 #[test]
218 fn nearest_empty() {
219 assert!(RTree::new(test_memory()).nearest(0.0, 0.0, 5).is_empty());
220 }
221
222 #[test]
223 fn rect_overlap_search() {
224 let mut tree = RTree::new(test_memory());
225 tree.insert(make_rect(1, 0.0, 0.0, 10.0, 10.0));
226 tree.insert(make_rect(2, 5.0, 5.0, 15.0, 15.0));
227 tree.insert(make_rect(3, 20.0, 20.0, 30.0, 30.0));
228 let results = tree.search(&BoundingBox::new(3.0, 3.0, 7.0, 7.0));
229 assert_eq!(results.len(), 2);
230 }
231
232 #[test]
233 fn stress_insert_delete() {
234 let mut tree = RTree::new(test_memory());
235 for i in 0..100_u64 {
236 tree.insert(make_entry(i, (i as f64) * 0.5, (i as f64) * 0.3));
237 }
238 for i in (0..100_u64).step_by(2) {
239 assert!(tree.delete(i));
240 }
241 assert_eq!(tree.len(), 50);
242 let all = tree.search(&BoundingBox::new(-180.0, -90.0, 180.0, 90.0));
243 assert!(all.iter().all(|e| e.id % 2 == 1));
244 }
245
246 #[test]
247 fn triggers_node_split() {
248 let mut tree = RTree::new(test_memory());
249 let count = LEAF_CAPACITY * 3;
250 for i in 0..count as u64 {
251 tree.insert(make_entry(i, (i as f64) * 0.1, (i as f64) * 0.1));
252 }
253 assert_eq!(tree.len(), count);
254 let all = tree.search(&BoundingBox::new(-180.0, -90.0, 180.0, 90.0));
255 assert_eq!(all.len(), count);
256 }
257
258 #[test]
259 fn entries_enumeration() {
260 let mut tree = RTree::new(test_memory());
261 for i in 0..10 {
262 tree.insert(make_entry(i, i as f64, i as f64));
263 }
264 assert_eq!(tree.entries().len(), 10);
265 }
266}