From 09542fffbb23b76b4aaa0fff42704f2c7f035c78 Mon Sep 17 00:00:00 2001 From: "alex.sharov" Date: Mon, 5 Aug 2024 18:43:28 +0700 Subject: [PATCH] save --- mdbx/mdbx.c | 842 +++++++++++++++++++------------------- mdbx/mdbx.h | 488 ++++++++++++---------- mdbxdist/CMakeLists.txt | 4 +- mdbxdist/ChangeLog.md | 23 +- mdbxdist/README.md | 8 +- mdbxdist/VERSION.txt | 2 +- mdbxdist/man1/mdbx_chk.1 | 6 +- mdbxdist/man1/mdbx_drop.1 | 6 +- mdbxdist/man1/mdbx_dump.1 | 8 +- mdbxdist/man1/mdbx_load.1 | 8 +- mdbxdist/man1/mdbx_stat.1 | 8 +- mdbxdist/mdbx.c | 842 +++++++++++++++++++------------------- mdbxdist/mdbx.c++ | 20 +- mdbxdist/mdbx.h | 488 ++++++++++++---------- mdbxdist/mdbx.h++ | 30 +- mdbxdist/mdbx_chk.c | 50 +-- mdbxdist/mdbx_copy.c | 20 +- mdbxdist/mdbx_drop.c | 22 +- mdbxdist/mdbx_dump.c | 36 +- mdbxdist/mdbx_load.c | 24 +- mdbxdist/mdbx_stat.c | 58 +-- 21 files changed, 1537 insertions(+), 1456 deletions(-) diff --git a/mdbx/mdbx.c b/mdbx/mdbx.c index 3d18d3a..5be12b8 100644 --- a/mdbx/mdbx.c +++ b/mdbx/mdbx.c @@ -3,7 +3,7 @@ #define xMDBX_ALLOY 1 /* alloyed build */ -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2520,11 +2520,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2555,10 +2555,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2587,9 +2587,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3922,16 +3922,16 @@ MDBX_INTERNAL int __must_check_result env_page_auxbuffer(MDBX_env *env); MDBX_INTERNAL unsigned env_setup_pagesize(MDBX_env *env, const size_t pagesize); /* tree.c */ -MDBX_INTERNAL int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs); +MDBX_INTERNAL int tree_drop(MDBX_cursor *mc, const bool may_have_tables); MDBX_INTERNAL int __must_check_result tree_rebalance(MDBX_cursor *mc); MDBX_INTERNAL int __must_check_result tree_propagate_key(MDBX_cursor *mc, const MDBX_val *key); MDBX_INTERNAL void recalculate_merge_thresholds(MDBX_env *env); MDBX_INTERNAL void recalculate_subpage_thresholds(MDBX_env *env); -/* subdb.c */ -MDBX_INTERNAL int __must_check_result sdb_fetch(MDBX_txn *txn, size_t dbi); -MDBX_INTERNAL int __must_check_result sdb_setup(const MDBX_env *env, +/* table.c */ +MDBX_INTERNAL int __must_check_result tbl_fetch(MDBX_txn *txn, size_t dbi); +MDBX_INTERNAL int __must_check_result tbl_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db); @@ -4392,7 +4392,7 @@ typedef struct clc { size_t lmin, lmax; /* min/max length constraints */ } clc_t; -/* Вспомогательная информация о subDB. +/* Вспомогательная информация о table. * * Совокупность потребностей: * 1. Для транзакций и основного курсора нужны все поля. @@ -4432,7 +4432,7 @@ typedef struct clc2 { struct kvx { clc2_t clc; - MDBX_val name; /* имя subDB */ + MDBX_val name; /* имя table */ }; /* Non-shared DBI state flags inside transaction */ @@ -4874,7 +4874,7 @@ MDBX_MAYBE_UNUSED static void static_checks(void) { /* valid flags for mdbx_node_add() */ -#define NODE_ADD_FLAGS (N_DUPDATA | N_SUBDATA | MDBX_RESERVE | MDBX_APPEND) +#define NODE_ADD_FLAGS (N_DUP | N_TREE | MDBX_RESERVE | MDBX_APPEND) /* Get the page number pointed to by a branch node */ MDBX_NOTHROW_PURE_FUNCTION static inline pgno_t @@ -4949,7 +4949,7 @@ node_size(const MDBX_val *key, const MDBX_val *value) { MDBX_NOTHROW_PURE_FUNCTION static inline pgno_t node_largedata_pgno(const node_t *const __restrict node) { - assert(node_flags(node) & N_BIGDATA); + assert(node_flags(node) & N_BIG); return peek_pgno(node_data(node)); } @@ -4964,7 +4964,7 @@ static inline int __must_check_result node_read(MDBX_cursor *mc, const page_t *mp) { data->iov_len = node_ds(node); data->iov_base = node_data(node); - if (likely(node_flags(node) != N_BIGDATA)) + if (likely(node_flags(node) != N_BIG)) return MDBX_SUCCESS; return node_read_bigdata(mc, node, data, mp); } @@ -5162,10 +5162,10 @@ MDBX_MAYBE_UNUSED MDBX_INTERNAL bool pv2pages_verify(void); * LEAF_NODE_MAX = even_floor(PAGESPACE / 2 - sizeof(indx_t)); * DATALEN_NO_OVERFLOW = LEAF_NODE_MAX - NODESIZE - KEYLEN_MAX; * - * - SubDatabase-node must fit into one leaf-page: - * SUBDB_NAME_MAX = LEAF_NODE_MAX - node_hdr_len - sizeof(tree_t); + * - Table-node must fit into one leaf-page: + * TABLE_NAME_MAX = LEAF_NODE_MAX - node_hdr_len - sizeof(tree_t); * - * - Dupsort values itself are a keys in a dupsort-subdb and couldn't be longer + * - Dupsort values itself are a keys in a dupsort-table and couldn't be longer * than the KEYLEN_MAX. But dupsort node must not great than LEAF_NODE_MAX, * since dupsort value couldn't be placed on a large/overflow page: * DUPSORT_DATALEN_MAX = min(KEYLEN_MAX, @@ -5330,7 +5330,7 @@ flags_db2sub(uint16_t db_flags) { return sub_flags; } -static inline bool check_sdb_flags(unsigned flags) { +static inline bool check_table_flags(unsigned flags) { switch (flags & ~(MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { default: NOTICE("invalid db-flags 0x%x", flags); @@ -6073,7 +6073,7 @@ MDBX_MAYBE_UNUSED static inline void cursor_inner_refresh(const MDBX_cursor *mc, const page_t *mp, unsigned ki) { cASSERT(mc, is_leaf(mp)); const node_t *node = page_node(mp, ki); - if ((node_flags(node) & (N_DUPDATA | N_SUBDATA)) == N_DUPDATA) + if ((node_flags(node) & (N_DUP | N_TREE)) == N_DUP) mc->subcur->cursor.pg[0] = node_data(node); } @@ -6844,13 +6844,13 @@ static inline void thread_key_delete(osal_thread_key_t key) { -typedef struct walk_sdb { +typedef struct walk_tbl { MDBX_val name; tree_t *internal, *nested; -} walk_sdb_t; +} walk_tbl_t; typedef int walk_func(const size_t pgno, const unsigned number, void *const ctx, - const int deep, const walk_sdb_t *subdb, + 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, @@ -7631,12 +7631,12 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r, if (is_pointed(&l->subcur->cursor)) { const page_t *mp = l->pg[l->top]; const node_t *node = page_node(mp, l->ki[l->top]); - assert(node_flags(node) & N_DUPDATA); + assert(node_flags(node) & N_DUP); } if (is_pointed(&r->subcur->cursor)) { const page_t *mp = r->pg[r->top]; const node_t *node = page_node(mp, r->ki[r->top]); - assert(node_flags(node) & N_DUPDATA); + assert(node_flags(node) & N_DUP); } #endif /* MDBX_DEBUG */ @@ -7680,7 +7680,7 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) { if (!inner_hollow(mc)) { const page_t *mp = mc->pg[mc->top]; const node_t *node = page_node(mp, mc->ki[mc->top]); - cASSERT(mc, node_flags(node) & N_DUPDATA); + cASSERT(mc, node_flags(node) & N_DUP); *countp = unlikely(mc->subcur->nested_tree.items > PTRDIFF_MAX) ? PTRDIFF_MAX : (size_t)mc->subcur->nested_tree.items; @@ -7937,7 +7937,7 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs, return MDBX_BAD_DBI; if (unlikely(mc->subcur)) - return MDBX_INCOMPATIBLE /* must be a non-dupsort subDB */; + return MDBX_INCOMPATIBLE /* must be a non-dupsort table */; switch (op) { case MDBX_NEXT: @@ -9941,16 +9941,16 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, const tree_t *db = node_data(node); const unsigned flags = node_flags(node); switch (flags) { - case N_BIGDATA: + case N_BIG: case 0: /* single-value entry, deep = 0 */ *mask |= 1 << 0; break; - case N_DUPDATA: + case N_DUP: /* single sub-page, deep = 1 */ *mask |= 1 << 1; break; - case N_DUPDATA | N_SUBDATA: + case N_DUP | N_TREE: /* sub-tree */ *mask |= 1 << UNALIGNED_PEEK_16(db, tree_t, height); break; @@ -10210,7 +10210,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, /* LY: allows update (explicit overwrite) only for unique keys */ node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { tASSERT(txn, inner_pointed(&cx.outer) && cx.outer.subcur->nested_tree.items > 1); rc = MDBX_EMULTIVAL; @@ -10323,7 +10323,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, if (flags & MDBX_CURRENT) { /* disallow update/delete for multi-values */ node_t *node = page_node(page, cx.outer.ki[cx.outer.top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { tASSERT(txn, inner_pointed(&cx.outer) && cx.outer.subcur->nested_tree.items > 1); if (cx.outer.subcur->nested_tree.items > 1) { @@ -10466,7 +10466,7 @@ __cold static int audit_ex_locked(MDBX_txn *txn, size_t retired_stored, ctx.used = NUM_METAS + audit_db_used(dbi_dig(txn, FREE_DBI, nullptr)) + audit_db_used(dbi_dig(txn, MAIN_DBI, nullptr)); - rc = mdbx_enumerate_subdb(txn, audit_dbi, &ctx); + rc = mdbx_enumerate_tables(txn, audit_dbi, &ctx); tASSERT(txn, rc == MDBX_SUCCESS); for (size_t dbi = CORE_DBS; dbi < txn->n_dbi; ++dbi) { @@ -10525,12 +10525,12 @@ typedef struct MDBX_chk_internal { bool write_locked; uint8_t scope_depth; - MDBX_chk_subdb_t subdb_gc, subdb_main; + MDBX_chk_table_t table_gc, table_main; int16_t *pagemap; - MDBX_chk_subdb_t *last_lookup; + MDBX_chk_table_t *last_lookup; const void *last_nested; MDBX_chk_scope_t scope_stack[12]; - MDBX_chk_subdb_t *subdb[MDBX_MAX_DBI + CORE_DBS]; + MDBX_chk_table_t *table[MDBX_MAX_DBI + CORE_DBS]; MDBX_envinfo envinfo; troika_t troika; @@ -10996,18 +10996,18 @@ __cold static const char *chk_v2a(MDBX_chk_internal_t *chk, } __cold static void chk_dispose(MDBX_chk_internal_t *chk) { - assert(chk->subdb[FREE_DBI] == &chk->subdb_gc); - assert(chk->subdb[MAIN_DBI] == &chk->subdb_main); - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb); ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; - if (sdb) { - chk->subdb[i] = nullptr; - if (chk->cb->subdb_dispose && sdb->cookie) { - chk->cb->subdb_dispose(chk->usr, sdb); - sdb->cookie = nullptr; + assert(chk->table[FREE_DBI] == &chk->table_gc); + assert(chk->table[MAIN_DBI] == &chk->table_main); + for (size_t i = 0; i < ARRAY_LENGTH(chk->table); ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; + if (tbl) { + chk->table[i] = nullptr; + if (chk->cb->table_dispose && tbl->cookie) { + chk->cb->table_dispose(chk->usr, tbl); + tbl->cookie = nullptr; } - if (sdb != &chk->subdb_gc && sdb != &chk->subdb_main) { - osal_free(sdb); + if (tbl != &chk->table_gc && tbl != &chk->table_main) { + osal_free(tbl); } } } @@ -11150,8 +11150,8 @@ histogram_print(MDBX_chk_scope_t *scope, MDBX_chk_line_t *line, //----------------------------------------------------------------------------- -__cold static int chk_get_sdb(MDBX_chk_scope_t *const scope, - const walk_sdb_t *in, MDBX_chk_subdb_t **out) { +__cold static int chk_get_tbl(MDBX_chk_scope_t *const scope, + const walk_tbl_t *in, MDBX_chk_table_t **out) { MDBX_chk_internal_t *const chk = scope->internal; if (chk->last_lookup && chk->last_lookup->name.iov_base == in->name.iov_base) { @@ -11159,33 +11159,33 @@ __cold static int chk_get_sdb(MDBX_chk_scope_t *const scope, return MDBX_SUCCESS; } - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb); ++i) { - MDBX_chk_subdb_t *sdb = chk->subdb[i]; - if (!sdb) { - sdb = osal_calloc(1, sizeof(MDBX_chk_subdb_t)); - if (unlikely(!sdb)) { + for (size_t i = 0; i < ARRAY_LENGTH(chk->table); ++i) { + MDBX_chk_table_t *tbl = chk->table[i]; + if (!tbl) { + tbl = osal_calloc(1, sizeof(MDBX_chk_table_t)); + if (unlikely(!tbl)) { *out = nullptr; - return chk_error_rc(scope, MDBX_ENOMEM, "alloc_subDB"); - } - chk->subdb[i] = sdb; - sdb->flags = in->internal->flags; - sdb->id = -1; - sdb->name = in->name; - } - if (sdb->name.iov_base == in->name.iov_base) { - if (sdb->id < 0) { - sdb->id = (int)i; - sdb->cookie = - chk->cb->subdb_filter - ? chk->cb->subdb_filter(chk->usr, &sdb->name, sdb->flags) + return chk_error_rc(scope, MDBX_ENOMEM, "alloc_table"); + } + chk->table[i] = tbl; + tbl->flags = in->internal->flags; + tbl->id = -1; + tbl->name = in->name; + } + if (tbl->name.iov_base == in->name.iov_base) { + if (tbl->id < 0) { + tbl->id = (int)i; + tbl->cookie = + chk->cb->table_filter + ? chk->cb->table_filter(chk->usr, &tbl->name, tbl->flags) : (void *)(intptr_t)-1; } - *out = (chk->last_lookup = sdb); + *out = (chk->last_lookup = tbl); return MDBX_SUCCESS; } } - chk_scope_issue(scope, "too many subDBs > %u", - (unsigned)ARRAY_LENGTH(chk->subdb) - CORE_DBS - /* meta */ 1); + chk_scope_issue(scope, "too many tables > %u", + (unsigned)ARRAY_LENGTH(chk->table) - CORE_DBS - /* meta */ 1); *out = nullptr; return MDBX_PROBLEM; } @@ -11252,7 +11252,7 @@ __cold static void chk_verbose_meta(MDBX_chk_scope_t *const scope, __cold static int chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, - const int deep, const walk_sdb_t *sdb_info, + 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, @@ -11262,8 +11262,8 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, MDBX_chk_context_t *const usr = chk->usr; MDBX_env *const env = usr->env; - MDBX_chk_subdb_t *sdb; - int err = chk_get_sdb(scope, sdb_info, &sdb); + MDBX_chk_table_t *tbl; + int err = chk_get_tbl(scope, tbl_info, &tbl); if (unlikely(err)) return err; @@ -11271,21 +11271,21 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, chk_scope_issue(scope, "too deeply %u", deep); return MDBX_CORRUPTED /* avoid infinite loop/recursion */; } - histogram_acc(deep, &sdb->histogram.deep); + histogram_acc(deep, &tbl->histogram.deep); usr->result.processed_pages += npages; const size_t page_bytes = payload_bytes + header_bytes + unused_bytes; int height = deep + 1; - if (sdb->id >= CORE_DBS) + if (tbl->id >= CORE_DBS) height -= usr->txn->dbs[MAIN_DBI].height; - const tree_t *nested = sdb_info->nested; + const tree_t *nested = tbl_info->nested; if (nested) { - if (sdb->flags & MDBX_DUPSORT) - height -= sdb_info->internal->height; + if (tbl->flags & MDBX_DUPSORT) + height -= tbl_info->internal->height; else { chk_object_issue(scope, "nested tree", pgno, "unexpected", - "subDb %s flags 0x%x, deep %i", chk_v2a(chk, &sdb->name), - sdb->flags, deep); + "table %s flags 0x%x, deep %i", chk_v2a(chk, &tbl->name), + tbl->flags, deep); nested = nullptr; } } else @@ -11298,82 +11298,82 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, chk_object_issue(scope, "page", pgno, "unknown page-type", "type %u, deep %i", (unsigned)pagetype, deep); pagetype_caption = "unknown"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_broken: assert(page_err != MDBX_SUCCESS); pagetype_caption = "broken"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_sub_broken: assert(page_err != MDBX_SUCCESS); pagetype_caption = "broken-subpage"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_large: pagetype_caption = "large"; - histogram_acc(npages, &sdb->histogram.large_pages); - if (sdb->flags & MDBX_DUPSORT) + histogram_acc(npages, &tbl->histogram.large_pages); + if (tbl->flags & MDBX_DUPSORT) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); break; case page_branch: branch = true; if (!nested) { pagetype_caption = "branch"; - sdb->pages.branch += 1; + tbl->pages.branch += 1; } else { pagetype_caption = "nested-branch"; - sdb->pages.nested_branch += 1; + tbl->pages.nested_branch += 1; } break; case page_dupfix_leaf: if (!nested) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); /* fall through */ __fallthrough; case page_leaf: if (!nested) { pagetype_caption = "leaf"; - sdb->pages.leaf += 1; - if (height != sdb_info->internal->height) + tbl->pages.leaf += 1; + if (height != tbl_info->internal->height) chk_object_issue(scope, "page", pgno, "wrong tree height", - "actual %i != %i subDb %s", height, - sdb_info->internal->height, chk_v2a(chk, &sdb->name)); + "actual %i != %i table %s", height, + tbl_info->internal->height, chk_v2a(chk, &tbl->name)); } else { pagetype_caption = (pagetype == page_leaf) ? "nested-leaf" : "nested-leaf-dupfix"; - sdb->pages.nested_leaf += 1; + tbl->pages.nested_leaf += 1; if (chk->last_nested != nested) { - histogram_acc(height, &sdb->histogram.nested_tree); + histogram_acc(height, &tbl->histogram.nested_tree); chk->last_nested = nested; } if (height != nested->height) chk_object_issue(scope, "page", pgno, "wrong nested-tree height", "actual %i != %i dupsort-node %s", height, - nested->height, chk_v2a(chk, &sdb->name)); + nested->height, chk_v2a(chk, &tbl->name)); } break; case page_sub_dupfix_leaf: case page_sub_leaf: pagetype_caption = (pagetype == page_sub_leaf) ? "subleaf-dupsort" : "subleaf-dupfix"; - sdb->pages.nested_subleaf += 1; - if ((sdb->flags & MDBX_DUPSORT) == 0 || nested) + tbl->pages.nested_subleaf += 1; + if ((tbl->flags & MDBX_DUPSORT) == 0 || nested) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); break; } if (npages) { - if (sdb->cookie) { + if (tbl->cookie) { MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_extra); if (npages == 1) chk_print(line, "%s-page %" PRIuSIZE, pagetype_caption, pgno); @@ -11384,7 +11384,7 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, " of %s: header %" PRIiPTR ", %s %" PRIiPTR ", payload %" PRIiPTR ", unused %" PRIiPTR ", deep %i", - chk_v2a(chk, &sdb->name), header_bytes, + chk_v2a(chk, &tbl->name), header_bytes, (pagetype == page_branch) ? "keys" : "entries", nentries, payload_bytes, unused_bytes, deep)); } @@ -11397,18 +11397,18 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, "%s-page: %" PRIuSIZE " > %" PRIuSIZE ", deep %i", pagetype_caption, spanpgno, usr->result.alloc_pages, deep); - sdb->pages.all += 1; + tbl->pages.all += 1; } else if (chk->pagemap[spanpgno]) { - const MDBX_chk_subdb_t *const rival = - chk->subdb[chk->pagemap[spanpgno] - 1]; + const MDBX_chk_table_t *const rival = + chk->table[chk->pagemap[spanpgno] - 1]; chk_object_issue(scope, "page", spanpgno, - (branch && rival == sdb) ? "loop" : "already used", + (branch && rival == tbl) ? "loop" : "already used", "%s-page: by %s, deep %i", pagetype_caption, chk_v2a(chk, &rival->name), deep); already_used = true; } else { - chk->pagemap[spanpgno] = (int16_t)sdb->id + 1; - sdb->pages.all += 1; + chk->pagemap[spanpgno] = (int16_t)tbl->id + 1; + tbl->pages.all += 1; } } @@ -11438,7 +11438,7 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, "%s-page: payload %" PRIuSIZE " bytes, %" PRIuSIZE " entries, deep %i", pagetype_caption, payload_bytes, nentries, deep); - sdb->pages.empty += 1; + tbl->pages.empty += 1; } if (npages) { @@ -11449,9 +11449,9 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, pagetype_caption, page_size, page_bytes, header_bytes, payload_bytes, unused_bytes, deep); if (page_size > page_bytes) - sdb->lost_bytes += page_size - page_bytes; + tbl->lost_bytes += page_size - page_bytes; } else { - sdb->payload_bytes += payload_bytes + header_bytes; + tbl->payload_bytes += payload_bytes + header_bytes; usr->result.total_payload_bytes += payload_bytes + header_bytes; } } @@ -11489,21 +11489,21 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { if (!chk->pagemap[n]) usr->result.unused_pages += 1; - MDBX_chk_subdb_t total; + MDBX_chk_table_t total; memset(&total, 0, sizeof(total)); total.pages.all = NUM_METAS; - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb) && chk->subdb[i]; ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; - total.payload_bytes += sdb->payload_bytes; - total.lost_bytes += sdb->lost_bytes; - total.pages.all += sdb->pages.all; - total.pages.empty += sdb->pages.empty; - total.pages.other += sdb->pages.other; - total.pages.branch += sdb->pages.branch; - total.pages.leaf += sdb->pages.leaf; - total.pages.nested_branch += sdb->pages.nested_branch; - total.pages.nested_leaf += sdb->pages.nested_leaf; - total.pages.nested_subleaf += sdb->pages.nested_subleaf; + for (size_t i = 0; i < ARRAY_LENGTH(chk->table) && chk->table[i]; ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; + total.payload_bytes += tbl->payload_bytes; + total.lost_bytes += tbl->lost_bytes; + total.pages.all += tbl->pages.all; + total.pages.empty += tbl->pages.empty; + total.pages.other += tbl->pages.other; + total.pages.branch += tbl->pages.branch; + total.pages.leaf += tbl->pages.leaf; + total.pages.nested_branch += tbl->pages.nested_branch; + total.pages.nested_leaf += tbl->pages.nested_leaf; + total.pages.nested_subleaf += tbl->pages.nested_subleaf; } assert(total.pages.all == usr->result.processed_pages); @@ -11518,70 +11518,70 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { err = chk_scope_restore(scope, err); if (scope->verbosity > MDBX_chk_info) { - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb) && chk->subdb[i]; ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; + for (size_t i = 0; i < ARRAY_LENGTH(chk->table) && chk->table[i]; ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; MDBX_chk_scope_t *inner = - chk_scope_push(scope, 0, "tree %s:", chk_v2a(chk, &sdb->name)); - if (sdb->pages.all == 0) + chk_scope_push(scope, 0, "tree %s:", chk_v2a(chk, &tbl->name)); + if (tbl->pages.all == 0) chk_line_end( chk_print(chk_line_begin(inner, MDBX_chk_resolution), "empty")); else { MDBX_chk_line_t *line = chk_line_begin(inner, MDBX_chk_info); if (line) { line = chk_print(line, "page usage: subtotal %" PRIuSIZE, - sdb->pages.all); + tbl->pages.all); const size_t branch_pages = - sdb->pages.branch + sdb->pages.nested_branch; - const size_t leaf_pages = sdb->pages.leaf + sdb->pages.nested_leaf + - sdb->pages.nested_subleaf; - if (sdb->pages.other) - line = chk_print(line, ", other %" PRIuSIZE, sdb->pages.other); - if (sdb->pages.other == 0 || - (branch_pages | leaf_pages | sdb->histogram.large_pages.count) != + tbl->pages.branch + tbl->pages.nested_branch; + const size_t leaf_pages = tbl->pages.leaf + tbl->pages.nested_leaf + + tbl->pages.nested_subleaf; + if (tbl->pages.other) + line = chk_print(line, ", other %" PRIuSIZE, tbl->pages.other); + if (tbl->pages.other == 0 || + (branch_pages | leaf_pages | tbl->histogram.large_pages.count) != 0) { line = chk_print(line, ", branch %" PRIuSIZE ", leaf %" PRIuSIZE, branch_pages, leaf_pages); - if (sdb->histogram.large_pages.count || - (sdb->flags & MDBX_DUPSORT) == 0) { + if (tbl->histogram.large_pages.count || + (tbl->flags & MDBX_DUPSORT) == 0) { line = chk_print(line, ", large %" PRIuSIZE, - sdb->histogram.large_pages.count); - if (sdb->histogram.large_pages.amount | - sdb->histogram.large_pages.count) - line = histogram_print(inner, line, &sdb->histogram.large_pages, + tbl->histogram.large_pages.count); + if (tbl->histogram.large_pages.amount | + tbl->histogram.large_pages.count) + line = histogram_print(inner, line, &tbl->histogram.large_pages, " amount", "single", true); } } - line = histogram_dist(chk_line_feed(line), &sdb->histogram.deep, + line = histogram_dist(chk_line_feed(line), &tbl->histogram.deep, "tree deep density", "1", false); - if (sdb != &chk->subdb_gc && sdb->histogram.nested_tree.count) { + if (tbl != &chk->table_gc && tbl->histogram.nested_tree.count) { line = chk_print(chk_line_feed(line), "nested tree(s) %" PRIuSIZE, - sdb->histogram.nested_tree.count); - line = histogram_dist(line, &sdb->histogram.nested_tree, " density", + tbl->histogram.nested_tree.count); + line = histogram_dist(line, &tbl->histogram.nested_tree, " density", "1", false); line = chk_print(chk_line_feed(line), "nested tree(s) pages %" PRIuSIZE ": branch %" PRIuSIZE ", leaf %" PRIuSIZE ", subleaf %" PRIuSIZE, - sdb->pages.nested_branch + sdb->pages.nested_leaf, - sdb->pages.nested_branch, sdb->pages.nested_leaf, - sdb->pages.nested_subleaf); + tbl->pages.nested_branch + tbl->pages.nested_leaf, + tbl->pages.nested_branch, tbl->pages.nested_leaf, + tbl->pages.nested_subleaf); } - const size_t bytes = pgno2bytes(env, sdb->pages.all); + const size_t bytes = pgno2bytes(env, tbl->pages.all); line = chk_print( chk_line_feed(line), "page filling: subtotal %" PRIuSIZE " bytes (%.1f%%), payload %" PRIuSIZE " (%.1f%%), unused %" PRIuSIZE " (%.1f%%)", - bytes, bytes * 100.0 / total_page_bytes, sdb->payload_bytes, - sdb->payload_bytes * 100.0 / bytes, bytes - sdb->payload_bytes, - (bytes - sdb->payload_bytes) * 100.0 / bytes); - if (sdb->pages.empty) + bytes, bytes * 100.0 / total_page_bytes, tbl->payload_bytes, + tbl->payload_bytes * 100.0 / bytes, bytes - tbl->payload_bytes, + (bytes - tbl->payload_bytes) * 100.0 / bytes); + if (tbl->pages.empty) line = chk_print(line, ", %" PRIuSIZE " empty pages", - sdb->pages.empty); - if (sdb->lost_bytes) + tbl->pages.empty); + if (tbl->lost_bytes) line = - chk_print(line, ", %" PRIuSIZE " bytes lost", sdb->lost_bytes); + chk_print(line, ", %" PRIuSIZE " bytes lost", tbl->lost_bytes); chk_line_end(line); } } @@ -11609,23 +11609,23 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { } typedef int(chk_kv_visitor)(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, const size_t record_number, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data); __cold static int chk_handle_kv(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data) { MDBX_chk_internal_t *const chk = scope->internal; int err = MDBX_SUCCESS; - assert(sdb->cookie); - if (chk->cb->subdb_handle_kv) - err = chk->cb->subdb_handle_kv(chk->usr, sdb, record_number, key, data); + assert(tbl->cookie); + if (chk->cb->table_handle_kv) + err = chk->cb->table_handle_kv(chk->usr, tbl, record_number, key, data); return err ? err : chk_check_break(scope); } __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, - MDBX_chk_subdb_t *sdb, chk_kv_visitor *handler) { + MDBX_chk_table_t *tbl, chk_kv_visitor *handler) { MDBX_chk_internal_t *const chk = scope->internal; MDBX_chk_context_t *const usr = chk->usr; MDBX_env *const env = usr->env; @@ -11638,14 +11638,14 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, chk_line_end( chk_flush(chk_print(chk_line_begin(scope, MDBX_chk_error), "abort processing %s due to a previous error", - chk_v2a(chk, &sdb->name)))); + chk_v2a(chk, &tbl->name)))); err = MDBX_BAD_TXN; goto bailout; } if (0 > (int)dbi) { err = dbi_open( - txn, &sdb->name, MDBX_DB_ACCEDE, &dbi, + txn, &tbl->name, MDBX_DB_ACCEDE, &dbi, (chk->flags & MDBX_CHK_IGNORE_ORDER) ? cmp_equal_or_greater : nullptr, (chk->flags & MDBX_CHK_IGNORE_ORDER) ? cmp_equal_or_greater : nullptr); if (unlikely(err)) { @@ -11661,7 +11661,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, const tree_t *const db = txn->dbs + dbi; if (handler) { const char *key_mode = nullptr; - switch (sdb->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { + switch (tbl->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { case 0: key_mode = "usual"; break; @@ -11677,11 +11677,11 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, default: key_mode = "inconsistent"; chk_scope_issue(scope, "wrong key-mode (0x%x)", - sdb->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)); + tbl->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)); } const char *value_mode = nullptr; - switch (sdb->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | + switch (tbl->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP)) { case 0: value_mode = "single"; @@ -11710,7 +11710,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, default: value_mode = "inconsistent"; chk_scope_issue(scope, "wrong value-mode (0x%x)", - sdb->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | + tbl->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP)); } @@ -11718,7 +11718,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, line = chk_print(line, "key-value kind: %s-key => %s-value", key_mode, value_mode); line = chk_print(line, ", flags:"); - if (!sdb->flags) + if (!tbl->flags) line = chk_print(line, " none"); else { const uint8_t f[] = {MDBX_DUPSORT, @@ -11731,10 +11731,10 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, const char *const t[] = {"dupsort", "integerkey", "reversekey", "dupfix", "reversedup", "integerdup"}; for (size_t i = 0; f[i]; i++) - if (sdb->flags & f[i]) + if (tbl->flags & f[i]) line = chk_print(line, " %s", t[i]); } - chk_line_end(chk_print(line, " (0x%02X)", sdb->flags)); + chk_line_end(chk_print(line, " (0x%02X)", tbl->flags)); line = chk_print(chk_line_begin(scope, MDBX_chk_verbose), "entries %" PRIu64 ", sequence %" PRIu64, db->items, @@ -11752,14 +11752,14 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, db->large_pages)); if ((chk->flags & MDBX_CHK_SKIP_BTREE_TRAVERSAL) == 0) { - const size_t branch_pages = sdb->pages.branch + sdb->pages.nested_branch; - const size_t leaf_pages = sdb->pages.leaf + sdb->pages.nested_leaf; + const size_t branch_pages = tbl->pages.branch + tbl->pages.nested_branch; + const size_t leaf_pages = tbl->pages.leaf + tbl->pages.nested_leaf; const size_t subtotal_pages = db->branch_pages + db->leaf_pages + db->large_pages; - if (subtotal_pages != sdb->pages.all) + if (subtotal_pages != tbl->pages.all) chk_scope_issue( scope, "%s pages mismatch (%" PRIuSIZE " != walked %" PRIuSIZE ")", - "subtotal", subtotal_pages, sdb->pages.all); + "subtotal", subtotal_pages, tbl->pages.all); if (db->branch_pages != branch_pages) chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", @@ -11768,11 +11768,11 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", "all-leaf", db->leaf_pages, leaf_pages); - if (db->large_pages != sdb->histogram.large_pages.amount) + if (db->large_pages != tbl->histogram.large_pages.amount) chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", "large/overlow", db->large_pages, - sdb->histogram.large_pages.amount); + tbl->histogram.large_pages.amount); } } @@ -11787,7 +11787,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, cursor->subcur->cursor.checking |= z_ignord | z_pagecheck; } - const size_t maxkeysize = mdbx_env_get_maxkeysize_ex(env, sdb->flags); + const size_t maxkeysize = mdbx_env_get_maxkeysize_ex(env, tbl->flags); MDBX_val prev_key = {nullptr, 0}, prev_data = {nullptr, 0}; MDBX_val key, data; err = mdbx_cursor_get(cursor, &key, &data, MDBX_FIRST); @@ -11802,7 +11802,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, "key length exceeds max-key-size", "%" PRIuPTR " > %" PRIuPTR, key.iov_len, maxkeysize); bad_key = true; - } else if ((sdb->flags & MDBX_INTEGERKEY) && key.iov_len != 8 && + } else if ((tbl->flags & MDBX_INTEGERKEY) && key.iov_len != 8 && key.iov_len != 4) { chk_object_issue(scope, "entry", record_count, "wrong key length", "%" PRIuPTR " != 4or8", key.iov_len); @@ -11810,7 +11810,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } bool bad_data = false; - if ((sdb->flags & MDBX_INTEGERDUP) && data.iov_len != 8 && + if ((tbl->flags & MDBX_INTEGERDUP) && data.iov_len != 8 && data.iov_len != 4) { chk_object_issue(scope, "entry", record_count, "wrong data length", "%" PRIuPTR " != 4or8", data.iov_len); @@ -11818,7 +11818,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } if (prev_key.iov_base) { - if (prev_data.iov_base && !bad_data && (sdb->flags & MDBX_DUPFIXED) && + if (prev_data.iov_base && !bad_data && (tbl->flags & MDBX_DUPFIXED) && prev_data.iov_len != data.iov_len) { chk_object_issue(scope, "entry", record_count, "different data length", "%" PRIuPTR " != %" PRIuPTR, prev_data.iov_len, @@ -11830,7 +11830,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, int cmp = mdbx_cmp(txn, dbi, &key, &prev_key); if (cmp == 0) { ++dups; - if ((sdb->flags & MDBX_DUPSORT) == 0) { + if ((tbl->flags & MDBX_DUPSORT) == 0) { chk_object_issue(scope, "entry", record_count, "duplicated entries", nullptr); if (prev_data.iov_base && data.iov_len == prev_data.iov_len && @@ -11853,57 +11853,55 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } if (!bad_key) { - if (!prev_key.iov_base && (sdb->flags & MDBX_INTEGERKEY)) + if (!prev_key.iov_base && (tbl->flags & MDBX_INTEGERKEY)) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "fixed key-size %" PRIuSIZE, key.iov_len)); prev_key = key; } if (!bad_data) { if (!prev_data.iov_base && - (sdb->flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED))) + (tbl->flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED))) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "fixed data-size %" PRIuSIZE, data.iov_len)); prev_data = data; } record_count++; - histogram_acc(key.iov_len, &sdb->histogram.key_len); - histogram_acc(data.iov_len, &sdb->histogram.val_len); + histogram_acc(key.iov_len, &tbl->histogram.key_len); + histogram_acc(data.iov_len, &tbl->histogram.val_len); const node_t *const node = page_node(cursor->pg[cursor->top], cursor->ki[cursor->top]); - if (node_flags(node) == N_SUBDATA) { - if (dbi != MAIN_DBI || (sdb->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | + if (node_flags(node) == N_TREE) { + if (dbi != MAIN_DBI || (tbl->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | MDBX_REVERSEDUP | MDBX_INTEGERDUP))) - chk_object_issue(scope, "entry", record_count, - "unexpected sub-database", "node-flags 0x%x", - node_flags(node)); + chk_object_issue(scope, "entry", record_count, "unexpected table", + "node-flags 0x%x", node_flags(node)); else if (data.iov_len != sizeof(tree_t)) - chk_object_issue(scope, "entry", record_count, - "wrong sub-database node size", + chk_object_issue(scope, "entry", record_count, "wrong table node size", "node-size %" PRIuSIZE " != %" PRIuSIZE, data.iov_len, sizeof(tree_t)); else if (scope->stage == MDBX_chk_maindb) - /* подсчитываем subDB при первом проходе */ + /* подсчитываем table при первом проходе */ sub_databases += 1; else { - /* обработка subDB при втором проходе */ + /* обработка table при втором проходе */ tree_t aligned_db; memcpy(&aligned_db, data.iov_base, sizeof(aligned_db)); - walk_sdb_t sdb_info = {.name = key}; - sdb_info.internal = &aligned_db; - MDBX_chk_subdb_t *subdb; - err = chk_get_sdb(scope, &sdb_info, &subdb); + walk_tbl_t tbl_info = {.name = key}; + tbl_info.internal = &aligned_db; + MDBX_chk_table_t *table; + err = chk_get_tbl(scope, &tbl_info, &table); if (unlikely(err)) goto bailout; - if (subdb->cookie) { + if (table->cookie) { err = chk_scope_begin( - chk, 0, MDBX_chk_subdbs, subdb, &usr->result.problems_kv, - "Processing subDB %s...", chk_v2a(chk, &subdb->name)); + chk, 0, MDBX_chk_tables, table, &usr->result.problems_kv, + "Processing table %s...", chk_v2a(chk, &table->name)); if (likely(!err)) { - err = chk_db(usr->scope, (MDBX_dbi)-1, subdb, chk_handle_kv); + err = chk_db(usr->scope, (MDBX_dbi)-1, table, chk_handle_kv); if (err != MDBX_EINTR && err != MDBX_RESULT_TRUE) - usr->result.subdb_processed += 1; + usr->result.table_processed += 1; } err = chk_scope_restore(scope, err); if (unlikely(err)) @@ -11911,10 +11909,10 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } else chk_line_end(chk_flush( chk_print(chk_line_begin(scope, MDBX_chk_processing), - "Skip processing %s...", chk_v2a(chk, &subdb->name)))); + "Skip processing %s...", chk_v2a(chk, &table->name)))); } } else if (handler) { - err = handler(scope, sdb, record_count, &key, &data); + err = handler(scope, tbl, record_count, &key, &data); if (unlikely(err)) goto bailout; } @@ -11931,32 +11929,32 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, bailout: if (cursor) { if (handler) { - if (sdb->histogram.key_len.count) { + if (tbl->histogram.key_len.count) { MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_info); - line = histogram_dist(line, &sdb->histogram.key_len, + line = histogram_dist(line, &tbl->histogram.key_len, "key length density", "0/1", false); chk_line_feed(line); - line = histogram_dist(line, &sdb->histogram.val_len, + line = histogram_dist(line, &tbl->histogram.val_len, "value length density", "0/1", false); chk_line_end(line); } if (scope->stage == MDBX_chk_maindb) - usr->result.subdb_total = sub_databases; - if (chk->cb->subdb_conclude) - err = chk->cb->subdb_conclude(usr, sdb, cursor, err); + usr->result.table_total = sub_databases; + if (chk->cb->table_conclude) + err = chk->cb->table_conclude(usr, tbl, cursor, err); MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_resolution); line = chk_print(line, "summary: %" PRIuSIZE " records,", record_count); - if (dups || (sdb->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | + if (dups || (tbl->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | MDBX_REVERSEDUP | MDBX_INTEGERDUP))) line = chk_print(line, " %" PRIuSIZE " dups,", dups); if (sub_databases || dbi == MAIN_DBI) - line = chk_print(line, " %" PRIuSIZE " sub-databases,", sub_databases); + line = chk_print(line, " %" PRIuSIZE " tables,", sub_databases); line = chk_print(line, " %" PRIuSIZE " key's bytes," " %" PRIuSIZE " data's bytes," " %" PRIuSIZE " problem(s)", - sdb->histogram.key_len.amount, - sdb->histogram.val_len.amount, scope->subtotal_issues); + tbl->histogram.key_len.amount, + tbl->histogram.val_len.amount, scope->subtotal_issues); chk_line_end(chk_flush(line)); } @@ -11968,13 +11966,13 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data) { MDBX_chk_internal_t *const chk = scope->internal; MDBX_chk_context_t *const usr = chk->usr; - assert(sdb == &chk->subdb_gc); - (void)sdb; + assert(tbl == &chk->table_gc); + (void)tbl; const char *bad = ""; pgno_t *iptr = data->iov_base; @@ -12043,9 +12041,9 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, if (id == 0) chk->pagemap[pgno] = -1 /* mark the pgno listed in GC */; else if (id > 0) { - assert(id - 1 <= (intptr_t)ARRAY_LENGTH(chk->subdb)); + assert(id - 1 <= (intptr_t)ARRAY_LENGTH(chk->table)); chk_object_issue(scope, "page", pgno, "already used", "by %s", - chk_v2a(chk, &chk->subdb[id - 1]->name)); + chk_v2a(chk, &chk->table[id - 1]->name)); } else chk_object_issue(scope, "page", pgno, "already listed in GC", nullptr); @@ -12057,7 +12055,7 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, : pgno_sub(pgno, span))) ++span; } - if (sdb->cookie) { + if (tbl->cookie) { chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_details), "transaction %" PRIaTXN ", %" PRIuSIZE " pages, maxspan %" PRIuSIZE "%s", @@ -12070,7 +12068,7 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, : pgno_sub(pgno, span)); ++span) ; - histogram_acc(span, &sdb->histogram.nested_tree); + histogram_acc(span, &tbl->histogram.nested_tree); MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_extra); if (line) { if (span > 1) @@ -12343,13 +12341,13 @@ __cold static int env_chk(MDBX_chk_scope_t *const scope) { usr->result.problems_gc = usr->result.gc_tree_problems)); else { err = chk_scope_begin( - chk, -1, MDBX_chk_gc, &chk->subdb_gc, &usr->result.problems_gc, + chk, -1, MDBX_chk_gc, &chk->table_gc, &usr->result.problems_gc, "Processing %s by txn#%" PRIaTXN "...", subj_gc, txn->txnid); if (likely(!err)) - err = chk_db(usr->scope, FREE_DBI, &chk->subdb_gc, chk_handle_gc); + err = chk_db(usr->scope, FREE_DBI, &chk->table_gc, chk_handle_gc); line = chk_line_begin(scope, MDBX_chk_info); if (line) { - histogram_print(scope, line, &chk->subdb_gc.histogram.nested_tree, + histogram_print(scope, line, &chk->table_gc.histogram.nested_tree, "span(s)", "single", false); chk_line_end(line); } @@ -12481,32 +12479,32 @@ __cold static int env_chk(MDBX_chk_scope_t *const scope) { subj_main, subj_tree, usr->result.problems_kv = usr->result.kv_tree_problems)); else { - err = chk_scope_begin(chk, 0, MDBX_chk_maindb, &chk->subdb_main, + err = chk_scope_begin(chk, 0, MDBX_chk_maindb, &chk->table_main, &usr->result.problems_kv, "Processing %s...", subj_main); if (likely(!err)) - err = chk_db(usr->scope, MAIN_DBI, &chk->subdb_main, chk_handle_kv); + err = chk_db(usr->scope, MAIN_DBI, &chk->table_main, chk_handle_kv); chk_scope_restore(scope, err); - const char *const subj_subdbs = "sub-database(s)"; - if (usr->result.problems_kv && usr->result.subdb_total) + const char *const subj_tables = "table(s)"; + if (usr->result.problems_kv && usr->result.table_total) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_processing), - "Skip processing %s", subj_subdbs)); - else if (usr->result.problems_kv == 0 && usr->result.subdb_total == 0) + "Skip processing %s", subj_tables)); + else if (usr->result.problems_kv == 0 && usr->result.table_total == 0) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "No %s", - subj_subdbs)); - else if (usr->result.problems_kv == 0 && usr->result.subdb_total) { + subj_tables)); + else if (usr->result.problems_kv == 0 && usr->result.table_total) { err = chk_scope_begin( - chk, 1, MDBX_chk_subdbs, nullptr, &usr->result.problems_kv, - "Processing %s by txn#%" PRIaTXN "...", subj_subdbs, txn->txnid); + chk, 1, MDBX_chk_tables, nullptr, &usr->result.problems_kv, + "Processing %s by txn#%" PRIaTXN "...", subj_tables, txn->txnid); if (!err) - err = chk_db(usr->scope, MAIN_DBI, &chk->subdb_main, nullptr); + err = chk_db(usr->scope, MAIN_DBI, &chk->table_main, nullptr); if (usr->scope->subtotal_issues) chk_line_end(chk_print(chk_line_begin(usr->scope, MDBX_chk_resolution), "processed %" PRIuSIZE " of %" PRIuSIZE " %s, %" PRIuSIZE " problems(s)", - usr->result.subdb_processed, - usr->result.subdb_total, subj_subdbs, + usr->result.table_processed, + usr->result.table_total, subj_tables, usr->scope->subtotal_issues)); } chk_scope_restore(scope, err); @@ -12546,20 +12544,20 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb, chk->usr->env = env; chk->flags = flags; - chk->subdb_gc.id = -1; - chk->subdb_gc.name.iov_base = MDBX_CHK_GC; - chk->subdb[FREE_DBI] = &chk->subdb_gc; + chk->table_gc.id = -1; + chk->table_gc.name.iov_base = MDBX_CHK_GC; + chk->table[FREE_DBI] = &chk->table_gc; - chk->subdb_main.id = -1; - chk->subdb_main.name.iov_base = MDBX_CHK_MAIN; - chk->subdb[MAIN_DBI] = &chk->subdb_main; + chk->table_main.id = -1; + chk->table_main.name.iov_base = MDBX_CHK_MAIN; + chk->table[MAIN_DBI] = &chk->table_main; chk->monotime_timeout = timeout_seconds_16dot16 ? osal_16dot16_to_monotime(timeout_seconds_16dot16) + osal_monotime() : 0; chk->usr->scope_nesting = 0; - chk->usr->result.subdbs = (const void *)&chk->subdb; + chk->usr->result.tables = (const void *)&chk->table; MDBX_chk_scope_t *const top = chk->scope_stack; top->verbosity = verbosity; @@ -12591,8 +12589,8 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb, // doit if (likely(!rc)) { - chk->subdb_gc.flags = ctx->txn->dbs[FREE_DBI].flags; - chk->subdb_main.flags = ctx->txn->dbs[MAIN_DBI].flags; + chk->table_gc.flags = ctx->txn->dbs[FREE_DBI].flags; + chk->table_main.flags = ctx->txn->dbs[MAIN_DBI].flags; rc = env_chk(top); } @@ -12999,7 +12997,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, unlikely(freedb_root_pgno >= last_pgno)) { if (report) WARNING( - "catch invalid %sdb root %" PRIaPGNO " for meta_txnid %" PRIaTXN + "catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "free", freedb_root_pgno, txnid, (env->stuck_meta < 0) @@ -13011,7 +13009,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, unlikely(maindb_root_pgno >= last_pgno)) { if (report) WARNING( - "catch invalid %sdb root %" PRIaPGNO " for meta_txnid %" PRIaTXN + "catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "main", maindb_root_pgno, txnid, (env->stuck_meta < 0) @@ -13024,7 +13022,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, likely(magic_and_version == MDBX_DATA_MAGIC)))) { if (report) WARNING( - "catch invalid %sdb.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN + "catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "free", freedb_mod_txnid, txnid, (env->stuck_meta < 0) @@ -13037,7 +13035,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, likely(magic_and_version == MDBX_DATA_MAGIC)))) { if (report) WARNING( - "catch invalid %sdb.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN + "catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "main", maindb_mod_txnid, txnid, (env->stuck_meta < 0) @@ -13052,7 +13050,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, if (unlikely(root_txnid != freedb_mod_txnid)) { if (report) WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN - " for %sdb.mod_txnid %" PRIaTXN " %s", + " for %s-db.mod_txnid %" PRIaTXN " %s", freedb_root_pgno, root_txnid, "free", freedb_mod_txnid, (env->stuck_meta < 0) ? "(workaround for incoherent flaw of " "unified page/buffer cache)" @@ -13067,7 +13065,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, if (unlikely(root_txnid != maindb_mod_txnid)) { if (report) WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN - " for %sdb.mod_txnid %" PRIaTXN " %s", + " for %s-db.mod_txnid %" PRIaTXN " %s", maindb_root_pgno, root_txnid, "main", maindb_mod_txnid, (env->stuck_meta < 0) ? "(workaround for incoherent flaw of " "unified page/buffer cache)" @@ -13138,7 +13136,7 @@ __hot int coherency_check_head(MDBX_txn *txn, const meta_ptr_t head, txn->dbs[FREE_DBI].flags &= DB_PERSISTENT_FLAGS; } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); return MDBX_SUCCESS; } @@ -13151,7 +13149,7 @@ int coherency_check_written(const MDBX_env *env, const txnid_t txnid, if (likely( coherency_check(env, head_txnid, &meta->trees.gc, meta, report))) { eASSERT(env, meta->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(meta->trees.main.flags)); + eASSERT(env, check_table_flags(meta->trees.main.flags)); return MDBX_SUCCESS; } } else if (report) { @@ -13361,17 +13359,17 @@ __cold static int stat_acc(const MDBX_txn *txn, MDBX_stat *st, size_t bytes) { if (!(txn->dbs[MAIN_DBI].flags & MDBX_DUPSORT) && txn->dbs[MAIN_DBI].items /* TODO: use `md_subs` field */) { - /* scan and account not opened named subDBs */ + /* scan and account not opened named tables */ err = tree_search(&cx.outer, nullptr, Z_FIRST); while (err == MDBX_SUCCESS) { const page_t *mp = cx.outer.pg[cx.outer.top]; for (size_t i = 0; i < page_numkeys(mp); i++) { const node_t *node = page_node(mp, i); - if (node_flags(node) != N_SUBDATA) + if (node_flags(node) != N_TREE) continue; if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %zu", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", node_ds(node)); + "invalid table node size", node_ds(node)); return MDBX_CORRUPTED; } @@ -14130,11 +14128,10 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, page_t *mp = mc->pg[mc->top]; const size_t nkeys = page_numkeys(mp); if (is_leaf(mp)) { - if (!(mc->flags & - z_inner) /* may have nested N_SUBDATA or N_BIGDATA nodes */) { + if (!(mc->flags & z_inner) /* may have nested N_TREE or N_BIG nodes */) { for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - if (node_flags(node) == N_BIGDATA) { + if (node_flags(node) == N_BIG) { /* Need writable leaf */ if (mp != leaf) { mc->pg[mc->top] = leaf; @@ -14154,7 +14151,7 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, npages); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - } else if (node_flags(node) & N_SUBDATA) { + } else if (node_flags(node) & N_TREE) { if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, @@ -14173,7 +14170,7 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, } tree_t *nested = nullptr; - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { rc = cursor_dupsort_setup(mc, node, mp); if (likely(rc == MDBX_SUCCESS)) { nested = &mc->subcur->nested_tree; @@ -15181,10 +15178,10 @@ static __always_inline int couple_init(cursor_couple_t *couple, } if (unlikely(*dbi_state & DBI_STALE)) - return sdb_fetch(couple->outer.txn, cursor_dbi(&couple->outer)); + return tbl_fetch(couple->outer.txn, cursor_dbi(&couple->outer)); if (unlikely(kvx->clc.k.lmax == 0)) - return sdb_setup(txn->env, kvx, tree); + return tbl_setup(txn->env, kvx, tree); return MDBX_SUCCESS; } @@ -15223,7 +15220,7 @@ int cursor_dupsort_setup(MDBX_cursor *mc, const node_t *node, default: ERROR("invalid node flags %u", flags); goto bailout; - case N_DUPDATA | N_SUBDATA: + case N_DUP | N_TREE: if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("invalid nested-db record size (%zu, expect %zu)", node_ds(node), sizeof(tree_t)); @@ -15239,7 +15236,7 @@ int cursor_dupsort_setup(MDBX_cursor *mc, const node_t *node, } mx->cursor.top_and_flags = z_fresh_mark | z_inner; break; - case N_DUPDATA: + case N_DUP: if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) <= PAGEHDRSZ)) { ERROR("invalid nested-page size %zu", node_ds(node)); goto bailout; @@ -15414,12 +15411,12 @@ static __always_inline int cursor_bring(const bool inner, const bool tend2first, } const node_t *__restrict node = page_node(mp, ki); - if (!inner && (node_flags(node) & N_DUPDATA)) { + if (!inner && (node_flags(node) & N_DUP)) { int err = cursor_dupsort_setup(mc, node, mp); if (unlikely(err != MDBX_SUCCESS)) return err; MDBX_ANALYSIS_ASSUME(mc->subcur != nullptr); - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { err = tend2first ? inner_first(&mc->subcur->cursor, data) : inner_last(&mc->subcur->cursor, data); if (unlikely(err != MDBX_SUCCESS)) @@ -15666,7 +15663,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, if (mc->subcur) { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { cASSERT(mc, inner_pointed(mc)); /* Если за ключом более одного значения, либо если размер данных * отличается, то вместо обновления требуется удаление и @@ -15726,7 +15723,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, } } else { csr_t csr = - /* olddata may not be updated in case DUPFIX-page of dupfix-subDB */ + /* olddata may not be updated in case DUPFIX-page of dupfix-table */ cursor_seek(mc, (MDBX_val *)key, &old_data, MDBX_SET); rc = csr.err; exact = csr.exact; @@ -15744,7 +15741,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, eASSERT(env, data->iov_len == 0 && (old_data.iov_len == 0 || /* olddata may not be updated in case - DUPFIX-page of dupfix-subDB */ + DUPFIX-page of dupfix-table */ (mc->tree->flags & MDBX_DUPFIXED))); return MDBX_SUCCESS; } @@ -15887,7 +15884,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, node_t *const node = page_node(mc->pg[mc->top], mc->ki[mc->top]); /* Large/Overflow page overwrites need special handling */ - if (unlikely(node_flags(node) & N_BIGDATA)) { + if (unlikely(node_flags(node) & N_BIG)) { const size_t dpages = (node_size(key, data) > env->leaf_nodemax) ? largechunk_npages(env, data->iov_len) : 0; @@ -15974,7 +15971,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, mp->pgno = mc->pg[mc->top]->pgno; /* Was a single item before, must convert now */ - if (!(node_flags(node) & N_DUPDATA)) { + if (!(node_flags(node) & N_DUP)) { /* does data match? */ if (flags & MDBX_APPENDDUP) { const int cmp = mc->clc->v.cmp(data, &old_data); @@ -16026,9 +16023,9 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, cASSERT(mc, (xdata.iov_len & 1) == 0); fp->upper = (uint16_t)(xdata.iov_len - PAGEHDRSZ); old_data.iov_len = xdata.iov_len; /* pretend olddata is fp */ - } else if (node_flags(node) & N_SUBDATA) { + } else if (node_flags(node) & N_TREE) { /* Data is on sub-DB, just store it */ - flags |= N_DUPDATA | N_SUBDATA; + flags |= N_DUP | N_TREE; goto dupsort_put; } else { /* Data is on sub-page */ @@ -16123,7 +16120,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, fp->txnid = mc->txn->front_txnid; fp->pgno = mp->pgno; mc->subcur->cursor.pg[0] = fp; - flags |= N_DUPDATA; + flags |= N_DUP; goto dupsort_put; } xdata.iov_len = old_data.iov_len + growth; @@ -16162,7 +16159,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, cASSERT(mc, env->ps > old_data.iov_len); growth = env->ps - (unsigned)old_data.iov_len; cASSERT(mc, (growth & 1) == 0); - flags |= N_DUPDATA | N_SUBDATA; + flags |= N_DUP | N_TREE; nested_dupdb.root = mp->pgno; nested_dupdb.sequence = 0; nested_dupdb.mod_txnid = mc->txn->txnid; @@ -16197,12 +16194,12 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, if (!insert_key) node_del(mc, 0); ref_data = &xdata; - flags |= N_DUPDATA; + flags |= N_DUP; goto insert_node; } - /* MDBX passes N_SUBDATA in 'flags' to write a DB record */ - if (unlikely((node_flags(node) ^ flags) & N_SUBDATA)) + /* MDBX passes N_TREE in 'flags' to write a DB record */ + if (unlikely((node_flags(node) ^ flags) & N_TREE)) return MDBX_INCOMPATIBLE; current: @@ -16254,8 +16251,7 @@ insert_node:; } else { /* There is room already in this leaf page. */ if (is_dupfix_leaf(mc->pg[mc->top])) { - cASSERT(mc, !(naf & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) && - ref_data->iov_len == 0); + cASSERT(mc, !(naf & (N_BIG | N_TREE | N_DUP)) && ref_data->iov_len == 0); rc = node_add_dupfix(mc, mc->ki[mc->top], key); } else rc = node_add_leaf(mc, mc->ki[mc->top], key, ref_data, naf); @@ -16280,7 +16276,7 @@ insert_node:; * storing the user data in the keys field, so there are strict * size limits on dupdata. The actual data fields of the child * DB are all zero size. */ - if (flags & N_DUPDATA) { + if (flags & N_DUP) { MDBX_val empty; dupsort_put: empty.iov_len = 0; @@ -16318,7 +16314,7 @@ insert_node:; goto dupsort_error; mx->cursor.tree->items = 1; } - if (!(node_flags(node) & N_SUBDATA) || sub_root) { + if (!(node_flags(node) & N_TREE) || sub_root) { page_t *const mp = mc->pg[mc->top]; const intptr_t nkeys = page_numkeys(mp); const size_t dbi = cursor_dbi(mc); @@ -16352,7 +16348,7 @@ insert_node:; inner_flags |= (flags & MDBX_APPENDDUP) >> SHIFT_MDBX_APPENDDUP_TO_MDBX_APPEND; rc = cursor_put(&mc->subcur->cursor, data, &empty, inner_flags); - if (flags & N_SUBDATA) { + if (flags & N_TREE) { void *db = node_data(node); mc->subcur->nested_tree.mod_txnid = mc->txn->txnid; memcpy(db, &mc->subcur->nested_tree, sizeof(tree_t)); @@ -16479,12 +16475,12 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { goto del_key; node_t *node = page_node(mp, mc->ki[mc->top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { if (flags & (MDBX_ALLDUPS | /* for compatibility */ MDBX_NODUPDATA)) { /* will subtract the final entry later */ mc->tree->items -= mc->subcur->nested_tree.items - 1; } else { - if (!(node_flags(node) & N_SUBDATA)) { + if (!(node_flags(node) & N_TREE)) { page_t *sp = node_data(node); cASSERT(mc, is_subpage(sp)); sp->txnid = mp->txnid; @@ -16495,8 +16491,8 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { return rc; /* If sub-DB still has entries, we're done */ if (mc->subcur->nested_tree.items) { - if (node_flags(node) & N_SUBDATA) { - /* update subDB info */ + if (node_flags(node) & N_TREE) { + /* update table info */ mc->subcur->nested_tree.mod_txnid = mc->txn->txnid; memcpy(node_data(node), &mc->subcur->nested_tree, sizeof(tree_t)); } else { @@ -16517,7 +16513,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { } if (m2->ki[mc->top] != mc->ki[mc->top]) { inner = page_node(mp, m2->ki[mc->top]); - if (node_flags(inner) & N_SUBDATA) + if (node_flags(inner) & N_TREE) continue; } m2->subcur->cursor.pg[0] = node_data(inner); @@ -16531,7 +16527,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { /* otherwise fall thru and delete the sub-DB */ } - if ((node_flags(node) & N_SUBDATA) && mc->subcur->cursor.tree->height) { + if ((node_flags(node) & N_TREE) && mc->subcur->cursor.tree->height) { /* add all the child DB's pages to the free list */ rc = tree_drop(&mc->subcur->cursor, false); if (unlikely(rc != MDBX_SUCCESS)) @@ -16540,13 +16536,13 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { inner_gone(mc); } else { cASSERT(mc, !inner_pointed(mc)); - /* MDBX passes N_SUBDATA in 'flags' to delete a DB record */ - if (unlikely((node_flags(node) ^ flags) & N_SUBDATA)) + /* MDBX passes N_TREE in 'flags' to delete a DB record */ + if (unlikely((node_flags(node) ^ flags) & N_TREE)) return MDBX_INCOMPATIBLE; } /* add large/overflow pages to free list */ - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { pgr_t lp = page_get_large(mc, node_largedata_pgno(node), mp->txnid); if (unlikely((rc = lp.err) || (rc = page_retire(mc, lp.page)))) goto fail; @@ -16624,19 +16620,19 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { /* уже переместились вправо */ m3->pg[top] != mp)) { node = page_node(m3->pg[m3->top], m3->ki[m3->top]); /* Если это dupsort-узел, то должен быть валидный вложенный курсор. */ - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { /* Тут три варианта событий: - * 1) Вложенный курсор уже инициализирован, у узла есть флаг N_SUBDATA, + * 1) Вложенный курсор уже инициализирован, у узла есть флаг N_TREE, * соответственно дубликаты вынесены в отдельное дерево с корнем * в отдельной странице = ничего корректировать не требуется. - * 2) Вложенный курсор уже инициализирован, у узла нет флага N_SUBDATA, + * 2) Вложенный курсор уже инициализирован, у узла нет флага N_TREE, * соответственно дубликаты размещены на вложенной sub-странице. * 3) Курсор стоял на удалённом элементе, который имел одно значение, * а после удаления переместился на следующий элемент с дубликатами. * В этом случае вложенный курсор не инициализирован и тепеь его * нужно установить на первый дубликат. */ if (is_pointed(&m3->subcur->cursor)) { - if ((node_flags(node) & N_SUBDATA) == 0) { + if ((node_flags(node) & N_TREE) == 0) { cASSERT(m3, m3->subcur->cursor.top == 0 && m3->subcur->nested_tree.height == 1); m3->subcur->cursor.pg[0] = node_data(node); @@ -16645,7 +16641,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { rc = cursor_dupsort_setup(m3, node, m3->pg[m3->top]); if (unlikely(rc != MDBX_SUCCESS)) goto fail; - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { rc = inner_first(&m3->subcur->cursor, nullptr); if (unlikely(rc != MDBX_SUCCESS)) goto fail; @@ -16865,13 +16861,13 @@ __hot csr_t cursor_seek(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, return ret; } - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { ret.err = cursor_dupsort_setup(mc, node, mp); if (unlikely(ret.err != MDBX_SUCCESS)) return ret; if (op >= MDBX_SET) { MDBX_ANALYSIS_ASSUME(mc->subcur != nullptr); - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { ret.err = inner_first(&mc->subcur->cursor, data); if (unlikely(ret.err != MDBX_SUCCESS)) return ret; @@ -16983,7 +16979,7 @@ __hot int cursor_ops(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, get_key_optional(node, key); if (!data) return MDBX_SUCCESS; - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { if (!MDBX_DISABLE_VALIDATION && unlikely(!mc->subcur)) return unexpected_dupsort(mc); mc = &mc->subcur->cursor; @@ -17114,7 +17110,7 @@ __hot int cursor_ops(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, else { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); get_key_optional(node, key); - if ((node_flags(node) & N_DUPDATA) == 0) + if ((node_flags(node) & N_DUP) == 0) return node_read(mc, node, data, mc->pg[mc->top]); else if (MDBX_DISABLE_VALIDATION || likely(mc->subcur)) return ((op == MDBX_FIRST_DUP) ? inner_first @@ -17406,7 +17402,7 @@ __noinline int dbi_import(MDBX_txn *txn, const size_t dbi) { if (parent) { /* вложенная пишущая транзакция */ int rc = dbi_check(parent, dbi); - /* копируем состояние subDB очищая new-флаги. */ + /* копируем состояние table очищая new-флаги. */ eASSERT(env, txn->dbi_seqs == parent->dbi_seqs); txn->dbi_state[dbi] = parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY); @@ -17577,15 +17573,15 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, /* Если dbi уже использовался, то корректными считаем четыре варианта: * 1) user_flags равны MDBX_DB_ACCEDE - * = предполагаем что пользователь открывает существующую subDb, + * = предполагаем что пользователь открывает существующую table, * при этом код проверки не позволит установить другие компараторы. * 2) user_flags нулевые, а оба компаратора пустые/нулевые или равны текущим - * = предполагаем что пользователь открывает существующую subDb + * = предполагаем что пользователь открывает существующую table * старым способом с нулевыми с флагами по-умолчанию. * 3) user_flags совпадают, а компараторы не заданы или те же - * = предполагаем что пользователь открывает subDb указывая все параметры; - * 4) user_flags отличаются, но subDb пустая и задан флаг MDBX_CREATE - * = предполагаем что пользователь пересоздает subDb; + * = предполагаем что пользователь открывает table указывая все параметры; + * 4) user_flags отличаются, но table пустая и задан флаг MDBX_CREATE + * = предполагаем что пользователь пересоздает table; */ if ((user_flags & ~MDBX_CREATE) != (unsigned)(env->dbs_flags[dbi] & DB_PERSISTENT_FLAGS)) { @@ -17599,7 +17595,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, else { eASSERT(env, env->dbs_flags[dbi] & DB_VALID); if (txn->dbi_state[dbi] & DBI_STALE) { - int err = sdb_fetch(txn, dbi); + int err = tbl_fetch(txn, dbi); if (unlikely(err == MDBX_SUCCESS)) return err; } @@ -17609,7 +17605,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, if (unlikely(txn->dbs[dbi].leaf_pages)) return /* FIXME: return extended info */ MDBX_INCOMPATIBLE; - /* Пересоздаём subDB если там пусто */ + /* Пересоздаём table если там пусто */ if (unlikely(txn->cursors[dbi])) return MDBX_DANGLING_DBI; env->dbs_flags[dbi] = DB_POISON; @@ -17624,7 +17620,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, env->kvs[dbi].clc.v.cmp = datacmp ? datacmp : builtin_datacmp(user_flags); txn->dbs[dbi].flags = db_flags; txn->dbs[dbi].dupfix_size = 0; - if (unlikely(sdb_setup(env, &env->kvs[dbi], &txn->dbs[dbi]))) { + if (unlikely(tbl_setup(env, &env->kvs[dbi], &txn->dbs[dbi]))) { txn->dbi_state[dbi] = DBI_LINDO; txn->flags |= MDBX_TXN_ERROR; return MDBX_PROBLEM; @@ -17697,7 +17693,7 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, env->kvs[MAIN_DBI].clc.v.cmp = builtin_datacmp(main_flags); txn->dbs[MAIN_DBI].flags = main_flags; txn->dbs[MAIN_DBI].dupfix_size = 0; - int err = sdb_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); + int err = tbl_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); if (unlikely(err != MDBX_SUCCESS)) { txn->dbi_state[MAIN_DBI] = DBI_LINDO; txn->flags |= MDBX_TXN_ERROR; @@ -17777,11 +17773,11 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, /* make sure this is actually a table */ node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (unlikely((node_flags(node) & (N_DUPDATA | N_SUBDATA)) != N_SUBDATA)) + if (unlikely((node_flags(node) & (N_DUP | N_TREE)) != N_TREE)) return MDBX_INCOMPATIBLE; if (!MDBX_DISABLE_VALIDATION && unlikely(body.iov_len != sizeof(tree_t))) { ERROR("%s/%d: %s %zu", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", body.iov_len); + "invalid table node size", body.iov_len); return MDBX_CORRUPTED; } memcpy(&txn->dbs[slot], body.iov_base, sizeof(tree_t)); @@ -17807,8 +17803,8 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, txn->dbs[slot].flags = user_flags & DB_PERSISTENT_FLAGS; cx.outer.next = txn->cursors[MAIN_DBI]; txn->cursors[MAIN_DBI] = &cx.outer; - rc = cursor_put_checklen(&cx.outer, &name, &body, - N_SUBDATA | MDBX_NOOVERWRITE); + rc = + cursor_put_checklen(&cx.outer, &name, &body, N_TREE | MDBX_NOOVERWRITE); txn->cursors[MAIN_DBI] = cx.outer.next; if (unlikely(rc != MDBX_SUCCESS)) goto bailout; @@ -17859,7 +17855,7 @@ int dbi_open(MDBX_txn *txn, const MDBX_val *const name, unsigned user_flags, *dbi = 0; if (user_flags != MDBX_ACCEDE && - unlikely(!check_sdb_flags(user_flags & ~MDBX_CREATE))) + unlikely(!check_table_flags(user_flags & ~MDBX_CREATE))) return MDBX_EINVAL; int rc = check_txn(txn, MDBX_TXN_BLOCKED); @@ -18013,11 +18009,11 @@ dbi_rename_locked(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val new_name) { MDBX_val data = {&txn->dbs[dbi], sizeof(tree_t)}; pair.err = cursor_put_checklen(&cx.outer, &new_name, &data, - N_SUBDATA | MDBX_NOOVERWRITE); + N_TREE | MDBX_NOOVERWRITE); if (likely(pair.err == MDBX_SUCCESS)) { pair.err = cursor_seek(&cx.outer, &old_name, nullptr, MDBX_SET).err; if (likely(pair.err == MDBX_SUCCESS)) - pair.err = cursor_del(&cx.outer, N_SUBDATA); + pair.err = cursor_del(&cx.outer, N_TREE); if (likely(pair.err == MDBX_SUCCESS)) { pair.defer = env->kvs[dbi].name.iov_base; env->kvs[dbi].name = new_name; @@ -18131,7 +18127,7 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) { if (likely(rc == MDBX_SUCCESS)) { cx.outer.next = txn->cursors[MAIN_DBI]; txn->cursors[MAIN_DBI] = &cx.outer; - rc = cursor_del(&cx.outer, N_SUBDATA); + rc = cursor_del(&cx.outer, N_TREE); txn->cursors[MAIN_DBI] = cx.outer.next; if (likely(rc == MDBX_SUCCESS)) { tASSERT(txn, txn->dbi_state[MAIN_DBI] & DBI_DIRTY); @@ -18261,7 +18257,7 @@ __cold int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest, return MDBX_BAD_TXN; if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { - rc = sdb_fetch((MDBX_txn *)txn, dbi); + rc = tbl_fetch((MDBX_txn *)txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) return rc; } @@ -18295,8 +18291,8 @@ __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi, return fallback; } -__cold int mdbx_enumerate_subdb(const MDBX_txn *txn, MDBX_subdb_enum_func *func, - void *ctx) { +__cold int mdbx_enumerate_tables(const MDBX_txn *txn, + MDBX_table_enum_func *func, void *ctx) { if (unlikely(!func)) return MDBX_EINVAL; @@ -18315,7 +18311,7 @@ __cold int mdbx_enumerate_subdb(const MDBX_txn *txn, MDBX_subdb_enum_func *func, rc = outer_next(&cx.outer, nullptr, nullptr, MDBX_NEXT_NODUP)) { node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (node_flags(node) != N_SUBDATA) + if (node_flags(node) != N_TREE) continue; if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, @@ -20006,7 +20002,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika_t *const troika) { eASSERT(env, ((env->flags ^ flags) & MDBX_WRITEMAP) == 0); eASSERT(env, pending->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(pending->trees.main.flags)); + eASSERT(env, check_table_flags(pending->trees.main.flags)); const meta_t *const meta0 = METAPAGE(env, 0); const meta_t *const meta1 = METAPAGE(env, 1); const meta_t *const meta2 = METAPAGE(env, 2); @@ -20305,7 +20301,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, target->trees.gc = pending->trees.gc; target->trees.main = pending->trees.main; eASSERT(env, target->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(target->trees.main.flags)); + eASSERT(env, check_table_flags(target->trees.main.flags)); target->canary = pending->canary; memcpy(target->pages_retired, pending->pages_retired, 8); jitter4testing(true); @@ -20360,7 +20356,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, #endif /* MDBX_ENABLE_PGOP_STAT */ const meta_t undo_meta = *target; eASSERT(env, pending->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(pending->trees.main.flags)); + eASSERT(env, check_table_flags(pending->trees.main.flags)); rc = osal_pwrite(env->fd4meta, pending, sizeof(meta_t), ptr_dist(target, env->dxb_mmap.base)); if (unlikely(rc != MDBX_SUCCESS)) { @@ -26567,9 +26563,9 @@ __cold const char *pagetype_caption(const uint8_t type, char buf4unknown[16]) { __cold static const char *leafnode_type(node_t *n) { static const char *const tp[2][2] = {{"", ": DB"}, {": sub-page", ": sub-DB"}}; - return (node_flags(n) & N_BIGDATA) + return (node_flags(n) & N_BIG) ? ": large page" - : tp[!!(node_flags(n) & N_DUPDATA)][!!(node_flags(n) & N_SUBDATA)]; + : tp[!!(node_flags(n) & N_DUP)][!!(node_flags(n) & N_TREE)]; } /* Display all the keys in the page. */ @@ -26629,7 +26625,7 @@ __cold void page_list(page_t *mp) { DKEY(&key)); total += nsize; } else { - if (node_flags(node) & N_BIGDATA) + if (node_flags(node) & N_BIG) nsize += sizeof(pgno_t); else nsize += node_ds(node); @@ -27241,7 +27237,7 @@ __cold int meta_validate(MDBX_env *env, meta_t *const meta, return MDBX_INCOMPATIBLE; } - if (unlikely(!check_sdb_flags(meta->trees.main.flags))) { + if (unlikely(!check_table_flags(meta->trees.main.flags))) { WARNING("meta[%u] has invalid %s flags 0x%x, skip it", meta_number, "MainDB", meta->trees.main.flags); return MDBX_INCOMPATIBLE; @@ -27487,7 +27483,7 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, return rc; if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { - rc = sdb_fetch(txn, dbi); + rc = tbl_fetch(txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) return rc; } @@ -27529,9 +27525,9 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, * - изменить семантику установки/обновления mod_txnid, привязав его * строго к изменению b-tree, но не атрибутов; * - обновлять mod_txnid при фиксации вложенных транзакций; - * - для dbi-хендлов пользовательских subDb (видимо) можно оставить + * - для dbi-хендлов пользовательских table (видимо) можно оставить * DBI_DIRTY в качестве признака необходимости обновления записи - * subDb в MainDB, при этом взводить DBI_DIRTY вместе с обновлением + * table в MainDB, при этом взводить DBI_DIRTY вместе с обновлением * mod_txnid, в том числе при обновлении sequence. * - для MAIN_DBI при обновлении sequence не следует взводить DBI_DIRTY * и/или обновлять mod_txnid, а только взводить MDBX_TXN_DIRTY. @@ -27608,7 +27604,7 @@ __cold const char *mdbx_liberr2str(int errnum) { "MDBX_BAD_TXN: Transaction is not valid for requested operation," " e.g. had errored and be must aborted, has a child, or is invalid", "MDBX_BAD_VALSIZE: Invalid size or alignment of key or data" - " for target database, either invalid subDB name", + " for target database, either invalid table name", "MDBX_BAD_DBI: The specified DBI-handle is invalid" " or changed by another thread/transaction", "MDBX_PROBLEM: Unexpected internal error, transaction should be aborted", @@ -27651,7 +27647,7 @@ __cold const char *mdbx_liberr2str(int errnum) { " please keep one and remove unused other"; case MDBX_DANGLING_DBI: return "MDBX_DANGLING_DBI: Some cursors and/or other resources should be" - " closed before subDb or corresponding DBI-handle could be (re)used"; + " closed before table or corresponding DBI-handle could be (re)used"; case MDBX_OUSTED: return "MDBX_OUSTED: The parked read transaction was outed for the sake" " of recycling old MVCC snapshots"; @@ -28443,7 +28439,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, page_t *largepage = nullptr; size_t node_bytes; - if (unlikely(flags & N_BIGDATA)) { + if (unlikely(flags & N_BIG)) { /* Data already on large/overflow page. */ STATIC_ASSERT(sizeof(pgno_t) % 2 == 0); node_bytes = @@ -28456,7 +28452,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, mc->tree->flags); return MDBX_PROBLEM; } - if (unlikely(flags & (N_DUPDATA | N_SUBDATA))) { + if (unlikely(flags & (N_DUP | N_TREE))) { ERROR("Unexpected target %s flags 0x%x for large data-item", "node", flags); return MDBX_PROBLEM; @@ -28470,7 +28466,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, DEBUG("allocated %u large/overflow page(s) %" PRIaPGNO "for %" PRIuPTR " data bytes", largepage->pages, largepage->pgno, data->iov_len); - flags |= N_BIGDATA; + flags |= N_BIG; node_bytes = node_size_len(key->iov_len, 0) + sizeof(pgno_t) + sizeof(indx_t); cASSERT(mc, node_bytes == leaf_size(mc->txn->env, key, data)); @@ -28506,7 +28502,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, void *nodedata = node_data(node); if (likely(largepage == nullptr)) { - if (unlikely(flags & N_BIGDATA)) { + if (unlikely(flags & N_BIG)) { memcpy(nodedata, data->iov_base, sizeof(pgno_t)); return MDBX_SUCCESS; } @@ -28548,8 +28544,7 @@ __hot void node_del(MDBX_cursor *mc, size_t ksize) { cASSERT(mc, !is_branch(mp) || hole || node_ks(node) == 0); size_t hole_size = NODESIZE + node_ks(node); if (is_leaf(mp)) - hole_size += - (node_flags(node) & N_BIGDATA) ? sizeof(pgno_t) : node_ds(node); + hole_size += (node_flags(node) & N_BIG) ? sizeof(pgno_t) : node_ds(node); hole_size = EVEN_CEIL(hole_size); const indx_t hole_offset = mp->entries[hole]; @@ -28579,7 +28574,7 @@ __hot void node_del(MDBX_cursor *mc, size_t ksize) { __noinline int node_read_bigdata(MDBX_cursor *mc, const node_t *node, MDBX_val *data, const page_t *mp) { - cASSERT(mc, node_flags(node) == N_BIGDATA && data->iov_len == node_ds(node)); + cASSERT(mc, node_flags(node) == N_BIG && data->iov_len == node_ds(node)); pgr_t lp = page_get_large(mc, node_largedata_pgno(node), mp->txnid); if (unlikely((lp.err != MDBX_SUCCESS))) { @@ -32637,17 +32632,17 @@ __cold int page_check(const MDBX_cursor *const mc, const page_t *const mp) { rc = bad_page(mp, "invalid node[%zu] flags (%u)\n", i, node_flags(node)); break; - case N_BIGDATA /* data on large-page */: + case N_BIG /* data on large-page */: case 0 /* usual */: - case N_SUBDATA /* sub-db */: - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: - case N_DUPDATA /* short sub-page */: + case N_TREE /* sub-db */: + case N_TREE | N_DUP /* dupsorted sub-tree */: + case N_DUP /* short sub-page */: break; } const size_t dsize = node_ds(node); const char *const data = node_data(node); - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { if (unlikely(end_of_page < data + sizeof(pgno_t))) { rc = bad_page( mp, "node-%s(%zu of %zu, %zu bytes) beyond (%zu) page-end\n", @@ -32704,20 +32699,20 @@ __cold int page_check(const MDBX_cursor *const mc, const page_t *const mp) { continue; } break; - case N_SUBDATA /* sub-db */: + case N_TREE /* sub-db */: if (unlikely(dsize != sizeof(tree_t))) { rc = bad_page(mp, "invalid sub-db record size (%zu)\n", dsize); continue; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(dsize != sizeof(tree_t))) { rc = bad_page(mp, "invalid nested-db record size (%zu, expect %zu)\n", dsize, sizeof(tree_t)); continue; } break; - case N_DUPDATA /* short sub-page */: + case N_DUP /* short sub-page */: if (unlikely(dsize <= PAGEHDRSZ)) { rc = bad_page(mp, "invalid nested/sub-page record size (%zu)\n", dsize); @@ -34001,7 +33996,7 @@ __hot int tree_search(MDBX_cursor *mc, const MDBX_val *key, int flags) { const size_t dbi = cursor_dbi(mc); if (unlikely(*cursor_dbi_state(mc) & DBI_STALE)) { - err = sdb_fetch(mc->txn, dbi); + err = tbl_fetch(mc->txn, dbi); if (unlikely(err != MDBX_SUCCESS)) goto bailout; } @@ -35081,7 +35076,7 @@ static size_t spill_cursor_keep(const MDBX_txn *const txn, tASSERT(txn, is_leaf(mp)); if (!mc->subcur || mc->ki[mc->top] >= page_numkeys(mp)) break; - if (!(node_flags(page_node(mp, mc->ki[mc->top])) & N_SUBDATA)) + if (!(node_flags(page_node(mp, mc->ki[mc->top])) & N_TREE)) break; mc = &mc->subcur->cursor; } @@ -35468,8 +35463,8 @@ __cold int spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0, /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -int sdb_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { - if (unlikely(!check_sdb_flags(db->flags))) { +int tbl_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { + if (unlikely(!check_table_flags(db->flags))) { ERROR("incompatible or invalid db.flags (0x%x) ", db->flags); return MDBX_INCOMPATIBLE; } @@ -35496,7 +35491,7 @@ int sdb_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { return MDBX_SUCCESS; } -int sdb_fetch(MDBX_txn *txn, size_t dbi) { +int tbl_fetch(MDBX_txn *txn, size_t dbi) { cursor_couple_t couple; int rc = cursor_init(&couple.outer, txn, MAIN_DBI); if (unlikely(rc != MDBX_SUCCESS)) @@ -35506,7 +35501,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { rc = tree_search(&couple.outer, &kvx->name, 0); if (unlikely(rc != MDBX_SUCCESS)) { bailout: - NOTICE("dbi %zu refs to inaccessible subDB `%*s` for txn %" PRIaTXN + NOTICE("dbi %zu refs to inaccessible table `%*s` for txn %" PRIaTXN " (err %d)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, rc); @@ -35519,8 +35514,8 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { rc = MDBX_NOTFOUND; goto bailout; } - if (unlikely((node_flags(nsr.node) & (N_DUPDATA | N_SUBDATA)) != N_SUBDATA)) { - NOTICE("dbi %zu refs to not a named subDB `%*s` for txn %" PRIaTXN " (%s)", + if (unlikely((node_flags(nsr.node) & (N_DUP | N_TREE)) != N_TREE)) { + NOTICE("dbi %zu refs to not a named table `%*s` for txn %" PRIaTXN " (%s)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, "wrong flags"); return MDBX_INCOMPATIBLE; /* not a named DB */ @@ -35532,7 +35527,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { return rc; if (unlikely(data.iov_len != sizeof(tree_t))) { - NOTICE("dbi %zu refs to not a named subDB `%*s` for txn %" PRIaTXN " (%s)", + NOTICE("dbi %zu refs to not a named table `%*s` for txn %" PRIaTXN " (%s)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, "wrong rec-size"); return MDBX_INCOMPATIBLE; /* not a named DB */ @@ -35543,7 +35538,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { * have dropped and recreated the DB with other flags. */ tree_t *const db = &txn->dbs[dbi]; if (unlikely((db->flags & DB_PERSISTENT_FLAGS) != flags)) { - NOTICE("dbi %zu refs to the re-created subDB `%*s` for txn %" PRIaTXN + NOTICE("dbi %zu refs to the re-created table `%*s` for txn %" PRIaTXN " with different flags (present 0x%X != wanna 0x%X)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, db->flags & DB_PERSISTENT_FLAGS, flags); @@ -35560,7 +35555,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { return MDBX_CORRUPTED; } #endif /* !MDBX_DISABLE_VALIDATION */ - rc = sdb_setup(txn->env, kvx, db); + rc = tbl_setup(txn->env, kvx, db); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -36226,15 +36221,15 @@ void recalculate_merge_thresholds(MDBX_env *env) { : bytes / 4 /* 25 % */)); } -int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { +int tree_drop(MDBX_cursor *mc, const bool may_have_tables) { MDBX_txn *txn = mc->txn; int rc = tree_search(mc, nullptr, Z_FIRST); if (likely(rc == MDBX_SUCCESS)) { - /* DUPSORT sub-DBs have no large-pages/subDBs. Omit scanning leaves. + /* DUPSORT sub-DBs have no large-pages/tables. Omit scanning leaves. * This also avoids any P_DUPFIX pages, which have no nodes. * Also if the DB doesn't have sub-DBs and has no large/overflow * pages, omit scanning leaves. */ - if (!(may_have_subDBs | mc->tree->large_pages)) + if (!(may_have_tables | mc->tree->large_pages)) cursor_pop(mc); rc = pnl_need(&txn->tw.retired_pages, (size_t)mc->tree->branch_pages + @@ -36254,15 +36249,15 @@ int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { cASSERT(mc, mc->top + 1 == mc->tree->height); for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { rc = page_retire_ex(mc, node_largedata_pgno(node), nullptr, 0); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - if (!(may_have_subDBs | mc->tree->large_pages)) + if (!(may_have_tables | mc->tree->large_pages)) goto pop; - } else if (node_flags(node) & N_SUBDATA) { - if (unlikely((node_flags(node) & N_DUPDATA) == 0)) { - rc = /* disallowing implicit subDB deletion */ MDBX_INCOMPATIBLE; + } else if (node_flags(node) & N_TREE) { + if (unlikely((node_flags(node) & N_DUP) == 0)) { + rc = /* disallowing implicit table deletion */ MDBX_INCOMPATIBLE; goto bailout; } rc = cursor_dupsort_setup(mc, node, mp); @@ -36282,8 +36277,7 @@ int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { : P_BRANCH); for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - tASSERT(txn, (node_flags(node) & - (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + tASSERT(txn, (node_flags(node) & (N_BIG | N_TREE | N_DUP)) == 0); const pgno_t pgno = node_pgno(node); rc = page_retire_ex(mc, pgno, nullptr, pagetype); if (unlikely(rc != MDBX_SUCCESS)) @@ -37417,8 +37411,8 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, node_t *node = ptr_disp(mp, tmp_ki_copy->entries[i] + PAGEHDRSZ); size = NODESIZE + node_ks(node) + sizeof(indx_t); if (is_leaf(mp)) - size += (node_flags(node) & N_BIGDATA) ? sizeof(pgno_t) - : node_ds(node); + size += + (node_flags(node) & N_BIG) ? sizeof(pgno_t) : node_ds(node); size = EVEN_CEIL(size); } @@ -37562,7 +37556,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = node_add_leaf(mc, 0, newkey, newdata, naf); } break; case P_LEAF | P_DUPFIX: { - cASSERT(mc, (naf & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + cASSERT(mc, (naf & (N_BIG | N_TREE | N_DUP)) == 0); cASSERT(mc, newpgno == 0 || newpgno == P_INVALID); rc = node_add_dupfix(mc, 0, newkey); } break; @@ -37633,7 +37627,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = node_add_leaf(mc, n, &rkey, rdata, flags); } break; /* case P_LEAF | P_DUPFIX: { - cASSERT(mc, (nflags & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + cASSERT(mc, (nflags & (N_BIG | N_TREE | N_DUP)) == 0); cASSERT(mc, gno == 0); rc = mdbx_node_add_dupfix(mc, n, &rkey); } break; */ @@ -37745,7 +37739,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = cursor_check_updating(mc); if (unlikely(naf & MDBX_RESERVE)) { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); - if (!(node_flags(node) & N_BIGDATA)) + if (!(node_flags(node) & N_BIG)) newdata->iov_base = node_data(node); } #if MDBX_ENABLE_PGOP_STAT @@ -38607,7 +38601,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { txn->dbs[FREE_DBI].root); if (txn->n_dbi > CORE_DBS) { - /* Update subDB root pointers */ + /* Update table root pointers */ cursor_couple_t cx; rc = cursor_init(&cx.outer, txn, MAIN_DBI); if (unlikely(rc != MDBX_SUCCESS)) @@ -38624,7 +38618,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { /* Может быть mod_txnid > front после коммита вложенных тразакций */ db->mod_txnid = txn->txnid; MDBX_val data = {db, sizeof(tree_t)}; - rc = cursor_put(&cx.outer, &env->kvs[i].name, &data, N_SUBDATA); + rc = cursor_put(&cx.outer, &env->kvs[i].name, &data, N_TREE); if (unlikely(rc != MDBX_SUCCESS)) { txn->cursors[MAIN_DBI] = cx.outer.next; goto fail; @@ -38971,7 +38965,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { txn->txnid >= /* paranoia is appropriate here */ env->lck->cached_oldest.weak); tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); } else { eASSERT(env, (flags & ~(txn_rw_begin_flags | MDBX_TXN_SPILLS | MDBX_WRITEMAP | MDBX_NOSTICKYTHREADS)) == 0); @@ -39029,7 +39023,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); txn->flags = flags; txn->nested = nullptr; txn->tw.loose_pages = nullptr; @@ -39067,7 +39061,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { /* Setup db info */ tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); VALGRIND_MAKE_MEM_UNDEFINED(txn->dbi_state, env->max_dbi); #if MDBX_ENABLE_DBI_SPARSE txn->n_dbi = CORE_DBS; @@ -39118,7 +39112,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { txn->dbs[MAIN_DBI].flags); env->dbs_flags[MAIN_DBI] = DB_POISON; atomic_store32(&env->dbi_seqs[MAIN_DBI], seq, mo_AcquireRelease); - rc = sdb_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); + rc = tbl_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); if (likely(rc == MDBX_SUCCESS)) { seq = dbi_seq_next(env, MAIN_DBI); env->dbs_flags[MAIN_DBI] = DB_VALID | txn->dbs[MAIN_DBI].flags; @@ -39151,7 +39145,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); if (unlikely(env->flags & ENV_FATAL_ERROR)) { WARNING("%s", "environment had fatal error, must shutdown!"); rc = MDBX_PANIC; @@ -39992,7 +39986,7 @@ typedef struct walk_ctx { MDBX_cursor *cursor; } walk_ctx_t; -__cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb); +__cold static int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl); static page_type_t walk_page_type(const page_t *mp) { if (mp) @@ -40021,7 +40015,7 @@ 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_sdb_t *sdb, const pgno_t pgno, +__cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno, txnid_t parent_txnid) { assert(pgno != P_INVALID); page_t *mp = nullptr; @@ -40062,7 +40056,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; break; - case N_BIGDATA /* long data on the large/overflow page */: { + case N_BIG /* long data on the large/overflow page */: { const pgno_t large_pgno = node_largedata_pgno(node); const size_t over_payload = node_data_size; const size_t over_header = PAGEHDRSZ; @@ -40074,7 +40068,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, 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, - sdb, pagesize, page_large, err, 1, + tbl, pagesize, page_large, err, 1, over_payload, over_header, over_unused); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; @@ -40082,10 +40076,10 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += node_key_size & 1; } break; - case N_SUBDATA /* sub-db */: { + case N_TREE /* sub-db */: { if (unlikely(node_data_size != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", (unsigned)node_data_size); + "invalid table node size", (unsigned)node_data_size); assert(err == MDBX_CORRUPTED); err = MDBX_CORRUPTED; } @@ -40093,7 +40087,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(node_data_size != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-tree node size", (unsigned)node_data_size); @@ -40104,7 +40098,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; break; - case N_DUPDATA /* short sub-page */: { + case N_DUP /* short sub-page */: { if (unlikely(node_data_size <= PAGEHDRSZ || (node_data_size & 1))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-page node size", (unsigned)node_data_size); @@ -40150,7 +40144,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } const int rc = - ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, sdb, + ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, tbl, node_data_size, subtype, err, nsubkeys, subpayload_size, subheader_size, subunused_size + subalign_bytes); if (unlikely(rc != MDBX_SUCCESS)) @@ -40170,7 +40164,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } const int rc = ctx->visitor( - pgno, 1, ctx->userctx, ctx->deep, sdb, ctx->txn->env->ps, type, err, + pgno, 1, ctx->userctx, ctx->deep, tbl, ctx->txn->env->ps, type, err, nentries, payload_size, header_size, unused_size + align_bytes); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; @@ -40183,7 +40177,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, if (type == page_branch) { assert(err == MDBX_SUCCESS); ctx->deep += 1; - err = walk_pgno(ctx, sdb, node_pgno(node), mp->txnid); + err = walk_pgno(ctx, tbl, node_pgno(node), mp->txnid); ctx->deep -= 1; if (unlikely(err != MDBX_SUCCESS)) { if (err == MDBX_RESULT_TRUE) @@ -40198,7 +40192,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, default: continue; - case N_SUBDATA /* sub-db */: + case N_TREE /* sub-db */: if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-tree node size", (unsigned)node_ds(node)); @@ -40207,16 +40201,16 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } else { tree_t aligned_db; memcpy(&aligned_db, node_data(node), sizeof(aligned_db)); - walk_sdb_t subdb = {{node_key(node), node_ks(node)}, nullptr, nullptr}; - subdb.internal = &aligned_db; + walk_tbl_t table = {{node_key(node), node_ks(node)}, nullptr, nullptr}; + table.internal = &aligned_db; assert(err == MDBX_SUCCESS); ctx->deep += 1; - err = walk_sdb(ctx, &subdb); + err = walk_tbl(ctx, &table); ctx->deep -= 1; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid dupsort sub-tree node size", (unsigned)node_ds(node)); @@ -40232,9 +40226,9 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, &container_of(ctx->cursor, cursor_couple_t, outer)->inner); ctx->cursor = &ctx->cursor->subcur->cursor; ctx->deep += 1; - sdb->nested = &aligned_db; - err = walk_pgno(ctx, sdb, aligned_db.root, mp->txnid); - sdb->nested = nullptr; + tbl->nested = &aligned_db; + err = walk_pgno(ctx, tbl, aligned_db.root, mp->txnid); + tbl->nested = nullptr; ctx->deep -= 1; subcur_t *inner_xcursor = container_of(ctx->cursor, subcur_t, cursor); cursor_couple_t *couple = @@ -40249,8 +40243,8 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, return MDBX_SUCCESS; } -__cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb) { - tree_t *const db = sdb->internal; +__cold static int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl) { + tree_t *const db = tbl->internal; if (unlikely(db->root == P_INVALID)) return MDBX_SUCCESS; /* empty db */ @@ -40268,7 +40262,7 @@ __cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb) { couple.outer.next = ctx->cursor; couple.outer.top_and_flags = z_disable_tree_search_fastpath; ctx->cursor = &couple.outer; - rc = walk_pgno(ctx, sdb, db->root, + rc = walk_pgno(ctx, tbl, db->root, db->mod_txnid ? db->mod_txnid : ctx->txn->txnid); ctx->cursor = couple.outer.next; return rc; @@ -40282,13 +40276,13 @@ __cold int walk_pages(MDBX_txn *txn, walk_func *visitor, void *user, walk_ctx_t ctx = { .txn = txn, .userctx = user, .visitor = visitor, .options = options}; - walk_sdb_t sdb = {.name = {.iov_base = MDBX_CHK_GC}, + walk_tbl_t tbl = {.name = {.iov_base = MDBX_CHK_GC}, .internal = &txn->dbs[FREE_DBI]}; - rc = walk_sdb(&ctx, &sdb); + rc = walk_tbl(&ctx, &tbl); if (!MDBX_IS_ERROR(rc)) { - sdb.name.iov_base = MDBX_CHK_MAIN; - sdb.internal = &txn->dbs[MAIN_DBI]; - rc = walk_sdb(&ctx, &sdb); + tbl.name.iov_base = MDBX_CHK_MAIN; + tbl.internal = &txn->dbs[MAIN_DBI]; + rc = walk_tbl(&ctx, &tbl); } return rc; } @@ -40481,9 +40475,9 @@ __dll_export 0, 13, 0, - 110, - {"2024-08-03T00:30:06+03:00", "0a032f804b7a1d447beb7394173f09fde8697a41", "dd0ee3f278552424190f2f0bf1e63779a10dece6", - "v0.13.0-110-gdd0ee3f2"}, + 115, + {"2024-08-03T15:14:23+03:00", "7a23f6614a32db727acc8a29d774445e47d31f3f", "7bff3b3df699ca761c79c7350808fc1fb7f1216d", + "v0.13.0-115-g7bff3b3d"}, sourcery}; __dll_export diff --git a/mdbx/mdbx.h b/mdbx/mdbx.h index aa2989c..07d9ecf 100644 --- a/mdbx/mdbx.h +++ b/mdbx/mdbx.h @@ -68,7 +68,7 @@ credits and acknowledgments. \defgroup c_err Error handling \defgroup c_opening Opening & Closing \defgroup c_transactions Transactions - \defgroup c_dbi Databases + \defgroup c_dbi Tables \defgroup c_crud Create/Read/Update/Delete (see Quick Reference in details) \details @@ -79,9 +79,9 @@ Historically, libmdbx inherits the API basis from LMDB, where it is often difficult to select flags/options and functions for the desired operation. So it is recommend using this hints. -## Databases with UNIQUE keys +## Tables with UNIQUE keys -In databases created without the \ref MDBX_DUPSORT option, keys are always +In tables created without the \ref MDBX_DUPSORT option, keys are always unique. Thus always a single value corresponds to the each key, and so there are only a few cases of changing data. @@ -104,10 +104,10 @@ are only a few cases of changing data. |Extract (read & delete) value by the key |\ref mdbx_replace() with zero flag and parameter `new_data = NULL`|Returning a deleted value| -## Databases with NON-UNIQUE keys +## Tables with NON-UNIQUE keys -In databases created with the \ref MDBX_DUPSORT (Sorted Duplicates) option, keys -may be non unique. Such non-unique keys in a key-value database may be treated +In tables created with the \ref MDBX_DUPSORT (Sorted Duplicates) option, keys +may be non unique. Such non-unique keys in a key-value table may be treated as a duplicates or as like a multiple values corresponds to keys. @@ -713,8 +713,8 @@ void LIBMDBX_API NTAPI mdbx_module_handler(PVOID module, DWORD reason, /* OPACITY STRUCTURES *********************************************************/ /** \brief Opaque structure for a database environment. - * \details An environment supports multiple key-value sub-databases (aka - * key-value spaces or tables), all residing in the same shared-memory map. + * \details An environment supports multiple key-value tables (aka key-value + * maps, spaces or sub-databases), all residing in the same shared-memory map. * \see mdbx_env_create() \see mdbx_env_close() */ #ifndef __cplusplus typedef struct MDBX_env MDBX_env; @@ -724,7 +724,7 @@ struct MDBX_env; /** \brief Opaque structure for a transaction handle. * \ingroup c_transactions - * \details All database operations require a transaction handle. Transactions + * \details All table operations require a transaction handle. Transactions * may be read-only or read-write. * \see mdbx_txn_begin() \see mdbx_txn_commit() \see mdbx_txn_abort() */ #ifndef __cplusplus @@ -733,16 +733,16 @@ typedef struct MDBX_txn MDBX_txn; struct MDBX_txn; #endif -/** \brief A handle for an individual database (key-value spaces) in the +/** \brief A handle for an individual table (key-value spaces) in the * environment. * \ingroup c_dbi - * \details Zero handle is used internally (hidden Garbage Collection subDB). + * \details Zero handle is used internally (hidden Garbage Collection table). * So, any valid DBI-handle great than 0 and less than or equal * \ref MDBX_MAX_DBI. * \see mdbx_dbi_open() \see mdbx_dbi_close() */ typedef uint32_t MDBX_dbi; -/** \brief Opaque structure for navigating through a database +/** \brief Opaque structure for navigating through a table * \ingroup c_cursors * \see mdbx_cursor_create() \see mdbx_cursor_bind() \see mdbx_cursor_close() */ @@ -753,15 +753,15 @@ struct MDBX_cursor; #endif /** \brief Generic structure used for passing keys and data in and out of the - * database. + * table. * \anchor MDBX_val \see mdbx::slice \see mdbx::buffer * - * \details Values returned from the database are valid only until a subsequent + * \details Values returned from the table are valid only until a subsequent * update operation, or the end of the transaction. Do not modify or * free them, they commonly point into the database itself. * * Key sizes must be between 0 and \ref mdbx_env_get_maxkeysize() inclusive. - * The same applies to data sizes in databases with the \ref MDBX_DUPSORT flag. + * The same applies to data sizes in tables with the \ref MDBX_DUPSORT flag. * Other data items can in theory be from 0 to \ref MDBX_MAXDATASIZE bytes long. * * \note The notable difference between MDBX and LMDB is that MDBX support zero @@ -1607,7 +1607,7 @@ typedef enum MDBX_txn_flags { } MDBX_txn_flags_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_txn_flags) -/** \brief Database flags +/** \brief Table flags * \ingroup c_dbi * \anchor db_flags * \see mdbx_dbi_open() */ @@ -1643,15 +1643,15 @@ typedef enum MDBX_db_flags { /** Create DB if not already existing. */ MDBX_CREATE = UINT32_C(0x40000), - /** Opens an existing sub-database created with unknown flags. + /** Opens an existing table created with unknown flags. * - * The `MDBX_DB_ACCEDE` flag is intend to open a existing sub-database which + * The `MDBX_DB_ACCEDE` flag is intend to open a existing table which * was created with unknown flags (\ref MDBX_REVERSEKEY, \ref MDBX_DUPSORT, * \ref MDBX_INTEGERKEY, \ref MDBX_DUPFIXED, \ref MDBX_INTEGERDUP and * \ref MDBX_REVERSEDUP). * * In such cases, instead of returning the \ref MDBX_INCOMPATIBLE error, the - * sub-database will be opened with flags which it was created, and then an + * table will be opened with flags which it was created, and then an * application could determine the actual flags by \ref mdbx_dbi_flags(). */ MDBX_DB_ACCEDE = MDBX_ACCEDE } MDBX_db_flags_t; @@ -1668,7 +1668,7 @@ typedef enum MDBX_put_flags { /** For insertion: Don't write if the key already exists. */ MDBX_NOOVERWRITE = UINT32_C(0x10), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * For upsertion: don't write if the key-value pair already exist. */ MDBX_NODUPDATA = UINT32_C(0x20), @@ -1678,7 +1678,7 @@ typedef enum MDBX_put_flags { * For deletion: remove only single entry at the current cursor position. */ MDBX_CURRENT = UINT32_C(0x40), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * For deletion: remove all multi-values (aka duplicates) for given key. * For upsertion: replace all multi-values for given key with a new one. */ MDBX_ALLDUPS = UINT32_C(0x80), @@ -1691,7 +1691,7 @@ typedef enum MDBX_put_flags { * Don't split full pages, continue on a new instead. */ MDBX_APPEND = UINT32_C(0x20000), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * Duplicate data is being appended. * Don't split full pages, continue on a new instead. */ MDBX_APPENDDUP = UINT32_C(0x40000), @@ -1920,14 +1920,14 @@ typedef enum MDBX_error { * or explicit call of \ref mdbx_env_set_geometry(). */ MDBX_UNABLE_EXTEND_MAPSIZE = -30785, - /** Environment or database is not compatible with the requested operation + /** Environment or table is not compatible with the requested operation * or the specified flags. This can mean: * - The operation expects an \ref MDBX_DUPSORT / \ref MDBX_DUPFIXED - * database. + * table. * - Opening a named DB when the unnamed DB has \ref MDBX_DUPSORT / * \ref MDBX_INTEGERKEY. - * - Accessing a data record as a database, or vice versa. - * - The database was dropped and recreated with different flags. */ + * - Accessing a data record as a named table, or vice versa. + * - The table was dropped and recreated with different flags. */ MDBX_INCOMPATIBLE = -30784, /** Invalid reuse of reader locktable slot, @@ -1939,8 +1939,8 @@ typedef enum MDBX_error { * or is invalid */ MDBX_BAD_TXN = -30782, - /** Invalid size or alignment of key or data for target database, - * either invalid subDB name */ + /** Invalid size or alignment of key or data for target table, + * either invalid table name */ MDBX_BAD_VALSIZE = -30781, /** The specified DBI-handle is invalid @@ -1995,7 +1995,7 @@ typedef enum MDBX_error { /** Alternative/Duplicate LCK-file is exists and should be removed manually */ MDBX_DUPLICATED_CLK = -30413, - /** Some cursors and/or other resources should be closed before subDb or + /** Some cursors and/or other resources should be closed before table or * corresponding DBI-handle could be (re)used */ MDBX_DANGLING_DBI = -30412, @@ -2134,11 +2134,11 @@ LIBMDBX_API int mdbx_env_create(MDBX_env **penv); * \ingroup c_settings * \see mdbx_env_set_option() \see mdbx_env_get_option() */ typedef enum MDBX_option { - /** \brief Controls the maximum number of named databases for the environment. + /** \brief Controls the maximum number of named tables for the environment. * - * \details By default only unnamed key-value database could used and + * \details By default only unnamed key-value table could used and * appropriate value should set by `MDBX_opt_max_db` to using any more named - * subDB(s). To reduce overhead, use the minimum sufficient value. This option + * table(s). To reduce overhead, use the minimum sufficient value. This option * may only set after \ref mdbx_env_create() and before \ref mdbx_env_open(). * * \see mdbx_env_set_maxdbs() \see mdbx_env_get_maxdbs() */ @@ -2587,6 +2587,7 @@ LIBMDBX_API int mdbx_env_delete(const char *pathname, #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_delete() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_delete() */ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathname, @@ -2627,6 +2628,24 @@ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathname, * - \ref MDBX_CP_FORCE_DYNAMIC_SIZE * Force to make resizable copy, i.e. dynamic size instead of fixed. * + * - \ref MDBX_CP_DONT_FLUSH + * Don't explicitly flush the written data to an output media to reduce + * the time of the operation and the duration of the transaction. + * + * - \ref MDBX_CP_THROTTLE_MVCC + * Use read transaction parking during copying MVCC-snapshot + * to avoid stopping recycling and overflowing the database. + * This allows the writing transaction to oust the read + * transaction used to copy the database if copying takes so long + * that it will interfere with the recycling old MVCC snapshots + * and may lead to an overflow of the database. + * However, if the reading transaction is ousted the copy will + * be aborted until successful completion. Thus, this option + * allows copy the database without interfering with write + * transactions and a threat of database overflow, but at the cost + * that copying will be aborted to prevent such conditions. + * \see mdbx_txn_park() + * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest, MDBX_copy_flags_t flags); @@ -2665,18 +2684,38 @@ LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest, * - \ref MDBX_CP_FORCE_DYNAMIC_SIZE * Force to make resizable copy, i.e. dynamic size instead of fixed. * + * - \ref MDBX_CP_DONT_FLUSH + * Don't explicitly flush the written data to an output media to reduce + * the time of the operation and the duration of the transaction. + * + * - \ref MDBX_CP_THROTTLE_MVCC + * Use read transaction parking during copying MVCC-snapshot + * to avoid stopping recycling and overflowing the database. + * This allows the writing transaction to oust the read + * transaction used to copy the database if copying takes so long + * that it will interfere with the recycling old MVCC snapshots + * and may lead to an overflow of the database. + * However, if the reading transaction is ousted the copy will + * be aborted until successful completion. Thus, this option + * allows copy the database without interfering with write + * transactions and a threat of database overflow, but at the cost + * that copying will be aborted to prevent such conditions. + * \see mdbx_txn_park() + * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest, MDBX_copy_flags_t flags); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_copy() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_copy() */ LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest, MDBX_copy_flags_t flags); /** \copydoc mdbx_txn_copy2pathname() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_txn_copy2pathname() */ LIBMDBX_API int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest, @@ -2736,12 +2775,12 @@ LIBMDBX_API int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, LIBMDBX_API int mdbx_txn_copy2fd(MDBX_txn *txn, mdbx_filehandle_t fd, MDBX_copy_flags_t flags); -/** \brief Statistics for a database in the environment +/** \brief Statistics for a table in the environment * \ingroup c_statinfo * \see mdbx_env_stat_ex() \see mdbx_dbi_stat() */ struct MDBX_stat { - uint32_t ms_psize; /**< Size of a database page. This is the same for all - databases. */ + uint32_t ms_psize; /**< Size of a table page. This is the same for all tables + in a database. */ uint32_t ms_depth; /**< Depth (height) of the B-tree */ uint64_t ms_branch_pages; /**< Number of internal (non-leaf) pages */ uint64_t ms_leaf_pages; /**< Number of leaf pages */ @@ -3081,7 +3120,7 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_syncperiod, /** \brief Close the environment and release the memory map. * \ingroup c_opening * - * Only a single thread may call this function. All transactions, databases, + * Only a single thread may call this function. All transactions, tables, * and cursors must already be closed before calling this function. Attempts * to use any such handles after calling this function is UB and would cause * a `SIGSEGV`. The environment handle will be freed and must not be used again @@ -3240,7 +3279,7 @@ typedef enum MDBX_warmup_flags { * On successful, all currently allocated pages, both unused in GC and * containing payload, will be locked in memory until the environment closes, * or explicitly unblocked by using \ref MDBX_warmup_release, or the - * database geomenry will changed, including its auto-shrinking. */ + * database geometry will changed, including its auto-shrinking. */ MDBX_warmup_lock = 4, /** Alters corresponding current resource limits to be enough for lock pages @@ -3256,8 +3295,9 @@ typedef enum MDBX_warmup_flags { } MDBX_warmup_flags_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_warmup_flags) -/** \brief Warms up the database by loading pages into memory, optionally lock - * ones. \ingroup c_settings +/** \brief Warms up the database by loading pages into memory, + * optionally lock ones. + * \ingroup c_settings * * Depending on the specified flags, notifies OS kernel about following access, * force loads the database pages, including locks ones in memory or releases @@ -3342,6 +3382,7 @@ LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_get_path() + * \ingroup c_statinfo * \note Available only on Windows. * \see mdbx_env_get_path() */ LIBMDBX_API int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **dest); @@ -3615,40 +3656,40 @@ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_max(intptr_t pagesize); /** \brief Returns maximal key size in bytes for given page size - * and database flags, or -1 if pagesize is invalid. + * and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags); -/** \brief Returns minimal key size in bytes for given database flags. +/** \brief Returns minimal key size in bytes for given table flags. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_min(MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes for given page size - * and database flags, or -1 if pagesize is invalid. + * and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags); -/** \brief Returns minimal data size in bytes for given database flags. +/** \brief Returns minimal data size in bytes for given table flags. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_min(MDBX_db_flags_t flags); /** \brief Returns maximal size of key-value pair to fit in a single page with - * the given size and database flags, or -1 if pagesize is invalid. + * the given size and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_pairsize4page_max(intptr_t pagesize, MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes to fit in a leaf-page or - * single large/overflow-page with the given page size and database flags, + * single large/overflow-page with the given page size and table flags, * or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ @@ -3711,12 +3752,12 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_maxreaders, return rc; } -/** \brief Set the maximum number of named databases for the environment. +/** \brief Set the maximum number of named tables for the environment. * \ingroup c_settings * - * This function is only needed if multiple databases will be used in the + * This function is only needed if multiple tables will be used in the * environment. Simpler applications that use the environment as a single - * unnamed database can ignore this option. + * unnamed table can ignore this option. * This function may only be called after \ref mdbx_env_create() and before * \ref mdbx_env_open(). * @@ -3726,7 +3767,7 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_maxreaders, * \see mdbx_env_get_maxdbs() * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] dbs The maximum number of databases. + * \param [in] dbs The maximum number of tables. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: @@ -3736,12 +3777,12 @@ LIBMDBX_INLINE_API(int, mdbx_env_set_maxdbs, (MDBX_env * env, MDBX_dbi dbs)) { return mdbx_env_set_option(env, MDBX_opt_max_db, dbs); } -/** \brief Get the maximum number of named databases for the environment. +/** \brief Get the maximum number of named tables for the environment. * \ingroup c_statinfo * \see mdbx_env_set_maxdbs() * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [out] dbs Address to store the maximum number of databases. + * \param [out] dbs Address to store the maximum number of tables. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: @@ -3784,7 +3825,7 @@ LIBMDBX_API int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages, * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a key can write, @@ -3796,7 +3837,7 @@ mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags); * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -3811,11 +3852,11 @@ MDBX_DEPRECATED MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxkeysize(const MDBX_env *env); /** \brief Returns maximal size of key-value pair to fit in a single page - * for specified database flags. + * for specified table flags. * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -3824,11 +3865,11 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_pairsize4page_max(const MDBX_env *env, MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes to fit in a leaf-page or - * single large/overflow-page for specified database flags. + * single large/overflow-page for specified table flags. * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -4113,7 +4154,7 @@ mdbx_txn_id(const MDBX_txn *txn); * \see mdbx_txn_commit_ex() */ struct MDBX_commit_latency { /** \brief Duration of preparation (commit child transactions, update - * sub-databases records and cursors destroying). */ + * table's records and cursors destroying). */ uint32_t preparation; /** \brief Duration of GC update by wall clock. */ uint32_t gc_wallclock; @@ -4495,7 +4536,7 @@ LIBMDBX_API int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary); * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary); -/** \brief A callback function used to compare two keys in a database +/** \brief A callback function used to compare two keys in a table * \ingroup c_crud * \see mdbx_cmp() \see mdbx_get_keycmp() * \see mdbx_get_datacmp \see mdbx_dcmp() @@ -4518,23 +4559,23 @@ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary); typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b) MDBX_CXX17_NOEXCEPT; -/** \brief Open or Create a database in the environment. +/** \brief Open or Create a named table in the environment. * \ingroup c_dbi * - * A database handle denotes the name and parameters of a database, - * independently of whether such a database exists. The database handle may be - * discarded by calling \ref mdbx_dbi_close(). The old database handle is - * returned if the database was already open. The handle may only be closed + * A table handle denotes the name and parameters of a table, + * independently of whether such a table exists. The table handle may be + * discarded by calling \ref mdbx_dbi_close(). The old table handle is + * returned if the table was already open. The handle may only be closed * once. * * \note A notable difference between MDBX and LMDB is that MDBX make handles - * opened for existing databases immediately available for other transactions, + * opened for existing tables immediately available for other transactions, * regardless this transaction will be aborted or reset. The REASON for this is * to avoiding the requirement for multiple opening a same handles in * concurrent read transactions, and tracking of such open but hidden handles * until the completion of read transactions which opened them. * - * Nevertheless, the handle for the NEWLY CREATED database will be invisible + * Nevertheless, the handle for the NEWLY CREATED table will be invisible * for other transactions until the this write transaction is successfully * committed. If the write transaction is aborted the handle will be closed * automatically. After a successful commit the such handle will reside in the @@ -4543,15 +4584,15 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * In contrast to LMDB, the MDBX allow this function to be called from multiple * concurrent transactions or threads in the same process. * - * To use named database (with name != NULL), \ref mdbx_env_set_maxdbs() + * To use named table (with name != NULL), \ref mdbx_env_set_maxdbs() * must be called before opening the environment. Table names are - * keys in the internal unnamed database, and may be read but not written. + * keys in the internal unnamed table, and may be read but not written. * * \param [in] txn transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] name The name of the database to open. If only a single - * database is needed in the environment, + * \param [in] name The name of the table to open. If only a single + * table is needed in the environment, * this value may be NULL. - * \param [in] flags Special options for this database. This parameter must + * \param [in] flags Special options for this table. This parameter must * be bitwise OR'ing together any of the constants * described here: * @@ -4565,12 +4606,12 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * uint64_t, and will be sorted as such. The keys must all be of the * same size and must be aligned while passing as arguments. * - \ref MDBX_DUPSORT - * Duplicate keys may be used in the database. Or, from another point of + * Duplicate keys may be used in the table. Or, from another point of * view, keys may have multiple data items, stored in sorted order. By * default keys must be unique and may have only a single data item. * - \ref MDBX_DUPFIXED * This flag may only be used in combination with \ref MDBX_DUPSORT. This - * option tells the library that the data items for this database are + * option tells the library that the data items for this table are * all the same size, which allows further optimizations in storage and * retrieval. When all data items are the same size, the * \ref MDBX_GET_MULTIPLE, \ref MDBX_NEXT_MULTIPLE and @@ -4585,7 +4626,7 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * strings in reverse order (the comparison is performed in the direction * from the last byte to the first). * - \ref MDBX_CREATE - * Create the named database if it doesn't exist. This option is not + * Create the named table if it doesn't exist. This option is not * allowed in a read-only transaction or a read-only environment. * * \param [out] dbi Address where the new \ref MDBX_dbi handle @@ -4597,61 +4638,66 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: - * \retval MDBX_NOTFOUND The specified database doesn't exist in the + * \retval MDBX_NOTFOUND The specified table doesn't exist in the * environment and \ref MDBX_CREATE was not specified. - * \retval MDBX_DBS_FULL Too many databases have been opened. + * \retval MDBX_DBS_FULL Too many tables have been opened. * \see mdbx_env_set_maxdbs() - * \retval MDBX_INCOMPATIBLE Database is incompatible with given flags, + * \retval MDBX_INCOMPATIBLE Table is incompatible with given flags, * i.e. the passed flags is different with which the - * database was created, or the database was already + * table was created, or the table was already * opened with a different comparison function(s). * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. */ LIBMDBX_API int mdbx_dbi_open(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, MDBX_dbi *dbi); -/** \copydoc mdbx_dbi_open() */ +/** \copydoc mdbx_dbi_open() + * \ingroup c_dbi */ LIBMDBX_API int mdbx_dbi_open2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, MDBX_dbi *dbi); -/** \deprecated Please - * \ref avoid_custom_comparators "avoid using custom comparators" and use - * \ref mdbx_dbi_open() instead. - * +/** \brief Open or Create a named table in the environment + * with using custom comparison functions. * \ingroup c_dbi * + * \deprecated Please \ref avoid_custom_comparators + * "avoid using custom comparators" and use \ref mdbx_dbi_open() instead. + * * \param [in] txn transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] name The name of the database to open. If only a single - * database is needed in the environment, + * \param [in] name The name of the table to open. If only a single + * table is needed in the environment, * this value may be NULL. - * \param [in] flags Special options for this database. - * \param [in] keycmp Optional custom key comparison function for a database. - * \param [in] datacmp Optional custom data comparison function for a database. + * \param [in] flags Special options for this table. + * \param [in] keycmp Optional custom key comparison function for a table. + * \param [in] datacmp Optional custom data comparison function for a table. * \param [out] dbi Address where the new MDBX_dbi handle will be stored. * \returns A non-zero error value on failure and 0 on success. */ MDBX_DEPRECATED LIBMDBX_API int mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, MDBX_dbi *dbi, MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp); -/** \copydoc mdbx_dbi_open_ex() */ +/** \copydoc mdbx_dbi_open_ex() + * \ingroup c_dbi */ MDBX_DEPRECATED LIBMDBX_API int mdbx_dbi_open_ex2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, MDBX_dbi *dbi, MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp); -/** \brief Переименовает таблицу по DBI-дескриптору. +/** \brief Переименовает таблицу по DBI-дескриптору + * * \ingroup c_dbi * - * Переименовывает пользовательскую именованную subDB связанную с передаваемым + * Переименовывает пользовательскую именованную таблицу связанную с передаваемым * DBI-дескриптором. * * \param [in,out] txn Пишущая транзакция запущенная посредством * \ref mdbx_txn_begin(). - * \param [in] dbi Дескриптор таблицы (именованной пользовательской subDB) + * \param [in] dbi Дескриптор таблицы * открытый посредством \ref mdbx_dbi_open(). * * \param [in] name Новое имя для переименования. * * \returns Ненулевое значение кода ошибки, либо 0 при успешном выполнении. */ LIBMDBX_API int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name); -/** \copydoc mdbx_dbi_rename() */ +/** \copydoc mdbx_dbi_rename() + * \ingroup c_dbi */ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *name); @@ -4659,10 +4705,10 @@ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, * пользовательских именованных таблиц. * * \ingroup c_statinfo - * \see mdbx_enumerate_subdb() + * \see mdbx_enumerate_tables() * * \param [in] ctx Указатель на контекст переданный аналогичным - * параметром в \ref mdbx_enumerate_subdb(). + * параметром в \ref mdbx_enumerate_tables(). * \param [in] txn Транзазакция. * \param [in] name Имя таблицы. * \param [in] flags Флаги \ref MDBX_db_flags_t. @@ -4674,7 +4720,7 @@ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, * \returns Ноль при успехе и продолжении перечисления, при возвращении другого * значения оно будет немедленно возвращено вызывающему * без продолжения перечисления. */ -typedef int(MDBX_subdb_enum_func)(void *ctx, const MDBX_txn *txn, +typedef int(MDBX_table_enum_func)(void *ctx, const MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, const struct MDBX_stat *stat, MDBX_dbi dbi) MDBX_CXX17_NOEXCEPT; @@ -4688,19 +4734,19 @@ typedef int(MDBX_subdb_enum_func)(void *ctx, const MDBX_txn *txn, * сразу возвращено в качестве результата. * * \ingroup c_statinfo - * \see MDBX_subdb_enum_func + * \see MDBX_table_enum_func * * \param [in] txn Транзакция запущенная посредством * \ref mdbx_txn_begin(). * \param [in] func Указатель на пользовательскую функцию - * с сигнатурой \ref MDBX_subdb_enum_func, + * с сигнатурой \ref MDBX_table_enum_func, * которая будет вызвана для каждой таблицы. * \param [in] ctx Указатель на некоторый контект, который будет передан * в функцию `func()` как есть. * * \returns Ненулевое значение кода ошибки, либо 0 при успешном выполнении. */ -LIBMDBX_API int mdbx_enumerate_subdb(const MDBX_txn *txn, - MDBX_subdb_enum_func *func, void *ctx); +LIBMDBX_API int mdbx_enumerate_tables(const MDBX_txn *txn, + MDBX_table_enum_func *func, void *ctx); /** \defgroup value2key Value-to-Key functions * \brief Value-to-Key functions to @@ -4760,11 +4806,11 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t mdbx_int64_from_key(const MDBX_val); /** end of value2key @} */ -/** \brief Retrieve statistics for a database. +/** \brief Retrieve statistics for a table. * \ingroup c_statinfo * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] stat The address of an \ref MDBX_stat structure where * the statistics will be copied. * \param [in] bytes The size of \ref MDBX_stat. @@ -4778,11 +4824,11 @@ LIBMDBX_API int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat, size_t bytes); /** \brief Retrieve depth (bitmask) information of nested dupsort (multi-value) - * B+trees for given database. + * B+trees for given table. * \ingroup c_statinfo * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] mask The address of an uint32_t value where the bitmask * will be stored. * @@ -4791,7 +4837,7 @@ LIBMDBX_API int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. * \retval MDBX_EINVAL An invalid parameter was specified. - * \retval MDBX_RESULT_TRUE The dbi isn't a dupsort (multi-value) database. */ + * \retval MDBX_RESULT_TRUE The dbi isn't a dupsort (multi-value) table. */ LIBMDBX_API int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, uint32_t *mask); @@ -4810,13 +4856,13 @@ typedef enum MDBX_dbi_state { } MDBX_dbi_state_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_dbi_state) -/** \brief Retrieve the DB flags and status for a database handle. +/** \brief Retrieve the DB flags and status for a table handle. * \ingroup c_statinfo * \see MDBX_db_flags_t * \see MDBX_dbi_state_t * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] flags Address where the flags will be returned. * \param [out] state Address where the state will be returned. * @@ -4833,10 +4879,10 @@ LIBMDBX_INLINE_API(int, mdbx_dbi_flags, return mdbx_dbi_flags_ex(txn, dbi, flags, &state); } -/** \brief Close a database handle. Normally unnecessary. +/** \brief Close a table handle. Normally unnecessary. * \ingroup c_dbi * - * Closing a database handle is not necessary, but lets \ref mdbx_dbi_open() + * Closing a table handle is not necessary, but lets \ref mdbx_dbi_open() * reuse the handle value. Usually it's better to set a bigger * \ref mdbx_env_set_maxdbs(), unless that value would be large. * @@ -4846,68 +4892,68 @@ LIBMDBX_INLINE_API(int, mdbx_dbi_flags, * (\ref MithrilDB) will solve this issue. * * Handles should only be closed if no other threads are going to reference - * the database handle or one of its cursors any further. Do not close a handle - * if an existing transaction has modified its database. Doing so can cause - * misbehavior from database corruption to errors like \ref MDBX_BAD_DBI + * the table handle or one of its cursors any further. Do not close a handle + * if an existing transaction has modified its table. Doing so can cause + * misbehavior from table corruption to errors like \ref MDBX_BAD_DBI * (since the DB name is gone). * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi); -/** \brief Empty or delete and close a database. +/** \brief Empty or delete and close a table. * \ingroup c_crud * * \see mdbx_dbi_close() \see mdbx_dbi_open() * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] del `false` to empty the DB, `true` to delete it * from the environment and close the DB handle. * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del); -/** \brief Get items from a database. +/** \brief Get items from a table. * \ingroup c_crud * - * This function retrieves key/data pairs from the database. The address + * This function retrieves key/data pairs from the table. The address * and length of the data associated with the specified key are returned * in the structure to which data refers. - * If the database supports duplicate keys (\ref MDBX_DUPSORT) then the + * If the table supports duplicate keys (\ref MDBX_DUPSORT) then the * first data item for the key will be returned. Retrieval of other * items requires the use of \ref mdbx_cursor_get(). * * \note The memory pointed to by the returned values is owned by the - * database. The caller MUST not dispose of the memory, and MUST not modify it + * table. The caller MUST not dispose of the memory, and MUST not modify it * in any way regardless in a read-only nor read-write transactions! - * For case a database opened without the \ref MDBX_WRITEMAP modification - * attempts likely will cause a `SIGSEGV`. However, when a database opened with + * For case a table opened without the \ref MDBX_WRITEMAP modification + * attempts likely will cause a `SIGSEGV`. However, when a table opened with * the \ref MDBX_WRITEMAP or in case values returned inside read-write * transaction are located on a "dirty" (modified and pending to commit) pages, * such modification will silently accepted and likely will lead to DB and/or * data corruption. * - * \note Values returned from the database are valid only until a + * \note Values returned from the table are valid only until a * subsequent update operation, or the end of the transaction. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data); -/** \brief Get items from a database +/** \brief Get items from a table * and optionally number of data items for a given key. * * \ingroup c_crud @@ -4917,30 +4963,30 @@ LIBMDBX_API int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * 1. If values_count is NOT NULL, then returns the count * of multi-values/duplicates for a given key. * 2. Updates BOTH the key and the data for pointing to the actual key-value - * pair inside the database. + * pair inside the table. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in,out] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in,out] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * \param [out] values_count The optional address to return number of values * associated with given key: * = 0 - in case \ref MDBX_NOTFOUND error; - * = 1 - exactly for databases + * = 1 - exactly for tables * WITHOUT \ref MDBX_DUPSORT; - * >= 1 for databases WITH \ref MDBX_DUPSORT. + * >= 1 for tables WITH \ref MDBX_DUPSORT. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, size_t *values_count); -/** \brief Get equal or great item from a database. +/** \brief Get equal or great item from a table. * \ingroup c_crud * * Briefly this function does the same as \ref mdbx_get() with a few @@ -4948,17 +4994,17 @@ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * 1. Return equal or great (due comparison function) key-value * pair, but not only exactly matching with the key. * 2. On success return \ref MDBX_SUCCESS if key found exactly, - * and \ref MDBX_RESULT_TRUE otherwise. Moreover, for databases with + * and \ref MDBX_RESULT_TRUE otherwise. Moreover, for tables with * \ref MDBX_DUPSORT flag the data argument also will be used to match over * multi-value/duplicates, and \ref MDBX_SUCCESS will be returned only when * BOTH the key and the data match exactly. * 3. Updates BOTH the key and the data for pointing to the actual key-value - * pair inside the database. + * pair inside the table. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in,out] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in,out] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * * \returns A non-zero error value on failure and \ref MDBX_RESULT_FALSE @@ -4966,43 +5012,43 @@ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * Some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data); -/** \brief Store items into a database. +/** \brief Store items into a table. * \ingroup c_crud * - * This function stores key/data pairs in the database. The default behavior + * This function stores key/data pairs in the table. The default behavior * is to enter the new key/data pair, replacing any previously existing key * if duplicates are disallowed, or adding a duplicate data item if * duplicates are allowed (see \ref MDBX_DUPSORT). * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to store in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to store in the table. * \param [in,out] data The data to store. * \param [in] flags Special options for this operation. * This parameter must be set to 0 or by bitwise OR'ing * together one or more of the values described here: * - \ref MDBX_NODUPDATA * Enter the new key-value pair only if it does not already appear - * in the database. This flag may only be specified if the database + * in the table. This flag may only be specified if the table * was opened with \ref MDBX_DUPSORT. The function will return - * \ref MDBX_KEYEXIST if the key/data pair already appears in the database. + * \ref MDBX_KEYEXIST if the key/data pair already appears in the table. * * - \ref MDBX_NOOVERWRITE * Enter the new key/data pair only if the key does not already appear - * in the database. The function will return \ref MDBX_KEYEXIST if the key - * already appears in the database, even if the database supports + * in the table. The function will return \ref MDBX_KEYEXIST if the key + * already appears in the table, even if the table supports * duplicates (see \ref MDBX_DUPSORT). The data parameter will be set * to point to the existing item. * * - \ref MDBX_CURRENT * Update an single existing entry, but not add new ones. The function will - * return \ref MDBX_NOTFOUND if the given key not exist in the database. + * return \ref MDBX_NOTFOUND if the given key not exist in the table. * In case multi-values for the given key, with combination of * the \ref MDBX_ALLDUPS will replace all multi-values, * otherwise return the \ref MDBX_EMULTIVAL. @@ -5014,10 +5060,10 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * transaction ends. This saves an extra memcpy if the data is being * generated later. MDBX does nothing else with this memory, the caller * is expected to modify all of the space requested. This flag must not - * be specified if the database was opened with \ref MDBX_DUPSORT. + * be specified if the table was opened with \ref MDBX_DUPSORT. * * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. This option + * Append the given key/data pair to the end of the table. This option * allows fast bulk loading when keys are already known to be in the * correct order. Loading unsorted keys with this flag will cause * a \ref MDBX_EKEYMISMATCH error. @@ -5027,14 +5073,14 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * * - \ref MDBX_MULTIPLE * Store multiple contiguous data elements in a single request. This flag - * may only be specified if the database was opened with + * may only be specified if the table was opened with * \ref MDBX_DUPFIXED. With combination the \ref MDBX_ALLDUPS * will replace all multi-values. * The data argument must be an array of two \ref MDBX_val. The `iov_len` * of the first \ref MDBX_val must be the size of a single data element. * The `iov_base` of the first \ref MDBX_val must point to the beginning * of the array of contiguous data elements which must be properly aligned - * in case of database with \ref MDBX_INTEGERDUP flag. + * in case of table with \ref MDBX_INTEGERDUP flag. * The `iov_len` of the second \ref MDBX_val must be the count of the * number of data elements to store. On return this field will be set to * the count of the number of elements actually written. The `iov_base` of @@ -5046,7 +5092,7 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_KEYEXIST The key/value pair already exists in the database. + * \retval MDBX_KEYEXIST The key/value pair already exists in the table. * \retval MDBX_MAP_FULL The database is full, see \ref mdbx_env_set_mapsize(). * \retval MDBX_TXN_FULL The transaction has too many dirty pages. * \retval MDBX_EACCES An attempt was made to write @@ -5055,7 +5101,7 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, MDBX_put_flags_t flags); -/** \brief Replace items in a database. +/** \brief Replace items in a table. * \ingroup c_crud * * This function allows to update or delete an existing value at the same time @@ -5070,7 +5116,7 @@ LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * field pointed by old_data argument to the appropriate value, without * performing any changes. * - * For databases with non-unique keys (i.e. with \ref MDBX_DUPSORT flag), + * For tables with non-unique keys (i.e. with \ref MDBX_DUPSORT flag), * another use case is also possible, when by old_data argument selects a * specific item from multi-value/duplicates with the same key for deletion or * update. To select this scenario in flags should simultaneously specify @@ -5080,8 +5126,8 @@ LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to store in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to store in the table. * \param [in] new_data The data to store, if NULL then deletion will * be performed. * \param [in,out] old_data The buffer for retrieve previous value as describe @@ -5110,24 +5156,24 @@ LIBMDBX_API int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_preserve_func preserver, void *preserver_context); -/** \brief Delete items from a database. +/** \brief Delete items from a table. * \ingroup c_crud * - * This function removes key/data pairs from the database. + * This function removes key/data pairs from the table. * - * \note The data parameter is NOT ignored regardless the database does + * \note The data parameter is NOT ignored regardless the table does * support sorted duplicate data items or not. If the data parameter * is non-NULL only the matching data item will be deleted. Otherwise, if data * parameter is NULL, any/all value(s) for specified key will be deleted. * * This function will return \ref MDBX_NOTFOUND if the specified key/data - * pair is not in the database. + * pair is not in the table. * * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to delete from the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to delete from the table. * \param [in] data The data to delete. * * \returns A non-zero error value on failure and 0 on success, @@ -5141,7 +5187,7 @@ LIBMDBX_API int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, /** \brief Create a cursor handle but not bind it to transaction nor DBI-handle. * \ingroup c_cursors * - * A cursor cannot be used when its database handle is closed. Nor when its + * A cursor cannot be used when its table handle is closed. Nor when its * transaction has ended, except with \ref mdbx_cursor_bind() and \ref * mdbx_cursor_renew(). Also it can be discarded with \ref mdbx_cursor_close(). * @@ -5192,7 +5238,7 @@ mdbx_cursor_get_userctx(const MDBX_cursor *cursor); * \ref mdbx_cursor_renew() but with specifying an arbitrary DBI-handle. * * A cursor may be associated with a new transaction, and referencing a new or - * the same database handle as it was created with. This may be done whether the + * the same table handle as it was created with. This may be done whether the * previous transaction is live or dead. * * \note In contrast to LMDB, the MDBX required that any opened cursors can be @@ -5202,7 +5248,7 @@ mdbx_cursor_get_userctx(const MDBX_cursor *cursor); * memory corruption and segfaults. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_create(). * * \returns A non-zero error value on failure and 0 on success, @@ -5256,7 +5302,7 @@ LIBMDBX_API int mdbx_cursor_reset(MDBX_cursor *cursor); * Using of the `mdbx_cursor_open()` is equivalent to calling * \ref mdbx_cursor_create() and then \ref mdbx_cursor_bind() functions. * - * A cursor cannot be used when its database handle is closed. Nor when its + * A cursor cannot be used when its table handle is closed. Nor when its * transaction has ended, except with \ref mdbx_cursor_bind() and \ref * mdbx_cursor_renew(). Also it can be discarded with \ref mdbx_cursor_close(). * @@ -5271,7 +5317,7 @@ LIBMDBX_API int mdbx_cursor_reset(MDBX_cursor *cursor); * memory corruption and segfaults. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] cursor Address where the new \ref MDBX_cursor handle will be * stored. * @@ -5353,7 +5399,7 @@ LIBMDBX_API int mdbx_cursor_renew(const MDBX_txn *txn, MDBX_cursor *cursor); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_txn * mdbx_cursor_txn(const MDBX_cursor *cursor); -/** \brief Return the cursor's database handle. +/** \brief Return the cursor's table handle. * \ingroup c_cursors * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */ @@ -5399,7 +5445,7 @@ LIBMDBX_API int mdbx_cursor_compare(const MDBX_cursor *left, /** \brief Retrieve by cursor. * \ingroup c_crud * - * This function retrieves key/data pairs from the database. The address and + * This function retrieves key/data pairs from the table. The address and * length of the key are returned in the object to which key refers (except * for the case of the \ref MDBX_SET option, in which the key object is * unchanged), and the address and length of the data are returned in the object @@ -5488,12 +5534,11 @@ typedef int(MDBX_predicate_func)(void *context, MDBX_val *key, MDBX_val *value, * DSO-трансграничных вызовов. * * Функция принимает курсор, который должен быть привязан к некоторой транзакции - * и DBI-дескриптору таблицы (именованной пользовательской subDB), выполняет - * первоначальное позиционирование курсора определяемое аргументом `start_op`. - * Далее, производится оценка каждой пары ключ-значения посредством - * предоставляемой вами предикативной функции `predicate` и затем, при - * необходимости, переход к следующему элементу посредством операции `turn_op`, - * до наступления одного из четырех событий: + * и DBI-дескриптору таблицы, выполняет первоначальное позиционирование курсора + * определяемое аргументом `start_op`. Далее, производится оценка каждой пары + * ключ-значения посредством предоставляемой вами предикативной функции + * `predicate` и затем, при необходимости, переход к следующему элементу + * посредством операции `turn_op`, до наступления одного из четырех событий: * - достигается конец данных; * - возникнет ошибка при позиционировании курсора; * - оценочная функция вернет \ref MDBX_RESULT_TRUE, сигнализируя @@ -5557,13 +5602,12 @@ LIBMDBX_API int mdbx_cursor_scan(MDBX_cursor *cursor, * \ingroup c_crud * * Функция принимает курсор, который должен быть привязан к некоторой транзакции - * и DBI-дескриптору таблицы (именованной пользовательской subDB), выполняет - * первоначальное позиционирование курсора определяемое аргументом `from_op`. - * а также аргументами `from_key` и `from_value`. - * Далее, производится оценка каждой пары ключ-значения посредством - * предоставляемой вами предикативной функции `predicate` и затем, при - * необходимости, переход к следующему элементу посредством операции `turn_op`, - * до наступления одного из четырех событий: + * и DBI-дескриптору таблицы, выполняет первоначальное позиционирование курсора + * определяемое аргументом `from_op`. а также аргументами `from_key` и + * `from_value`. Далее, производится оценка каждой пары ключ-значения + * посредством предоставляемой вами предикативной функции `predicate` и затем, + * при необходимости, переход к следующему элементу посредством операции + * `turn_op`, до наступления одного из четырех событий: * - достигается конец данных; * - возникнет ошибка при позиционировании курсора; * - оценочная функция вернет \ref MDBX_RESULT_TRUE, сигнализируя @@ -5645,8 +5689,8 @@ LIBMDBX_API int mdbx_cursor_scan_from(MDBX_cursor *cursor, /** \brief Retrieve multiple non-dupsort key/value pairs by cursor. * \ingroup c_crud * - * This function retrieves multiple key/data pairs from the database without - * \ref MDBX_DUPSORT option. For `MDBX_DUPSORT` databases please + * This function retrieves multiple key/data pairs from the table without + * \ref MDBX_DUPSORT option. For `MDBX_DUPSORT` tables please * use \ref MDBX_GET_MULTIPLE and \ref MDBX_NEXT_MULTIPLE. * * The number of key and value items is returned in the `size_t count` @@ -5690,7 +5734,7 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, /** \brief Store by cursor. * \ingroup c_crud * - * This function stores key/data pairs into the database. The cursor is + * This function stores key/data pairs into the table. The cursor is * positioned at the new item, or on failure usually near it. * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). @@ -5711,14 +5755,14 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * * - \ref MDBX_NODUPDATA * Enter the new key-value pair only if it does not already appear in the - * database. This flag may only be specified if the database was opened + * table. This flag may only be specified if the table was opened * with \ref MDBX_DUPSORT. The function will return \ref MDBX_KEYEXIST - * if the key/data pair already appears in the database. + * if the key/data pair already appears in the table. * * - \ref MDBX_NOOVERWRITE * Enter the new key/data pair only if the key does not already appear - * in the database. The function will return \ref MDBX_KEYEXIST if the key - * already appears in the database, even if the database supports + * in the table. The function will return \ref MDBX_KEYEXIST if the key + * already appears in the table, even if the table supports * duplicates (\ref MDBX_DUPSORT). * * - \ref MDBX_RESERVE @@ -5726,11 +5770,11 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * data. Instead, return a pointer to the reserved space, which the * caller can fill in later - before the next update operation or the * transaction ends. This saves an extra memcpy if the data is being - * generated later. This flag must not be specified if the database + * generated later. This flag must not be specified if the table * was opened with \ref MDBX_DUPSORT. * * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. No key + * Append the given key/data pair to the end of the table. No key * comparisons are performed. This option allows fast bulk loading when * keys are already known to be in the correct order. Loading unsorted * keys with this flag will cause a \ref MDBX_KEYEXIST error. @@ -5740,14 +5784,14 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * * - \ref MDBX_MULTIPLE * Store multiple contiguous data elements in a single request. This flag - * may only be specified if the database was opened with + * may only be specified if the table was opened with * \ref MDBX_DUPFIXED. With combination the \ref MDBX_ALLDUPS * will replace all multi-values. * The data argument must be an array of two \ref MDBX_val. The `iov_len` * of the first \ref MDBX_val must be the size of a single data element. * The `iov_base` of the first \ref MDBX_val must point to the beginning * of the array of contiguous data elements which must be properly aligned - * in case of database with \ref MDBX_INTEGERDUP flag. + * in case of table with \ref MDBX_INTEGERDUP flag. * The `iov_len` of the second \ref MDBX_val must be the count of the * number of data elements to store. On return this field will be set to * the count of the number of elements actually written. The `iov_base` of @@ -5786,7 +5830,7 @@ LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, const MDBX_val *key, * - \ref MDBX_ALLDUPS * or \ref MDBX_NODUPDATA (supported for compatibility) * Delete all of the data items for the current key. This flag has effect - * only for database(s) was created with \ref MDBX_DUPSORT. + * only for table(s) was created with \ref MDBX_DUPSORT. * * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" * @@ -5805,7 +5849,7 @@ LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags); /** \brief Return count of duplicates for current key. * \ingroup c_crud * - * This call is valid for all databases, but reasonable only for that support + * This call is valid for all tables, but reasonable only for that support * sorted duplicate data items \ref MDBX_DUPSORT. * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). @@ -5925,7 +5969,7 @@ mdbx_cursor_on_last_dup(const MDBX_cursor *cursor); * Please see notes on accuracy of the result in the details * of \ref c_rqest section. * - * Both cursors must be initialized for the same database and the same + * Both cursors must be initialized for the same table and the same * transaction. * * \param [in] first The first cursor for estimation. @@ -5974,7 +6018,7 @@ LIBMDBX_API int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key, * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] begin_key The key of range beginning or NULL for explicit FIRST. * \param [in] begin_data Optional additional data to seeking among sorted * duplicates. @@ -6033,18 +6077,18 @@ LIBMDBX_API int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr); -/** \brief Sequence generation for a database. +/** \brief Sequence generation for a table. * \ingroup c_crud * * The function allows to create a linear sequence of unique positive integers - * for each database. The function can be called for a read transaction to + * for each table. The function can be called for a read transaction to * retrieve the current sequence value, and the increment must be zero. * Sequence changes become visible outside the current write transaction after * it is committed, and discarded on abort. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] result The optional address where the value of sequence * before the change will be stored. * \param [in] increment Value to increase the sequence, @@ -6057,17 +6101,17 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, uint64_t increment); -/** \brief Compare two keys according to a particular database. +/** \brief Compare two keys according to a particular table. * \ingroup c_crud * \see MDBX_cmp_func * * This returns a comparison as if the two data items were keys in the - * specified database. + * specified table. * * \warning There ss a Undefined behavior if one of arguments is invalid. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] a The first item to compare. * \param [in] b The second item to compare. * @@ -6077,22 +6121,22 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, const MDBX_val *a, const MDBX_val *b); -/** \brief Returns default internal key's comparator for given database flags. +/** \brief Returns default internal key's comparator for given table flags. * \ingroup c_extra */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_keycmp(MDBX_db_flags_t flags); -/** \brief Compare two data items according to a particular database. +/** \brief Compare two data items according to a particular table. * \ingroup c_crud * \see MDBX_cmp_func * * This returns a comparison as if the two items were data items of the - * specified database. + * specified table. * * \warning There ss a Undefined behavior if one of arguments is invalid. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] a The first item to compare. * \param [in] b The second item to compare. * @@ -6102,7 +6146,7 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, const MDBX_val *a, const MDBX_val *b); -/** \brief Returns default internal data's comparator for given database flags +/** \brief Returns default internal data's comparator for given table flags * \ingroup c_extra */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_datacmp(MDBX_db_flags_t flags); @@ -6355,6 +6399,7 @@ LIBMDBX_API int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname, #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_open_for_recovery() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_open_for_recovery() */ LIBMDBX_API int mdbx_env_open_for_recoveryW(MDBX_env *env, @@ -6405,6 +6450,7 @@ LIBMDBX_API int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *info, size_t bytes); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_preopen_snapinfo() + * \ingroup c_opening * \note Available only on Windows. * \see mdbx_preopen_snapinfo() */ LIBMDBX_API int mdbx_preopen_snapinfoW(const wchar_t *pathname, @@ -6467,7 +6513,7 @@ typedef enum MDBX_chk_stage { MDBX_chk_gc, MDBX_chk_space, MDBX_chk_maindb, - MDBX_chk_subdbs, + MDBX_chk_tables, MDBX_chk_conclude, MDBX_chk_unlock, MDBX_chk_finalize @@ -6507,7 +6553,7 @@ typedef struct MDBX_chk_scope { /** \brief Пользовательский тип для привязки дополнительных данных, * связанных с некоторой таблицей ключ-значение, при проверке целостности базы * данных. \see mdbx_env_chk() */ -typedef struct MDBX_chk_user_subdb_cookie MDBX_chk_user_subdb_cookie_t; +typedef struct MDBX_chk_user_table_cookie MDBX_chk_user_table_cookie_t; /** \brief Гистограмма с некоторой статистической информацией, * собираемой при проверке целостности БД. @@ -6522,8 +6568,8 @@ struct MDBX_chk_histogram { /** \brief Информация о некоторой таблицей ключ-значение, * при проверке целостности базы данных. * \see mdbx_env_chk() */ -typedef struct MDBX_chk_subdb { - MDBX_chk_user_subdb_cookie_t *cookie; +typedef struct MDBX_chk_table { + MDBX_chk_user_table_cookie_t *cookie; /** \brief Pseudo-name for MainDB */ #define MDBX_CHK_MAIN ((void *)((ptrdiff_t)0)) @@ -6554,7 +6600,7 @@ typedef struct MDBX_chk_subdb { /// Values length histogram struct MDBX_chk_histogram val_len; } histogram; -} MDBX_chk_subdb_t; +} MDBX_chk_table_t; /** \brief Контекст проверки целостности базы данных. * \see mdbx_env_chk() */ @@ -6566,17 +6612,17 @@ typedef struct MDBX_chk_context { uint8_t scope_nesting; struct { size_t total_payload_bytes; - size_t subdb_total, subdb_processed; + size_t table_total, table_processed; size_t total_unused_bytes, unused_pages; size_t processed_pages, reclaimable_pages, gc_pages, alloc_pages, backed_pages; size_t problems_meta, tree_problems, gc_tree_problems, kv_tree_problems, problems_gc, problems_kv, total_problems; uint64_t steady_txnid, recent_txnid; - /** Указатель на массив размером subdb_total с указателями на экземпляры - * структур MDBX_chk_subdb_t с информацией о всех таблицах ключ-значение, + /** Указатель на массив размером table_total с указателями на экземпляры + * структур MDBX_chk_table_t с информацией о всех таблицах ключ-значение, * включая MainDB и GC/FreeDB. */ - const MDBX_chk_subdb_t *const *subdbs; + const MDBX_chk_table_t *const *tables; } result; } MDBX_chk_context_t; @@ -6606,14 +6652,14 @@ typedef struct MDBX_chk_callbacks { void (*issue)(MDBX_chk_context_t *ctx, const char *object, uint64_t entry_number, const char *issue, const char *extra_fmt, va_list extra_args); - MDBX_chk_user_subdb_cookie_t *(*subdb_filter)(MDBX_chk_context_t *ctx, + MDBX_chk_user_table_cookie_t *(*table_filter)(MDBX_chk_context_t *ctx, const MDBX_val *name, MDBX_db_flags_t flags); - int (*subdb_conclude)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb, + int (*table_conclude)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table, MDBX_cursor *cursor, int err); - void (*subdb_dispose)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb); + void (*table_dispose)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table); - int (*subdb_handle_kv)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb, + int (*table_handle_kv)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table, size_t entry_number, const MDBX_val *key, const MDBX_val *value); diff --git a/mdbxdist/CMakeLists.txt b/mdbxdist/CMakeLists.txt index 0033495..1a378bf 100644 --- a/mdbxdist/CMakeLists.txt +++ b/mdbxdist/CMakeLists.txt @@ -138,7 +138,7 @@ if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/sort.h" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/spill.c" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/spill.h" AND - EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/subdb.c" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/table.c" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tls.c" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tls.h" AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/tools/chk.c" AND @@ -749,7 +749,7 @@ else() "${MDBX_SOURCE_DIR}/sort.h" "${MDBX_SOURCE_DIR}/spill.c" "${MDBX_SOURCE_DIR}/spill.h" - "${MDBX_SOURCE_DIR}/subdb.c" + "${MDBX_SOURCE_DIR}/table.c" "${MDBX_SOURCE_DIR}/tls.c" "${MDBX_SOURCE_DIR}/tls.h" "${MDBX_SOURCE_DIR}/tree.c" diff --git a/mdbxdist/ChangeLog.md b/mdbxdist/ChangeLog.md index 3142f04..aa686f0 100644 --- a/mdbxdist/ChangeLog.md +++ b/mdbxdist/ChangeLog.md @@ -1,7 +1,7 @@ ChangeLog ========= -English version [by Google](https://gitflic-ru.translate.goog/project/erthink/libmdbx/blob?file=ChangeLog.md&_x_tr_sl=ru&_x_tr_tl=en) +English version [by liar Google](https://gitflic-ru.translate.goog/project/erthink/libmdbx/blob?file=ChangeLog.md&_x_tr_sl=ru&_x_tr_tl=en) and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic.ru/project/erthink/libmdbx/blob?file=ChangeLog.md). ## v0.13.1 (в процессе подготовки выпуска) @@ -44,7 +44,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic припаркованных транзакций является как дополнением, так и более простой в использовании альтернативой обратному вызову [Handle-Slow-Readers](https://libmdbx.dqdkfa.ru/group__c__err.html#ga2cb11b56414c282fe06dd942ae6cade6). - Для удобства функции `mdbx_txn_park()` и `mdbx_txn_unpack()` имеют + Для удобства функции `mdbx_txn_park()` и `mdbx_txn_unpark()` имеют дополнительные аргументы, позволяющие запросить автоматическую "распарковку" припаркованных и перезапуск вытесненных транзакций. @@ -75,7 +75,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic - Функция `mdbx_preopen_snapinfo()` для получения информации о БД без её открытия. - - Функция `mdbx_enumerate_subdb()` для получение информации + - Функция `mdbx_enumerate_tables()` для получение информации об именованных пользовательских таблицах. - Поддержка функций логирования обратного вызова без функционала @@ -109,19 +109,19 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic - Расширение и доработка C++ API: - - добавлен тип `mdbx::cursor::estimation_result`, а поведение методов - `cursor::estimate()` унифицировано с `cursor::move()`; + - добавлен тип `mdbx::cursor::estimate_result`, а поведение методов + `mdbx::cursor::estimate()` унифицировано с `mdbx::cursor::move()`; - для предотвращения незаметного неверного использования API, для инициализации - возвращаемых по ссылке срезов, вместо пустых срезов задействован `slice::invalid()`; + возвращаемых по ссылке срезов, вместо пустых срезов задействован `mdbx::slice::invalid()`; - добавлены дополнительные C++ операторы преобразования к типам C API; - для совместимости со старыми стандартами C++ и старыми версиями STL перенесены - в public классы `buffer::move_assign_alloc` и `buffer::copy_assign_alloc`; + в public классы `mdbx::buffer::move_assign_alloc` и `mdbx::buffer::copy_assign_alloc`; - добавлен тип `mdbx::default_buffer`; - - для срезов и буферов добавлены методы `hex_decode()`, `base64_decode()`, `base58_decode()`; + - для срезов и буферов добавлены методы `mdbx::buffer::hex_decode()`, `mdbx::buffer::base64_decode()`, `mdbx::buffer::base58_decode()`; - добавлен тип `mdbx::comparator` и функций `mdbx::default_comparator()`; - - добавлены статические методы `buffer::hex()`, `base64()`, `base58()`; + - добавлены статические методы `mdbx::buffer::hex()`, `mdbx::buffer::base64()`, `mdbx::buffer::base58()`; - для транзакций и курсоров добавлены методы `get_/set_context`; - - добавлен метод `cursor::clone()`; + - добавлен метод `mdbx::cursor::clone()`; - поддержка base58 переработана и приведена в соответствии с черновиком RFC, в текущем понимании теперь это одна из самых высокопроизводительных реализаций base58; - переработка `to_hex()` и `from_hex()`; @@ -131,6 +131,7 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic Нарушение совместимости: + - Использование термина "таблица" вместо "subDb". - Опция `MDBX_COALESCE` объявлена устаревшей, так как соответствующий функционал всегда включен начиная с предыдущей версии 0.12. - Опция `MDBX_NOTLS` объявлена устаревшей и заменена на `MDBX_NOSTICKYTHREADS`. - Опция сборки `MDBX_USE_VALGRIND` заменена на общепринятую `ENABLE_MEMCHECK`. @@ -334,7 +335,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) - Из разрабатываемой версии перенесены не-нарушающие совместимости доработки C++ API: - - добавлен тип `mdbx::cursor::estimation_result`, а поведение методов + - добавлен тип `mdbx::cursor::estimate_result`, а поведение методов `cursor::estimate()` унифицировано с `cursor::move()`; - для предотвращения незаметного неверного использования API, для инициализации возвращаемых по ссылке срезов, вместо пустых срезов задействован `slice::invalid()`; diff --git a/mdbxdist/README.md b/mdbxdist/README.md index 2fc4f51..d82599b 100644 --- a/mdbxdist/README.md +++ b/mdbxdist/README.md @@ -160,7 +160,7 @@ $ cc --version [MVCC](https://en.wikipedia.org/wiki/Multiversion_concurrency_control) and [CoW](https://en.wikipedia.org/wiki/Copy-on-write). -- Multiple key-value sub-databases within a single datafile. +- Multiple key-value tables/sub-databases within a single datafile. - Range lookups, including range query estimation. @@ -204,7 +204,7 @@ transaction journal. No crash recovery needed. No maintenance is required. - **Value size**: minimum `0`, maximum `2146435072` (`0x7FF00000`) bytes for maps, ≈½ pagesize for multimaps (`2022` bytes for default 4K pagesize, `32742` bytes for 64K pagesize). - **Write transaction size**: up to `1327217884` pages (`4.944272` TiB for default 4K pagesize, `79.108351` TiB for 64K pagesize). - **Database size**: up to `2147483648` pages (≈`8.0` TiB for default 4K pagesize, ≈`128.0` TiB for 64K pagesize). -- **Maximum sub-databases**: `32765`. +- **Maximum tables/sub-databases**: `32765`. ## Gotchas @@ -298,7 +298,7 @@ and/or optimize query execution plans. 11. Ability to determine whether the particular data is on a dirty page or not, that allows to avoid copy-out before updates. -12. Extended information of whole-database, sub-databases, transactions, readers enumeration. +12. Extended information of whole-database, tables/sub-databases, transactions, readers enumeration. > _libmdbx_ provides a lot of information, including dirty and leftover pages > for a write transaction, reading lag and holdover space for read transactions. @@ -321,7 +321,7 @@ pair, to the first, to the last, or not set to anything. ## Other fixes and specifics 1. Fixed more than 10 significant errors, in particular: page leaks, -wrong sub-database statistics, segfault in several conditions, +wrong table/sub-database statistics, segfault in several conditions, nonoptimal page merge strategy, updating an existing record with a change in data size (including for multimap), etc. diff --git a/mdbxdist/VERSION.txt b/mdbxdist/VERSION.txt index d96fc0e..cc95191 100644 --- a/mdbxdist/VERSION.txt +++ b/mdbxdist/VERSION.txt @@ -1 +1 @@ -0.13.0.110 +0.13.0.115 diff --git a/mdbxdist/man1/mdbx_chk.1 b/mdbxdist/man1/mdbx_chk.1 index bc438e8..4ff7fc6 100644 --- a/mdbxdist/man1/mdbx_chk.1 +++ b/mdbxdist/man1/mdbx_chk.1 @@ -22,7 +22,7 @@ mdbx_chk \- MDBX checking tool [\c .BR \-i ] [\c -.BI \-s \ subdb\fR] +.BI \-s \ table\fR] .BR \ dbpath .SH DESCRIPTION The @@ -69,8 +69,8 @@ pages. Ignore wrong order errors, which will likely false-positive if custom comparator(s) was used. .TP -.BR \-s \ subdb -Verify and show info only for a specific subdatabase. +.BR \-s \ table +Verify and show info only for a specific table. .TP .BR \-0 | \-1 | \-2 Using specific meta-page 0, or 2 for checking. diff --git a/mdbxdist/man1/mdbx_drop.1 b/mdbxdist/man1/mdbx_drop.1 index 7ae14f9..99f8d37 100644 --- a/mdbxdist/man1/mdbx_drop.1 +++ b/mdbxdist/man1/mdbx_drop.1 @@ -11,7 +11,7 @@ mdbx_drop \- MDBX database delete tool [\c .BR \-d ] [\c -.BI \-s \ subdb\fR] +.BI \-s \ table\fR] [\c .BR \-n ] .BR \ dbpath @@ -28,8 +28,8 @@ Write the library version number to the standard output, and exit. .BR \-d Delete the specified database, don't just empty it. .TP -.BR \-s \ subdb -Operate on a specific subdatabase. If no database is specified, only the main database is dropped. +.BR \-s \ table +Operate on a specific table. If no table is specified, only the main table is dropped. .TP .BR \-n Dump an MDBX database which does not use subdirectories. diff --git a/mdbxdist/man1/mdbx_dump.1 b/mdbxdist/man1/mdbx_dump.1 index 51e6cac..ecd9618 100644 --- a/mdbxdist/man1/mdbx_dump.1 +++ b/mdbxdist/man1/mdbx_dump.1 @@ -19,7 +19,7 @@ mdbx_dump \- MDBX environment export tool .BR \-p ] [\c .BR \-a \ | -.BI \-s \ subdb\fR] +.BI \-s \ table\fR] [\c .BR \-r ] [\c @@ -58,10 +58,10 @@ are considered printing characters, and databases dumped in this manner may be less portable to external systems. .TP .BR \-a -Dump all of the subdatabases in the environment. +Dump all of the tables in the environment. .TP -.BR \-s \ subdb -Dump a specific subdatabase. If no database is specified, only the main database is dumped. +.BR \-s \ table +Dump a specific table. If no database is specified, only the main table is dumped. .TP .BR \-r Rescure mode. Ignore some errors to dump corrupted DB. diff --git a/mdbxdist/man1/mdbx_load.1 b/mdbxdist/man1/mdbx_load.1 index b7fa87f..6c2e16c 100644 --- a/mdbxdist/man1/mdbx_load.1 +++ b/mdbxdist/man1/mdbx_load.1 @@ -16,7 +16,7 @@ mdbx_load \- MDBX environment import tool [\c .BI \-f \ file\fR] [\c -.BI \-s \ subdb\fR] +.BI \-s \ table\fR] [\c .BR \-N ] [\c @@ -71,11 +71,11 @@ on a database that uses custom compare functions. .BR \-f \ file Read from the specified file instead of from the standard input. .TP -.BR \-s \ subdb -Load a specific subdatabase. If no database is specified, data is loaded into the main database. +.BR \-s \ table +Load a specific table. If no table is specified, data is loaded into the main table. .TP .BR \-N -Don't overwrite existing records when loading into an already existing database; just skip them. +Don't overwrite existing records when loading into an already existing table; just skip them. .TP .BR \-T Load data from simple text files. The input must be paired lines of text, where the first diff --git a/mdbxdist/man1/mdbx_stat.1 b/mdbxdist/man1/mdbx_stat.1 index 997bdae..2b87f20 100644 --- a/mdbxdist/man1/mdbx_stat.1 +++ b/mdbxdist/man1/mdbx_stat.1 @@ -21,7 +21,7 @@ mdbx_stat \- MDBX environment status tool .BR \-r [ r ]] [\c .BR \-a \ | -.BI \-s \ subdb\fR] +.BI \-s \ table\fR] .BR \ dbpath [\c .BR \-n ] @@ -61,10 +61,10 @@ table and clear them. The reader table will be printed again after the check is performed. .TP .BR \-a -Display the status of all of the subdatabases in the environment. +Display the status of all of the tables in the environment. .TP -.BR \-s \ subdb -Display the status of a specific subdatabase. +.BR \-s \ table +Display the status of a specific table. .TP .BR \-n Display the status of an MDBX database which does not use subdirectories. diff --git a/mdbxdist/mdbx.c b/mdbxdist/mdbx.c index 3d18d3a..5be12b8 100644 --- a/mdbxdist/mdbx.c +++ b/mdbxdist/mdbx.c @@ -3,7 +3,7 @@ #define xMDBX_ALLOY 1 /* alloyed build */ -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2520,11 +2520,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2555,10 +2555,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2587,9 +2587,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3922,16 +3922,16 @@ MDBX_INTERNAL int __must_check_result env_page_auxbuffer(MDBX_env *env); MDBX_INTERNAL unsigned env_setup_pagesize(MDBX_env *env, const size_t pagesize); /* tree.c */ -MDBX_INTERNAL int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs); +MDBX_INTERNAL int tree_drop(MDBX_cursor *mc, const bool may_have_tables); MDBX_INTERNAL int __must_check_result tree_rebalance(MDBX_cursor *mc); MDBX_INTERNAL int __must_check_result tree_propagate_key(MDBX_cursor *mc, const MDBX_val *key); MDBX_INTERNAL void recalculate_merge_thresholds(MDBX_env *env); MDBX_INTERNAL void recalculate_subpage_thresholds(MDBX_env *env); -/* subdb.c */ -MDBX_INTERNAL int __must_check_result sdb_fetch(MDBX_txn *txn, size_t dbi); -MDBX_INTERNAL int __must_check_result sdb_setup(const MDBX_env *env, +/* table.c */ +MDBX_INTERNAL int __must_check_result tbl_fetch(MDBX_txn *txn, size_t dbi); +MDBX_INTERNAL int __must_check_result tbl_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db); @@ -4392,7 +4392,7 @@ typedef struct clc { size_t lmin, lmax; /* min/max length constraints */ } clc_t; -/* Вспомогательная информация о subDB. +/* Вспомогательная информация о table. * * Совокупность потребностей: * 1. Для транзакций и основного курсора нужны все поля. @@ -4432,7 +4432,7 @@ typedef struct clc2 { struct kvx { clc2_t clc; - MDBX_val name; /* имя subDB */ + MDBX_val name; /* имя table */ }; /* Non-shared DBI state flags inside transaction */ @@ -4874,7 +4874,7 @@ MDBX_MAYBE_UNUSED static void static_checks(void) { /* valid flags for mdbx_node_add() */ -#define NODE_ADD_FLAGS (N_DUPDATA | N_SUBDATA | MDBX_RESERVE | MDBX_APPEND) +#define NODE_ADD_FLAGS (N_DUP | N_TREE | MDBX_RESERVE | MDBX_APPEND) /* Get the page number pointed to by a branch node */ MDBX_NOTHROW_PURE_FUNCTION static inline pgno_t @@ -4949,7 +4949,7 @@ node_size(const MDBX_val *key, const MDBX_val *value) { MDBX_NOTHROW_PURE_FUNCTION static inline pgno_t node_largedata_pgno(const node_t *const __restrict node) { - assert(node_flags(node) & N_BIGDATA); + assert(node_flags(node) & N_BIG); return peek_pgno(node_data(node)); } @@ -4964,7 +4964,7 @@ static inline int __must_check_result node_read(MDBX_cursor *mc, const page_t *mp) { data->iov_len = node_ds(node); data->iov_base = node_data(node); - if (likely(node_flags(node) != N_BIGDATA)) + if (likely(node_flags(node) != N_BIG)) return MDBX_SUCCESS; return node_read_bigdata(mc, node, data, mp); } @@ -5162,10 +5162,10 @@ MDBX_MAYBE_UNUSED MDBX_INTERNAL bool pv2pages_verify(void); * LEAF_NODE_MAX = even_floor(PAGESPACE / 2 - sizeof(indx_t)); * DATALEN_NO_OVERFLOW = LEAF_NODE_MAX - NODESIZE - KEYLEN_MAX; * - * - SubDatabase-node must fit into one leaf-page: - * SUBDB_NAME_MAX = LEAF_NODE_MAX - node_hdr_len - sizeof(tree_t); + * - Table-node must fit into one leaf-page: + * TABLE_NAME_MAX = LEAF_NODE_MAX - node_hdr_len - sizeof(tree_t); * - * - Dupsort values itself are a keys in a dupsort-subdb and couldn't be longer + * - Dupsort values itself are a keys in a dupsort-table and couldn't be longer * than the KEYLEN_MAX. But dupsort node must not great than LEAF_NODE_MAX, * since dupsort value couldn't be placed on a large/overflow page: * DUPSORT_DATALEN_MAX = min(KEYLEN_MAX, @@ -5330,7 +5330,7 @@ flags_db2sub(uint16_t db_flags) { return sub_flags; } -static inline bool check_sdb_flags(unsigned flags) { +static inline bool check_table_flags(unsigned flags) { switch (flags & ~(MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { default: NOTICE("invalid db-flags 0x%x", flags); @@ -6073,7 +6073,7 @@ MDBX_MAYBE_UNUSED static inline void cursor_inner_refresh(const MDBX_cursor *mc, const page_t *mp, unsigned ki) { cASSERT(mc, is_leaf(mp)); const node_t *node = page_node(mp, ki); - if ((node_flags(node) & (N_DUPDATA | N_SUBDATA)) == N_DUPDATA) + if ((node_flags(node) & (N_DUP | N_TREE)) == N_DUP) mc->subcur->cursor.pg[0] = node_data(node); } @@ -6844,13 +6844,13 @@ static inline void thread_key_delete(osal_thread_key_t key) { -typedef struct walk_sdb { +typedef struct walk_tbl { MDBX_val name; tree_t *internal, *nested; -} walk_sdb_t; +} walk_tbl_t; typedef int walk_func(const size_t pgno, const unsigned number, void *const ctx, - const int deep, const walk_sdb_t *subdb, + 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, @@ -7631,12 +7631,12 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r, if (is_pointed(&l->subcur->cursor)) { const page_t *mp = l->pg[l->top]; const node_t *node = page_node(mp, l->ki[l->top]); - assert(node_flags(node) & N_DUPDATA); + assert(node_flags(node) & N_DUP); } if (is_pointed(&r->subcur->cursor)) { const page_t *mp = r->pg[r->top]; const node_t *node = page_node(mp, r->ki[r->top]); - assert(node_flags(node) & N_DUPDATA); + assert(node_flags(node) & N_DUP); } #endif /* MDBX_DEBUG */ @@ -7680,7 +7680,7 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) { if (!inner_hollow(mc)) { const page_t *mp = mc->pg[mc->top]; const node_t *node = page_node(mp, mc->ki[mc->top]); - cASSERT(mc, node_flags(node) & N_DUPDATA); + cASSERT(mc, node_flags(node) & N_DUP); *countp = unlikely(mc->subcur->nested_tree.items > PTRDIFF_MAX) ? PTRDIFF_MAX : (size_t)mc->subcur->nested_tree.items; @@ -7937,7 +7937,7 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs, return MDBX_BAD_DBI; if (unlikely(mc->subcur)) - return MDBX_INCOMPATIBLE /* must be a non-dupsort subDB */; + return MDBX_INCOMPATIBLE /* must be a non-dupsort table */; switch (op) { case MDBX_NEXT: @@ -9941,16 +9941,16 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, const tree_t *db = node_data(node); const unsigned flags = node_flags(node); switch (flags) { - case N_BIGDATA: + case N_BIG: case 0: /* single-value entry, deep = 0 */ *mask |= 1 << 0; break; - case N_DUPDATA: + case N_DUP: /* single sub-page, deep = 1 */ *mask |= 1 << 1; break; - case N_DUPDATA | N_SUBDATA: + case N_DUP | N_TREE: /* sub-tree */ *mask |= 1 << UNALIGNED_PEEK_16(db, tree_t, height); break; @@ -10210,7 +10210,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, /* LY: allows update (explicit overwrite) only for unique keys */ node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { tASSERT(txn, inner_pointed(&cx.outer) && cx.outer.subcur->nested_tree.items > 1); rc = MDBX_EMULTIVAL; @@ -10323,7 +10323,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, if (flags & MDBX_CURRENT) { /* disallow update/delete for multi-values */ node_t *node = page_node(page, cx.outer.ki[cx.outer.top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { tASSERT(txn, inner_pointed(&cx.outer) && cx.outer.subcur->nested_tree.items > 1); if (cx.outer.subcur->nested_tree.items > 1) { @@ -10466,7 +10466,7 @@ __cold static int audit_ex_locked(MDBX_txn *txn, size_t retired_stored, ctx.used = NUM_METAS + audit_db_used(dbi_dig(txn, FREE_DBI, nullptr)) + audit_db_used(dbi_dig(txn, MAIN_DBI, nullptr)); - rc = mdbx_enumerate_subdb(txn, audit_dbi, &ctx); + rc = mdbx_enumerate_tables(txn, audit_dbi, &ctx); tASSERT(txn, rc == MDBX_SUCCESS); for (size_t dbi = CORE_DBS; dbi < txn->n_dbi; ++dbi) { @@ -10525,12 +10525,12 @@ typedef struct MDBX_chk_internal { bool write_locked; uint8_t scope_depth; - MDBX_chk_subdb_t subdb_gc, subdb_main; + MDBX_chk_table_t table_gc, table_main; int16_t *pagemap; - MDBX_chk_subdb_t *last_lookup; + MDBX_chk_table_t *last_lookup; const void *last_nested; MDBX_chk_scope_t scope_stack[12]; - MDBX_chk_subdb_t *subdb[MDBX_MAX_DBI + CORE_DBS]; + MDBX_chk_table_t *table[MDBX_MAX_DBI + CORE_DBS]; MDBX_envinfo envinfo; troika_t troika; @@ -10996,18 +10996,18 @@ __cold static const char *chk_v2a(MDBX_chk_internal_t *chk, } __cold static void chk_dispose(MDBX_chk_internal_t *chk) { - assert(chk->subdb[FREE_DBI] == &chk->subdb_gc); - assert(chk->subdb[MAIN_DBI] == &chk->subdb_main); - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb); ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; - if (sdb) { - chk->subdb[i] = nullptr; - if (chk->cb->subdb_dispose && sdb->cookie) { - chk->cb->subdb_dispose(chk->usr, sdb); - sdb->cookie = nullptr; + assert(chk->table[FREE_DBI] == &chk->table_gc); + assert(chk->table[MAIN_DBI] == &chk->table_main); + for (size_t i = 0; i < ARRAY_LENGTH(chk->table); ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; + if (tbl) { + chk->table[i] = nullptr; + if (chk->cb->table_dispose && tbl->cookie) { + chk->cb->table_dispose(chk->usr, tbl); + tbl->cookie = nullptr; } - if (sdb != &chk->subdb_gc && sdb != &chk->subdb_main) { - osal_free(sdb); + if (tbl != &chk->table_gc && tbl != &chk->table_main) { + osal_free(tbl); } } } @@ -11150,8 +11150,8 @@ histogram_print(MDBX_chk_scope_t *scope, MDBX_chk_line_t *line, //----------------------------------------------------------------------------- -__cold static int chk_get_sdb(MDBX_chk_scope_t *const scope, - const walk_sdb_t *in, MDBX_chk_subdb_t **out) { +__cold static int chk_get_tbl(MDBX_chk_scope_t *const scope, + const walk_tbl_t *in, MDBX_chk_table_t **out) { MDBX_chk_internal_t *const chk = scope->internal; if (chk->last_lookup && chk->last_lookup->name.iov_base == in->name.iov_base) { @@ -11159,33 +11159,33 @@ __cold static int chk_get_sdb(MDBX_chk_scope_t *const scope, return MDBX_SUCCESS; } - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb); ++i) { - MDBX_chk_subdb_t *sdb = chk->subdb[i]; - if (!sdb) { - sdb = osal_calloc(1, sizeof(MDBX_chk_subdb_t)); - if (unlikely(!sdb)) { + for (size_t i = 0; i < ARRAY_LENGTH(chk->table); ++i) { + MDBX_chk_table_t *tbl = chk->table[i]; + if (!tbl) { + tbl = osal_calloc(1, sizeof(MDBX_chk_table_t)); + if (unlikely(!tbl)) { *out = nullptr; - return chk_error_rc(scope, MDBX_ENOMEM, "alloc_subDB"); - } - chk->subdb[i] = sdb; - sdb->flags = in->internal->flags; - sdb->id = -1; - sdb->name = in->name; - } - if (sdb->name.iov_base == in->name.iov_base) { - if (sdb->id < 0) { - sdb->id = (int)i; - sdb->cookie = - chk->cb->subdb_filter - ? chk->cb->subdb_filter(chk->usr, &sdb->name, sdb->flags) + return chk_error_rc(scope, MDBX_ENOMEM, "alloc_table"); + } + chk->table[i] = tbl; + tbl->flags = in->internal->flags; + tbl->id = -1; + tbl->name = in->name; + } + if (tbl->name.iov_base == in->name.iov_base) { + if (tbl->id < 0) { + tbl->id = (int)i; + tbl->cookie = + chk->cb->table_filter + ? chk->cb->table_filter(chk->usr, &tbl->name, tbl->flags) : (void *)(intptr_t)-1; } - *out = (chk->last_lookup = sdb); + *out = (chk->last_lookup = tbl); return MDBX_SUCCESS; } } - chk_scope_issue(scope, "too many subDBs > %u", - (unsigned)ARRAY_LENGTH(chk->subdb) - CORE_DBS - /* meta */ 1); + chk_scope_issue(scope, "too many tables > %u", + (unsigned)ARRAY_LENGTH(chk->table) - CORE_DBS - /* meta */ 1); *out = nullptr; return MDBX_PROBLEM; } @@ -11252,7 +11252,7 @@ __cold static void chk_verbose_meta(MDBX_chk_scope_t *const scope, __cold static int chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, - const int deep, const walk_sdb_t *sdb_info, + 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, @@ -11262,8 +11262,8 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, MDBX_chk_context_t *const usr = chk->usr; MDBX_env *const env = usr->env; - MDBX_chk_subdb_t *sdb; - int err = chk_get_sdb(scope, sdb_info, &sdb); + MDBX_chk_table_t *tbl; + int err = chk_get_tbl(scope, tbl_info, &tbl); if (unlikely(err)) return err; @@ -11271,21 +11271,21 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, chk_scope_issue(scope, "too deeply %u", deep); return MDBX_CORRUPTED /* avoid infinite loop/recursion */; } - histogram_acc(deep, &sdb->histogram.deep); + histogram_acc(deep, &tbl->histogram.deep); usr->result.processed_pages += npages; const size_t page_bytes = payload_bytes + header_bytes + unused_bytes; int height = deep + 1; - if (sdb->id >= CORE_DBS) + if (tbl->id >= CORE_DBS) height -= usr->txn->dbs[MAIN_DBI].height; - const tree_t *nested = sdb_info->nested; + const tree_t *nested = tbl_info->nested; if (nested) { - if (sdb->flags & MDBX_DUPSORT) - height -= sdb_info->internal->height; + if (tbl->flags & MDBX_DUPSORT) + height -= tbl_info->internal->height; else { chk_object_issue(scope, "nested tree", pgno, "unexpected", - "subDb %s flags 0x%x, deep %i", chk_v2a(chk, &sdb->name), - sdb->flags, deep); + "table %s flags 0x%x, deep %i", chk_v2a(chk, &tbl->name), + tbl->flags, deep); nested = nullptr; } } else @@ -11298,82 +11298,82 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, chk_object_issue(scope, "page", pgno, "unknown page-type", "type %u, deep %i", (unsigned)pagetype, deep); pagetype_caption = "unknown"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_broken: assert(page_err != MDBX_SUCCESS); pagetype_caption = "broken"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_sub_broken: assert(page_err != MDBX_SUCCESS); pagetype_caption = "broken-subpage"; - sdb->pages.other += npages; + tbl->pages.other += npages; break; case page_large: pagetype_caption = "large"; - histogram_acc(npages, &sdb->histogram.large_pages); - if (sdb->flags & MDBX_DUPSORT) + histogram_acc(npages, &tbl->histogram.large_pages); + if (tbl->flags & MDBX_DUPSORT) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); break; case page_branch: branch = true; if (!nested) { pagetype_caption = "branch"; - sdb->pages.branch += 1; + tbl->pages.branch += 1; } else { pagetype_caption = "nested-branch"; - sdb->pages.nested_branch += 1; + tbl->pages.nested_branch += 1; } break; case page_dupfix_leaf: if (!nested) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); /* fall through */ __fallthrough; case page_leaf: if (!nested) { pagetype_caption = "leaf"; - sdb->pages.leaf += 1; - if (height != sdb_info->internal->height) + tbl->pages.leaf += 1; + if (height != tbl_info->internal->height) chk_object_issue(scope, "page", pgno, "wrong tree height", - "actual %i != %i subDb %s", height, - sdb_info->internal->height, chk_v2a(chk, &sdb->name)); + "actual %i != %i table %s", height, + tbl_info->internal->height, chk_v2a(chk, &tbl->name)); } else { pagetype_caption = (pagetype == page_leaf) ? "nested-leaf" : "nested-leaf-dupfix"; - sdb->pages.nested_leaf += 1; + tbl->pages.nested_leaf += 1; if (chk->last_nested != nested) { - histogram_acc(height, &sdb->histogram.nested_tree); + histogram_acc(height, &tbl->histogram.nested_tree); chk->last_nested = nested; } if (height != nested->height) chk_object_issue(scope, "page", pgno, "wrong nested-tree height", "actual %i != %i dupsort-node %s", height, - nested->height, chk_v2a(chk, &sdb->name)); + nested->height, chk_v2a(chk, &tbl->name)); } break; case page_sub_dupfix_leaf: case page_sub_leaf: pagetype_caption = (pagetype == page_sub_leaf) ? "subleaf-dupsort" : "subleaf-dupfix"; - sdb->pages.nested_subleaf += 1; - if ((sdb->flags & MDBX_DUPSORT) == 0 || nested) + tbl->pages.nested_subleaf += 1; + if ((tbl->flags & MDBX_DUPSORT) == 0 || nested) chk_object_issue(scope, "page", pgno, "unexpected", - "type %u, subDb %s flags 0x%x, deep %i", - (unsigned)pagetype, chk_v2a(chk, &sdb->name), sdb->flags, + "type %u, table %s flags 0x%x, deep %i", + (unsigned)pagetype, chk_v2a(chk, &tbl->name), tbl->flags, deep); break; } if (npages) { - if (sdb->cookie) { + if (tbl->cookie) { MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_extra); if (npages == 1) chk_print(line, "%s-page %" PRIuSIZE, pagetype_caption, pgno); @@ -11384,7 +11384,7 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, " of %s: header %" PRIiPTR ", %s %" PRIiPTR ", payload %" PRIiPTR ", unused %" PRIiPTR ", deep %i", - chk_v2a(chk, &sdb->name), header_bytes, + chk_v2a(chk, &tbl->name), header_bytes, (pagetype == page_branch) ? "keys" : "entries", nentries, payload_bytes, unused_bytes, deep)); } @@ -11397,18 +11397,18 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, "%s-page: %" PRIuSIZE " > %" PRIuSIZE ", deep %i", pagetype_caption, spanpgno, usr->result.alloc_pages, deep); - sdb->pages.all += 1; + tbl->pages.all += 1; } else if (chk->pagemap[spanpgno]) { - const MDBX_chk_subdb_t *const rival = - chk->subdb[chk->pagemap[spanpgno] - 1]; + const MDBX_chk_table_t *const rival = + chk->table[chk->pagemap[spanpgno] - 1]; chk_object_issue(scope, "page", spanpgno, - (branch && rival == sdb) ? "loop" : "already used", + (branch && rival == tbl) ? "loop" : "already used", "%s-page: by %s, deep %i", pagetype_caption, chk_v2a(chk, &rival->name), deep); already_used = true; } else { - chk->pagemap[spanpgno] = (int16_t)sdb->id + 1; - sdb->pages.all += 1; + chk->pagemap[spanpgno] = (int16_t)tbl->id + 1; + tbl->pages.all += 1; } } @@ -11438,7 +11438,7 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, "%s-page: payload %" PRIuSIZE " bytes, %" PRIuSIZE " entries, deep %i", pagetype_caption, payload_bytes, nentries, deep); - sdb->pages.empty += 1; + tbl->pages.empty += 1; } if (npages) { @@ -11449,9 +11449,9 @@ chk_pgvisitor(const size_t pgno, const unsigned npages, void *const ctx, pagetype_caption, page_size, page_bytes, header_bytes, payload_bytes, unused_bytes, deep); if (page_size > page_bytes) - sdb->lost_bytes += page_size - page_bytes; + tbl->lost_bytes += page_size - page_bytes; } else { - sdb->payload_bytes += payload_bytes + header_bytes; + tbl->payload_bytes += payload_bytes + header_bytes; usr->result.total_payload_bytes += payload_bytes + header_bytes; } } @@ -11489,21 +11489,21 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { if (!chk->pagemap[n]) usr->result.unused_pages += 1; - MDBX_chk_subdb_t total; + MDBX_chk_table_t total; memset(&total, 0, sizeof(total)); total.pages.all = NUM_METAS; - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb) && chk->subdb[i]; ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; - total.payload_bytes += sdb->payload_bytes; - total.lost_bytes += sdb->lost_bytes; - total.pages.all += sdb->pages.all; - total.pages.empty += sdb->pages.empty; - total.pages.other += sdb->pages.other; - total.pages.branch += sdb->pages.branch; - total.pages.leaf += sdb->pages.leaf; - total.pages.nested_branch += sdb->pages.nested_branch; - total.pages.nested_leaf += sdb->pages.nested_leaf; - total.pages.nested_subleaf += sdb->pages.nested_subleaf; + for (size_t i = 0; i < ARRAY_LENGTH(chk->table) && chk->table[i]; ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; + total.payload_bytes += tbl->payload_bytes; + total.lost_bytes += tbl->lost_bytes; + total.pages.all += tbl->pages.all; + total.pages.empty += tbl->pages.empty; + total.pages.other += tbl->pages.other; + total.pages.branch += tbl->pages.branch; + total.pages.leaf += tbl->pages.leaf; + total.pages.nested_branch += tbl->pages.nested_branch; + total.pages.nested_leaf += tbl->pages.nested_leaf; + total.pages.nested_subleaf += tbl->pages.nested_subleaf; } assert(total.pages.all == usr->result.processed_pages); @@ -11518,70 +11518,70 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { err = chk_scope_restore(scope, err); if (scope->verbosity > MDBX_chk_info) { - for (size_t i = 0; i < ARRAY_LENGTH(chk->subdb) && chk->subdb[i]; ++i) { - MDBX_chk_subdb_t *const sdb = chk->subdb[i]; + for (size_t i = 0; i < ARRAY_LENGTH(chk->table) && chk->table[i]; ++i) { + MDBX_chk_table_t *const tbl = chk->table[i]; MDBX_chk_scope_t *inner = - chk_scope_push(scope, 0, "tree %s:", chk_v2a(chk, &sdb->name)); - if (sdb->pages.all == 0) + chk_scope_push(scope, 0, "tree %s:", chk_v2a(chk, &tbl->name)); + if (tbl->pages.all == 0) chk_line_end( chk_print(chk_line_begin(inner, MDBX_chk_resolution), "empty")); else { MDBX_chk_line_t *line = chk_line_begin(inner, MDBX_chk_info); if (line) { line = chk_print(line, "page usage: subtotal %" PRIuSIZE, - sdb->pages.all); + tbl->pages.all); const size_t branch_pages = - sdb->pages.branch + sdb->pages.nested_branch; - const size_t leaf_pages = sdb->pages.leaf + sdb->pages.nested_leaf + - sdb->pages.nested_subleaf; - if (sdb->pages.other) - line = chk_print(line, ", other %" PRIuSIZE, sdb->pages.other); - if (sdb->pages.other == 0 || - (branch_pages | leaf_pages | sdb->histogram.large_pages.count) != + tbl->pages.branch + tbl->pages.nested_branch; + const size_t leaf_pages = tbl->pages.leaf + tbl->pages.nested_leaf + + tbl->pages.nested_subleaf; + if (tbl->pages.other) + line = chk_print(line, ", other %" PRIuSIZE, tbl->pages.other); + if (tbl->pages.other == 0 || + (branch_pages | leaf_pages | tbl->histogram.large_pages.count) != 0) { line = chk_print(line, ", branch %" PRIuSIZE ", leaf %" PRIuSIZE, branch_pages, leaf_pages); - if (sdb->histogram.large_pages.count || - (sdb->flags & MDBX_DUPSORT) == 0) { + if (tbl->histogram.large_pages.count || + (tbl->flags & MDBX_DUPSORT) == 0) { line = chk_print(line, ", large %" PRIuSIZE, - sdb->histogram.large_pages.count); - if (sdb->histogram.large_pages.amount | - sdb->histogram.large_pages.count) - line = histogram_print(inner, line, &sdb->histogram.large_pages, + tbl->histogram.large_pages.count); + if (tbl->histogram.large_pages.amount | + tbl->histogram.large_pages.count) + line = histogram_print(inner, line, &tbl->histogram.large_pages, " amount", "single", true); } } - line = histogram_dist(chk_line_feed(line), &sdb->histogram.deep, + line = histogram_dist(chk_line_feed(line), &tbl->histogram.deep, "tree deep density", "1", false); - if (sdb != &chk->subdb_gc && sdb->histogram.nested_tree.count) { + if (tbl != &chk->table_gc && tbl->histogram.nested_tree.count) { line = chk_print(chk_line_feed(line), "nested tree(s) %" PRIuSIZE, - sdb->histogram.nested_tree.count); - line = histogram_dist(line, &sdb->histogram.nested_tree, " density", + tbl->histogram.nested_tree.count); + line = histogram_dist(line, &tbl->histogram.nested_tree, " density", "1", false); line = chk_print(chk_line_feed(line), "nested tree(s) pages %" PRIuSIZE ": branch %" PRIuSIZE ", leaf %" PRIuSIZE ", subleaf %" PRIuSIZE, - sdb->pages.nested_branch + sdb->pages.nested_leaf, - sdb->pages.nested_branch, sdb->pages.nested_leaf, - sdb->pages.nested_subleaf); + tbl->pages.nested_branch + tbl->pages.nested_leaf, + tbl->pages.nested_branch, tbl->pages.nested_leaf, + tbl->pages.nested_subleaf); } - const size_t bytes = pgno2bytes(env, sdb->pages.all); + const size_t bytes = pgno2bytes(env, tbl->pages.all); line = chk_print( chk_line_feed(line), "page filling: subtotal %" PRIuSIZE " bytes (%.1f%%), payload %" PRIuSIZE " (%.1f%%), unused %" PRIuSIZE " (%.1f%%)", - bytes, bytes * 100.0 / total_page_bytes, sdb->payload_bytes, - sdb->payload_bytes * 100.0 / bytes, bytes - sdb->payload_bytes, - (bytes - sdb->payload_bytes) * 100.0 / bytes); - if (sdb->pages.empty) + bytes, bytes * 100.0 / total_page_bytes, tbl->payload_bytes, + tbl->payload_bytes * 100.0 / bytes, bytes - tbl->payload_bytes, + (bytes - tbl->payload_bytes) * 100.0 / bytes); + if (tbl->pages.empty) line = chk_print(line, ", %" PRIuSIZE " empty pages", - sdb->pages.empty); - if (sdb->lost_bytes) + tbl->pages.empty); + if (tbl->lost_bytes) line = - chk_print(line, ", %" PRIuSIZE " bytes lost", sdb->lost_bytes); + chk_print(line, ", %" PRIuSIZE " bytes lost", tbl->lost_bytes); chk_line_end(line); } } @@ -11609,23 +11609,23 @@ __cold static int chk_tree(MDBX_chk_scope_t *const scope) { } typedef int(chk_kv_visitor)(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, const size_t record_number, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data); __cold static int chk_handle_kv(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data) { MDBX_chk_internal_t *const chk = scope->internal; int err = MDBX_SUCCESS; - assert(sdb->cookie); - if (chk->cb->subdb_handle_kv) - err = chk->cb->subdb_handle_kv(chk->usr, sdb, record_number, key, data); + assert(tbl->cookie); + if (chk->cb->table_handle_kv) + err = chk->cb->table_handle_kv(chk->usr, tbl, record_number, key, data); return err ? err : chk_check_break(scope); } __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, - MDBX_chk_subdb_t *sdb, chk_kv_visitor *handler) { + MDBX_chk_table_t *tbl, chk_kv_visitor *handler) { MDBX_chk_internal_t *const chk = scope->internal; MDBX_chk_context_t *const usr = chk->usr; MDBX_env *const env = usr->env; @@ -11638,14 +11638,14 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, chk_line_end( chk_flush(chk_print(chk_line_begin(scope, MDBX_chk_error), "abort processing %s due to a previous error", - chk_v2a(chk, &sdb->name)))); + chk_v2a(chk, &tbl->name)))); err = MDBX_BAD_TXN; goto bailout; } if (0 > (int)dbi) { err = dbi_open( - txn, &sdb->name, MDBX_DB_ACCEDE, &dbi, + txn, &tbl->name, MDBX_DB_ACCEDE, &dbi, (chk->flags & MDBX_CHK_IGNORE_ORDER) ? cmp_equal_or_greater : nullptr, (chk->flags & MDBX_CHK_IGNORE_ORDER) ? cmp_equal_or_greater : nullptr); if (unlikely(err)) { @@ -11661,7 +11661,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, const tree_t *const db = txn->dbs + dbi; if (handler) { const char *key_mode = nullptr; - switch (sdb->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { + switch (tbl->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)) { case 0: key_mode = "usual"; break; @@ -11677,11 +11677,11 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, default: key_mode = "inconsistent"; chk_scope_issue(scope, "wrong key-mode (0x%x)", - sdb->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)); + tbl->flags & (MDBX_REVERSEKEY | MDBX_INTEGERKEY)); } const char *value_mode = nullptr; - switch (sdb->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | + switch (tbl->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP)) { case 0: value_mode = "single"; @@ -11710,7 +11710,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, default: value_mode = "inconsistent"; chk_scope_issue(scope, "wrong value-mode (0x%x)", - sdb->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | + tbl->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP | MDBX_DUPFIXED | MDBX_INTEGERDUP)); } @@ -11718,7 +11718,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, line = chk_print(line, "key-value kind: %s-key => %s-value", key_mode, value_mode); line = chk_print(line, ", flags:"); - if (!sdb->flags) + if (!tbl->flags) line = chk_print(line, " none"); else { const uint8_t f[] = {MDBX_DUPSORT, @@ -11731,10 +11731,10 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, const char *const t[] = {"dupsort", "integerkey", "reversekey", "dupfix", "reversedup", "integerdup"}; for (size_t i = 0; f[i]; i++) - if (sdb->flags & f[i]) + if (tbl->flags & f[i]) line = chk_print(line, " %s", t[i]); } - chk_line_end(chk_print(line, " (0x%02X)", sdb->flags)); + chk_line_end(chk_print(line, " (0x%02X)", tbl->flags)); line = chk_print(chk_line_begin(scope, MDBX_chk_verbose), "entries %" PRIu64 ", sequence %" PRIu64, db->items, @@ -11752,14 +11752,14 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, db->large_pages)); if ((chk->flags & MDBX_CHK_SKIP_BTREE_TRAVERSAL) == 0) { - const size_t branch_pages = sdb->pages.branch + sdb->pages.nested_branch; - const size_t leaf_pages = sdb->pages.leaf + sdb->pages.nested_leaf; + const size_t branch_pages = tbl->pages.branch + tbl->pages.nested_branch; + const size_t leaf_pages = tbl->pages.leaf + tbl->pages.nested_leaf; const size_t subtotal_pages = db->branch_pages + db->leaf_pages + db->large_pages; - if (subtotal_pages != sdb->pages.all) + if (subtotal_pages != tbl->pages.all) chk_scope_issue( scope, "%s pages mismatch (%" PRIuSIZE " != walked %" PRIuSIZE ")", - "subtotal", subtotal_pages, sdb->pages.all); + "subtotal", subtotal_pages, tbl->pages.all); if (db->branch_pages != branch_pages) chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", @@ -11768,11 +11768,11 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", "all-leaf", db->leaf_pages, leaf_pages); - if (db->large_pages != sdb->histogram.large_pages.amount) + if (db->large_pages != tbl->histogram.large_pages.amount) chk_scope_issue( scope, "%s pages mismatch (%" PRIaPGNO " != walked %" PRIuSIZE ")", "large/overlow", db->large_pages, - sdb->histogram.large_pages.amount); + tbl->histogram.large_pages.amount); } } @@ -11787,7 +11787,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, cursor->subcur->cursor.checking |= z_ignord | z_pagecheck; } - const size_t maxkeysize = mdbx_env_get_maxkeysize_ex(env, sdb->flags); + const size_t maxkeysize = mdbx_env_get_maxkeysize_ex(env, tbl->flags); MDBX_val prev_key = {nullptr, 0}, prev_data = {nullptr, 0}; MDBX_val key, data; err = mdbx_cursor_get(cursor, &key, &data, MDBX_FIRST); @@ -11802,7 +11802,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, "key length exceeds max-key-size", "%" PRIuPTR " > %" PRIuPTR, key.iov_len, maxkeysize); bad_key = true; - } else if ((sdb->flags & MDBX_INTEGERKEY) && key.iov_len != 8 && + } else if ((tbl->flags & MDBX_INTEGERKEY) && key.iov_len != 8 && key.iov_len != 4) { chk_object_issue(scope, "entry", record_count, "wrong key length", "%" PRIuPTR " != 4or8", key.iov_len); @@ -11810,7 +11810,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } bool bad_data = false; - if ((sdb->flags & MDBX_INTEGERDUP) && data.iov_len != 8 && + if ((tbl->flags & MDBX_INTEGERDUP) && data.iov_len != 8 && data.iov_len != 4) { chk_object_issue(scope, "entry", record_count, "wrong data length", "%" PRIuPTR " != 4or8", data.iov_len); @@ -11818,7 +11818,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } if (prev_key.iov_base) { - if (prev_data.iov_base && !bad_data && (sdb->flags & MDBX_DUPFIXED) && + if (prev_data.iov_base && !bad_data && (tbl->flags & MDBX_DUPFIXED) && prev_data.iov_len != data.iov_len) { chk_object_issue(scope, "entry", record_count, "different data length", "%" PRIuPTR " != %" PRIuPTR, prev_data.iov_len, @@ -11830,7 +11830,7 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, int cmp = mdbx_cmp(txn, dbi, &key, &prev_key); if (cmp == 0) { ++dups; - if ((sdb->flags & MDBX_DUPSORT) == 0) { + if ((tbl->flags & MDBX_DUPSORT) == 0) { chk_object_issue(scope, "entry", record_count, "duplicated entries", nullptr); if (prev_data.iov_base && data.iov_len == prev_data.iov_len && @@ -11853,57 +11853,55 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } if (!bad_key) { - if (!prev_key.iov_base && (sdb->flags & MDBX_INTEGERKEY)) + if (!prev_key.iov_base && (tbl->flags & MDBX_INTEGERKEY)) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "fixed key-size %" PRIuSIZE, key.iov_len)); prev_key = key; } if (!bad_data) { if (!prev_data.iov_base && - (sdb->flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED))) + (tbl->flags & (MDBX_INTEGERDUP | MDBX_DUPFIXED))) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "fixed data-size %" PRIuSIZE, data.iov_len)); prev_data = data; } record_count++; - histogram_acc(key.iov_len, &sdb->histogram.key_len); - histogram_acc(data.iov_len, &sdb->histogram.val_len); + histogram_acc(key.iov_len, &tbl->histogram.key_len); + histogram_acc(data.iov_len, &tbl->histogram.val_len); const node_t *const node = page_node(cursor->pg[cursor->top], cursor->ki[cursor->top]); - if (node_flags(node) == N_SUBDATA) { - if (dbi != MAIN_DBI || (sdb->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | + if (node_flags(node) == N_TREE) { + if (dbi != MAIN_DBI || (tbl->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | MDBX_REVERSEDUP | MDBX_INTEGERDUP))) - chk_object_issue(scope, "entry", record_count, - "unexpected sub-database", "node-flags 0x%x", - node_flags(node)); + chk_object_issue(scope, "entry", record_count, "unexpected table", + "node-flags 0x%x", node_flags(node)); else if (data.iov_len != sizeof(tree_t)) - chk_object_issue(scope, "entry", record_count, - "wrong sub-database node size", + chk_object_issue(scope, "entry", record_count, "wrong table node size", "node-size %" PRIuSIZE " != %" PRIuSIZE, data.iov_len, sizeof(tree_t)); else if (scope->stage == MDBX_chk_maindb) - /* подсчитываем subDB при первом проходе */ + /* подсчитываем table при первом проходе */ sub_databases += 1; else { - /* обработка subDB при втором проходе */ + /* обработка table при втором проходе */ tree_t aligned_db; memcpy(&aligned_db, data.iov_base, sizeof(aligned_db)); - walk_sdb_t sdb_info = {.name = key}; - sdb_info.internal = &aligned_db; - MDBX_chk_subdb_t *subdb; - err = chk_get_sdb(scope, &sdb_info, &subdb); + walk_tbl_t tbl_info = {.name = key}; + tbl_info.internal = &aligned_db; + MDBX_chk_table_t *table; + err = chk_get_tbl(scope, &tbl_info, &table); if (unlikely(err)) goto bailout; - if (subdb->cookie) { + if (table->cookie) { err = chk_scope_begin( - chk, 0, MDBX_chk_subdbs, subdb, &usr->result.problems_kv, - "Processing subDB %s...", chk_v2a(chk, &subdb->name)); + chk, 0, MDBX_chk_tables, table, &usr->result.problems_kv, + "Processing table %s...", chk_v2a(chk, &table->name)); if (likely(!err)) { - err = chk_db(usr->scope, (MDBX_dbi)-1, subdb, chk_handle_kv); + err = chk_db(usr->scope, (MDBX_dbi)-1, table, chk_handle_kv); if (err != MDBX_EINTR && err != MDBX_RESULT_TRUE) - usr->result.subdb_processed += 1; + usr->result.table_processed += 1; } err = chk_scope_restore(scope, err); if (unlikely(err)) @@ -11911,10 +11909,10 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } else chk_line_end(chk_flush( chk_print(chk_line_begin(scope, MDBX_chk_processing), - "Skip processing %s...", chk_v2a(chk, &subdb->name)))); + "Skip processing %s...", chk_v2a(chk, &table->name)))); } } else if (handler) { - err = handler(scope, sdb, record_count, &key, &data); + err = handler(scope, tbl, record_count, &key, &data); if (unlikely(err)) goto bailout; } @@ -11931,32 +11929,32 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, bailout: if (cursor) { if (handler) { - if (sdb->histogram.key_len.count) { + if (tbl->histogram.key_len.count) { MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_info); - line = histogram_dist(line, &sdb->histogram.key_len, + line = histogram_dist(line, &tbl->histogram.key_len, "key length density", "0/1", false); chk_line_feed(line); - line = histogram_dist(line, &sdb->histogram.val_len, + line = histogram_dist(line, &tbl->histogram.val_len, "value length density", "0/1", false); chk_line_end(line); } if (scope->stage == MDBX_chk_maindb) - usr->result.subdb_total = sub_databases; - if (chk->cb->subdb_conclude) - err = chk->cb->subdb_conclude(usr, sdb, cursor, err); + usr->result.table_total = sub_databases; + if (chk->cb->table_conclude) + err = chk->cb->table_conclude(usr, tbl, cursor, err); MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_resolution); line = chk_print(line, "summary: %" PRIuSIZE " records,", record_count); - if (dups || (sdb->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | + if (dups || (tbl->flags & (MDBX_DUPSORT | MDBX_DUPFIXED | MDBX_REVERSEDUP | MDBX_INTEGERDUP))) line = chk_print(line, " %" PRIuSIZE " dups,", dups); if (sub_databases || dbi == MAIN_DBI) - line = chk_print(line, " %" PRIuSIZE " sub-databases,", sub_databases); + line = chk_print(line, " %" PRIuSIZE " tables,", sub_databases); line = chk_print(line, " %" PRIuSIZE " key's bytes," " %" PRIuSIZE " data's bytes," " %" PRIuSIZE " problem(s)", - sdb->histogram.key_len.amount, - sdb->histogram.val_len.amount, scope->subtotal_issues); + tbl->histogram.key_len.amount, + tbl->histogram.val_len.amount, scope->subtotal_issues); chk_line_end(chk_flush(line)); } @@ -11968,13 +11966,13 @@ __cold static int chk_db(MDBX_chk_scope_t *const scope, MDBX_dbi dbi, } __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, - MDBX_chk_subdb_t *sdb, + MDBX_chk_table_t *tbl, const size_t record_number, const MDBX_val *key, const MDBX_val *data) { MDBX_chk_internal_t *const chk = scope->internal; MDBX_chk_context_t *const usr = chk->usr; - assert(sdb == &chk->subdb_gc); - (void)sdb; + assert(tbl == &chk->table_gc); + (void)tbl; const char *bad = ""; pgno_t *iptr = data->iov_base; @@ -12043,9 +12041,9 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, if (id == 0) chk->pagemap[pgno] = -1 /* mark the pgno listed in GC */; else if (id > 0) { - assert(id - 1 <= (intptr_t)ARRAY_LENGTH(chk->subdb)); + assert(id - 1 <= (intptr_t)ARRAY_LENGTH(chk->table)); chk_object_issue(scope, "page", pgno, "already used", "by %s", - chk_v2a(chk, &chk->subdb[id - 1]->name)); + chk_v2a(chk, &chk->table[id - 1]->name)); } else chk_object_issue(scope, "page", pgno, "already listed in GC", nullptr); @@ -12057,7 +12055,7 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, : pgno_sub(pgno, span))) ++span; } - if (sdb->cookie) { + if (tbl->cookie) { chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_details), "transaction %" PRIaTXN ", %" PRIuSIZE " pages, maxspan %" PRIuSIZE "%s", @@ -12070,7 +12068,7 @@ __cold static int chk_handle_gc(MDBX_chk_scope_t *const scope, : pgno_sub(pgno, span)); ++span) ; - histogram_acc(span, &sdb->histogram.nested_tree); + histogram_acc(span, &tbl->histogram.nested_tree); MDBX_chk_line_t *line = chk_line_begin(scope, MDBX_chk_extra); if (line) { if (span > 1) @@ -12343,13 +12341,13 @@ __cold static int env_chk(MDBX_chk_scope_t *const scope) { usr->result.problems_gc = usr->result.gc_tree_problems)); else { err = chk_scope_begin( - chk, -1, MDBX_chk_gc, &chk->subdb_gc, &usr->result.problems_gc, + chk, -1, MDBX_chk_gc, &chk->table_gc, &usr->result.problems_gc, "Processing %s by txn#%" PRIaTXN "...", subj_gc, txn->txnid); if (likely(!err)) - err = chk_db(usr->scope, FREE_DBI, &chk->subdb_gc, chk_handle_gc); + err = chk_db(usr->scope, FREE_DBI, &chk->table_gc, chk_handle_gc); line = chk_line_begin(scope, MDBX_chk_info); if (line) { - histogram_print(scope, line, &chk->subdb_gc.histogram.nested_tree, + histogram_print(scope, line, &chk->table_gc.histogram.nested_tree, "span(s)", "single", false); chk_line_end(line); } @@ -12481,32 +12479,32 @@ __cold static int env_chk(MDBX_chk_scope_t *const scope) { subj_main, subj_tree, usr->result.problems_kv = usr->result.kv_tree_problems)); else { - err = chk_scope_begin(chk, 0, MDBX_chk_maindb, &chk->subdb_main, + err = chk_scope_begin(chk, 0, MDBX_chk_maindb, &chk->table_main, &usr->result.problems_kv, "Processing %s...", subj_main); if (likely(!err)) - err = chk_db(usr->scope, MAIN_DBI, &chk->subdb_main, chk_handle_kv); + err = chk_db(usr->scope, MAIN_DBI, &chk->table_main, chk_handle_kv); chk_scope_restore(scope, err); - const char *const subj_subdbs = "sub-database(s)"; - if (usr->result.problems_kv && usr->result.subdb_total) + const char *const subj_tables = "table(s)"; + if (usr->result.problems_kv && usr->result.table_total) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_processing), - "Skip processing %s", subj_subdbs)); - else if (usr->result.problems_kv == 0 && usr->result.subdb_total == 0) + "Skip processing %s", subj_tables)); + else if (usr->result.problems_kv == 0 && usr->result.table_total == 0) chk_line_end(chk_print(chk_line_begin(scope, MDBX_chk_info), "No %s", - subj_subdbs)); - else if (usr->result.problems_kv == 0 && usr->result.subdb_total) { + subj_tables)); + else if (usr->result.problems_kv == 0 && usr->result.table_total) { err = chk_scope_begin( - chk, 1, MDBX_chk_subdbs, nullptr, &usr->result.problems_kv, - "Processing %s by txn#%" PRIaTXN "...", subj_subdbs, txn->txnid); + chk, 1, MDBX_chk_tables, nullptr, &usr->result.problems_kv, + "Processing %s by txn#%" PRIaTXN "...", subj_tables, txn->txnid); if (!err) - err = chk_db(usr->scope, MAIN_DBI, &chk->subdb_main, nullptr); + err = chk_db(usr->scope, MAIN_DBI, &chk->table_main, nullptr); if (usr->scope->subtotal_issues) chk_line_end(chk_print(chk_line_begin(usr->scope, MDBX_chk_resolution), "processed %" PRIuSIZE " of %" PRIuSIZE " %s, %" PRIuSIZE " problems(s)", - usr->result.subdb_processed, - usr->result.subdb_total, subj_subdbs, + usr->result.table_processed, + usr->result.table_total, subj_tables, usr->scope->subtotal_issues)); } chk_scope_restore(scope, err); @@ -12546,20 +12544,20 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb, chk->usr->env = env; chk->flags = flags; - chk->subdb_gc.id = -1; - chk->subdb_gc.name.iov_base = MDBX_CHK_GC; - chk->subdb[FREE_DBI] = &chk->subdb_gc; + chk->table_gc.id = -1; + chk->table_gc.name.iov_base = MDBX_CHK_GC; + chk->table[FREE_DBI] = &chk->table_gc; - chk->subdb_main.id = -1; - chk->subdb_main.name.iov_base = MDBX_CHK_MAIN; - chk->subdb[MAIN_DBI] = &chk->subdb_main; + chk->table_main.id = -1; + chk->table_main.name.iov_base = MDBX_CHK_MAIN; + chk->table[MAIN_DBI] = &chk->table_main; chk->monotime_timeout = timeout_seconds_16dot16 ? osal_16dot16_to_monotime(timeout_seconds_16dot16) + osal_monotime() : 0; chk->usr->scope_nesting = 0; - chk->usr->result.subdbs = (const void *)&chk->subdb; + chk->usr->result.tables = (const void *)&chk->table; MDBX_chk_scope_t *const top = chk->scope_stack; top->verbosity = verbosity; @@ -12591,8 +12589,8 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb, // doit if (likely(!rc)) { - chk->subdb_gc.flags = ctx->txn->dbs[FREE_DBI].flags; - chk->subdb_main.flags = ctx->txn->dbs[MAIN_DBI].flags; + chk->table_gc.flags = ctx->txn->dbs[FREE_DBI].flags; + chk->table_main.flags = ctx->txn->dbs[MAIN_DBI].flags; rc = env_chk(top); } @@ -12999,7 +12997,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, unlikely(freedb_root_pgno >= last_pgno)) { if (report) WARNING( - "catch invalid %sdb root %" PRIaPGNO " for meta_txnid %" PRIaTXN + "catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "free", freedb_root_pgno, txnid, (env->stuck_meta < 0) @@ -13011,7 +13009,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, unlikely(maindb_root_pgno >= last_pgno)) { if (report) WARNING( - "catch invalid %sdb root %" PRIaPGNO " for meta_txnid %" PRIaTXN + "catch invalid %s-db root %" PRIaPGNO " for meta_txnid %" PRIaTXN " %s", "main", maindb_root_pgno, txnid, (env->stuck_meta < 0) @@ -13024,7 +13022,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, likely(magic_and_version == MDBX_DATA_MAGIC)))) { if (report) WARNING( - "catch invalid %sdb.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN + "catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "free", freedb_mod_txnid, txnid, (env->stuck_meta < 0) @@ -13037,7 +13035,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, likely(magic_and_version == MDBX_DATA_MAGIC)))) { if (report) WARNING( - "catch invalid %sdb.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN + "catch invalid %s-db.mod_txnid %" PRIaTXN " for meta_txnid %" PRIaTXN " %s", "main", maindb_mod_txnid, txnid, (env->stuck_meta < 0) @@ -13052,7 +13050,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, if (unlikely(root_txnid != freedb_mod_txnid)) { if (report) WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN - " for %sdb.mod_txnid %" PRIaTXN " %s", + " for %s-db.mod_txnid %" PRIaTXN " %s", freedb_root_pgno, root_txnid, "free", freedb_mod_txnid, (env->stuck_meta < 0) ? "(workaround for incoherent flaw of " "unified page/buffer cache)" @@ -13067,7 +13065,7 @@ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, if (unlikely(root_txnid != maindb_mod_txnid)) { if (report) WARNING("catch invalid root_page %" PRIaPGNO " mod_txnid %" PRIaTXN - " for %sdb.mod_txnid %" PRIaTXN " %s", + " for %s-db.mod_txnid %" PRIaTXN " %s", maindb_root_pgno, root_txnid, "main", maindb_mod_txnid, (env->stuck_meta < 0) ? "(workaround for incoherent flaw of " "unified page/buffer cache)" @@ -13138,7 +13136,7 @@ __hot int coherency_check_head(MDBX_txn *txn, const meta_ptr_t head, txn->dbs[FREE_DBI].flags &= DB_PERSISTENT_FLAGS; } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); return MDBX_SUCCESS; } @@ -13151,7 +13149,7 @@ int coherency_check_written(const MDBX_env *env, const txnid_t txnid, if (likely( coherency_check(env, head_txnid, &meta->trees.gc, meta, report))) { eASSERT(env, meta->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(meta->trees.main.flags)); + eASSERT(env, check_table_flags(meta->trees.main.flags)); return MDBX_SUCCESS; } } else if (report) { @@ -13361,17 +13359,17 @@ __cold static int stat_acc(const MDBX_txn *txn, MDBX_stat *st, size_t bytes) { if (!(txn->dbs[MAIN_DBI].flags & MDBX_DUPSORT) && txn->dbs[MAIN_DBI].items /* TODO: use `md_subs` field */) { - /* scan and account not opened named subDBs */ + /* scan and account not opened named tables */ err = tree_search(&cx.outer, nullptr, Z_FIRST); while (err == MDBX_SUCCESS) { const page_t *mp = cx.outer.pg[cx.outer.top]; for (size_t i = 0; i < page_numkeys(mp); i++) { const node_t *node = page_node(mp, i); - if (node_flags(node) != N_SUBDATA) + if (node_flags(node) != N_TREE) continue; if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %zu", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", node_ds(node)); + "invalid table node size", node_ds(node)); return MDBX_CORRUPTED; } @@ -14130,11 +14128,10 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, page_t *mp = mc->pg[mc->top]; const size_t nkeys = page_numkeys(mp); if (is_leaf(mp)) { - if (!(mc->flags & - z_inner) /* may have nested N_SUBDATA or N_BIGDATA nodes */) { + if (!(mc->flags & z_inner) /* may have nested N_TREE or N_BIG nodes */) { for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - if (node_flags(node) == N_BIGDATA) { + if (node_flags(node) == N_BIG) { /* Need writable leaf */ if (mp != leaf) { mc->pg[mc->top] = leaf; @@ -14154,7 +14151,7 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, npages); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - } else if (node_flags(node) & N_SUBDATA) { + } else if (node_flags(node) & N_TREE) { if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, @@ -14173,7 +14170,7 @@ __cold static int compacting_walk(ctx_t *ctx, MDBX_cursor *mc, } tree_t *nested = nullptr; - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { rc = cursor_dupsort_setup(mc, node, mp); if (likely(rc == MDBX_SUCCESS)) { nested = &mc->subcur->nested_tree; @@ -15181,10 +15178,10 @@ static __always_inline int couple_init(cursor_couple_t *couple, } if (unlikely(*dbi_state & DBI_STALE)) - return sdb_fetch(couple->outer.txn, cursor_dbi(&couple->outer)); + return tbl_fetch(couple->outer.txn, cursor_dbi(&couple->outer)); if (unlikely(kvx->clc.k.lmax == 0)) - return sdb_setup(txn->env, kvx, tree); + return tbl_setup(txn->env, kvx, tree); return MDBX_SUCCESS; } @@ -15223,7 +15220,7 @@ int cursor_dupsort_setup(MDBX_cursor *mc, const node_t *node, default: ERROR("invalid node flags %u", flags); goto bailout; - case N_DUPDATA | N_SUBDATA: + case N_DUP | N_TREE: if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("invalid nested-db record size (%zu, expect %zu)", node_ds(node), sizeof(tree_t)); @@ -15239,7 +15236,7 @@ int cursor_dupsort_setup(MDBX_cursor *mc, const node_t *node, } mx->cursor.top_and_flags = z_fresh_mark | z_inner; break; - case N_DUPDATA: + case N_DUP: if (!MDBX_DISABLE_VALIDATION && unlikely(node_ds(node) <= PAGEHDRSZ)) { ERROR("invalid nested-page size %zu", node_ds(node)); goto bailout; @@ -15414,12 +15411,12 @@ static __always_inline int cursor_bring(const bool inner, const bool tend2first, } const node_t *__restrict node = page_node(mp, ki); - if (!inner && (node_flags(node) & N_DUPDATA)) { + if (!inner && (node_flags(node) & N_DUP)) { int err = cursor_dupsort_setup(mc, node, mp); if (unlikely(err != MDBX_SUCCESS)) return err; MDBX_ANALYSIS_ASSUME(mc->subcur != nullptr); - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { err = tend2first ? inner_first(&mc->subcur->cursor, data) : inner_last(&mc->subcur->cursor, data); if (unlikely(err != MDBX_SUCCESS)) @@ -15666,7 +15663,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, if (mc->subcur) { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { cASSERT(mc, inner_pointed(mc)); /* Если за ключом более одного значения, либо если размер данных * отличается, то вместо обновления требуется удаление и @@ -15726,7 +15723,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, } } else { csr_t csr = - /* olddata may not be updated in case DUPFIX-page of dupfix-subDB */ + /* olddata may not be updated in case DUPFIX-page of dupfix-table */ cursor_seek(mc, (MDBX_val *)key, &old_data, MDBX_SET); rc = csr.err; exact = csr.exact; @@ -15744,7 +15741,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, eASSERT(env, data->iov_len == 0 && (old_data.iov_len == 0 || /* olddata may not be updated in case - DUPFIX-page of dupfix-subDB */ + DUPFIX-page of dupfix-table */ (mc->tree->flags & MDBX_DUPFIXED))); return MDBX_SUCCESS; } @@ -15887,7 +15884,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, node_t *const node = page_node(mc->pg[mc->top], mc->ki[mc->top]); /* Large/Overflow page overwrites need special handling */ - if (unlikely(node_flags(node) & N_BIGDATA)) { + if (unlikely(node_flags(node) & N_BIG)) { const size_t dpages = (node_size(key, data) > env->leaf_nodemax) ? largechunk_npages(env, data->iov_len) : 0; @@ -15974,7 +15971,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, mp->pgno = mc->pg[mc->top]->pgno; /* Was a single item before, must convert now */ - if (!(node_flags(node) & N_DUPDATA)) { + if (!(node_flags(node) & N_DUP)) { /* does data match? */ if (flags & MDBX_APPENDDUP) { const int cmp = mc->clc->v.cmp(data, &old_data); @@ -16026,9 +16023,9 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, cASSERT(mc, (xdata.iov_len & 1) == 0); fp->upper = (uint16_t)(xdata.iov_len - PAGEHDRSZ); old_data.iov_len = xdata.iov_len; /* pretend olddata is fp */ - } else if (node_flags(node) & N_SUBDATA) { + } else if (node_flags(node) & N_TREE) { /* Data is on sub-DB, just store it */ - flags |= N_DUPDATA | N_SUBDATA; + flags |= N_DUP | N_TREE; goto dupsort_put; } else { /* Data is on sub-page */ @@ -16123,7 +16120,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, fp->txnid = mc->txn->front_txnid; fp->pgno = mp->pgno; mc->subcur->cursor.pg[0] = fp; - flags |= N_DUPDATA; + flags |= N_DUP; goto dupsort_put; } xdata.iov_len = old_data.iov_len + growth; @@ -16162,7 +16159,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, cASSERT(mc, env->ps > old_data.iov_len); growth = env->ps - (unsigned)old_data.iov_len; cASSERT(mc, (growth & 1) == 0); - flags |= N_DUPDATA | N_SUBDATA; + flags |= N_DUP | N_TREE; nested_dupdb.root = mp->pgno; nested_dupdb.sequence = 0; nested_dupdb.mod_txnid = mc->txn->txnid; @@ -16197,12 +16194,12 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, if (!insert_key) node_del(mc, 0); ref_data = &xdata; - flags |= N_DUPDATA; + flags |= N_DUP; goto insert_node; } - /* MDBX passes N_SUBDATA in 'flags' to write a DB record */ - if (unlikely((node_flags(node) ^ flags) & N_SUBDATA)) + /* MDBX passes N_TREE in 'flags' to write a DB record */ + if (unlikely((node_flags(node) ^ flags) & N_TREE)) return MDBX_INCOMPATIBLE; current: @@ -16254,8 +16251,7 @@ insert_node:; } else { /* There is room already in this leaf page. */ if (is_dupfix_leaf(mc->pg[mc->top])) { - cASSERT(mc, !(naf & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) && - ref_data->iov_len == 0); + cASSERT(mc, !(naf & (N_BIG | N_TREE | N_DUP)) && ref_data->iov_len == 0); rc = node_add_dupfix(mc, mc->ki[mc->top], key); } else rc = node_add_leaf(mc, mc->ki[mc->top], key, ref_data, naf); @@ -16280,7 +16276,7 @@ insert_node:; * storing the user data in the keys field, so there are strict * size limits on dupdata. The actual data fields of the child * DB are all zero size. */ - if (flags & N_DUPDATA) { + if (flags & N_DUP) { MDBX_val empty; dupsort_put: empty.iov_len = 0; @@ -16318,7 +16314,7 @@ insert_node:; goto dupsort_error; mx->cursor.tree->items = 1; } - if (!(node_flags(node) & N_SUBDATA) || sub_root) { + if (!(node_flags(node) & N_TREE) || sub_root) { page_t *const mp = mc->pg[mc->top]; const intptr_t nkeys = page_numkeys(mp); const size_t dbi = cursor_dbi(mc); @@ -16352,7 +16348,7 @@ insert_node:; inner_flags |= (flags & MDBX_APPENDDUP) >> SHIFT_MDBX_APPENDDUP_TO_MDBX_APPEND; rc = cursor_put(&mc->subcur->cursor, data, &empty, inner_flags); - if (flags & N_SUBDATA) { + if (flags & N_TREE) { void *db = node_data(node); mc->subcur->nested_tree.mod_txnid = mc->txn->txnid; memcpy(db, &mc->subcur->nested_tree, sizeof(tree_t)); @@ -16479,12 +16475,12 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { goto del_key; node_t *node = page_node(mp, mc->ki[mc->top]); - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { if (flags & (MDBX_ALLDUPS | /* for compatibility */ MDBX_NODUPDATA)) { /* will subtract the final entry later */ mc->tree->items -= mc->subcur->nested_tree.items - 1; } else { - if (!(node_flags(node) & N_SUBDATA)) { + if (!(node_flags(node) & N_TREE)) { page_t *sp = node_data(node); cASSERT(mc, is_subpage(sp)); sp->txnid = mp->txnid; @@ -16495,8 +16491,8 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { return rc; /* If sub-DB still has entries, we're done */ if (mc->subcur->nested_tree.items) { - if (node_flags(node) & N_SUBDATA) { - /* update subDB info */ + if (node_flags(node) & N_TREE) { + /* update table info */ mc->subcur->nested_tree.mod_txnid = mc->txn->txnid; memcpy(node_data(node), &mc->subcur->nested_tree, sizeof(tree_t)); } else { @@ -16517,7 +16513,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { } if (m2->ki[mc->top] != mc->ki[mc->top]) { inner = page_node(mp, m2->ki[mc->top]); - if (node_flags(inner) & N_SUBDATA) + if (node_flags(inner) & N_TREE) continue; } m2->subcur->cursor.pg[0] = node_data(inner); @@ -16531,7 +16527,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { /* otherwise fall thru and delete the sub-DB */ } - if ((node_flags(node) & N_SUBDATA) && mc->subcur->cursor.tree->height) { + if ((node_flags(node) & N_TREE) && mc->subcur->cursor.tree->height) { /* add all the child DB's pages to the free list */ rc = tree_drop(&mc->subcur->cursor, false); if (unlikely(rc != MDBX_SUCCESS)) @@ -16540,13 +16536,13 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { inner_gone(mc); } else { cASSERT(mc, !inner_pointed(mc)); - /* MDBX passes N_SUBDATA in 'flags' to delete a DB record */ - if (unlikely((node_flags(node) ^ flags) & N_SUBDATA)) + /* MDBX passes N_TREE in 'flags' to delete a DB record */ + if (unlikely((node_flags(node) ^ flags) & N_TREE)) return MDBX_INCOMPATIBLE; } /* add large/overflow pages to free list */ - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { pgr_t lp = page_get_large(mc, node_largedata_pgno(node), mp->txnid); if (unlikely((rc = lp.err) || (rc = page_retire(mc, lp.page)))) goto fail; @@ -16624,19 +16620,19 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { /* уже переместились вправо */ m3->pg[top] != mp)) { node = page_node(m3->pg[m3->top], m3->ki[m3->top]); /* Если это dupsort-узел, то должен быть валидный вложенный курсор. */ - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { /* Тут три варианта событий: - * 1) Вложенный курсор уже инициализирован, у узла есть флаг N_SUBDATA, + * 1) Вложенный курсор уже инициализирован, у узла есть флаг N_TREE, * соответственно дубликаты вынесены в отдельное дерево с корнем * в отдельной странице = ничего корректировать не требуется. - * 2) Вложенный курсор уже инициализирован, у узла нет флага N_SUBDATA, + * 2) Вложенный курсор уже инициализирован, у узла нет флага N_TREE, * соответственно дубликаты размещены на вложенной sub-странице. * 3) Курсор стоял на удалённом элементе, который имел одно значение, * а после удаления переместился на следующий элемент с дубликатами. * В этом случае вложенный курсор не инициализирован и тепеь его * нужно установить на первый дубликат. */ if (is_pointed(&m3->subcur->cursor)) { - if ((node_flags(node) & N_SUBDATA) == 0) { + if ((node_flags(node) & N_TREE) == 0) { cASSERT(m3, m3->subcur->cursor.top == 0 && m3->subcur->nested_tree.height == 1); m3->subcur->cursor.pg[0] = node_data(node); @@ -16645,7 +16641,7 @@ __hot int cursor_del(MDBX_cursor *mc, unsigned flags) { rc = cursor_dupsort_setup(m3, node, m3->pg[m3->top]); if (unlikely(rc != MDBX_SUCCESS)) goto fail; - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { rc = inner_first(&m3->subcur->cursor, nullptr); if (unlikely(rc != MDBX_SUCCESS)) goto fail; @@ -16865,13 +16861,13 @@ __hot csr_t cursor_seek(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, return ret; } - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { ret.err = cursor_dupsort_setup(mc, node, mp); if (unlikely(ret.err != MDBX_SUCCESS)) return ret; if (op >= MDBX_SET) { MDBX_ANALYSIS_ASSUME(mc->subcur != nullptr); - if (node_flags(node) & N_SUBDATA) { + if (node_flags(node) & N_TREE) { ret.err = inner_first(&mc->subcur->cursor, data); if (unlikely(ret.err != MDBX_SUCCESS)) return ret; @@ -16983,7 +16979,7 @@ __hot int cursor_ops(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, get_key_optional(node, key); if (!data) return MDBX_SUCCESS; - if (node_flags(node) & N_DUPDATA) { + if (node_flags(node) & N_DUP) { if (!MDBX_DISABLE_VALIDATION && unlikely(!mc->subcur)) return unexpected_dupsort(mc); mc = &mc->subcur->cursor; @@ -17114,7 +17110,7 @@ __hot int cursor_ops(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, else { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); get_key_optional(node, key); - if ((node_flags(node) & N_DUPDATA) == 0) + if ((node_flags(node) & N_DUP) == 0) return node_read(mc, node, data, mc->pg[mc->top]); else if (MDBX_DISABLE_VALIDATION || likely(mc->subcur)) return ((op == MDBX_FIRST_DUP) ? inner_first @@ -17406,7 +17402,7 @@ __noinline int dbi_import(MDBX_txn *txn, const size_t dbi) { if (parent) { /* вложенная пишущая транзакция */ int rc = dbi_check(parent, dbi); - /* копируем состояние subDB очищая new-флаги. */ + /* копируем состояние table очищая new-флаги. */ eASSERT(env, txn->dbi_seqs == parent->dbi_seqs); txn->dbi_state[dbi] = parent->dbi_state[dbi] & ~(DBI_FRESH | DBI_CREAT | DBI_DIRTY); @@ -17577,15 +17573,15 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, /* Если dbi уже использовался, то корректными считаем четыре варианта: * 1) user_flags равны MDBX_DB_ACCEDE - * = предполагаем что пользователь открывает существующую subDb, + * = предполагаем что пользователь открывает существующую table, * при этом код проверки не позволит установить другие компараторы. * 2) user_flags нулевые, а оба компаратора пустые/нулевые или равны текущим - * = предполагаем что пользователь открывает существующую subDb + * = предполагаем что пользователь открывает существующую table * старым способом с нулевыми с флагами по-умолчанию. * 3) user_flags совпадают, а компараторы не заданы или те же - * = предполагаем что пользователь открывает subDb указывая все параметры; - * 4) user_flags отличаются, но subDb пустая и задан флаг MDBX_CREATE - * = предполагаем что пользователь пересоздает subDb; + * = предполагаем что пользователь открывает table указывая все параметры; + * 4) user_flags отличаются, но table пустая и задан флаг MDBX_CREATE + * = предполагаем что пользователь пересоздает table; */ if ((user_flags & ~MDBX_CREATE) != (unsigned)(env->dbs_flags[dbi] & DB_PERSISTENT_FLAGS)) { @@ -17599,7 +17595,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, else { eASSERT(env, env->dbs_flags[dbi] & DB_VALID); if (txn->dbi_state[dbi] & DBI_STALE) { - int err = sdb_fetch(txn, dbi); + int err = tbl_fetch(txn, dbi); if (unlikely(err == MDBX_SUCCESS)) return err; } @@ -17609,7 +17605,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, if (unlikely(txn->dbs[dbi].leaf_pages)) return /* FIXME: return extended info */ MDBX_INCOMPATIBLE; - /* Пересоздаём subDB если там пусто */ + /* Пересоздаём table если там пусто */ if (unlikely(txn->cursors[dbi])) return MDBX_DANGLING_DBI; env->dbs_flags[dbi] = DB_POISON; @@ -17624,7 +17620,7 @@ int dbi_bind(MDBX_txn *txn, const size_t dbi, unsigned user_flags, env->kvs[dbi].clc.v.cmp = datacmp ? datacmp : builtin_datacmp(user_flags); txn->dbs[dbi].flags = db_flags; txn->dbs[dbi].dupfix_size = 0; - if (unlikely(sdb_setup(env, &env->kvs[dbi], &txn->dbs[dbi]))) { + if (unlikely(tbl_setup(env, &env->kvs[dbi], &txn->dbs[dbi]))) { txn->dbi_state[dbi] = DBI_LINDO; txn->flags |= MDBX_TXN_ERROR; return MDBX_PROBLEM; @@ -17697,7 +17693,7 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, env->kvs[MAIN_DBI].clc.v.cmp = builtin_datacmp(main_flags); txn->dbs[MAIN_DBI].flags = main_flags; txn->dbs[MAIN_DBI].dupfix_size = 0; - int err = sdb_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); + int err = tbl_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); if (unlikely(err != MDBX_SUCCESS)) { txn->dbi_state[MAIN_DBI] = DBI_LINDO; txn->flags |= MDBX_TXN_ERROR; @@ -17777,11 +17773,11 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, /* make sure this is actually a table */ node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (unlikely((node_flags(node) & (N_DUPDATA | N_SUBDATA)) != N_SUBDATA)) + if (unlikely((node_flags(node) & (N_DUP | N_TREE)) != N_TREE)) return MDBX_INCOMPATIBLE; if (!MDBX_DISABLE_VALIDATION && unlikely(body.iov_len != sizeof(tree_t))) { ERROR("%s/%d: %s %zu", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", body.iov_len); + "invalid table node size", body.iov_len); return MDBX_CORRUPTED; } memcpy(&txn->dbs[slot], body.iov_base, sizeof(tree_t)); @@ -17807,8 +17803,8 @@ static int dbi_open_locked(MDBX_txn *txn, unsigned user_flags, MDBX_dbi *dbi, txn->dbs[slot].flags = user_flags & DB_PERSISTENT_FLAGS; cx.outer.next = txn->cursors[MAIN_DBI]; txn->cursors[MAIN_DBI] = &cx.outer; - rc = cursor_put_checklen(&cx.outer, &name, &body, - N_SUBDATA | MDBX_NOOVERWRITE); + rc = + cursor_put_checklen(&cx.outer, &name, &body, N_TREE | MDBX_NOOVERWRITE); txn->cursors[MAIN_DBI] = cx.outer.next; if (unlikely(rc != MDBX_SUCCESS)) goto bailout; @@ -17859,7 +17855,7 @@ int dbi_open(MDBX_txn *txn, const MDBX_val *const name, unsigned user_flags, *dbi = 0; if (user_flags != MDBX_ACCEDE && - unlikely(!check_sdb_flags(user_flags & ~MDBX_CREATE))) + unlikely(!check_table_flags(user_flags & ~MDBX_CREATE))) return MDBX_EINVAL; int rc = check_txn(txn, MDBX_TXN_BLOCKED); @@ -18013,11 +18009,11 @@ dbi_rename_locked(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val new_name) { MDBX_val data = {&txn->dbs[dbi], sizeof(tree_t)}; pair.err = cursor_put_checklen(&cx.outer, &new_name, &data, - N_SUBDATA | MDBX_NOOVERWRITE); + N_TREE | MDBX_NOOVERWRITE); if (likely(pair.err == MDBX_SUCCESS)) { pair.err = cursor_seek(&cx.outer, &old_name, nullptr, MDBX_SET).err; if (likely(pair.err == MDBX_SUCCESS)) - pair.err = cursor_del(&cx.outer, N_SUBDATA); + pair.err = cursor_del(&cx.outer, N_TREE); if (likely(pair.err == MDBX_SUCCESS)) { pair.defer = env->kvs[dbi].name.iov_base; env->kvs[dbi].name = new_name; @@ -18131,7 +18127,7 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) { if (likely(rc == MDBX_SUCCESS)) { cx.outer.next = txn->cursors[MAIN_DBI]; txn->cursors[MAIN_DBI] = &cx.outer; - rc = cursor_del(&cx.outer, N_SUBDATA); + rc = cursor_del(&cx.outer, N_TREE); txn->cursors[MAIN_DBI] = cx.outer.next; if (likely(rc == MDBX_SUCCESS)) { tASSERT(txn, txn->dbi_state[MAIN_DBI] & DBI_DIRTY); @@ -18261,7 +18257,7 @@ __cold int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest, return MDBX_BAD_TXN; if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { - rc = sdb_fetch((MDBX_txn *)txn, dbi); + rc = tbl_fetch((MDBX_txn *)txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) return rc; } @@ -18295,8 +18291,8 @@ __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi, return fallback; } -__cold int mdbx_enumerate_subdb(const MDBX_txn *txn, MDBX_subdb_enum_func *func, - void *ctx) { +__cold int mdbx_enumerate_tables(const MDBX_txn *txn, + MDBX_table_enum_func *func, void *ctx) { if (unlikely(!func)) return MDBX_EINVAL; @@ -18315,7 +18311,7 @@ __cold int mdbx_enumerate_subdb(const MDBX_txn *txn, MDBX_subdb_enum_func *func, rc = outer_next(&cx.outer, nullptr, nullptr, MDBX_NEXT_NODUP)) { node_t *node = page_node(cx.outer.pg[cx.outer.top], cx.outer.ki[cx.outer.top]); - if (node_flags(node) != N_SUBDATA) + if (node_flags(node) != N_TREE) continue; if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, @@ -20006,7 +20002,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, troika_t *const troika) { eASSERT(env, ((env->flags ^ flags) & MDBX_WRITEMAP) == 0); eASSERT(env, pending->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(pending->trees.main.flags)); + eASSERT(env, check_table_flags(pending->trees.main.flags)); const meta_t *const meta0 = METAPAGE(env, 0); const meta_t *const meta1 = METAPAGE(env, 1); const meta_t *const meta2 = METAPAGE(env, 2); @@ -20305,7 +20301,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, target->trees.gc = pending->trees.gc; target->trees.main = pending->trees.main; eASSERT(env, target->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(target->trees.main.flags)); + eASSERT(env, check_table_flags(target->trees.main.flags)); target->canary = pending->canary; memcpy(target->pages_retired, pending->pages_retired, 8); jitter4testing(true); @@ -20360,7 +20356,7 @@ int dxb_sync_locked(MDBX_env *env, unsigned flags, meta_t *const pending, #endif /* MDBX_ENABLE_PGOP_STAT */ const meta_t undo_meta = *target; eASSERT(env, pending->trees.gc.flags == MDBX_INTEGERKEY); - eASSERT(env, check_sdb_flags(pending->trees.main.flags)); + eASSERT(env, check_table_flags(pending->trees.main.flags)); rc = osal_pwrite(env->fd4meta, pending, sizeof(meta_t), ptr_dist(target, env->dxb_mmap.base)); if (unlikely(rc != MDBX_SUCCESS)) { @@ -26567,9 +26563,9 @@ __cold const char *pagetype_caption(const uint8_t type, char buf4unknown[16]) { __cold static const char *leafnode_type(node_t *n) { static const char *const tp[2][2] = {{"", ": DB"}, {": sub-page", ": sub-DB"}}; - return (node_flags(n) & N_BIGDATA) + return (node_flags(n) & N_BIG) ? ": large page" - : tp[!!(node_flags(n) & N_DUPDATA)][!!(node_flags(n) & N_SUBDATA)]; + : tp[!!(node_flags(n) & N_DUP)][!!(node_flags(n) & N_TREE)]; } /* Display all the keys in the page. */ @@ -26629,7 +26625,7 @@ __cold void page_list(page_t *mp) { DKEY(&key)); total += nsize; } else { - if (node_flags(node) & N_BIGDATA) + if (node_flags(node) & N_BIG) nsize += sizeof(pgno_t); else nsize += node_ds(node); @@ -27241,7 +27237,7 @@ __cold int meta_validate(MDBX_env *env, meta_t *const meta, return MDBX_INCOMPATIBLE; } - if (unlikely(!check_sdb_flags(meta->trees.main.flags))) { + if (unlikely(!check_table_flags(meta->trees.main.flags))) { WARNING("meta[%u] has invalid %s flags 0x%x, skip it", meta_number, "MainDB", meta->trees.main.flags); return MDBX_INCOMPATIBLE; @@ -27487,7 +27483,7 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, return rc; if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) { - rc = sdb_fetch(txn, dbi); + rc = tbl_fetch(txn, dbi); if (unlikely(rc != MDBX_SUCCESS)) return rc; } @@ -27529,9 +27525,9 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, * - изменить семантику установки/обновления mod_txnid, привязав его * строго к изменению b-tree, но не атрибутов; * - обновлять mod_txnid при фиксации вложенных транзакций; - * - для dbi-хендлов пользовательских subDb (видимо) можно оставить + * - для dbi-хендлов пользовательских table (видимо) можно оставить * DBI_DIRTY в качестве признака необходимости обновления записи - * subDb в MainDB, при этом взводить DBI_DIRTY вместе с обновлением + * table в MainDB, при этом взводить DBI_DIRTY вместе с обновлением * mod_txnid, в том числе при обновлении sequence. * - для MAIN_DBI при обновлении sequence не следует взводить DBI_DIRTY * и/или обновлять mod_txnid, а только взводить MDBX_TXN_DIRTY. @@ -27608,7 +27604,7 @@ __cold const char *mdbx_liberr2str(int errnum) { "MDBX_BAD_TXN: Transaction is not valid for requested operation," " e.g. had errored and be must aborted, has a child, or is invalid", "MDBX_BAD_VALSIZE: Invalid size or alignment of key or data" - " for target database, either invalid subDB name", + " for target database, either invalid table name", "MDBX_BAD_DBI: The specified DBI-handle is invalid" " or changed by another thread/transaction", "MDBX_PROBLEM: Unexpected internal error, transaction should be aborted", @@ -27651,7 +27647,7 @@ __cold const char *mdbx_liberr2str(int errnum) { " please keep one and remove unused other"; case MDBX_DANGLING_DBI: return "MDBX_DANGLING_DBI: Some cursors and/or other resources should be" - " closed before subDb or corresponding DBI-handle could be (re)used"; + " closed before table or corresponding DBI-handle could be (re)used"; case MDBX_OUSTED: return "MDBX_OUSTED: The parked read transaction was outed for the sake" " of recycling old MVCC snapshots"; @@ -28443,7 +28439,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, page_t *largepage = nullptr; size_t node_bytes; - if (unlikely(flags & N_BIGDATA)) { + if (unlikely(flags & N_BIG)) { /* Data already on large/overflow page. */ STATIC_ASSERT(sizeof(pgno_t) % 2 == 0); node_bytes = @@ -28456,7 +28452,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, mc->tree->flags); return MDBX_PROBLEM; } - if (unlikely(flags & (N_DUPDATA | N_SUBDATA))) { + if (unlikely(flags & (N_DUP | N_TREE))) { ERROR("Unexpected target %s flags 0x%x for large data-item", "node", flags); return MDBX_PROBLEM; @@ -28470,7 +28466,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, DEBUG("allocated %u large/overflow page(s) %" PRIaPGNO "for %" PRIuPTR " data bytes", largepage->pages, largepage->pgno, data->iov_len); - flags |= N_BIGDATA; + flags |= N_BIG; node_bytes = node_size_len(key->iov_len, 0) + sizeof(pgno_t) + sizeof(indx_t); cASSERT(mc, node_bytes == leaf_size(mc->txn->env, key, data)); @@ -28506,7 +28502,7 @@ __hot int __must_check_result node_add_leaf(MDBX_cursor *mc, size_t indx, void *nodedata = node_data(node); if (likely(largepage == nullptr)) { - if (unlikely(flags & N_BIGDATA)) { + if (unlikely(flags & N_BIG)) { memcpy(nodedata, data->iov_base, sizeof(pgno_t)); return MDBX_SUCCESS; } @@ -28548,8 +28544,7 @@ __hot void node_del(MDBX_cursor *mc, size_t ksize) { cASSERT(mc, !is_branch(mp) || hole || node_ks(node) == 0); size_t hole_size = NODESIZE + node_ks(node); if (is_leaf(mp)) - hole_size += - (node_flags(node) & N_BIGDATA) ? sizeof(pgno_t) : node_ds(node); + hole_size += (node_flags(node) & N_BIG) ? sizeof(pgno_t) : node_ds(node); hole_size = EVEN_CEIL(hole_size); const indx_t hole_offset = mp->entries[hole]; @@ -28579,7 +28574,7 @@ __hot void node_del(MDBX_cursor *mc, size_t ksize) { __noinline int node_read_bigdata(MDBX_cursor *mc, const node_t *node, MDBX_val *data, const page_t *mp) { - cASSERT(mc, node_flags(node) == N_BIGDATA && data->iov_len == node_ds(node)); + cASSERT(mc, node_flags(node) == N_BIG && data->iov_len == node_ds(node)); pgr_t lp = page_get_large(mc, node_largedata_pgno(node), mp->txnid); if (unlikely((lp.err != MDBX_SUCCESS))) { @@ -32637,17 +32632,17 @@ __cold int page_check(const MDBX_cursor *const mc, const page_t *const mp) { rc = bad_page(mp, "invalid node[%zu] flags (%u)\n", i, node_flags(node)); break; - case N_BIGDATA /* data on large-page */: + case N_BIG /* data on large-page */: case 0 /* usual */: - case N_SUBDATA /* sub-db */: - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: - case N_DUPDATA /* short sub-page */: + case N_TREE /* sub-db */: + case N_TREE | N_DUP /* dupsorted sub-tree */: + case N_DUP /* short sub-page */: break; } const size_t dsize = node_ds(node); const char *const data = node_data(node); - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { if (unlikely(end_of_page < data + sizeof(pgno_t))) { rc = bad_page( mp, "node-%s(%zu of %zu, %zu bytes) beyond (%zu) page-end\n", @@ -32704,20 +32699,20 @@ __cold int page_check(const MDBX_cursor *const mc, const page_t *const mp) { continue; } break; - case N_SUBDATA /* sub-db */: + case N_TREE /* sub-db */: if (unlikely(dsize != sizeof(tree_t))) { rc = bad_page(mp, "invalid sub-db record size (%zu)\n", dsize); continue; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(dsize != sizeof(tree_t))) { rc = bad_page(mp, "invalid nested-db record size (%zu, expect %zu)\n", dsize, sizeof(tree_t)); continue; } break; - case N_DUPDATA /* short sub-page */: + case N_DUP /* short sub-page */: if (unlikely(dsize <= PAGEHDRSZ)) { rc = bad_page(mp, "invalid nested/sub-page record size (%zu)\n", dsize); @@ -34001,7 +33996,7 @@ __hot int tree_search(MDBX_cursor *mc, const MDBX_val *key, int flags) { const size_t dbi = cursor_dbi(mc); if (unlikely(*cursor_dbi_state(mc) & DBI_STALE)) { - err = sdb_fetch(mc->txn, dbi); + err = tbl_fetch(mc->txn, dbi); if (unlikely(err != MDBX_SUCCESS)) goto bailout; } @@ -35081,7 +35076,7 @@ static size_t spill_cursor_keep(const MDBX_txn *const txn, tASSERT(txn, is_leaf(mp)); if (!mc->subcur || mc->ki[mc->top] >= page_numkeys(mp)) break; - if (!(node_flags(page_node(mp, mc->ki[mc->top])) & N_SUBDATA)) + if (!(node_flags(page_node(mp, mc->ki[mc->top])) & N_TREE)) break; mc = &mc->subcur->cursor; } @@ -35468,8 +35463,8 @@ __cold int spill_slowpath(MDBX_txn *const txn, MDBX_cursor *const m0, /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -int sdb_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { - if (unlikely(!check_sdb_flags(db->flags))) { +int tbl_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { + if (unlikely(!check_table_flags(db->flags))) { ERROR("incompatible or invalid db.flags (0x%x) ", db->flags); return MDBX_INCOMPATIBLE; } @@ -35496,7 +35491,7 @@ int sdb_setup(const MDBX_env *env, kvx_t *const kvx, const tree_t *const db) { return MDBX_SUCCESS; } -int sdb_fetch(MDBX_txn *txn, size_t dbi) { +int tbl_fetch(MDBX_txn *txn, size_t dbi) { cursor_couple_t couple; int rc = cursor_init(&couple.outer, txn, MAIN_DBI); if (unlikely(rc != MDBX_SUCCESS)) @@ -35506,7 +35501,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { rc = tree_search(&couple.outer, &kvx->name, 0); if (unlikely(rc != MDBX_SUCCESS)) { bailout: - NOTICE("dbi %zu refs to inaccessible subDB `%*s` for txn %" PRIaTXN + NOTICE("dbi %zu refs to inaccessible table `%*s` for txn %" PRIaTXN " (err %d)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, rc); @@ -35519,8 +35514,8 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { rc = MDBX_NOTFOUND; goto bailout; } - if (unlikely((node_flags(nsr.node) & (N_DUPDATA | N_SUBDATA)) != N_SUBDATA)) { - NOTICE("dbi %zu refs to not a named subDB `%*s` for txn %" PRIaTXN " (%s)", + if (unlikely((node_flags(nsr.node) & (N_DUP | N_TREE)) != N_TREE)) { + NOTICE("dbi %zu refs to not a named table `%*s` for txn %" PRIaTXN " (%s)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, "wrong flags"); return MDBX_INCOMPATIBLE; /* not a named DB */ @@ -35532,7 +35527,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { return rc; if (unlikely(data.iov_len != sizeof(tree_t))) { - NOTICE("dbi %zu refs to not a named subDB `%*s` for txn %" PRIaTXN " (%s)", + NOTICE("dbi %zu refs to not a named table `%*s` for txn %" PRIaTXN " (%s)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, "wrong rec-size"); return MDBX_INCOMPATIBLE; /* not a named DB */ @@ -35543,7 +35538,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { * have dropped and recreated the DB with other flags. */ tree_t *const db = &txn->dbs[dbi]; if (unlikely((db->flags & DB_PERSISTENT_FLAGS) != flags)) { - NOTICE("dbi %zu refs to the re-created subDB `%*s` for txn %" PRIaTXN + NOTICE("dbi %zu refs to the re-created table `%*s` for txn %" PRIaTXN " with different flags (present 0x%X != wanna 0x%X)", dbi, (int)kvx->name.iov_len, (const char *)kvx->name.iov_base, txn->txnid, db->flags & DB_PERSISTENT_FLAGS, flags); @@ -35560,7 +35555,7 @@ int sdb_fetch(MDBX_txn *txn, size_t dbi) { return MDBX_CORRUPTED; } #endif /* !MDBX_DISABLE_VALIDATION */ - rc = sdb_setup(txn->env, kvx, db); + rc = tbl_setup(txn->env, kvx, db); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -36226,15 +36221,15 @@ void recalculate_merge_thresholds(MDBX_env *env) { : bytes / 4 /* 25 % */)); } -int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { +int tree_drop(MDBX_cursor *mc, const bool may_have_tables) { MDBX_txn *txn = mc->txn; int rc = tree_search(mc, nullptr, Z_FIRST); if (likely(rc == MDBX_SUCCESS)) { - /* DUPSORT sub-DBs have no large-pages/subDBs. Omit scanning leaves. + /* DUPSORT sub-DBs have no large-pages/tables. Omit scanning leaves. * This also avoids any P_DUPFIX pages, which have no nodes. * Also if the DB doesn't have sub-DBs and has no large/overflow * pages, omit scanning leaves. */ - if (!(may_have_subDBs | mc->tree->large_pages)) + if (!(may_have_tables | mc->tree->large_pages)) cursor_pop(mc); rc = pnl_need(&txn->tw.retired_pages, (size_t)mc->tree->branch_pages + @@ -36254,15 +36249,15 @@ int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { cASSERT(mc, mc->top + 1 == mc->tree->height); for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - if (node_flags(node) & N_BIGDATA) { + if (node_flags(node) & N_BIG) { rc = page_retire_ex(mc, node_largedata_pgno(node), nullptr, 0); if (unlikely(rc != MDBX_SUCCESS)) goto bailout; - if (!(may_have_subDBs | mc->tree->large_pages)) + if (!(may_have_tables | mc->tree->large_pages)) goto pop; - } else if (node_flags(node) & N_SUBDATA) { - if (unlikely((node_flags(node) & N_DUPDATA) == 0)) { - rc = /* disallowing implicit subDB deletion */ MDBX_INCOMPATIBLE; + } else if (node_flags(node) & N_TREE) { + if (unlikely((node_flags(node) & N_DUP) == 0)) { + rc = /* disallowing implicit table deletion */ MDBX_INCOMPATIBLE; goto bailout; } rc = cursor_dupsort_setup(mc, node, mp); @@ -36282,8 +36277,7 @@ int tree_drop(MDBX_cursor *mc, const bool may_have_subDBs) { : P_BRANCH); for (size_t i = 0; i < nkeys; i++) { node_t *node = page_node(mp, i); - tASSERT(txn, (node_flags(node) & - (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + tASSERT(txn, (node_flags(node) & (N_BIG | N_TREE | N_DUP)) == 0); const pgno_t pgno = node_pgno(node); rc = page_retire_ex(mc, pgno, nullptr, pagetype); if (unlikely(rc != MDBX_SUCCESS)) @@ -37417,8 +37411,8 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, node_t *node = ptr_disp(mp, tmp_ki_copy->entries[i] + PAGEHDRSZ); size = NODESIZE + node_ks(node) + sizeof(indx_t); if (is_leaf(mp)) - size += (node_flags(node) & N_BIGDATA) ? sizeof(pgno_t) - : node_ds(node); + size += + (node_flags(node) & N_BIG) ? sizeof(pgno_t) : node_ds(node); size = EVEN_CEIL(size); } @@ -37562,7 +37556,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = node_add_leaf(mc, 0, newkey, newdata, naf); } break; case P_LEAF | P_DUPFIX: { - cASSERT(mc, (naf & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + cASSERT(mc, (naf & (N_BIG | N_TREE | N_DUP)) == 0); cASSERT(mc, newpgno == 0 || newpgno == P_INVALID); rc = node_add_dupfix(mc, 0, newkey); } break; @@ -37633,7 +37627,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = node_add_leaf(mc, n, &rkey, rdata, flags); } break; /* case P_LEAF | P_DUPFIX: { - cASSERT(mc, (nflags & (N_BIGDATA | N_SUBDATA | N_DUPDATA)) == 0); + cASSERT(mc, (nflags & (N_BIG | N_TREE | N_DUP)) == 0); cASSERT(mc, gno == 0); rc = mdbx_node_add_dupfix(mc, n, &rkey); } break; */ @@ -37745,7 +37739,7 @@ int page_split(MDBX_cursor *mc, const MDBX_val *const newkey, rc = cursor_check_updating(mc); if (unlikely(naf & MDBX_RESERVE)) { node_t *node = page_node(mc->pg[mc->top], mc->ki[mc->top]); - if (!(node_flags(node) & N_BIGDATA)) + if (!(node_flags(node) & N_BIG)) newdata->iov_base = node_data(node); } #if MDBX_ENABLE_PGOP_STAT @@ -38607,7 +38601,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { txn->dbs[FREE_DBI].root); if (txn->n_dbi > CORE_DBS) { - /* Update subDB root pointers */ + /* Update table root pointers */ cursor_couple_t cx; rc = cursor_init(&cx.outer, txn, MAIN_DBI); if (unlikely(rc != MDBX_SUCCESS)) @@ -38624,7 +38618,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) { /* Может быть mod_txnid > front после коммита вложенных тразакций */ db->mod_txnid = txn->txnid; MDBX_val data = {db, sizeof(tree_t)}; - rc = cursor_put(&cx.outer, &env->kvs[i].name, &data, N_SUBDATA); + rc = cursor_put(&cx.outer, &env->kvs[i].name, &data, N_TREE); if (unlikely(rc != MDBX_SUCCESS)) { txn->cursors[MAIN_DBI] = cx.outer.next; goto fail; @@ -38971,7 +38965,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { txn->txnid >= /* paranoia is appropriate here */ env->lck->cached_oldest.weak); tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); } else { eASSERT(env, (flags & ~(txn_rw_begin_flags | MDBX_TXN_SPILLS | MDBX_WRITEMAP | MDBX_NOSTICKYTHREADS)) == 0); @@ -39029,7 +39023,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); txn->flags = flags; txn->nested = nullptr; txn->tw.loose_pages = nullptr; @@ -39067,7 +39061,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { /* Setup db info */ tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); VALGRIND_MAKE_MEM_UNDEFINED(txn->dbi_state, env->max_dbi); #if MDBX_ENABLE_DBI_SPARSE txn->n_dbi = CORE_DBS; @@ -39118,7 +39112,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { txn->dbs[MAIN_DBI].flags); env->dbs_flags[MAIN_DBI] = DB_POISON; atomic_store32(&env->dbi_seqs[MAIN_DBI], seq, mo_AcquireRelease); - rc = sdb_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); + rc = tbl_setup(env, &env->kvs[MAIN_DBI], &txn->dbs[MAIN_DBI]); if (likely(rc == MDBX_SUCCESS)) { seq = dbi_seq_next(env, MAIN_DBI); env->dbs_flags[MAIN_DBI] = DB_VALID | txn->dbs[MAIN_DBI].flags; @@ -39151,7 +39145,7 @@ int txn_renew(MDBX_txn *txn, unsigned flags) { } tASSERT(txn, txn->dbs[FREE_DBI].flags == MDBX_INTEGERKEY); - tASSERT(txn, check_sdb_flags(txn->dbs[MAIN_DBI].flags)); + tASSERT(txn, check_table_flags(txn->dbs[MAIN_DBI].flags)); if (unlikely(env->flags & ENV_FATAL_ERROR)) { WARNING("%s", "environment had fatal error, must shutdown!"); rc = MDBX_PANIC; @@ -39992,7 +39986,7 @@ typedef struct walk_ctx { MDBX_cursor *cursor; } walk_ctx_t; -__cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb); +__cold static int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl); static page_type_t walk_page_type(const page_t *mp) { if (mp) @@ -40021,7 +40015,7 @@ 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_sdb_t *sdb, const pgno_t pgno, +__cold static int walk_pgno(walk_ctx_t *ctx, walk_tbl_t *tbl, const pgno_t pgno, txnid_t parent_txnid) { assert(pgno != P_INVALID); page_t *mp = nullptr; @@ -40062,7 +40056,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; break; - case N_BIGDATA /* long data on the large/overflow page */: { + case N_BIG /* long data on the large/overflow page */: { const pgno_t large_pgno = node_largedata_pgno(node); const size_t over_payload = node_data_size; const size_t over_header = PAGEHDRSZ; @@ -40074,7 +40068,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, 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, - sdb, pagesize, page_large, err, 1, + tbl, pagesize, page_large, err, 1, over_payload, over_header, over_unused); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; @@ -40082,10 +40076,10 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += node_key_size & 1; } break; - case N_SUBDATA /* sub-db */: { + case N_TREE /* sub-db */: { if (unlikely(node_data_size != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, - "invalid subDb node size", (unsigned)node_data_size); + "invalid table node size", (unsigned)node_data_size); assert(err == MDBX_CORRUPTED); err = MDBX_CORRUPTED; } @@ -40093,7 +40087,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(node_data_size != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-tree node size", (unsigned)node_data_size); @@ -40104,7 +40098,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, align_bytes += (node_key_size + node_data_size) & 1; break; - case N_DUPDATA /* short sub-page */: { + case N_DUP /* short sub-page */: { if (unlikely(node_data_size <= PAGEHDRSZ || (node_data_size & 1))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-page node size", (unsigned)node_data_size); @@ -40150,7 +40144,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } const int rc = - ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, sdb, + ctx->visitor(pgno, 0, ctx->userctx, ctx->deep + 1, tbl, node_data_size, subtype, err, nsubkeys, subpayload_size, subheader_size, subunused_size + subalign_bytes); if (unlikely(rc != MDBX_SUCCESS)) @@ -40170,7 +40164,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } const int rc = ctx->visitor( - pgno, 1, ctx->userctx, ctx->deep, sdb, ctx->txn->env->ps, type, err, + pgno, 1, ctx->userctx, ctx->deep, tbl, ctx->txn->env->ps, type, err, nentries, payload_size, header_size, unused_size + align_bytes); if (unlikely(rc != MDBX_SUCCESS)) return (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; @@ -40183,7 +40177,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, if (type == page_branch) { assert(err == MDBX_SUCCESS); ctx->deep += 1; - err = walk_pgno(ctx, sdb, node_pgno(node), mp->txnid); + err = walk_pgno(ctx, tbl, node_pgno(node), mp->txnid); ctx->deep -= 1; if (unlikely(err != MDBX_SUCCESS)) { if (err == MDBX_RESULT_TRUE) @@ -40198,7 +40192,7 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, default: continue; - case N_SUBDATA /* sub-db */: + case N_TREE /* sub-db */: if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid sub-tree node size", (unsigned)node_ds(node)); @@ -40207,16 +40201,16 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, } else { tree_t aligned_db; memcpy(&aligned_db, node_data(node), sizeof(aligned_db)); - walk_sdb_t subdb = {{node_key(node), node_ks(node)}, nullptr, nullptr}; - subdb.internal = &aligned_db; + walk_tbl_t table = {{node_key(node), node_ks(node)}, nullptr, nullptr}; + table.internal = &aligned_db; assert(err == MDBX_SUCCESS); ctx->deep += 1; - err = walk_sdb(ctx, &subdb); + err = walk_tbl(ctx, &table); ctx->deep -= 1; } break; - case N_SUBDATA | N_DUPDATA /* dupsorted sub-tree */: + case N_TREE | N_DUP /* dupsorted sub-tree */: if (unlikely(node_ds(node) != sizeof(tree_t))) { ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid dupsort sub-tree node size", (unsigned)node_ds(node)); @@ -40232,9 +40226,9 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, &container_of(ctx->cursor, cursor_couple_t, outer)->inner); ctx->cursor = &ctx->cursor->subcur->cursor; ctx->deep += 1; - sdb->nested = &aligned_db; - err = walk_pgno(ctx, sdb, aligned_db.root, mp->txnid); - sdb->nested = nullptr; + tbl->nested = &aligned_db; + err = walk_pgno(ctx, tbl, aligned_db.root, mp->txnid); + tbl->nested = nullptr; ctx->deep -= 1; subcur_t *inner_xcursor = container_of(ctx->cursor, subcur_t, cursor); cursor_couple_t *couple = @@ -40249,8 +40243,8 @@ __cold static int walk_pgno(walk_ctx_t *ctx, walk_sdb_t *sdb, const pgno_t pgno, return MDBX_SUCCESS; } -__cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb) { - tree_t *const db = sdb->internal; +__cold static int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl) { + tree_t *const db = tbl->internal; if (unlikely(db->root == P_INVALID)) return MDBX_SUCCESS; /* empty db */ @@ -40268,7 +40262,7 @@ __cold static int walk_sdb(walk_ctx_t *ctx, walk_sdb_t *sdb) { couple.outer.next = ctx->cursor; couple.outer.top_and_flags = z_disable_tree_search_fastpath; ctx->cursor = &couple.outer; - rc = walk_pgno(ctx, sdb, db->root, + rc = walk_pgno(ctx, tbl, db->root, db->mod_txnid ? db->mod_txnid : ctx->txn->txnid); ctx->cursor = couple.outer.next; return rc; @@ -40282,13 +40276,13 @@ __cold int walk_pages(MDBX_txn *txn, walk_func *visitor, void *user, walk_ctx_t ctx = { .txn = txn, .userctx = user, .visitor = visitor, .options = options}; - walk_sdb_t sdb = {.name = {.iov_base = MDBX_CHK_GC}, + walk_tbl_t tbl = {.name = {.iov_base = MDBX_CHK_GC}, .internal = &txn->dbs[FREE_DBI]}; - rc = walk_sdb(&ctx, &sdb); + rc = walk_tbl(&ctx, &tbl); if (!MDBX_IS_ERROR(rc)) { - sdb.name.iov_base = MDBX_CHK_MAIN; - sdb.internal = &txn->dbs[MAIN_DBI]; - rc = walk_sdb(&ctx, &sdb); + tbl.name.iov_base = MDBX_CHK_MAIN; + tbl.internal = &txn->dbs[MAIN_DBI]; + rc = walk_tbl(&ctx, &tbl); } return rc; } @@ -40481,9 +40475,9 @@ __dll_export 0, 13, 0, - 110, - {"2024-08-03T00:30:06+03:00", "0a032f804b7a1d447beb7394173f09fde8697a41", "dd0ee3f278552424190f2f0bf1e63779a10dece6", - "v0.13.0-110-gdd0ee3f2"}, + 115, + {"2024-08-03T15:14:23+03:00", "7a23f6614a32db727acc8a29d774445e47d31f3f", "7bff3b3df699ca761c79c7350808fc1fb7f1216d", + "v0.13.0-115-g7bff3b3d"}, sourcery}; __dll_export diff --git a/mdbxdist/mdbx.c++ b/mdbxdist/mdbx.c++ index de59ba8..c49e0ae 100644 --- a/mdbxdist/mdbx.c++ +++ b/mdbxdist/mdbx.c++ @@ -2,7 +2,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2519,11 +2519,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2554,10 +2554,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2586,9 +2586,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) diff --git a/mdbxdist/mdbx.h b/mdbxdist/mdbx.h index aa2989c..07d9ecf 100644 --- a/mdbxdist/mdbx.h +++ b/mdbxdist/mdbx.h @@ -68,7 +68,7 @@ credits and acknowledgments. \defgroup c_err Error handling \defgroup c_opening Opening & Closing \defgroup c_transactions Transactions - \defgroup c_dbi Databases + \defgroup c_dbi Tables \defgroup c_crud Create/Read/Update/Delete (see Quick Reference in details) \details @@ -79,9 +79,9 @@ Historically, libmdbx inherits the API basis from LMDB, where it is often difficult to select flags/options and functions for the desired operation. So it is recommend using this hints. -## Databases with UNIQUE keys +## Tables with UNIQUE keys -In databases created without the \ref MDBX_DUPSORT option, keys are always +In tables created without the \ref MDBX_DUPSORT option, keys are always unique. Thus always a single value corresponds to the each key, and so there are only a few cases of changing data. @@ -104,10 +104,10 @@ are only a few cases of changing data. |Extract (read & delete) value by the key |\ref mdbx_replace() with zero flag and parameter `new_data = NULL`|Returning a deleted value| -## Databases with NON-UNIQUE keys +## Tables with NON-UNIQUE keys -In databases created with the \ref MDBX_DUPSORT (Sorted Duplicates) option, keys -may be non unique. Such non-unique keys in a key-value database may be treated +In tables created with the \ref MDBX_DUPSORT (Sorted Duplicates) option, keys +may be non unique. Such non-unique keys in a key-value table may be treated as a duplicates or as like a multiple values corresponds to keys. @@ -713,8 +713,8 @@ void LIBMDBX_API NTAPI mdbx_module_handler(PVOID module, DWORD reason, /* OPACITY STRUCTURES *********************************************************/ /** \brief Opaque structure for a database environment. - * \details An environment supports multiple key-value sub-databases (aka - * key-value spaces or tables), all residing in the same shared-memory map. + * \details An environment supports multiple key-value tables (aka key-value + * maps, spaces or sub-databases), all residing in the same shared-memory map. * \see mdbx_env_create() \see mdbx_env_close() */ #ifndef __cplusplus typedef struct MDBX_env MDBX_env; @@ -724,7 +724,7 @@ struct MDBX_env; /** \brief Opaque structure for a transaction handle. * \ingroup c_transactions - * \details All database operations require a transaction handle. Transactions + * \details All table operations require a transaction handle. Transactions * may be read-only or read-write. * \see mdbx_txn_begin() \see mdbx_txn_commit() \see mdbx_txn_abort() */ #ifndef __cplusplus @@ -733,16 +733,16 @@ typedef struct MDBX_txn MDBX_txn; struct MDBX_txn; #endif -/** \brief A handle for an individual database (key-value spaces) in the +/** \brief A handle for an individual table (key-value spaces) in the * environment. * \ingroup c_dbi - * \details Zero handle is used internally (hidden Garbage Collection subDB). + * \details Zero handle is used internally (hidden Garbage Collection table). * So, any valid DBI-handle great than 0 and less than or equal * \ref MDBX_MAX_DBI. * \see mdbx_dbi_open() \see mdbx_dbi_close() */ typedef uint32_t MDBX_dbi; -/** \brief Opaque structure for navigating through a database +/** \brief Opaque structure for navigating through a table * \ingroup c_cursors * \see mdbx_cursor_create() \see mdbx_cursor_bind() \see mdbx_cursor_close() */ @@ -753,15 +753,15 @@ struct MDBX_cursor; #endif /** \brief Generic structure used for passing keys and data in and out of the - * database. + * table. * \anchor MDBX_val \see mdbx::slice \see mdbx::buffer * - * \details Values returned from the database are valid only until a subsequent + * \details Values returned from the table are valid only until a subsequent * update operation, or the end of the transaction. Do not modify or * free them, they commonly point into the database itself. * * Key sizes must be between 0 and \ref mdbx_env_get_maxkeysize() inclusive. - * The same applies to data sizes in databases with the \ref MDBX_DUPSORT flag. + * The same applies to data sizes in tables with the \ref MDBX_DUPSORT flag. * Other data items can in theory be from 0 to \ref MDBX_MAXDATASIZE bytes long. * * \note The notable difference between MDBX and LMDB is that MDBX support zero @@ -1607,7 +1607,7 @@ typedef enum MDBX_txn_flags { } MDBX_txn_flags_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_txn_flags) -/** \brief Database flags +/** \brief Table flags * \ingroup c_dbi * \anchor db_flags * \see mdbx_dbi_open() */ @@ -1643,15 +1643,15 @@ typedef enum MDBX_db_flags { /** Create DB if not already existing. */ MDBX_CREATE = UINT32_C(0x40000), - /** Opens an existing sub-database created with unknown flags. + /** Opens an existing table created with unknown flags. * - * The `MDBX_DB_ACCEDE` flag is intend to open a existing sub-database which + * The `MDBX_DB_ACCEDE` flag is intend to open a existing table which * was created with unknown flags (\ref MDBX_REVERSEKEY, \ref MDBX_DUPSORT, * \ref MDBX_INTEGERKEY, \ref MDBX_DUPFIXED, \ref MDBX_INTEGERDUP and * \ref MDBX_REVERSEDUP). * * In such cases, instead of returning the \ref MDBX_INCOMPATIBLE error, the - * sub-database will be opened with flags which it was created, and then an + * table will be opened with flags which it was created, and then an * application could determine the actual flags by \ref mdbx_dbi_flags(). */ MDBX_DB_ACCEDE = MDBX_ACCEDE } MDBX_db_flags_t; @@ -1668,7 +1668,7 @@ typedef enum MDBX_put_flags { /** For insertion: Don't write if the key already exists. */ MDBX_NOOVERWRITE = UINT32_C(0x10), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * For upsertion: don't write if the key-value pair already exist. */ MDBX_NODUPDATA = UINT32_C(0x20), @@ -1678,7 +1678,7 @@ typedef enum MDBX_put_flags { * For deletion: remove only single entry at the current cursor position. */ MDBX_CURRENT = UINT32_C(0x40), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * For deletion: remove all multi-values (aka duplicates) for given key. * For upsertion: replace all multi-values for given key with a new one. */ MDBX_ALLDUPS = UINT32_C(0x80), @@ -1691,7 +1691,7 @@ typedef enum MDBX_put_flags { * Don't split full pages, continue on a new instead. */ MDBX_APPEND = UINT32_C(0x20000), - /** Has effect only for \ref MDBX_DUPSORT databases. + /** Has effect only for \ref MDBX_DUPSORT tables. * Duplicate data is being appended. * Don't split full pages, continue on a new instead. */ MDBX_APPENDDUP = UINT32_C(0x40000), @@ -1920,14 +1920,14 @@ typedef enum MDBX_error { * or explicit call of \ref mdbx_env_set_geometry(). */ MDBX_UNABLE_EXTEND_MAPSIZE = -30785, - /** Environment or database is not compatible with the requested operation + /** Environment or table is not compatible with the requested operation * or the specified flags. This can mean: * - The operation expects an \ref MDBX_DUPSORT / \ref MDBX_DUPFIXED - * database. + * table. * - Opening a named DB when the unnamed DB has \ref MDBX_DUPSORT / * \ref MDBX_INTEGERKEY. - * - Accessing a data record as a database, or vice versa. - * - The database was dropped and recreated with different flags. */ + * - Accessing a data record as a named table, or vice versa. + * - The table was dropped and recreated with different flags. */ MDBX_INCOMPATIBLE = -30784, /** Invalid reuse of reader locktable slot, @@ -1939,8 +1939,8 @@ typedef enum MDBX_error { * or is invalid */ MDBX_BAD_TXN = -30782, - /** Invalid size or alignment of key or data for target database, - * either invalid subDB name */ + /** Invalid size or alignment of key or data for target table, + * either invalid table name */ MDBX_BAD_VALSIZE = -30781, /** The specified DBI-handle is invalid @@ -1995,7 +1995,7 @@ typedef enum MDBX_error { /** Alternative/Duplicate LCK-file is exists and should be removed manually */ MDBX_DUPLICATED_CLK = -30413, - /** Some cursors and/or other resources should be closed before subDb or + /** Some cursors and/or other resources should be closed before table or * corresponding DBI-handle could be (re)used */ MDBX_DANGLING_DBI = -30412, @@ -2134,11 +2134,11 @@ LIBMDBX_API int mdbx_env_create(MDBX_env **penv); * \ingroup c_settings * \see mdbx_env_set_option() \see mdbx_env_get_option() */ typedef enum MDBX_option { - /** \brief Controls the maximum number of named databases for the environment. + /** \brief Controls the maximum number of named tables for the environment. * - * \details By default only unnamed key-value database could used and + * \details By default only unnamed key-value table could used and * appropriate value should set by `MDBX_opt_max_db` to using any more named - * subDB(s). To reduce overhead, use the minimum sufficient value. This option + * table(s). To reduce overhead, use the minimum sufficient value. This option * may only set after \ref mdbx_env_create() and before \ref mdbx_env_open(). * * \see mdbx_env_set_maxdbs() \see mdbx_env_get_maxdbs() */ @@ -2587,6 +2587,7 @@ LIBMDBX_API int mdbx_env_delete(const char *pathname, #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_delete() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_delete() */ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathname, @@ -2627,6 +2628,24 @@ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathname, * - \ref MDBX_CP_FORCE_DYNAMIC_SIZE * Force to make resizable copy, i.e. dynamic size instead of fixed. * + * - \ref MDBX_CP_DONT_FLUSH + * Don't explicitly flush the written data to an output media to reduce + * the time of the operation and the duration of the transaction. + * + * - \ref MDBX_CP_THROTTLE_MVCC + * Use read transaction parking during copying MVCC-snapshot + * to avoid stopping recycling and overflowing the database. + * This allows the writing transaction to oust the read + * transaction used to copy the database if copying takes so long + * that it will interfere with the recycling old MVCC snapshots + * and may lead to an overflow of the database. + * However, if the reading transaction is ousted the copy will + * be aborted until successful completion. Thus, this option + * allows copy the database without interfering with write + * transactions and a threat of database overflow, but at the cost + * that copying will be aborted to prevent such conditions. + * \see mdbx_txn_park() + * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest, MDBX_copy_flags_t flags); @@ -2665,18 +2684,38 @@ LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest, * - \ref MDBX_CP_FORCE_DYNAMIC_SIZE * Force to make resizable copy, i.e. dynamic size instead of fixed. * + * - \ref MDBX_CP_DONT_FLUSH + * Don't explicitly flush the written data to an output media to reduce + * the time of the operation and the duration of the transaction. + * + * - \ref MDBX_CP_THROTTLE_MVCC + * Use read transaction parking during copying MVCC-snapshot + * to avoid stopping recycling and overflowing the database. + * This allows the writing transaction to oust the read + * transaction used to copy the database if copying takes so long + * that it will interfere with the recycling old MVCC snapshots + * and may lead to an overflow of the database. + * However, if the reading transaction is ousted the copy will + * be aborted until successful completion. Thus, this option + * allows copy the database without interfering with write + * transactions and a threat of database overflow, but at the cost + * that copying will be aborted to prevent such conditions. + * \see mdbx_txn_park() + * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest, MDBX_copy_flags_t flags); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_copy() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_copy() */ LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest, MDBX_copy_flags_t flags); /** \copydoc mdbx_txn_copy2pathname() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_txn_copy2pathname() */ LIBMDBX_API int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest, @@ -2736,12 +2775,12 @@ LIBMDBX_API int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, LIBMDBX_API int mdbx_txn_copy2fd(MDBX_txn *txn, mdbx_filehandle_t fd, MDBX_copy_flags_t flags); -/** \brief Statistics for a database in the environment +/** \brief Statistics for a table in the environment * \ingroup c_statinfo * \see mdbx_env_stat_ex() \see mdbx_dbi_stat() */ struct MDBX_stat { - uint32_t ms_psize; /**< Size of a database page. This is the same for all - databases. */ + uint32_t ms_psize; /**< Size of a table page. This is the same for all tables + in a database. */ uint32_t ms_depth; /**< Depth (height) of the B-tree */ uint64_t ms_branch_pages; /**< Number of internal (non-leaf) pages */ uint64_t ms_leaf_pages; /**< Number of leaf pages */ @@ -3081,7 +3120,7 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_syncperiod, /** \brief Close the environment and release the memory map. * \ingroup c_opening * - * Only a single thread may call this function. All transactions, databases, + * Only a single thread may call this function. All transactions, tables, * and cursors must already be closed before calling this function. Attempts * to use any such handles after calling this function is UB and would cause * a `SIGSEGV`. The environment handle will be freed and must not be used again @@ -3240,7 +3279,7 @@ typedef enum MDBX_warmup_flags { * On successful, all currently allocated pages, both unused in GC and * containing payload, will be locked in memory until the environment closes, * or explicitly unblocked by using \ref MDBX_warmup_release, or the - * database geomenry will changed, including its auto-shrinking. */ + * database geometry will changed, including its auto-shrinking. */ MDBX_warmup_lock = 4, /** Alters corresponding current resource limits to be enough for lock pages @@ -3256,8 +3295,9 @@ typedef enum MDBX_warmup_flags { } MDBX_warmup_flags_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_warmup_flags) -/** \brief Warms up the database by loading pages into memory, optionally lock - * ones. \ingroup c_settings +/** \brief Warms up the database by loading pages into memory, + * optionally lock ones. + * \ingroup c_settings * * Depending on the specified flags, notifies OS kernel about following access, * force loads the database pages, including locks ones in memory or releases @@ -3342,6 +3382,7 @@ LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_get_path() + * \ingroup c_statinfo * \note Available only on Windows. * \see mdbx_env_get_path() */ LIBMDBX_API int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **dest); @@ -3615,40 +3656,40 @@ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_dbsize_max(intptr_t pagesize); /** \brief Returns maximal key size in bytes for given page size - * and database flags, or -1 if pagesize is invalid. + * and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_max(intptr_t pagesize, MDBX_db_flags_t flags); -/** \brief Returns minimal key size in bytes for given database flags. +/** \brief Returns minimal key size in bytes for given table flags. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_keysize_min(MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes for given page size - * and database flags, or -1 if pagesize is invalid. + * and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_max(intptr_t pagesize, MDBX_db_flags_t flags); -/** \brief Returns minimal data size in bytes for given database flags. +/** \brief Returns minimal data size in bytes for given table flags. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_valsize_min(MDBX_db_flags_t flags); /** \brief Returns maximal size of key-value pair to fit in a single page with - * the given size and database flags, or -1 if pagesize is invalid. + * the given size and table flags, or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API intptr_t mdbx_limits_pairsize4page_max(intptr_t pagesize, MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes to fit in a leaf-page or - * single large/overflow-page with the given page size and database flags, + * single large/overflow-page with the given page size and table flags, * or -1 if pagesize is invalid. * \ingroup c_statinfo * \see db_flags */ @@ -3711,12 +3752,12 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_maxreaders, return rc; } -/** \brief Set the maximum number of named databases for the environment. +/** \brief Set the maximum number of named tables for the environment. * \ingroup c_settings * - * This function is only needed if multiple databases will be used in the + * This function is only needed if multiple tables will be used in the * environment. Simpler applications that use the environment as a single - * unnamed database can ignore this option. + * unnamed table can ignore this option. * This function may only be called after \ref mdbx_env_create() and before * \ref mdbx_env_open(). * @@ -3726,7 +3767,7 @@ LIBMDBX_INLINE_API(int, mdbx_env_get_maxreaders, * \see mdbx_env_get_maxdbs() * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] dbs The maximum number of databases. + * \param [in] dbs The maximum number of tables. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: @@ -3736,12 +3777,12 @@ LIBMDBX_INLINE_API(int, mdbx_env_set_maxdbs, (MDBX_env * env, MDBX_dbi dbs)) { return mdbx_env_set_option(env, MDBX_opt_max_db, dbs); } -/** \brief Get the maximum number of named databases for the environment. +/** \brief Get the maximum number of named tables for the environment. * \ingroup c_statinfo * \see mdbx_env_set_maxdbs() * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [out] dbs Address to store the maximum number of databases. + * \param [out] dbs Address to store the maximum number of tables. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: @@ -3784,7 +3825,7 @@ LIBMDBX_API int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages, * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a key can write, @@ -3796,7 +3837,7 @@ mdbx_env_get_maxkeysize_ex(const MDBX_env *env, MDBX_db_flags_t flags); * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -3811,11 +3852,11 @@ MDBX_DEPRECATED MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_maxkeysize(const MDBX_env *env); /** \brief Returns maximal size of key-value pair to fit in a single page - * for specified database flags. + * for specified table flags. * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -3824,11 +3865,11 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_env_get_pairsize4page_max(const MDBX_env *env, MDBX_db_flags_t flags); /** \brief Returns maximal data size in bytes to fit in a leaf-page or - * single large/overflow-page for specified database flags. + * single large/overflow-page for specified table flags. * \ingroup c_statinfo * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] flags Database options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY + * \param [in] flags Table options (\ref MDBX_DUPSORT, \ref MDBX_INTEGERKEY * and so on). \see db_flags * * \returns The maximum size of a data can write, @@ -4113,7 +4154,7 @@ mdbx_txn_id(const MDBX_txn *txn); * \see mdbx_txn_commit_ex() */ struct MDBX_commit_latency { /** \brief Duration of preparation (commit child transactions, update - * sub-databases records and cursors destroying). */ + * table's records and cursors destroying). */ uint32_t preparation; /** \brief Duration of GC update by wall clock. */ uint32_t gc_wallclock; @@ -4495,7 +4536,7 @@ LIBMDBX_API int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary); * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary); -/** \brief A callback function used to compare two keys in a database +/** \brief A callback function used to compare two keys in a table * \ingroup c_crud * \see mdbx_cmp() \see mdbx_get_keycmp() * \see mdbx_get_datacmp \see mdbx_dcmp() @@ -4518,23 +4559,23 @@ LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary); typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b) MDBX_CXX17_NOEXCEPT; -/** \brief Open or Create a database in the environment. +/** \brief Open or Create a named table in the environment. * \ingroup c_dbi * - * A database handle denotes the name and parameters of a database, - * independently of whether such a database exists. The database handle may be - * discarded by calling \ref mdbx_dbi_close(). The old database handle is - * returned if the database was already open. The handle may only be closed + * A table handle denotes the name and parameters of a table, + * independently of whether such a table exists. The table handle may be + * discarded by calling \ref mdbx_dbi_close(). The old table handle is + * returned if the table was already open. The handle may only be closed * once. * * \note A notable difference between MDBX and LMDB is that MDBX make handles - * opened for existing databases immediately available for other transactions, + * opened for existing tables immediately available for other transactions, * regardless this transaction will be aborted or reset. The REASON for this is * to avoiding the requirement for multiple opening a same handles in * concurrent read transactions, and tracking of such open but hidden handles * until the completion of read transactions which opened them. * - * Nevertheless, the handle for the NEWLY CREATED database will be invisible + * Nevertheless, the handle for the NEWLY CREATED table will be invisible * for other transactions until the this write transaction is successfully * committed. If the write transaction is aborted the handle will be closed * automatically. After a successful commit the such handle will reside in the @@ -4543,15 +4584,15 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * In contrast to LMDB, the MDBX allow this function to be called from multiple * concurrent transactions or threads in the same process. * - * To use named database (with name != NULL), \ref mdbx_env_set_maxdbs() + * To use named table (with name != NULL), \ref mdbx_env_set_maxdbs() * must be called before opening the environment. Table names are - * keys in the internal unnamed database, and may be read but not written. + * keys in the internal unnamed table, and may be read but not written. * * \param [in] txn transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] name The name of the database to open. If only a single - * database is needed in the environment, + * \param [in] name The name of the table to open. If only a single + * table is needed in the environment, * this value may be NULL. - * \param [in] flags Special options for this database. This parameter must + * \param [in] flags Special options for this table. This parameter must * be bitwise OR'ing together any of the constants * described here: * @@ -4565,12 +4606,12 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * uint64_t, and will be sorted as such. The keys must all be of the * same size and must be aligned while passing as arguments. * - \ref MDBX_DUPSORT - * Duplicate keys may be used in the database. Or, from another point of + * Duplicate keys may be used in the table. Or, from another point of * view, keys may have multiple data items, stored in sorted order. By * default keys must be unique and may have only a single data item. * - \ref MDBX_DUPFIXED * This flag may only be used in combination with \ref MDBX_DUPSORT. This - * option tells the library that the data items for this database are + * option tells the library that the data items for this table are * all the same size, which allows further optimizations in storage and * retrieval. When all data items are the same size, the * \ref MDBX_GET_MULTIPLE, \ref MDBX_NEXT_MULTIPLE and @@ -4585,7 +4626,7 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * strings in reverse order (the comparison is performed in the direction * from the last byte to the first). * - \ref MDBX_CREATE - * Create the named database if it doesn't exist. This option is not + * Create the named table if it doesn't exist. This option is not * allowed in a read-only transaction or a read-only environment. * * \param [out] dbi Address where the new \ref MDBX_dbi handle @@ -4597,61 +4638,66 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: - * \retval MDBX_NOTFOUND The specified database doesn't exist in the + * \retval MDBX_NOTFOUND The specified table doesn't exist in the * environment and \ref MDBX_CREATE was not specified. - * \retval MDBX_DBS_FULL Too many databases have been opened. + * \retval MDBX_DBS_FULL Too many tables have been opened. * \see mdbx_env_set_maxdbs() - * \retval MDBX_INCOMPATIBLE Database is incompatible with given flags, + * \retval MDBX_INCOMPATIBLE Table is incompatible with given flags, * i.e. the passed flags is different with which the - * database was created, or the database was already + * table was created, or the table was already * opened with a different comparison function(s). * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. */ LIBMDBX_API int mdbx_dbi_open(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, MDBX_dbi *dbi); -/** \copydoc mdbx_dbi_open() */ +/** \copydoc mdbx_dbi_open() + * \ingroup c_dbi */ LIBMDBX_API int mdbx_dbi_open2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, MDBX_dbi *dbi); -/** \deprecated Please - * \ref avoid_custom_comparators "avoid using custom comparators" and use - * \ref mdbx_dbi_open() instead. - * +/** \brief Open or Create a named table in the environment + * with using custom comparison functions. * \ingroup c_dbi * + * \deprecated Please \ref avoid_custom_comparators + * "avoid using custom comparators" and use \ref mdbx_dbi_open() instead. + * * \param [in] txn transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] name The name of the database to open. If only a single - * database is needed in the environment, + * \param [in] name The name of the table to open. If only a single + * table is needed in the environment, * this value may be NULL. - * \param [in] flags Special options for this database. - * \param [in] keycmp Optional custom key comparison function for a database. - * \param [in] datacmp Optional custom data comparison function for a database. + * \param [in] flags Special options for this table. + * \param [in] keycmp Optional custom key comparison function for a table. + * \param [in] datacmp Optional custom data comparison function for a table. * \param [out] dbi Address where the new MDBX_dbi handle will be stored. * \returns A non-zero error value on failure and 0 on success. */ MDBX_DEPRECATED LIBMDBX_API int mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags, MDBX_dbi *dbi, MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp); -/** \copydoc mdbx_dbi_open_ex() */ +/** \copydoc mdbx_dbi_open_ex() + * \ingroup c_dbi */ MDBX_DEPRECATED LIBMDBX_API int mdbx_dbi_open_ex2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, MDBX_dbi *dbi, MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp); -/** \brief Переименовает таблицу по DBI-дескриптору. +/** \brief Переименовает таблицу по DBI-дескриптору + * * \ingroup c_dbi * - * Переименовывает пользовательскую именованную subDB связанную с передаваемым + * Переименовывает пользовательскую именованную таблицу связанную с передаваемым * DBI-дескриптором. * * \param [in,out] txn Пишущая транзакция запущенная посредством * \ref mdbx_txn_begin(). - * \param [in] dbi Дескриптор таблицы (именованной пользовательской subDB) + * \param [in] dbi Дескриптор таблицы * открытый посредством \ref mdbx_dbi_open(). * * \param [in] name Новое имя для переименования. * * \returns Ненулевое значение кода ошибки, либо 0 при успешном выполнении. */ LIBMDBX_API int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name); -/** \copydoc mdbx_dbi_rename() */ +/** \copydoc mdbx_dbi_rename() + * \ingroup c_dbi */ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *name); @@ -4659,10 +4705,10 @@ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, * пользовательских именованных таблиц. * * \ingroup c_statinfo - * \see mdbx_enumerate_subdb() + * \see mdbx_enumerate_tables() * * \param [in] ctx Указатель на контекст переданный аналогичным - * параметром в \ref mdbx_enumerate_subdb(). + * параметром в \ref mdbx_enumerate_tables(). * \param [in] txn Транзазакция. * \param [in] name Имя таблицы. * \param [in] flags Флаги \ref MDBX_db_flags_t. @@ -4674,7 +4720,7 @@ LIBMDBX_API int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi, * \returns Ноль при успехе и продолжении перечисления, при возвращении другого * значения оно будет немедленно возвращено вызывающему * без продолжения перечисления. */ -typedef int(MDBX_subdb_enum_func)(void *ctx, const MDBX_txn *txn, +typedef int(MDBX_table_enum_func)(void *ctx, const MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, const struct MDBX_stat *stat, MDBX_dbi dbi) MDBX_CXX17_NOEXCEPT; @@ -4688,19 +4734,19 @@ typedef int(MDBX_subdb_enum_func)(void *ctx, const MDBX_txn *txn, * сразу возвращено в качестве результата. * * \ingroup c_statinfo - * \see MDBX_subdb_enum_func + * \see MDBX_table_enum_func * * \param [in] txn Транзакция запущенная посредством * \ref mdbx_txn_begin(). * \param [in] func Указатель на пользовательскую функцию - * с сигнатурой \ref MDBX_subdb_enum_func, + * с сигнатурой \ref MDBX_table_enum_func, * которая будет вызвана для каждой таблицы. * \param [in] ctx Указатель на некоторый контект, который будет передан * в функцию `func()` как есть. * * \returns Ненулевое значение кода ошибки, либо 0 при успешном выполнении. */ -LIBMDBX_API int mdbx_enumerate_subdb(const MDBX_txn *txn, - MDBX_subdb_enum_func *func, void *ctx); +LIBMDBX_API int mdbx_enumerate_tables(const MDBX_txn *txn, + MDBX_table_enum_func *func, void *ctx); /** \defgroup value2key Value-to-Key functions * \brief Value-to-Key functions to @@ -4760,11 +4806,11 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int64_t mdbx_int64_from_key(const MDBX_val); /** end of value2key @} */ -/** \brief Retrieve statistics for a database. +/** \brief Retrieve statistics for a table. * \ingroup c_statinfo * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] stat The address of an \ref MDBX_stat structure where * the statistics will be copied. * \param [in] bytes The size of \ref MDBX_stat. @@ -4778,11 +4824,11 @@ LIBMDBX_API int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat, size_t bytes); /** \brief Retrieve depth (bitmask) information of nested dupsort (multi-value) - * B+trees for given database. + * B+trees for given table. * \ingroup c_statinfo * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] mask The address of an uint32_t value where the bitmask * will be stored. * @@ -4791,7 +4837,7 @@ LIBMDBX_API int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. * \retval MDBX_EINVAL An invalid parameter was specified. - * \retval MDBX_RESULT_TRUE The dbi isn't a dupsort (multi-value) database. */ + * \retval MDBX_RESULT_TRUE The dbi isn't a dupsort (multi-value) table. */ LIBMDBX_API int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, uint32_t *mask); @@ -4810,13 +4856,13 @@ typedef enum MDBX_dbi_state { } MDBX_dbi_state_t; DEFINE_ENUM_FLAG_OPERATORS(MDBX_dbi_state) -/** \brief Retrieve the DB flags and status for a database handle. +/** \brief Retrieve the DB flags and status for a table handle. * \ingroup c_statinfo * \see MDBX_db_flags_t * \see MDBX_dbi_state_t * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] flags Address where the flags will be returned. * \param [out] state Address where the state will be returned. * @@ -4833,10 +4879,10 @@ LIBMDBX_INLINE_API(int, mdbx_dbi_flags, return mdbx_dbi_flags_ex(txn, dbi, flags, &state); } -/** \brief Close a database handle. Normally unnecessary. +/** \brief Close a table handle. Normally unnecessary. * \ingroup c_dbi * - * Closing a database handle is not necessary, but lets \ref mdbx_dbi_open() + * Closing a table handle is not necessary, but lets \ref mdbx_dbi_open() * reuse the handle value. Usually it's better to set a bigger * \ref mdbx_env_set_maxdbs(), unless that value would be large. * @@ -4846,68 +4892,68 @@ LIBMDBX_INLINE_API(int, mdbx_dbi_flags, * (\ref MithrilDB) will solve this issue. * * Handles should only be closed if no other threads are going to reference - * the database handle or one of its cursors any further. Do not close a handle - * if an existing transaction has modified its database. Doing so can cause - * misbehavior from database corruption to errors like \ref MDBX_BAD_DBI + * the table handle or one of its cursors any further. Do not close a handle + * if an existing transaction has modified its table. Doing so can cause + * misbehavior from table corruption to errors like \ref MDBX_BAD_DBI * (since the DB name is gone). * * \param [in] env An environment handle returned by \ref mdbx_env_create(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi); -/** \brief Empty or delete and close a database. +/** \brief Empty or delete and close a table. * \ingroup c_crud * * \see mdbx_dbi_close() \see mdbx_dbi_open() * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] del `false` to empty the DB, `true` to delete it * from the environment and close the DB handle. * * \returns A non-zero error value on failure and 0 on success. */ LIBMDBX_API int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del); -/** \brief Get items from a database. +/** \brief Get items from a table. * \ingroup c_crud * - * This function retrieves key/data pairs from the database. The address + * This function retrieves key/data pairs from the table. The address * and length of the data associated with the specified key are returned * in the structure to which data refers. - * If the database supports duplicate keys (\ref MDBX_DUPSORT) then the + * If the table supports duplicate keys (\ref MDBX_DUPSORT) then the * first data item for the key will be returned. Retrieval of other * items requires the use of \ref mdbx_cursor_get(). * * \note The memory pointed to by the returned values is owned by the - * database. The caller MUST not dispose of the memory, and MUST not modify it + * table. The caller MUST not dispose of the memory, and MUST not modify it * in any way regardless in a read-only nor read-write transactions! - * For case a database opened without the \ref MDBX_WRITEMAP modification - * attempts likely will cause a `SIGSEGV`. However, when a database opened with + * For case a table opened without the \ref MDBX_WRITEMAP modification + * attempts likely will cause a `SIGSEGV`. However, when a table opened with * the \ref MDBX_WRITEMAP or in case values returned inside read-write * transaction are located on a "dirty" (modified and pending to commit) pages, * such modification will silently accepted and likely will lead to DB and/or * data corruption. * - * \note Values returned from the database are valid only until a + * \note Values returned from the table are valid only until a * subsequent update operation, or the end of the transaction. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data); -/** \brief Get items from a database +/** \brief Get items from a table * and optionally number of data items for a given key. * * \ingroup c_crud @@ -4917,30 +4963,30 @@ LIBMDBX_API int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * 1. If values_count is NOT NULL, then returns the count * of multi-values/duplicates for a given key. * 2. Updates BOTH the key and the data for pointing to the actual key-value - * pair inside the database. + * pair inside the table. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in,out] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in,out] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * \param [out] values_count The optional address to return number of values * associated with given key: * = 0 - in case \ref MDBX_NOTFOUND error; - * = 1 - exactly for databases + * = 1 - exactly for tables * WITHOUT \ref MDBX_DUPSORT; - * >= 1 for databases WITH \ref MDBX_DUPSORT. + * >= 1 for tables WITH \ref MDBX_DUPSORT. * * \returns A non-zero error value on failure and 0 on success, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, size_t *values_count); -/** \brief Get equal or great item from a database. +/** \brief Get equal or great item from a table. * \ingroup c_crud * * Briefly this function does the same as \ref mdbx_get() with a few @@ -4948,17 +4994,17 @@ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * 1. Return equal or great (due comparison function) key-value * pair, but not only exactly matching with the key. * 2. On success return \ref MDBX_SUCCESS if key found exactly, - * and \ref MDBX_RESULT_TRUE otherwise. Moreover, for databases with + * and \ref MDBX_RESULT_TRUE otherwise. Moreover, for tables with * \ref MDBX_DUPSORT flag the data argument also will be used to match over * multi-value/duplicates, and \ref MDBX_SUCCESS will be returned only when * BOTH the key and the data match exactly. * 3. Updates BOTH the key and the data for pointing to the actual key-value - * pair inside the database. + * pair inside the table. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in,out] key The key to search for in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in,out] key The key to search for in the table. * \param [in,out] data The data corresponding to the key. * * \returns A non-zero error value on failure and \ref MDBX_RESULT_FALSE @@ -4966,43 +5012,43 @@ LIBMDBX_API int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * Some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_NOTFOUND The key was not in the database. + * \retval MDBX_NOTFOUND The key was not in the table. * \retval MDBX_EINVAL An invalid parameter was specified. */ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data); -/** \brief Store items into a database. +/** \brief Store items into a table. * \ingroup c_crud * - * This function stores key/data pairs in the database. The default behavior + * This function stores key/data pairs in the table. The default behavior * is to enter the new key/data pair, replacing any previously existing key * if duplicates are disallowed, or adding a duplicate data item if * duplicates are allowed (see \ref MDBX_DUPSORT). * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to store in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to store in the table. * \param [in,out] data The data to store. * \param [in] flags Special options for this operation. * This parameter must be set to 0 or by bitwise OR'ing * together one or more of the values described here: * - \ref MDBX_NODUPDATA * Enter the new key-value pair only if it does not already appear - * in the database. This flag may only be specified if the database + * in the table. This flag may only be specified if the table * was opened with \ref MDBX_DUPSORT. The function will return - * \ref MDBX_KEYEXIST if the key/data pair already appears in the database. + * \ref MDBX_KEYEXIST if the key/data pair already appears in the table. * * - \ref MDBX_NOOVERWRITE * Enter the new key/data pair only if the key does not already appear - * in the database. The function will return \ref MDBX_KEYEXIST if the key - * already appears in the database, even if the database supports + * in the table. The function will return \ref MDBX_KEYEXIST if the key + * already appears in the table, even if the table supports * duplicates (see \ref MDBX_DUPSORT). The data parameter will be set * to point to the existing item. * * - \ref MDBX_CURRENT * Update an single existing entry, but not add new ones. The function will - * return \ref MDBX_NOTFOUND if the given key not exist in the database. + * return \ref MDBX_NOTFOUND if the given key not exist in the table. * In case multi-values for the given key, with combination of * the \ref MDBX_ALLDUPS will replace all multi-values, * otherwise return the \ref MDBX_EMULTIVAL. @@ -5014,10 +5060,10 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * transaction ends. This saves an extra memcpy if the data is being * generated later. MDBX does nothing else with this memory, the caller * is expected to modify all of the space requested. This flag must not - * be specified if the database was opened with \ref MDBX_DUPSORT. + * be specified if the table was opened with \ref MDBX_DUPSORT. * * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. This option + * Append the given key/data pair to the end of the table. This option * allows fast bulk loading when keys are already known to be in the * correct order. Loading unsorted keys with this flag will cause * a \ref MDBX_EKEYMISMATCH error. @@ -5027,14 +5073,14 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * * - \ref MDBX_MULTIPLE * Store multiple contiguous data elements in a single request. This flag - * may only be specified if the database was opened with + * may only be specified if the table was opened with * \ref MDBX_DUPFIXED. With combination the \ref MDBX_ALLDUPS * will replace all multi-values. * The data argument must be an array of two \ref MDBX_val. The `iov_len` * of the first \ref MDBX_val must be the size of a single data element. * The `iov_base` of the first \ref MDBX_val must point to the beginning * of the array of contiguous data elements which must be properly aligned - * in case of database with \ref MDBX_INTEGERDUP flag. + * in case of table with \ref MDBX_INTEGERDUP flag. * The `iov_len` of the second \ref MDBX_val must be the count of the * number of data elements to store. On return this field will be set to * the count of the number of elements actually written. The `iov_base` of @@ -5046,7 +5092,7 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, * some possible errors are: * \retval MDBX_THREAD_MISMATCH Given transaction is not owned * by current thread. - * \retval MDBX_KEYEXIST The key/value pair already exists in the database. + * \retval MDBX_KEYEXIST The key/value pair already exists in the table. * \retval MDBX_MAP_FULL The database is full, see \ref mdbx_env_set_mapsize(). * \retval MDBX_TXN_FULL The transaction has too many dirty pages. * \retval MDBX_EACCES An attempt was made to write @@ -5055,7 +5101,7 @@ LIBMDBX_API int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, MDBX_put_flags_t flags); -/** \brief Replace items in a database. +/** \brief Replace items in a table. * \ingroup c_crud * * This function allows to update or delete an existing value at the same time @@ -5070,7 +5116,7 @@ LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * field pointed by old_data argument to the appropriate value, without * performing any changes. * - * For databases with non-unique keys (i.e. with \ref MDBX_DUPSORT flag), + * For tables with non-unique keys (i.e. with \ref MDBX_DUPSORT flag), * another use case is also possible, when by old_data argument selects a * specific item from multi-value/duplicates with the same key for deletion or * update. To select this scenario in flags should simultaneously specify @@ -5080,8 +5126,8 @@ LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to store in the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to store in the table. * \param [in] new_data The data to store, if NULL then deletion will * be performed. * \param [in,out] old_data The buffer for retrieve previous value as describe @@ -5110,24 +5156,24 @@ LIBMDBX_API int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, MDBX_preserve_func preserver, void *preserver_context); -/** \brief Delete items from a database. +/** \brief Delete items from a table. * \ingroup c_crud * - * This function removes key/data pairs from the database. + * This function removes key/data pairs from the table. * - * \note The data parameter is NOT ignored regardless the database does + * \note The data parameter is NOT ignored regardless the table does * support sorted duplicate data items or not. If the data parameter * is non-NULL only the matching data item will be deleted. Otherwise, if data * parameter is NULL, any/all value(s) for specified key will be deleted. * * This function will return \ref MDBX_NOTFOUND if the specified key/data - * pair is not in the database. + * pair is not in the table. * * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). - * \param [in] key The key to delete from the database. + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). + * \param [in] key The key to delete from the table. * \param [in] data The data to delete. * * \returns A non-zero error value on failure and 0 on success, @@ -5141,7 +5187,7 @@ LIBMDBX_API int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, /** \brief Create a cursor handle but not bind it to transaction nor DBI-handle. * \ingroup c_cursors * - * A cursor cannot be used when its database handle is closed. Nor when its + * A cursor cannot be used when its table handle is closed. Nor when its * transaction has ended, except with \ref mdbx_cursor_bind() and \ref * mdbx_cursor_renew(). Also it can be discarded with \ref mdbx_cursor_close(). * @@ -5192,7 +5238,7 @@ mdbx_cursor_get_userctx(const MDBX_cursor *cursor); * \ref mdbx_cursor_renew() but with specifying an arbitrary DBI-handle. * * A cursor may be associated with a new transaction, and referencing a new or - * the same database handle as it was created with. This may be done whether the + * the same table handle as it was created with. This may be done whether the * previous transaction is live or dead. * * \note In contrast to LMDB, the MDBX required that any opened cursors can be @@ -5202,7 +5248,7 @@ mdbx_cursor_get_userctx(const MDBX_cursor *cursor); * memory corruption and segfaults. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_create(). * * \returns A non-zero error value on failure and 0 on success, @@ -5256,7 +5302,7 @@ LIBMDBX_API int mdbx_cursor_reset(MDBX_cursor *cursor); * Using of the `mdbx_cursor_open()` is equivalent to calling * \ref mdbx_cursor_create() and then \ref mdbx_cursor_bind() functions. * - * A cursor cannot be used when its database handle is closed. Nor when its + * A cursor cannot be used when its table handle is closed. Nor when its * transaction has ended, except with \ref mdbx_cursor_bind() and \ref * mdbx_cursor_renew(). Also it can be discarded with \ref mdbx_cursor_close(). * @@ -5271,7 +5317,7 @@ LIBMDBX_API int mdbx_cursor_reset(MDBX_cursor *cursor); * memory corruption and segfaults. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] cursor Address where the new \ref MDBX_cursor handle will be * stored. * @@ -5353,7 +5399,7 @@ LIBMDBX_API int mdbx_cursor_renew(const MDBX_txn *txn, MDBX_cursor *cursor); MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API MDBX_txn * mdbx_cursor_txn(const MDBX_cursor *cursor); -/** \brief Return the cursor's database handle. +/** \brief Return the cursor's table handle. * \ingroup c_cursors * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). */ @@ -5399,7 +5445,7 @@ LIBMDBX_API int mdbx_cursor_compare(const MDBX_cursor *left, /** \brief Retrieve by cursor. * \ingroup c_crud * - * This function retrieves key/data pairs from the database. The address and + * This function retrieves key/data pairs from the table. The address and * length of the key are returned in the object to which key refers (except * for the case of the \ref MDBX_SET option, in which the key object is * unchanged), and the address and length of the data are returned in the object @@ -5488,12 +5534,11 @@ typedef int(MDBX_predicate_func)(void *context, MDBX_val *key, MDBX_val *value, * DSO-трансграничных вызовов. * * Функция принимает курсор, который должен быть привязан к некоторой транзакции - * и DBI-дескриптору таблицы (именованной пользовательской subDB), выполняет - * первоначальное позиционирование курсора определяемое аргументом `start_op`. - * Далее, производится оценка каждой пары ключ-значения посредством - * предоставляемой вами предикативной функции `predicate` и затем, при - * необходимости, переход к следующему элементу посредством операции `turn_op`, - * до наступления одного из четырех событий: + * и DBI-дескриптору таблицы, выполняет первоначальное позиционирование курсора + * определяемое аргументом `start_op`. Далее, производится оценка каждой пары + * ключ-значения посредством предоставляемой вами предикативной функции + * `predicate` и затем, при необходимости, переход к следующему элементу + * посредством операции `turn_op`, до наступления одного из четырех событий: * - достигается конец данных; * - возникнет ошибка при позиционировании курсора; * - оценочная функция вернет \ref MDBX_RESULT_TRUE, сигнализируя @@ -5557,13 +5602,12 @@ LIBMDBX_API int mdbx_cursor_scan(MDBX_cursor *cursor, * \ingroup c_crud * * Функция принимает курсор, который должен быть привязан к некоторой транзакции - * и DBI-дескриптору таблицы (именованной пользовательской subDB), выполняет - * первоначальное позиционирование курсора определяемое аргументом `from_op`. - * а также аргументами `from_key` и `from_value`. - * Далее, производится оценка каждой пары ключ-значения посредством - * предоставляемой вами предикативной функции `predicate` и затем, при - * необходимости, переход к следующему элементу посредством операции `turn_op`, - * до наступления одного из четырех событий: + * и DBI-дескриптору таблицы, выполняет первоначальное позиционирование курсора + * определяемое аргументом `from_op`. а также аргументами `from_key` и + * `from_value`. Далее, производится оценка каждой пары ключ-значения + * посредством предоставляемой вами предикативной функции `predicate` и затем, + * при необходимости, переход к следующему элементу посредством операции + * `turn_op`, до наступления одного из четырех событий: * - достигается конец данных; * - возникнет ошибка при позиционировании курсора; * - оценочная функция вернет \ref MDBX_RESULT_TRUE, сигнализируя @@ -5645,8 +5689,8 @@ LIBMDBX_API int mdbx_cursor_scan_from(MDBX_cursor *cursor, /** \brief Retrieve multiple non-dupsort key/value pairs by cursor. * \ingroup c_crud * - * This function retrieves multiple key/data pairs from the database without - * \ref MDBX_DUPSORT option. For `MDBX_DUPSORT` databases please + * This function retrieves multiple key/data pairs from the table without + * \ref MDBX_DUPSORT option. For `MDBX_DUPSORT` tables please * use \ref MDBX_GET_MULTIPLE and \ref MDBX_NEXT_MULTIPLE. * * The number of key and value items is returned in the `size_t count` @@ -5690,7 +5734,7 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, /** \brief Store by cursor. * \ingroup c_crud * - * This function stores key/data pairs into the database. The cursor is + * This function stores key/data pairs into the table. The cursor is * positioned at the new item, or on failure usually near it. * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). @@ -5711,14 +5755,14 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * * - \ref MDBX_NODUPDATA * Enter the new key-value pair only if it does not already appear in the - * database. This flag may only be specified if the database was opened + * table. This flag may only be specified if the table was opened * with \ref MDBX_DUPSORT. The function will return \ref MDBX_KEYEXIST - * if the key/data pair already appears in the database. + * if the key/data pair already appears in the table. * * - \ref MDBX_NOOVERWRITE * Enter the new key/data pair only if the key does not already appear - * in the database. The function will return \ref MDBX_KEYEXIST if the key - * already appears in the database, even if the database supports + * in the table. The function will return \ref MDBX_KEYEXIST if the key + * already appears in the table, even if the table supports * duplicates (\ref MDBX_DUPSORT). * * - \ref MDBX_RESERVE @@ -5726,11 +5770,11 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * data. Instead, return a pointer to the reserved space, which the * caller can fill in later - before the next update operation or the * transaction ends. This saves an extra memcpy if the data is being - * generated later. This flag must not be specified if the database + * generated later. This flag must not be specified if the table * was opened with \ref MDBX_DUPSORT. * * - \ref MDBX_APPEND - * Append the given key/data pair to the end of the database. No key + * Append the given key/data pair to the end of the table. No key * comparisons are performed. This option allows fast bulk loading when * keys are already known to be in the correct order. Loading unsorted * keys with this flag will cause a \ref MDBX_KEYEXIST error. @@ -5740,14 +5784,14 @@ LIBMDBX_API int mdbx_cursor_get_batch(MDBX_cursor *cursor, size_t *count, * * - \ref MDBX_MULTIPLE * Store multiple contiguous data elements in a single request. This flag - * may only be specified if the database was opened with + * may only be specified if the table was opened with * \ref MDBX_DUPFIXED. With combination the \ref MDBX_ALLDUPS * will replace all multi-values. * The data argument must be an array of two \ref MDBX_val. The `iov_len` * of the first \ref MDBX_val must be the size of a single data element. * The `iov_base` of the first \ref MDBX_val must point to the beginning * of the array of contiguous data elements which must be properly aligned - * in case of database with \ref MDBX_INTEGERDUP flag. + * in case of table with \ref MDBX_INTEGERDUP flag. * The `iov_len` of the second \ref MDBX_val must be the count of the * number of data elements to store. On return this field will be set to * the count of the number of elements actually written. The `iov_base` of @@ -5786,7 +5830,7 @@ LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, const MDBX_val *key, * - \ref MDBX_ALLDUPS * or \ref MDBX_NODUPDATA (supported for compatibility) * Delete all of the data items for the current key. This flag has effect - * only for database(s) was created with \ref MDBX_DUPSORT. + * only for table(s) was created with \ref MDBX_DUPSORT. * * \see \ref c_crud_hints "Quick reference for Insert/Update/Delete operations" * @@ -5805,7 +5849,7 @@ LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags); /** \brief Return count of duplicates for current key. * \ingroup c_crud * - * This call is valid for all databases, but reasonable only for that support + * This call is valid for all tables, but reasonable only for that support * sorted duplicate data items \ref MDBX_DUPSORT. * * \param [in] cursor A cursor handle returned by \ref mdbx_cursor_open(). @@ -5925,7 +5969,7 @@ mdbx_cursor_on_last_dup(const MDBX_cursor *cursor); * Please see notes on accuracy of the result in the details * of \ref c_rqest section. * - * Both cursors must be initialized for the same database and the same + * Both cursors must be initialized for the same table and the same * transaction. * * \param [in] first The first cursor for estimation. @@ -5974,7 +6018,7 @@ LIBMDBX_API int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key, * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] begin_key The key of range beginning or NULL for explicit FIRST. * \param [in] begin_data Optional additional data to seeking among sorted * duplicates. @@ -6033,18 +6077,18 @@ LIBMDBX_API int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr); -/** \brief Sequence generation for a database. +/** \brief Sequence generation for a table. * \ingroup c_crud * * The function allows to create a linear sequence of unique positive integers - * for each database. The function can be called for a read transaction to + * for each table. The function can be called for a read transaction to * retrieve the current sequence value, and the increment must be zero. * Sequence changes become visible outside the current write transaction after * it is committed, and discarded on abort. * * \param [in] txn A transaction handle returned * by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [out] result The optional address where the value of sequence * before the change will be stored. * \param [in] increment Value to increase the sequence, @@ -6057,17 +6101,17 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_is_dirty(const MDBX_txn *txn, LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, uint64_t increment); -/** \brief Compare two keys according to a particular database. +/** \brief Compare two keys according to a particular table. * \ingroup c_crud * \see MDBX_cmp_func * * This returns a comparison as if the two data items were keys in the - * specified database. + * specified table. * * \warning There ss a Undefined behavior if one of arguments is invalid. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] a The first item to compare. * \param [in] b The second item to compare. * @@ -6077,22 +6121,22 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, const MDBX_val *a, const MDBX_val *b); -/** \brief Returns default internal key's comparator for given database flags. +/** \brief Returns default internal key's comparator for given table flags. * \ingroup c_extra */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_keycmp(MDBX_db_flags_t flags); -/** \brief Compare two data items according to a particular database. +/** \brief Compare two data items according to a particular table. * \ingroup c_crud * \see MDBX_cmp_func * * This returns a comparison as if the two items were data items of the - * specified database. + * specified table. * * \warning There ss a Undefined behavior if one of arguments is invalid. * * \param [in] txn A transaction handle returned by \ref mdbx_txn_begin(). - * \param [in] dbi A database handle returned by \ref mdbx_dbi_open(). + * \param [in] dbi A table handle returned by \ref mdbx_dbi_open(). * \param [in] a The first item to compare. * \param [in] b The second item to compare. * @@ -6102,7 +6146,7 @@ MDBX_NOTHROW_PURE_FUNCTION LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, const MDBX_val *a, const MDBX_val *b); -/** \brief Returns default internal data's comparator for given database flags +/** \brief Returns default internal data's comparator for given table flags * \ingroup c_extra */ MDBX_NOTHROW_CONST_FUNCTION LIBMDBX_API MDBX_cmp_func * mdbx_get_datacmp(MDBX_db_flags_t flags); @@ -6355,6 +6399,7 @@ LIBMDBX_API int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname, #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_env_open_for_recovery() + * \ingroup c_extra * \note Available only on Windows. * \see mdbx_env_open_for_recovery() */ LIBMDBX_API int mdbx_env_open_for_recoveryW(MDBX_env *env, @@ -6405,6 +6450,7 @@ LIBMDBX_API int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *info, size_t bytes); #if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN) /** \copydoc mdbx_preopen_snapinfo() + * \ingroup c_opening * \note Available only on Windows. * \see mdbx_preopen_snapinfo() */ LIBMDBX_API int mdbx_preopen_snapinfoW(const wchar_t *pathname, @@ -6467,7 +6513,7 @@ typedef enum MDBX_chk_stage { MDBX_chk_gc, MDBX_chk_space, MDBX_chk_maindb, - MDBX_chk_subdbs, + MDBX_chk_tables, MDBX_chk_conclude, MDBX_chk_unlock, MDBX_chk_finalize @@ -6507,7 +6553,7 @@ typedef struct MDBX_chk_scope { /** \brief Пользовательский тип для привязки дополнительных данных, * связанных с некоторой таблицей ключ-значение, при проверке целостности базы * данных. \see mdbx_env_chk() */ -typedef struct MDBX_chk_user_subdb_cookie MDBX_chk_user_subdb_cookie_t; +typedef struct MDBX_chk_user_table_cookie MDBX_chk_user_table_cookie_t; /** \brief Гистограмма с некоторой статистической информацией, * собираемой при проверке целостности БД. @@ -6522,8 +6568,8 @@ struct MDBX_chk_histogram { /** \brief Информация о некоторой таблицей ключ-значение, * при проверке целостности базы данных. * \see mdbx_env_chk() */ -typedef struct MDBX_chk_subdb { - MDBX_chk_user_subdb_cookie_t *cookie; +typedef struct MDBX_chk_table { + MDBX_chk_user_table_cookie_t *cookie; /** \brief Pseudo-name for MainDB */ #define MDBX_CHK_MAIN ((void *)((ptrdiff_t)0)) @@ -6554,7 +6600,7 @@ typedef struct MDBX_chk_subdb { /// Values length histogram struct MDBX_chk_histogram val_len; } histogram; -} MDBX_chk_subdb_t; +} MDBX_chk_table_t; /** \brief Контекст проверки целостности базы данных. * \see mdbx_env_chk() */ @@ -6566,17 +6612,17 @@ typedef struct MDBX_chk_context { uint8_t scope_nesting; struct { size_t total_payload_bytes; - size_t subdb_total, subdb_processed; + size_t table_total, table_processed; size_t total_unused_bytes, unused_pages; size_t processed_pages, reclaimable_pages, gc_pages, alloc_pages, backed_pages; size_t problems_meta, tree_problems, gc_tree_problems, kv_tree_problems, problems_gc, problems_kv, total_problems; uint64_t steady_txnid, recent_txnid; - /** Указатель на массив размером subdb_total с указателями на экземпляры - * структур MDBX_chk_subdb_t с информацией о всех таблицах ключ-значение, + /** Указатель на массив размером table_total с указателями на экземпляры + * структур MDBX_chk_table_t с информацией о всех таблицах ключ-значение, * включая MainDB и GC/FreeDB. */ - const MDBX_chk_subdb_t *const *subdbs; + const MDBX_chk_table_t *const *tables; } result; } MDBX_chk_context_t; @@ -6606,14 +6652,14 @@ typedef struct MDBX_chk_callbacks { void (*issue)(MDBX_chk_context_t *ctx, const char *object, uint64_t entry_number, const char *issue, const char *extra_fmt, va_list extra_args); - MDBX_chk_user_subdb_cookie_t *(*subdb_filter)(MDBX_chk_context_t *ctx, + MDBX_chk_user_table_cookie_t *(*table_filter)(MDBX_chk_context_t *ctx, const MDBX_val *name, MDBX_db_flags_t flags); - int (*subdb_conclude)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb, + int (*table_conclude)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table, MDBX_cursor *cursor, int err); - void (*subdb_dispose)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb); + void (*table_dispose)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table); - int (*subdb_handle_kv)(MDBX_chk_context_t *ctx, const MDBX_chk_subdb_t *subdb, + int (*table_handle_kv)(MDBX_chk_context_t *ctx, const MDBX_chk_table_t *table, size_t entry_number, const MDBX_val *key, const MDBX_val *value); diff --git a/mdbxdist/mdbx.h++ b/mdbxdist/mdbx.h++ index 0d2e8d0..9c4101f 100644 --- a/mdbxdist/mdbx.h++ +++ b/mdbxdist/mdbx.h++ @@ -3537,8 +3537,8 @@ enum put_mode { /// instances, but does not destroys the represented underlying object from the /// own class destructor. /// -/// An environment supports multiple key-value sub-databases (aka key-value -/// spaces or tables), all residing in the same shared-memory map. +/// An environment supports multiple key-value tables (aka key-value +/// maps, spaces or sub-databases), all residing in the same shared-memory map. class LIBMDBX_API_TYPE env { friend class txn; @@ -4101,7 +4101,7 @@ public: /// environment is busy by other thread or none of the thresholds are reached. bool poll_sync_to_disk() { return sync_to_disk(false, true); } - /// \brief Close a key-value map (aka sub-database) handle. Normally + /// \brief Close a key-value map (aka table) handle. Normally /// unnecessary. /// /// Closing a database handle is not necessary, but lets \ref txn::open_map() @@ -4519,12 +4519,12 @@ public: #endif /* __cpp_lib_string_view >= 201606L */ using map_stat = ::MDBX_stat; - /// \brief Returns statistics for a sub-database. + /// \brief Returns statistics for a table. inline map_stat get_map_stat(map_handle map) const; /// \brief Returns depth (bitmask) information of nested dupsort (multi-value) /// B+trees for given database. inline uint32_t get_tree_deepmask(map_handle map) const; - /// \brief Returns information about key-value map (aka sub-database) handle. + /// \brief Returns information about key-value map (aka table) handle. inline map_handle::info get_handle_info(map_handle map) const; using canary = ::MDBX_canary; @@ -4536,39 +4536,39 @@ public: inline canary get_canary() const; /// Reads sequence generator associated with a key-value map (aka - /// sub-database). + /// table). inline uint64_t sequence(map_handle map) const; /// \brief Reads and increment sequence generator associated with a key-value - /// map (aka sub-database). + /// map (aka table). inline uint64_t sequence(map_handle map, uint64_t increment); /// \brief Compare two keys according to a particular key-value map (aka - /// sub-database). + /// table). inline int compare_keys(map_handle map, const slice &a, const slice &b) const noexcept; /// \brief Compare two values according to a particular key-value map (aka - /// sub-database). + /// table). inline int compare_values(map_handle map, const slice &a, const slice &b) const noexcept; /// \brief Compare keys of two pairs according to a particular key-value map - /// (aka sub-database). + /// (aka table). inline int compare_keys(map_handle map, const pair &a, const pair &b) const noexcept; /// \brief Compare values of two pairs according to a particular key-value map - /// (aka sub-database). + /// (aka table). inline int compare_values(map_handle map, const pair &a, const pair &b) const noexcept; - /// \brief Get value by key from a key-value map (aka sub-database). + /// \brief Get value by key from a key-value map (aka table). inline slice get(map_handle map, const slice &key) const; /// \brief Get first of multi-value and values count by key from a key-value - /// multimap (aka sub-database). + /// multimap (aka table). inline slice get(map_handle map, slice key, size_t &values_count) const; - /// \brief Get value by key from a key-value map (aka sub-database). + /// \brief Get value by key from a key-value map (aka table). inline slice get(map_handle map, const slice &key, const slice &value_at_absence) const; /// \brief Get first of multi-value and values count by key from a key-value - /// multimap (aka sub-database). + /// multimap (aka table). inline slice get(map_handle map, slice key, size_t &values_count, const slice &value_at_absence) const; /// \brief Get value for equal or great key from a database. diff --git a/mdbxdist/mdbx_chk.c b/mdbxdist/mdbx_chk.c index 95eac7d..c92a842 100644 --- a/mdbxdist/mdbx_chk.c +++ b/mdbxdist/mdbx_chk.c @@ -16,7 +16,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2533,11 +2533,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2568,10 +2568,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2600,9 +2600,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3543,7 +3543,7 @@ MDBX_env *env; MDBX_txn *txn; unsigned verbose = 0; bool quiet; -MDBX_val only_subdb; +MDBX_val only_table; int stuck_meta = -1; MDBX_chk_context_t chk; bool turn_meta = false; @@ -3583,7 +3583,7 @@ static bool silently(enum MDBX_chk_severity severity) { chk.scope ? chk.scope->verbosity >> MDBX_chk_severity_prio_shift : verbose + (MDBX_chk_result >> MDBX_chk_severity_prio_shift); int prio = (severity >> MDBX_chk_severity_prio_shift); - if (chk.scope && chk.scope->stage == MDBX_chk_subdbs && verbose < 2) + if (chk.scope && chk.scope->stage == MDBX_chk_tables && verbose < 2) prio += 1; return quiet || cutoff < ((prio > 0) ? prio : 0); } @@ -3758,14 +3758,14 @@ static void scope_pop(MDBX_chk_context_t *ctx, MDBX_chk_scope_t *scope, flush(); } -static MDBX_chk_user_subdb_cookie_t *subdb_filter(MDBX_chk_context_t *ctx, +static MDBX_chk_user_table_cookie_t *table_filter(MDBX_chk_context_t *ctx, const MDBX_val *name, MDBX_db_flags_t flags) { (void)ctx; (void)flags; - return (!only_subdb.iov_base || - (only_subdb.iov_len == name->iov_len && - memcmp(only_subdb.iov_base, name->iov_base, name->iov_len) == 0)) + return (!only_table.iov_base || + (only_table.iov_len == name->iov_len && + memcmp(only_table.iov_base, name->iov_base, name->iov_len) == 0)) ? (void *)(intptr_t)-1 : nullptr; } @@ -3832,7 +3832,7 @@ static void print_format(MDBX_chk_line_t *line, const char *fmt, va_list args) { static const MDBX_chk_callbacks_t cb = {.check_break = check_break, .scope_push = scope_push, .scope_pop = scope_pop, - .subdb_filter = subdb_filter, + .table_filter = table_filter, .stage_begin = stage_begin, .stage_end = stage_end, .print_begin = print_begin, @@ -3845,7 +3845,7 @@ static void usage(char *prog) { fprintf( stderr, "usage: %s " - "[-V] [-v] [-q] [-c] [-0|1|2] [-w] [-d] [-i] [-s subdb] [-u|U] dbpath\n" + "[-V] [-v] [-q] [-c] [-0|1|2] [-w] [-d] [-i] [-s table] [-u|U] dbpath\n" " -V\t\tprint version and exit\n" " -v\t\tmore verbose, could be repeated upto 9 times for extra details\n" " -q\t\tbe quiet\n" @@ -3853,7 +3853,7 @@ static void usage(char *prog) { " -w\t\twrite-mode checking\n" " -d\t\tdisable page-by-page traversal of B-tree\n" " -i\t\tignore wrong order errors (for custom comparators case)\n" - " -s subdb\tprocess a specific subdatabase only\n" + " -s table\tprocess a specific subdatabase only\n" " -u\t\twarmup database before checking\n" " -U\t\twarmup and try lock database pages in memory before checking\n" " -0|1|2\tforce using specific meta-page 0, or 2 for checking\n" @@ -3868,7 +3868,7 @@ static int conclude(MDBX_chk_context_t *ctx) { if (ctx->result.total_problems == 1 && ctx->result.problems_meta == 1 && (chk_flags & (MDBX_CHK_SKIP_BTREE_TRAVERSAL | MDBX_CHK_SKIP_KV_TRAVERSAL)) == 0 && - (env_flags & MDBX_RDONLY) == 0 && !only_subdb.iov_base && + (env_flags & MDBX_RDONLY) == 0 && !only_table.iov_base && stuck_meta < 0 && ctx->result.steady_txnid < ctx->result.recent_txnid) { const size_t step_lineno = print(MDBX_chk_resolution, @@ -3887,7 +3887,7 @@ static int conclude(MDBX_chk_context_t *ctx) { if (turn_meta && stuck_meta >= 0 && (chk_flags & (MDBX_CHK_SKIP_BTREE_TRAVERSAL | MDBX_CHK_SKIP_KV_TRAVERSAL)) == 0 && - !only_subdb.iov_base && + !only_table.iov_base && (env_flags & (MDBX_RDONLY | MDBX_EXCLUSIVE)) == MDBX_EXCLUSIVE) { const bool successful_check = (err | ctx->result.total_problems | ctx->result.problems_meta) == 0; @@ -4017,11 +4017,11 @@ int main(int argc, char *argv[]) { chk_flags |= MDBX_CHK_SKIP_BTREE_TRAVERSAL; break; case 's': - if (only_subdb.iov_base && strcmp(only_subdb.iov_base, optarg)) + if (only_table.iov_base && strcmp(only_table.iov_base, optarg)) usage(prog); else { - only_subdb.iov_base = optarg; - only_subdb.iov_len = strlen(optarg); + only_table.iov_base = optarg; + only_table.iov_len = strlen(optarg); } break; case 'i': @@ -4062,7 +4062,7 @@ int main(int argc, char *argv[]) { "write-mode must be enabled to turn to the specified meta-page."); rc = EXIT_INTERRUPTED; } - if (only_subdb.iov_base || (chk_flags & (MDBX_CHK_SKIP_BTREE_TRAVERSAL | + if (only_table.iov_base || (chk_flags & (MDBX_CHK_SKIP_BTREE_TRAVERSAL | MDBX_CHK_SKIP_KV_TRAVERSAL))) { error_fmt( "whole database checking with b-tree traversal are required to turn " diff --git a/mdbxdist/mdbx_copy.c b/mdbxdist/mdbx_copy.c index dd8b250..d80b1a6 100644 --- a/mdbxdist/mdbx_copy.c +++ b/mdbxdist/mdbx_copy.c @@ -18,7 +18,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2535,11 +2535,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2570,10 +2570,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2602,9 +2602,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) diff --git a/mdbxdist/mdbx_drop.c b/mdbxdist/mdbx_drop.c index 4d933d7..3ebf371 100644 --- a/mdbxdist/mdbx_drop.c +++ b/mdbxdist/mdbx_drop.c @@ -18,7 +18,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2535,11 +2535,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2570,10 +2570,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2602,9 +2602,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3534,7 +3534,7 @@ static void usage(void) { " -V\t\tprint version and exit\n" " -q\t\tbe quiet\n" " -d\t\tdelete the specified database, don't just empty it\n" - " -s name\tdrop the specified named subDB\n" + " -s name\tdrop the specified named table\n" " \t\tby default empty the main DB\n", prog); exit(EXIT_FAILURE); diff --git a/mdbxdist/mdbx_dump.c b/mdbxdist/mdbx_dump.c index e289c06..024d940 100644 --- a/mdbxdist/mdbx_dump.c +++ b/mdbxdist/mdbx_dump.c @@ -18,7 +18,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2535,11 +2535,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2570,10 +2570,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2602,9 +2602,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3588,7 +3588,7 @@ static void error(const char *func, int rc) { } /* Dump in BDB-compatible format */ -static int dump_sdb(MDBX_txn *txn, MDBX_dbi dbi, char *name) { +static int dump_tbl(MDBX_txn *txn, MDBX_dbi dbi, char *name) { unsigned flags; int rc = mdbx_dbi_flags(txn, dbi, &flags); if (unlikely(rc != MDBX_SUCCESS)) { @@ -3703,16 +3703,16 @@ static void usage(void) { fprintf( stderr, "usage: %s " - "[-V] [-q] [-f file] [-l] [-p] [-r] [-a|-s subdb] [-u|U] " + "[-V] [-q] [-f file] [-l] [-p] [-r] [-a|-s table] [-u|U] " "dbpath\n" " -V\t\tprint version and exit\n" " -q\t\tbe quiet\n" " -f\t\twrite to file instead of stdout\n" - " -l\t\tlist subDBs and exit\n" + " -l\t\tlist tables and exit\n" " -p\t\tuse printable characters\n" " -r\t\trescue mode (ignore errors to dump corrupted DB)\n" - " -a\t\tdump main DB and all subDBs\n" - " -s name\tdump only the specified named subDB\n" + " -a\t\tdump main DB and all tables\n" + " -s name\tdump only the specified named table\n" " -u\t\twarmup database before dumping\n" " -U\t\twarmup and try lock database pages in memory before dumping\n" " \t\tby default dump only the main DB\n", @@ -3938,7 +3938,7 @@ int main(int argc, char *argv[]) { if (list) { printf("%s\n", subname); } else { - err = dump_sdb(txn, sub_dbi, subname); + err = dump_tbl(txn, sub_dbi, subname); if (unlikely(err != MDBX_SUCCESS)) { if (!rescue) break; @@ -3976,7 +3976,7 @@ int main(int argc, char *argv[]) { cursor = nullptr; if (have_raw && (!count /* || rescue */)) - err = dump_sdb(txn, MAIN_DBI, nullptr); + err = dump_tbl(txn, MAIN_DBI, nullptr); else if (!count) { if (!quiet) fprintf(stderr, "%s: %s does not contain multiple databases\n", prog, @@ -3984,7 +3984,7 @@ int main(int argc, char *argv[]) { err = MDBX_NOTFOUND; } } else { - err = dump_sdb(txn, dbi, subname); + err = dump_tbl(txn, dbi, subname); } switch (err) { diff --git a/mdbxdist/mdbx_load.c b/mdbxdist/mdbx_load.c index eb5fc1a..c1d8489 100644 --- a/mdbxdist/mdbx_load.c +++ b/mdbxdist/mdbx_load.c @@ -18,7 +18,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2535,11 +2535,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2570,10 +2570,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2602,9 +2602,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3965,10 +3965,10 @@ static void usage(void) { " -a\t\tappend records in input order (required for custom " "comparators)\n" " -f file\tread from file instead of stdin\n" - " -s name\tload into specified named subDB\n" + " -s name\tload into specified named table\n" " -N\t\tdon't overwrite existing records when loading, just skip " "ones\n" - " -p\t\tpurge subDB before loading\n" + " -p\t\tpurge table before loading\n" " -T\t\tread plaintext\n" " -r\t\trescue mode (ignore errors to load corrupted DB dump)\n" " -n\t\tdon't use subdirectory for newly created database " diff --git a/mdbxdist/mdbx_stat.c b/mdbxdist/mdbx_stat.c index c4240bc..b013443 100644 --- a/mdbxdist/mdbx_stat.c +++ b/mdbxdist/mdbx_stat.c @@ -18,7 +18,7 @@ /// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2024 -#define MDBX_BUILD_SOURCERY 8f23af99dc8a425935da3f9fbc044a565c83f49f124f885acceba17444721dde_v0_13_0_110_gdd0ee3f2 +#define MDBX_BUILD_SOURCERY 40a5b5a8cb0aa52b17df5a541e416ef747538cfa71b8010c27e9010b9a079946_v0_13_0_115_g7bff3b3d #define LIBMDBX_INTERNALS @@ -2535,11 +2535,11 @@ typedef enum page_type { * omit entries and pack sorted MDBX_DUPFIXED values after the page header. * * P_LARGE records occupy one or more contiguous pages where only the - * first has a page header. They hold the real data of N_BIGDATA nodes. + * first has a page header. They hold the real data of N_BIG nodes. * * P_SUBP sub-pages are small leaf "pages" with duplicate data. - * A node with flag N_DUPDATA but not N_SUBDATA contains a sub-page. - * (Duplicate data can also go in sub-databases, which use normal pages.) + * A node with flag N_DUP but not N_TREE contains a sub-page. + * (Duplicate data can also go in tables, which use normal pages.) * * P_META pages contain meta_t, the start point of an MDBX snapshot. * @@ -2570,10 +2570,10 @@ typedef struct page { * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX. * We guarantee 2-byte alignment for 'node_t's. * - * Leaf node flags describe node contents. N_BIGDATA says the node's + * Leaf node flags describe node contents. N_BIG says the node's * data part is the page number of an overflow page with actual data. - * N_DUPDATA and N_SUBDATA can be combined giving duplicate data in - * a sub-page/sub-database, and named databases (just N_SUBDATA). */ + * N_DUP and N_TREE can be combined giving duplicate data in + * a sub-page/table, and named databases (just N_TREE). */ typedef struct node { #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ union { @@ -2602,9 +2602,9 @@ typedef struct node { #define NODESIZE 8u typedef enum node_flags { - N_BIGDATA = 0x01 /* data put on large page */, - N_SUBDATA = 0x02 /* data is a sub-database */, - N_DUPDATA = 0x04 /* data has duplicates */ + N_BIG = 0x01 /* data put on large page */, + N_TREE = 0x02 /* data is a b-tree */, + N_DUP = 0x04 /* data has duplicates */ } node_flags_t; #pragma pack(pop) @@ -3535,15 +3535,15 @@ static void print_stat(MDBX_stat *ms) { static void usage(const char *prog) { fprintf(stderr, - "usage: %s [-V] [-q] [-e] [-f[f[f]]] [-r[r]] [-a|-s name] dbpath\n" + "usage: %s [-V] [-q] [-e] [-f[f[f]]] [-r[r]] [-a|-s table] dbpath\n" " -V\t\tprint version and exit\n" " -q\t\tbe quiet\n" " -p\t\tshow statistics of page operations for current session\n" " -e\t\tshow whole DB info\n" " -f\t\tshow GC info\n" " -r\t\tshow readers\n" - " -a\t\tprint stat of main DB and all subDBs\n" - " -s name\tprint stat of only the specified named subDB\n" + " -a\t\tprint stat of main DB and all tables\n" + " -s table\tprint stat of only the specified named table\n" " \t\tby default print stat of only the main DB\n", prog); exit(EXIT_FAILURE); @@ -3592,7 +3592,7 @@ int main(int argc, char *argv[]) { MDBX_envinfo mei; prog = argv[0]; char *envname; - char *subname = nullptr; + char *table = nullptr; bool alldbs = false, envinfo = false, pgop = false; int freinfo = 0, rdrinfo = 0; @@ -3631,7 +3631,7 @@ int main(int argc, char *argv[]) { pgop = true; break; case 'a': - if (subname) + if (table) usage(prog); alldbs = true; break; @@ -3649,7 +3649,7 @@ int main(int argc, char *argv[]) { case 's': if (alldbs) usage(prog); - subname = optarg; + table = optarg; break; default: usage(prog); @@ -3687,7 +3687,7 @@ int main(int argc, char *argv[]) { return EXIT_FAILURE; } - if (alldbs || subname) { + if (alldbs || table) { rc = mdbx_env_set_maxdbs(env, 2); if (unlikely(rc != MDBX_SUCCESS)) { error("mdbx_env_set_maxdbs", rc); @@ -3815,7 +3815,7 @@ int main(int argc, char *argv[]) { } else printf(" No stale readers.\n"); } - if (!(subname || alldbs || freinfo)) + if (!(table || alldbs || freinfo)) goto txn_abort; } @@ -3938,7 +3938,7 @@ int main(int argc, char *argv[]) { printf(" GC: %" PRIaPGNO " pages\n", pages); } - rc = mdbx_dbi_open(txn, subname, MDBX_DB_ACCEDE, &dbi); + rc = mdbx_dbi_open(txn, table, MDBX_DB_ACCEDE, &dbi); if (unlikely(rc != MDBX_SUCCESS)) { error("mdbx_dbi_open", rc); goto txn_abort; @@ -3950,7 +3950,7 @@ int main(int argc, char *argv[]) { error("mdbx_dbi_stat", rc); goto txn_abort; } - printf("Status of %s\n", subname ? subname : "Main DB"); + printf("Status of %s\n", table ? table : "Main DB"); print_stat(&mst); if (alldbs) { @@ -3964,16 +3964,16 @@ int main(int argc, char *argv[]) { MDBX_val key; while (MDBX_SUCCESS == (rc = mdbx_cursor_get(cursor, &key, nullptr, MDBX_NEXT_NODUP))) { - MDBX_dbi subdbi; + MDBX_dbi xdbi; if (memchr(key.iov_base, '\0', key.iov_len)) continue; - subname = osal_malloc(key.iov_len + 1); - memcpy(subname, key.iov_base, key.iov_len); - subname[key.iov_len] = '\0'; - rc = mdbx_dbi_open(txn, subname, MDBX_DB_ACCEDE, &subdbi); + table = osal_malloc(key.iov_len + 1); + memcpy(table, key.iov_base, key.iov_len); + table[key.iov_len] = '\0'; + rc = mdbx_dbi_open(txn, table, MDBX_DB_ACCEDE, &xdbi); if (rc == MDBX_SUCCESS) - printf("Status of %s\n", subname); - osal_free(subname); + printf("Status of %s\n", table); + osal_free(table); if (unlikely(rc != MDBX_SUCCESS)) { if (rc == MDBX_INCOMPATIBLE) continue; @@ -3981,14 +3981,14 @@ int main(int argc, char *argv[]) { goto txn_abort; } - rc = mdbx_dbi_stat(txn, subdbi, &mst, sizeof(mst)); + rc = mdbx_dbi_stat(txn, xdbi, &mst, sizeof(mst)); if (unlikely(rc != MDBX_SUCCESS)) { error("mdbx_dbi_stat", rc); goto txn_abort; } print_stat(&mst); - rc = mdbx_dbi_close(env, subdbi); + rc = mdbx_dbi_close(env, xdbi); if (unlikely(rc != MDBX_SUCCESS)) { error("mdbx_dbi_close", rc); goto txn_abort;