mdbx: refine/optimize update-gc (remove anything in our spill list from parent's dirty list).

Change-Id: I945bdbc1431bac39173121210e1a08787e027b0c
This commit is contained in:
Leonid Yuriev 2019-10-17 10:13:18 +03:00
parent 781a814864
commit b11d655173

View File

@ -5264,7 +5264,7 @@ retry:
txn->tw.loose_count = 0; txn->tw.loose_count = 0;
} }
// handle retired-list - store ones into single gc-record /* handle retired-list - store ones into single gc-record */
if (retired_stored < MDBX_PNL_SIZE(txn->tw.retired_pages)) { if (retired_stored < MDBX_PNL_SIZE(txn->tw.retired_pages)) {
if (unlikely(!retired_stored)) { if (unlikely(!retired_stored)) {
/* Make sure last page of GC is touched and on retired-list */ /* Make sure last page of GC is touched and on retired-list */
@ -5306,7 +5306,7 @@ retry:
continue; continue;
} }
// handle reclaimed and loost pages - merge and store both into gc /* handle reclaimed and loost pages - merge and store both into gc */
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));
mdbx_tassert(txn, txn->tw.loose_count == 0); mdbx_tassert(txn, txn->tw.loose_count == 0);
@ -5941,45 +5941,64 @@ int mdbx_txn_commit(MDBX_txn *txn) {
MDBX_DPL src = mdbx_dpl_sort(txn->tw.dirtylist); MDBX_DPL src = mdbx_dpl_sort(txn->tw.dirtylist);
if (likely(src->length > 0) && parent->tw.spill_pages && if (likely(src->length > 0) && parent->tw.spill_pages &&
MDBX_PNL_SIZE(parent->tw.spill_pages) > 0) { MDBX_PNL_SIZE(parent->tw.spill_pages) > 0) {
MDBX_PNL ps = parent->tw.spill_pages; MDBX_PNL sp = parent->tw.spill_pages;
assert(mdbx_pnl_check4assert(ps, txn->mt_next_pgno)); assert(mdbx_pnl_check4assert(sp, txn->mt_next_pgno));
const unsigned pslen = MDBX_PNL_SIZE(parent->tw.spill_pages); const unsigned len = MDBX_PNL_SIZE(parent->tw.spill_pages);
MDBX_PNL_SIZE(ps) = ~(pgno_t)0; MDBX_PNL_SIZE(sp) = ~(pgno_t)0;
/* Mark our dirty pages as deleted in parent spill list */ /* Mark our dirty pages as deleted in parent spill list */
unsigned r, w, i = 1; unsigned r, w, i = 1;
w = r = pslen; w = r = len;
do { do {
pgno_t pn = src[i].pgno << 1; pgno_t pn = src[i].pgno << 1;
while (pn > ps[r]) while (pn > sp[r])
r--; r--;
if (pn == ps[r]) { if (pn == sp[r]) {
ps[r] = 1; sp[r] = 1;
w = --r; w = --r;
} }
} while (++i <= src->length); } while (++i <= src->length);
/* Squash deleted pagenums if we deleted any */ /* Squash deleted pagenums if we deleted any */
for (r = w; ++r <= pslen;) for (r = w; ++r <= len;)
if ((ps[r] & 1) == 0) if ((sp[r] & 1) == 0)
ps[++w] = ps[r]; sp[++w] = sp[r];
MDBX_PNL_SIZE(ps) = w; MDBX_PNL_SIZE(sp) = w;
assert(mdbx_pnl_check4assert(ps, txn->mt_next_pgno << 1)); assert(mdbx_pnl_check4assert(sp, txn->mt_next_pgno << 1));
} }
/* Remove anything in our spill list from parent's dirty list */ /* Remove anything in our spill list from parent's dirty list */
if (txn->tw.spill_pages && MDBX_PNL_SIZE(txn->tw.spill_pages) > 0) { if (txn->tw.spill_pages && MDBX_PNL_SIZE(txn->tw.spill_pages) > 0) {
unsigned i = 1; const MDBX_PNL sp = txn->tw.spill_pages;
do { mdbx_pnl_sort(sp);
pgno_t pn = txn->tw.spill_pages[i]; /* Scanning in ascend order */
if (pn & 1) const int step = MDBX_PNL_ASCENDING ? 1 : -1;
continue; /* deleted spillpg */ const int begin = MDBX_PNL_ASCENDING ? 1 : MDBX_PNL_SIZE(sp);
parent->tw.dirtyroom += 1; const int end = MDBX_PNL_ASCENDING ? MDBX_PNL_SIZE(sp) + 1 : 0;
MDBX_page *dp = mdbx_dpl_remove(dst, pn >> 1); mdbx_tassert(txn, sp[begin] <= sp[end - step]);
if ((env->me_flags & MDBX_WRITEMAP) == 0)
mdbx_dpage_free(env, dp, 1); unsigned r, w = r = mdbx_dpl_search(dst, sp[begin] >> 1);
} while (++i <= MDBX_PNL_SIZE(txn->tw.spill_pages)); mdbx_tassert(txn, dst->sorted == dst->length);
for (int i = begin; r <= dst->length;) {
mdbx_tassert(txn, (sp[i] & 1) == 0);
const pgno_t pgno = sp[i] >> 1;
if (dst[r].pgno < pgno) {
dst[w++] = dst[r++];
} else if (dst[r].pgno > pgno) {
i += step;
if (i == end)
while (r <= dst->length)
dst[w++] = dst[r++];
} else {
MDBX_page *dp = dst[r++].ptr;
if ((env->me_flags & MDBX_WRITEMAP) == 0)
mdbx_dpage_free(env, dp, IS_OVERFLOW(dp) ? dp->mp_pages : 1);
}
}
mdbx_tassert(txn, r == dst->length + 1);
dst->length = w;
parent->tw.dirtyroom += r - w;
} }
assert(dst->sorted == dst->length); assert(dst->sorted == dst->length);
mdbx_tassert(parent, mdbx_tassert(parent,