mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-20 05:58:21 +08:00
mdbx: add MDBX_PNL_MAX and checking size of lists.
Change-Id: I32e31d2caf676e1e96cc4f82610544b5c5ee3a6d
This commit is contained in:
parent
b4fd29a67b
commit
c472300b13
@ -512,6 +512,7 @@ typedef MDBX_ID2 *MDBX_ID2L;
|
||||
|
||||
#define MDBX_PNL_DB_MAX (MDBX_PNL_DB_SIZE - 1)
|
||||
#define MDBX_PNL_UM_MAX (MDBX_PNL_UM_SIZE - 1)
|
||||
#define MDBX_PNL_MAX (MAX_PAGENO / 4)
|
||||
|
||||
#define MDBX_PNL_SIZEOF(pl) (((pl)[0] + 1) * sizeof(pgno_t))
|
||||
#define MDBX_PNL_IS_ZERO(pl) ((pl)[0] == 0)
|
||||
|
127
src/mdbx.c
127
src/mdbx.c
@ -501,6 +501,7 @@ __cold void mdbx_rthc_remove(const mdbx_thread_key_t key) {
|
||||
* Allocates memory for an PNL of the given size.
|
||||
* Returns PNL on success, NULL on failure. */
|
||||
static MDBX_PNL mdbx_pnl_alloc(size_t size) {
|
||||
assert(size <= MDBX_PNL_MAX);
|
||||
MDBX_PNL pl = malloc((size + 2) * sizeof(pgno_t));
|
||||
if (likely(pl)) {
|
||||
*pl++ = (pgno_t)size;
|
||||
@ -540,8 +541,11 @@ static __inline void mdbx_pnl_xappend(MDBX_PNL pl, pgno_t id) {
|
||||
pl[pl[0] += 1] = id;
|
||||
}
|
||||
|
||||
static bool mdbx_pnl_check(MDBX_PNL pl) {
|
||||
static bool mdbx_pnl_check(MDBX_PNL pl, bool allocated) {
|
||||
if (pl) {
|
||||
if (allocated) {
|
||||
assert(pl[0] <= MDBX_PNL_MAX && pl[0] <= pl[-1]);
|
||||
}
|
||||
for (const pgno_t *ptr = pl + pl[0]; --ptr > pl;) {
|
||||
assert(MDBX_PNL_ORDERED(ptr[0], ptr[1]));
|
||||
assert(ptr[0] >= NUM_METAS);
|
||||
@ -555,6 +559,7 @@ static bool mdbx_pnl_check(MDBX_PNL pl) {
|
||||
/* Sort an PNL.
|
||||
* [in,out] pnl The PNL to sort. */
|
||||
static void __hot mdbx_pnl_sort(MDBX_PNL pnl) {
|
||||
assert(pnl[0] <= MDBX_PNL_MAX && pnl[0] <= pnl[-1]);
|
||||
/* Max possible depth of int-indexed tree * 2 items/level */
|
||||
int istack[sizeof(int) * CHAR_BIT * 2];
|
||||
int i, j, k, l, ir, jstack;
|
||||
@ -629,7 +634,7 @@ static void __hot mdbx_pnl_sort(MDBX_PNL pnl) {
|
||||
}
|
||||
#undef PNL_SMALL
|
||||
#undef PNL_SWAP
|
||||
assert(mdbx_pnl_check(pnl));
|
||||
assert(mdbx_pnl_check(pnl, true));
|
||||
}
|
||||
|
||||
/* Search for an ID in an PNL.
|
||||
@ -637,7 +642,7 @@ static void __hot mdbx_pnl_sort(MDBX_PNL pnl) {
|
||||
* [in] id The ID to search for.
|
||||
* 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) {
|
||||
assert(mdbx_pnl_check(pnl));
|
||||
assert(mdbx_pnl_check(pnl, true));
|
||||
|
||||
/* binary search of id in pl
|
||||
* if found, returns position of id
|
||||
@ -687,18 +692,23 @@ static void mdbx_pnl_shrink(MDBX_PNL *ppl) {
|
||||
/* Grow an PNL.
|
||||
* Return the PNL to the size growed by given number.
|
||||
* [in,out] ppl Address of the PNL to grow. */
|
||||
static int mdbx_pnl_grow(MDBX_PNL *ppl, size_t num) {
|
||||
static int __must_check_result mdbx_pnl_grow(MDBX_PNL *ppl, size_t num) {
|
||||
MDBX_PNL idn = *ppl - 1;
|
||||
assert(idn[0] <= MDBX_PNL_MAX && idn[0] <= idn[-1]);
|
||||
assert(num <= MDBX_PNL_MAX);
|
||||
num += *idn;
|
||||
if (unlikely(num > MDBX_PNL_MAX))
|
||||
return MDBX_TXN_FULL;
|
||||
/* grow it */
|
||||
idn = realloc(idn, (*idn + num + 2) * sizeof(pgno_t));
|
||||
idn = realloc(idn, (num + 2) * sizeof(pgno_t));
|
||||
if (unlikely(!idn))
|
||||
return MDBX_ENOMEM;
|
||||
*idn++ += (pgno_t)num;
|
||||
*ppl = idn;
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static int mdbx_txl_grow(MDBX_TXL *ptr, size_t num) {
|
||||
static int __must_check_result mdbx_txl_grow(MDBX_TXL *ptr, size_t num) {
|
||||
MDBX_TXL list = *ptr - 1;
|
||||
/* grow it */
|
||||
list = realloc(list, ((size_t)*list + num + 2) * sizeof(txnid_t));
|
||||
@ -706,85 +716,96 @@ static int mdbx_txl_grow(MDBX_TXL *ptr, size_t num) {
|
||||
return MDBX_ENOMEM;
|
||||
*list++ += num;
|
||||
*ptr = list;
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Make room for num additional elements in an PNL.
|
||||
* [in,out] ppl Address of the PNL.
|
||||
* [in] num Number of elements to make room for.
|
||||
* Returns 0 on success, MDBX_ENOMEM on failure. */
|
||||
static int mdbx_pnl_need(MDBX_PNL *ppl, size_t num) {
|
||||
static int __must_check_result mdbx_pnl_need(MDBX_PNL *ppl, size_t num) {
|
||||
MDBX_PNL pl = *ppl;
|
||||
assert(pl[0] <= MDBX_PNL_MAX && pl[0] <= pl[-1]);
|
||||
assert(num <= MDBX_PNL_MAX);
|
||||
num += pl[0];
|
||||
if (unlikely(num > pl[-1])) {
|
||||
num = (num + num / 4 + (256 + 2)) & -256;
|
||||
if (unlikely(num > MDBX_PNL_MAX))
|
||||
return MDBX_TXN_FULL;
|
||||
num = (num + num / 4 + (256 + 2)) & ~255u;
|
||||
num = (num < MDBX_PNL_MAX + 2) ? num : MDBX_PNL_MAX + 2;
|
||||
pl = realloc(pl - 1, num * sizeof(pgno_t));
|
||||
if (unlikely(!pl))
|
||||
return MDBX_ENOMEM;
|
||||
*pl++ = (pgno_t)num - 2;
|
||||
*ppl = pl;
|
||||
}
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Append an ID onto an PNL.
|
||||
* [in,out] ppl Address of the PNL to append to.
|
||||
* [in] id The ID to append.
|
||||
* Returns 0 on success, MDBX_ENOMEM if the PNL is too large. */
|
||||
static int mdbx_pnl_append(MDBX_PNL *ppl, pgno_t id) {
|
||||
static int __must_check_result mdbx_pnl_append(MDBX_PNL *ppl, pgno_t id) {
|
||||
MDBX_PNL pl = *ppl;
|
||||
/* Too big? */
|
||||
if (unlikely(pl[0] >= pl[-1])) {
|
||||
if (mdbx_pnl_grow(ppl, MDBX_PNL_UM_MAX))
|
||||
return MDBX_ENOMEM;
|
||||
int rc = mdbx_pnl_grow(ppl, MDBX_PNL_UM_MAX);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
pl = *ppl;
|
||||
}
|
||||
pl[0]++;
|
||||
pl[pl[0]] = id;
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static int mdbx_txl_append(MDBX_TXL *ptr, txnid_t id) {
|
||||
static int __must_check_result mdbx_txl_append(MDBX_TXL *ptr, txnid_t id) {
|
||||
MDBX_TXL list = *ptr;
|
||||
/* Too big? */
|
||||
if (unlikely(list[0] >= list[-1])) {
|
||||
if (mdbx_txl_grow(ptr, (size_t)list[0]))
|
||||
return MDBX_ENOMEM;
|
||||
int rc = mdbx_txl_grow(ptr, (size_t)list[0]);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
list = *ptr;
|
||||
}
|
||||
list[0]++;
|
||||
list[list[0]] = id;
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Append an PNL onto an PNL.
|
||||
* [in,out] ppl Address of the PNL to append to.
|
||||
* [in] app The PNL to append.
|
||||
* Returns 0 on success, MDBX_ENOMEM if the PNL is too large. */
|
||||
static int mdbx_pnl_append_list(MDBX_PNL *ppl, MDBX_PNL app) {
|
||||
static int __must_check_result mdbx_pnl_append_list(MDBX_PNL *ppl,
|
||||
MDBX_PNL app) {
|
||||
MDBX_PNL pnl = *ppl;
|
||||
/* Too big? */
|
||||
if (unlikely(pnl[0] + app[0] >= pnl[-1])) {
|
||||
if (mdbx_pnl_grow(ppl, app[0]))
|
||||
return MDBX_ENOMEM;
|
||||
int rc = mdbx_pnl_grow(ppl, app[0]);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
pnl = *ppl;
|
||||
}
|
||||
memcpy(&pnl[pnl[0] + 1], &app[1], app[0] * sizeof(pgno_t));
|
||||
pnl[0] += app[0];
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) {
|
||||
static int __must_check_result mdbx_txl_append_list(MDBX_TXL *ptr,
|
||||
MDBX_TXL append) {
|
||||
MDBX_TXL list = *ptr;
|
||||
/* Too big? */
|
||||
if (unlikely(list[0] + append[0] >= list[-1])) {
|
||||
if (mdbx_txl_grow(ptr, (size_t)append[0]))
|
||||
return MDBX_ENOMEM;
|
||||
int rc = mdbx_txl_grow(ptr, (size_t)append[0]);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
list = *ptr;
|
||||
}
|
||||
memcpy(&list[list[0] + 1], &append[1], (size_t)append[0] * sizeof(txnid_t));
|
||||
list[0] += append[0];
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Append an ID range onto an PNL.
|
||||
@ -792,27 +813,29 @@ static int mdbx_txl_append_list(MDBX_TXL *ptr, MDBX_TXL append) {
|
||||
* [in] id The lowest ID to append.
|
||||
* [in] n Number of IDs to append.
|
||||
* Returns 0 on success, MDBX_ENOMEM if the PNL is too large. */
|
||||
static int mdbx_pnl_append_range(MDBX_PNL *ppl, pgno_t id, size_t n) {
|
||||
static int __must_check_result mdbx_pnl_append_range(MDBX_PNL *ppl, pgno_t id,
|
||||
size_t n) {
|
||||
pgno_t *pnl = *ppl, len = pnl[0];
|
||||
/* Too big? */
|
||||
if (unlikely(len + n > pnl[-1])) {
|
||||
if (mdbx_pnl_grow(ppl, n | MDBX_PNL_UM_MAX))
|
||||
return MDBX_ENOMEM;
|
||||
int rc = mdbx_pnl_grow(ppl, n | MDBX_PNL_UM_MAX);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
pnl = *ppl;
|
||||
}
|
||||
pnl[0] = len + (pgno_t)n;
|
||||
pnl += len;
|
||||
while (n)
|
||||
pnl[n--] = id++;
|
||||
return 0;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
/* Merge an PNL onto an PNL. The destination PNL must be big enough.
|
||||
* [in] pl The PNL to merge into.
|
||||
* [in] merge The PNL to merge. */
|
||||
static void __hot mdbx_pnl_xmerge(MDBX_PNL pnl, MDBX_PNL merge) {
|
||||
assert(mdbx_pnl_check(pnl));
|
||||
assert(mdbx_pnl_check(merge));
|
||||
assert(mdbx_pnl_check(pnl, true));
|
||||
assert(mdbx_pnl_check(merge, false));
|
||||
pgno_t old_id, merge_id, i = merge[0], j = pnl[0], k = i + j, total = k;
|
||||
pnl[0] =
|
||||
MDBX_PNL_ASCENDING ? 0 : ~(pgno_t)0; /* delimiter for pl scan below */
|
||||
@ -824,7 +847,7 @@ static void __hot mdbx_pnl_xmerge(MDBX_PNL pnl, MDBX_PNL merge) {
|
||||
pnl[k--] = merge_id;
|
||||
}
|
||||
pnl[0] = total;
|
||||
assert(mdbx_pnl_check(pnl));
|
||||
assert(mdbx_pnl_check(pnl, true));
|
||||
}
|
||||
|
||||
/* Search for an ID in an ID2L.
|
||||
@ -2171,7 +2194,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
||||
}
|
||||
}
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
pgno_t pgno, *repg_list = env->me_reclaimed_pglist;
|
||||
unsigned repg_pos = 0, repg_len = repg_list ? repg_list[0] : 0;
|
||||
txnid_t oldest = 0, last = 0;
|
||||
@ -2191,7 +2214,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
||||
|
||||
/* Seek a big enough contiguous page range.
|
||||
* Prefer pages with lower pgno. */
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (likely(flags & MDBX_ALLOC_CACHE) && repg_len > wanna_range &&
|
||||
(!(flags & MDBX_COALESCE) || op == MDBX_FIRST)) {
|
||||
#if MDBX_PNL_ASCENDING
|
||||
@ -2305,7 +2328,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
||||
pgno_t *re_pnl = (pgno_t *)data.iov_base;
|
||||
mdbx_tassert(txn, re_pnl[0] == 0 ||
|
||||
data.iov_len == (re_pnl[0] + 1) * sizeof(pgno_t));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(re_pnl));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(re_pnl, false));
|
||||
repg_pos = re_pnl[0];
|
||||
if (!repg_list) {
|
||||
if (unlikely(!(env->me_reclaimed_pglist = repg_list =
|
||||
@ -2375,7 +2398,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
||||
mdbx_info("refunded %" PRIaPGNO " pages: %" PRIaPGNO " -> %" PRIaPGNO,
|
||||
tail - txn->mt_next_pgno, tail, txn->mt_next_pgno);
|
||||
txn->mt_next_pgno = tail;
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -2485,7 +2508,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, unsigned num, MDBX_page **mp,
|
||||
}
|
||||
|
||||
fail:
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (mp) {
|
||||
*mp = NULL;
|
||||
txn->mt_flags |= MDBX_TXN_ERROR;
|
||||
@ -2516,7 +2539,7 @@ done:
|
||||
repg_list[0] = repg_len -= num;
|
||||
for (unsigned i = repg_pos - num; i < repg_len;)
|
||||
repg_list[++i] = repg_list[++repg_pos];
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
} else {
|
||||
txn->mt_next_pgno = pgno + num;
|
||||
mdbx_assert(env, txn->mt_next_pgno <= txn->mt_end_pgno);
|
||||
@ -2533,7 +2556,7 @@ done:
|
||||
mdbx_page_dirty(txn, np);
|
||||
*mp = np;
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
@ -3510,14 +3533,14 @@ static int mdbx_freelist_save(MDBX_txn *txn) {
|
||||
(env->me_flags & (MDBX_NOMEMINIT | MDBX_WRITEMAP)) ? SSIZE_MAX
|
||||
: env->me_maxfree_1pg;
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
again_on_freelist_change:
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
while (1) {
|
||||
/* Come back here after each Put() in case freelist changed */
|
||||
MDBX_val key, data;
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (!lifo) {
|
||||
/* If using records from freeDB which we have not yet deleted,
|
||||
* now delete them and any we reserved for me_reclaimed_pglist. */
|
||||
@ -3560,7 +3583,7 @@ again_on_freelist_change:
|
||||
}
|
||||
}
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (txn->mt_loose_pages) {
|
||||
/* Return loose page numbers to me_reclaimed_pglist,
|
||||
* though usually none are left at this point.
|
||||
@ -3613,7 +3636,7 @@ again_on_freelist_change:
|
||||
txn->mt_loose_count = 0;
|
||||
}
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (env->me_reclaimed_pglist) {
|
||||
/* Refund suitable pages into "unallocated" space */
|
||||
pgno_t tail = txn->mt_next_pgno;
|
||||
@ -3641,7 +3664,7 @@ again_on_freelist_change:
|
||||
mdbx_info("refunded %" PRIaPGNO " pages: %" PRIaPGNO " -> %" PRIaPGNO,
|
||||
tail - txn->mt_next_pgno, tail, txn->mt_next_pgno);
|
||||
txn->mt_next_pgno = tail;
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
}
|
||||
}
|
||||
|
||||
@ -3682,7 +3705,7 @@ again_on_freelist_change:
|
||||
continue;
|
||||
}
|
||||
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
const intptr_t rpl_len =
|
||||
(env->me_reclaimed_pglist ? env->me_reclaimed_pglist[0] : 0) +
|
||||
txn->mt_loose_count;
|
||||
@ -3760,7 +3783,7 @@ again_on_freelist_change:
|
||||
key.iov_base = &head_id;
|
||||
data.iov_len = (head_room + 1) * sizeof(pgno_t);
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE);
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (unlikely(rc))
|
||||
goto bailout;
|
||||
|
||||
@ -3780,7 +3803,7 @@ again_on_freelist_change:
|
||||
|
||||
/* Fill in the reserved me_reclaimed_pglist records */
|
||||
rc = MDBX_SUCCESS;
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist, true));
|
||||
if (env->me_reclaimed_pglist && env->me_reclaimed_pglist[0]) {
|
||||
MDBX_val key, data;
|
||||
key.iov_len = data.iov_len = 0; /* avoid MSVC warning */
|
||||
@ -3831,11 +3854,11 @@ again_on_freelist_change:
|
||||
data.iov_base = rpl_end;
|
||||
pgno_t save = rpl_end[0];
|
||||
rpl_end[0] = (pgno_t)chunk_len;
|
||||
mdbx_tassert(txn, mdbx_pnl_check(rpl_end));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(rpl_end, false));
|
||||
mc.mc_flags |= C_RECLAIMING;
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_CURRENT);
|
||||
mc.mc_flags ^= C_RECLAIMING;
|
||||
mdbx_tassert(txn, mdbx_pnl_check(rpl_end));
|
||||
mdbx_tassert(txn, mdbx_pnl_check(rpl_end, false));
|
||||
mdbx_tassert(
|
||||
txn, cleanup_reclaimed_pos ==
|
||||
(txn->mt_lifo_reclaimed ? txn->mt_lifo_reclaimed[0] : 0));
|
||||
|
@ -340,7 +340,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
data->iov_len);
|
||||
else {
|
||||
const pgno_t number = *iptr++;
|
||||
if (number >= MDBX_PNL_UM_MAX)
|
||||
if (number < 1 || number > MDBX_PNL_MAX)
|
||||
problem_add("entry", record_number, "wrong idl length", "%" PRIiPTR "",
|
||||
number);
|
||||
else if ((number + 1) * sizeof(pgno_t) != data->iov_len)
|
||||
|
Loading…
x
Reference in New Issue
Block a user