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:
Леонид Юрьев (Leonid Yuriev) 2023-10-06 17:34:09 +03:00
parent e7ae8214fd
commit a387284458

View File

@ -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;
} }
} }