From 6e4cdae25638284a77c8487fd062b46b1f5dfd9f Mon Sep 17 00:00:00 2001 From: Thomas Haller Date: Tue, 16 Mar 2021 09:29:53 +0100 Subject: [PATCH] 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. --- src/core/nm-config.c | 8 +--- src/libnm-client-impl/nm-libnm-utils.c | 2 - src/libnm-core-impl/nm-keyfile.c | 2 - src/libnm-core-impl/nm-utils.c | 2 - src/libnm-core-impl/tests/test-general.c | 50 ++++++++++++++++-------- src/libnm-glib-aux/nm-shared-utils.c | 43 ++++++++++++++++++-- src/libnm-glib-aux/nm-shared-utils.h | 14 ++++--- 7 files changed, 83 insertions(+), 38 deletions(-) diff --git a/src/core/nm-config.c b/src/core/nm-config.c index 4d61f1aa22..778ba25900 100644 --- a/src/core/nm-config.c +++ b/src/core/nm-config.c @@ -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. */ diff --git a/src/libnm-client-impl/nm-libnm-utils.c b/src/libnm-client-impl/nm-libnm-utils.c index fe1b911b68..3cc88ef4d8 100644 --- a/src/libnm-client-impl/nm-libnm-utils.c +++ b/src/libnm-client-impl/nm-libnm-utils.c @@ -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; diff --git a/src/libnm-core-impl/nm-keyfile.c b/src/libnm-core-impl/nm-keyfile.c index bc5398e7ba..bd89345506 100644 --- a/src/libnm-core-impl/nm-keyfile.c +++ b/src/libnm-core-impl/nm-keyfile.c @@ -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]; diff --git a/src/libnm-core-impl/nm-utils.c b/src/libnm-core-impl/nm-utils.c index 1296b6db12..202f160ead 100644 --- a/src/libnm-core-impl/nm-utils.c +++ b/src/libnm-core-impl/nm-utils.c @@ -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; diff --git a/src/libnm-core-impl/tests/test-general.c b/src/libnm-core-impl/tests/test-general.c index 0fb130997c..f75401693e 100644 --- a/src/libnm-core-impl/tests/test-general.c +++ b/src/libnm-core-impl/tests/test-general.c @@ -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); diff --git a/src/libnm-glib-aux/nm-shared-utils.c b/src/libnm-glib-aux/nm-shared-utils.c index d3effc551d..fe9994459f 100644 --- a/src/libnm-glib-aux/nm-shared-utils.c +++ b/src/libnm-glib-aux/nm-shared-utils.c @@ -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; diff --git a/src/libnm-glib-aux/nm-shared-utils.h b/src/libnm-glib-aux/nm-shared-utils.h index 588541e3fe..e33c1c19d6 100644 --- a/src/libnm-glib-aux/nm-shared-utils.h +++ b/src/libnm-glib-aux/nm-shared-utils.h @@ -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); \ })