mirror of
https://github.com/isar/libmdbx.git
synced 2025-02-01 12:48:21 +08:00
mdbx: add mdbx_dpl_alloc()
& mdbx_dpl_free()
.
Change-Id: I0f05ff02d4a45d02faa1076cbb1a2a8e17b7e2b9
This commit is contained in:
parent
c530c83337
commit
5636dbf12b
84
src/core.c
84
src/core.c
@ -2977,6 +2977,35 @@ static int __must_check_result mdbx_txl_append(MDBX_TXL *ptl, txnid_t id) {
|
|||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
static __always_inline size_t dpl2bytes(const ptrdiff_t size) {
|
||||||
|
assert(size > 0 && size <= MDBX_PGL_LIMIT);
|
||||||
|
return (size + 1) * sizeof(MDBX_DP);
|
||||||
|
}
|
||||||
|
|
||||||
|
static __always_inline void mdbx_dpl_clear(MDBX_DPL dl) {
|
||||||
|
dl->sorted = dl->length = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void mdbx_dpl_free(MDBX_txn *txn) {
|
||||||
|
if (likely(txn->tw.dirtylist)) {
|
||||||
|
mdbx_free(txn->tw.dirtylist);
|
||||||
|
txn->tw.dirtylist = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int mdbx_dpl_alloc(MDBX_txn *txn) {
|
||||||
|
mdbx_tassert(txn,
|
||||||
|
(txn->mt_flags & MDBX_TXN_RDONLY) == 0 && !txn->tw.dirtylist);
|
||||||
|
unsigned limit = /* TODO */ MDBX_DPL_TXNFULL;
|
||||||
|
size_t bytes = dpl2bytes(limit);
|
||||||
|
MDBX_DPL dl = mdbx_malloc(bytes);
|
||||||
|
if (unlikely(!dl))
|
||||||
|
return MDBX_ENOMEM;
|
||||||
|
mdbx_dpl_clear(dl);
|
||||||
|
txn->tw.dirtylist = dl;
|
||||||
|
return MDBX_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
#define DP_SORT_CMP(first, last) ((first).pgno < (last).pgno)
|
#define DP_SORT_CMP(first, last) ((first).pgno < (last).pgno)
|
||||||
SORT_IMPL(dp_sort, false, MDBX_DP, DP_SORT_CMP)
|
SORT_IMPL(dp_sort, false, MDBX_DP, DP_SORT_CMP)
|
||||||
static __always_inline MDBX_DPL mdbx_dpl_sort(MDBX_DPL dl) {
|
static __always_inline MDBX_DPL mdbx_dpl_sort(MDBX_DPL dl) {
|
||||||
@ -3071,7 +3100,8 @@ static __hot MDBX_page *mdbx_dpl_remove(MDBX_DPL dl, pgno_t prno) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline int __must_check_result
|
static __always_inline int __must_check_result
|
||||||
mdbx_dpl_append(MDBX_DPL dl, pgno_t pgno, MDBX_page *page) {
|
mdbx_dpl_append(MDBX_txn *txn, pgno_t pgno, MDBX_page *page) {
|
||||||
|
MDBX_DPL dl = txn->tw.dirtylist;
|
||||||
assert(dl->length <= MDBX_PGL_LIMIT);
|
assert(dl->length <= MDBX_PGL_LIMIT);
|
||||||
if (mdbx_audit_enabled()) {
|
if (mdbx_audit_enabled()) {
|
||||||
for (unsigned i = dl->length; i > 0; --i) {
|
for (unsigned i = dl->length; i > 0; --i) {
|
||||||
@ -3094,10 +3124,6 @@ mdbx_dpl_append(MDBX_DPL dl, pgno_t pgno, MDBX_page *page) {
|
|||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static __always_inline void mdbx_dpl_clear(MDBX_DPL dl) {
|
|
||||||
dl->sorted = dl->length = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*----------------------------------------------------------------------------*/
|
/*----------------------------------------------------------------------------*/
|
||||||
|
|
||||||
uint8_t mdbx_runtime_flags = MDBX_RUNTIME_FLAGS_INIT;
|
uint8_t mdbx_runtime_flags = MDBX_RUNTIME_FLAGS_INIT;
|
||||||
@ -4638,7 +4664,7 @@ static __cold pgno_t mdbx_find_largest(MDBX_env *env, pgno_t largest) {
|
|||||||
static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
static int __must_check_result mdbx_page_dirty(MDBX_txn *txn, MDBX_page *mp) {
|
||||||
mp->mp_txnid = INVALID_TXNID;
|
mp->mp_txnid = INVALID_TXNID;
|
||||||
mp->mp_flags |= P_DIRTY;
|
mp->mp_flags |= P_DIRTY;
|
||||||
const int rc = mdbx_dpl_append(txn->tw.dirtylist, mp->mp_pgno, mp);
|
const int rc = mdbx_dpl_append(txn, mp->mp_pgno, mp);
|
||||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
txn->mt_flags |= MDBX_TXN_ERROR;
|
txn->mt_flags |= MDBX_TXN_ERROR;
|
||||||
return rc;
|
return rc;
|
||||||
@ -5691,7 +5717,7 @@ __hot static int mdbx_page_touch(MDBX_cursor *mc) {
|
|||||||
rc = MDBX_ENOMEM;
|
rc = MDBX_ENOMEM;
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
rc = mdbx_dpl_append(txn->tw.dirtylist, pgno, np);
|
rc = mdbx_dpl_append(txn, pgno, np);
|
||||||
if (unlikely(rc)) {
|
if (unlikely(rc)) {
|
||||||
mdbx_dpage_free(txn->mt_env, np, 1);
|
mdbx_dpage_free(txn->mt_env, np, 1);
|
||||||
goto fail;
|
goto fail;
|
||||||
@ -6606,16 +6632,20 @@ int mdbx_txn_begin_ex(MDBX_env *env, MDBX_txn *parent, MDBX_txn_flags_t flags,
|
|||||||
mdbx_tassert(txn, mdbx_dirtylist_check(parent));
|
mdbx_tassert(txn, mdbx_dirtylist_check(parent));
|
||||||
txn->tw.cursors = (MDBX_cursor **)(txn->mt_dbs + env->me_maxdbs);
|
txn->tw.cursors = (MDBX_cursor **)(txn->mt_dbs + env->me_maxdbs);
|
||||||
txn->mt_dbiseqs = parent->mt_dbiseqs;
|
txn->mt_dbiseqs = parent->mt_dbiseqs;
|
||||||
txn->tw.dirtylist = mdbx_malloc(sizeof(MDBX_DP) * (MDBX_DPL_TXNFULL + 1));
|
rc = mdbx_dpl_alloc(txn);
|
||||||
txn->tw.reclaimed_pglist =
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
mdbx_pnl_alloc(MDBX_PNL_ALLOCLEN(parent->tw.reclaimed_pglist));
|
txn->tw.reclaimed_pglist =
|
||||||
if (!txn->tw.dirtylist || !txn->tw.reclaimed_pglist) {
|
mdbx_pnl_alloc(MDBX_PNL_ALLOCLEN(parent->tw.reclaimed_pglist));
|
||||||
mdbx_pnl_free(txn->tw.reclaimed_pglist);
|
if (unlikely(!txn->tw.reclaimed_pglist))
|
||||||
mdbx_free(txn->tw.dirtylist);
|
rc = MDBX_ENOMEM;
|
||||||
mdbx_free(txn);
|
|
||||||
return MDBX_ENOMEM;
|
|
||||||
}
|
}
|
||||||
mdbx_dpl_clear(txn->tw.dirtylist);
|
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||||
|
mdbx_pnl_free(txn->tw.reclaimed_pglist);
|
||||||
|
mdbx_dpl_free(txn);
|
||||||
|
mdbx_free(txn);
|
||||||
|
return rc;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(txn->tw.reclaimed_pglist, parent->tw.reclaimed_pglist,
|
memcpy(txn->tw.reclaimed_pglist, parent->tw.reclaimed_pglist,
|
||||||
MDBX_PNL_SIZEOF(parent->tw.reclaimed_pglist));
|
MDBX_PNL_SIZEOF(parent->tw.reclaimed_pglist));
|
||||||
mdbx_assert(env, mdbx_pnl_check4assert(
|
mdbx_assert(env, mdbx_pnl_check4assert(
|
||||||
@ -6971,7 +7001,7 @@ static int mdbx_txn_end(MDBX_txn *txn, unsigned mode) {
|
|||||||
parent->tw.retired_pages = txn->tw.retired_pages;
|
parent->tw.retired_pages = txn->tw.retired_pages;
|
||||||
}
|
}
|
||||||
|
|
||||||
mdbx_free(txn->tw.dirtylist);
|
mdbx_dpl_free(txn);
|
||||||
parent->mt_child = NULL;
|
parent->mt_child = NULL;
|
||||||
parent->mt_flags &= ~MDBX_TXN_HAS_CHILD;
|
parent->mt_flags &= ~MDBX_TXN_HAS_CHILD;
|
||||||
|
|
||||||
@ -8336,8 +8366,7 @@ int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency) {
|
|||||||
}
|
}
|
||||||
assert(l == 0);
|
assert(l == 0);
|
||||||
dst->length = dst->sorted;
|
dst->length = dst->sorted;
|
||||||
mdbx_free(txn->tw.dirtylist);
|
mdbx_dpl_free(txn);
|
||||||
txn->tw.dirtylist = nullptr;
|
|
||||||
mdbx_tassert(parent,
|
mdbx_tassert(parent,
|
||||||
parent->mt_parent ||
|
parent->mt_parent ||
|
||||||
parent->tw.dirtyroom + parent->tw.dirtylist->length ==
|
parent->tw.dirtyroom + parent->tw.dirtylist->length ==
|
||||||
@ -10893,12 +10922,13 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
|||||||
txn->mt_dbxs = env->me_dbxs;
|
txn->mt_dbxs = env->me_dbxs;
|
||||||
txn->mt_flags = MDBX_TXN_FINISHED;
|
txn->mt_flags = MDBX_TXN_FINISHED;
|
||||||
env->me_txn0 = txn;
|
env->me_txn0 = txn;
|
||||||
txn->tw.retired_pages = mdbx_pnl_alloc(MDBX_PNL_INITIAL);
|
rc = mdbx_dpl_alloc(txn);
|
||||||
txn->tw.reclaimed_pglist = mdbx_pnl_alloc(MDBX_PNL_INITIAL);
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
txn->tw.dirtylist = mdbx_malloc(sizeof(MDBX_DP) * (MDBX_DPL_TXNFULL + 1));
|
txn->tw.retired_pages = mdbx_pnl_alloc(MDBX_PNL_INITIAL);
|
||||||
if (!txn->tw.retired_pages || !txn->tw.reclaimed_pglist ||
|
txn->tw.reclaimed_pglist = mdbx_pnl_alloc(MDBX_PNL_INITIAL);
|
||||||
!txn->tw.dirtylist)
|
if (unlikely(!txn->tw.retired_pages || !txn->tw.reclaimed_pglist))
|
||||||
rc = MDBX_ENOMEM;
|
rc = MDBX_ENOMEM;
|
||||||
|
}
|
||||||
} else
|
} else
|
||||||
rc = MDBX_ENOMEM;
|
rc = MDBX_ENOMEM;
|
||||||
}
|
}
|
||||||
@ -10997,7 +11027,7 @@ static __cold int mdbx_env_close0(MDBX_env *env) {
|
|||||||
mdbx_free(env->me_dbflags);
|
mdbx_free(env->me_dbflags);
|
||||||
mdbx_free(env->me_pathname);
|
mdbx_free(env->me_pathname);
|
||||||
if (env->me_txn0) {
|
if (env->me_txn0) {
|
||||||
mdbx_free(env->me_txn0->tw.dirtylist);
|
mdbx_dpl_free(env->me_txn0);
|
||||||
mdbx_txl_free(env->me_txn0->tw.lifo_reclaimed);
|
mdbx_txl_free(env->me_txn0->tw.lifo_reclaimed);
|
||||||
mdbx_pnl_free(env->me_txn0->tw.retired_pages);
|
mdbx_pnl_free(env->me_txn0->tw.retired_pages);
|
||||||
mdbx_pnl_free(env->me_txn0->tw.spill_pages);
|
mdbx_pnl_free(env->me_txn0->tw.spill_pages);
|
||||||
@ -13044,7 +13074,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
|
|||||||
if (unlikely(!np))
|
if (unlikely(!np))
|
||||||
return MDBX_ENOMEM;
|
return MDBX_ENOMEM;
|
||||||
/* Note - this page is already counted in parent's dirtyroom */
|
/* Note - this page is already counted in parent's dirtyroom */
|
||||||
rc2 = mdbx_dpl_append(mc->mc_txn->tw.dirtylist, pg, np);
|
rc2 = mdbx_dpl_append(mc->mc_txn, pg, np);
|
||||||
if (unlikely(rc2 != MDBX_SUCCESS)) {
|
if (unlikely(rc2 != MDBX_SUCCESS)) {
|
||||||
rc = rc2;
|
rc = rc2;
|
||||||
mdbx_dpage_free(env, np, ovpages);
|
mdbx_dpage_free(env, np, ovpages);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user