mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-06 19:24:13 +08:00
mdbx: микро-оптимизация и рефакториг cursor_put_nochecklen()
.
- удалены переменные-флаги dupdata_flag и do_sub; - вместо dupdata_flag используется условие dkey.iov_base != nullptr; - вместо do_sub используется условие flags & F_DUPDATA; - очищено использование dkey, добавлена инициализация dkey.iov_base в ключевых точках; - декларация части переменных перенеса ближе к месту использования.
This commit is contained in:
parent
e7ae8214fd
commit
a387284458
38
src/core.c
38
src/core.c
@ -17215,9 +17215,6 @@ static __hot int cursor_touch(MDBX_cursor *const mc, const MDBX_val *key,
|
|||||||
|
|
||||||
static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
||||||
MDBX_val *data, unsigned flags) {
|
MDBX_val *data, unsigned flags) {
|
||||||
MDBX_page *sub_root = nullptr;
|
|
||||||
MDBX_val xdata, *rdata, dkey, olddata;
|
|
||||||
MDBX_db nested_dupdb;
|
|
||||||
int err;
|
int err;
|
||||||
DKBUF_DEBUG;
|
DKBUF_DEBUG;
|
||||||
MDBX_env *const env = mc->mc_txn->mt_env;
|
MDBX_env *const env = mc->mc_txn->mt_env;
|
||||||
@ -17225,7 +17222,6 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
DDBI(mc), DKEY_DEBUG(key), key->iov_len,
|
DDBI(mc), DKEY_DEBUG(key), key->iov_len,
|
||||||
DVAL_DEBUG((flags & MDBX_RESERVE) ? nullptr : data), data->iov_len);
|
DVAL_DEBUG((flags & MDBX_RESERVE) ? nullptr : data), data->iov_len);
|
||||||
|
|
||||||
bool dupdata_flag = false;
|
|
||||||
if ((flags & MDBX_CURRENT) != 0 && (mc->mc_flags & C_SUB) == 0) {
|
if ((flags & MDBX_CURRENT) != 0 && (mc->mc_flags & C_SUB) == 0) {
|
||||||
if (unlikely(flags & (MDBX_APPEND | MDBX_NOOVERWRITE)))
|
if (unlikely(flags & (MDBX_APPEND | MDBX_NOOVERWRITE)))
|
||||||
return MDBX_EINVAL;
|
return MDBX_EINVAL;
|
||||||
@ -17284,10 +17280,11 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
rc = MDBX_NO_ROOT;
|
rc = MDBX_NO_ROOT;
|
||||||
} else if ((flags & MDBX_CURRENT) == 0) {
|
} else if ((flags & MDBX_CURRENT) == 0) {
|
||||||
bool exact = false;
|
bool exact = false;
|
||||||
|
MDBX_val lastkey, olddata;
|
||||||
if ((flags & MDBX_APPEND) && mc->mc_db->md_entries > 0) {
|
if ((flags & MDBX_APPEND) && mc->mc_db->md_entries > 0) {
|
||||||
rc = cursor_last(mc, &dkey, &olddata);
|
rc = cursor_last(mc, &lastkey, &olddata);
|
||||||
if (likely(rc == MDBX_SUCCESS)) {
|
if (likely(rc == MDBX_SUCCESS)) {
|
||||||
const int cmp = mc->mc_dbx->md_cmp(key, &dkey);
|
const int cmp = mc->mc_dbx->md_cmp(key, &lastkey);
|
||||||
if (likely(cmp > 0)) {
|
if (likely(cmp > 0)) {
|
||||||
mc->mc_ki[mc->mc_top]++; /* step forward for appending */
|
mc->mc_ki[mc->mc_top]++; /* step forward for appending */
|
||||||
rc = MDBX_NOTFOUND;
|
rc = MDBX_NOTFOUND;
|
||||||
@ -17352,7 +17349,7 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
}
|
}
|
||||||
|
|
||||||
mc->mc_flags &= ~C_DEL;
|
mc->mc_flags &= ~C_DEL;
|
||||||
rdata = data;
|
MDBX_val xdata, *rdata = data;
|
||||||
size_t mcount = 0, dcount = 0;
|
size_t mcount = 0, dcount = 0;
|
||||||
if (unlikely(flags & MDBX_MULTIPLE)) {
|
if (unlikely(flags & MDBX_MULTIPLE)) {
|
||||||
dcount = data[1].iov_len;
|
dcount = data[1].iov_len;
|
||||||
@ -17397,11 +17394,15 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
mc->mc_flags |= C_INITIALIZED;
|
mc->mc_flags |= C_INITIALIZED;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool insert_key, insert_data, do_sub = false;
|
MDBX_val dkey, olddata;
|
||||||
insert_key = insert_data = (rc != MDBX_SUCCESS);
|
MDBX_db nested_dupdb;
|
||||||
|
MDBX_page *sub_root = nullptr;
|
||||||
|
bool insert_key, insert_data;
|
||||||
uint16_t fp_flags = P_LEAF;
|
uint16_t fp_flags = P_LEAF;
|
||||||
MDBX_page *fp = env->me_pbuf;
|
MDBX_page *fp = env->me_pbuf;
|
||||||
fp->mp_txnid = mc->mc_txn->mt_front;
|
fp->mp_txnid = mc->mc_txn->mt_front;
|
||||||
|
insert_key = insert_data = (rc != MDBX_SUCCESS);
|
||||||
|
dkey.iov_base = nullptr;
|
||||||
if (insert_key) {
|
if (insert_key) {
|
||||||
/* The key does not exist */
|
/* The key does not exist */
|
||||||
DEBUG("inserting key at index %i", mc->mc_ki[mc->mc_top]);
|
DEBUG("inserting key at index %i", mc->mc_ki[mc->mc_top]);
|
||||||
@ -17576,7 +17577,6 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
/* Back up original data item */
|
/* Back up original data item */
|
||||||
memcpy(dkey.iov_base = fp + 1, olddata.iov_base,
|
memcpy(dkey.iov_base = fp + 1, olddata.iov_base,
|
||||||
dkey.iov_len = olddata.iov_len);
|
dkey.iov_len = olddata.iov_len);
|
||||||
dupdata_flag = true;
|
|
||||||
|
|
||||||
/* Make sub-page header for the dup items, with dummy body */
|
/* Make sub-page header for the dup items, with dummy body */
|
||||||
fp->mp_flags = P_LEAF | P_SUBP;
|
fp->mp_flags = P_LEAF | P_SUBP;
|
||||||
@ -17680,11 +17680,10 @@ static __hot int cursor_put_nochecklen(MDBX_cursor *mc, const MDBX_val *key,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
rdata = &xdata;
|
|
||||||
flags |= F_DUPDATA;
|
|
||||||
do_sub = true;
|
|
||||||
if (!insert_key)
|
if (!insert_key)
|
||||||
node_del(mc, 0);
|
node_del(mc, 0);
|
||||||
|
rdata = &xdata;
|
||||||
|
flags |= F_DUPDATA;
|
||||||
goto new_sub;
|
goto new_sub;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -17769,8 +17768,8 @@ new_sub:;
|
|||||||
* storing the user data in the keys field, so there are strict
|
* storing the user data in the keys field, so there are strict
|
||||||
* size limits on dupdata. The actual data fields of the child
|
* size limits on dupdata. The actual data fields of the child
|
||||||
* DB are all zero size. */
|
* DB are all zero size. */
|
||||||
if (do_sub) {
|
if (flags & F_DUPDATA) {
|
||||||
int xflags;
|
unsigned xflags;
|
||||||
size_t ecount;
|
size_t ecount;
|
||||||
put_sub:
|
put_sub:
|
||||||
xdata.iov_len = 0;
|
xdata.iov_len = 0;
|
||||||
@ -17791,13 +17790,11 @@ new_sub:;
|
|||||||
if (sub_root)
|
if (sub_root)
|
||||||
mc->mc_xcursor->mx_cursor.mc_pg[0] = sub_root;
|
mc->mc_xcursor->mx_cursor.mc_pg[0] = sub_root;
|
||||||
/* converted, write the original data first */
|
/* converted, write the original data first */
|
||||||
if (dupdata_flag) {
|
if (dkey.iov_base) {
|
||||||
rc = cursor_put_nochecklen(&mc->mc_xcursor->mx_cursor, &dkey, &xdata,
|
rc = cursor_put_nochecklen(&mc->mc_xcursor->mx_cursor, &dkey, &xdata,
|
||||||
xflags);
|
xflags);
|
||||||
if (unlikely(rc))
|
if (unlikely(rc))
|
||||||
goto bad_sub;
|
goto bad_sub;
|
||||||
/* we've done our job */
|
|
||||||
dkey.iov_len = 0;
|
|
||||||
}
|
}
|
||||||
if (!(node_flags(node) & F_SUBDATA) || sub_root) {
|
if (!(node_flags(node) & F_SUBDATA) || sub_root) {
|
||||||
/* Adjust other cursors pointing to mp */
|
/* Adjust other cursors pointing to mp */
|
||||||
@ -17814,7 +17811,7 @@ new_sub:;
|
|||||||
continue;
|
continue;
|
||||||
if (m2->mc_pg[i] == mp) {
|
if (m2->mc_pg[i] == mp) {
|
||||||
if (m2->mc_ki[i] == mc->mc_ki[i]) {
|
if (m2->mc_ki[i] == mc->mc_ki[i]) {
|
||||||
err = cursor_xinit2(m2, mx, dupdata_flag);
|
err = cursor_xinit2(m2, mx, dkey.iov_base != nullptr);
|
||||||
if (unlikely(err != MDBX_SUCCESS))
|
if (unlikely(err != MDBX_SUCCESS))
|
||||||
return err;
|
return err;
|
||||||
} else if (!insert_key && m2->mc_ki[i] < nkeys) {
|
} else if (!insert_key && m2->mc_ki[i] < nkeys) {
|
||||||
@ -17857,7 +17854,8 @@ new_sub:;
|
|||||||
data[1].iov_len = mcount;
|
data[1].iov_len = mcount;
|
||||||
if (mcount < dcount) {
|
if (mcount < dcount) {
|
||||||
data[0].iov_base = ptr_disp(data[0].iov_base, data[0].iov_len);
|
data[0].iov_base = ptr_disp(data[0].iov_base, data[0].iov_len);
|
||||||
dupdata_flag = insert_key = insert_data = false;
|
insert_key = insert_data = false;
|
||||||
|
dkey.iov_base = nullptr;
|
||||||
goto more;
|
goto more;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user