mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-21 02:04:17 +00:00
core: add _nm_utils_array_find_binary_search()
Also add nm_cmp_uint32_p_with_data(). Will be used later.
This commit is contained in:
parent
08f5681b0e
commit
c3ecca225c
|
@ -147,6 +147,7 @@ GPtrArray *_nm_utils_copy_object_array (const GPtrArray *array);
|
|||
gssize _nm_utils_ptrarray_find_first (gconstpointer *list, gssize len, gconstpointer needle);
|
||||
|
||||
gssize _nm_utils_ptrarray_find_binary_search (gconstpointer *list, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data);
|
||||
gssize _nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, gpointer user_data);
|
||||
|
||||
gssize _nm_utils_strv_find_first (char **list, gssize len, const char *needle);
|
||||
|
||||
|
|
|
@ -724,6 +724,40 @@ _nm_utils_ptrarray_find_binary_search (gconstpointer *list, gsize len, gconstpoi
|
|||
return ~imin;
|
||||
}
|
||||
|
||||
gssize
|
||||
_nm_utils_array_find_binary_search (gconstpointer list, gsize elem_size, gsize len, gconstpointer needle, GCompareDataFunc cmpfcn, 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));
|
||||
g_return_val_if_fail (elem_size > 0, ~((gssize) 0));
|
||||
|
||||
imin = 0;
|
||||
if (len == 0)
|
||||
return ~imin;
|
||||
|
||||
imax = len - 1;
|
||||
|
||||
while (imin <= imax) {
|
||||
imid = imin + (imax - imin) / 2;
|
||||
|
||||
cmp = cmpfcn (&((const char *) list)[elem_size * 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. */
|
||||
return ~imin;
|
||||
}
|
||||
|
||||
GVariant *
|
||||
_nm_utils_bytes_to_dbus (const GValue *prop_value)
|
||||
{
|
||||
|
|
|
@ -5006,10 +5006,51 @@ _test_find_binary_search_do (const int *array, gsize len)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
_test_find_binary_search_do_uint32 (const int *int_array, gsize len)
|
||||
{
|
||||
gssize idx;
|
||||
const int OFFSET = 100;
|
||||
const int NEEDLE = 0 + OFFSET;
|
||||
gssize expected_result = -1;
|
||||
guint32 array[len];
|
||||
|
||||
/* the test data has negative values. Shift them... */
|
||||
for (idx = 0; idx < len; idx++) {
|
||||
int v = int_array[idx];
|
||||
|
||||
g_assert (v > -OFFSET);
|
||||
g_assert (v < OFFSET);
|
||||
g_assert (idx == 0 || v > int_array[idx - 1]);
|
||||
array[idx] = (guint32) (int_array[idx] + OFFSET);
|
||||
if (array[idx] == NEEDLE)
|
||||
expected_result = idx;
|
||||
}
|
||||
|
||||
idx = _nm_utils_array_find_binary_search (array,
|
||||
sizeof (guint32),
|
||||
len,
|
||||
&NEEDLE,
|
||||
nm_cmp_uint32_p_with_data,
|
||||
NULL);
|
||||
if (expected_result >= 0)
|
||||
g_assert_cmpint (expected_result, ==, idx);
|
||||
else {
|
||||
gssize idx2 = ~idx;
|
||||
g_assert_cmpint (idx, <, 0);
|
||||
|
||||
g_assert (idx2 >= 0);
|
||||
g_assert (idx2 <= len);
|
||||
g_assert (idx2 - 1 < 0 || array[idx2 - 1] < NEEDLE);
|
||||
g_assert (idx2 >= len || array[idx2] > NEEDLE);
|
||||
}
|
||||
}
|
||||
#define test_find_binary_search_do(...) \
|
||||
G_STMT_START { \
|
||||
const int _array[] = { __VA_ARGS__ }; \
|
||||
_test_find_binary_search_do (_array, G_N_ELEMENTS (_array)); \
|
||||
_test_find_binary_search_do_uint32 (_array, G_N_ELEMENTS (_array)); \
|
||||
} G_STMT_END
|
||||
|
||||
static void
|
||||
|
|
|
@ -516,6 +516,19 @@ nm_strcmp_p_with_data (gconstpointer a, gconstpointer b, gpointer user_data)
|
|||
return strcmp (s1, s2);
|
||||
}
|
||||
|
||||
static inline int
|
||||
nm_cmp_uint32_p_with_data (gconstpointer p_a, gconstpointer p_b, gpointer user_data)
|
||||
{
|
||||
const guint32 a = *((const guint32 *) p_a);
|
||||
const guint32 b = *((const guint32 *) p_b);
|
||||
|
||||
if (a < b)
|
||||
return -1;
|
||||
if (a > b)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Taken from systemd's UNIQ_T and UNIQ macros. */
|
||||
|
|
Loading…
Reference in a new issue