mdbx: provide the parent-pgno during a tree traversal.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2025-07-28 13:41:27 +03:00
parent 79465dbc7f
commit 5c6d91f7c8
4 changed files with 20 additions and 9 deletions

View File

@ -686,11 +686,12 @@ __cold static void chk_verbose_meta(MDBX_chk_scope_t *const scope, const unsigne
__cold static int chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, const int deep, __cold static int chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, const int deep,
const walk_tbl_t *tbl_info, const size_t page_size, const page_type_t pagetype, const walk_tbl_t *tbl_info, const size_t page_size, const page_type_t pagetype,
const MDBX_error_t page_err, const size_t nentries, const size_t payload_bytes, const MDBX_error_t page_err, const size_t nentries, const size_t payload_bytes,
const size_t header_bytes, const size_t unused_bytes) { const size_t header_bytes, const size_t unused_bytes, const size_t parent_pgno) {
MDBX_chk_scope_t *const scope = ctx; MDBX_chk_scope_t *const scope = ctx;
MDBX_chk_internal_t *const chk = scope->internal; MDBX_chk_internal_t *const chk = scope->internal;
MDBX_chk_context_t *const usr = chk->usr; MDBX_chk_context_t *const usr = chk->usr;
MDBX_env *const env = usr->env; MDBX_env *const env = usr->env;
(void)parent_pgno;
MDBX_chk_table_t *tbl; MDBX_chk_table_t *tbl;
int err = chk_get_tbl(scope, tbl_info, &tbl); int err = chk_get_tbl(scope, tbl_info, &tbl);

View File

@ -932,8 +932,17 @@ retry:
return MDBX_PROBLEM; return MDBX_PROBLEM;
} }
static int do_page_split(MDBX_cursor *mc, const MDBX_val *const newkey, MDBX_val *const newdata, pgno_t newpgno,
const unsigned naf);
int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, MDBX_val *const newdata, pgno_t newpgno, int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, MDBX_val *const newdata, pgno_t newpgno,
const unsigned naf) { const unsigned naf) {
int rc = do_page_split(mc, newkey, newdata, newpgno, naf);
return rc;
}
int do_page_split(MDBX_cursor *mc, const MDBX_val *const newkey, MDBX_val *const newdata, pgno_t newpgno,
const unsigned naf) {
unsigned flags; unsigned flags;
int rc = MDBX_SUCCESS, foliage = 0; int rc = MDBX_SUCCESS, foliage = 0;
MDBX_env *const env = mc->txn->env; MDBX_env *const env = mc->txn->env;

View File

@ -30,7 +30,8 @@ static page_type_t walk_subpage_type(const page_t *sp) {
} }
/* Depth-first tree traversal. */ /* Depth-first tree traversal. */
__cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno, txnid_t parent_txnid) { __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno, txnid_t parent_txnid,
const pgno_t parent_pgno) {
assert(pgno != P_INVALID); assert(pgno != P_INVALID);
page_t *mp = nullptr; page_t *mp = nullptr;
int err = page_get(ctx->cursor, pgno, &mp, parent_txnid); int err = page_get(ctx->cursor, pgno, &mp, parent_txnid);
@ -79,7 +80,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno,
const size_t pagesize = pgno2bytes(ctx->txn->env, npages); const size_t pagesize = pgno2bytes(ctx->txn->env, npages);
const size_t over_unused = pagesize - over_payload - over_header; const size_t over_unused = pagesize - over_payload - over_header;
const int rc = ctx->visitor(large_pgno, npages, ctx->userctx, ctx->deep, tbl, pagesize, page_large, err, 1, const int rc = ctx->visitor(large_pgno, npages, ctx->userctx, ctx->deep, tbl, pagesize, page_large, err, 1,
over_payload, over_header, over_unused); over_payload, over_header, over_unused, pgno);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc;
payload_size += sizeof(pgno_t); payload_size += sizeof(pgno_t);
@ -148,7 +149,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno,
} }
const int rc = ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, tbl, node_data_size, subtype, err, nsubkeys, const int rc = ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, tbl, node_data_size, subtype, err, nsubkeys,
subpayload_size, subheader_size, subunused_size + subalign_bytes); subpayload_size, subheader_size, subunused_size + subalign_bytes, pgno);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc;
header_size += subheader_size; header_size += subheader_size;
@ -165,7 +166,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno,
} }
const int rc = ctx->visitor(pgno, 1, ctx->userctx, ctx->deep, tbl, ctx->txn->env->ps, type, err, nentries, const int rc = ctx->visitor(pgno, 1, ctx->userctx, ctx->deep, tbl, ctx->txn->env->ps, type, err, nentries,
payload_size, header_size, unused_size + align_bytes); payload_size, header_size, unused_size + align_bytes, parent_pgno);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc;
@ -177,7 +178,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno,
if (type == page_branch) { if (type == page_branch) {
assert(err == MDBX_SUCCESS); assert(err == MDBX_SUCCESS);
ctx->deep += 1; ctx->deep += 1;
err = walk_pgno(ctx, tbl, node_pgno(node), mp->txnid); err = walk_pgno(ctx, tbl, node_pgno(node), mp->txnid, pgno);
ctx->deep -= 1; ctx->deep -= 1;
if (unlikely(err != MDBX_SUCCESS)) { if (unlikely(err != MDBX_SUCCESS)) {
if (err == MDBX_RESULT_TRUE) if (err == MDBX_RESULT_TRUE)
@ -225,7 +226,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno,
ctx->cursor = &ctx->cursor->subcur->cursor; ctx->cursor = &ctx->cursor->subcur->cursor;
ctx->deep += 1; ctx->deep += 1;
tbl->nested = &aligned_db; tbl->nested = &aligned_db;
err = walk_pgno(ctx, tbl, aligned_db.root, mp->txnid); err = walk_pgno(ctx, tbl, aligned_db.root, mp->txnid, 0);
tbl->nested = nullptr; tbl->nested = nullptr;
ctx->deep -= 1; ctx->deep -= 1;
subcur_t *inner_xcursor = container_of(ctx->cursor, subcur_t, cursor); subcur_t *inner_xcursor = container_of(ctx->cursor, subcur_t, cursor);
@ -257,7 +258,7 @@ __cold int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl) {
couple.outer.next = ctx->cursor; couple.outer.next = ctx->cursor;
couple.outer.top_and_flags = z_disable_tree_search_fastpath; couple.outer.top_and_flags = z_disable_tree_search_fastpath;
ctx->cursor = &couple.outer; ctx->cursor = &couple.outer;
rc = walk_pgno(ctx, tbl, db->root, db->mod_txnid ? db->mod_txnid : ctx->txn->txnid); rc = walk_pgno(ctx, tbl, db->root, db->mod_txnid ? db->mod_txnid : ctx->txn->txnid, 0);
ctx->cursor = couple.outer.next; ctx->cursor = couple.outer.next;
return rc; return rc;
} }

View File

@ -13,7 +13,7 @@ typedef struct walk_tbl {
typedef int walk_func(const size_t pgno, const unsigned number, void *const ctx, const int deep, typedef int walk_func(const size_t pgno, const unsigned number, void *const ctx, const int deep,
const walk_tbl_t *table, const size_t page_size, const page_type_t page_type, const walk_tbl_t *table, const size_t page_size, const page_type_t page_type,
const MDBX_error_t err, const size_t nentries, const size_t payload_bytes, const MDBX_error_t err, const size_t nentries, const size_t payload_bytes,
const size_t header_bytes, const size_t unused_bytes); const size_t header_bytes, const size_t unused_bytes, const size_t parent_pgno);
typedef enum walk_options { dont_check_keys_ordering = 1 } walk_options_t; typedef enum walk_options { dont_check_keys_ordering = 1 } walk_options_t;