mdbx-test: чуть более разумное/удобное поведение при коллизии генерации не-уникальных пар ключ-значение.

This commit is contained in:
Леонид Юрьев (Leonid Yuriev) 2024-03-02 01:11:24 +03:00
parent e29cb076d3
commit d8db63a67d
2 changed files with 37 additions and 23 deletions

View File

@ -599,9 +599,9 @@ void testcase::db_table_drop(MDBX_dbi handle) {
void testcase::db_table_clear(MDBX_dbi handle, MDBX_txn *txn) { void testcase::db_table_clear(MDBX_dbi handle, MDBX_txn *txn) {
log_trace(">> testcase::db_table_clear, handle %u", handle); log_trace(">> testcase::db_table_clear, handle %u", handle);
int rc = mdbx_drop(txn ? txn : txn_guard.get(), handle, false); int err = mdbx_drop(txn ? txn : txn_guard.get(), handle, false);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
failure_perror("mdbx_drop(delete=false)", rc); failure_perror("mdbx_drop(delete=false)", err);
speculum.clear(); speculum.clear();
log_trace("<< testcase::db_table_clear"); log_trace("<< testcase::db_table_clear");
} }
@ -609,21 +609,25 @@ void testcase::db_table_clear(MDBX_dbi handle, MDBX_txn *txn) {
void testcase::db_table_close(MDBX_dbi handle) { void testcase::db_table_close(MDBX_dbi handle) {
log_trace(">> testcase::db_table_close, handle %u", handle); log_trace(">> testcase::db_table_close, handle %u", handle);
assert(!txn_guard); assert(!txn_guard);
int rc = mdbx_dbi_close(db_guard.get(), handle); int err = mdbx_dbi_close(db_guard.get(), handle);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS))
failure_perror("mdbx_dbi_close()", rc); failure_perror("mdbx_dbi_close()", err);
log_trace("<< testcase::db_table_close"); log_trace("<< testcase::db_table_close");
} }
void testcase::checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check, bool testcase::checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check,
MDBX_val expected_valued) { MDBX_val expected_valued) {
MDBX_val actual_value = expected_valued; MDBX_val actual_value = expected_valued;
int rc = mdbx_get_equal_or_great(txn_guard.get(), handle, &key2check, int err = mdbx_get_equal_or_great(txn_guard.get(), handle, &key2check,
&actual_value); &actual_value);
if (unlikely(rc != MDBX_SUCCESS)) if (unlikely(err != MDBX_SUCCESS)) {
failure_perror(step, rc); if (!config.params.speculum || err != MDBX_RESULT_TRUE)
failure_perror(step, (err == MDBX_RESULT_TRUE) ? MDBX_NOTFOUND : err);
return false;
}
if (!is_samedata(&actual_value, &expected_valued)) if (!is_samedata(&actual_value, &expected_valued))
failure("%s data mismatch", step); failure("%s data mismatch", step);
return true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -988,7 +992,9 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
} }
auto it_lowerbound = insertion_result.first; auto it_lowerbound = insertion_result.first;
if (++it_lowerbound != speculum.end()) { if (insertion_result.second)
++it_lowerbound;
if (it_lowerbound != speculum.end()) {
const auto cursor_lowerbound = speculum_cursors[lowerbound].get(); const auto cursor_lowerbound = speculum_cursors[lowerbound].get();
speculum_check_cursor("after-insert", "lowerbound", it_lowerbound, speculum_check_cursor("after-insert", "lowerbound", it_lowerbound,
cursor_lowerbound, MDBX_GET_CURRENT); cursor_lowerbound, MDBX_GET_CURRENT);
@ -1015,30 +1021,37 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
int testcase::replace(const keygen::buffer &akey, int testcase::replace(const keygen::buffer &akey,
const keygen::buffer &new_data, const keygen::buffer &new_data,
const keygen::buffer &old_data, MDBX_put_flags_t flags) { const keygen::buffer &old_data, MDBX_put_flags_t flags,
bool hush_keygen_mistakes) {
int expected_err = MDBX_SUCCESS;
if (config.params.speculum) { if (config.params.speculum) {
const auto S_key = iov2dataview(akey); const auto S_key = iov2dataview(akey);
const auto S_old = iov2dataview(old_data); const auto S_old = iov2dataview(old_data);
const auto S_new = iov2dataview(new_data); const auto S_new = iov2dataview(new_data);
const auto removed = speculum.erase(SET::key_type(S_key, S_old)); const auto removed = speculum.erase(SET::key_type(S_key, S_old));
if (unlikely(removed != 1)) { if (unlikely(!removed)) {
char dump_key[128], dump_value[128]; char dump_key[128], dump_value[128];
log_error( log_error(
"speculum-%s: %s old value {%s, %s}", "replace", "speculum-%s: no old pair {%s, %s} (keygen mistake)", "replace",
(removed > 1) ? "multi" : "no",
mdbx_dump_val(&akey->value, dump_key, sizeof(dump_key)), mdbx_dump_val(&akey->value, dump_key, sizeof(dump_key)),
mdbx_dump_val(&old_data->value, dump_value, sizeof(dump_value))); mdbx_dump_val(&old_data->value, dump_value, sizeof(dump_value)));
} expected_err = MDBX_NOTFOUND;
if (unlikely(!speculum.emplace(S_key, S_new).second)) { } else if (unlikely(!speculum.emplace(S_key, S_new).second)) {
char dump_key[128], dump_value[128]; char dump_key[128], dump_value[128];
log_error( log_error(
"speculum-replace: new pair not inserted {%s, %s}", "speculum-%s: %s {%s, %s}", "replace", "new pair not inserted",
mdbx_dump_val(&akey->value, dump_key, sizeof(dump_key)), mdbx_dump_val(&akey->value, dump_key, sizeof(dump_key)),
mdbx_dump_val(&new_data->value, dump_value, sizeof(dump_value))); mdbx_dump_val(&new_data->value, dump_value, sizeof(dump_value)));
expected_err = MDBX_KEYEXIST;
} }
} }
return mdbx_replace(txn_guard.get(), dbi, &akey->value, &new_data->value, int err = mdbx_replace(txn_guard.get(), dbi, &akey->value, &new_data->value,
&old_data->value, flags); &old_data->value, flags);
if (err && err == expected_err && hush_keygen_mistakes) {
log_notice("speculum-%s: %s %d", "replace", "hust keygen mistake", err);
err = MDBX_SUCCESS;
}
return err;
} }
int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) { int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) {

View File

@ -232,7 +232,8 @@ protected:
int insert(const keygen::buffer &akey, const keygen::buffer &adata, int insert(const keygen::buffer &akey, const keygen::buffer &adata,
MDBX_put_flags_t flags); MDBX_put_flags_t flags);
int replace(const keygen::buffer &akey, const keygen::buffer &new_value, int replace(const keygen::buffer &akey, const keygen::buffer &new_value,
const keygen::buffer &old_value, MDBX_put_flags_t flags); const keygen::buffer &old_value, MDBX_put_flags_t flags,
bool hush_keygen_mistakes = true);
int remove(const keygen::buffer &akey, const keygen::buffer &adata); int remove(const keygen::buffer &akey, const keygen::buffer &adata);
static int hsr_callback(const MDBX_env *env, const MDBX_txn *txn, static int hsr_callback(const MDBX_env *env, const MDBX_txn *txn,
@ -262,7 +263,7 @@ protected:
void txn_inject_writefault(MDBX_txn *txn); void txn_inject_writefault(MDBX_txn *txn);
void fetch_canary(); void fetch_canary();
void update_canary(uint64_t increment); void update_canary(uint64_t increment);
void checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check, bool checkdata(const char *step, MDBX_dbi handle, MDBX_val key2check,
MDBX_val expected_valued); MDBX_val expected_valued);
unsigned txn_underutilization_x256(MDBX_txn *txn) const; unsigned txn_underutilization_x256(MDBX_txn *txn) const;