def _find_longest_prefix_match(tree, bin_X, hash_size, left_masks, right_masks):
 hi = np.empty_like(bin_X, dtype=np.intp)
 hi.fill(hash_size)
 lo = np.zeros_like(bin_X, dtype=np.intp)
 res = np.empty_like(bin_X, dtype=np.intp)
 (left_idx, right_idx) = _find_matching_indices(tree, bin_X, left_masks[hi], right_masks[hi])
 found = (right_idx > left_idx)
 res[found] = lo[found] = hash_size
 r = np.arange(bin_X.shape[0])
 kept = r[(lo < hi)]
 while kept.shape[0]:
  mid = ((lo.take(kept) + hi.take(kept)) // 2)
  (left_idx, right_idx) = _find_matching_indices(tree, bin_X.take(kept), left_masks[mid], right_masks[mid])
  found = (right_idx > left_idx)
  mid_found = mid[found]
  lo[kept[found]] = (mid_found + 1)
  res[kept[found]] = mid_found
  hi[kept[(~ found)]] = mid[(~ found)]
  kept = r[(lo < hi)]
 return res

def _find_longest_prefix_match ( tree , bin_X , hash_size , left_masks , right_masks ) : hi = np . empty_like ( bin_X , dtype = np . intp ) hi . fill ( hash_size ) lo = np . zeros_like ( bin_X , dtype = np . intp ) res = np . empty_like ( bin_X , dtype = np . intp ) ( left_idx , right_idx ) = _find_matching_indices ( tree , bin_X , left_masks [ hi ] , right_masks [ hi ] ) found = ( right_idx > left_idx ) res [ found ] = lo [ found ] = hash_size r = np . arange ( bin_X . shape [ 0 ] ) kept = r [ ( lo < hi ) ] while kept . shape [ 0 ] : mid = ( ( lo . take ( kept ) + hi . take ( kept ) ) // 2 ) ( left_idx , right_idx ) = _find_matching_indices ( tree , bin_X . take ( kept ) , left_masks [ mid ] , right_masks [ mid ] ) found = ( right_idx > left_idx ) mid_found = mid [ found ] lo [ kept [ found ] ] = ( mid_found + 1 ) res [ kept [ found ] ] = mid_found hi [ kept [ ( ~ found ) ] ] = mid [ ( ~ found ) ] kept = r [ ( lo < hi ) ] return res
find the longest prefix match in tree for each query in bin_x most significant bits are considered as the prefix .