mirror of
https://github.com/isar/libmdbx.git
synced 2025-11-06 19:08:56 +08:00
141 lines
4.3 KiB
C++
141 lines
4.3 KiB
C++
#include "mdbx.h++"
|
|
|
|
#include <chrono>
|
|
#include <deque>
|
|
#include <iostream>
|
|
#include <vector>
|
|
#if defined(__cpp_lib_latch) && __cpp_lib_latch >= 201907L
|
|
#include <latch>
|
|
#include <thread>
|
|
#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;
|
|
}
|
|
}
|