mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-09 02:14:13 +08:00
mdbx: backport - refine backlog preparation inside update_gc().
Change-Id: Ib18842c2922afba794d6ab69337580bcea29bfe6
This commit is contained in:
parent
5c488d7033
commit
c7674f671d
29
src/mdbx.c
29
src/mdbx.c
@ -3455,7 +3455,7 @@ static __inline int mdbx_backlog_size(MDBX_txn *txn) {
|
||||
int reclaimed = txn->mt_env->me_reclaimed_pglist
|
||||
? txn->mt_env->me_reclaimed_pglist[0]
|
||||
: 0;
|
||||
return reclaimed + txn->mt_loose_count + txn->mt_end_pgno - txn->mt_next_pgno;
|
||||
return reclaimed + txn->mt_loose_count;
|
||||
}
|
||||
|
||||
static __inline int mdbx_backlog_extragap(MDBX_env *env) {
|
||||
@ -3468,7 +3468,9 @@ static __inline int mdbx_backlog_extragap(MDBX_env *env) {
|
||||
* in mdbx_page_alloc() during a deleting, when freeDB tree is unbalanced. */
|
||||
static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
/* LY: extra page(s) for b-tree rebalancing */
|
||||
const int extra = mdbx_backlog_extragap(txn->mt_env);
|
||||
const int extra =
|
||||
mdbx_backlog_extragap(txn->mt_env) +
|
||||
MDBX_PNL_SIZEOF(txn->mt_befree_pages) / txn->mt_env->me_maxkey_limit;
|
||||
|
||||
if (mdbx_backlog_size(txn) < mc->mc_db->md_depth + extra) {
|
||||
mc->mc_flags &= ~C_RECLAIMING;
|
||||
@ -3476,11 +3478,10 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
|
||||
int backlog;
|
||||
while (unlikely((backlog = mdbx_backlog_size(txn)) < extra)) {
|
||||
while (unlikely(mdbx_backlog_size(txn) < extra)) {
|
||||
rc = mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC);
|
||||
if (unlikely(rc)) {
|
||||
if (unlikely(rc != MDBX_NOTFOUND))
|
||||
if (rc != MDBX_NOTFOUND)
|
||||
return rc;
|
||||
break;
|
||||
}
|
||||
@ -3491,6 +3492,20 @@ static int mdbx_prep_backlog(MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
static void mdbx_prep_backlog_data(MDBX_txn *txn, MDBX_cursor *mc,
|
||||
size_t bytes) {
|
||||
const int wanna =
|
||||
(int)OVPAGES(txn->mt_env, bytes) + mdbx_backlog_extragap(txn->mt_env);
|
||||
if (unlikely(wanna > mdbx_backlog_size(txn))) {
|
||||
mc->mc_flags &= ~C_RECLAIMING;
|
||||
do {
|
||||
if (mdbx_page_alloc(mc, 1, NULL, MDBX_ALLOC_GC) != MDBX_SUCCESS)
|
||||
break;
|
||||
} while (wanna > mdbx_backlog_size(txn));
|
||||
mc->mc_flags |= C_RECLAIMING;
|
||||
}
|
||||
}
|
||||
|
||||
/* Cleanup reclaimed GC records, than save the befree-list as of this
|
||||
* transaction to GC (aka freeDB). This recursive changes the reclaimed-list
|
||||
* loose-list and befree-list. Keep trying until it stabilizes. */
|
||||
@ -3683,7 +3698,7 @@ retry:
|
||||
mc.mc_flags &= ~C_RECLAIMING;
|
||||
rc = mdbx_page_search(&mc, NULL, MDBX_PS_LAST | MDBX_PS_MODIFY);
|
||||
mc.mc_flags |= C_RECLAIMING;
|
||||
if (unlikely(rc != MDBX_SUCCESS && rc != MDBX_NOTFOUND))
|
||||
if (unlikely(rc != MDBX_SUCCESS) && rc != MDBX_NOTFOUND)
|
||||
goto bailout;
|
||||
}
|
||||
/* Write to last page of freeDB */
|
||||
@ -3691,6 +3706,7 @@ retry:
|
||||
key.iov_base = &txn->mt_txnid;
|
||||
do {
|
||||
data.iov_len = MDBX_PNL_SIZEOF(txn->mt_befree_pages);
|
||||
mdbx_prep_backlog_data(txn, &mc, data.iov_len);
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
goto bailout;
|
||||
@ -3888,6 +3904,7 @@ retry:
|
||||
data.iov_len = (chunk + 1) * sizeof(pgno_t);
|
||||
mdbx_trace("%s.reserve: %u [%u...%u] @%" PRIaTXN, dbg_prefix_mode, chunk,
|
||||
settled + 1, settled + chunk + 1, reservation_gc_id);
|
||||
mdbx_prep_backlog_data(txn, &mc, data.iov_len);
|
||||
rc = mdbx_cursor_put(&mc, &key, &data, MDBX_RESERVE | MDBX_NOOVERWRITE);
|
||||
mdbx_tassert(txn, mdbx_pnl_check(env->me_reclaimed_pglist));
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
|
Loading…
x
Reference in New Issue
Block a user