@@ -270,26 +270,41 @@ class RmMTree {
270270 if (node_pattern10_count[node_index] < target_pattern_rank) {
271271 return npos;
272272 }
273+ const size_t tree_size = segment_size_bits.size () - 1 ;
273274 size_t segment_base = 0 ;
274275 while (node_index < first_leaf_index) {
275- const size_t left_child = node_index << 1 , right_child = left_child | 1 ;
276+ const size_t left_child = node_index << 1 ;
277+ const size_t left_segment_size =
278+ (left_child <= tree_size) ? segment_size_bits[left_child] : 0 ;
279+ if (left_segment_size == 0 ) {
280+ return npos;
281+ }
282+
283+ const size_t left_count = node_pattern10_count[left_child];
284+ if (left_count >= target_pattern_rank) {
285+ node_index = left_child;
286+ continue ;
287+ }
288+
289+ size_t remaining_rank = target_pattern_rank - left_count;
290+ const size_t right_child = left_child | 1 ;
291+ const bool has_right =
292+ (right_child <= tree_size) && (segment_size_bits[right_child] != 0 );
293+ if (!has_right) {
294+ return npos;
295+ }
296+
276297 const size_t crossing_pattern =
277298 (node_last_bit[left_child] == 1 && node_first_bit[right_child] == 0 )
278299 ? 1u
279300 : 0u ;
280- if (node_pattern10_count[left_child] >= target_pattern_rank) {
281- node_index = left_child;
282- continue ;
283- }
284- size_t remaining_rank =
285- target_pattern_rank - node_pattern10_count[left_child];
286301 if (crossing_pattern) {
287302 if (remaining_rank == 1 ) {
288- return segment_base + segment_size_bits[left_child] - 1 ;
303+ return segment_base + left_segment_size - 1 ;
289304 }
290305 --remaining_rank;
291306 }
292- segment_base += segment_size_bits[left_child] ;
307+ segment_base += left_segment_size ;
293308 node_index = right_child;
294309 target_pattern_rank = remaining_rank;
295310 }
0 commit comments