From f7cfa21d70552a321d82b392e75222099ee17329 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Thu, 6 Nov 2025 10:35:23 +0300 Subject: [PATCH] mdbx-test: initial/incomplete/draft test for `get-cached` feature. --- test/CMakeLists.txt | 1 + test/extra/get_cached.c++ | 140 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 141 insertions(+) create mode 100644 test/extra/get_cached.c++ diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt index df9c7281..7e9bf673 100644 --- a/test/CMakeLists.txt +++ b/test/CMakeLists.txt @@ -292,6 +292,7 @@ else() add_extra_test(dbi) add_extra_test(open) add_extra_test(txn) + add_extra_test(get_cached) endif() add_extra_test(hex_base64_base58) endif() diff --git a/test/extra/get_cached.c++ b/test/extra/get_cached.c++ new file mode 100644 index 00000000..5ec001e2 --- /dev/null +++ b/test/extra/get_cached.c++ @@ -0,0 +1,140 @@ +#include "mdbx.h++" + +#include +#include +#include +#include +#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L +#include +#include +#endif + +#if defined(ENABLE_MEMCHECK) || defined(MDBX_CI) +#if MDBX_DEBUG || !defined(NDEBUG) +#define RELIEF_FACTOR 16 +#else +#define RELIEF_FACTOR 8 +#endif +#elif MDBX_DEBUG || !defined(NDEBUG) || defined(__APPLE__) || defined(_WIN32) +#define RELIEF_FACTOR 4 +#elif UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul +#define RELIEF_FACTOR 2 +#else +#define RELIEF_FACTOR 1 +#endif + +// static const auto NN = 1000u / RELIEF_FACTOR; + +#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L +static const auto N = std::min(17u, std::thread::hardware_concurrency()); +#else +static const auto N = 3u; +#endif + +static void logger_nofmt(MDBX_log_level_t loglevel, const char *function, int line, const char *msg, + unsigned length) noexcept { + (void)length; + (void)loglevel; + fflush(nullptr); + std::cout << function << ":" << line << " " << msg; + std::cout.flush(); +} + +static char log_buffer[1024]; + +//-------------------------------------------------------------------------------------------- + +typedef MDBX_cache_result_t (*get_cached_t)(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, + MDBX_cache_entry *entry); + +static bool check_state(const MDBX_cache_result_t &r, const MDBX_error_t wanna_errcode, + const MDBX_cache_status_t wanna_status, unsigned line) { + if (r.errcode == wanna_errcode && r.status == wanna_status) + return true; + std::cerr << "unecpected (at " << line + << "): " + "err " + << r.errcode << " (wanna " << wanna_errcode + << "), " + "status " + << r.status << " (wanna " << wanna_status << ")" << std::endl; + return false; +} + +bool case0(mdbx::env env) { + get_cached_t get_cached = mdbx_cache_get_SingleThreaded; + auto txn = env.start_write(); + auto table = txn.create_map("case0", mdbx::key_mode::usual, mdbx::value_mode::single); + + MDBX_val data; + MDBX_cache_entry entry; + MDBX_cache_result_t r; + + bool ok = true; + mdbx_cache_init(&entry); + r = get_cached(txn, table, mdbx::slice("key"), &data, &entry); + ok = check_state(r, MDBX_NOTFOUND, MDBX_CACHE_DIRTY, __LINE__) && ok; + + txn.commit_embark_read(); + r = get_cached(txn, table, mdbx::slice("key"), &data, &entry); + ok = check_state(r, MDBX_NOTFOUND, MDBX_CACHE_REFRESHED, __LINE__) && ok; + + { + auto params = mdbx::env::operate_parameters(42); + params.options.no_sticky_threads = true; + mdbx::env_managed env2(env.get_path(), params); + auto txn2 = env2.start_write(); + txn2.drop_map("case0"); + txn2.commit(); + } + txn.renew_reading(); + r = get_cached(txn, table, mdbx::slice("key"), &data, &entry); + ok = check_state(r, MDBX_NOTFOUND, MDBX_CACHE_CONFIRMED, __LINE__) && ok; + + txn.abort(); + txn = env.start_write(); + table = txn.create_map("case0", mdbx::key_mode::usual, mdbx::value_mode::single); + r = get_cached(txn, table, mdbx::slice("key"), &data, &entry); + ok = check_state(r, MDBX_NOTFOUND, MDBX_CACHE_DIRTY, __LINE__) && ok; + + txn.commit_embark_read(); + r = get_cached(txn, table, mdbx::slice("key"), &data, &entry); + ok = check_state(r, MDBX_NOTFOUND, MDBX_CACHE_CONFIRMED, __LINE__) && ok; + + return ok; +} + +//-------------------------------------------------------------------------------------------- + +int doit() { + mdbx::path db_filename = "test-get-cached"; + mdbx::env::remove(db_filename); + + mdbx::env_managed env(db_filename, mdbx::env_managed::create_parameters(), + mdbx::env::operate_parameters(N + 2, 0, mdbx::env::nested_transactions)); + + bool ok = case0(env); + // ok = case1(env) && ok; + // ok = case2(env) && ok; + + if (ok) { + std::cout << "OK\n"; + return EXIT_SUCCESS; + } else { + std::cout << "FAIL!\n"; + return EXIT_FAILURE; + } +} + +int main(int argc, char *argv[]) { + (void)argc; + (void)argv; + mdbx_setup_debug_nofmt(MDBX_LOG_NOTICE, MDBX_DBG_ASSERT | MDBX_DBG_LEGACY_MULTIOPEN, logger_nofmt, log_buffer, + sizeof(log_buffer)); + try { + return doit(); + } catch (const std::exception &ex) { + std::cerr << "Exception: " << ex.what() << "\n"; + return EXIT_FAILURE; + } +}