mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-06 16:21:50 +00:00
glib-aux: add an inlinable version of nm_array_find_bsearch()
To implement binary search is not very hard. It's almost easy enough to just open-code it, without using the existing nm_array_find_bsearch() function. In particular, because nm_array_find_bsearch() won't be inlined, and thus it is slower than implementing it by hand. Add nm_array_find_bsearch_inline() as a variant that will be inlined. This actually is as fast as reimplementing it by hand (I measured), which takes away any reason to avoid the function. However, our headers get huge. That may be a problem for complication time. To counter that a bit, only define the function when the caller requests it with a NM_WANT_NM_ARRAY_FIND_BSEARCH_INLINE define.
This commit is contained in:
parent
2f0808a610
commit
28fa48aee4
|
@ -3,6 +3,8 @@
|
|||
* Copyright (C) 2016 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#define NM_WANT_NM_ARRAY_FIND_BSEARCH_INLINE
|
||||
|
||||
#include "libnm-glib-aux/nm-default-glib-i18n-lib.h"
|
||||
|
||||
#include "nm-shared-utils.h"
|
||||
|
@ -3943,37 +3945,7 @@ nm_array_find_bsearch(gconstpointer list,
|
|||
GCompareDataFunc cmpfcn,
|
||||
gpointer user_data)
|
||||
{
|
||||
gssize imax;
|
||||
gssize imid;
|
||||
gssize imin;
|
||||
int cmp;
|
||||
|
||||
nm_assert(list || len == 0);
|
||||
nm_assert(cmpfcn);
|
||||
nm_assert(elem_size > 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;
|
||||
return nm_array_find_bsearch_inline(list, len, elem_size, needle, cmpfcn, user_data);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
|
@ -2135,6 +2135,57 @@ gssize nm_ptrarray_find_bsearch_range(gconstpointer *list,
|
|||
NULL); \
|
||||
})
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
#ifdef NM_WANT_NM_ARRAY_FIND_BSEARCH_INLINE
|
||||
/**
|
||||
* nm_array_find_bsearch_inline:
|
||||
*
|
||||
* An inlined version of nm_array_find_bsearch(). See there.
|
||||
* Define NM_WANT_NM_ARRAY_FIND_BSEARCH_INLINE to get it.
|
||||
*/
|
||||
_nm_always_inline static inline gssize
|
||||
nm_array_find_bsearch_inline(gconstpointer list,
|
||||
gsize len,
|
||||
gsize elem_size,
|
||||
gconstpointer needle,
|
||||
GCompareDataFunc cmpfcn,
|
||||
gpointer user_data)
|
||||
{
|
||||
gssize imax;
|
||||
gssize imid;
|
||||
gssize imin;
|
||||
int cmp;
|
||||
|
||||
nm_assert(list || len == 0);
|
||||
nm_assert(cmpfcn);
|
||||
nm_assert(elem_size > 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;
|
||||
}
|
||||
#endif
|
||||
|
||||
gssize nm_array_find_bsearch(gconstpointer list,
|
||||
gsize len,
|
||||
gsize elem_size,
|
||||
|
@ -2142,6 +2193,8 @@ gssize nm_array_find_bsearch(gconstpointer list,
|
|||
GCompareDataFunc cmpfcn,
|
||||
gpointer user_data);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
gssize nm_utils_ptrarray_find_first(gconstpointer *list, gssize len, gconstpointer needle);
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
Loading…
Reference in a new issue