mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-19 21:08:20 +08:00
mdbx: использование MDBX_GET_BOTH
для проверки наличия добавляемого значения в таблице.
This commit is contained in:
parent
84e2c70b98
commit
a994a9bbcc
52
src/cursor.c
52
src/cursor.c
@ -775,8 +775,9 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig
|
|||||||
rc = MDBX_NO_ROOT;
|
rc = MDBX_NO_ROOT;
|
||||||
} else if ((flags & MDBX_CURRENT) == 0) {
|
} else if ((flags & MDBX_CURRENT) == 0) {
|
||||||
bool exact = false;
|
bool exact = false;
|
||||||
MDBX_val last_key, old_data;
|
MDBX_val old_data;
|
||||||
if ((flags & MDBX_APPEND) && mc->tree->items > 0) {
|
if ((flags & MDBX_APPEND) && mc->tree->items > 0) {
|
||||||
|
MDBX_val last_key;
|
||||||
old_data.iov_base = nullptr;
|
old_data.iov_base = nullptr;
|
||||||
old_data.iov_len = 0;
|
old_data.iov_len = 0;
|
||||||
rc = (mc->flags & z_inner) ? inner_last(mc, &last_key) : outer_last(mc, &last_key, &old_data);
|
rc = (mc->flags & z_inner) ? inner_last(mc, &last_key) : outer_last(mc, &last_key, &old_data);
|
||||||
@ -794,52 +795,54 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
csr_t csr =
|
csr_t csr = cursor_seek(mc, (MDBX_val *)key, &old_data, MDBX_SET);
|
||||||
/* olddata may not be updated in case DUPFIX-page of dupfix-table */
|
|
||||||
cursor_seek(mc, (MDBX_val *)key, &old_data, MDBX_SET);
|
|
||||||
rc = csr.err;
|
rc = csr.err;
|
||||||
exact = csr.exact;
|
exact = csr.exact;
|
||||||
}
|
}
|
||||||
if (likely(rc == MDBX_SUCCESS)) {
|
|
||||||
if (exact) {
|
if (exact) {
|
||||||
|
cASSERT(mc, rc == MDBX_SUCCESS);
|
||||||
if (unlikely(flags & MDBX_NOOVERWRITE)) {
|
if (unlikely(flags & MDBX_NOOVERWRITE)) {
|
||||||
DEBUG("duplicate key [%s]", DKEY_DEBUG(key));
|
DEBUG("duplicate key [%s]", DKEY_DEBUG(key));
|
||||||
*data = old_data;
|
*data = old_data;
|
||||||
return MDBX_KEYEXIST;
|
return MDBX_KEYEXIST;
|
||||||
}
|
}
|
||||||
if (unlikely(mc->flags & z_inner)) {
|
if (unlikely(mc->flags & z_inner)) {
|
||||||
/* nested subtree of DUPSORT-database with the same key,
|
/* nested subtree of DUPSORT-database with the same key, nothing to update */
|
||||||
* nothing to update */
|
cASSERT(mc, !"Should not happen since");
|
||||||
eASSERT(env, data->iov_len == 0 && (old_data.iov_len == 0 ||
|
return (flags & MDBX_NODUPDATA) ? MDBX_KEYEXIST : MDBX_SUCCESS;
|
||||||
/* olddata may not be updated in case
|
|
||||||
DUPFIX-page of dupfix-table */
|
|
||||||
(mc->tree->flags & MDBX_DUPFIXED)));
|
|
||||||
return MDBX_SUCCESS;
|
|
||||||
}
|
}
|
||||||
if (unlikely(flags & MDBX_ALLDUPS) && inner_pointed(mc)) {
|
if (inner_pointed(mc)) {
|
||||||
err = cursor_del(mc, MDBX_ALLDUPS);
|
if (unlikely(flags & MDBX_ALLDUPS)) {
|
||||||
if (unlikely(err != MDBX_SUCCESS))
|
rc = cursor_del(mc, MDBX_ALLDUPS);
|
||||||
return err;
|
if (unlikely(rc != MDBX_SUCCESS))
|
||||||
|
return rc;
|
||||||
flags -= MDBX_ALLDUPS;
|
flags -= MDBX_ALLDUPS;
|
||||||
cASSERT(mc, mc->top + 1 == mc->tree->height);
|
cASSERT(mc, mc->top + 1 == mc->tree->height);
|
||||||
rc = (mc->top >= 0) ? MDBX_NOTFOUND : MDBX_NO_ROOT;
|
rc = (mc->top >= 0) ? MDBX_NOTFOUND : MDBX_NO_ROOT;
|
||||||
exact = false;
|
} else if ((flags & (MDBX_RESERVE | MDBX_MULTIPLE)) == 0) {
|
||||||
} else if (!(flags & (MDBX_RESERVE | MDBX_MULTIPLE))) {
|
old_data = *data;
|
||||||
/* checking for early exit without dirtying pages */
|
csr_t csr = cursor_seek(&mc->subcur->cursor, &old_data, nullptr, MDBX_SET_RANGE);
|
||||||
if (unlikely(eq_fast(data, &old_data))) {
|
if (unlikely(csr.exact)) {
|
||||||
cASSERT(mc, mc->clc->v.cmp(data, &old_data) == 0);
|
cASSERT(mc, csr.err == MDBX_SUCCESS);
|
||||||
if (mc->subcur) {
|
|
||||||
if (flags & MDBX_NODUPDATA)
|
if (flags & MDBX_NODUPDATA)
|
||||||
return MDBX_KEYEXIST;
|
return MDBX_KEYEXIST;
|
||||||
if (flags & MDBX_APPENDDUP)
|
if (flags & MDBX_APPENDDUP)
|
||||||
return MDBX_EKEYMISMATCH;
|
return MDBX_EKEYMISMATCH;
|
||||||
}
|
|
||||||
/* the same data, nothing to update */
|
/* the same data, nothing to update */
|
||||||
return MDBX_SUCCESS;
|
return MDBX_SUCCESS;
|
||||||
|
} else if (csr.err != MDBX_SUCCESS && unlikely(csr.err != MDBX_NOTFOUND)) {
|
||||||
|
be_poor(mc);
|
||||||
|
return csr.err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if ((flags & MDBX_RESERVE) == 0) {
|
||||||
|
if (unlikely(eq_fast(data, &old_data))) {
|
||||||
|
cASSERT(mc, mc->clc->v.cmp(data, &old_data) == 0);
|
||||||
|
/* the same data, nothing to update */
|
||||||
|
return (mc->subcur && (flags & MDBX_NODUPDATA)) ? MDBX_KEYEXIST : MDBX_SUCCESS;
|
||||||
}
|
}
|
||||||
cASSERT(mc, mc->clc->v.cmp(data, &old_data) != 0);
|
cASSERT(mc, mc->clc->v.cmp(data, &old_data) != 0);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
} else if (unlikely(rc != MDBX_NOTFOUND))
|
} else if (unlikely(rc != MDBX_NOTFOUND))
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
@ -1042,6 +1045,7 @@ __hot int cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsig
|
|||||||
return MDBX_EKEYMISMATCH;
|
return MDBX_EKEYMISMATCH;
|
||||||
} else if (eq_fast(data, &old_data)) {
|
} else if (eq_fast(data, &old_data)) {
|
||||||
cASSERT(mc, mc->clc->v.cmp(data, &old_data) == 0);
|
cASSERT(mc, mc->clc->v.cmp(data, &old_data) == 0);
|
||||||
|
cASSERT(mc, !"Should not happen since" || batch_dupfix_done);
|
||||||
if (flags & MDBX_NODUPDATA)
|
if (flags & MDBX_NODUPDATA)
|
||||||
return MDBX_KEYEXIST;
|
return MDBX_KEYEXIST;
|
||||||
/* data is match exactly byte-to-byte, nothing to update */
|
/* data is match exactly byte-to-byte, nothing to update */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user