mirror of
https://github.com/isar/libmdbx.git
synced 2024-10-30 11:29:19 +08:00
mdbx: refine page-type macros.
Change-Id: I9f331bf17c1de1a1402d66e8b4081f31133e2b59
This commit is contained in:
parent
a30828b457
commit
b6aace0825
14
src/bits.h
14
src/bits.h
@ -1069,15 +1069,19 @@ static __inline unsigned mdbx_log2(size_t value) {
|
|||||||
#define FILL_THRESHOLD 256
|
#define FILL_THRESHOLD 256
|
||||||
|
|
||||||
/* Test if a page is a leaf page */
|
/* Test if a page is a leaf page */
|
||||||
#define IS_LEAF(p) F_ISSET((p)->mp_flags, P_LEAF)
|
#define IS_LEAF(p) (((p)->mp_flags & P_LEAF) != 0)
|
||||||
/* Test if a page is a LEAF2 page */
|
/* Test if a page is a LEAF2 page */
|
||||||
#define IS_LEAF2(p) F_ISSET((p)->mp_flags, P_LEAF2)
|
#define IS_LEAF2(p) unlikely(((p)->mp_flags & P_LEAF2) != 0)
|
||||||
/* Test if a page is a branch page */
|
/* Test if a page is a branch page */
|
||||||
#define IS_BRANCH(p) F_ISSET((p)->mp_flags, P_BRANCH)
|
#define IS_BRANCH(p) (((p)->mp_flags & P_BRANCH) != 0)
|
||||||
/* Test if a page is an overflow page */
|
/* Test if a page is an overflow page */
|
||||||
#define IS_OVERFLOW(p) unlikely(F_ISSET((p)->mp_flags, P_OVERFLOW))
|
#define IS_OVERFLOW(p) unlikely(((p)->mp_flags & P_OVERFLOW) != 0)
|
||||||
/* Test if a page is a sub page */
|
/* Test if a page is a sub page */
|
||||||
#define IS_SUBP(p) F_ISSET((p)->mp_flags, P_SUBP)
|
#define IS_SUBP(p) (((p)->mp_flags & P_SUBP) != 0)
|
||||||
|
/* Test if a page is dirty */
|
||||||
|
#define IS_DIRTY(p) (((p)->mp_flags & P_DIRTY) != 0)
|
||||||
|
|
||||||
|
#define PAGETYPE(p) ((p)->mp_flags & (P_BRANCH | P_LEAF | P_LEAF2 | P_OVERFLOW))
|
||||||
|
|
||||||
/* The number of overflow pages needed to store the given size. */
|
/* The number of overflow pages needed to store the given size. */
|
||||||
#define OVPAGES(env, size) (bytes2pgno(env, PAGEHDRSZ - 1 + (size)) + 1)
|
#define OVPAGES(env, size) (bytes2pgno(env, PAGEHDRSZ - 1 + (size)) + 1)
|
||||||
|
36
src/mdbx.c
36
src/mdbx.c
@ -1313,7 +1313,7 @@ static const char *mdbx_leafnode_type(MDBX_node *n) {
|
|||||||
/* Display all the keys in the page. */
|
/* Display all the keys in the page. */
|
||||||
static void mdbx_page_list(MDBX_page *mp) {
|
static void mdbx_page_list(MDBX_page *mp) {
|
||||||
pgno_t pgno = mp->mp_pgno;
|
pgno_t pgno = mp->mp_pgno;
|
||||||
const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : "";
|
const char *type, *state = IS_DIRTY(mp) ? ", dirty" : "";
|
||||||
MDBX_node *node;
|
MDBX_node *node;
|
||||||
unsigned i, nkeys, nsize, total = 0;
|
unsigned i, nkeys, nsize, total = 0;
|
||||||
MDBX_val key;
|
MDBX_val key;
|
||||||
@ -1577,7 +1577,7 @@ static int mdbx_page_loose(MDBX_cursor *mc, MDBX_page *mp) {
|
|||||||
mc->mc_db->md_leaf_pages--;
|
mc->mc_db->md_leaf_pages--;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((mp->mp_flags & P_DIRTY) && mc->mc_dbi != FREE_DBI) {
|
if (IS_DIRTY(mp) && mc->mc_dbi != FREE_DBI) {
|
||||||
if (txn->mt_parent) {
|
if (txn->mt_parent) {
|
||||||
mdbx_cassert(mc, (txn->mt_env->me_flags & MDBX_WRITEMAP) == 0);
|
mdbx_cassert(mc, (txn->mt_env->me_flags & MDBX_WRITEMAP) == 0);
|
||||||
MDBX_DP *dl = txn->mt_rw_dirtylist;
|
MDBX_DP *dl = txn->mt_rw_dirtylist;
|
||||||
@ -1659,7 +1659,7 @@ static int mdbx_pages_xkeep(MDBX_cursor *mc, unsigned pflags, bool all) {
|
|||||||
/* Proceed to mx if it is at a sub-database */
|
/* Proceed to mx if it is at a sub-database */
|
||||||
if (!(mx && (mx->mx_cursor.mc_flags & C_INITIALIZED)))
|
if (!(mx && (mx->mx_cursor.mc_flags & C_INITIALIZED)))
|
||||||
break;
|
break;
|
||||||
if (!(mp && (mp->mp_flags & P_LEAF)))
|
if (!(mp && IS_LEAF(mp)))
|
||||||
break;
|
break;
|
||||||
leaf = NODEPTR(mp, m3->mc_ki[j - 1]);
|
leaf = NODEPTR(mp, m3->mc_ki[j - 1]);
|
||||||
if (!(leaf->mn_flags & F_SUBDATA))
|
if (!(leaf->mn_flags & F_SUBDATA))
|
||||||
@ -6742,9 +6742,9 @@ mapped:
|
|||||||
p = pgno2page(env, pgno);
|
p = pgno2page(env, pgno);
|
||||||
|
|
||||||
done:
|
done:
|
||||||
if ((p->mp_flags & P_OVERFLOW) == 0 &&
|
if (unlikely(p->mp_upper < p->mp_lower ||
|
||||||
unlikely(p->mp_upper < p->mp_lower ||
|
PAGEHDRSZ + p->mp_upper > env->me_psize) &&
|
||||||
PAGEHDRSZ + p->mp_upper > env->me_psize))
|
!IS_OVERFLOW(p))
|
||||||
return MDBX_CORRUPTED;
|
return MDBX_CORRUPTED;
|
||||||
/* TODO: more checks here, including p->mp_validator */
|
/* TODO: more checks here, including p->mp_validator */
|
||||||
|
|
||||||
@ -6954,7 +6954,7 @@ static int mdbx_ovpage_free(MDBX_cursor *mc, MDBX_page *mp) {
|
|||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
mdbx_cassert(mc, (mc->mc_flags & C_GCFREEZE) == 0);
|
||||||
mdbx_cassert(mc, (mp->mp_flags & P_OVERFLOW) != 0);
|
mdbx_cassert(mc, IS_OVERFLOW(mp));
|
||||||
mdbx_debug("free ov page %" PRIaPGNO " (%u)", pg, ovpages);
|
mdbx_debug("free ov page %" PRIaPGNO " (%u)", pg, ovpages);
|
||||||
|
|
||||||
if (mdbx_audit_enabled() && env->me_reclaimed_pglist) {
|
if (mdbx_audit_enabled() && env->me_reclaimed_pglist) {
|
||||||
@ -6984,7 +6984,7 @@ static int mdbx_ovpage_free(MDBX_cursor *mc, MDBX_page *mp) {
|
|||||||
* Unsupported in nested txns: They would need to hide the page
|
* Unsupported in nested txns: They would need to hide the page
|
||||||
* range in ancestor txns' dirty and spilled lists. */
|
* range in ancestor txns' dirty and spilled lists. */
|
||||||
if (env->me_reclaimed_pglist && !txn->mt_parent &&
|
if (env->me_reclaimed_pglist && !txn->mt_parent &&
|
||||||
((mp->mp_flags & P_DIRTY) ||
|
(IS_DIRTY(mp) ||
|
||||||
(sl && (x = mdbx_pnl_search(sl, pn)) <= MDBX_PNL_SIZE(sl) &&
|
(sl && (x = mdbx_pnl_search(sl, pn)) <= MDBX_PNL_SIZE(sl) &&
|
||||||
sl[x] == pn))) {
|
sl[x] == pn))) {
|
||||||
unsigned i, j;
|
unsigned i, j;
|
||||||
@ -6994,7 +6994,7 @@ static int mdbx_ovpage_free(MDBX_cursor *mc, MDBX_page *mp) {
|
|||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
if (!(mp->mp_flags & P_DIRTY)) {
|
if (!IS_DIRTY(mp)) {
|
||||||
/* This page is no longer spilled */
|
/* This page is no longer spilled */
|
||||||
if (x == MDBX_PNL_SIZE(sl))
|
if (x == MDBX_PNL_SIZE(sl))
|
||||||
MDBX_PNL_SIZE(sl)--;
|
MDBX_PNL_SIZE(sl)--;
|
||||||
@ -7380,7 +7380,7 @@ static int mdbx_cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
mc->mc_ki[mc->mc_top] = 0;
|
mc->mc_ki[mc->mc_top] = 0;
|
||||||
return MDBX_NOTFOUND;
|
return MDBX_NOTFOUND;
|
||||||
}
|
}
|
||||||
if (mp->mp_flags & P_LEAF2) {
|
if (IS_LEAF2(mp)) {
|
||||||
nodekey.iov_len = mc->mc_db->md_xsize;
|
nodekey.iov_len = mc->mc_db->md_xsize;
|
||||||
nodekey.iov_base = LEAF2KEY(mp, 0, nodekey.iov_len);
|
nodekey.iov_base = LEAF2KEY(mp, 0, nodekey.iov_len);
|
||||||
} else {
|
} else {
|
||||||
@ -7400,7 +7400,7 @@ static int mdbx_cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
unsigned i;
|
unsigned i;
|
||||||
unsigned nkeys = NUMKEYS(mp);
|
unsigned nkeys = NUMKEYS(mp);
|
||||||
if (nkeys > 1) {
|
if (nkeys > 1) {
|
||||||
if (mp->mp_flags & P_LEAF2) {
|
if (IS_LEAF2(mp)) {
|
||||||
nodekey.iov_base = LEAF2KEY(mp, nkeys - 1, nodekey.iov_len);
|
nodekey.iov_base = LEAF2KEY(mp, nkeys - 1, nodekey.iov_len);
|
||||||
} else {
|
} else {
|
||||||
leaf = NODEPTR(mp, nkeys - 1);
|
leaf = NODEPTR(mp, nkeys - 1);
|
||||||
@ -7418,7 +7418,7 @@ static int mdbx_cursor_set(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
if (rc < 0) {
|
if (rc < 0) {
|
||||||
if (mc->mc_ki[mc->mc_top] < NUMKEYS(mp)) {
|
if (mc->mc_ki[mc->mc_top] < NUMKEYS(mp)) {
|
||||||
/* This is definitely the right page, skip search_page */
|
/* This is definitely the right page, skip search_page */
|
||||||
if (mp->mp_flags & P_LEAF2) {
|
if (IS_LEAF2(mp)) {
|
||||||
nodekey.iov_base =
|
nodekey.iov_base =
|
||||||
LEAF2KEY(mp, mc->mc_ki[mc->mc_top], nodekey.iov_len);
|
LEAF2KEY(mp, mc->mc_ki[mc->mc_top], nodekey.iov_len);
|
||||||
} else {
|
} else {
|
||||||
@ -8007,7 +8007,6 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
if (unlikely(rc2 = mdbx_page_new(mc, P_LEAF, 1, &np))) {
|
if (unlikely(rc2 = mdbx_page_new(mc, P_LEAF, 1, &np))) {
|
||||||
return rc2;
|
return rc2;
|
||||||
}
|
}
|
||||||
assert(np->mp_flags & P_LEAF);
|
|
||||||
rc2 = mdbx_cursor_push(mc, np);
|
rc2 = mdbx_cursor_push(mc, np);
|
||||||
if (unlikely(rc2 != MDBX_SUCCESS))
|
if (unlikely(rc2 != MDBX_SUCCESS))
|
||||||
return rc2;
|
return rc2;
|
||||||
@ -8189,7 +8188,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
mp->mp_lower = fp->mp_lower;
|
mp->mp_lower = fp->mp_lower;
|
||||||
mdbx_cassert(mc, fp->mp_upper + offset <= UINT16_MAX);
|
mdbx_cassert(mc, fp->mp_upper + offset <= UINT16_MAX);
|
||||||
mp->mp_upper = (indx_t)(fp->mp_upper + offset);
|
mp->mp_upper = (indx_t)(fp->mp_upper + offset);
|
||||||
if (fp_flags & P_LEAF2) {
|
if (unlikely(fp_flags & P_LEAF2)) {
|
||||||
memcpy(PAGEDATA(mp), PAGEDATA(fp), NUMKEYS(fp) * fp->mp_leaf2_ksize);
|
memcpy(PAGEDATA(mp), PAGEDATA(fp), NUMKEYS(fp) * fp->mp_leaf2_ksize);
|
||||||
} else {
|
} else {
|
||||||
memcpy((char *)mp + mp->mp_upper + PAGEHDRSZ,
|
memcpy((char *)mp + mp->mp_upper + PAGEHDRSZ,
|
||||||
@ -8232,15 +8231,14 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
|||||||
: ovpages ==
|
: ovpages ==
|
||||||
/* LY: add configurable threshold to keep reserve space */
|
/* LY: add configurable threshold to keep reserve space */
|
||||||
dpages) {
|
dpages) {
|
||||||
if (!(omp->mp_flags & P_DIRTY) &&
|
if (!IS_DIRTY(omp) && (level || (env->me_flags & MDBX_WRITEMAP))) {
|
||||||
(level || (env->me_flags & MDBX_WRITEMAP))) {
|
|
||||||
rc = mdbx_page_unspill(mc->mc_txn, omp, &omp);
|
rc = mdbx_page_unspill(mc->mc_txn, omp, &omp);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
return rc;
|
return rc;
|
||||||
level = 0; /* dirty in this txn or clean */
|
level = 0; /* dirty in this txn or clean */
|
||||||
}
|
}
|
||||||
/* Is it dirty? */
|
/* Is it dirty? */
|
||||||
if (omp->mp_flags & P_DIRTY) {
|
if (IS_DIRTY(omp)) {
|
||||||
/* yes, overwrite it. Note in this case we don't
|
/* yes, overwrite it. Note in this case we don't
|
||||||
* bother to try shrinking the page if the new data
|
* bother to try shrinking the page if the new data
|
||||||
* is smaller than the overflow threshold. */
|
* is smaller than the overflow threshold. */
|
||||||
@ -8892,7 +8890,7 @@ static void mdbx_node_shrink(MDBX_page *mp, unsigned indx) {
|
|||||||
assert(delta > 0);
|
assert(delta > 0);
|
||||||
|
|
||||||
/* Prepare to shift upward, set len = length(subpage part to shift) */
|
/* Prepare to shift upward, set len = length(subpage part to shift) */
|
||||||
if (unlikely(IS_LEAF2(sp))) {
|
if (IS_LEAF2(sp)) {
|
||||||
delta &= /* do not make the node uneven-sized */ ~1u;
|
delta &= /* do not make the node uneven-sized */ ~1u;
|
||||||
if (unlikely(delta) == 0)
|
if (unlikely(delta) == 0)
|
||||||
return;
|
return;
|
||||||
@ -12530,7 +12528,7 @@ int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *new_data,
|
|||||||
flags |= MDBX_CURRENT;
|
flags |= MDBX_CURRENT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (page->mp_flags & P_DIRTY) {
|
if (IS_DIRTY(page)) {
|
||||||
if (unlikely(old_data->iov_len < present_data.iov_len)) {
|
if (unlikely(old_data->iov_len < present_data.iov_len)) {
|
||||||
old_data->iov_base = NULL;
|
old_data->iov_base = NULL;
|
||||||
old_data->iov_len = present_data.iov_len;
|
old_data->iov_len = present_data.iov_len;
|
||||||
|
Loading…
Reference in New Issue
Block a user