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