mirror of
https://github.com/isar/libmdbx.git
synced 2024-12-28 03:28:48 +08:00
mdbx: возможность логирования ошибок возвращаемых из API (return LOG_IFERR).
Возможность полезная, но пожалуй еще нуждается в доработке и/или до-осмыслении. Основное неудобство в нестыковке с основным логированием. С одной стороны, сообщение об ошибках следует выводить с уровнем/severity MDBX_LOG_ERROR. Однако, это замусоривает и ломает тесты. Поэтому сейчас при возвращении ошибок из API сообщения логируются MDBX_LOG_ERROR, но производится это только при включении уровня логирования MDBX_LOG_DEBUG или более детальном.
This commit is contained in:
parent
9daff17c82
commit
28bd805ed8
207
src/api-cursor.c
207
src/api-cursor.c
@ -29,16 +29,16 @@ MDBX_cursor *mdbx_cursor_create(void *context) {
|
||||
int mdbx_cursor_renew(const MDBX_txn *txn, MDBX_cursor *mc) {
|
||||
return likely(mc)
|
||||
? mdbx_cursor_bind(txn, mc, (kvx_t *)mc->clc - txn->env->kvs)
|
||||
: MDBX_EINVAL;
|
||||
: LOG_IFERR(MDBX_EINVAL);
|
||||
}
|
||||
|
||||
int mdbx_cursor_reset(MDBX_cursor *mc) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_ready4dispose &&
|
||||
mc->signature != cur_signature_live))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
cursor_couple_t *couple = (cursor_couple_t *)mc;
|
||||
couple->outer.top_and_flags = z_poor_mark;
|
||||
@ -48,29 +48,29 @@ int mdbx_cursor_reset(MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_ready4dispose &&
|
||||
mc->signature != cur_signature_live))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = dbi_check(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(dbi == FREE_DBI && !(txn->flags & MDBX_TXN_RDONLY)))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
|
||||
if (unlikely(mc->backup)) /* Cursor from parent transaction */ {
|
||||
cASSERT(mc, mc->signature == cur_signature_live);
|
||||
if (unlikely(cursor_dbi(mc) != dbi ||
|
||||
/* paranoia */ mc->signature != cur_signature_live ||
|
||||
mc->txn != txn))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cASSERT(mc, mc->tree == &txn->dbs[dbi]);
|
||||
cASSERT(mc, mc->clc == &txn->env->kvs[dbi].clc);
|
||||
@ -79,7 +79,9 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
|
||||
/* paranoia */ mc->signature == cur_signature_live &&
|
||||
mc->txn == txn)
|
||||
? MDBX_SUCCESS
|
||||
: MDBX_EINVAL /* Disallow change DBI in nested transactions */;
|
||||
: LOG_IFERR(MDBX_EINVAL) /* Disallow change DBI in nested
|
||||
transactions */
|
||||
;
|
||||
}
|
||||
|
||||
if (mc->signature == cur_signature_live) {
|
||||
@ -91,7 +93,7 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
|
||||
|
||||
rc = cursor_init(mc, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
mc->next = txn->cursors[dbi];
|
||||
txn->cursors[dbi] = mc;
|
||||
@ -100,14 +102,15 @@ int mdbx_cursor_bind(const MDBX_txn *txn, MDBX_cursor *mc, MDBX_dbi dbi) {
|
||||
|
||||
int mdbx_cursor_unbind(MDBX_cursor *mc) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_SUCCESS
|
||||
: MDBX_EBADSIGN;
|
||||
return (mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_SUCCESS
|
||||
: LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
if (unlikely(mc->backup)) /* Cursor from parent transaction */
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
eASSERT(nullptr, mc->txn && mc->txn->signature == txn_signature);
|
||||
cASSERT(mc, mc->signature == cur_signature_live);
|
||||
@ -116,7 +119,7 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
|
||||
ERROR("Wrong cursor's transaction %p 0x%x",
|
||||
__Wpedantic_format_voidptr(mc->txn),
|
||||
mc->txn ? mc->txn->signature : 0);
|
||||
return MDBX_PROBLEM;
|
||||
return LOG_IFERR(MDBX_PROBLEM);
|
||||
}
|
||||
if (mc->next != mc) {
|
||||
const size_t dbi = (kvx_t *)mc->clc - mc->txn->env->kvs;
|
||||
@ -138,17 +141,17 @@ int mdbx_cursor_unbind(MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_open(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_cursor **ret) {
|
||||
if (unlikely(!ret))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
*ret = nullptr;
|
||||
|
||||
MDBX_cursor *const mc = mdbx_cursor_create(nullptr);
|
||||
if (unlikely(!mc))
|
||||
return MDBX_ENOMEM;
|
||||
return LOG_IFERR(MDBX_ENOMEM);
|
||||
|
||||
int rc = mdbx_cursor_bind(txn, mc, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
mdbx_cursor_close(mc);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
*ret = mc;
|
||||
@ -189,10 +192,11 @@ void mdbx_cursor_close(MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_copy(const MDBX_cursor *src, MDBX_cursor *dest) {
|
||||
if (unlikely(!src))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(src->signature != cur_signature_live))
|
||||
return (src->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((src->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = mdbx_cursor_bind(src->txn, dest, cursor_dbi(src));
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
@ -241,6 +245,7 @@ int mdbx_txn_release_all_cursors(const MDBX_txn *txn, bool unbind) {
|
||||
}
|
||||
} else {
|
||||
eASSERT(nullptr, rc < 0);
|
||||
LOG_IFERR(rc);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
@ -325,18 +330,19 @@ int mdbx_cursor_compare(const MDBX_cursor *l, const MDBX_cursor *r,
|
||||
/* Return the count of duplicate data items for the current key */
|
||||
int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(countp == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if ((*countp = is_filled(mc)) > 0) {
|
||||
if (!inner_hollow(mc)) {
|
||||
@ -353,11 +359,12 @@ int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) {
|
||||
|
||||
int mdbx_cursor_on_first(const MDBX_cursor *mc) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
for (intptr_t i = 0; i <= mc->top; ++i) {
|
||||
if (mc->ki[i])
|
||||
@ -369,11 +376,12 @@ int mdbx_cursor_on_first(const MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
if (is_filled(mc) && mc->subcur) {
|
||||
mc = &mc->subcur->cursor;
|
||||
@ -388,11 +396,12 @@ int mdbx_cursor_on_first_dup(const MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_on_last(const MDBX_cursor *mc) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
for (intptr_t i = 0; i <= mc->top; ++i) {
|
||||
size_t nkeys = page_numkeys(mc->pg[i]);
|
||||
@ -405,11 +414,12 @@ int mdbx_cursor_on_last(const MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
if (is_filled(mc) && mc->subcur) {
|
||||
mc = &mc->subcur->cursor;
|
||||
@ -425,11 +435,12 @@ int mdbx_cursor_on_last_dup(const MDBX_cursor *mc) {
|
||||
|
||||
int mdbx_cursor_eof(const MDBX_cursor *mc) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
return is_eof(mc) ? MDBX_RESULT_TRUE : MDBX_RESULT_FALSE;
|
||||
}
|
||||
@ -437,20 +448,21 @@ int mdbx_cursor_eof(const MDBX_cursor *mc) {
|
||||
int mdbx_cursor_get(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data,
|
||||
MDBX_cursor_op op) {
|
||||
if (unlikely(mc == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(cursor_dbi_changed(mc)))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
return cursor_ops(mc, key, data, op);
|
||||
return LOG_IFERR(cursor_ops(mc, key, data, op));
|
||||
}
|
||||
|
||||
__hot static int scan_confinue(MDBX_cursor *mc, MDBX_predicate_func *predicate,
|
||||
@ -520,33 +532,34 @@ int mdbx_cursor_scan(MDBX_cursor *mc, MDBX_predicate_func *predicate,
|
||||
void *context, MDBX_cursor_op start_op,
|
||||
MDBX_cursor_op turn_op, void *arg) {
|
||||
if (unlikely(!predicate))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const unsigned valid_start_mask =
|
||||
1 << MDBX_FIRST | 1 << MDBX_FIRST_DUP | 1 << MDBX_LAST |
|
||||
1 << MDBX_LAST_DUP | 1 << MDBX_GET_CURRENT | 1 << MDBX_GET_MULTIPLE;
|
||||
if (unlikely(start_op > 30 || ((1 << start_op) & valid_start_mask) == 0))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const unsigned valid_turn_mask =
|
||||
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
|
||||
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
|
||||
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
|
||||
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
MDBX_val key = {nullptr, 0}, value = {nullptr, 0};
|
||||
int rc = mdbx_cursor_get(mc, &key, &value, start_op);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return scan_confinue(mc, predicate, context, arg, &key, &value, turn_op);
|
||||
return LOG_IFERR(rc);
|
||||
return LOG_IFERR(
|
||||
scan_confinue(mc, predicate, context, arg, &key, &value, turn_op));
|
||||
}
|
||||
|
||||
int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
|
||||
void *context, MDBX_cursor_op from_op, MDBX_val *key,
|
||||
MDBX_val *value, MDBX_cursor_op turn_op, void *arg) {
|
||||
if (unlikely(!predicate || !key))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const unsigned valid_start_mask =
|
||||
1 << MDBX_GET_BOTH | 1 << MDBX_GET_BOTH_RANGE | 1 << MDBX_SET_KEY |
|
||||
@ -554,18 +567,18 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
|
||||
1 << MDBX_SET_UPPERBOUND;
|
||||
if (unlikely(from_op < MDBX_TO_KEY_LESSER_THAN &&
|
||||
((1 << from_op) & valid_start_mask) == 0))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const unsigned valid_turn_mask =
|
||||
1 << MDBX_NEXT | 1 << MDBX_NEXT_DUP | 1 << MDBX_NEXT_NODUP |
|
||||
1 << MDBX_PREV | 1 << MDBX_PREV_DUP | 1 << MDBX_PREV_NODUP |
|
||||
1 << MDBX_NEXT_MULTIPLE | 1 << MDBX_PREV_MULTIPLE;
|
||||
if (unlikely(turn_op > 30 || ((1 << turn_op) & valid_turn_mask) == 0))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
int rc = mdbx_cursor_get(mc, key, value, from_op);
|
||||
if (unlikely(MDBX_IS_ERROR(rc)))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cASSERT(mc, key != nullptr);
|
||||
MDBX_val stub;
|
||||
@ -573,51 +586,53 @@ int mdbx_cursor_scan_from(MDBX_cursor *mc, MDBX_predicate_func *predicate,
|
||||
value = &stub;
|
||||
rc = cursor_ops(mc, key, value, MDBX_GET_CURRENT);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
return scan_confinue(mc, predicate, context, arg, key, value, turn_op);
|
||||
return LOG_IFERR(
|
||||
scan_confinue(mc, predicate, context, arg, key, value, turn_op));
|
||||
}
|
||||
|
||||
int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
|
||||
size_t limit, MDBX_cursor_op op) {
|
||||
if (unlikely(!count))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*count = 0;
|
||||
if (unlikely(mc == nullptr || limit < 4 || limit > INTPTR_MAX - 2))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn(mc->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(cursor_dbi_changed(mc)))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(mc->subcur))
|
||||
return MDBX_INCOMPATIBLE /* must be a non-dupsort table */;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE) /* must be a non-dupsort table */;
|
||||
|
||||
switch (op) {
|
||||
case MDBX_NEXT:
|
||||
if (unlikely(is_eof(mc)))
|
||||
return is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA;
|
||||
return LOG_IFERR(is_pointed(mc) ? MDBX_NOTFOUND : MDBX_ENODATA);
|
||||
break;
|
||||
|
||||
case MDBX_FIRST:
|
||||
if (!is_filled(mc)) {
|
||||
rc = outer_first(mc, nullptr, nullptr);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
DEBUG("unhandled/unimplemented cursor operation %u", op);
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
}
|
||||
|
||||
const page_t *mp = mc->pg[mc->top];
|
||||
@ -662,18 +677,18 @@ int mdbx_cursor_get_batch(MDBX_cursor *mc, size_t *count, MDBX_val *pairs,
|
||||
|
||||
bailout:
|
||||
*count = n;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
int mdbx_cursor_set_userctx(MDBX_cursor *mc, void *ctx) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_ready4dispose &&
|
||||
mc->signature != cur_signature_live))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
cursor_couple_t *couple = container_of(mc, cursor_couple_t, outer);
|
||||
couple->userctx = ctx;
|
||||
@ -714,80 +729,84 @@ MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *mc) {
|
||||
int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data,
|
||||
MDBX_put_flags_t flags) {
|
||||
if (unlikely(mc == nullptr || key == nullptr || data == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(cursor_dbi_changed(mc)))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
cASSERT(mc, cursor_is_tracked(mc));
|
||||
|
||||
/* Check this first so counter will always be zero on any early failures. */
|
||||
if (unlikely(flags & MDBX_MULTIPLE)) {
|
||||
if (unlikely(flags & MDBX_RESERVE))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(!(mc->tree->flags & MDBX_DUPFIXED)))
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
const size_t dcount = data[1].iov_len;
|
||||
if (unlikely(dcount < 2 || data->iov_len == 0))
|
||||
return MDBX_BAD_VALSIZE;
|
||||
return LOG_IFERR(MDBX_BAD_VALSIZE);
|
||||
if (unlikely(mc->tree->dupfix_size != data->iov_len) &&
|
||||
mc->tree->dupfix_size)
|
||||
return MDBX_BAD_VALSIZE;
|
||||
return LOG_IFERR(MDBX_BAD_VALSIZE);
|
||||
if (unlikely(dcount >
|
||||
MAX_MAPSIZE / 2 /
|
||||
(BRANCH_NODE_MAX(MDBX_MAX_PAGESIZE) - NODESIZE))) {
|
||||
/* checking for multiplication overflow */
|
||||
if (unlikely(dcount > MAX_MAPSIZE / 2 / data->iov_len))
|
||||
return MDBX_TOO_LARGE;
|
||||
return LOG_IFERR(MDBX_TOO_LARGE);
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & MDBX_RESERVE) {
|
||||
if (unlikely(mc->tree->flags & (MDBX_DUPSORT | MDBX_REVERSEDUP |
|
||||
MDBX_INTEGERDUP | MDBX_DUPFIXED)))
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
data->iov_base = nullptr;
|
||||
}
|
||||
|
||||
if (unlikely(mc->txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
return LOG_IFERR((mc->txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
|
||||
: MDBX_BAD_TXN);
|
||||
|
||||
return cursor_put_checklen(mc, key, data, flags);
|
||||
return LOG_IFERR(cursor_put_checklen(mc, key, data, flags));
|
||||
}
|
||||
|
||||
int mdbx_cursor_del(MDBX_cursor *mc, MDBX_put_flags_t flags) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn_rw(mc->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(cursor_dbi_changed(mc)))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
return cursor_del(mc, flags);
|
||||
return LOG_IFERR(cursor_del(mc, flags));
|
||||
}
|
||||
|
||||
__cold int mdbx_cursor_ignord(MDBX_cursor *mc) {
|
||||
if (unlikely(!mc))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(mc->signature != cur_signature_live))
|
||||
return (mc->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((mc->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
mc->checking |= z_ignord;
|
||||
if (mc->subcur)
|
||||
|
112
src/api-env.c
112
src/api-env.c
@ -196,18 +196,18 @@ __cold static int env_handle_pathname(MDBX_env *env, const pathchar_t *pathname,
|
||||
|
||||
__cold int mdbx_env_create(MDBX_env **penv) {
|
||||
if (unlikely(!penv))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
*penv = nullptr;
|
||||
|
||||
#ifdef MDBX_HAVE_C11ATOMICS
|
||||
if (unlikely(!atomic_is_lock_free((const volatile uint32_t *)penv))) {
|
||||
ERROR("lock-free atomic ops for %u-bit types is required", 32);
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
#if MDBX_64BIT_ATOMIC
|
||||
if (unlikely(!atomic_is_lock_free((const volatile uint64_t *)penv))) {
|
||||
ERROR("lock-free atomic ops for %u-bit types is required", 64);
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
#endif /* MDBX_64BIT_ATOMIC */
|
||||
#endif /* MDBX_HAVE_C11ATOMICS */
|
||||
@ -215,25 +215,25 @@ __cold int mdbx_env_create(MDBX_env **penv) {
|
||||
if (unlikely(!is_powerof2(globals.sys_pagesize) ||
|
||||
globals.sys_pagesize < MDBX_MIN_PAGESIZE)) {
|
||||
ERROR("unsuitable system pagesize %u", globals.sys_pagesize);
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
|
||||
#if defined(__linux__) || defined(__gnu_linux__)
|
||||
if (unlikely(globals.linux_kernel_version < 0x04000000)) {
|
||||
/* 2022-09-01: Прошло уже больше двух после окончания какой-либо поддержки
|
||||
* самого "долгоиграющего" ядра 3.16.85 ветки 3.x */
|
||||
/* 2022-09-01: Прошло уже более двух лет после окончания какой-либо
|
||||
* поддержки самого "долгоиграющего" ядра 3.16.85 ветки 3.x */
|
||||
ERROR("too old linux kernel %u.%u.%u.%u, the >= 4.0.0 is required",
|
||||
globals.linux_kernel_version >> 24,
|
||||
(globals.linux_kernel_version >> 16) & 255,
|
||||
(globals.linux_kernel_version >> 8) & 255,
|
||||
globals.linux_kernel_version & 255);
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
#endif /* Linux */
|
||||
|
||||
MDBX_env *env = osal_calloc(1, sizeof(MDBX_env));
|
||||
if (unlikely(!env))
|
||||
return MDBX_ENOMEM;
|
||||
return LOG_IFERR(MDBX_ENOMEM);
|
||||
|
||||
env->max_readers = DEFAULT_READERS;
|
||||
env->max_dbi = env->n_dbi = CORE_DBS;
|
||||
@ -278,18 +278,18 @@ __cold int mdbx_env_create(MDBX_env **penv) {
|
||||
|
||||
bailout:
|
||||
osal_free(env);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
|
||||
if (unlikely(target >= NUM_METAS))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely((env->flags & (MDBX_EXCLUSIVE | MDBX_RDONLY)) != MDBX_EXCLUSIVE))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
|
||||
const meta_t *const target_meta = METAPAGE(env, target);
|
||||
txnid_t new_txnid = constmeta_txnid(target_meta);
|
||||
@ -303,7 +303,7 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
|
||||
if (meta_validate(env, &meta, page, n, nullptr) != MDBX_SUCCESS) {
|
||||
int err = meta_override(env, n, 0, nullptr);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
} else {
|
||||
txnid_t txnid = constmeta_txnid(&meta);
|
||||
if (new_txnid <= txnid)
|
||||
@ -313,9 +313,9 @@ __cold int mdbx_env_turn_for_recovery(MDBX_env *env, unsigned target) {
|
||||
|
||||
if (unlikely(new_txnid > MAX_TXNID)) {
|
||||
ERROR("txnid overflow, raise %d", MDBX_TXN_FULL);
|
||||
return MDBX_TXN_FULL;
|
||||
return LOG_IFERR(MDBX_TXN_FULL);
|
||||
}
|
||||
return meta_override(env, target, new_txnid, target_meta);
|
||||
return LOG_IFERR(meta_override(env, target, new_txnid, target_meta));
|
||||
}
|
||||
|
||||
__cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
||||
@ -327,7 +327,7 @@ __cold int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
||||
rc = mdbx_env_open_for_recoveryW(env, pathnameW, target_meta, writeable);
|
||||
osal_free(pathnameW);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_open_for_recoveryW(MDBX_env *env, const wchar_t *pathname,
|
||||
@ -335,12 +335,12 @@ __cold int mdbx_env_open_for_recoveryW(MDBX_env *env, const wchar_t *pathname,
|
||||
#endif /* Windows */
|
||||
|
||||
if (unlikely(target_meta >= NUM_METAS))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
if (unlikely(env->dxb_mmap.base))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
|
||||
env->stuck_meta = (int8_t)target_meta;
|
||||
return
|
||||
@ -361,7 +361,7 @@ __cold int mdbx_env_delete(const char *pathname, MDBX_env_delete_mode_t mode) {
|
||||
rc = mdbx_env_deleteW(pathnameW, mode);
|
||||
osal_free(pathnameW);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_deleteW(const wchar_t *pathname,
|
||||
@ -370,7 +370,7 @@ __cold int mdbx_env_deleteW(const wchar_t *pathname,
|
||||
|
||||
switch (mode) {
|
||||
default:
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
case MDBX_ENV_JUST_DELETE:
|
||||
case MDBX_ENV_ENSURE_UNUSED:
|
||||
case MDBX_ENV_WAIT_FOR_UNUSED:
|
||||
@ -442,7 +442,7 @@ __cold int mdbx_env_deleteW(const wchar_t *pathname,
|
||||
err = MDBX_SUCCESS;
|
||||
|
||||
osal_free(dummy_env->pathname.buffer);
|
||||
return (err == MDBX_SUCCESS) ? rc : err;
|
||||
return LOG_IFERR((err == MDBX_SUCCESS) ? rc : err);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||
@ -457,7 +457,7 @@ __cold int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||
/* force to make cache of the multi-byte pathname representation */
|
||||
mdbx_env_get_path(env, &pathname);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
@ -466,14 +466,14 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(flags & ~ENV_USABLE_FLAGS))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(env->lazy_fd != INVALID_HANDLE_VALUE ||
|
||||
(env->flags & ENV_ACTIVE) != 0 || env->dxb_mmap.base))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
|
||||
/* Pickup previously mdbx_env_set_flags(),
|
||||
* but avoid MDBX_UTTERLY_NOSYNC by disjunction */
|
||||
@ -497,7 +497,7 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
debug_log(MDBX_LOG_ERROR, __func__, __LINE__,
|
||||
"System (i.e. OpenBSD) requires MDBX_WRITEMAP because "
|
||||
"of an internal flaw(s) in a file/buffer/page cache.\n");
|
||||
return 42 /* ENOPROTOOPT */;
|
||||
return LOG_IFERR(42 /* ENOPROTOOPT */);
|
||||
}
|
||||
}
|
||||
#endif /* MDBX_MMAP_INCOHERENT_FILE_WRITE */
|
||||
@ -590,7 +590,7 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
env->flags = saved_me_flags | ENV_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -598,13 +598,13 @@ __cold int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
#if !(defined(_WIN32) || defined(_WIN64))
|
||||
__cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
|
||||
if (unlikely(!env))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(env->signature.weak != env_signature))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
if (unlikely(env->flags & ENV_FATAL_ERROR))
|
||||
return MDBX_PANIC;
|
||||
return LOG_IFERR(MDBX_PANIC);
|
||||
|
||||
if (unlikely((env->flags & ENV_ACTIVE) == 0))
|
||||
return MDBX_SUCCESS;
|
||||
@ -614,7 +614,7 @@ __cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
|
||||
return MDBX_SUCCESS;
|
||||
|
||||
if (!atomic_cas32(&env->signature, env_signature, ~env_signature))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
if (env->txn)
|
||||
txn_abort(env->basal_txn);
|
||||
@ -628,7 +628,7 @@ __cold int mdbx_env_resurrect_after_fork(MDBX_env *env) {
|
||||
env->flags |= ENV_FATAL_ERROR;
|
||||
}
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
#endif /* Windows */
|
||||
|
||||
@ -637,10 +637,10 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
|
||||
int rc = MDBX_SUCCESS;
|
||||
|
||||
if (unlikely(!env))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(env->signature.weak != env_signature))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
#if MDBX_ENV_CHECKPID || !(defined(_WIN32) || defined(_WIN64))
|
||||
/* Check the PID even if MDBX_ENV_CHECKPID=0 on non-Windows
|
||||
@ -654,12 +654,12 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
|
||||
if (env->dxb_mmap.base &&
|
||||
(env->flags & (MDBX_RDONLY | ENV_FATAL_ERROR)) == 0 && env->basal_txn) {
|
||||
if (env->basal_txn->owner && env->basal_txn->owner != osal_thread_self())
|
||||
return MDBX_BUSY;
|
||||
return LOG_IFERR(MDBX_BUSY);
|
||||
} else
|
||||
dont_sync = true;
|
||||
|
||||
if (!atomic_cas32(&env->signature, env_signature, 0))
|
||||
return MDBX_EBADSIGN;
|
||||
return LOG_IFERR(MDBX_EBADSIGN);
|
||||
|
||||
if (!dont_sync) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
@ -712,7 +712,7 @@ __cold int mdbx_env_close_ex(MDBX_env *env, bool dont_sync) {
|
||||
VALGRIND_DESTROY_MEMPOOL(env);
|
||||
osal_free(env);
|
||||
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -889,32 +889,32 @@ __cold int env_info(const MDBX_env *env, const MDBX_txn *txn, MDBX_envinfo *out,
|
||||
__cold int mdbx_env_info_ex(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_envinfo *arg, size_t bytes) {
|
||||
if (unlikely((env == nullptr && txn == nullptr) || arg == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
|
||||
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
|
||||
const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid);
|
||||
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
|
||||
bytes != size_before_pgop_stat && bytes != size_before_dxbid)
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (txn) {
|
||||
int err = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
}
|
||||
if (env) {
|
||||
int err = check_env(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
if (txn && unlikely(txn->env != env))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
} else {
|
||||
env = txn->env;
|
||||
}
|
||||
|
||||
troika_t troika;
|
||||
return env_info(env, txn, arg, bytes, &troika);
|
||||
return LOG_IFERR(env_info(env, txn, arg, bytes, &troika));
|
||||
}
|
||||
|
||||
__cold int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *out,
|
||||
@ -926,21 +926,21 @@ __cold int mdbx_preopen_snapinfo(const char *pathname, MDBX_envinfo *out,
|
||||
rc = mdbx_preopen_snapinfoW(pathnameW, out, bytes);
|
||||
osal_free(pathnameW);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
|
||||
size_t bytes) {
|
||||
#endif /* Windows */
|
||||
if (unlikely(!out))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
const size_t size_before_bootid = offsetof(MDBX_envinfo, mi_bootid);
|
||||
const size_t size_before_pgop_stat = offsetof(MDBX_envinfo, mi_pgop_stat);
|
||||
const size_t size_before_dxbid = offsetof(MDBX_envinfo, mi_dxbid);
|
||||
if (unlikely(bytes != sizeof(MDBX_envinfo)) && bytes != size_before_bootid &&
|
||||
bytes != size_before_pgop_stat && bytes != size_before_dxbid)
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
memset(out, 0, bytes);
|
||||
if (likely(bytes > size_before_bootid)) {
|
||||
@ -954,7 +954,7 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
|
||||
if (unlikely(!is_powerof2(globals.sys_pagesize) ||
|
||||
globals.sys_pagesize < MDBX_MIN_PAGESIZE)) {
|
||||
ERROR("unsuitable system pagesize %u", globals.sys_pagesize);
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
}
|
||||
out->mi_sys_pagesize = globals.sys_pagesize;
|
||||
env.flags = MDBX_RDONLY | MDBX_NORDAHEAD | MDBX_ACCEDE | MDBX_VALIDATION;
|
||||
@ -1001,7 +1001,7 @@ __cold int mdbx_preopen_snapinfoW(const wchar_t *pathname, MDBX_envinfo *out,
|
||||
|
||||
bailout:
|
||||
env_close(&env, false);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -1012,7 +1012,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
|
||||
intptr_t shrink_threshold, intptr_t pagesize) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
const bool txn0_owned = env->basal_txn && env_txn0_owned(env);
|
||||
const bool inside_txn = txn0_owned && env->txn;
|
||||
@ -1029,12 +1029,12 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
|
||||
if (env->dxb_mmap.base) {
|
||||
/* env already mapped */
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
|
||||
if (!txn0_owned) {
|
||||
int err = lck_txn_lock(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
should_unlock = true;
|
||||
env->basal_txn->tw.troika = meta_tap(env);
|
||||
eASSERT(env, !env->txn && !env->basal_txn->nested);
|
||||
@ -1076,7 +1076,7 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
|
||||
} else {
|
||||
/* env NOT yet mapped */
|
||||
if (unlikely(inside_txn))
|
||||
return MDBX_PANIC;
|
||||
return LOG_IFERR(MDBX_PANIC);
|
||||
|
||||
/* is requested some auto-value for pagesize ? */
|
||||
if (pagesize >= INT_MAX /* maximal */)
|
||||
@ -1393,13 +1393,13 @@ __cold int mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower,
|
||||
bailout:
|
||||
if (should_unlock)
|
||||
lck_txn_unlock(env);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_sync_ex(MDBX_env *env, bool force, bool nonblock) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
return env_sync(env, force, nonblock);
|
||||
return LOG_IFERR(env_sync(env, force, nonblock));
|
||||
}
|
||||
|
@ -10,10 +10,10 @@ __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func,
|
||||
void *ctx) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!func))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
rc = MDBX_RESULT_TRUE;
|
||||
int serial = 0;
|
||||
@ -74,13 +74,13 @@ __cold int mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func,
|
||||
}
|
||||
}
|
||||
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_reader_check(MDBX_env *env, int *dead) {
|
||||
if (dead)
|
||||
*dead = 0;
|
||||
return mvcc_cleanup_dead(env, false, dead);
|
||||
return LOG_IFERR(mvcc_cleanup_dead(env, false, dead));
|
||||
}
|
||||
|
||||
/*------------------------------------------------------------------------------
|
||||
@ -89,28 +89,28 @@ __cold int mdbx_reader_check(MDBX_env *env, int *dead) {
|
||||
int mdbx_txn_lock(MDBX_env *env, bool dont_wait) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
if (unlikely(env->basal_txn->owner ||
|
||||
(env->basal_txn->flags & MDBX_TXN_FINISHED) == 0))
|
||||
return MDBX_BUSY;
|
||||
return LOG_IFERR(MDBX_BUSY);
|
||||
|
||||
return lck_txn_lock(env, dont_wait);
|
||||
return LOG_IFERR(lck_txn_lock(env, dont_wait));
|
||||
}
|
||||
|
||||
int mdbx_txn_unlock(MDBX_env *env) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
if (unlikely(env->basal_txn->owner != osal_thread_self()))
|
||||
return MDBX_THREAD_MISMATCH;
|
||||
return LOG_IFERR(MDBX_THREAD_MISMATCH);
|
||||
if (unlikely((env->basal_txn->flags & MDBX_TXN_FINISHED) == 0))
|
||||
return MDBX_BUSY;
|
||||
return LOG_IFERR(MDBX_BUSY);
|
||||
|
||||
lck_txn_unlock(env);
|
||||
return MDBX_SUCCESS;
|
||||
|
104
src/api-txn.c
104
src/api-txn.c
@ -11,7 +11,7 @@ int mdbx_txn_straggler(const MDBX_txn *txn, int *percent)
|
||||
{
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return (rc > 0) ? -rc : rc;
|
||||
return LOG_IFERR((rc > 0) ? -rc : rc);
|
||||
|
||||
MDBX_env *env = txn->env;
|
||||
if (unlikely((txn->flags & MDBX_TXN_RDONLY) == 0)) {
|
||||
@ -42,15 +42,15 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
uint32_t *mask) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!mask))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
if ((cx.outer.tree->flags & MDBX_DUPSORT) == 0)
|
||||
return MDBX_RESULT_TRUE;
|
||||
|
||||
@ -79,21 +79,21 @@ __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
default:
|
||||
ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED,
|
||||
"invalid node-size", flags);
|
||||
return MDBX_CORRUPTED;
|
||||
return LOG_IFERR(MDBX_CORRUPTED);
|
||||
}
|
||||
rc = outer_next(&cx.outer, &key, &data, MDBX_NEXT_NODUP);
|
||||
}
|
||||
|
||||
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
|
||||
return LOG_IFERR((rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc);
|
||||
}
|
||||
|
||||
int mdbx_canary_get(const MDBX_txn *txn, MDBX_canary *canary) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(canary == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*canary = txn->canary;
|
||||
return MDBX_SUCCESS;
|
||||
@ -106,37 +106,37 @@ int mdbx_get(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key || !data))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
return cursor_seek(&cx.outer, (MDBX_val *)key, data, MDBX_SET).err;
|
||||
return LOG_IFERR(cursor_seek(&cx.outer, (MDBX_val *)key, data, MDBX_SET).err);
|
||||
}
|
||||
|
||||
int mdbx_get_equal_or_great(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
|
||||
MDBX_val *data) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key || !data))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(txn->flags & MDBX_TXN_BLOCKED))
|
||||
return MDBX_BAD_TXN;
|
||||
return LOG_IFERR(MDBX_BAD_TXN);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
return cursor_ops(&cx.outer, key, data, MDBX_SET_LOWERBOUND);
|
||||
return LOG_IFERR(cursor_ops(&cx.outer, key, data, MDBX_SET_LOWERBOUND));
|
||||
}
|
||||
|
||||
int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
|
||||
@ -146,21 +146,21 @@ int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
|
||||
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key || !data))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = cursor_seek(&cx.outer, key, data, MDBX_SET_KEY).err;
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
if (values_count)
|
||||
*values_count = 0;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
if (values_count) {
|
||||
@ -180,7 +180,7 @@ int mdbx_get_ex(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
|
||||
int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (likely(canary)) {
|
||||
if (txn->canary.x == canary->x && txn->canary.y == canary->y &&
|
||||
@ -221,7 +221,7 @@ int mdbx_canary_put(MDBX_txn *txn, const MDBX_canary *canary) {
|
||||
int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
const MDBX_env *env = txn->env;
|
||||
const ptrdiff_t offset = ptr_dist(ptr, env->dxb_mmap.base);
|
||||
@ -232,7 +232,7 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
|
||||
if (unlikely(page->pgno != pgno || (page->flags & P_ILL_BITS) != 0)) {
|
||||
/* The ptr pointed into middle of a large page,
|
||||
* not to the beginning of a data. */
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
}
|
||||
return ((txn->flags & MDBX_TXN_RDONLY) || !is_modifable(txn, page))
|
||||
? MDBX_RESULT_FALSE
|
||||
@ -243,7 +243,8 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
|
||||
* распределенных страниц. Такое может случится если mdbx_is_dirty()
|
||||
* вызывается после операции, в ходе которой грязная страница была
|
||||
* возвращена в нераспределенное пространство. */
|
||||
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EINVAL : MDBX_RESULT_TRUE;
|
||||
return (txn->flags & MDBX_TXN_RDONLY) ? LOG_IFERR(MDBX_EINVAL)
|
||||
: MDBX_RESULT_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@ -253,29 +254,31 @@ int mdbx_is_dirty(const MDBX_txn *txn, const void *ptr) {
|
||||
*
|
||||
* Для режима MDBX_WRITE_MAP режима страница однозначно "не грязная",
|
||||
* а для режимов без MDBX_WRITE_MAP однозначно "не чистая". */
|
||||
return (txn->flags & (MDBX_WRITEMAP | MDBX_TXN_RDONLY)) ? MDBX_EINVAL
|
||||
: MDBX_RESULT_TRUE;
|
||||
return (txn->flags & (MDBX_WRITEMAP | MDBX_TXN_RDONLY))
|
||||
? LOG_IFERR(MDBX_EINVAL)
|
||||
: MDBX_RESULT_TRUE;
|
||||
}
|
||||
|
||||
int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
const MDBX_val *data) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(dbi <= FREE_DBI))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
return LOG_IFERR((txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
|
||||
: MDBX_BAD_TXN);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
MDBX_val proxy;
|
||||
MDBX_cursor_op op = MDBX_SET;
|
||||
@ -288,39 +291,40 @@ int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
}
|
||||
rc = cursor_seek(&cx.outer, (MDBX_val *)key, (MDBX_val *)data, op).err;
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cx.outer.next = txn->cursors[dbi];
|
||||
txn->cursors[dbi] = &cx.outer;
|
||||
rc = cursor_del(&cx.outer, flags);
|
||||
txn->cursors[dbi] = cx.outer.next;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data,
|
||||
MDBX_put_flags_t flags) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key || !data))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(dbi <= FREE_DBI))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(flags & ~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_ALLDUPS |
|
||||
MDBX_ALLDUPS | MDBX_RESERVE | MDBX_APPEND |
|
||||
MDBX_APPENDDUP | MDBX_CURRENT | MDBX_MULTIPLE)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(txn->flags & (MDBX_TXN_RDONLY | MDBX_TXN_BLOCKED)))
|
||||
return (txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS : MDBX_BAD_TXN;
|
||||
return LOG_IFERR((txn->flags & MDBX_TXN_RDONLY) ? MDBX_EACCESS
|
||||
: MDBX_BAD_TXN);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
cx.outer.next = txn->cursors[dbi];
|
||||
txn->cursors[dbi] = &cx.outer;
|
||||
|
||||
@ -348,7 +352,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data,
|
||||
rc = cursor_put_checklen(&cx.outer, key, data, flags);
|
||||
txn->cursors[dbi] = cx.outer.next;
|
||||
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
//------------------------------------------------------------------------------
|
||||
@ -383,30 +387,30 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
void *preserver_context) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!key || !old_data || old_data == new_data))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(old_data->iov_base == nullptr && old_data->iov_len))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(new_data == nullptr &&
|
||||
(flags & (MDBX_CURRENT | MDBX_RESERVE)) != MDBX_CURRENT))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(dbi <= FREE_DBI))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(flags &
|
||||
~(MDBX_NOOVERWRITE | MDBX_NODUPDATA | MDBX_ALLDUPS |
|
||||
MDBX_RESERVE | MDBX_APPEND | MDBX_APPENDDUP | MDBX_CURRENT)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
cx.outer.next = txn->cursors[dbi];
|
||||
txn->cursors[dbi] = &cx.outer;
|
||||
|
||||
@ -427,7 +431,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
} else {
|
||||
/* в old_data буфер для сохранения предыдущего значения */
|
||||
if (unlikely(new_data && old_data->iov_base == new_data->iov_base))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
MDBX_val present_data;
|
||||
rc = cursor_seek(&cx.outer, &present_key, &present_data, MDBX_SET_KEY).err;
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
@ -485,7 +489,7 @@ int mdbx_replace_ex(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key,
|
||||
|
||||
bailout:
|
||||
txn->cursors[dbi] = cx.outer.next;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
static int default_value_preserver(void *context, MDBX_val *target,
|
||||
|
@ -2019,13 +2019,13 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb,
|
||||
unsigned timeout_seconds_16dot16) {
|
||||
int err, rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
if (unlikely(!cb || !ctx || ctx->internal))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
MDBX_chk_internal_t *const chk = osal_calloc(1, sizeof(MDBX_chk_internal_t));
|
||||
if (unlikely(!chk))
|
||||
return MDBX_ENOMEM;
|
||||
return LOG_IFERR(MDBX_ENOMEM);
|
||||
|
||||
chk->cb = cb;
|
||||
chk->usr = ctx;
|
||||
@ -2101,5 +2101,5 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb,
|
||||
err = chk_scope_begin(chk, 0, MDBX_chk_finalize, nullptr, nullptr, nullptr);
|
||||
rc = chk_scope_end(chk, err ? err : rc);
|
||||
chk_dispose(chk);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
70
src/cold.c
70
src/cold.c
@ -229,35 +229,35 @@ __cold static int stat_acc(const MDBX_txn *txn, MDBX_stat *st, size_t bytes) {
|
||||
__cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_stat *dest, size_t bytes) {
|
||||
if (unlikely(!dest))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid);
|
||||
if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid)
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (likely(txn)) {
|
||||
if (env && unlikely(txn->env != env))
|
||||
return MDBX_EINVAL;
|
||||
return stat_acc(txn, dest, bytes);
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
return LOG_IFERR(stat_acc(txn, dest, bytes));
|
||||
}
|
||||
|
||||
int err = check_env(env, true);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
|
||||
if (env->txn && env_txn0_owned(env))
|
||||
/* inside write-txn */
|
||||
return stat_acc(env->txn, dest, bytes);
|
||||
return LOG_IFERR(stat_acc(env->txn, dest, bytes));
|
||||
|
||||
MDBX_txn *tmp_txn;
|
||||
err = mdbx_txn_begin((MDBX_env *)env, nullptr, MDBX_TXN_RDONLY, &tmp_txn);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
|
||||
const int rc = stat_acc(tmp_txn, dest, bytes);
|
||||
err = mdbx_txn_abort(tmp_txn);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return rc;
|
||||
return LOG_IFERR(err);
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -271,23 +271,23 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
|
||||
MDBX_warmup_flags_t flags,
|
||||
unsigned timeout_seconds_16dot16) {
|
||||
if (unlikely(env == nullptr && txn == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(flags >
|
||||
(MDBX_warmup_force | MDBX_warmup_oomsafe | MDBX_warmup_lock |
|
||||
MDBX_warmup_touchlimit | MDBX_warmup_release)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (txn) {
|
||||
int err = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
}
|
||||
if (env) {
|
||||
int err = check_env(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
if (txn && unlikely(txn->env != env))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
} else {
|
||||
env = txn->env;
|
||||
}
|
||||
@ -504,7 +504,7 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
|
||||
#endif
|
||||
}
|
||||
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@ -512,10 +512,10 @@ __cold int mdbx_env_warmup(const MDBX_env *env, const MDBX_txn *txn,
|
||||
__cold int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!arg))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*arg = env->lazy_fd;
|
||||
return MDBX_SUCCESS;
|
||||
@ -525,21 +525,21 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
|
||||
bool onoff) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(flags & ((env->flags & ENV_ACTIVE) ? ~ENV_CHANGEABLE_FLAGS
|
||||
: ~ENV_USABLE_FLAGS)))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
|
||||
const bool lock_needed = (env->flags & ENV_ACTIVE) && !env_txn0_owned(env);
|
||||
bool should_unlock = false;
|
||||
if (lock_needed) {
|
||||
rc = lck_txn_lock(env, false);
|
||||
if (unlikely(rc))
|
||||
return rc;
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return LOG_IFERR(rc);
|
||||
should_unlock = true;
|
||||
}
|
||||
|
||||
@ -556,10 +556,10 @@ __cold int mdbx_env_set_flags(MDBX_env *env, MDBX_env_flags_t flags,
|
||||
__cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!arg))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*arg = env->flags & ENV_USABLE_FLAGS;
|
||||
return MDBX_SUCCESS;
|
||||
@ -568,7 +568,7 @@ __cold int mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) {
|
||||
__cold int mdbx_env_set_userctx(MDBX_env *env, void *ctx) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
env->userctx = ctx;
|
||||
return MDBX_SUCCESS;
|
||||
@ -581,21 +581,21 @@ __cold void *mdbx_env_get_userctx(const MDBX_env *env) {
|
||||
__cold int mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
#if MDBX_DEBUG
|
||||
env->assert_func = func;
|
||||
return MDBX_SUCCESS;
|
||||
#else
|
||||
(void)func;
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
#endif
|
||||
}
|
||||
|
||||
__cold int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr) {
|
||||
int rc = check_env(env, false);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
env->hsr_callback = hsr;
|
||||
return MDBX_SUCCESS;
|
||||
@ -610,10 +610,10 @@ __cold MDBX_hsr_func *mdbx_env_get_hsr(const MDBX_env *env) {
|
||||
__cold int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **arg) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!arg))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*arg = env->pathname.specified;
|
||||
return MDBX_SUCCESS;
|
||||
@ -623,10 +623,10 @@ __cold int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **arg) {
|
||||
__cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!arg))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (!env->pathname_char) {
|
||||
@ -643,17 +643,17 @@ __cold int mdbx_env_get_path(const MDBX_env *env, const char **arg) {
|
||||
rc = mb_len ? MDBX_SUCCESS : (int)GetLastError();
|
||||
}
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
char *const mb_pathname = osal_malloc(mb_len);
|
||||
if (!mb_pathname)
|
||||
return MDBX_ENOMEM;
|
||||
return LOG_IFERR(MDBX_ENOMEM);
|
||||
if (mb_len != (size_t)WideCharToMultiByte(
|
||||
CP_THREAD_ACP, flags, env->pathname.specified, -1,
|
||||
mb_pathname, (int)mb_len, nullptr, nullptr)) {
|
||||
rc = (int)GetLastError();
|
||||
osal_free(mb_pathname);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
if (env->pathname_char ||
|
||||
InterlockedCompareExchangePointer((PVOID volatile *)&env->pathname_char,
|
||||
|
24
src/copy.c
24
src/copy.c
@ -844,26 +844,26 @@ __cold int mdbx_txn_copy2fd(MDBX_txn *txn, mdbx_filehandle_t fd,
|
||||
rc = copy2fd(txn, fd, flags);
|
||||
if (flags & MDBX_CP_DISPOSE_TXN)
|
||||
mdbx_txn_abort(txn);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd,
|
||||
MDBX_copy_flags_t flags) {
|
||||
if (unlikely(flags & (MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
MDBX_txn *txn = nullptr;
|
||||
rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = copy2fd(txn, fd, flags | MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN);
|
||||
mdbx_txn_abort(txn);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest_path,
|
||||
@ -875,7 +875,7 @@ __cold int mdbx_txn_copy2pathname(MDBX_txn *txn, const char *dest_path,
|
||||
rc = mdbx_txn_copy2pathnameW(txn, dest_pathW, flags);
|
||||
osal_free(dest_pathW);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest_path,
|
||||
@ -886,7 +886,7 @@ __cold int mdbx_txn_copy2pathnameW(MDBX_txn *txn, const wchar_t *dest_path,
|
||||
rc = copy2pathname(txn, dest_path, flags);
|
||||
if (flags & MDBX_CP_DISPOSE_TXN)
|
||||
mdbx_txn_abort(txn);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
|
||||
@ -898,26 +898,26 @@ __cold int mdbx_env_copy(MDBX_env *env, const char *dest_path,
|
||||
rc = mdbx_env_copyW(env, dest_pathW, flags);
|
||||
osal_free(dest_pathW);
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest_path,
|
||||
MDBX_copy_flags_t flags) {
|
||||
#endif /* Windows */
|
||||
if (unlikely(flags & (MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
MDBX_txn *txn = nullptr;
|
||||
rc = mdbx_txn_begin(env, nullptr, MDBX_TXN_RDONLY, &txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = copy2pathname(txn, dest_path,
|
||||
flags | MDBX_CP_DISPOSE_TXN | MDBX_CP_RENEW_TXN);
|
||||
mdbx_txn_abort(txn);
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
68
src/dbi.c
68
src/dbi.c
@ -745,35 +745,35 @@ static defer_free_item_t *dbi_close_locked(MDBX_env *env, MDBX_dbi dbi) {
|
||||
|
||||
int mdbx_dbi_open(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags,
|
||||
MDBX_dbi *dbi) {
|
||||
return dbi_open_cstr(txn, name, flags, dbi, nullptr, nullptr);
|
||||
return LOG_IFERR(dbi_open_cstr(txn, name, flags, dbi, nullptr, nullptr));
|
||||
}
|
||||
|
||||
int mdbx_dbi_open2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags,
|
||||
MDBX_dbi *dbi) {
|
||||
return dbi_open(txn, name, flags, dbi, nullptr, nullptr);
|
||||
return LOG_IFERR(dbi_open(txn, name, flags, dbi, nullptr, nullptr));
|
||||
}
|
||||
|
||||
int mdbx_dbi_open_ex(MDBX_txn *txn, const char *name, MDBX_db_flags_t flags,
|
||||
MDBX_dbi *dbi, MDBX_cmp_func *keycmp,
|
||||
MDBX_cmp_func *datacmp) {
|
||||
return dbi_open_cstr(txn, name, flags, dbi, keycmp, datacmp);
|
||||
return LOG_IFERR(dbi_open_cstr(txn, name, flags, dbi, keycmp, datacmp));
|
||||
}
|
||||
|
||||
int mdbx_dbi_open_ex2(MDBX_txn *txn, const MDBX_val *name,
|
||||
MDBX_db_flags_t flags, MDBX_dbi *dbi,
|
||||
MDBX_cmp_func *keycmp, MDBX_cmp_func *datacmp) {
|
||||
return dbi_open(txn, name, flags, dbi, keycmp, datacmp);
|
||||
return LOG_IFERR(dbi_open(txn, name, flags, dbi, keycmp, datacmp));
|
||||
}
|
||||
|
||||
__cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (txn->dbs[dbi].height) {
|
||||
cx.outer.next = txn->cursors[dbi];
|
||||
@ -782,7 +782,7 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
|
||||
dbi == MAIN_DBI || (cx.outer.tree->flags & MDBX_DUPSORT));
|
||||
txn->cursors[dbi] = cx.outer.next;
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
/* Invalidate the dropped DB's cursors */
|
||||
@ -820,12 +820,12 @@ __cold int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, bool del) {
|
||||
txn->dbi_state[dbi] = DBI_LINDO | DBI_OLDEN;
|
||||
rc = osal_fastmutex_acquire(&env->dbi_lock);
|
||||
if (likely(rc == MDBX_SUCCESS))
|
||||
return defer_and_release(env, dbi_close_locked(env, dbi));
|
||||
return LOG_IFERR(defer_and_release(env, dbi_close_locked(env, dbi)));
|
||||
}
|
||||
}
|
||||
}
|
||||
txn->flags |= MDBX_TXN_ERROR;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
__cold int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name_cstr) {
|
||||
@ -838,22 +838,22 @@ __cold int mdbx_dbi_rename(MDBX_txn *txn, MDBX_dbi dbi, const char *name_cstr) {
|
||||
thunk.iov_base = (void *)name_cstr;
|
||||
name = &thunk;
|
||||
}
|
||||
return mdbx_dbi_rename2(txn, dbi, name);
|
||||
return LOG_IFERR(mdbx_dbi_rename2(txn, dbi, name));
|
||||
}
|
||||
|
||||
int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(dbi < CORE_DBS))
|
||||
return (dbi == MAIN_DBI) ? MDBX_SUCCESS : MDBX_BAD_DBI;
|
||||
return (dbi == MAIN_DBI) ? MDBX_SUCCESS : LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(dbi >= env->max_dbi))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
if (unlikely(dbi < CORE_DBS || dbi >= env->max_dbi))
|
||||
return MDBX_BAD_DBI;
|
||||
return LOG_IFERR(MDBX_BAD_DBI);
|
||||
|
||||
rc = osal_fastmutex_acquire(&env->dbi_lock);
|
||||
if (likely(rc == MDBX_SUCCESS && dbi < env->n_dbi)) {
|
||||
@ -886,7 +886,7 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
|
||||
(DBI_LINDO | DBI_DIRTY | DBI_CREAT)) > DBI_LINDO) {
|
||||
bailout_dirty_dbi:
|
||||
osal_fastmutex_release(&env->dbi_lock);
|
||||
return MDBX_DANGLING_DBI;
|
||||
return LOG_IFERR(MDBX_DANGLING_DBI);
|
||||
}
|
||||
osal_memory_barrier();
|
||||
if (unlikely(hazard != env->txn))
|
||||
@ -903,21 +903,21 @@ int mdbx_dbi_close(MDBX_env *env, MDBX_dbi dbi) {
|
||||
}
|
||||
rc = defer_and_release(env, dbi_close_locked(env, dbi));
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
int mdbx_dbi_flags_ex(const MDBX_txn *txn, MDBX_dbi dbi, unsigned *flags,
|
||||
unsigned *state) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR - MDBX_TXN_PARKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!flags || !state))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
rc = dbi_check(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
*flags = txn->dbs[dbi].flags & DB_PERSISTENT_FLAGS;
|
||||
*state =
|
||||
@ -930,19 +930,19 @@ __cold int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi,
|
||||
const MDBX_val *new_name) {
|
||||
int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(new_name == MDBX_CHK_MAIN ||
|
||||
new_name->iov_base == MDBX_CHK_MAIN || new_name == MDBX_CHK_GC ||
|
||||
new_name->iov_base == MDBX_CHK_GC || new_name == MDBX_CHK_META ||
|
||||
new_name->iov_base == MDBX_CHK_META))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(dbi < CORE_DBS))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
rc = dbi_check(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = osal_fastmutex_acquire(&txn->env->dbi_lock);
|
||||
if (likely(rc == MDBX_SUCCESS)) {
|
||||
@ -952,7 +952,7 @@ __cold int mdbx_dbi_rename2(MDBX_txn *txn, MDBX_dbi dbi,
|
||||
defer_and_release(txn->env, pair.defer);
|
||||
rc = pair.err;
|
||||
}
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
static void stat_get(const tree_t *db, MDBX_stat *st, size_t bytes) {
|
||||
@ -970,26 +970,26 @@ __cold int mdbx_dbi_stat(const MDBX_txn *txn, MDBX_dbi dbi, MDBX_stat *dest,
|
||||
size_t bytes) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!dest))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
rc = dbi_check(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
const size_t size_before_modtxnid = offsetof(MDBX_stat, ms_mod_txnid);
|
||||
if (unlikely(bytes != sizeof(MDBX_stat)) && bytes != size_before_modtxnid)
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(txn->flags & MDBX_TXN_BLOCKED))
|
||||
return MDBX_BAD_TXN;
|
||||
return LOG_IFERR(MDBX_BAD_TXN);
|
||||
|
||||
if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) {
|
||||
rc = tbl_fetch((MDBX_txn *)txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
dest->ms_psize = txn->env->ps;
|
||||
@ -1024,16 +1024,16 @@ __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi,
|
||||
__cold int mdbx_enumerate_tables(const MDBX_txn *txn,
|
||||
MDBX_table_enum_func *func, void *ctx) {
|
||||
if (unlikely(!func))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, MAIN_DBI);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cx.outer.next = txn->cursors[MAIN_DBI];
|
||||
txn->cursors[MAIN_DBI] = &cx.outer;
|
||||
@ -1076,5 +1076,5 @@ __cold int mdbx_enumerate_tables(const MDBX_txn *txn,
|
||||
|
||||
bailout:
|
||||
txn->cursors[MAIN_DBI] = cx.outer.next;
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
@ -105,7 +105,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
uint64_t value) {
|
||||
int err = check_env(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
|
||||
const bool lock_needed =
|
||||
((env->flags & ENV_ACTIVE) && env->basal_txn && !env_txn0_owned(env));
|
||||
@ -115,11 +115,11 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = MAX_WRITE;
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
if (unlikely(!(env->flags & ENV_ACTIVE)))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
if (unlikely(value > SIZE_MAX - 65536))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
value = bytes2pgno(env, (size_t)value + env->ps - 1);
|
||||
if ((uint32_t)value !=
|
||||
atomic_load32(&env->lck->autosync_threshold, mo_AcquireRelease) &&
|
||||
@ -138,11 +138,11 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 2780315 /* 42.42424 секунды */;
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
if (unlikely(!(env->flags & ENV_ACTIVE)))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
if (unlikely(value > UINT32_MAX))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
value = osal_16dot16_to_monotime((uint32_t)value);
|
||||
if (value != atomic_load64(&env->lck->autosync_period, mo_AcquireRelease) &&
|
||||
atomic_store64(&env->lck->autosync_period, value, mo_Relaxed)
|
||||
@ -159,9 +159,9 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 42;
|
||||
if (unlikely(value > MDBX_MAX_DBI))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(env->dxb_mmap.base))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
env->max_dbi = (unsigned)value + CORE_DBS;
|
||||
break;
|
||||
|
||||
@ -169,9 +169,9 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = MDBX_READERS_LIMIT;
|
||||
if (unlikely(value < 1 || value > MDBX_READERS_LIMIT))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(env->dxb_mmap.base))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
env->max_readers = (unsigned)value;
|
||||
break;
|
||||
|
||||
@ -179,12 +179,12 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = INT_MAX;
|
||||
if (unlikely(value > INT_MAX))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (env->options.dp_reserve_limit != (unsigned)value) {
|
||||
if (lock_needed) {
|
||||
err = lck_txn_lock(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
should_unlock = true;
|
||||
}
|
||||
env->options.dp_reserve_limit = (unsigned)value;
|
||||
@ -206,7 +206,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
env->options.flags.non_auto.rp_augment_limit = 0;
|
||||
env->options.rp_augment_limit = default_rp_augment_limit(env);
|
||||
} else if (unlikely(value > PAGELIST_LIMIT))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
else {
|
||||
env->options.flags.non_auto.rp_augment_limit = 1;
|
||||
env->options.rp_augment_limit = (unsigned)value;
|
||||
@ -217,13 +217,13 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 0;
|
||||
if (unlikely(value > UINT32_MAX))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
value = osal_16dot16_to_monotime((uint32_t)value);
|
||||
if (value != env->options.gc_time_limit) {
|
||||
if (env->txn && lock_needed)
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
env->options.gc_time_limit = value;
|
||||
if (!env->options.flags.non_auto.rp_augment_limit)
|
||||
env->options.rp_augment_limit = default_rp_augment_limit(env);
|
||||
@ -235,13 +235,13 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = PAGELIST_LIMIT;
|
||||
if (unlikely(value > PAGELIST_LIMIT || value < CURSOR_STACK_SIZE * 4))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (unlikely(env->flags & MDBX_RDONLY))
|
||||
return MDBX_EACCESS;
|
||||
return LOG_IFERR(MDBX_EACCESS);
|
||||
if (lock_needed) {
|
||||
err = lck_txn_lock(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
should_unlock = true;
|
||||
}
|
||||
if (env->txn)
|
||||
@ -269,21 +269,21 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 8;
|
||||
if (unlikely(value > 255))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
env->options.spill_max_denominator = (uint8_t)value;
|
||||
break;
|
||||
case MDBX_opt_spill_min_denominator:
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 8;
|
||||
if (unlikely(value > 255))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
env->options.spill_min_denominator = (uint8_t)value;
|
||||
break;
|
||||
case MDBX_opt_spill_parent4child_denominator:
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 0;
|
||||
if (unlikely(value > 255))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
env->options.spill_parent4child_denominator = (uint8_t)value;
|
||||
break;
|
||||
|
||||
@ -291,7 +291,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 64;
|
||||
if (unlikely(value > 255))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
env->options.dp_loose_limit = (uint8_t)value;
|
||||
break;
|
||||
|
||||
@ -299,7 +299,7 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
if (value == /* default */ UINT64_MAX)
|
||||
value = 65536 / 4 /* 25% */;
|
||||
if (unlikely(value < 8192 || value > 32768))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
env->options.merge_threshold_16dot16_percent = (unsigned)value;
|
||||
recalculate_merge_thresholds(env);
|
||||
break;
|
||||
@ -392,33 +392,33 @@ __cold int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
break;
|
||||
|
||||
default:
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
}
|
||||
|
||||
if (should_unlock)
|
||||
lck_txn_unlock(env);
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
}
|
||||
|
||||
__cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option,
|
||||
uint64_t *pvalue) {
|
||||
int err = check_env(env, false);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
if (unlikely(!pvalue))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
switch (option) {
|
||||
case MDBX_opt_sync_bytes:
|
||||
if (unlikely(!(env->flags & ENV_ACTIVE)))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
*pvalue = pgno2bytes(
|
||||
env, atomic_load32(&env->lck->autosync_threshold, mo_Relaxed));
|
||||
break;
|
||||
|
||||
case MDBX_opt_sync_period:
|
||||
if (unlikely(!(env->flags & ENV_ACTIVE)))
|
||||
return MDBX_EPERM;
|
||||
return LOG_IFERR(MDBX_EPERM);
|
||||
*pvalue = osal_monotime_to_16dot16(
|
||||
atomic_load64(&env->lck->autosync_period, mo_Relaxed));
|
||||
break;
|
||||
@ -501,7 +501,7 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option,
|
||||
break;
|
||||
|
||||
default:
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
}
|
||||
|
||||
return MDBX_SUCCESS;
|
||||
|
@ -59,6 +59,16 @@ __cold void debug_log(int level, const char *function, int line,
|
||||
va_end(args);
|
||||
}
|
||||
|
||||
__cold int log_error(const int err, const char *func, unsigned line) {
|
||||
assert(err != MDBX_SUCCESS);
|
||||
if (unlikely(globals.loglevel >= MDBX_LOG_DEBUG)) {
|
||||
char buf[256];
|
||||
debug_log(MDBX_LOG_ERROR, func, line, "error %d (%s)\n", err,
|
||||
mdbx_strerror_r(err, buf, sizeof(buf)));
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Dump a val in ascii or hexadecimal. */
|
||||
__cold const char *mdbx_dump_val(const MDBX_val *val, char *const buf,
|
||||
const size_t bufsize) {
|
||||
|
@ -158,3 +158,11 @@ MDBX_INTERNAL const char *pagetype_caption(const uint8_t type,
|
||||
#define DKEY_DEBUG(x) ("-")
|
||||
#define DVAL_DEBUG(x) ("-")
|
||||
#endif
|
||||
|
||||
MDBX_INTERNAL int log_error(const int err, const char *func, unsigned line);
|
||||
|
||||
static inline int log_if_error(int err, const char *func, unsigned line) {
|
||||
return likely(err == MDBX_SUCCESS) ? err : log_error(err, func, line);
|
||||
}
|
||||
|
||||
#define LOG_IFERR(err) log_if_error((err), __func__, __LINE__)
|
||||
|
14
src/misc.c
14
src/misc.c
@ -10,7 +10,7 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) {
|
||||
intptr_t pagesize, total_ram_pages;
|
||||
int err = mdbx_get_sysraminfo(&pagesize, &total_ram_pages, nullptr);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
|
||||
const int log2page = log2n_powerof2(pagesize);
|
||||
const intptr_t volume_pages = (volume + pagesize - 1) >> log2page;
|
||||
@ -24,7 +24,7 @@ __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) {
|
||||
intptr_t avail_ram_pages;
|
||||
err = mdbx_get_sysraminfo(nullptr, nullptr, &avail_ram_pages);
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
return err;
|
||||
return LOG_IFERR(err);
|
||||
|
||||
return (volume_pages + redundancy_pages >= avail_ram_pages)
|
||||
? MDBX_RESULT_FALSE
|
||||
@ -35,16 +35,16 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
|
||||
uint64_t increment) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
rc = dbi_check(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(txn->dbi_state[dbi] & DBI_STALE)) {
|
||||
rc = tbl_fetch(txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
tree_t *dbs = &txn->dbs[dbi];
|
||||
@ -95,10 +95,10 @@ int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result,
|
||||
cursor_couple_t cx;
|
||||
rc = cursor_init(&cx.outer, txn, MAIN_DBI);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
rc = tree_search(&cx.outer, nullptr, Z_MODIFY | Z_ROOTONLY);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
}
|
||||
dbs->sequence = new;
|
||||
|
@ -536,14 +536,14 @@ __cold txnid_t mvcc_kick_laggards(MDBX_env *env, const txnid_t straggler) {
|
||||
__cold int mdbx_thread_register(const MDBX_env *env) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!env->lck_mmap.lck))
|
||||
return (env->flags & MDBX_EXCLUSIVE) ? MDBX_EINVAL : MDBX_EPERM;
|
||||
return LOG_IFERR((env->flags & MDBX_EXCLUSIVE) ? MDBX_EINVAL : MDBX_EPERM);
|
||||
|
||||
if (unlikely((env->flags & ENV_TXKEY) == 0)) {
|
||||
eASSERT(env, env->flags & MDBX_NOSTICKYTHREADS);
|
||||
return MDBX_EINVAL /* MDBX_NOSTICKYTHREADS mode */;
|
||||
return LOG_IFERR(MDBX_EINVAL) /* MDBX_NOSTICKYTHREADS mode */;
|
||||
}
|
||||
|
||||
eASSERT(env, (env->flags & (MDBX_NOSTICKYTHREADS | ENV_TXKEY)) == ENV_TXKEY);
|
||||
@ -552,17 +552,17 @@ __cold int mdbx_thread_register(const MDBX_env *env) {
|
||||
eASSERT(env, r->pid.weak == env->pid);
|
||||
eASSERT(env, r->tid.weak == osal_thread_self());
|
||||
if (unlikely(r->pid.weak != env->pid))
|
||||
return MDBX_BAD_RSLOT;
|
||||
return LOG_IFERR(MDBX_BAD_RSLOT);
|
||||
return MDBX_RESULT_TRUE /* already registered */;
|
||||
}
|
||||
|
||||
return mvcc_bind_slot((MDBX_env *)env).err;
|
||||
return LOG_IFERR(mvcc_bind_slot((MDBX_env *)env).err);
|
||||
}
|
||||
|
||||
__cold int mdbx_thread_unregister(const MDBX_env *env) {
|
||||
int rc = check_env(env, true);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!env->lck_mmap.lck))
|
||||
return MDBX_RESULT_TRUE;
|
||||
@ -580,11 +580,11 @@ __cold int mdbx_thread_unregister(const MDBX_env *env) {
|
||||
eASSERT(env, r->pid.weak == env->pid);
|
||||
eASSERT(env, r->tid.weak == osal_thread_self());
|
||||
if (unlikely(r->pid.weak != env->pid || r->tid.weak != osal_thread_self()))
|
||||
return MDBX_BAD_RSLOT;
|
||||
return LOG_IFERR(MDBX_BAD_RSLOT);
|
||||
|
||||
eASSERT(env, r->txnid.weak >= SAFE64_INVALID_THRESHOLD);
|
||||
if (unlikely(r->txnid.weak < SAFE64_INVALID_THRESHOLD))
|
||||
return MDBX_BUSY /* transaction is still active */;
|
||||
return LOG_IFERR(MDBX_BUSY) /* transaction is still active */;
|
||||
|
||||
atomic_store32(&r->pid, 0, mo_Relaxed);
|
||||
atomic_store32(&env->lck->rdt_refresh_flag, true, mo_AcquireRelease);
|
||||
|
26
src/osal.c
26
src/osal.c
@ -3405,7 +3405,7 @@ __cold static bin128_t osal_bootid(void) {
|
||||
__cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
intptr_t *avail_pages) {
|
||||
if (!page_size && !total_pages && !avail_pages)
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
if (total_pages)
|
||||
*total_pages = -1;
|
||||
if (avail_pages)
|
||||
@ -3415,7 +3415,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
if (page_size)
|
||||
*page_size = pagesize;
|
||||
if (unlikely(pagesize < MDBX_MIN_PAGESIZE || !is_powerof2(pagesize)))
|
||||
return MDBX_INCOMPATIBLE;
|
||||
return LOG_IFERR(MDBX_INCOMPATIBLE);
|
||||
|
||||
MDBX_MAYBE_UNUSED const int log2page = log2n_powerof2(pagesize);
|
||||
assert(pagesize == (INT64_C(1) << log2page));
|
||||
@ -3426,7 +3426,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
memset(&info, 0, sizeof(info));
|
||||
info.dwLength = sizeof(info);
|
||||
if (!GlobalMemoryStatusEx(&info))
|
||||
return (int)GetLastError();
|
||||
return LOG_IFERR((int)GetLastError());
|
||||
#endif
|
||||
|
||||
if (total_pages) {
|
||||
@ -3435,11 +3435,11 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
#elif defined(_SC_PHYS_PAGES)
|
||||
const intptr_t total_ram_pages = sysconf(_SC_PHYS_PAGES);
|
||||
if (total_ram_pages == -1)
|
||||
return errno;
|
||||
return LOG_IFERR(errno);
|
||||
#elif defined(_SC_AIX_REALMEM)
|
||||
const intptr_t total_ram_Kb = sysconf(_SC_AIX_REALMEM);
|
||||
if (total_ram_Kb == -1)
|
||||
return errno;
|
||||
return LOG_IFERR(errno);
|
||||
const intptr_t total_ram_pages = (total_ram_Kb << 10) >> log2page;
|
||||
#elif defined(HW_USERMEM) || defined(HW_PHYSMEM64) || defined(HW_MEMSIZE) || \
|
||||
defined(HW_PHYSMEM)
|
||||
@ -3461,16 +3461,16 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
#endif
|
||||
mib,
|
||||
ARRAY_LENGTH(mib), &ram, &len, nullptr, 0) != 0)
|
||||
return errno;
|
||||
return LOG_IFERR(errno);
|
||||
if (len != sizeof(ram))
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
const intptr_t total_ram_pages = (intptr_t)(ram >> log2page);
|
||||
#else
|
||||
#error "FIXME: Get User-accessible or physical RAM"
|
||||
#endif
|
||||
*total_pages = total_ram_pages;
|
||||
if (total_ram_pages < 1)
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
}
|
||||
|
||||
if (avail_pages) {
|
||||
@ -3479,7 +3479,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
#elif defined(_SC_AVPHYS_PAGES)
|
||||
const intptr_t avail_ram_pages = sysconf(_SC_AVPHYS_PAGES);
|
||||
if (avail_ram_pages == -1)
|
||||
return errno;
|
||||
return LOG_IFERR(errno);
|
||||
#elif defined(__MACH__)
|
||||
mach_msg_type_number_t count = HOST_VM_INFO_COUNT;
|
||||
vm_statistics_data_t vmstat;
|
||||
@ -3488,7 +3488,7 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
(host_info_t)&vmstat, &count);
|
||||
mach_port_deallocate(mach_task_self(), mport);
|
||||
if (unlikely(kerr != KERN_SUCCESS))
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
const intptr_t avail_ram_pages = vmstat.free_count;
|
||||
#elif defined(VM_TOTAL) || defined(VM_METER)
|
||||
struct vmtotal info;
|
||||
@ -3506,16 +3506,16 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
|
||||
#endif
|
||||
mib,
|
||||
ARRAY_LENGTH(mib), &info, &len, nullptr, 0) != 0)
|
||||
return errno;
|
||||
return LOG_IFERR(errno);
|
||||
if (len != sizeof(info))
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
const intptr_t avail_ram_pages = info.t_free;
|
||||
#else
|
||||
#error "FIXME: Get Available RAM"
|
||||
#endif
|
||||
*avail_pages = avail_ram_pages;
|
||||
if (avail_ram_pages < 1)
|
||||
return MDBX_ENOSYS;
|
||||
return LOG_IFERR(MDBX_ENOSYS);
|
||||
}
|
||||
|
||||
return MDBX_SUCCESS;
|
||||
|
@ -154,13 +154,13 @@ __hot int mdbx_estimate_distance(const MDBX_cursor *first,
|
||||
ptrdiff_t *distance_items) {
|
||||
if (unlikely(first == nullptr || last == nullptr ||
|
||||
distance_items == nullptr))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
*distance_items = 0;
|
||||
diff_t dr;
|
||||
int rc = cursor_diff(last, first, &dr);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cASSERT(first, dr.diff || inner_pointed(first) == inner_pointed(last));
|
||||
if (unlikely(dr.diff == 0) && inner_pointed(first)) {
|
||||
@ -168,7 +168,7 @@ __hot int mdbx_estimate_distance(const MDBX_cursor *first,
|
||||
last = &last->subcur->cursor;
|
||||
rc = cursor_diff(first, last, &dr);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
if (likely(dr.diff != 0))
|
||||
@ -182,23 +182,24 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
|
||||
ptrdiff_t *distance_items) {
|
||||
if (unlikely(cursor == nullptr || distance_items == nullptr ||
|
||||
move_op == MDBX_GET_CURRENT || move_op == MDBX_GET_MULTIPLE))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(cursor->signature != cur_signature_live))
|
||||
return (cursor->signature == cur_signature_ready4dispose) ? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN;
|
||||
return LOG_IFERR((cursor->signature == cur_signature_ready4dispose)
|
||||
? MDBX_EINVAL
|
||||
: MDBX_EBADSIGN);
|
||||
|
||||
int rc = check_txn(cursor->txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!is_pointed(cursor)))
|
||||
return MDBX_ENODATA;
|
||||
return LOG_IFERR(MDBX_ENODATA);
|
||||
|
||||
cursor_couple_t next;
|
||||
rc = cursor_init(&next.outer, cursor->txn, cursor_dbi(cursor));
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
cursor_cpstk(cursor, &next.outer);
|
||||
if (cursor->tree->flags & MDBX_DUPSORT) {
|
||||
@ -211,7 +212,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
|
||||
const unsigned mask =
|
||||
1 << MDBX_GET_BOTH | 1 << MDBX_GET_BOTH_RANGE | 1 << MDBX_SET_KEY;
|
||||
if (unlikely(mask & (1 << move_op)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
stub_data.iov_base = nullptr;
|
||||
stub_data.iov_len = 0;
|
||||
data = &stub_data;
|
||||
@ -223,7 +224,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
|
||||
1 << MDBX_SET_KEY | 1 << MDBX_SET |
|
||||
1 << MDBX_SET_RANGE;
|
||||
if (unlikely(mask & (1 << move_op)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
stub_key.iov_base = nullptr;
|
||||
stub_key.iov_len = 0;
|
||||
key = &stub_key;
|
||||
@ -233,7 +234,7 @@ __hot int mdbx_estimate_move(const MDBX_cursor *cursor, MDBX_val *key,
|
||||
rc = cursor_ops(&next.outer, key, data, move_op);
|
||||
if (unlikely(rc != MDBX_SUCCESS &&
|
||||
(rc != MDBX_NOTFOUND || !is_pointed(&next.outer))))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (move_op == MDBX_LAST) {
|
||||
next.outer.flags |= z_eof_hard;
|
||||
@ -249,26 +250,26 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
ptrdiff_t *size_items) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(!size_items))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(begin_data &&
|
||||
(begin_key == nullptr || begin_key == MDBX_EPSILON)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(end_data && (end_key == nullptr || end_key == MDBX_EPSILON)))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
if (unlikely(begin_key == MDBX_EPSILON && end_key == MDBX_EPSILON))
|
||||
return MDBX_EINVAL;
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
|
||||
cursor_couple_t begin;
|
||||
/* LY: first, initialize cursor to refresh a DB in case it have DB_STALE */
|
||||
rc = cursor_init(&begin.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
if (unlikely(begin.outer.tree->items == 0)) {
|
||||
*size_items = 0;
|
||||
@ -284,18 +285,20 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
rc = outer_first(&begin.outer, nullptr, nullptr);
|
||||
if (unlikely(end_key == MDBX_EPSILON)) {
|
||||
/* LY: FIRST..+epsilon case */
|
||||
return (rc == MDBX_SUCCESS)
|
||||
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
|
||||
: rc;
|
||||
return LOG_IFERR(
|
||||
(rc == MDBX_SUCCESS)
|
||||
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
|
||||
: rc);
|
||||
}
|
||||
} else {
|
||||
if (unlikely(begin_key == MDBX_EPSILON)) {
|
||||
if (end_key == nullptr) {
|
||||
/* LY: -epsilon..LAST case */
|
||||
rc = outer_last(&begin.outer, nullptr, nullptr);
|
||||
return (rc == MDBX_SUCCESS)
|
||||
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
|
||||
: rc;
|
||||
return LOG_IFERR(
|
||||
(rc == MDBX_SUCCESS)
|
||||
? mdbx_cursor_count(&begin.outer, (size_t *)size_items)
|
||||
: rc);
|
||||
}
|
||||
/* LY: -epsilon..value case */
|
||||
assert(end_key != MDBX_EPSILON);
|
||||
@ -313,7 +316,7 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
.err;
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
*size_items = 0;
|
||||
return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
|
||||
return LOG_IFERR((rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc);
|
||||
}
|
||||
*size_items = 1;
|
||||
if (inner_pointed(&begin.outer))
|
||||
@ -329,21 +332,21 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
MDBX_val proxy_data = {nullptr, 0};
|
||||
if (begin_data)
|
||||
proxy_data = *begin_data;
|
||||
rc = cursor_seek(&begin.outer, &proxy_key, &proxy_data,
|
||||
MDBX_SET_LOWERBOUND)
|
||||
.err;
|
||||
rc = LOG_IFERR(cursor_seek(&begin.outer, &proxy_key, &proxy_data,
|
||||
MDBX_SET_LOWERBOUND)
|
||||
.err);
|
||||
}
|
||||
}
|
||||
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
if (rc != MDBX_NOTFOUND || !is_pointed(&begin.outer))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
cursor_couple_t end;
|
||||
rc = cursor_init(&end.outer, txn, dbi);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
if (!end_key) {
|
||||
rc = outer_last(&end.outer, nullptr, nullptr);
|
||||
end.outer.flags |= z_eof_hard;
|
||||
@ -358,12 +361,12 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi,
|
||||
}
|
||||
if (unlikely(rc != MDBX_SUCCESS)) {
|
||||
if (rc != MDBX_NOTFOUND || !is_pointed(&end.outer))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
rc = mdbx_estimate_distance(&begin.outer, &end.outer, size_items);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return rc;
|
||||
return LOG_IFERR(rc);
|
||||
assert(*size_items >= -(ptrdiff_t)begin.outer.tree->items &&
|
||||
*size_items <= (ptrdiff_t)begin.outer.tree->items);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user