all: split "range" variant of nm_utils_ptrarray_find_binary_search()

nm_utils_ptrarray_find_binary_search() had two additional output
arguments: the first and last index -- in case the sorted list contains
duplicates.

That's nice, and was used in the past. But now, those output arguments
are no longer used.

So drop them from nm_utils_ptrarray_find_binary_search().

Actually, we could now also drop the previous variant
nm_utils_ptrarray_find_binary_search_range(), as it's only used by unit
tests. However, although not rocket science, getting this right is not
entirely trivial, so lets keep the code in case we need it again.
This commit is contained in:
Thomas Haller 2021-03-16 09:29:53 +01:00
parent 7fde244ed2
commit 6e4cdae256
No known key found for this signature in database
GPG key ID: 29C2366E4DFC5728
7 changed files with 83 additions and 38 deletions

View file

@ -433,13 +433,7 @@ nm_config_set_no_auto_default_for_device(NMConfig *self, NMDevice *device)
len = NM_PTRARRAY_LEN(no_auto_default_current);
idx = nm_utils_ptrarray_find_binary_search((gconstpointer *) no_auto_default_current,
len,
spec,
nm_strcmp_with_data,
NULL,
NULL,
NULL);
idx = nm_utils_strv_find_binary_search(no_auto_default_current, len, spec);
if (idx >= 0) {
/* @spec is already blocked. We don't have to update our in-memory representation.
* Maybe we should write to no_auto_default_file anew, but let's save that too. */

View file

@ -751,8 +751,6 @@ nml_dbus_meta_iface_get(const char *dbus_iface_name)
G_N_ELEMENTS(_nml_dbus_meta_ifaces),
&dbus_iface_name[NM_STRLEN(COMMON_PREFIX)],
_strcmp_common_prefix,
NULL,
NULL,
NULL);
} else
return NULL;

View file

@ -3087,8 +3087,6 @@ _parse_info_find(NMSetting * setting,
NM_PTRARRAY_LEN(pis->properties),
&property_name,
nm_strcmp_p_with_data,
NULL,
NULL,
NULL);
if (idx >= 0)
pip = pis->properties[idx];

View file

@ -5325,8 +5325,6 @@ _nm_variant_attribute_spec_find_binary_search(const NMVariantAttributeSpec *cons
len,
&name,
nm_strcmp_p_with_data,
NULL,
NULL,
NULL);
if (idx < 0)
return NULL;

View file

@ -8609,7 +8609,7 @@ static void
_test_find_binary_search_do(const int *array, gsize len)
{
gsize i;
gssize idx, idx_first, idx_last;
gssize idx, idx2, idx_first, idx_last;
gs_free gconstpointer *parray = g_new(gconstpointer, len);
const int NEEDLE = 0;
gconstpointer pneedle = GINT_TO_POINTER(NEEDLE);
@ -8620,17 +8620,26 @@ _test_find_binary_search_do(const int *array, gsize len)
expected_result = nm_utils_ptrarray_find_first(parray, len, pneedle);
idx = nm_utils_ptrarray_find_binary_search(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL,
&idx_first,
&idx_last);
idx = nm_utils_ptrarray_find_binary_search_range(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL,
&idx_first,
&idx_last);
idx2 = nm_utils_ptrarray_find_binary_search(parray,
len,
pneedle,
_test_find_binary_search_cmp,
NULL);
g_assert_cmpint(idx, ==, idx2);
if (expected_result >= 0) {
g_assert_cmpint(expected_result, ==, idx);
} else {
gssize idx2 = ~idx;
idx2 = ~idx;
g_assert_cmpint(idx, <, 0);
g_assert(idx2 >= 0);
@ -8787,13 +8796,13 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates(void)
for (i = 0; i < i_len + BIN_SEARCH_W_DUPS_JITTER; i++) {
gconstpointer p = GINT_TO_POINTER(i);
idx = nm_utils_ptrarray_find_binary_search(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL,
&idx_first,
&idx_last);
idx = nm_utils_ptrarray_find_binary_search_range(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL,
&idx_first,
&idx_last);
idx_first2 = nm_utils_ptrarray_find_first(arr, i_len, p);
@ -8805,6 +8814,13 @@ test_nm_utils_ptrarray_find_binary_search_with_duplicates(void)
NULL);
g_assert_cmpint(idx, ==, idx2);
idx2 = nm_utils_ptrarray_find_binary_search(arr,
i_len,
p,
_test_bin_search2_cmp,
NULL);
g_assert_cmpint(idx, ==, idx2);
if (idx_first2 < 0) {
g_assert_cmpint(idx, <, 0);
g_assert_cmpint(idx, ==, idx_first);
@ -10813,7 +10829,7 @@ main(int argc, char **argv)
g_test_add_func("/core/general/_nm_utils_ascii_str_to_int64", test_nm_utils_ascii_str_to_int64);
g_test_add_func("/core/general/nm_utils_is_power_of_two", test_nm_utils_is_power_of_two);
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search",
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_range",
test_nm_utils_ptrarray_find_binary_search);
g_test_add_func("/core/general/nm_utils_ptrarray_find_binary_search_with_duplicates",
test_nm_utils_ptrarray_find_binary_search_with_duplicates);

View file

@ -3833,9 +3833,46 @@ nm_utils_ptrarray_find_binary_search(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last)
gpointer user_data)
{
gssize imin, imax, imid;
int cmp;
g_return_val_if_fail(list || !len, ~((gssize) 0));
g_return_val_if_fail(cmpfcn, ~((gssize) 0));
imin = 0;
if (len > 0) {
imax = len - 1;
while (imin <= imax) {
imid = imin + (imax - imin) / 2;
cmp = cmpfcn(list[imid], needle, user_data);
if (cmp == 0)
return imid;
if (cmp < 0)
imin = imid + 1;
else
imax = imid - 1;
}
}
/* return the inverse of @imin. This is a negative number, but
* also is ~imin the position where the value should be inserted. */
imin = ~imin;
return imin;
}
gssize
nm_utils_ptrarray_find_binary_search_range(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last)
{
gssize imin, imax, imid, i2min, i2max, i2mid;
int cmp;

View file

@ -2018,9 +2018,15 @@ gssize nm_utils_ptrarray_find_binary_search(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last);
gpointer user_data);
gssize nm_utils_ptrarray_find_binary_search_range(gconstpointer * list,
gsize len,
gconstpointer needle,
GCompareDataFunc cmpfcn,
gpointer user_data,
gssize * out_idx_first,
gssize * out_idx_last);
#define nm_utils_strv_find_binary_search(strv, len, needle) \
({ \
@ -2035,8 +2041,6 @@ gssize nm_utils_ptrarray_find_binary_search(gconstpointer * list,
_len, \
_needle, \
nm_strcmp_with_data, \
NULL, \
NULL, \
NULL); \
})