| 170 | |
| 171 | template <side_t side> |
| 172 | static void |
| 173 | npy_binsearch(const char *arr, const char *key, char *ret, npy_intp arr_len, |
| 174 | npy_intp key_len, npy_intp arr_str, npy_intp key_str, |
| 175 | npy_intp ret_str, PyArrayObject *cmp) |
| 176 | { |
| 177 | using Cmp = typename side_to_generic_cmp<side>::type; |
| 178 | PyArray_CompareFunc *compare = PyArray_DESCR(cmp)->f->compare; |
| 179 | npy_intp min_idx = 0; |
| 180 | npy_intp max_idx = arr_len; |
| 181 | const char *last_key = key; |
| 182 | |
| 183 | for (; key_len > 0; key_len--, key += key_str, ret += ret_str) { |
| 184 | /* |
| 185 | * Updating only one of the indices based on the previous key |
| 186 | * gives the search a big boost when keys are sorted, but slightly |
| 187 | * slows down things for purely random ones. |
| 188 | */ |
| 189 | if (Cmp{}(compare(last_key, key, cmp), 0)) { |
| 190 | max_idx = arr_len; |
| 191 | } |
| 192 | else { |
| 193 | min_idx = 0; |
| 194 | max_idx = (max_idx < arr_len) ? (max_idx + 1) : arr_len; |
| 195 | } |
| 196 | |
| 197 | last_key = key; |
| 198 | |
| 199 | while (min_idx < max_idx) { |
| 200 | const npy_intp mid_idx = min_idx + ((max_idx - min_idx) >> 1); |
| 201 | const char *arr_ptr = arr + mid_idx * arr_str; |
| 202 | |
| 203 | if (Cmp{}(compare(arr_ptr, key, cmp), 0)) { |
| 204 | min_idx = mid_idx + 1; |
| 205 | } |
| 206 | else { |
| 207 | max_idx = mid_idx; |
| 208 | } |
| 209 | } |
| 210 | *(npy_intp *)ret = min_idx; |
| 211 | } |
| 212 | } |
| 213 | |
| 214 | template <side_t side> |
| 215 | static int |
nothing calls this directly
no test coverage detected