mdbx: refine find_oldest() and meta_head().

This commit is contained in:
Leo Yuriev 2017-05-28 13:04:36 +03:00
parent 91bc3129d5
commit 2ea97ae281

View File

@ -1273,25 +1273,29 @@ bailout:
#define METAPAGE_END(env) METAPAGE(env, NUM_METAS) #define METAPAGE_END(env) METAPAGE(env, NUM_METAS)
static __inline txnid_t mdbx_meta_txnid(const MDBX_env *env, static __inline txnid_t meta_txnid(const MDBX_env *env, const MDBX_meta *meta,
const MDBX_meta *meta, bool allow_volatile) {
bool allow_volatile) {
mdbx_assert(env, meta >= METAPAGE(env, 0) || meta < METAPAGE_END(env)); mdbx_assert(env, meta >= METAPAGE(env, 0) || meta < METAPAGE_END(env));
txnid_t top = meta->mm_txnid_top; txnid_t top = meta->mm_txnid_top;
txnid_t bottom = meta->mm_txnid_bottom; txnid_t bottom = meta->mm_txnid_bottom;
if (!allow_volatile) if (allow_volatile)
return (top < bottom) ? top : bottom;
if (unlikely(top != bottom)) {
mdbx_error("top %" PRIaTXN " != bottom %" PRIaTXN, top, bottom);
*(char *)0 = 0;
mdbx_assert(env, top == bottom); mdbx_assert(env, top == bottom);
return (top < bottom) ? top : bottom; }
return top;
} }
static __inline txnid_t mdbx_meta_txnid_stable(const MDBX_env *env, static __inline txnid_t mdbx_meta_txnid_stable(const MDBX_env *env,
const MDBX_meta *meta) { const MDBX_meta *meta) {
return mdbx_meta_txnid(env, meta, false); return meta_txnid(env, meta, false);
} }
static __inline txnid_t mdbx_meta_txnid_fluid(const MDBX_env *env, static __inline txnid_t mdbx_meta_txnid_fluid(const MDBX_env *env,
const MDBX_meta *meta) { const MDBX_meta *meta) {
return mdbx_meta_txnid(env, meta, true); return meta_txnid(env, meta, true);
} }
static __inline void mdbx_meta_update_begin(const MDBX_env *env, static __inline void mdbx_meta_update_begin(const MDBX_env *env,
@ -1425,10 +1429,11 @@ static const char *mdbx_durable_str(const MDBX_meta *const meta) {
/*----------------------------------------------------------------------------*/ /*----------------------------------------------------------------------------*/
/* Find oldest txnid still referenced. */ /* Find oldest txnid still referenced. */
static txnid_t mdbx_find_oldest(MDBX_env *env, int *laggard) { static txnid_t mdbx_find_oldest(MDBX_txn *txn, int *laggard) {
MDBX_env *env = txn->mt_env;
const MDBX_meta *const head = mdbx_meta_mostrecent( const MDBX_meta *const head = mdbx_meta_mostrecent(
env, F_ISSET(env->me_flags, MDBX_UTTERLY_NOSYNC) ? false : true); env, F_ISSET(env->me_flags, MDBX_UTTERLY_NOSYNC) ? false : true);
txnid_t oldest = mdbx_meta_txnid_stable(env, head); txnid_t oldest = meta_txnid(env, head, (txn->mt_flags & MDBX_RDONLY) ? true : false);
int i, reader; int i, reader;
const MDBX_reader *const r = env->me_lck->mti_readers; const MDBX_reader *const r = env->me_lck->mti_readers;
@ -1560,7 +1565,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, int num, MDBX_page **mp,
mdbx_cursor_init(&m2, txn, FREE_DBI, NULL); mdbx_cursor_init(&m2, txn, FREE_DBI, NULL);
if (flags & MDBX_LIFORECLAIM) { if (flags & MDBX_LIFORECLAIM) {
if (!found_oldest) { if (!found_oldest) {
oldest = mdbx_find_oldest(env, NULL); oldest = mdbx_find_oldest(txn, NULL);
found_oldest = 1; found_oldest = 1;
} }
/* Begin from oldest reader if any */ /* Begin from oldest reader if any */
@ -1582,7 +1587,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, int num, MDBX_page **mp,
/* Do not fetch more if the record will be too recent */ /* Do not fetch more if the record will be too recent */
if (op != MDBX_FIRST && ++last >= oldest) { if (op != MDBX_FIRST && ++last >= oldest) {
if (!found_oldest) { if (!found_oldest) {
oldest = mdbx_find_oldest(env, NULL); oldest = mdbx_find_oldest(txn, NULL);
found_oldest = 1; found_oldest = 1;
} }
if (oldest <= last) if (oldest <= last)
@ -1595,7 +1600,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, int num, MDBX_page **mp,
if (op == MDBX_SET_RANGE) if (op == MDBX_SET_RANGE)
continue; continue;
found_oldest = 1; found_oldest = 1;
if (oldest < mdbx_find_oldest(env, NULL)) { if (oldest < mdbx_find_oldest(txn, NULL)) {
oldest = env->me_pgoldest; oldest = env->me_pgoldest;
last = oldest - 1; last = oldest - 1;
key.iov_base = &last; key.iov_base = &last;
@ -1613,7 +1618,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, int num, MDBX_page **mp,
last = *(txnid_t *)key.iov_base; last = *(txnid_t *)key.iov_base;
if (oldest <= last) { if (oldest <= last) {
if (!found_oldest) { if (!found_oldest) {
oldest = mdbx_find_oldest(env, NULL); oldest = mdbx_find_oldest(txn, NULL);
found_oldest = 1; found_oldest = 1;
} }
if (oldest <= last) { if (oldest <= last) {
@ -1745,7 +1750,7 @@ static int mdbx_page_alloc(MDBX_cursor *mc, int num, MDBX_page **mp,
mdbx_assert(env, env->me_sync_pending > 0); mdbx_assert(env, env->me_sync_pending > 0);
MDBX_meta meta = *head; MDBX_meta meta = *head;
if (mdbx_sync_locked(env, me_flags, &meta) == MDBX_SUCCESS) { if (mdbx_sync_locked(env, me_flags, &meta) == MDBX_SUCCESS) {
txnid_t snap = mdbx_find_oldest(env, NULL); txnid_t snap = mdbx_find_oldest(txn, NULL);
if (snap > oldest) { if (snap > oldest) {
continue; continue;
} }
@ -9571,7 +9576,7 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) {
if (mdbx_reader_check(env, NULL)) if (mdbx_reader_check(env, NULL))
break; break;
txnid_t snap = mdbx_find_oldest(env, &reader); txnid_t snap = mdbx_find_oldest(env->me_txn, &reader);
if (oldest < snap || reader < 0) { if (oldest < snap || reader < 0) {
if (retry && env->me_oom_func) { if (retry && env->me_oom_func) {
/* LY: notify end of oom-loop */ /* LY: notify end of oom-loop */
@ -9614,7 +9619,7 @@ static txnid_t __cold mdbx_oomkick(MDBX_env *env, txnid_t oldest) {
/* LY: notify end of oom-loop */ /* LY: notify end of oom-loop */
env->me_oom_func(env, 0, 0, oldest, 0, -retry); env->me_oom_func(env, 0, 0, oldest, 0, -retry);
} }
return mdbx_find_oldest(env, NULL); return mdbx_find_oldest(env->me_txn, NULL);
} }
int __cold mdbx_env_set_syncbytes(MDBX_env *env, size_t bytes) { int __cold mdbx_env_set_syncbytes(MDBX_env *env, size_t bytes) {