mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:54:14 +08:00
mdbx: add mdbx_env_info2(txn) and mdbx_env_stat2(txn).
Change-Id: Ifd128185a084c9dc61da140eeeaaf4b6022d3537
This commit is contained in:
parent
d6a2f98ef5
commit
17407c9ecc
4
mdbx.h
4
mdbx.h
@ -735,6 +735,8 @@ LIBMDBX_API int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
||||
* [out] stat The address of an MDBX_stat structure where the statistics
|
||||
* will be copied */
|
||||
LIBMDBX_API int mdbx_env_stat(MDBX_env *env, MDBX_stat *stat, size_t bytes);
|
||||
LIBMDBX_API int mdbx_env_stat2(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_stat *stat, size_t bytes);
|
||||
|
||||
/* Return information about the MDBX environment.
|
||||
*
|
||||
@ -742,6 +744,8 @@ LIBMDBX_API int mdbx_env_stat(MDBX_env *env, MDBX_stat *stat, size_t bytes);
|
||||
* [out] stat The address of an MDBX_envinfo structure
|
||||
* where the information will be copied */
|
||||
LIBMDBX_API int mdbx_env_info(MDBX_env *env, MDBX_envinfo *info, size_t bytes);
|
||||
LIBMDBX_API int mdbx_env_info2(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_envinfo *info, size_t bytes);
|
||||
|
||||
/* Flush the data buffers to disk.
|
||||
*
|
||||
|
107
src/mdbx.c
107
src/mdbx.c
@ -11966,7 +11966,8 @@ int __cold mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *arg) {
|
||||
* [in] db the MDBX_db record containing the stats to return.
|
||||
* [out] arg the address of an MDBX_stat structure to receive the stats.
|
||||
* Returns 0, this function always succeeds. */
|
||||
static int __cold mdbx_stat0(MDBX_env *env, MDBX_db *db, MDBX_stat *arg) {
|
||||
static int __cold mdbx_stat0(const MDBX_env *env, const MDBX_db *db,
|
||||
MDBX_stat *arg) {
|
||||
arg->ms_psize = env->me_psize;
|
||||
arg->ms_depth = db->md_depth;
|
||||
arg->ms_branch_pages = db->md_branch_pages;
|
||||
@ -11977,60 +11978,108 @@ static int __cold mdbx_stat0(MDBX_env *env, MDBX_db *db, MDBX_stat *arg) {
|
||||
}
|
||||
|
||||
int __cold mdbx_env_stat(MDBX_env *env, MDBX_stat *arg, size_t bytes) {
|
||||
MDBX_meta *meta;
|
||||
return mdbx_env_stat2(env, NULL, arg, bytes);
|
||||
}
|
||||
|
||||
if (unlikely(env == NULL || arg == NULL))
|
||||
int __cold mdbx_env_stat2(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_stat *arg, size_t bytes) {
|
||||
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (txn) {
|
||||
if (unlikely(txn->mt_signature != MDBX_MT_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (unlikely(txn->mt_owner != mdbx_thread_self()))
|
||||
return MDBX_THREAD_MISMATCH;
|
||||
}
|
||||
if (env) {
|
||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (txn && unlikely(txn->mt_env != env))
|
||||
return MDBX_EINVAL;
|
||||
}
|
||||
|
||||
if (unlikely(bytes != sizeof(MDBX_stat)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
meta = mdbx_meta_head(env);
|
||||
return mdbx_stat0(env, &meta->mm_dbs[MAIN_DBI], arg);
|
||||
const MDBX_db *db =
|
||||
txn ? &txn->mt_dbs[MAIN_DBI] : &mdbx_meta_head(env)->mm_dbs[MAIN_DBI];
|
||||
return mdbx_stat0(txn->mt_env, db, arg);
|
||||
}
|
||||
|
||||
int __cold mdbx_env_info(MDBX_env *env, MDBX_envinfo *arg, size_t bytes) {
|
||||
if (unlikely(env == NULL || arg == NULL))
|
||||
return mdbx_env_info2(env, NULL, arg, bytes);
|
||||
}
|
||||
|
||||
int __cold mdbx_env_info2(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_envinfo *arg, size_t bytes) {
|
||||
if (unlikely((env == NULL && txn == NULL) || arg == NULL))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (txn) {
|
||||
if (unlikely(txn->mt_signature != MDBX_MT_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (unlikely(txn->mt_owner != mdbx_thread_self()))
|
||||
return MDBX_THREAD_MISMATCH;
|
||||
}
|
||||
if (env) {
|
||||
if (unlikely(env->me_signature != MDBX_ME_SIGNATURE))
|
||||
return MDBX_EBADSIGN;
|
||||
if (txn && unlikely(txn->mt_env != env))
|
||||
return MDBX_EINVAL;
|
||||
} else {
|
||||
env = txn->mt_env;
|
||||
}
|
||||
|
||||
if (bytes != sizeof(MDBX_envinfo))
|
||||
if (unlikely(bytes != sizeof(MDBX_envinfo)))
|
||||
return MDBX_EINVAL;
|
||||
|
||||
const MDBX_meta *const meta0 = METAPAGE(env, 0);
|
||||
const MDBX_meta *const meta1 = METAPAGE(env, 1);
|
||||
const MDBX_meta *const meta2 = METAPAGE(env, 2);
|
||||
const MDBX_meta *meta;
|
||||
do {
|
||||
meta = mdbx_meta_head(env);
|
||||
arg->mi_recent_txnid = mdbx_meta_txnid_fluid(env, meta);
|
||||
while (1) {
|
||||
if (unlikely(env->me_flags & MDBX_FATAL_ERROR))
|
||||
return MDBX_PANIC;
|
||||
|
||||
const MDBX_meta *const recent_meta = mdbx_meta_head(env);
|
||||
arg->mi_recent_txnid = mdbx_meta_txnid_fluid(env, recent_meta);
|
||||
arg->mi_meta0_txnid = mdbx_meta_txnid_fluid(env, meta0);
|
||||
arg->mi_meta0_sign = meta0->mm_datasync_sign;
|
||||
arg->mi_meta1_txnid = mdbx_meta_txnid_fluid(env, meta1);
|
||||
arg->mi_meta1_sign = meta1->mm_datasync_sign;
|
||||
arg->mi_meta2_txnid = mdbx_meta_txnid_fluid(env, meta2);
|
||||
arg->mi_meta2_sign = meta2->mm_datasync_sign;
|
||||
arg->mi_last_pgno = meta->mm_geo.next - 1;
|
||||
arg->mi_geo.lower = pgno2bytes(env, meta->mm_geo.lower);
|
||||
arg->mi_geo.upper = pgno2bytes(env, meta->mm_geo.upper);
|
||||
arg->mi_geo.current = pgno2bytes(env, meta->mm_geo.now);
|
||||
arg->mi_geo.shrink = pgno2bytes(env, meta->mm_geo.shrink);
|
||||
arg->mi_geo.grow = pgno2bytes(env, meta->mm_geo.grow);
|
||||
|
||||
const MDBX_meta *txn_meta = recent_meta;
|
||||
arg->mi_last_pgno = txn_meta->mm_geo.next - 1;
|
||||
arg->mi_geo.current = pgno2bytes(env, txn_meta->mm_geo.now);
|
||||
if (txn) {
|
||||
arg->mi_last_pgno = txn->mt_next_pgno - 1;
|
||||
arg->mi_geo.current = pgno2bytes(env, txn->mt_end_pgno);
|
||||
|
||||
const txnid_t wanna_meta_txnid =
|
||||
(txn->mt_flags & MDBX_RDONLY) ? txn->mt_txnid : txn->mt_txnid - 1;
|
||||
txn_meta = (arg->mi_meta0_txnid == wanna_meta_txnid) ? meta0 : txn_meta;
|
||||
txn_meta = (arg->mi_meta1_txnid == wanna_meta_txnid) ? meta1 : txn_meta;
|
||||
txn_meta = (arg->mi_meta2_txnid == wanna_meta_txnid) ? meta2 : txn_meta;
|
||||
}
|
||||
arg->mi_geo.lower = pgno2bytes(env, txn_meta->mm_geo.lower);
|
||||
arg->mi_geo.upper = pgno2bytes(env, txn_meta->mm_geo.upper);
|
||||
arg->mi_geo.shrink = pgno2bytes(env, txn_meta->mm_geo.shrink);
|
||||
arg->mi_geo.grow = pgno2bytes(env, txn_meta->mm_geo.grow);
|
||||
|
||||
arg->mi_mapsize = env->me_mapsize;
|
||||
mdbx_compiler_barrier();
|
||||
} while (unlikely(arg->mi_meta0_txnid != mdbx_meta_txnid_fluid(env, meta0) ||
|
||||
arg->mi_meta0_sign != meta0->mm_datasync_sign ||
|
||||
arg->mi_meta1_txnid != mdbx_meta_txnid_fluid(env, meta1) ||
|
||||
arg->mi_meta1_sign != meta1->mm_datasync_sign ||
|
||||
arg->mi_meta2_txnid != mdbx_meta_txnid_fluid(env, meta2) ||
|
||||
arg->mi_meta2_sign != meta2->mm_datasync_sign ||
|
||||
meta != mdbx_meta_head(env) ||
|
||||
arg->mi_recent_txnid != mdbx_meta_txnid_fluid(env, meta)));
|
||||
if (likely(arg->mi_meta0_txnid == mdbx_meta_txnid_fluid(env, meta0) &&
|
||||
arg->mi_meta0_sign == meta0->mm_datasync_sign &&
|
||||
arg->mi_meta1_txnid == mdbx_meta_txnid_fluid(env, meta1) &&
|
||||
arg->mi_meta1_sign == meta1->mm_datasync_sign &&
|
||||
arg->mi_meta2_txnid == mdbx_meta_txnid_fluid(env, meta2) &&
|
||||
arg->mi_meta2_sign == meta2->mm_datasync_sign &&
|
||||
recent_meta == mdbx_meta_head(env) &&
|
||||
arg->mi_recent_txnid == mdbx_meta_txnid_fluid(env, recent_meta)))
|
||||
break;
|
||||
}
|
||||
|
||||
arg->mi_maxreaders = env->me_maxreaders;
|
||||
arg->mi_numreaders = env->me_lck ? env->me_lck->mti_numreaders : INT32_MAX;
|
||||
|
Loading…
x
Reference in New Issue
Block a user