mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:24:13 +08:00
mdbx: add MDBX_PGWALK-tags and refine pgwalk internals.
Change-Id: I1f4eb79463dc6eec3d94d43baab0b28ceefa8c03
This commit is contained in:
parent
ce0e5d67f5
commit
c05702eacf
4
mdbx.h
4
mdbx.h
@ -1666,6 +1666,10 @@ typedef enum {
|
|||||||
MDBX_subpage_dupfixed_leaf
|
MDBX_subpage_dupfixed_leaf
|
||||||
} MDBX_page_type_t;
|
} 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,
|
typedef int MDBX_pgvisitor_func(uint64_t pgno, unsigned number, void *ctx,
|
||||||
int deep, const char *dbi, size_t page_size,
|
int deep, const char *dbi, size_t page_size,
|
||||||
MDBX_page_type_t type, size_t nentries,
|
MDBX_page_type_t type, size_t nentries,
|
||||||
|
19
src/mdbx.c
19
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);
|
payload_size += NODESIZE + NODEKSZ(node);
|
||||||
|
|
||||||
if (type == MDBX_page_branch) {
|
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)
|
if (rc)
|
||||||
return rc;
|
return rc;
|
||||||
continue;
|
continue;
|
||||||
@ -13056,15 +13056,16 @@ int __cold mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
|
|||||||
ctx.mw_visitor = visitor;
|
ctx.mw_visitor = visitor;
|
||||||
|
|
||||||
int rc = visitor(
|
int rc = visitor(
|
||||||
0, NUM_METAS, user, -2, "@META", pgno2bytes(txn->mt_env, NUM_METAS),
|
0, NUM_METAS, user, 0, MDBX_PGWALK_META,
|
||||||
MDBX_page_meta, NUM_METAS, sizeof(MDBX_meta) * NUM_METAS,
|
pgno2bytes(txn->mt_env, NUM_METAS), MDBX_page_meta, NUM_METAS,
|
||||||
PAGEHDRSZ * NUM_METAS,
|
sizeof(MDBX_meta) * NUM_METAS, PAGEHDRSZ * NUM_METAS,
|
||||||
(txn->mt_env->me_psize - sizeof(MDBX_meta) - PAGEHDRSZ) * NUM_METAS);
|
(txn->mt_env->me_psize - sizeof(MDBX_meta) - PAGEHDRSZ) * NUM_METAS);
|
||||||
if (!rc)
|
if (!MDBX_IS_ERROR(rc))
|
||||||
rc = mdbx_env_walk(&ctx, "@GC", txn->mt_dbs[FREE_DBI].md_root, -1);
|
rc = mdbx_env_walk(&ctx, MDBX_PGWALK_GC, txn->mt_dbs[FREE_DBI].md_root, 0);
|
||||||
if (!rc)
|
if (!MDBX_IS_ERROR(rc))
|
||||||
rc = mdbx_env_walk(&ctx, "@MAIN", txn->mt_dbs[MAIN_DBI].md_root, 0);
|
rc =
|
||||||
if (!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,
|
rc = visitor(P_INVALID, 0, user, INT_MIN, NULL, 0, MDBX_page_void, 0, 0, 0,
|
||||||
0);
|
0);
|
||||||
return rc;
|
return rc;
|
||||||
|
@ -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 *pagemap_lookup_dbi(const char *dbi_name, bool silent) {
|
||||||
static walk_dbi_t *last;
|
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)
|
if (last && strcmp(last->name, dbi_name) == 0)
|
||||||
return last;
|
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,
|
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,
|
MDBX_page_type_t pagetype, size_t nentries,
|
||||||
size_t payload_bytes, size_t header_bytes,
|
size_t payload_bytes, size_t header_bytes,
|
||||||
size_t unused_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)
|
if (pagetype == MDBX_page_void)
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
|
||||||
walk_dbi_t fake, *dbi = &fake;
|
walk_dbi_t *dbi = pagemap_lookup_dbi(dbi_name_or_tag, false);
|
||||||
if (deep > 0) {
|
if (!dbi)
|
||||||
dbi = pagemap_lookup_dbi(dbi_name, false);
|
return MDBX_ENOMEM;
|
||||||
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);
|
|
||||||
|
|
||||||
const size_t page_bytes = payload_bytes + header_bytes + unused_bytes;
|
const size_t page_bytes = payload_bytes + header_bytes + unused_bytes;
|
||||||
walk.pgcount += pgnumber;
|
walk.pgcount += pgnumber;
|
||||||
@ -310,14 +307,14 @@ static int pgvisitor(uint64_t pgno, unsigned pgnumber, void *ctx, int deep,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (pgnumber) {
|
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)
|
if (pgnumber == 1)
|
||||||
print(" %s-page %" PRIu64, pagetype_caption, pgno);
|
print(" %s-page %" PRIu64, pagetype_caption, pgno);
|
||||||
else
|
else
|
||||||
print(" %s-span %" PRIu64 "[%u]", pagetype_caption, pgno, pgnumber);
|
print(" %s-span %" PRIu64 "[%u]", pagetype_caption, pgno, pgnumber);
|
||||||
print(" of %s: header %" PRIiPTR ", payload %" PRIiPTR
|
print(" of %s: header %" PRIiPTR ", payload %" PRIiPTR
|
||||||
", unused %" PRIiPTR "\n",
|
", unused %" PRIiPTR ", deep %i\n",
|
||||||
dbi_name, header_bytes, payload_bytes, unused_bytes);
|
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 {
|
} else {
|
||||||
problem_add("page", pgno, "empty",
|
problem_add("page", pgno, "empty",
|
||||||
"%s-page: payload %" PRIuPTR " bytes, %" PRIuPTR " entries",
|
"%s-page: payload %" PRIuPTR " bytes, %" PRIuPTR
|
||||||
pagetype_caption, payload_bytes, nentries);
|
" entries, deep %i",
|
||||||
|
pagetype_caption, payload_bytes, nentries, deep);
|
||||||
dbi->pages.empty += 1;
|
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) {
|
if (page_bytes != page_size) {
|
||||||
problem_add("page", pgno, "misused",
|
problem_add("page", pgno, "misused",
|
||||||
"%s-page: %" PRIuPTR " != %" PRIuPTR " (%" PRIuPTR
|
"%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,
|
pagetype_caption, page_size, page_bytes, header_bytes,
|
||||||
payload_bytes, unused_bytes);
|
payload_bytes, unused_bytes, deep);
|
||||||
if (page_size > page_bytes)
|
if (page_size > page_bytes)
|
||||||
dbi->lost_bytes += page_size - page_bytes;
|
dbi->lost_bytes += page_size - page_bytes;
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user