mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-04 18:14:12 +08:00
mdbx: minor refine/speedup node_del()
.
This commit is contained in:
parent
0dd4532473
commit
1215bda188
74
src/core.c
74
src/core.c
@ -3286,7 +3286,7 @@ static int __must_check_result mdbx_node_add_leaf2(MDBX_cursor *mc,
|
|||||||
unsigned indx,
|
unsigned indx,
|
||||||
const MDBX_val *key);
|
const MDBX_val *key);
|
||||||
|
|
||||||
static void mdbx_node_del(MDBX_cursor *mc, size_t ksize);
|
static void node_del(MDBX_cursor *mc, size_t ksize);
|
||||||
static void mdbx_node_shrink(MDBX_page *mp, unsigned indx);
|
static void mdbx_node_shrink(MDBX_page *mp, unsigned indx);
|
||||||
static int __must_check_result mdbx_node_move(MDBX_cursor *csrc,
|
static int __must_check_result mdbx_node_move(MDBX_cursor *csrc,
|
||||||
MDBX_cursor *cdst, bool fromleft);
|
MDBX_cursor *cdst, bool fromleft);
|
||||||
@ -15790,7 +15790,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
|
|||||||
flags |= F_DUPDATA;
|
flags |= F_DUPDATA;
|
||||||
do_sub = true;
|
do_sub = true;
|
||||||
if (!insert_key)
|
if (!insert_key)
|
||||||
mdbx_node_del(mc, 0);
|
node_del(mc, 0);
|
||||||
goto new_sub;
|
goto new_sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -15829,7 +15829,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
|
|||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mdbx_node_del(mc, 0);
|
node_del(mc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
rdata = data;
|
rdata = data;
|
||||||
@ -16336,22 +16336,19 @@ static int __must_check_result mdbx_node_add_leaf(MDBX_cursor *mc,
|
|||||||
* [in] mc Cursor pointing to the node to delete.
|
* [in] mc Cursor pointing to the node to delete.
|
||||||
* [in] ksize The size of a node. Only used if the page is
|
* [in] ksize The size of a node. Only used if the page is
|
||||||
* part of a MDBX_DUPFIXED database. */
|
* part of a MDBX_DUPFIXED database. */
|
||||||
static void mdbx_node_del(MDBX_cursor *mc, size_t ksize) {
|
__hot static void node_del(MDBX_cursor *mc, size_t ksize) {
|
||||||
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
MDBX_page *mp = mc->mc_pg[mc->mc_top];
|
||||||
int indx = mc->mc_ki[mc->mc_top];
|
const unsigned hole = mc->mc_ki[mc->mc_top];
|
||||||
int i, j, nkeys, ptr;
|
const unsigned nkeys = page_numkeys(mp);
|
||||||
MDBX_node *node;
|
|
||||||
char *base;
|
|
||||||
|
|
||||||
mdbx_debug("delete node %u on %s page %" PRIaPGNO, indx,
|
mdbx_debug("delete node %u on %s page %" PRIaPGNO, hole,
|
||||||
IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno);
|
IS_LEAF(mp) ? "leaf" : "branch", mp->mp_pgno);
|
||||||
nkeys = page_numkeys(mp);
|
mdbx_cassert(mc, hole < nkeys);
|
||||||
mdbx_cassert(mc, indx < nkeys);
|
|
||||||
|
|
||||||
if (IS_LEAF2(mp)) {
|
if (IS_LEAF2(mp)) {
|
||||||
mdbx_cassert(mc, ksize >= sizeof(indx_t));
|
mdbx_cassert(mc, ksize >= sizeof(indx_t));
|
||||||
unsigned diff = nkeys - 1 - indx;
|
unsigned diff = nkeys - 1 - hole;
|
||||||
base = page_leaf2key(mp, indx, ksize);
|
char *base = page_leaf2key(mp, hole, ksize);
|
||||||
if (diff)
|
if (diff)
|
||||||
memmove(base, base + ksize, diff * ksize);
|
memmove(base, base + ksize, diff * ksize);
|
||||||
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
|
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
|
||||||
@ -16362,36 +16359,29 @@ static void mdbx_node_del(MDBX_cursor *mc, size_t ksize) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
node = page_node(mp, indx);
|
MDBX_node *node = page_node(mp, hole);
|
||||||
mdbx_cassert(mc, !IS_BRANCH(mp) || indx || node_ks(node) == 0);
|
mdbx_cassert(mc, !IS_BRANCH(mp) || hole || node_ks(node) == 0);
|
||||||
size_t sz = NODESIZE + node_ks(node);
|
size_t hole_size = NODESIZE + node_ks(node);
|
||||||
if (IS_LEAF(mp)) {
|
if (IS_LEAF(mp))
|
||||||
if (F_ISSET(node_flags(node), F_BIGDATA))
|
hole_size +=
|
||||||
sz += sizeof(pgno_t);
|
(node_flags(node) & F_BIGDATA) ? sizeof(pgno_t) : node_ds(node);
|
||||||
else
|
hole_size = EVEN(hole_size);
|
||||||
sz += node_ds(node);
|
|
||||||
}
|
|
||||||
sz = EVEN(sz);
|
|
||||||
|
|
||||||
ptr = mp->mp_ptrs[indx];
|
const indx_t hole_offset = mp->mp_ptrs[hole];
|
||||||
for (i = j = 0; i < nkeys; i++) {
|
unsigned r, w;
|
||||||
if (i != indx) {
|
for (r = w = 0; r < nkeys; r++)
|
||||||
mp->mp_ptrs[j] = mp->mp_ptrs[i];
|
if (r != hole)
|
||||||
if (mp->mp_ptrs[i] < ptr) {
|
mp->mp_ptrs[w++] = (mp->mp_ptrs[r] < hole_offset)
|
||||||
mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_ptrs[j] >= sz);
|
? mp->mp_ptrs[r] + (indx_t)hole_size
|
||||||
mp->mp_ptrs[j] += (indx_t)sz;
|
: mp->mp_ptrs[r];
|
||||||
}
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
base = (char *)mp + mp->mp_upper + PAGEHDRSZ;
|
char *base = (char *)mp + mp->mp_upper + PAGEHDRSZ;
|
||||||
memmove(base + sz, base, ptr - mp->mp_upper);
|
memmove(base + hole_size, base, hole_offset - mp->mp_upper);
|
||||||
|
|
||||||
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
|
mdbx_cassert(mc, mp->mp_lower >= sizeof(indx_t));
|
||||||
mp->mp_lower -= sizeof(indx_t);
|
mp->mp_lower -= sizeof(indx_t);
|
||||||
mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_upper >= sz);
|
mdbx_cassert(mc, (size_t)UINT16_MAX - mp->mp_upper >= hole_size);
|
||||||
mp->mp_upper += (indx_t)sz;
|
mp->mp_upper += (indx_t)hole_size;
|
||||||
|
|
||||||
if (mdbx_audit_enabled()) {
|
if (mdbx_audit_enabled()) {
|
||||||
const uint8_t checking = mc->mc_checking;
|
const uint8_t checking = mc->mc_checking;
|
||||||
@ -16968,7 +16958,7 @@ static int mdbx_update_key(MDBX_cursor *mc, const MDBX_val *key) {
|
|||||||
/* not enough space left, do a delete and split */
|
/* not enough space left, do a delete and split */
|
||||||
mdbx_debug("Not enough room, delta = %zd, splitting...", delta);
|
mdbx_debug("Not enough room, delta = %zd, splitting...", delta);
|
||||||
pgno_t pgno = node_pgno(node);
|
pgno_t pgno = node_pgno(node);
|
||||||
mdbx_node_del(mc, 0);
|
node_del(mc, 0);
|
||||||
int err = page_split(mc, key, NULL, pgno, MDBX_SPLIT_REPLACE);
|
int err = page_split(mc, key, NULL, pgno, MDBX_SPLIT_REPLACE);
|
||||||
if (err == MDBX_SUCCESS && mdbx_audit_enabled())
|
if (err == MDBX_SUCCESS && mdbx_audit_enabled())
|
||||||
err = mdbx_cursor_check_updating(mc);
|
err = mdbx_cursor_check_updating(mc);
|
||||||
@ -17173,7 +17163,7 @@ static int mdbx_node_move(MDBX_cursor *csrc, MDBX_cursor *cdst, bool fromleft) {
|
|||||||
return rc;
|
return rc;
|
||||||
|
|
||||||
/* Delete the node from the source page. */
|
/* Delete the node from the source page. */
|
||||||
mdbx_node_del(csrc, key4move.iov_len);
|
node_del(csrc, key4move.iov_len);
|
||||||
|
|
||||||
mdbx_cassert(csrc, psrc == csrc->mc_pg[csrc->mc_top]);
|
mdbx_cassert(csrc, psrc == csrc->mc_pg[csrc->mc_top]);
|
||||||
mdbx_cassert(cdst, pdst == cdst->mc_pg[cdst->mc_top]);
|
mdbx_cassert(cdst, pdst == cdst->mc_pg[cdst->mc_top]);
|
||||||
@ -17424,7 +17414,7 @@ static int mdbx_page_merge(MDBX_cursor *csrc, MDBX_cursor *cdst) {
|
|||||||
|
|
||||||
/* Unlink the src page from parent and add to free list. */
|
/* Unlink the src page from parent and add to free list. */
|
||||||
csrc->mc_top--;
|
csrc->mc_top--;
|
||||||
mdbx_node_del(csrc, 0);
|
node_del(csrc, 0);
|
||||||
if (csrc->mc_ki[csrc->mc_top] == 0) {
|
if (csrc->mc_ki[csrc->mc_top] == 0) {
|
||||||
const MDBX_val nullkey = {0, 0};
|
const MDBX_val nullkey = {0, 0};
|
||||||
rc = mdbx_update_key(csrc, &nullkey);
|
rc = mdbx_update_key(csrc, &nullkey);
|
||||||
@ -18313,7 +18303,7 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) {
|
|||||||
mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
|
mdbx_cassert(mc, IS_LEAF(mc->mc_pg[mc->mc_top]));
|
||||||
ki = mc->mc_ki[mc->mc_top];
|
ki = mc->mc_ki[mc->mc_top];
|
||||||
mp = mc->mc_pg[mc->mc_top];
|
mp = mc->mc_pg[mc->mc_top];
|
||||||
mdbx_node_del(mc, mc->mc_db->md_xsize);
|
node_del(mc, mc->mc_db->md_xsize);
|
||||||
mc->mc_db->md_entries--;
|
mc->mc_db->md_entries--;
|
||||||
|
|
||||||
/* Adjust other cursors pointing to mp */
|
/* Adjust other cursors pointing to mp */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user