From c05702eacff69d3a59121d34047299aa8036bafd Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Wed, 19 Jun 2019 14:40:35 +0300 Subject: [PATCH] mdbx: add MDBX_PGWALK-tags and refine pgwalk internals. Change-Id: I1f4eb79463dc6eec3d94d43baab0b28ceefa8c03 --- mdbx.h | 4 ++++ src/mdbx.c | 19 ++++++++++--------- src/tools/mdbx_chk.c | 40 +++++++++++++++++++--------------------- 3 files changed, 33 insertions(+), 30 deletions(-) diff --git a/mdbx.h b/mdbx.h index a6c7ba53..9e5c501f 100644 --- a/mdbx.h +++ b/mdbx.h @@ -1666,6 +1666,10 @@ typedef enum { MDBX_subpage_dupfixed_leaf } MDBX_page_type_t; +#define MDBX_PGWALK_MAIN ((const char *)((ptrdiff_t)0)) +#define MDBX_PGWALK_GC ((const char *)((ptrdiff_t)-1)) +#define MDBX_PGWALK_META ((const char *)((ptrdiff_t)-2)) + typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned number, void *ctx, int deep, const char *dbi, size_t page_size, MDBX_page_type_t type, size_t nentries, diff --git a/src/mdbx.c b/src/mdbx.c index a80d043c..999a95ab 100644 --- a/src/mdbx.c +++ b/src/mdbx.c @@ -12905,7 +12905,7 @@ static int __cold mdbx_env_walk(mdbx_walk_ctx_t *ctx, const char *dbi, payload_size += NODESIZE + NODEKSZ(node); if (type == MDBX_page_branch) { - rc = mdbx_env_walk(ctx, dbi, NODEPGNO(node), deep); + rc = mdbx_env_walk(ctx, dbi, NODEPGNO(node), deep + 1); if (rc) return rc; continue; @@ -13056,15 +13056,16 @@ int __cold mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor, ctx.mw_visitor = visitor; int rc = visitor( - 0, NUM_METAS, user, -2, "@META", pgno2bytes(txn->mt_env, NUM_METAS), - MDBX_page_meta, NUM_METAS, sizeof(MDBX_meta) * NUM_METAS, - PAGEHDRSZ * NUM_METAS, + 0, NUM_METAS, user, 0, MDBX_PGWALK_META, + pgno2bytes(txn->mt_env, NUM_METAS), MDBX_page_meta, NUM_METAS, + sizeof(MDBX_meta) * NUM_METAS, PAGEHDRSZ * NUM_METAS, (txn->mt_env->me_psize - sizeof(MDBX_meta) - PAGEHDRSZ) * NUM_METAS); - if (!rc) - rc = mdbx_env_walk(&ctx, "@GC", txn->mt_dbs[FREE_DBI].md_root, -1); - if (!rc) - rc = mdbx_env_walk(&ctx, "@MAIN", txn->mt_dbs[MAIN_DBI].md_root, 0); - if (!rc) + if (!MDBX_IS_ERROR(rc)) + rc = mdbx_env_walk(&ctx, MDBX_PGWALK_GC, txn->mt_dbs[FREE_DBI].md_root, 0); + if (!MDBX_IS_ERROR(rc)) + rc = + mdbx_env_walk(&ctx, MDBX_PGWALK_MAIN, txn->mt_dbs[MAIN_DBI].md_root, 0); + if (!MDBX_IS_ERROR(rc)) rc = visitor(P_INVALID, 0, user, INT_MIN, NULL, 0, MDBX_page_void, 0, 0, 0, 0); return rc; diff --git a/src/tools/mdbx_chk.c b/src/tools/mdbx_chk.c index 7cc24f15..343efe94 100644 --- a/src/tools/mdbx_chk.c +++ b/src/tools/mdbx_chk.c @@ -154,6 +154,13 @@ static void pagemap_cleanup(void) { static walk_dbi_t *pagemap_lookup_dbi(const char *dbi_name, bool silent) { static walk_dbi_t *last; + if (dbi_name == MDBX_PGWALK_MAIN) + return &dbi_main; + if (dbi_name == MDBX_PGWALK_GC) + return &dbi_free; + if (dbi_name == MDBX_PGWALK_META) + return &dbi_meta; + if (last && strcmp(last->name, dbi_name) == 0) return last; @@ -246,7 +253,7 @@ static size_t problems_pop(struct problem *list) { } static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep, - const char *dbi_name, size_t page_size, + const char *dbi_name_or_tag, size_t page_size, MDBX_page_type_t pagetype, size_t nentries, size_t payload_bytes, size_t header_bytes, size_t unused_bytes) { @@ -254,19 +261,9 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep, if (pagetype == MDBX_page_void) return MDBX_SUCCESS; - walk_dbi_t fake, *dbi = &fake; - if (deep > 0) { - dbi = pagemap_lookup_dbi(dbi_name, false); - if (!dbi) - return MDBX_ENOMEM; - } else if (deep == 0 && strcmp(dbi_name, dbi_main.name) == 0) - dbi = &dbi_main; - else if (deep == -1 && strcmp(dbi_name, dbi_free.name) == 0) - dbi = &dbi_free; - else if (deep == -2 && strcmp(dbi_name, dbi_meta.name) == 0) - dbi = &dbi_meta; - else - problem_add("deep", deep, "unknown area", "%s", dbi_name); + walk_dbi_t *dbi = pagemap_lookup_dbi(dbi_name_or_tag, false); + if (!dbi) + return MDBX_ENOMEM; const size_t page_bytes = payload_bytes + header_bytes + unused_bytes; walk.pgcount += pgnumber; @@ -310,14 +307,14 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep, } if (pgnumber) { - if (verbose > 3 && (!only_subdb || strcmp(only_subdb, dbi_name) == 0)) { + if (verbose > 3 && (!only_subdb || strcmp(only_subdb, dbi->name) == 0)) { if (pgnumber == 1) print(" %s-page %" PRIu64, pagetype_caption, pgno); else print(" %s-span %" PRIu64 "[%u]", pagetype_caption, pgno, pgnumber); print(" of %s: header %" PRIiPTR ", payload %" PRIiPTR - ", unused %" PRIiPTR "\n", - dbi_name, header_bytes, payload_bytes, unused_bytes); + ", unused %" PRIiPTR ", deep %i\n", + dbi->name, header_bytes, payload_bytes, unused_bytes, deep); } } @@ -343,8 +340,9 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep, } */ } else { problem_add("page", pgno, "empty", - "%s-page: payload %" PRIuPTR " bytes, %" PRIuPTR " entries", - pagetype_caption, payload_bytes, nentries); + "%s-page: payload %" PRIuPTR " bytes, %" PRIuPTR + " entries, deep %i", + pagetype_caption, payload_bytes, nentries, deep); dbi->pages.empty += 1; } } @@ -353,9 +351,9 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep, if (page_bytes != page_size) { problem_add("page", pgno, "misused", "%s-page: %" PRIuPTR " != %" PRIuPTR " (%" PRIuPTR - "h + %" PRIuPTR "p + %" PRIuPTR "u)", + "h + %" PRIuPTR "p + %" PRIuPTR "u), deep %i", pagetype_caption, page_size, page_bytes, header_bytes, - payload_bytes, unused_bytes); + payload_bytes, unused_bytes, deep); if (page_size > page_bytes) dbi->lost_bytes += page_size - page_bytes; } else {