mirror of
https://github.com/isar/libmdbx.git
synced 2025-05-12 16:27:46 +08:00
mdbx: добавление rkl_find()
и rkl_merge()
.
This commit is contained in:
parent
a56f5acc3d
commit
02b56e185f
69
src/rkl.c
69
src/rkl.c
@ -118,17 +118,11 @@ int rkl_copy(const rkl_t *src, rkl_t *dst) {
|
||||
|
||||
size_t rkl_len(const rkl_t *rkl) { return rkl_empty(rkl) ? 0 : rkl->solid_end - rkl->solid_begin + rkl->list_length; }
|
||||
|
||||
__hot bool rkl_find(const rkl_t *rkl, txnid_t id, rkl_iter_t *iter) {
|
||||
__hot bool rkl_contain(const rkl_t *rkl, txnid_t id) {
|
||||
assert(rkl_check(rkl));
|
||||
if (!rkl_empty(rkl)) {
|
||||
if (id >= rkl->solid_begin && id < rkl->solid_end) {
|
||||
if (iter) {
|
||||
*iter = rkl_iterator(rkl, false);
|
||||
iter->pos = iter->solid_offset + id - rkl->solid_begin;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
if (id >= rkl->solid_begin && id < rkl->solid_end)
|
||||
return true;
|
||||
if (rkl->list_length) {
|
||||
const txnid_t *it = rkl_bsearch(rkl->list, rkl->list_length, id);
|
||||
const txnid_t *const end = rkl->list + rkl->list_length;
|
||||
assert(it >= rkl->list && it <= end);
|
||||
@ -136,13 +130,32 @@ __hot bool rkl_find(const rkl_t *rkl, txnid_t id, rkl_iter_t *iter) {
|
||||
assert(RKL_ORDERED(it[-1], id));
|
||||
if (it != end) {
|
||||
assert(!RKL_ORDERED(it[0], id));
|
||||
if (*it == id) {
|
||||
if (iter) {
|
||||
*iter = rkl_iterator(rkl, false);
|
||||
iter->pos = it - rkl->list;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
return *it == id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
__hot bool rkl_find(const rkl_t *rkl, txnid_t id, rkl_iter_t *iter) {
|
||||
assert(rkl_check(rkl));
|
||||
*iter = rkl_iterator(rkl, false);
|
||||
if (id >= rkl->solid_begin) {
|
||||
if (id < rkl->solid_end) {
|
||||
iter->pos = iter->solid_offset + (unsigned)(id - rkl->solid_begin);
|
||||
return true;
|
||||
}
|
||||
iter->pos = (unsigned)(rkl->solid_end - rkl->solid_begin);
|
||||
}
|
||||
if (rkl->list_length) {
|
||||
const txnid_t *it = rkl_bsearch(rkl->list, rkl->list_length, id);
|
||||
const txnid_t *const end = rkl->list + rkl->list_length;
|
||||
assert(it >= rkl->list && it <= end);
|
||||
if (it != rkl->list)
|
||||
assert(RKL_ORDERED(it[-1], id));
|
||||
iter->pos += (unsigned)(it - rkl->list);
|
||||
if (it != end) {
|
||||
assert(!RKL_ORDERED(it[0], id));
|
||||
return *it == id;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
@ -366,7 +379,6 @@ txnid_t rkl_pop(rkl_t *rkl, const bool highest_not_lowest) {
|
||||
txnid_t rkl_lowest(const rkl_t *rkl) {
|
||||
if (rkl->list_length)
|
||||
return (solid_empty(rkl) || rkl->list[0] < rkl->solid_begin) ? rkl->list[0] : rkl->solid_begin;
|
||||
|
||||
return !solid_empty(rkl) ? rkl->solid_begin : INVALID_TXNID;
|
||||
}
|
||||
|
||||
@ -374,10 +386,29 @@ txnid_t rkl_highest(const rkl_t *rkl) {
|
||||
if (rkl->list_length)
|
||||
return (solid_empty(rkl) || rkl->list[rkl->list_length - 1] >= rkl->solid_end) ? rkl->list[rkl->list_length - 1]
|
||||
: rkl->solid_end - 1;
|
||||
|
||||
return !solid_empty(rkl) ? rkl->solid_end - 1 : 0;
|
||||
}
|
||||
|
||||
int rkl_merge(rkl_t *dst, const rkl_t *src, bool ignore_duplicates) {
|
||||
if (src->list_length) {
|
||||
size_t i = src->list_length;
|
||||
do {
|
||||
int err = rkl_push(dst, src->list[i - 1], false);
|
||||
if (unlikely(err != MDBX_SUCCESS) && (!ignore_duplicates || err != MDBX_RESULT_TRUE))
|
||||
return err;
|
||||
} while (--i);
|
||||
}
|
||||
|
||||
txnid_t id = src->solid_begin;
|
||||
while (id < src->solid_end) {
|
||||
int err = rkl_push(dst, id, false);
|
||||
if (unlikely(err != MDBX_SUCCESS) && (!ignore_duplicates || err != MDBX_RESULT_TRUE))
|
||||
return err;
|
||||
++id;
|
||||
}
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
rkl_iter_t rkl_iterator(const rkl_t *rkl, const bool reverse) {
|
||||
rkl_iter_t iter = {.rkl = rkl, .pos = reverse ? rkl_len(rkl) : 0, .solid_offset = 0};
|
||||
if (!solid_empty(rkl) && rkl->list_length) {
|
||||
|
@ -50,6 +50,7 @@ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline txnid_t rkl_edge(cons
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL __must_check_result int rkl_push(rkl_t *rkl, const txnid_t id,
|
||||
const bool known_continuous);
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL txnid_t rkl_pop(rkl_t *rkl, const bool highest_not_lowest);
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL __must_check_result int rkl_merge(rkl_t *dst, const rkl_t *src, bool ignore_duplicates);
|
||||
|
||||
/* Итератор для rkl.
|
||||
* Обеспечивает изоляцию внутреннего устройства rkl от остального кода, чем существенно его упрощает.
|
||||
@ -63,11 +64,9 @@ typedef struct MDBX_rkl_iter {
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL __must_check_result rkl_iter_t rkl_iterator(const rkl_t *rkl, const bool reverse);
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL __must_check_result txnid_t rkl_turn(rkl_iter_t *iter, const bool reverse);
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION MDBX_INTERNAL size_t rkl_left(rkl_iter_t *iter, const bool reverse);
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL __must_check_result bool rkl_find(const rkl_t *rkl, const txnid_t id, rkl_iter_t *iter);
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION __must_check_result static inline bool rkl_contain(const rkl_t *rkl,
|
||||
txnid_t id) {
|
||||
return rkl_find(rkl, id, nullptr);
|
||||
}
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL bool rkl_find(const rkl_t *rkl, const txnid_t id, rkl_iter_t *iter);
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION __must_check_result MDBX_INTERNAL bool rkl_contain(const rkl_t *rkl,
|
||||
txnid_t id);
|
||||
|
||||
typedef struct MDBX_rkl_hole {
|
||||
txnid_t begin;
|
||||
|
Loading…
x
Reference in New Issue
Block a user