mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:44:12 +08:00
mdbx: refine/optimize mdbx_page_alloc().
Change-Id: Iebbb8a611a82a379cf23b683bb21c9b6626ea9a5
This commit is contained in:
parent
36477ef408
commit
15ce797863
@ -3203,7 +3203,7 @@ bailout:
|
|||||||
*
|
*
|
||||||
* If there are free pages available from older transactions, they
|
* If there are free pages available from older transactions, they
|
||||||
* are re-used first. Otherwise allocate a new page at mt_next_pgno.
|
* are re-used first. Otherwise allocate a new page at mt_next_pgno.
|
||||||
* Do not modify the freedB, just merge GC records into mt_reclaimed_pglist
|
* Do not modify the GC, just merge GC records into mt_reclaimed_pglist
|
||||||
* and move mt_last_reclaimed to say which records were consumed. Only this
|
* and move mt_last_reclaimed to say which records were consumed. Only this
|
||||||
* function can create mt_reclaimed_pglist and move
|
* function can create mt_reclaimed_pglist and move
|
||||||
* mt_last_reclaimed/mt_next_pgno.
|
* mt_last_reclaimed/mt_next_pgno.
|
||||||
@ -3272,8 +3272,8 @@ skip_cache:
|
|||||||
|
|
||||||
mdbx_tassert(
|
mdbx_tassert(
|
||||||
txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist, txn->mt_next_pgno));
|
txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist, txn->mt_next_pgno));
|
||||||
pgno_t pgno, *repg_list = txn->tw.reclaimed_pglist;
|
pgno_t pgno, *re_list = txn->tw.reclaimed_pglist;
|
||||||
unsigned repg_pos = 0, repg_len = MDBX_PNL_SIZE(repg_list);
|
unsigned range_begin = 0, re_len = MDBX_PNL_SIZE(re_list);
|
||||||
txnid_t oldest = 0, last = 0;
|
txnid_t oldest = 0, last = 0;
|
||||||
const unsigned wanna_range = num - 1;
|
const unsigned wanna_range = num - 1;
|
||||||
|
|
||||||
@ -3293,24 +3293,33 @@ skip_cache:
|
|||||||
* Prefer pages with lower pgno. */
|
* Prefer pages with lower pgno. */
|
||||||
mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist,
|
mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist,
|
||||||
txn->mt_next_pgno));
|
txn->mt_next_pgno));
|
||||||
if (likely(flags & MDBX_ALLOC_CACHE) && repg_len > wanna_range &&
|
if (likely(flags & MDBX_ALLOC_CACHE) && re_len > wanna_range &&
|
||||||
(!(flags & MDBX_COALESCE) || op == MDBX_FIRST)) {
|
(!(flags & MDBX_COALESCE) || op == MDBX_FIRST)) {
|
||||||
mdbx_tassert(txn, MDBX_PNL_LAST(repg_list) < txn->mt_next_pgno &&
|
mdbx_tassert(txn, MDBX_PNL_LAST(re_list) < txn->mt_next_pgno &&
|
||||||
MDBX_PNL_FIRST(repg_list) < txn->mt_next_pgno);
|
MDBX_PNL_FIRST(re_list) < txn->mt_next_pgno);
|
||||||
|
range_begin = MDBX_PNL_ASCENDING ? 1 : re_len;
|
||||||
|
pgno = MDBX_PNL_LEAST(re_list);
|
||||||
|
if (likely(wanna_range == 0))
|
||||||
|
goto done;
|
||||||
#if MDBX_PNL_ASCENDING
|
#if MDBX_PNL_ASCENDING
|
||||||
for (repg_pos = 1; repg_pos <= repg_len - wanna_range; ++repg_pos) {
|
mdbx_tassert(txn, pgno == re_list[1] && range_begin == 1);
|
||||||
pgno = repg_list[repg_pos];
|
while (true) {
|
||||||
if (likely(repg_list[repg_pos + wanna_range - 1] ==
|
unsigned range_end = range_begin + wanna_range;
|
||||||
pgno + wanna_range - 1))
|
if (re_list[range_end] - pgno == wanna_range)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (range_end == re_len)
|
||||||
|
break;
|
||||||
|
pgno = re_list[++range_begin];
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
repg_pos = repg_len;
|
mdbx_tassert(txn, pgno == re_list[re_len] && range_begin == re_len);
|
||||||
do {
|
while (true) {
|
||||||
pgno = repg_list[repg_pos];
|
if (re_list[range_begin - wanna_range] - pgno == wanna_range)
|
||||||
if (likely(repg_list[repg_pos - wanna_range] == pgno + wanna_range))
|
|
||||||
goto done;
|
goto done;
|
||||||
} while (--repg_pos > wanna_range);
|
if (range_begin == wanna_range)
|
||||||
|
break;
|
||||||
|
pgno = re_list[--range_begin];
|
||||||
|
}
|
||||||
#endif /* MDBX_PNL sort-order */
|
#endif /* MDBX_PNL sort-order */
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3369,7 +3378,15 @@ skip_cache:
|
|||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
last = *(txnid_t *)key.iov_base;
|
if (unlikely(key.iov_len != sizeof(txnid_t))) {
|
||||||
|
rc = MDBX_CORRUPTED;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
memcpy(&last, key.iov_base, sizeof(txnid_t));
|
||||||
|
if (unlikely(last < 1 || last >= SAFE64_INVALID_THRESHOLD)) {
|
||||||
|
rc = MDBX_CORRUPTED;
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
if (oldest <= last) {
|
if (oldest <= last) {
|
||||||
oldest = mdbx_find_oldest(txn);
|
oldest = mdbx_find_oldest(txn);
|
||||||
if (oldest <= last) {
|
if (oldest <= last) {
|
||||||
@ -3407,20 +3424,20 @@ skip_cache:
|
|||||||
|
|
||||||
/* Append PNL from GC record to me_reclaimed_pglist */
|
/* Append PNL from GC record to me_reclaimed_pglist */
|
||||||
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
||||||
pgno_t *re_pnl = (pgno_t *)data.iov_base;
|
pgno_t *gc_pnl = (pgno_t *)data.iov_base;
|
||||||
mdbx_tassert(txn, data.iov_len >= MDBX_PNL_SIZEOF(re_pnl));
|
mdbx_tassert(txn, data.iov_len >= MDBX_PNL_SIZEOF(gc_pnl));
|
||||||
if (unlikely(data.iov_len < MDBX_PNL_SIZEOF(re_pnl) ||
|
if (unlikely(data.iov_len < MDBX_PNL_SIZEOF(gc_pnl) ||
|
||||||
!mdbx_pnl_check(re_pnl, txn->mt_next_pgno))) {
|
!mdbx_pnl_check(gc_pnl, txn->mt_next_pgno))) {
|
||||||
rc = MDBX_CORRUPTED;
|
rc = MDBX_CORRUPTED;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
repg_pos = MDBX_PNL_SIZE(re_pnl);
|
const unsigned gc_len = MDBX_PNL_SIZE(gc_pnl);
|
||||||
rc = mdbx_pnl_need(&txn->tw.reclaimed_pglist, repg_pos);
|
rc = mdbx_pnl_need(&txn->tw.reclaimed_pglist, gc_len);
|
||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
goto fail;
|
goto fail;
|
||||||
repg_list = txn->tw.reclaimed_pglist;
|
re_list = txn->tw.reclaimed_pglist;
|
||||||
|
|
||||||
/* Remember ID of FreeDB record */
|
/* Remember ID of GC record */
|
||||||
if (flags & MDBX_LIFORECLAIM) {
|
if (flags & MDBX_LIFORECLAIM) {
|
||||||
if ((rc = mdbx_txl_append(&txn->tw.lifo_reclaimed, last)) != 0)
|
if ((rc = mdbx_txl_append(&txn->tw.lifo_reclaimed, last)) != 0)
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -3430,66 +3447,76 @@ skip_cache:
|
|||||||
if (mdbx_log_enabled(MDBX_LOG_EXTRA)) {
|
if (mdbx_log_enabled(MDBX_LOG_EXTRA)) {
|
||||||
mdbx_debug_extra("PNL read txn %" PRIaTXN " root %" PRIaPGNO
|
mdbx_debug_extra("PNL read txn %" PRIaTXN " root %" PRIaPGNO
|
||||||
" num %u, PNL",
|
" num %u, PNL",
|
||||||
last, txn->mt_dbs[FREE_DBI].md_root, repg_pos);
|
last, txn->mt_dbs[FREE_DBI].md_root, gc_len);
|
||||||
unsigned i;
|
unsigned i;
|
||||||
for (i = repg_pos; i; i--)
|
for (i = gc_len; i; i--)
|
||||||
mdbx_debug_extra_print(" %" PRIaPGNO, re_pnl[i]);
|
mdbx_debug_extra_print(" %" PRIaPGNO, gc_pnl[i]);
|
||||||
mdbx_debug_extra_print("\n");
|
mdbx_debug_extra_print("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Merge in descending sorted order */
|
/* Merge in descending sorted order */
|
||||||
mdbx_pnl_xmerge(repg_list, re_pnl);
|
const unsigned prev_re_len = MDBX_PNL_SIZE(re_list);
|
||||||
|
mdbx_pnl_xmerge(re_list, gc_pnl);
|
||||||
/* re-check to avoid duplicates */
|
/* re-check to avoid duplicates */
|
||||||
if (unlikely(!mdbx_pnl_check(repg_list, txn->mt_next_pgno))) {
|
if (unlikely(!mdbx_pnl_check(re_list, txn->mt_next_pgno))) {
|
||||||
rc = MDBX_CORRUPTED;
|
rc = MDBX_CORRUPTED;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
repg_len = MDBX_PNL_SIZE(repg_list);
|
|
||||||
|
re_len = MDBX_PNL_SIZE(re_list);
|
||||||
|
mdbx_tassert(txn, re_len == 0 || re_list[re_len] < txn->mt_next_pgno);
|
||||||
|
if (re_len && unlikely(MDBX_PNL_MOST(re_list) == txn->mt_next_pgno - 1)) {
|
||||||
|
/* Refund suitable pages into "unallocated" space */
|
||||||
|
mdbx_refund(txn);
|
||||||
|
re_list = txn->tw.reclaimed_pglist;
|
||||||
|
re_len = MDBX_PNL_SIZE(re_list);
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely((flags & MDBX_ALLOC_CACHE) == 0)) {
|
if (unlikely((flags & MDBX_ALLOC_CACHE) == 0)) {
|
||||||
/* Done for a kick-reclaim mode, actually no page needed */
|
/* Done for a kick-reclaim mode, actually no page needed */
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdbx_tassert(txn,
|
|
||||||
repg_len == 0 || repg_list[repg_len] < txn->mt_next_pgno);
|
|
||||||
if (repg_len &&
|
|
||||||
unlikely(MDBX_PNL_MOST(repg_list) == txn->mt_next_pgno - 1)) {
|
|
||||||
/* Refund suitable pages into "unallocated" space */
|
|
||||||
mdbx_refund(txn);
|
|
||||||
repg_list = txn->tw.reclaimed_pglist;
|
|
||||||
repg_len = MDBX_PNL_SIZE(repg_list);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Don't try to coalesce too much. */
|
/* Don't try to coalesce too much. */
|
||||||
if (unlikely(repg_len > MDBX_DPL_TXNFULL / 4))
|
if (unlikely(re_len > MDBX_DPL_TXNFULL / 4))
|
||||||
break;
|
break;
|
||||||
if (repg_len /* current size */ >= env->me_maxgc_ov1page ||
|
if (re_len /* current size */ >= env->me_maxgc_ov1page ||
|
||||||
repg_pos /* prev size */ >= env->me_maxgc_ov1page / 2)
|
(re_len > prev_re_len && re_len - prev_re_len /* delta from prev */ >=
|
||||||
|
env->me_maxgc_ov1page / 2))
|
||||||
flags &= ~MDBX_COALESCE;
|
flags &= ~MDBX_COALESCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((flags & (MDBX_COALESCE | MDBX_ALLOC_CACHE)) ==
|
if ((flags & (MDBX_COALESCE | MDBX_ALLOC_CACHE)) ==
|
||||||
(MDBX_COALESCE | MDBX_ALLOC_CACHE) &&
|
(MDBX_COALESCE | MDBX_ALLOC_CACHE) &&
|
||||||
repg_len > wanna_range) {
|
re_len > wanna_range) {
|
||||||
|
range_begin = MDBX_PNL_ASCENDING ? 1 : re_len;
|
||||||
|
pgno = MDBX_PNL_LEAST(re_list);
|
||||||
|
if (likely(wanna_range == 0))
|
||||||
|
goto done;
|
||||||
#if MDBX_PNL_ASCENDING
|
#if MDBX_PNL_ASCENDING
|
||||||
for (repg_pos = 1; repg_pos <= repg_len - wanna_range; ++repg_pos) {
|
mdbx_tassert(txn, pgno == re_list[1] && range_begin == 1);
|
||||||
pgno = repg_list[repg_pos];
|
while (true) {
|
||||||
if (likely(repg_list[repg_pos + wanna_range - 1] ==
|
unsigned range_end = range_begin + wanna_range;
|
||||||
pgno + wanna_range - 1))
|
if (re_list[range_end] - pgno == wanna_range)
|
||||||
goto done;
|
goto done;
|
||||||
|
if (range_end == re_len)
|
||||||
|
break;
|
||||||
|
pgno = re_list[++range_begin];
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
repg_pos = repg_len;
|
mdbx_tassert(txn, pgno == re_list[re_len] && range_begin == re_len);
|
||||||
do {
|
while (true) {
|
||||||
pgno = repg_list[repg_pos];
|
if (re_list[range_begin - wanna_range] - pgno == wanna_range)
|
||||||
if (likely(repg_list[repg_pos - wanna_range] == pgno + wanna_range))
|
|
||||||
goto done;
|
goto done;
|
||||||
} while (--repg_pos > wanna_range);
|
if (range_begin == wanna_range)
|
||||||
|
break;
|
||||||
|
pgno = re_list[--range_begin];
|
||||||
|
}
|
||||||
#endif /* MDBX_PNL sort-order */
|
#endif /* MDBX_PNL sort-order */
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use new pages from the map when nothing suitable in the GC */
|
/* Use new pages from the map when nothing suitable in the GC */
|
||||||
repg_pos = 0;
|
range_begin = 0;
|
||||||
pgno = txn->mt_next_pgno;
|
pgno = txn->mt_next_pgno;
|
||||||
rc = MDBX_MAP_FULL;
|
rc = MDBX_MAP_FULL;
|
||||||
const pgno_t next = pgno_add(pgno, num);
|
const pgno_t next = pgno_add(pgno, num);
|
||||||
@ -3590,14 +3617,20 @@ done:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (repg_pos) {
|
if (range_begin) {
|
||||||
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
||||||
mdbx_tassert(txn, pgno < txn->mt_next_pgno);
|
mdbx_tassert(txn, pgno < txn->mt_next_pgno);
|
||||||
mdbx_tassert(txn, pgno == repg_list[repg_pos]);
|
mdbx_tassert(txn, pgno == re_list[range_begin]);
|
||||||
/* Cutoff allocated pages from me_reclaimed_pglist */
|
/* Cutoff allocated pages from me_reclaimed_pglist */
|
||||||
MDBX_PNL_SIZE(repg_list) = repg_len -= num;
|
#if MDBX_PNL_ASCENDING
|
||||||
for (unsigned i = repg_pos - num; i < repg_len;)
|
for (unsigned i = range_begin + num; i <= re_len;)
|
||||||
repg_list[++i] = repg_list[++repg_pos];
|
re_list[range_begin++] = re_list[i++];
|
||||||
|
MDBX_PNL_SIZE(re_list) = re_len = range_begin - 1;
|
||||||
|
#else
|
||||||
|
MDBX_PNL_SIZE(re_list) = re_len -= num;
|
||||||
|
for (unsigned i = range_begin - num; i < re_len;)
|
||||||
|
re_list[++i] = re_list[++range_begin];
|
||||||
|
#endif
|
||||||
mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist,
|
mdbx_tassert(txn, mdbx_pnl_check4assert(txn->tw.reclaimed_pglist,
|
||||||
txn->mt_next_pgno));
|
txn->mt_next_pgno));
|
||||||
} else {
|
} else {
|
||||||
@ -3606,7 +3639,7 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(env->me_flags & MDBX_PAGEPERTURB))
|
if (unlikely(env->me_flags & MDBX_PAGEPERTURB))
|
||||||
memset(np, 0x71 /* 'q', 113 */, pgno2bytes(env, num));
|
memset(np, -1, pgno2bytes(env, num));
|
||||||
VALGRIND_MAKE_MEM_UNDEFINED(np, pgno2bytes(env, num));
|
VALGRIND_MAKE_MEM_UNDEFINED(np, pgno2bytes(env, num));
|
||||||
|
|
||||||
np->mp_pgno = pgno;
|
np->mp_pgno = pgno;
|
||||||
@ -5369,7 +5402,7 @@ retry:
|
|||||||
rc = mdbx_page_alloc(&mc, 0, NULL, MDBX_ALLOC_GC | MDBX_ALLOC_KICK);
|
rc = mdbx_page_alloc(&mc, 0, NULL, MDBX_ALLOC_GC | MDBX_ALLOC_KICK);
|
||||||
mc.mc_flags |= C_RECLAIMING;
|
mc.mc_flags |= C_RECLAIMING;
|
||||||
if (likely(rc == MDBX_SUCCESS)) {
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
/* LY: ok, reclaimed from freedb. */
|
/* LY: ok, reclaimed from GC. */
|
||||||
mdbx_trace("%s: took @%" PRIaTXN " from GC, continue",
|
mdbx_trace("%s: took @%" PRIaTXN " from GC, continue",
|
||||||
dbg_prefix_mode, MDBX_PNL_LAST(txn->tw.lifo_reclaimed));
|
dbg_prefix_mode, MDBX_PNL_LAST(txn->tw.lifo_reclaimed));
|
||||||
continue;
|
continue;
|
||||||
@ -5378,7 +5411,7 @@ retry:
|
|||||||
/* LY: other troubles... */
|
/* LY: other troubles... */
|
||||||
goto bailout;
|
goto bailout;
|
||||||
|
|
||||||
/* LY: freedb is empty, will look any free txn-id in high2low order. */
|
/* LY: GC is empty, will look any free txn-id in high2low order. */
|
||||||
do {
|
do {
|
||||||
--head_gc_id;
|
--head_gc_id;
|
||||||
mdbx_assert(env,
|
mdbx_assert(env,
|
||||||
@ -5479,7 +5512,7 @@ retry:
|
|||||||
mdbx_tassert(txn, reservation_gc_id < *env->me_oldest);
|
mdbx_tassert(txn, reservation_gc_id < *env->me_oldest);
|
||||||
if (unlikely(reservation_gc_id < 1 ||
|
if (unlikely(reservation_gc_id < 1 ||
|
||||||
reservation_gc_id >= *env->me_oldest)) {
|
reservation_gc_id >= *env->me_oldest)) {
|
||||||
/* LY: not any txn in the past of freedb. */
|
/* LY: not any txn in the past of GC. */
|
||||||
rc = MDBX_PROBLEM;
|
rc = MDBX_PROBLEM;
|
||||||
goto bailout;
|
goto bailout;
|
||||||
}
|
}
|
||||||
@ -6414,20 +6447,20 @@ static int __cold mdbx_read_header(MDBX_env *env, MDBX_meta *meta,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* LY: FreeDB root */
|
/* LY: GC root */
|
||||||
if (page.mp_meta.mm_dbs[FREE_DBI].md_root == P_INVALID) {
|
if (page.mp_meta.mm_dbs[FREE_DBI].md_root == P_INVALID) {
|
||||||
if (page.mp_meta.mm_dbs[FREE_DBI].md_branch_pages ||
|
if (page.mp_meta.mm_dbs[FREE_DBI].md_branch_pages ||
|
||||||
page.mp_meta.mm_dbs[FREE_DBI].md_depth ||
|
page.mp_meta.mm_dbs[FREE_DBI].md_depth ||
|
||||||
page.mp_meta.mm_dbs[FREE_DBI].md_entries ||
|
page.mp_meta.mm_dbs[FREE_DBI].md_entries ||
|
||||||
page.mp_meta.mm_dbs[FREE_DBI].md_leaf_pages ||
|
page.mp_meta.mm_dbs[FREE_DBI].md_leaf_pages ||
|
||||||
page.mp_meta.mm_dbs[FREE_DBI].md_overflow_pages) {
|
page.mp_meta.mm_dbs[FREE_DBI].md_overflow_pages) {
|
||||||
mdbx_notice("meta[%u] has false-empty freedb, skip it", meta_number);
|
mdbx_notice("meta[%u] has false-empty GC, skip it", meta_number);
|
||||||
rc = MDBX_CORRUPTED;
|
rc = MDBX_CORRUPTED;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else if (page.mp_meta.mm_dbs[FREE_DBI].md_root >=
|
} else if (page.mp_meta.mm_dbs[FREE_DBI].md_root >=
|
||||||
page.mp_meta.mm_geo.next) {
|
page.mp_meta.mm_geo.next) {
|
||||||
mdbx_notice("meta[%u] has invalid freedb-root %" PRIaPGNO ", skip it",
|
mdbx_notice("meta[%u] has invalid GC-root %" PRIaPGNO ", skip it",
|
||||||
meta_number, page.mp_meta.mm_dbs[FREE_DBI].md_root);
|
meta_number, page.mp_meta.mm_dbs[FREE_DBI].md_root);
|
||||||
rc = MDBX_CORRUPTED;
|
rc = MDBX_CORRUPTED;
|
||||||
continue;
|
continue;
|
||||||
@ -8744,8 +8777,8 @@ __hot static int mdbx_page_search_root(MDBX_cursor *mc, MDBX_val *key,
|
|||||||
|
|
||||||
mdbx_debug("branch page %" PRIaPGNO " has %u keys", mp->mp_pgno,
|
mdbx_debug("branch page %" PRIaPGNO " has %u keys", mp->mp_pgno,
|
||||||
NUMKEYS(mp));
|
NUMKEYS(mp));
|
||||||
/* Don't assert on branch pages in the FreeDB. We can get here
|
/* Don't assert on branch pages in the GC. We can get here
|
||||||
* while in the process of rebalancing a FreeDB branch page; we must
|
* while in the process of rebalancing a GC branch page; we must
|
||||||
* let that proceed. ITS#8336 */
|
* let that proceed. ITS#8336 */
|
||||||
mdbx_cassert(mc, !mc->mc_dbi || NUMKEYS(mp) > 1);
|
mdbx_cassert(mc, !mc->mc_dbi || NUMKEYS(mp) > 1);
|
||||||
mdbx_debug("found index 0 to page %" PRIaPGNO, NODEPGNO(NODEPTR(mp, 0)));
|
mdbx_debug("found index 0 to page %" PRIaPGNO, NODEPGNO(NODEPTR(mp, 0)));
|
||||||
@ -11738,7 +11771,7 @@ static int mdbx_page_merge(MDBX_cursor *csrc, MDBX_cursor *cdst) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If not operating on FreeDB, allow this page to be reused
|
/* If not operating on GC, allow this page to be reused
|
||||||
* in this txn. Otherwise just add to free list. */
|
* in this txn. Otherwise just add to free list. */
|
||||||
rc = mdbx_page_retire(csrc, psrc);
|
rc = mdbx_page_retire(csrc, psrc);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
|
@ -438,7 +438,7 @@ typedef struct MDBX_meta {
|
|||||||
* P_META pages contain MDBX_meta, the start point of an MDBX snapshot.
|
* P_META pages contain MDBX_meta, the start point of an MDBX snapshot.
|
||||||
*
|
*
|
||||||
* Each non-metapage up to MDBX_meta.mm_last_pg is reachable exactly once
|
* Each non-metapage up to MDBX_meta.mm_last_pg is reachable exactly once
|
||||||
* in the snapshot: Either used by a database or listed in a freeDB record. */
|
* in the snapshot: Either used by a database or listed in a GC record. */
|
||||||
typedef struct MDBX_page {
|
typedef struct MDBX_page {
|
||||||
union {
|
union {
|
||||||
struct MDBX_page *mp_next; /* for in-memory list of freed pages */
|
struct MDBX_page *mp_next; /* for in-memory list of freed pages */
|
||||||
@ -829,7 +829,7 @@ struct MDBX_txn {
|
|||||||
MDBX_reader *reader;
|
MDBX_reader *reader;
|
||||||
} to;
|
} to;
|
||||||
struct {
|
struct {
|
||||||
pgno_t *reclaimed_pglist; /* Reclaimed freeDB pages */
|
pgno_t *reclaimed_pglist; /* Reclaimed GC pages */
|
||||||
txnid_t last_reclaimed; /* ID of last used record */
|
txnid_t last_reclaimed; /* ID of last used record */
|
||||||
pgno_t loose_refund_wl /* FIXME: describe */;
|
pgno_t loose_refund_wl /* FIXME: describe */;
|
||||||
/* dirtylist room: Dirty array size - dirty pages visible to this txn.
|
/* dirtylist room: Dirty array size - dirty pages visible to this txn.
|
||||||
@ -904,7 +904,7 @@ struct MDBX_cursor {
|
|||||||
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
#define C_SUB 0x04 /* Cursor is a sub-cursor */
|
||||||
#define C_DEL 0x08 /* last op was a cursor_del */
|
#define C_DEL 0x08 /* last op was a cursor_del */
|
||||||
#define C_UNTRACK 0x10 /* Un-track cursor when closing */
|
#define C_UNTRACK 0x10 /* Un-track cursor when closing */
|
||||||
#define C_RECLAIMING 0x20 /* FreeDB lookup is prohibited */
|
#define C_RECLAIMING 0x20 /* GC lookup is prohibited */
|
||||||
#define C_GCFREEZE 0x40 /* reclaimed_pglist must not be updated */
|
#define C_GCFREEZE 0x40 /* reclaimed_pglist must not be updated */
|
||||||
unsigned mc_flags; /* see mdbx_cursor */
|
unsigned mc_flags; /* see mdbx_cursor */
|
||||||
MDBX_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
MDBX_page *mc_pg[CURSOR_STACK]; /* stack of pushed pages */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user