mdbx: extract node_read_bigdata().

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2022-07-03 22:37:47 +03:00
parent d4ef9bf233
commit 2d300d807b

View File

@ -3926,7 +3926,7 @@ static int __must_check_result mdbx_node_move(MDBX_cursor *csrc,
static int __must_check_result mdbx_node_read(MDBX_cursor *mc, static int __must_check_result mdbx_node_read(MDBX_cursor *mc,
const MDBX_node *leaf, const MDBX_node *leaf,
MDBX_val *data, MDBX_val *data,
const txnid_t front); const MDBX_page *mp);
static int __must_check_result mdbx_rebalance(MDBX_cursor *mc); static int __must_check_result mdbx_rebalance(MDBX_cursor *mc);
static int __must_check_result mdbx_update_key(MDBX_cursor *mc, static int __must_check_result mdbx_update_key(MDBX_cursor *mc,
const MDBX_val *key); const MDBX_val *key);
@ -6695,7 +6695,7 @@ page_alloc_slowpath(MDBX_cursor *mc, const pgno_t num, int flags) {
if (unlikely((ret.err = mdbx_node_read( if (unlikely((ret.err = mdbx_node_read(
&recur.outer, &recur.outer,
page_node(mp, recur.outer.mc_ki[recur.outer.mc_top]), page_node(mp, recur.outer.mc_ki[recur.outer.mc_top]),
&data, mp->mp_txnid)) != MDBX_SUCCESS)) &data, mp)) != MDBX_SUCCESS))
goto fail; goto fail;
if ((flags & MDBX_LIFORECLAIM) && !txn->tw.lifo_reclaimed) { if ((flags & MDBX_LIFORECLAIM) && !txn->tw.lifo_reclaimed) {
@ -14114,8 +14114,8 @@ static int mdbx_fetch_sdb(MDBX_txn *txn, MDBX_dbi dbi) {
return MDBX_INCOMPATIBLE; /* not a named DB */ return MDBX_INCOMPATIBLE; /* not a named DB */
} }
const txnid_t pp_txnid = couple.outer.mc_pg[couple.outer.mc_top]->mp_txnid; rc = mdbx_node_read(&couple.outer, nsr.node, &data,
rc = mdbx_node_read(&couple.outer, nsr.node, &data, pp_txnid); couple.outer.mc_pg[couple.outer.mc_top]);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
@ -14142,6 +14142,7 @@ static int mdbx_fetch_sdb(MDBX_txn *txn, MDBX_dbi dbi) {
memcpy(db, data.iov_base, sizeof(MDBX_db)); memcpy(db, data.iov_base, sizeof(MDBX_db));
#if !MDBX_DISABLE_VALIDATION #if !MDBX_DISABLE_VALIDATION
const txnid_t pp_txnid = couple.outer.mc_pg[couple.outer.mc_top]->mp_txnid;
mdbx_tassert(txn, txn->mt_front >= pp_txnid); mdbx_tassert(txn, txn->mt_front >= pp_txnid);
if (unlikely(db->md_mod_txnid > pp_txnid)) { if (unlikely(db->md_mod_txnid > pp_txnid)) {
mdbx_error("db.md_mod_txnid (%" PRIaTXN ") > page-txnid (%" PRIaTXN ")", mdbx_error("db.md_mod_txnid (%" PRIaTXN ") > page-txnid (%" PRIaTXN ")",
@ -14256,32 +14257,55 @@ __hot static int mdbx_page_search(MDBX_cursor *mc, const MDBX_val *key,
return mdbx_page_search_root(mc, key, flags); return mdbx_page_search_root(mc, key, flags);
} }
/* Return the data associated with a given node. /* Read overflow node data. */
* static __noinline int node_read_bigdata(MDBX_cursor *mc, const MDBX_node *node,
* [in] mc The cursor for this operation. MDBX_val *data, const MDBX_page *mp) {
* [in] leaf The node being read. mdbx_cassert(mc,
* [out] data Updated to point to the node's data. node_flags(node) == F_BIGDATA && data->iov_len == node_ds(node));
*
* Returns 0 on success, non-zero on failure. */ struct page_result ret =
static __always_inline int mdbx_node_read(MDBX_cursor *mc, mdbx_page_get_ex(mc, node_largedata_pgno(node), mp->mp_txnid);
const MDBX_node *node, MDBX_val *data, if (unlikely((ret.err != MDBX_SUCCESS))) {
const txnid_t front) {
data->iov_len = node_ds(node);
data->iov_base = node_data(node);
if (unlikely(F_ISSET(node_flags(node), F_BIGDATA))) {
/* Read overflow data. */
MDBX_page *omp; /* overflow page */
int rc = mdbx_page_get(mc, node_largedata_pgno(node), &omp, front);
if (unlikely((rc != MDBX_SUCCESS))) {
mdbx_debug("read overflow page %" PRIaPGNO " failed", mdbx_debug("read overflow page %" PRIaPGNO " failed",
node_largedata_pgno(node)); node_largedata_pgno(node));
return rc; return ret.err;
} }
data->iov_base = page_data(omp);
data->iov_base = page_data(ret.page);
if (!MDBX_DISABLE_VALIDATION &&
unlikely(PAGETYPE_EXTRA(ret.page) != P_OVERFLOW))
return bad_page(ret.page, "invalid page-type 0x%x for bigdata-node",
PAGETYPE_EXTRA(ret.page));
if (!MDBX_DISABLE_VALIDATION &&
unlikely(node_size_len(node_ks(node), data->iov_len) <=
mc->mc_txn->mt_env->me_leaf_nodemax))
bad_page(mp, "too small data (%zu bytes) for bigdata-node", data->iov_len);
if (!MDBX_DISABLE_VALIDATION &&
unlikely(ret.page->mp_pages !=
number_of_ovpages(mc->mc_txn->mt_env, data->iov_len))) {
if (ret.page->mp_pages <
number_of_ovpages(mc->mc_txn->mt_env, data->iov_len))
return bad_page(ret.page,
"too less n-pages %u for bigdata-node (%zu bytes)",
ret.page->mp_pages, data->iov_len);
else
bad_page(ret.page, "extra n-pages %u for bigdata-node (%zu bytes)",
ret.page->mp_pages, data->iov_len);
} }
return MDBX_SUCCESS; return MDBX_SUCCESS;
} }
/* Return the data associated with a given node. */
static __always_inline int mdbx_node_read(MDBX_cursor *mc,
const MDBX_node *node, MDBX_val *data,
const MDBX_page *mp) {
data->iov_len = node_ds(node);
data->iov_base = node_data(node);
if (likely(node_flags(node) != F_BIGDATA))
return MDBX_SUCCESS;
return node_read_bigdata(mc, node, data, mp);
}
int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data) { int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data) {
DKBUF_DEBUG; DKBUF_DEBUG;
mdbx_debug("===> get db %u key [%s]", dbi, DKEY_DEBUG(key)); mdbx_debug("===> get db %u key [%s]", dbi, DKEY_DEBUG(key));
@ -14523,7 +14547,7 @@ skip:
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
rc = mdbx_node_read(mc, node, data, mp->mp_txnid); rc = mdbx_node_read(mc, node, data, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
@ -14616,7 +14640,7 @@ static int mdbx_cursor_prev(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
rc = mdbx_node_read(mc, node, data, mp->mp_txnid); rc = mdbx_node_read(mc, node, data, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
@ -14880,8 +14904,7 @@ got_node:
} }
} }
MDBX_val actual_data; MDBX_val actual_data;
ret.err = mdbx_node_read(mc, node, &actual_data, ret.err = mdbx_node_read(mc, node, &actual_data, mc->mc_pg[mc->mc_top]);
mc->mc_pg[mc->mc_top]->mp_txnid);
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
const int cmp = mc->mc_dbx->md_dcmp(&aligned_data, &actual_data); const int cmp = mc->mc_dbx->md_dcmp(&aligned_data, &actual_data);
@ -14896,7 +14919,7 @@ got_node:
} }
*data = actual_data; *data = actual_data;
} else { } else {
ret.err = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid); ret.err = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]);
if (unlikely(ret.err != MDBX_SUCCESS)) if (unlikely(ret.err != MDBX_SUCCESS))
return ret; return ret;
} }
@ -14953,7 +14976,7 @@ static int mdbx_cursor_first(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
rc = mdbx_node_read(mc, node, data, mp->mp_txnid); rc = mdbx_node_read(mc, node, data, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
@ -15002,7 +15025,7 @@ static int mdbx_cursor_last(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) {
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} else if (likely(data)) { } else if (likely(data)) {
rc = mdbx_node_read(mc, node, data, mp->mp_txnid); rc = mdbx_node_read(mc, node, data, mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
return rc; return rc;
} }
@ -15069,7 +15092,7 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
return rc; return rc;
} }
} else { } else {
rc = mdbx_node_read(mc, node, data, mp->mp_txnid); rc = mdbx_node_read(mc, node, data, mp);
if (unlikely(rc)) if (unlikely(rc))
return rc; return rc;
} }
@ -15176,7 +15199,7 @@ int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
MDBX_node *node = page_node(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); MDBX_node *node = page_node(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]);
if (!F_ISSET(node_flags(node), F_DUPDATA)) { if (!F_ISSET(node_flags(node), F_DUPDATA)) {
get_key_optional(node, key); get_key_optional(node, key);
rc = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]->mp_txnid); rc = mdbx_node_read(mc, node, data, mc->mc_pg[mc->mc_top]);
break; break;
} }
} }
@ -15350,7 +15373,6 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
return MDBX_NOTFOUND; return MDBX_NOTFOUND;
} }
const txnid_t pp_txnid = mp->mp_txnid;
do { do {
if (unlikely(n + 2 > limit)) { if (unlikely(n + 2 > limit)) {
rc = MDBX_RESULT_TRUE; rc = MDBX_RESULT_TRUE;
@ -15358,7 +15380,7 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
} }
const MDBX_node *leaf = page_node(mp, i); const MDBX_node *leaf = page_node(mp, i);
get_key(leaf, &pairs[n]); get_key(leaf, &pairs[n]);
rc = mdbx_node_read(mc, leaf, &pairs[n + 1], pp_txnid); rc = mdbx_node_read(mc, leaf, &pairs[n + 1], mp);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(rc != MDBX_SUCCESS))
break; break;
n += 2; n += 2;