mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-16 01:04:31 +08:00
mdbx: добавление mdbx_cursor_count_ex()
в API.
This commit is contained in:
parent
90b187c3ba
commit
526ed28de1
28
mdbx.h
28
mdbx.h
@ -5701,9 +5701,11 @@ LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, const MDBX_val *key, MDBX_v
|
|||||||
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
||||||
LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags);
|
LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags);
|
||||||
|
|
||||||
/** \brief Return count of duplicates for current key.
|
/** \brief Return count values (aka duplicates) for current key.
|
||||||
* \ingroup c_crud
|
* \ingroup c_crud
|
||||||
*
|
*
|
||||||
|
* \see mdbx_cursor_count_ex
|
||||||
|
*
|
||||||
* This call is valid for all tables, 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.
|
* sorted duplicate data items \ref MDBX_DUPSORT.
|
||||||
*
|
*
|
||||||
@ -5718,6 +5720,30 @@ LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, MDBX_put_flags_t flags);
|
|||||||
* was specified. */
|
* was specified. */
|
||||||
LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *pcount);
|
LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *pcount);
|
||||||
|
|
||||||
|
/** \brief Return count values (aka duplicates) and nested b-tree statistics for current key.
|
||||||
|
* \ingroup c_crud
|
||||||
|
*
|
||||||
|
* \see mdbx_dbi_stat
|
||||||
|
* \see mdbx_dbi_dupsort_depthmask
|
||||||
|
* \see mdbx_cursor_count
|
||||||
|
*
|
||||||
|
* 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().
|
||||||
|
* \param [out] pcount Address where the count will be stored.
|
||||||
|
* \param [out] stat The address of an \ref MDBX_stat structure where
|
||||||
|
* the statistics of a nested b-tree will be copied.
|
||||||
|
* \param [in] bytes The size of \ref MDBX_stat.
|
||||||
|
*
|
||||||
|
* \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_EINVAL Cursor is not initialized, or an invalid parameter
|
||||||
|
* was specified. */
|
||||||
|
LIBMDBX_API int mdbx_cursor_count_ex(const MDBX_cursor *mc, size_t *count, MDBX_stat *stat, size_t bytes);
|
||||||
|
|
||||||
/** \brief Determines whether the cursor is pointed to a key-value pair or not,
|
/** \brief Determines whether the cursor is pointed to a key-value pair or not,
|
||||||
* i.e. was not positioned or points to the end of data.
|
* i.e. was not positioned or points to the end of data.
|
||||||
* \ingroup c_cursors
|
* \ingroup c_cursors
|
||||||
|
@ -308,8 +308,7 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r, bool ignore_
|
|||||||
return (l->flags & z_eof_hard) - (r->flags & z_eof_hard);
|
return (l->flags & z_eof_hard) - (r->flags & z_eof_hard);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Return the count of duplicate data items for the current key */
|
int mdbx_cursor_count_ex(const MDBX_cursor *mc, size_t *count, MDBX_stat *ns, size_t bytes) {
|
||||||
int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
|
|
||||||
if (unlikely(mc == nullptr))
|
if (unlikely(mc == nullptr))
|
||||||
return LOG_IFERR(MDBX_EINVAL);
|
return LOG_IFERR(MDBX_EINVAL);
|
||||||
|
|
||||||
@ -320,21 +319,51 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
|
|||||||
if (unlikely(rc != MDBX_SUCCESS))
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
return LOG_IFERR(rc);
|
return LOG_IFERR(rc);
|
||||||
|
|
||||||
if (unlikely(countp == nullptr))
|
if (ns) {
|
||||||
return LOG_IFERR(MDBX_EINVAL);
|
const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid);
|
||||||
|
if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid)
|
||||||
|
return LOG_IFERR(MDBX_EINVAL);
|
||||||
|
memset(ns, 0, sizeof(*ns));
|
||||||
|
}
|
||||||
|
|
||||||
if ((*countp = is_filled(mc)) > 0) {
|
size_t nvals = 0;
|
||||||
|
if (is_filled(mc)) {
|
||||||
|
nvals = 1;
|
||||||
if (!inner_hollow(mc)) {
|
if (!inner_hollow(mc)) {
|
||||||
const page_t *mp = mc->pg[mc->top];
|
const page_t *mp = mc->pg[mc->top];
|
||||||
const node_t *node = page_node(mp, mc->ki[mc->top]);
|
const node_t *node = page_node(mp, mc->ki[mc->top]);
|
||||||
cASSERT(mc, node_flags(node) & N_DUP);
|
cASSERT(mc, node_flags(node) & N_DUP);
|
||||||
*countp =
|
const tree_t *nt = &mc->subcur->nested_tree;
|
||||||
unlikely(mc->subcur->nested_tree.items > PTRDIFF_MAX) ? PTRDIFF_MAX : (size_t)mc->subcur->nested_tree.items;
|
nvals = unlikely(nt->items > PTRDIFF_MAX) ? PTRDIFF_MAX : (size_t)nt->items;
|
||||||
|
if (ns) {
|
||||||
|
ns->ms_psize = (unsigned)node_ds(node);
|
||||||
|
if (node_flags(node) & N_TREE) {
|
||||||
|
ns->ms_psize = mc->txn->env->ps;
|
||||||
|
ns->ms_depth = nt->height;
|
||||||
|
ns->ms_branch_pages = nt->branch_pages;
|
||||||
|
}
|
||||||
|
cASSERT(mc, nt->large_pages == 0);
|
||||||
|
ns->ms_leaf_pages = nt->leaf_pages;
|
||||||
|
ns->ms_entries = nt->items;
|
||||||
|
if (likely(bytes >= offsetof(MDBX_stat, ms_mod_txnid) + sizeof(ns->ms_mod_txnid)))
|
||||||
|
ns->ms_mod_txnid = nt->mod_txnid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (likely(count))
|
||||||
|
*count = nvals;
|
||||||
|
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int mdbx_cursor_count(const MDBX_cursor *mc, size_t *count) {
|
||||||
|
if (unlikely(count == nullptr))
|
||||||
|
return LOG_IFERR(MDBX_EINVAL);
|
||||||
|
|
||||||
|
return mdbx_cursor_count_ex(mc, count, nullptr, 0);
|
||||||
|
}
|
||||||
|
|
||||||
int mdbx_cursor_on_first(const MDBX_cursor *mc) {
|
int mdbx_cursor_on_first(const MDBX_cursor *mc) {
|
||||||
if (unlikely(mc == nullptr))
|
if (unlikely(mc == nullptr))
|
||||||
return LOG_IFERR(MDBX_EINVAL);
|
return LOG_IFERR(MDBX_EINVAL);
|
||||||
|
@ -62,7 +62,7 @@ typedef struct tree {
|
|||||||
uint16_t height; /* height of this tree */
|
uint16_t height; /* height of this tree */
|
||||||
uint32_t dupfix_size; /* key-size for MDBX_DUPFIXED (DUPFIX pages) */
|
uint32_t dupfix_size; /* key-size for MDBX_DUPFIXED (DUPFIX pages) */
|
||||||
pgno_t root; /* the root page of this tree */
|
pgno_t root; /* the root page of this tree */
|
||||||
pgno_t branch_pages; /* number of internal pages */
|
pgno_t branch_pages; /* number of branch pages */
|
||||||
pgno_t leaf_pages; /* number of leaf pages */
|
pgno_t leaf_pages; /* number of leaf pages */
|
||||||
pgno_t large_pages; /* number of large pages */
|
pgno_t large_pages; /* number of large pages */
|
||||||
uint64_t sequence; /* table sequence counter */
|
uint64_t sequence; /* table sequence counter */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user