rstar/algorithm/
rstar.rs

1use crate::envelope::Envelope;
2use crate::node::{envelope_for_children, ParentNode, RTreeNode};
3use crate::object::RTreeObject;
4use crate::params::{InsertionStrategy, RTreeParams};
5use crate::point::{Point, PointExt};
6use crate::rtree::RTree;
7
8use alloc::vec::Vec;
9use num_traits::{Bounded, Zero};
10
11/// Inserts points according to the r-star heuristic.
12///
13/// The r*-heuristic focusses on good insertion quality at the costs of
14/// insertion performance. This strategy is best for use cases with few
15/// insertions and many nearest neighbor queries.
16///
17/// `RStarInsertionStrategy` is used as the default insertion strategy.
18/// See [InsertionStrategy] for more information on insertion strategies.
19pub enum RStarInsertionStrategy {}
20
21enum InsertionResult<T>
22where
23    T: RTreeObject,
24{
25    Split(RTreeNode<T>),
26    Reinsert(Vec<RTreeNode<T>>, usize),
27    Complete,
28}
29
30impl InsertionStrategy for RStarInsertionStrategy {
31    fn insert<T, Params>(tree: &mut RTree<T, Params>, t: T)
32    where
33        Params: RTreeParams,
34        T: RTreeObject,
35    {
36        use InsertionAction::*;
37
38        enum InsertionAction<T: RTreeObject> {
39            PerformSplit(RTreeNode<T>),
40            PerformReinsert(RTreeNode<T>),
41        }
42
43        let first = recursive_insert::<_, Params>(tree.root_mut(), RTreeNode::Leaf(t), 0);
44        let mut target_height = 0;
45        let mut insertion_stack = Vec::new();
46        match first {
47            InsertionResult::Split(node) => insertion_stack.push(PerformSplit(node)),
48            InsertionResult::Reinsert(nodes_to_reinsert, real_target_height) => {
49                insertion_stack.extend(nodes_to_reinsert.into_iter().map(PerformReinsert));
50                target_height = real_target_height;
51            }
52            InsertionResult::Complete => {}
53        };
54
55        while let Some(next) = insertion_stack.pop() {
56            match next {
57                PerformSplit(node) => {
58                    // The root node was split, create a new root and increase height
59                    let new_root = ParentNode::new_root::<Params>();
60                    let old_root = ::core::mem::replace(tree.root_mut(), new_root);
61                    let new_envelope = old_root.envelope.merged(&node.envelope());
62                    let root = tree.root_mut();
63                    root.envelope = new_envelope;
64                    root.children.push(RTreeNode::Parent(old_root));
65                    root.children.push(node);
66                    target_height += 1;
67                }
68                PerformReinsert(node_to_reinsert) => {
69                    let root = tree.root_mut();
70                    match forced_insertion::<T, Params>(root, node_to_reinsert, target_height) {
71                        InsertionResult::Split(node) => insertion_stack.push(PerformSplit(node)),
72                        InsertionResult::Reinsert(_, _) => {
73                            panic!("Unexpected reinsert. This is a bug in rstar.")
74                        }
75                        InsertionResult::Complete => {}
76                    }
77                }
78            }
79        }
80    }
81}
82
83fn forced_insertion<T, Params>(
84    node: &mut ParentNode<T>,
85    t: RTreeNode<T>,
86    target_height: usize,
87) -> InsertionResult<T>
88where
89    T: RTreeObject,
90    Params: RTreeParams,
91{
92    node.envelope.merge(&t.envelope());
93    let expand_index = choose_subtree(node, &t);
94
95    if target_height == 0 || node.children.len() < expand_index {
96        // Force insertion into this node
97        node.children.push(t);
98        return resolve_overflow_without_reinsertion::<_, Params>(node);
99    }
100
101    if let RTreeNode::Parent(ref mut follow) = node.children[expand_index] {
102        match forced_insertion::<_, Params>(follow, t, target_height - 1) {
103            InsertionResult::Split(child) => {
104                node.envelope.merge(&child.envelope());
105                node.children.push(child);
106                resolve_overflow_without_reinsertion::<_, Params>(node)
107            }
108            other => other,
109        }
110    } else {
111        unreachable!("This is a bug in rstar.")
112    }
113}
114
115fn recursive_insert<T, Params>(
116    node: &mut ParentNode<T>,
117    t: RTreeNode<T>,
118    current_height: usize,
119) -> InsertionResult<T>
120where
121    T: RTreeObject,
122    Params: RTreeParams,
123{
124    node.envelope.merge(&t.envelope());
125    let expand_index = choose_subtree(node, &t);
126
127    if node.children.len() < expand_index {
128        // Force insertion into this node
129        node.children.push(t);
130        return resolve_overflow::<_, Params>(node, current_height);
131    }
132
133    let expand = if let RTreeNode::Parent(ref mut follow) = node.children[expand_index] {
134        recursive_insert::<_, Params>(follow, t, current_height + 1)
135    } else {
136        panic!("This is a bug in rstar.")
137    };
138
139    match expand {
140        InsertionResult::Split(child) => {
141            node.envelope.merge(&child.envelope());
142            node.children.push(child);
143            resolve_overflow::<_, Params>(node, current_height)
144        }
145        InsertionResult::Reinsert(a, b) => {
146            node.envelope = envelope_for_children(&node.children);
147            InsertionResult::Reinsert(a, b)
148        }
149        other => other,
150    }
151}
152
153fn choose_subtree<T>(node: &mut ParentNode<T>, to_insert: &RTreeNode<T>) -> usize
154where
155    T: RTreeObject,
156{
157    let all_leaves = match node.children.first() {
158        Some(RTreeNode::Leaf(_)) => return usize::max_value(),
159        Some(RTreeNode::Parent(ref data)) => data
160            .children
161            .first()
162            .map(RTreeNode::is_leaf)
163            .unwrap_or(true),
164        _ => return usize::max_value(),
165    };
166
167    let zero: <<T::Envelope as Envelope>::Point as Point>::Scalar = Zero::zero();
168    let insertion_envelope = to_insert.envelope();
169    let mut inclusion_count = 0;
170    let mut min_area = <<T::Envelope as Envelope>::Point as Point>::Scalar::max_value();
171    let mut min_index = 0;
172    for (index, child) in node.children.iter().enumerate() {
173        let envelope = child.envelope();
174        if envelope.contains_envelope(&insertion_envelope) {
175            inclusion_count += 1;
176            let area = envelope.area();
177            if area < min_area {
178                min_area = area;
179                min_index = index;
180            }
181        }
182    }
183    if inclusion_count == 0 {
184        // No inclusion found, subtree depends on overlap and area increase
185        let mut min = (zero, zero, zero);
186
187        for (index, child1) in node.children.iter().enumerate() {
188            let envelope = child1.envelope();
189            let mut new_envelope = envelope.clone();
190            new_envelope.merge(&insertion_envelope);
191            let overlap_increase = if all_leaves {
192                // Calculate minimal overlap increase
193                let mut overlap = zero;
194                let mut new_overlap = zero;
195                for child2 in &node.children {
196                    if child1 as *const _ != child2 as *const _ {
197                        let child_envelope = child2.envelope();
198                        let temp1 = envelope.intersection_area(&child_envelope);
199                        overlap = overlap + temp1;
200                        let temp2 = new_envelope.intersection_area(&child_envelope);
201                        new_overlap = new_overlap + temp2;
202                    }
203                }
204                new_overlap - overlap
205            } else {
206                // Don't calculate overlap increase if not all children are leaves
207                zero
208            };
209            // Calculate area increase and area
210            let area = new_envelope.area();
211            let area_increase = area - envelope.area();
212            let new_min = (overlap_increase, area_increase, area);
213            if new_min < min || index == 0 {
214                min = new_min;
215                min_index = index;
216            }
217        }
218    }
219    min_index
220}
221
222// Never returns a request for reinsertion
223fn resolve_overflow_without_reinsertion<T, Params>(node: &mut ParentNode<T>) -> InsertionResult<T>
224where
225    T: RTreeObject,
226    Params: RTreeParams,
227{
228    if node.children.len() > Params::MAX_SIZE {
229        let off_split = split::<_, Params>(node);
230        InsertionResult::Split(off_split)
231    } else {
232        InsertionResult::Complete
233    }
234}
235
236fn resolve_overflow<T, Params>(node: &mut ParentNode<T>, current_depth: usize) -> InsertionResult<T>
237where
238    T: RTreeObject,
239    Params: RTreeParams,
240{
241    if Params::REINSERTION_COUNT == 0 {
242        resolve_overflow_without_reinsertion::<_, Params>(node)
243    } else if node.children.len() > Params::MAX_SIZE {
244        let nodes_for_reinsertion = get_nodes_for_reinsertion::<_, Params>(node);
245        InsertionResult::Reinsert(nodes_for_reinsertion, current_depth)
246    } else {
247        InsertionResult::Complete
248    }
249}
250
251fn split<T, Params>(node: &mut ParentNode<T>) -> RTreeNode<T>
252where
253    T: RTreeObject,
254    Params: RTreeParams,
255{
256    let axis = get_split_axis::<_, Params>(node);
257    let zero = <<T::Envelope as Envelope>::Point as Point>::Scalar::zero();
258    debug_assert!(node.children.len() >= 2);
259    // Sort along axis
260    T::Envelope::sort_envelopes(axis, &mut node.children);
261    let mut best = (zero, zero);
262    let min_size = Params::MIN_SIZE;
263    let mut best_index = min_size;
264
265    for k in min_size..=node.children.len() - min_size {
266        let mut first_envelope = node.children[k - 1].envelope();
267        let mut second_envelope = node.children[k].envelope();
268        let (l, r) = node.children.split_at(k);
269        for child in l {
270            first_envelope.merge(&child.envelope());
271        }
272        for child in r {
273            second_envelope.merge(&child.envelope());
274        }
275
276        let overlap_value = first_envelope.intersection_area(&second_envelope);
277        let area_value = first_envelope.area() + second_envelope.area();
278        let new_best = (overlap_value, area_value);
279        if new_best < best || k == min_size {
280            best = new_best;
281            best_index = k;
282        }
283    }
284    let off_split = node.children.split_off(best_index);
285    node.envelope = envelope_for_children(&node.children);
286    RTreeNode::Parent(ParentNode::new_parent(off_split))
287}
288
289fn get_split_axis<T, Params>(node: &mut ParentNode<T>) -> usize
290where
291    T: RTreeObject,
292    Params: RTreeParams,
293{
294    let mut best_goodness = <<T::Envelope as Envelope>::Point as Point>::Scalar::max_value();
295    let mut best_axis = 0;
296    let min_size = Params::MIN_SIZE;
297    let until = node.children.len() - min_size + 1;
298    for axis in 0..<T::Envelope as Envelope>::Point::DIMENSIONS {
299        // Sort children along the current axis
300        T::Envelope::sort_envelopes(axis, &mut node.children);
301        let mut first_envelope = T::Envelope::new_empty();
302        let mut second_envelope = T::Envelope::new_empty();
303        for child in &node.children[..min_size] {
304            first_envelope.merge(&child.envelope());
305        }
306        for child in &node.children[until..] {
307            second_envelope.merge(&child.envelope());
308        }
309        for k in min_size..until {
310            let mut first_modified = first_envelope.clone();
311            let mut second_modified = second_envelope.clone();
312            let (l, r) = node.children.split_at(k);
313            for child in l {
314                first_modified.merge(&child.envelope());
315            }
316            for child in r {
317                second_modified.merge(&child.envelope());
318            }
319
320            let perimeter_value =
321                first_modified.perimeter_value() + second_modified.perimeter_value();
322            if best_goodness > perimeter_value {
323                best_axis = axis;
324                best_goodness = perimeter_value;
325            }
326        }
327    }
328    best_axis
329}
330
331fn get_nodes_for_reinsertion<T, Params>(node: &mut ParentNode<T>) -> Vec<RTreeNode<T>>
332where
333    T: RTreeObject,
334    Params: RTreeParams,
335{
336    let center = node.envelope.center();
337    // Sort with increasing order so we can use Vec::split_off
338    node.children.sort_by(|l, r| {
339        let l_center = l.envelope().center();
340        let r_center = r.envelope().center();
341        l_center
342            .sub(&center)
343            .length_2()
344            .partial_cmp(&(r_center.sub(&center)).length_2())
345            .unwrap()
346    });
347    let num_children = node.children.len();
348    let result = node
349        .children
350        .split_off(num_children - Params::REINSERTION_COUNT);
351    node.envelope = envelope_for_children(&node.children);
352    result
353}