mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-01 22:54:12 +08:00
mdbx: add mdbx_dbi_dupsort_depthmask().
Change-Id: Ib056663f26baea517d6f2b9d58cd64c643619ef9
This commit is contained in:
parent
4dc7f0cb4b
commit
5cc1cb3f87
15
mdbx.h
15
mdbx.h
@ -2716,6 +2716,21 @@ __inline uint32_t mdbx_key_from_int32(const int32_t i32) {
|
|||||||
LIBMDBX_API int mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat,
|
LIBMDBX_API int mdbx_dbi_stat(MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *stat,
|
||||||
size_t bytes);
|
size_t bytes);
|
||||||
|
|
||||||
|
/* Retrieve depth (bitmask) information of nested dupsort (multi-value) B+trees
|
||||||
|
* for given database.
|
||||||
|
*
|
||||||
|
* [in] txn A transaction handle returned by mdbx_txn_begin().
|
||||||
|
* [in] dbi A database handle returned by mdbx_dbi_open().
|
||||||
|
* [out] mask The address of an uint32_t value where the bitmask
|
||||||
|
* will be stored.
|
||||||
|
*
|
||||||
|
* Returns A non-zero error value on failure and 0 on success, some
|
||||||
|
* possible errors are:
|
||||||
|
* - MDBX_EINVAL = an invalid parameter was specified.
|
||||||
|
* - MDBX_RESULT_TRUE = the dbi isn't a dupsort (multi-value) database. */
|
||||||
|
LIBMDBX_API int mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi,
|
||||||
|
uint32_t *mask);
|
||||||
|
|
||||||
/* Retrieve the DB flags and status for a database handle.
|
/* Retrieve the DB flags and status for a database handle.
|
||||||
*
|
*
|
||||||
* [in] txn A transaction handle returned by mdbx_txn_begin().
|
* [in] txn A transaction handle returned by mdbx_txn_begin().
|
||||||
|
50
src/core.c
50
src/core.c
@ -16129,6 +16129,56 @@ int __cold mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int __cold mdbx_dbi_dupsort_depthmask(MDBX_txn *txn, MDBX_dbi dbi,
|
||||||
|
uint32_t *mask) {
|
||||||
|
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
return rc;
|
||||||
|
|
||||||
|
if (unlikely(!mask))
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
if (unlikely(!mdbx_txn_dbi_exists(txn, dbi, DB_VALID)))
|
||||||
|
return MDBX_EINVAL;
|
||||||
|
|
||||||
|
MDBX_cursor_couple cx;
|
||||||
|
rc = mdbx_cursor_init(&cx.outer, txn, dbi);
|
||||||
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
return rc;
|
||||||
|
if ((cx.outer.mc_db->md_flags & MDBX_DUPSORT) == 0)
|
||||||
|
return MDBX_RESULT_TRUE;
|
||||||
|
|
||||||
|
MDBX_val key, data;
|
||||||
|
rc = mdbx_cursor_first(&cx.outer, &key, &data);
|
||||||
|
*mask = 0;
|
||||||
|
while (rc == MDBX_SUCCESS) {
|
||||||
|
const MDBX_node *node = page_node(cx.outer.mc_pg[cx.outer.mc_top],
|
||||||
|
cx.outer.mc_ki[cx.outer.mc_top]);
|
||||||
|
const MDBX_db *db = node_data(node);
|
||||||
|
const unsigned flags = node_flags(node);
|
||||||
|
switch (flags) {
|
||||||
|
case F_BIGDATA:
|
||||||
|
case 0:
|
||||||
|
/* single-value entry, deep = 0 */
|
||||||
|
*mask |= 1 << 0;
|
||||||
|
break;
|
||||||
|
case F_DUPDATA:
|
||||||
|
/* single sub-page, deep = 1 */
|
||||||
|
*mask |= 1 << 1;
|
||||||
|
break;
|
||||||
|
case F_DUPDATA | F_SUBDATA:
|
||||||
|
/* sub-tree */
|
||||||
|
*mask |= 1 << unaligned_peek_u16(1, &db->md_depth);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return MDBX_CORRUPTED;
|
||||||
|
}
|
||||||
|
rc = mdbx_cursor_next(&cx.outer, &key, &data, MDBX_NEXT_NODUP);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
|
||||||
|
}
|
||||||
|
|
||||||
int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) {
|
int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) {
|
||||||
return mdbx_env_info_ex(env, NULL, arg, bytes);
|
return mdbx_env_info_ex(env, NULL, arg, bytes);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user