11use std:: cmp:: Reverse ;
2- use std:: collections:: BinaryHeap ;
2+ use std:: collections:: { BinaryHeap , VecDeque } ;
3+ use std:: vec;
34
45use geo_traits:: { CoordTrait , RectTrait } ;
56
@@ -80,7 +81,7 @@ pub trait RTreeIndex<N: IndexableNum>: Sized {
8081
8182 let mut outer_node_index = boxes. len ( ) . checked_sub ( 4 ) ;
8283
83- let mut queue = vec ! [ ] ;
84+ let mut queue = VecDeque :: with_capacity ( self . node_size ( ) as usize ) ;
8485 let mut results = vec ! [ ] ;
8586
8687 while let Some ( node_index) = outer_node_index {
@@ -90,31 +91,36 @@ pub trait RTreeIndex<N: IndexableNum>: Sized {
9091
9192 // search through child nodes
9293 for pos in ( node_index..end) . step_by ( 4 ) {
93- // check if node bbox intersects with query bbox
94- if max_x < boxes[ pos] {
95- continue ; // maxX < nodeMinX
96- }
97- if max_y < boxes[ pos + 1 ] {
98- continue ; // maxY < nodeMinY
99- }
100- if min_x > boxes[ pos + 2 ] {
101- continue ; // minX > nodeMaxX
102- }
103- if min_y > boxes[ pos + 3 ] {
104- continue ; // minY > nodeMaxY
94+ // Safety: pos was checked before to be within bounds
95+ // Justification: avoiding bounds check improves performance by up to 30%
96+ let ( node_min_x, node_min_y, node_max_x, node_max_y) = unsafe {
97+ let node_min_x = * boxes. get_unchecked ( pos) ;
98+ let node_min_y = * boxes. get_unchecked ( pos + 1 ) ;
99+ let node_max_x = * boxes. get_unchecked ( pos + 2 ) ;
100+ let node_max_y = * boxes. get_unchecked ( pos + 3 ) ;
101+ ( node_min_x, node_min_y, node_max_x, node_max_y)
102+ } ;
103+
104+ // check if the query box disjoint with the node box
105+ if max_x < node_min_x
106+ || max_y < node_min_y
107+ || min_x > node_max_x
108+ || min_y > node_max_y
109+ {
110+ continue ;
105111 }
106112
107113 let index = indices. get ( pos >> 2 ) ;
108114
109115 if node_index >= self . num_items ( ) as usize * 4 {
110- queue. push ( index) ; // node; add it to the search queue
116+ queue. push_back ( index) ; // node; add it to the search queue
111117 } else {
112118 // Since the max items of the index is u32, we can coerce to u32
113119 results. push ( index. try_into ( ) . unwrap ( ) ) ; // leaf item
114120 }
115121 }
116122
117- outer_node_index = queue. pop ( ) ;
123+ outer_node_index = queue. pop_front ( ) ;
118124 }
119125
120126 results
0 commit comments