From 5c6d91f7c84af99fc056f44ae9a0e84062b9a1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Mon, 28 Jul 2025 13:41:27 +0300 Subject: [PATCH] mdbx: provide the parent-pgno during a tree traversal. --- src/chk.c | 3 ++- src/tree-ops.c | 9 +++++++++ src/walk.c | 15 ++++++++------- src/walk.h | 2 +- 4 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/chk.c b/src/chk.c index f7b79067..da9fb477 100644 --- a/src/chk.c +++ b/src/chk.c @@ -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, 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 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_internal_t *const chk = scope->internal; MDBX_chk_context_t *const usr = chk->usr; MDBX_env *const env = usr->env; + (void)parent_pgno; MDBX_chk_table_t *tbl; int err = chk_get_tbl(scope, tbl_info, &tbl); diff --git a/src/tree-ops.c b/src/tree-ops.c index 61429d82..169a8fe6 100644 --- a/src/tree-ops.c +++ b/src/tree-ops.c @@ -932,8 +932,17 @@ retry: 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, 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; int rc = MDBX_SUCCESS, foliage = 0; MDBX_env *const env = mc->txn->env; diff --git a/src/walk.c b/src/walk.c index 4399c211..d653e0a2 100644 --- a/src/walk.c +++ b/src/walk.c @@ -30,7 +30,8 @@ static page_type_t walk_subpage_type(const page_t *sp) { } /* 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); page_t *mp = nullptr; 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 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, - over_payload, over_header, over_unused); + over_payload, over_header, over_unused, pgno); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; 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, - subpayload_size, subheader_size, subunused_size + subalign_bytes); + subpayload_size, subheader_size, subunused_size + subalign_bytes, pgno); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; 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, - payload_size, header_size, unused_size + align_bytes); + payload_size, header_size, unused_size + align_bytes, parent_pgno); if (unlikely(rc != MDBX_SUCCESS)) 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) { assert(err == MDBX_SUCCESS); 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; if (unlikely(err != MDBX_SUCCESS)) { 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->deep += 1; 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; ctx->deep -= 1; 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.top_and_flags = z_disable_tree_search_fastpath; 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; return rc; } diff --git a/src/walk.h b/src/walk.h index 0feee06d..a5fba787 100644 --- a/src/walk.h +++ b/src/walk.h @@ -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, 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 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;