mirror of
https://github.com/isar/libmdbx.git
synced 2025-04-20 03:57:47 +08:00
mdbx: rewrite internal bsearch for pages-lists.
Change-Id: I77615a2146d83d4304c05c3bafb8bfc89a1a4fd0
This commit is contained in:
parent
aceab9be44
commit
f3a51be7ff
@ -944,6 +944,42 @@ static int lcklist_detach_locked(MDBX_env *env) {
|
|||||||
SORT_SHELLPASS(TYPE, CMP, begin, end, 1); \
|
SORT_SHELLPASS(TYPE, CMP, begin, end, 1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*------------------------------------------------------------------------------
|
||||||
|
* LY: Binary search */
|
||||||
|
|
||||||
|
#define SEARCH_IMPL(NAME, TYPE_LIST, TYPE_ARG, CMP) \
|
||||||
|
static __always_inline TYPE_LIST *NAME(TYPE_LIST *first, unsigned length, \
|
||||||
|
const TYPE_ARG item) { \
|
||||||
|
while (length > 3) { \
|
||||||
|
const size_t half = length >> 1; \
|
||||||
|
TYPE_LIST *const middle = first + half; \
|
||||||
|
if (CMP(*middle, item)) { \
|
||||||
|
first = middle + 1; \
|
||||||
|
length -= half + 1; \
|
||||||
|
} else \
|
||||||
|
length = half; \
|
||||||
|
} \
|
||||||
|
\
|
||||||
|
switch (length) { \
|
||||||
|
case 3: \
|
||||||
|
if (!CMP(*first, item)) \
|
||||||
|
break; \
|
||||||
|
++first; \
|
||||||
|
/* fall through */ \
|
||||||
|
__fallthrough; \
|
||||||
|
case 2: \
|
||||||
|
if (!CMP(*first, item)) \
|
||||||
|
break; \
|
||||||
|
++first; \
|
||||||
|
/* fall through */ \
|
||||||
|
__fallthrough; \
|
||||||
|
case 1: \
|
||||||
|
if (CMP(*first, item)) \
|
||||||
|
++first; \
|
||||||
|
} \
|
||||||
|
return first; \
|
||||||
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
static __inline size_t pnl2bytes(const size_t size) {
|
static __inline size_t pnl2bytes(const size_t size) {
|
||||||
@ -1132,37 +1168,19 @@ static __hot void mdbx_pnl_sort(MDBX_PNL pnl) {
|
|||||||
* [in] pl The PNL to search.
|
* [in] pl The PNL to search.
|
||||||
* [in] id The ID to search for.
|
* [in] id The ID to search for.
|
||||||
* Returns The index of the first ID greater than or equal to id. */
|
* Returns The index of the first ID greater than or equal to id. */
|
||||||
static unsigned __hot mdbx_pnl_search(MDBX_PNL pnl, pgno_t id) {
|
SEARCH_IMPL(pgno_bsearch, pgno_t, pgno_t, MDBX_PNL_ORDERED)
|
||||||
|
|
||||||
|
static __noinline __hot unsigned mdbx_pnl_search(MDBX_PNL pnl, pgno_t id) {
|
||||||
assert(mdbx_pnl_check(pnl, true));
|
assert(mdbx_pnl_check(pnl, true));
|
||||||
|
pgno_t *begin = MDBX_PNL_BEGIN(pnl);
|
||||||
/* binary search of id in pl
|
pgno_t *it = pgno_bsearch(begin, MDBX_PNL_SIZE(pnl), id);
|
||||||
* if found, returns position of id
|
pgno_t *end = begin + MDBX_PNL_SIZE(pnl);
|
||||||
* if not found, returns first position greater than id */
|
assert(it >= begin && it <= end);
|
||||||
unsigned base = 0;
|
if (it != begin)
|
||||||
unsigned cursor = 1;
|
assert(it[-1] < id);
|
||||||
int val = 0;
|
if (it != end)
|
||||||
unsigned n = MDBX_PNL_SIZE(pnl);
|
assert(it[0] >= id);
|
||||||
|
return (unsigned)(it - begin);
|
||||||
while (n > 0) {
|
|
||||||
unsigned pivot = n >> 1;
|
|
||||||
cursor = base + pivot + 1;
|
|
||||||
val = MDBX_PNL_ASCENDING ? mdbx_cmp2int(id, pnl[cursor])
|
|
||||||
: mdbx_cmp2int(pnl[cursor], id);
|
|
||||||
|
|
||||||
if (val < 0) {
|
|
||||||
n = pivot;
|
|
||||||
} else if (val > 0) {
|
|
||||||
base = cursor;
|
|
||||||
n -= pivot + 1;
|
|
||||||
} else {
|
|
||||||
return cursor;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (val > 0)
|
|
||||||
++cursor;
|
|
||||||
|
|
||||||
return cursor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
@ -8896,7 +8914,8 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
if (unlikely(mc->mc_xcursor == NULL))
|
if (unlikely(mc->mc_xcursor == NULL))
|
||||||
return MDBX_INCOMPATIBLE;
|
return MDBX_INCOMPATIBLE;
|
||||||
/* FALLTHRU */
|
/* fall through */
|
||||||
|
__fallthrough;
|
||||||
case MDBX_SET:
|
case MDBX_SET:
|
||||||
case MDBX_SET_KEY:
|
case MDBX_SET_KEY:
|
||||||
case MDBX_SET_RANGE:
|
case MDBX_SET_RANGE:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user