mirror of
https://github.com/isar/libmdbx.git
synced 2025-02-19 12:58:13 +08:00
mdbx-testing: вывод "табло" с информацией о положении курсоров для удобства отладки.
This commit is contained in:
parent
a10506fb6a
commit
9670cf5709
150
test/test.c++
150
test/test.c++
@ -728,22 +728,26 @@ void testcase::verbose(const char *where, const char *stage, const MDBX_val &k,
|
||||
|
||||
bool testcase::speculum_check_iterator(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it,
|
||||
const MDBX_val &k,
|
||||
const MDBX_val &v) const {
|
||||
const MDBX_val &k, const MDBX_val &v,
|
||||
MDBX_cursor *cursor) const {
|
||||
char dump_key[32], dump_value[32];
|
||||
MDBX_val it_key = dataview2iov(it->first);
|
||||
MDBX_val it_data = dataview2iov(it->second);
|
||||
// log_verbose("speculum-%s: %s expect {%s, %s}", where, stage,
|
||||
// mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||
// mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
||||
if (!is_samedata(it_key, k))
|
||||
if (!is_samedata(it_key, k)) {
|
||||
speculum_render(it, cursor);
|
||||
return failure("speculum-%s: %s key mismatch %s (must) != %s", where, stage,
|
||||
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&k, dump_value, sizeof(dump_value)));
|
||||
if (!is_samedata(it_data, v))
|
||||
}
|
||||
if (!is_samedata(it_data, v)) {
|
||||
speculum_render(it, cursor);
|
||||
return failure("speculum-%s: %s data mismatch %s (must) != %s", where,
|
||||
stage, mdbx_dump_val(&it_data, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&v, dump_value, sizeof(dump_value)));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -761,32 +765,139 @@ bool testcase::failure(const char *fmt, ...) const {
|
||||
}
|
||||
|
||||
#if SPECULUM_CURSORS
|
||||
|
||||
static void speculum_render_cursor(const MDBX_val &ikey, const MDBX_val &ival,
|
||||
const MDBX_cursor *cursor,
|
||||
const MDBX_cursor *ref) {
|
||||
scoped_cursor_guard guard(mdbx_cursor_create(nullptr));
|
||||
if (!guard)
|
||||
failure("mdbx_cursor_create()");
|
||||
/* работаем с копией курсора, чтобы не влиять на состояние оригинала. */
|
||||
int err = mdbx_cursor_copy(cursor, guard.get());
|
||||
if (err)
|
||||
failure("mdbx_cursor_copy(), err %d", err);
|
||||
|
||||
MDBX_cursor *const clone = guard.get();
|
||||
char status[10], *s = status;
|
||||
if (cursor == ref) {
|
||||
*s++ = '_';
|
||||
*s++ = '_';
|
||||
}
|
||||
|
||||
if (mdbx_cursor_eof(clone) == MDBX_RESULT_TRUE)
|
||||
*s++ = 'e';
|
||||
if (mdbx_cursor_on_first(clone) == MDBX_RESULT_TRUE)
|
||||
*s++ = 'F';
|
||||
if (mdbx_cursor_on_first_dup(clone) == MDBX_RESULT_TRUE)
|
||||
*s++ = 'f';
|
||||
if (mdbx_cursor_on_last(clone) == MDBX_RESULT_TRUE)
|
||||
*s++ = 'L';
|
||||
if (mdbx_cursor_on_last_dup(clone) == MDBX_RESULT_TRUE)
|
||||
*s++ = 'l';
|
||||
|
||||
MDBX_val ckey, cval;
|
||||
if (mdbx_cursor_get(clone, &ckey, &cval, MDBX_GET_CURRENT) != MDBX_SUCCESS)
|
||||
*s++ = '!';
|
||||
else {
|
||||
const int kcmp =
|
||||
mdbx_cmp(mdbx_cursor_txn(clone), mdbx_cursor_dbi(clone), &ikey, &ckey);
|
||||
if (kcmp < 0)
|
||||
*s++ = '<';
|
||||
else if (kcmp > 0)
|
||||
*s++ = '>';
|
||||
else {
|
||||
*s++ = '=';
|
||||
const int vcmp = mdbx_dcmp(mdbx_cursor_txn(clone), mdbx_cursor_dbi(clone),
|
||||
&ival, &cval);
|
||||
if (vcmp < 0)
|
||||
*s++ = '<';
|
||||
else if (vcmp > 0)
|
||||
*s++ = '>';
|
||||
else
|
||||
*s++ = '=';
|
||||
}
|
||||
}
|
||||
|
||||
if (clone == ref) {
|
||||
*s++ = '_';
|
||||
*s++ = '_';
|
||||
}
|
||||
*s = '\0';
|
||||
|
||||
printf(" | %-10.10s", status);
|
||||
}
|
||||
|
||||
void testcase::speculum_render(const testcase::SET::const_iterator &it,
|
||||
const MDBX_cursor *ref) const {
|
||||
char dump_key[32], dump_value[32];
|
||||
|
||||
auto top = it;
|
||||
int offset = 0;
|
||||
while (offset > -5 && top != speculum.begin()) {
|
||||
--top;
|
||||
--offset;
|
||||
}
|
||||
printf("## %-20.20s %-20.20s | %-10.10s | %-10.10s | %-10.10s | %-10.10s | "
|
||||
"%-10.10s | %-10.10s |\n",
|
||||
"k0_1_2_3_4_5_6_7_8_9", "v0_1_2_3_4_5_6_7_8_9", "prev-prev", "prev",
|
||||
"seek", "lowerbound", "next", "next-next");
|
||||
while (offset < 5 && top != speculum.end()) {
|
||||
const MDBX_val ikey = dataview2iov(top->first);
|
||||
const MDBX_val idata = dataview2iov(top->second);
|
||||
printf("%+d) %20.20s %20.20s", offset,
|
||||
mdbx_dump_val(&ikey, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&idata, dump_value, sizeof(dump_value)));
|
||||
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[prev_prev].get(), ref);
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[prev].get(), ref);
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[seek_check].get(),
|
||||
ref);
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[lowerbound].get(),
|
||||
ref);
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[next].get(), ref);
|
||||
speculum_render_cursor(ikey, idata, speculum_cursors[next_next].get(), ref);
|
||||
|
||||
printf(" %s\n", "|");
|
||||
++top;
|
||||
++offset;
|
||||
}
|
||||
}
|
||||
|
||||
bool testcase::speculum_check_cursor(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it,
|
||||
int cursor_err, const MDBX_val &cursor_key,
|
||||
const MDBX_val &cursor_data) const {
|
||||
const MDBX_val &cursor_data,
|
||||
MDBX_cursor *cursor) const {
|
||||
// verbose(where, stage, cursor_key, cursor_data, cursor_err);
|
||||
// verbose(where, stage, it);
|
||||
if (cursor_err != MDBX_SUCCESS && cursor_err != MDBX_NOTFOUND &&
|
||||
cursor_err != MDBX_RESULT_TRUE && cursor_err != MDBX_ENODATA)
|
||||
cursor_err != MDBX_RESULT_TRUE && cursor_err != MDBX_ENODATA) {
|
||||
speculum_render(it, cursor);
|
||||
return failure("speculum-%s: %s %s %d %s", where, stage, "cursor-get",
|
||||
cursor_err, mdbx_strerror(cursor_err));
|
||||
}
|
||||
|
||||
char dump_key[32], dump_value[32];
|
||||
if (it == speculum.end() && cursor_err != MDBX_NOTFOUND)
|
||||
if (it == speculum.end() && cursor_err != MDBX_NOTFOUND &&
|
||||
cursor_err != MDBX_ENODATA) {
|
||||
speculum_render(it, cursor);
|
||||
return failure("speculum-%s: %s extra pair {%s, %s}", where, stage,
|
||||
mdbx_dump_val(&cursor_key, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&cursor_data, dump_value, sizeof(dump_value)));
|
||||
else if (it != speculum.end() && cursor_err == MDBX_NOTFOUND) {
|
||||
} else if (it != speculum.end() &&
|
||||
(cursor_err == MDBX_NOTFOUND || cursor_err == MDBX_ENODATA)) {
|
||||
speculum_render(it, cursor);
|
||||
MDBX_val it_key = dataview2iov(it->first);
|
||||
MDBX_val it_data = dataview2iov(it->second);
|
||||
return failure("speculum-%s: %s lack pair {%s, %s}", where, stage,
|
||||
mdbx_dump_val(&it_key, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&it_data, dump_value, sizeof(dump_value)));
|
||||
} else if (cursor_err == MDBX_SUCCESS || cursor_err == MDBX_RESULT_TRUE)
|
||||
return speculum_check_iterator(where, stage, it, cursor_key, cursor_data);
|
||||
return speculum_check_iterator(where, stage, it, cursor_key, cursor_data,
|
||||
cursor);
|
||||
else {
|
||||
assert(it == speculum.end() && cursor_err == MDBX_NOTFOUND);
|
||||
assert(it == speculum.end() &&
|
||||
(cursor_err == MDBX_NOTFOUND || cursor_err == MDBX_ENODATA));
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -798,7 +909,8 @@ bool testcase::speculum_check_cursor(const char *where, const char *stage,
|
||||
MDBX_val cursor_key = {0, 0};
|
||||
MDBX_val cursor_data = {0, 0};
|
||||
int err = mdbx_cursor_get(cursor, &cursor_key, &cursor_data, op);
|
||||
return speculum_check_cursor(where, stage, it, err, cursor_key, cursor_data);
|
||||
return speculum_check_cursor(where, stage, it, err, cursor_key, cursor_data,
|
||||
cursor);
|
||||
}
|
||||
|
||||
void testcase::speculum_prepare_cursors(const Item &item) {
|
||||
@ -822,6 +934,7 @@ void testcase::speculum_prepare_cursors(const Item &item) {
|
||||
guard.reset(cursor);
|
||||
}
|
||||
|
||||
// mdbx_cursor_reset(speculum_cursors[seek_check].get());
|
||||
const auto cursor_lowerbound = speculum_cursors[lowerbound].get();
|
||||
const MDBX_val item_key = dataview2iov(item.first),
|
||||
item_data = dataview2iov(item.second);
|
||||
@ -840,7 +953,7 @@ void testcase::speculum_prepare_cursors(const Item &item) {
|
||||
auto it_lowerbound = speculum.lower_bound(item);
|
||||
// verbose("prepare-cursors", "lowerbound", it_lowerbound);
|
||||
speculum_check_cursor("prepare-cursors", "lowerbound", it_lowerbound, err,
|
||||
lowerbound_key, lowerbound_data);
|
||||
lowerbound_key, lowerbound_data, cursor_lowerbound);
|
||||
|
||||
const auto cursor_prev = speculum_cursors[prev].get();
|
||||
err = mdbx_cursor_copy(cursor_lowerbound, cursor_prev);
|
||||
@ -916,6 +1029,7 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
||||
seek_check_data = adata->value;
|
||||
seek_check_err = mdbx_cursor_get(check_seek_cursor, &seek_check_key,
|
||||
&seek_check_data, MDBX_SET_LOWERBOUND);
|
||||
// speculum_render(speculum.find(item), check_seek_cursor);
|
||||
if (seek_check_err != MDBX_SUCCESS && seek_check_err != MDBX_NOTFOUND &&
|
||||
seek_check_err != MDBX_RESULT_TRUE)
|
||||
failure("speculum-%s: %s pre-insert %d %s", "insert", "seek",
|
||||
@ -959,7 +1073,8 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
||||
mdbx_dump_val(&seek_check_key, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&seek_check_data, dump_value, sizeof(dump_value)));
|
||||
speculum_check_iterator("insert", "pre-seek", insertion_result.first,
|
||||
seek_check_key, seek_check_data);
|
||||
seek_check_key, seek_check_data,
|
||||
check_seek_cursor);
|
||||
rc = false;
|
||||
}
|
||||
}
|
||||
@ -999,6 +1114,8 @@ int testcase::insert(const keygen::buffer &akey, const keygen::buffer &adata,
|
||||
}
|
||||
}
|
||||
}
|
||||
// speculum_render(insertion_result.first,
|
||||
// speculum_cursors[seek_check].get());
|
||||
#endif /* SPECULUM_CURSORS */
|
||||
}
|
||||
|
||||
@ -1049,6 +1166,12 @@ int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) {
|
||||
item.second = iov2dataview(adata);
|
||||
#if SPECULUM_CURSORS
|
||||
speculum_prepare_cursors(item);
|
||||
// MDBX_cursor *check_seek_cursor = speculum_cursors[seek_check].get();
|
||||
// MDBX_val seek_check_key = akey->value;
|
||||
// MDBX_val seek_check_data = adata->value;
|
||||
// mdbx_cursor_get(check_seek_cursor, &seek_check_key, &seek_check_data,
|
||||
// MDBX_SET_LOWERBOUND);
|
||||
// speculum_render(speculum.find(item), check_seek_cursor);
|
||||
#endif /* SPECULUM_CURSORS */
|
||||
}
|
||||
|
||||
@ -1075,6 +1198,7 @@ int testcase::remove(const keygen::buffer &akey, const keygen::buffer &adata) {
|
||||
}
|
||||
|
||||
#if SPECULUM_CURSORS
|
||||
speculum_render(it_found, speculum_cursors[seek_check].get());
|
||||
if (it_found != speculum.begin()) {
|
||||
const auto cursor_prev = speculum_cursors[prev].get();
|
||||
auto it_prev = it_found;
|
||||
|
@ -197,15 +197,19 @@ protected:
|
||||
bool speculum_check_cursor(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it,
|
||||
int cursor_err, const MDBX_val &cursor_key,
|
||||
const MDBX_val &cursor_data) const;
|
||||
const MDBX_val &cursor_data,
|
||||
MDBX_cursor *cursor) const;
|
||||
bool speculum_check_cursor(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it,
|
||||
MDBX_cursor *cursor,
|
||||
const MDBX_cursor_op op) const;
|
||||
void speculum_render(const testcase::SET::const_iterator &it,
|
||||
const MDBX_cursor *ref) const;
|
||||
#endif /* SPECULUM_CURSORS */
|
||||
bool speculum_check_iterator(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it,
|
||||
const MDBX_val &k, const MDBX_val &v) const;
|
||||
const MDBX_val &k, const MDBX_val &v,
|
||||
MDBX_cursor *cursor) const;
|
||||
|
||||
void verbose(const char *where, const char *stage,
|
||||
const testcase::SET::const_iterator &it) const;
|
||||
|
Loading…
x
Reference in New Issue
Block a user