mdbx: remove pp_txnid4chk(), preparing to rework of page checking/validation.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-06-30 13:42:10 +03:00
parent 48c6051482
commit 6c5ff863ff
2 changed files with 52 additions and 79 deletions

View File

@ -3856,11 +3856,9 @@ enum {
static int mdbx_txn_end(MDBX_txn *txn, const unsigned mode); static int mdbx_txn_end(MDBX_txn *txn, const unsigned mode);
__hot static struct page_result __must_check_result __hot static struct page_result __must_check_result
mdbx_page_get_ex(MDBX_cursor *const mc, const pgno_t pgno, txnid_t front); mdbx_page_get_ex(MDBX_cursor *const mc, const pgno_t pgno, const txnid_t front);
static __always_inline int __must_check_result mdbx_page_get(MDBX_cursor *mc, static __always_inline int __must_check_result mdbx_page_get(
pgno_t pgno, MDBX_cursor *mc, const pgno_t pgno, MDBX_page **mp, const txnid_t front) {
MDBX_page **mp,
txnid_t front) {
struct page_result ret = mdbx_page_get_ex(mc, pgno, front); struct page_result ret = mdbx_page_get_ex(mc, pgno, front);
*mp = ret.page; *mp = ret.page;
@ -4798,16 +4796,6 @@ static __inline void mdbx_page_wash(MDBX_txn *txn, const unsigned di,
mdbx_dpage_free(txn->mt_env, mp, npages); mdbx_dpage_free(txn->mt_env, mp, npages);
} }
static __inline txnid_t pp_txnid4chk(const MDBX_page *mp, const MDBX_txn *txn) {
(void)txn;
#if MDBX_DISABLE_PAGECHECKS
(void)mp;
return 0;
#else
return /* maybe zero in legacy DB */ mp->mp_txnid;
#endif /* !MDBX_DISABLE_PAGECHECKS */
}
/* Retire, loosen or free a single page. /* Retire, loosen or free a single page.
* *
* For dirty pages, saves single pages to a list for future reuse in this same * For dirty pages, saves single pages to a list for future reuse in this same
@ -6717,7 +6705,7 @@ page_alloc_slowpath(MDBX_cursor *mc, const pgno_t num, int flags) {
if (unlikely((ret.err = mdbx_node_read( if (unlikely((ret.err = mdbx_node_read(
&recur.outer, &recur.outer,
page_node(mp, recur.outer.mc_ki[recur.outer.mc_top]), page_node(mp, recur.outer.mc_ki[recur.outer.mc_top]),
&data, pp_txnid4chk(mp, txn))) != MDBX_SUCCESS)) &data, mp->mp_txnid)) != MDBX_SUCCESS))
goto fail; goto fail;
if ((flags & MDBX_LIFORECLAIM) && !txn->tw.lifo_reclaimed) { if ((flags & MDBX_LIFORECLAIM) && !txn->tw.lifo_reclaimed) {
@ -13923,9 +13911,9 @@ static __inline int mdbx_cursor_push(MDBX_cursor *mc, MDBX_page *mp) {
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
__hot static struct page_result __hot static struct page_result mdbx_page_get_ex(MDBX_cursor *const mc,
mdbx_page_get_ex(MDBX_cursor *const mc, const pgno_t pgno, const pgno_t pgno,
/* TODO: use parent-page ptr */ txnid_t front) { const txnid_t front) {
struct page_result ret; struct page_result ret;
MDBX_txn *const txn = mc->mc_txn; MDBX_txn *const txn = mc->mc_txn;
mdbx_tassert(txn, front <= txn->mt_front); mdbx_tassert(txn, front <= txn->mt_front);
@ -14058,8 +14046,8 @@ __hot static int mdbx_page_search_root(MDBX_cursor *mc, const MDBX_val *key,
mdbx_cassert(mc, i >= 0 && i < (int)page_numkeys(mp)); mdbx_cassert(mc, i >= 0 && i < (int)page_numkeys(mp));
node = page_node(mp, i); node = page_node(mp, i);
if (unlikely((rc = mdbx_page_get(mc, node_pgno(node), &mp, rc = mdbx_page_get(mc, node_pgno(node), &mp, mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn))) != 0)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
mc->mc_ki[mc->mc_top] = (indx_t)i; mc->mc_ki[mc->mc_top] = (indx_t)i;
@ -14155,8 +14143,7 @@ static int mdbx_fetch_sdb(MDBX_txn *txn, MDBX_dbi dbi) {
return MDBX_INCOMPATIBLE; /* not a named DB */ return MDBX_INCOMPATIBLE; /* not a named DB */
} }
const txnid_t pp_txnid = const txnid_t pp_txnid = couple.outer.mc_pg[couple.outer.mc_top]->mp_txnid;
pp_txnid4chk(couple.outer.mc_pg[couple.outer.mc_top], txn);
rc = mdbx_node_read(&couple.outer, nsr.node, &data, pp_txnid); rc = mdbx_node_read(&couple.outer, nsr.node, &data, pp_txnid);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -14208,10 +14195,9 @@ __hot static int mdbx_page_search_lowest(MDBX_cursor *mc) {
MDBX_page *mp = mc->mc_pg[mc->mc_top]; MDBX_page *mp = mc->mc_pg[mc->mc_top];
mdbx_cassert(mc, IS_BRANCH(mp)); mdbx_cassert(mc, IS_BRANCH(mp));
MDBX_node *node = page_node(mp, 0); MDBX_node *node = page_node(mp, 0);
int rc;
if (unlikely((rc = mdbx_page_get(mc, node_pgno(node), &mp, int rc = mdbx_page_get(mc, node_pgno(node), &mp, mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn))) != 0)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
mc->mc_ki[mc->mc_top] = 0; mc->mc_ki[mc->mc_top] = 0;
@ -14460,8 +14446,8 @@ static int mdbx_cursor_sibling(MDBX_cursor *mc, int dir) {
mdbx_cassert(mc, IS_BRANCH(mc->mc_pg[mc->mc_top])); mdbx_cassert(mc, IS_BRANCH(mc->mc_pg[mc->mc_top]));
node = page_node(mp = mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); node = page_node(mp = mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
if (unlikely((rc = mdbx_page_get(mc, node_pgno(node), &mp, rc = mdbx_page_get(mc, node_pgno(node), &mp, mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn))) != 0)) { if (unlikely(rc != MDBX_SUCCESS)) {
/* mc will be inconsistent if caller does mc_snum++ as above */ /* mc will be inconsistent if caller does mc_snum++ as above */
mc->mc_flags &= ~(C_INITIALIZED | C_EOF); mc->mc_flags &= ~(C_INITIALIZED | C_EOF);
return rc; return rc;
@ -14472,7 +14458,7 @@ static int mdbx_cursor_sibling(MDBX_cursor *mc, int dir) {
return rc; return rc;
mc->mc_ki[mc->mc_top] = mc->mc_ki[mc->mc_top] =
(indx_t)((dir == SIBLING_LEFT) ? page_numkeys(mp) - 1 : 0); (dir == SIBLING_LEFT) ? (indx_t)page_numkeys(mp) - 1 : 0;
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
@ -14528,8 +14514,8 @@ static int mdbx_cursor_next(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
if (unlikely(ki >= numkeys)) { if (unlikely(ki >= numkeys)) {
mdbx_debug("%s", "=====> move to next sibling page"); mdbx_debug("%s", "=====> move to next sibling page");
mc->mc_ki[mc->mc_top] = (indx_t)(numkeys - 1); mc->mc_ki[mc->mc_top] = (indx_t)(numkeys - 1);
if (unlikely((rc = mdbx_cursor_sibling(mc, SIBLING_RIGHT)) != rc = mdbx_cursor_sibling(mc, SIBLING_RIGHT);
MDBX_SUCCESS)) { if (unlikely(rc != MDBX_SUCCESS)) {
mc->mc_flags |= C_EOF; mc->mc_flags |= C_EOF;
return rc; return rc;
} }
@ -14567,9 +14553,8 @@ skip:
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
if (unlikely((rc = mdbx_node_read(mc, node, data, rc = mdbx_node_read(mc, node, data, mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn))) != if (unlikely(rc != MDBX_SUCCESS))
MDBX_SUCCESS))
return rc; return rc;
} }
@ -14662,9 +14647,8 @@ static int mdbx_cursor_prev(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
if (unlikely((rc = mdbx_node_read(mc, node, data, rc = mdbx_node_read(mc, node, data, mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn))) != if (unlikely(rc != MDBX_SUCCESS))
MDBX_SUCCESS))
return rc; return rc;
} }
@ -14927,7 +14911,7 @@ got_node:
} }
MDBX_val actual_data; MDBX_val actual_data;
ret.err = mdbx_node_read(mc, node, &actual_data, ret.err = mdbx_node_read(mc, node, &actual_data,
pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn)); mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
const int cmp = mc->mc_dbx->md_dcmp(&aligned_data, &actual_data); const int cmp = mc->mc_dbx->md_dcmp(&aligned_data, &actual_data);
@ -14942,8 +14926,7 @@ got_node:
} }
*data = actual_data; *data = actual_data;
} else { } else {
ret.err = mdbx_node_read(mc, node, data, ret.err = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid);
pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn));
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
} }
@ -15000,10 +14983,8 @@ static int mdbx_cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
if (unlikely((rc = mdbx_node_read( rc = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid);
mc, node, data, if (unlikely(rc != MDBX_SUCCESS))
pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn))) !=
MDBX_SUCCESS))
return rc; return rc;
} }
@ -15052,10 +15033,8 @@ static int mdbx_cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
if (unlikely((rc = mdbx_node_read( rc = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid);
mc, node, data, if (unlikely(rc != MDBX_SUCCESS))
pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn))) !=
MDBX_SUCCESS))
return rc; return rc;
} }
@ -15121,7 +15100,7 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
return rc; return rc;
} }
} else { } else {
rc = mdbx_node_read(mc, node, data, pp_txnid4chk(mp, mc->mc_txn)); rc = mdbx_node_read(mc, node, data, mp->mp_txnid);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} }
@ -15228,8 +15207,7 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
MDBX_node *node = page_node(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); MDBX_node *node = page_node(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
if (!F_ISSET(node_flags(node), F_DUPDATA)) { if (!F_ISSET(node_flags(node), F_DUPDATA)) {
get_key_optional(node, key); get_key_optional(node, key);
rc = mdbx_node_read(mc, node, data, rc = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid);
pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn));
break; break;
} }
} }
@ -15393,7 +15371,7 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
return MDBX_NOTFOUND; return MDBX_NOTFOUND;
} }
const txnid_t pp_txnid = pp_txnid4chk(page, mc->mc_txn); const txnid_t pp_txnid = page->mp_txnid;
do { do {
if (unlikely(n + 2 > limit)) { if (unlikely(n + 2 > limit)) {
rc = MDBX_RESULT_TRUE; rc = MDBX_RESULT_TRUE;
@ -15837,8 +15815,8 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
: 0; : 0;
const pgno_t pgno = node_largedata_pgno(node); const pgno_t pgno = node_largedata_pgno(node);
struct page_result pgr = mdbx_page_get_ex( struct page_result pgr =
mc, pgno, pp_txnid4chk(mc->mc_pg[mc->mc_top], mc->mc_txn)); mdbx_page_get_ex(mc, pgno, mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(pgr.err != MDBX_SUCCESS)) if (unlikely(pgr.err != MDBX_SUCCESS))
return pgr.err; return pgr.err;
if (unlikely(!IS_OVERFLOW(pgr.page))) if (unlikely(!IS_OVERFLOW(pgr.page)))
@ -16366,7 +16344,7 @@ int mdbx_cursor_del(MDBX_cursor *mc, MDBX_put_flags_t flags) {
if (F_ISSET(node_flags(node), F_BIGDATA)) { if (F_ISSET(node_flags(node), F_BIGDATA)) {
MDBX_page *omp; MDBX_page *omp;
if (unlikely((rc = mdbx_page_get(mc, node_largedata_pgno(node), &omp, if (unlikely((rc = mdbx_page_get(mc, node_largedata_pgno(node), &omp,
pp_txnid4chk(mp, mc->mc_txn))) || mp->mp_txnid)) ||
(rc = mdbx_page_retire(mc, omp)))) (rc = mdbx_page_retire(mc, omp))))
goto fail; goto fail;
} }
@ -17942,8 +17920,7 @@ static int mdbx_rebalance(MDBX_cursor *mc) {
} else if (IS_BRANCH(mp) && nkeys == 1) { } else if (IS_BRANCH(mp) && nkeys == 1) {
mdbx_debug("%s", "collapsing root page!"); mdbx_debug("%s", "collapsing root page!");
mc->mc_db->md_root = node_pgno(page_node(mp, 0)); mc->mc_db->md_root = node_pgno(page_node(mp, 0));
rc = mdbx_page_get(mc, mc->mc_db->md_root, &mc->mc_pg[0], rc = mdbx_page_get(mc, mc->mc_db->md_root, &mc->mc_pg[0], mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn));
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
mc->mc_db->md_depth--; mc->mc_db->md_depth--;
@ -18004,7 +17981,7 @@ static int mdbx_rebalance(MDBX_cursor *mc) {
if (mn.mc_ki[pre_top] > 0) { if (mn.mc_ki[pre_top] > 0) {
rc = mdbx_page_get( rc = mdbx_page_get(
&mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] - 1)), &mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] - 1)),
&left, pp_txnid4chk(mn.mc_pg[pre_top], mc->mc_txn)); &left, mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
mdbx_cassert(mc, PAGETYPE(left) == PAGETYPE(mc->mc_pg[mc->mc_top])); mdbx_cassert(mc, PAGETYPE(left) == PAGETYPE(mc->mc_pg[mc->mc_top]));
@ -18012,7 +17989,7 @@ static int mdbx_rebalance(MDBX_cursor *mc) {
if (mn.mc_ki[pre_top] + 1u < page_numkeys(mn.mc_pg[pre_top])) { if (mn.mc_ki[pre_top] + 1u < page_numkeys(mn.mc_pg[pre_top])) {
rc = mdbx_page_get( rc = mdbx_page_get(
&mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + 1)), &mn, node_pgno(page_node(mn.mc_pg[pre_top], mn.mc_ki[pre_top] + 1)),
&right, pp_txnid4chk(mn.mc_pg[pre_top], mc->mc_txn)); &right, mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
mdbx_cassert(mc, PAGETYPE(right) == PAGETYPE(mc->mc_pg[mc->mc_top])); mdbx_cassert(mc, PAGETYPE(right) == PAGETYPE(mc->mc_pg[mc->mc_top]));
@ -18244,20 +18221,19 @@ __cold static int mdbx_page_check(MDBX_cursor *const mc,
dsize, mc->mc_dbx->md_vlen_min, mc->mc_dbx->md_vlen_max); dsize, mc->mc_dbx->md_vlen_min, mc->mc_dbx->md_vlen_max);
} }
if ((options & C_RETIRING) == 0) { if ((options & C_RETIRING) == 0) {
MDBX_page *lp; const struct page_result lp =
int err = mdbx_page_get(mc, node_largedata_pgno(node), &lp, mdbx_page_get_ex(mc, node_largedata_pgno(node), mp->mp_txnid);
pp_txnid4chk(mp, mc->mc_txn)); if (unlikely(lp.err != MDBX_SUCCESS))
if (unlikely(err != MDBX_SUCCESS)) return lp.err;
return err; if (unlikely(!IS_OVERFLOW(lp.page))) {
if (unlikely(!IS_OVERFLOW(lp))) {
rc = bad_page(mp, "big-node refs to non-overflow page (%u)\n", rc = bad_page(mp, "big-node refs to non-overflow page (%u)\n",
lp->mp_pgno); lp.page->mp_pgno);
continue; continue;
} }
if (unlikely(number_of_ovpages(env, dsize) > lp->mp_pages)) if (unlikely(number_of_ovpages(env, dsize) > lp.page->mp_pages))
rc = rc =
bad_page(mp, "big-node size (%zu) mismatch n-pages size (%u)\n", bad_page(mp, "big-node size (%zu) mismatch n-pages size (%u)\n",
dsize, lp->mp_pages); dsize, lp.page->mp_pages);
} }
continue; continue;
} }
@ -18455,7 +18431,7 @@ __cold static int mdbx_cursor_check(MDBX_cursor *mc, unsigned options) {
return MDBX_CURSOR_FULL; return MDBX_CURSOR_FULL;
pgno_t pgno = node_pgno(node); pgno_t pgno = node_pgno(node);
MDBX_page *np; MDBX_page *np;
int rc = mdbx_page_get(mc, pgno, &np, pp_txnid4chk(mp, mc->mc_txn)); int rc = mdbx_page_get(mc, pgno, &np, mp->mp_txnid);
mdbx_cassert(mc, rc == MDBX_SUCCESS); mdbx_cassert(mc, rc == MDBX_SUCCESS);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -19473,8 +19449,7 @@ __cold static int mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
const pgno_t pgno = node_largedata_pgno(node); const pgno_t pgno = node_largedata_pgno(node);
poke_pgno(node_data(node), my->mc_next_pgno); poke_pgno(node_data(node), my->mc_next_pgno);
rc = mdbx_page_get(&couple.outer, pgno, &omp, rc = mdbx_page_get(&couple.outer, pgno, &omp, mp->mp_txnid);
pp_txnid4chk(mp, my->mc_txn));
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto done; goto done;
unsigned toggle = my->mc_head & 1; unsigned toggle = my->mc_head & 1;
@ -19529,7 +19504,7 @@ __cold static int mdbx_env_cwalk(mdbx_copy *my, pgno_t *pg, int flags) {
rc = mdbx_page_get( rc = mdbx_page_get(
&couple.outer, &couple.outer,
node_pgno(page_node(mp, couple.outer.mc_ki[couple.outer.mc_top])), node_pgno(page_node(mp, couple.outer.mc_ki[couple.outer.mc_top])),
&mp, pp_txnid4chk(mp, my->mc_txn)); &mp, mp->mp_txnid);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
goto done; goto done;
couple.outer.mc_top++; couple.outer.mc_top++;
@ -21542,8 +21517,7 @@ __cold static int mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno,
npages = 1; npages = 1;
MDBX_page *op; MDBX_page *op;
err = mdbx_page_get(ctx->mw_cursor, large_pgno, &op, err = mdbx_page_get(ctx->mw_cursor, large_pgno, &op, mp->mp_txnid);
pp_txnid4chk(mp, ctx->mw_txn));
if (err == MDBX_SUCCESS) if (err == MDBX_SUCCESS)
err = mdbx_page_check(ctx->mw_cursor, op, 0); err = mdbx_page_check(ctx->mw_cursor, op, 0);
if (err == MDBX_SUCCESS) { if (err == MDBX_SUCCESS) {
@ -21648,8 +21622,7 @@ __cold static int mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno,
MDBX_node *node = page_node(mp, i); MDBX_node *node = page_node(mp, i);
if (type == MDBX_page_branch) { if (type == MDBX_page_branch) {
err = mdbx_walk_tree(ctx, node_pgno(node), name, deep + 1, err = mdbx_walk_tree(ctx, node_pgno(node), name, deep + 1, mp->mp_txnid);
pp_txnid4chk(mp, ctx->mw_txn));
if (unlikely(err != MDBX_SUCCESS)) { if (unlikely(err != MDBX_SUCCESS)) {
if (err == MDBX_RESULT_TRUE) if (err == MDBX_RESULT_TRUE)
break; break;
@ -21696,8 +21669,7 @@ __cold static int mdbx_walk_tree(mdbx_walk_ctx_t *ctx, const pgno_t pgno,
assert(ctx->mw_cursor->mc_xcursor == assert(ctx->mw_cursor->mc_xcursor ==
&container_of(ctx->mw_cursor, MDBX_cursor_couple, outer)->inner); &container_of(ctx->mw_cursor, MDBX_cursor_couple, outer)->inner);
ctx->mw_cursor = &ctx->mw_cursor->mc_xcursor->mx_cursor; ctx->mw_cursor = &ctx->mw_cursor->mc_xcursor->mx_cursor;
err = mdbx_walk_tree(ctx, db.md_root, name, deep + 1, err = mdbx_walk_tree(ctx, db.md_root, name, deep + 1, mp->mp_txnid);
pp_txnid4chk(mp, ctx->mw_txn));
MDBX_xcursor *inner_xcursor = MDBX_xcursor *inner_xcursor =
container_of(ctx->mw_cursor, MDBX_xcursor, mx_cursor); container_of(ctx->mw_cursor, MDBX_xcursor, mx_cursor);
MDBX_cursor_couple *couple = MDBX_cursor_couple *couple =

View File

@ -511,7 +511,8 @@ typedef struct MDBX_page {
#define IS_SHADOWED(txn, p) ((p)->mp_txnid > (txn)->mt_txnid) #define IS_SHADOWED(txn, p) ((p)->mp_txnid > (txn)->mt_txnid)
#define IS_VALID(txn, p) ((p)->mp_txnid <= (txn)->mt_front) #define IS_VALID(txn, p) ((p)->mp_txnid <= (txn)->mt_front)
#define IS_MODIFIABLE(txn, p) ((p)->mp_txnid == (txn)->mt_front) #define IS_MODIFIABLE(txn, p) ((p)->mp_txnid == (txn)->mt_front)
uint64_t mp_txnid; uint64_t
mp_txnid; /* txnid which created this page, maybe zero in legacy DB */
struct MDBX_page *mp_next; /* for in-memory list of freed pages */ struct MDBX_page *mp_next; /* for in-memory list of freed pages */
}; };
uint16_t mp_leaf2_ksize; /* key size if this is a LEAF2 page */ uint16_t mp_leaf2_ksize; /* key size if this is a LEAF2 page */