mirror of
https://gitflic.ru/project/erthink/libmdbx.git
synced 2026-04-10 18:32:21 +00:00
mdbx: introduce the mdbx_txn_rollback() (v0.14.1-453-ga529b6d0).
2026-03-08 mdbx: update ChangeLog. 2026-03-08 mdbx: add `mdbx_txn_rollback()` with tests. 2026-03-08 mdbx-make: fix order of test-targets to avoid removing `src/version.c`. 2026-03-07 mdbx: add cost-cache for defrag internals.
This commit is contained in:
@@ -42,6 +42,7 @@ BTC `bc1qzvl9uegf2ea6cwlytnanrscyv8snwsvrc0xfsu`, SOL `FTCTgbHajoLVZGr8aEFWMzx3N
|
||||
- добавлена функция `mdbx_txn_checkpoint()` для фиксации пишущих транзакций без освобождения блокировок.
|
||||
- добавлена функция `mdbx_txn_commit_embark_read()` для фиксации пишущей транзакции и запуска читающей без вклинивания других изменений.
|
||||
- добавлена функция `mdbx_txn_amend()` для изменения данных начиная со снимка данных используемого в заданной транзакции чтения.
|
||||
- добавлена функция `mdbx_txn_rollback()` для прерывания и перезапуска транзакции с отменой всех изменений, но без освобождения блокировок.
|
||||
- добавлена поддержка клонирования читающих транзакций посредством `mdbx_txn_clone()`.
|
||||
- добавлена поддержка вложенных транзакций только для чтения.
|
||||
- добавлена функция `mdbx_gc_info()` для получения информации о GC, использовании страниц, с возможностью итерирования содержимого GC.
|
||||
|
||||
@@ -287,12 +287,14 @@ ctest: cmake-build
|
||||
run-ut: mdbx_example
|
||||
$(QUIET)for UT in $^; do echo " Running $$UT" && ./$${UT} || exit -1; done
|
||||
|
||||
TEST_TARGETS := mdbx_legacy_example $(call select_by,MDBX_BUILD_CXX,mdbx_modern_example,)
|
||||
TEST_BUILD_TARGETS := build-test
|
||||
TEST_TARGETS :=
|
||||
TEST_BUILD_TARGETS :=
|
||||
ifneq ($(CMAKE),"")
|
||||
TEST_TARGETS += ctest
|
||||
TEST_BUILD_TARGETS += cmake-build
|
||||
endif
|
||||
TEST_TARGETS += mdbx_legacy_example $(call select_by,MDBX_BUILD_CXX,mdbx_modern_example,)
|
||||
TEST_BUILD_TARGETS += build-test
|
||||
|
||||
.PHONY: ninja-assertions ninja-debug ninja $(TEST_TARGETS) $(TEST_BUILD_TARGETS) test-ubsan test-asan test-memcheck test-leak test-assertion test build-test smoke check
|
||||
test: $(TEST_TARGETS)
|
||||
|
||||
@@ -1 +1 @@
|
||||
{ "git_describe": "v0.14.1-449-ga2319c94", "git_timestamp": "2026-03-06T22:09:32+03:00", "git_tree": "722d2f848a0f79d9bec0116ca398f146b041f3ed", "git_commit": "a2319c949e5a2fc30ea7a36432dd7faeb248b94f", "semver": "0.14.1.449" }
|
||||
{ "git_describe": "v0.14.1-453-ga529b6d0", "git_timestamp": "2026-03-08T20:32:09+03:00", "git_tree": "1d75989481133843e97103dabd0f5dfa8d7481ac", "git_commit": "a529b6d02d5e628738207dc39331c9186d164f88", "semver": "0.14.1.453" }
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00),
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00),
|
||||
* it is the template for libmdbx's config.h
|
||||
******************************************************************************/
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
@@ -24,7 +24,7 @@
|
||||
|
||||
#define xMDBX_ALLOY 1 /* alloyed build */
|
||||
|
||||
#define MDBX_BUILD_SOURCERY c61e4bb68caf0e66edd5735e42142a872fab4e6ba53310c1dadad3a333300d72_v0_14_1_449_ga2319c94
|
||||
#define MDBX_BUILD_SOURCERY a21e2e56d1f7e0e3b639be630fc6ddc90c1352abb5e8900d3e2cb154bdba53d5_v0_14_1_453_ga529b6d0
|
||||
|
||||
#define LIBMDBX_INTERNALS
|
||||
#define MDBX_DEPRECATED
|
||||
|
||||
89
mdbx.c
89
mdbx.c
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
@@ -1463,6 +1463,7 @@ MDBX_INTERNAL int txn_nested_create(MDBX_txn *parent, bool readonly);
|
||||
MDBX_INTERNAL int txn_nested_abort(MDBX_txn *txn);
|
||||
MDBX_INTERNAL int txn_nested_commit(MDBX_txn *txn, struct commit_timestamp *ts);
|
||||
MDBX_INTERNAL int txn_nested_checkpoint(MDBX_txn *txn, struct commit_timestamp *ts);
|
||||
MDBX_INTERNAL int txn_nested_rollback(MDBX_txn *txn);
|
||||
MDBX_INTERNAL MDBX_txn *txn_nested_fakero_begin(MDBX_txn *parent);
|
||||
MDBX_INTERNAL int txn_nested_fakero_end(MDBX_txn *txn);
|
||||
|
||||
@@ -1473,6 +1474,7 @@ MDBX_INTERNAL int txn_basal_commit(MDBX_txn *txn, struct commit_timestamp *ts);
|
||||
MDBX_INTERNAL int txn_basal_end(MDBX_txn *txn, bool unlock);
|
||||
MDBX_INTERNAL int txn_basal_checkpoint(MDBX_txn *txn, MDBX_txn_flags_t weakening_durability,
|
||||
struct commit_timestamp *ts);
|
||||
MDBX_INTERNAL int txn_basal_rollback(MDBX_txn *txn);
|
||||
MDBX_INTERNAL int txn_basal_update_tbl_roots(MDBX_txn *txn);
|
||||
|
||||
MDBX_INTERNAL int txn_ro_park(MDBX_txn *txn, bool autounpark);
|
||||
@@ -3033,6 +3035,10 @@ typedef struct defract_context {
|
||||
|
||||
txnid_t stopor;
|
||||
struct gc_reclaiming_obstacle gc_obstacle;
|
||||
struct cache_item {
|
||||
pgno_t pgno;
|
||||
unsigned cost;
|
||||
} cache_cost[64];
|
||||
} dfc_t;
|
||||
|
||||
MDBX_INTERNAL int defrag_init(dfc_t *dfc, MDBX_txn *txn, size_t defrag_atleast_pages,
|
||||
@@ -11288,6 +11294,28 @@ bailout:
|
||||
return LOG_IFERR(rc);
|
||||
}
|
||||
|
||||
int mdbx_txn_rollback(MDBX_txn *txn) {
|
||||
int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_ERROR - MDBX_TXN_PARKED);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return LOG_IFERR(rc);
|
||||
|
||||
txn->flags |= /* avoid merge cursors' state */ MDBX_TXN_ERROR;
|
||||
if (txn->flags & txn_may_have_cursors)
|
||||
txn_done_cursors(txn);
|
||||
|
||||
if (likely(txn->flags & txn_ro_flat) == 0) {
|
||||
if (!txn->parent)
|
||||
return LOG_IFERR(txn_basal_rollback(txn));
|
||||
else
|
||||
return LOG_IFERR(txn_nested_rollback(txn));
|
||||
}
|
||||
|
||||
rc = txn_ro_reset(txn);
|
||||
if (unlikely(rc != MDBX_SUCCESS))
|
||||
return LOG_IFERR(rc);
|
||||
return LOG_IFERR(txn_ro_start(txn, false));
|
||||
}
|
||||
|
||||
int mdbx_txn_amend(MDBX_txn *rtxn, MDBX_txn **ptxn, MDBX_txn_flags_t flags, void *context) {
|
||||
if (unlikely(!ptxn))
|
||||
return LOG_IFERR(MDBX_EINVAL);
|
||||
@@ -16894,8 +16922,7 @@ int dbi_close_release(MDBX_env *env, MDBX_dbi dbi) { return dbi_defer_release(en
|
||||
|
||||
static uint64_t defrag_now(uint64_t now_cache) { return now_cache ? now_cache : osal_monotime(); }
|
||||
|
||||
uint64_t defrag_result(dfc_t *dfc, MDBX_defrag_result_t *out,
|
||||
uint64_t now_cache) {
|
||||
uint64_t defrag_result(dfc_t *dfc, MDBX_defrag_result_t *out, uint64_t now_cache) {
|
||||
memset(out, 0, sizeof(*out));
|
||||
if (dfc->txn)
|
||||
dfc->last_allocated = dfc->txn->geo.first_unallocated;
|
||||
@@ -17524,7 +17551,7 @@ bailout:
|
||||
return MDBX_RESULT_TRUE;
|
||||
}
|
||||
|
||||
__hot __noinline static unsigned defrag_move_cost(dfc_t *dfc, pgno_t pgno, pgno_t span) {
|
||||
__hot __noinline static unsigned defrag_move_cost_uncached(dfc_t *dfc, pgno_t pgno, pgno_t span) {
|
||||
if (pgno < NUM_METAS || pgno >= dfc->retreat_edge)
|
||||
return INT_MAX;
|
||||
|
||||
@@ -17551,6 +17578,14 @@ __hot __noinline static unsigned defrag_move_cost(dfc_t *dfc, pgno_t pgno, pgno_
|
||||
return cost;
|
||||
}
|
||||
|
||||
static inline unsigned defrag_move_cost(dfc_t *dfc, pgno_t pgno, pgno_t span) {
|
||||
struct cache_item *cache = &dfc->cache_cost[pgno % ARRAY_LENGTH(dfc->cache_cost)];
|
||||
if (cache->pgno == pgno)
|
||||
return cache->cost;
|
||||
cache->pgno = pgno;
|
||||
return cache->cost = defrag_move_cost_uncached(dfc, pgno, span);
|
||||
}
|
||||
|
||||
__hot static int defrag_provide_span(dfc_t *const dfc, const size_t npages) {
|
||||
assert(npages > 1);
|
||||
const pnl_t pnl = dfc->txn->wr.repnl;
|
||||
@@ -17559,6 +17594,7 @@ __hot static int defrag_provide_span(dfc_t *const dfc, const size_t npages) {
|
||||
if (len < npages)
|
||||
return MDBX_RESULT_TRUE;
|
||||
|
||||
memset(dfc->cache_cost, 0, sizeof(dfc->cache_cost));
|
||||
size_t best_begin = MAX_PAGENO, best_cost = len;
|
||||
#if MDBX_PNL_ASCENDING
|
||||
#error "FIXME"
|
||||
@@ -37500,6 +37536,16 @@ int txn_basal_checkpoint(MDBX_txn *txn, MDBX_txn_flags_t weakening_durability, s
|
||||
return (err == MDBX_SUCCESS) ? rc : err;
|
||||
}
|
||||
|
||||
int txn_basal_rollback(MDBX_txn *txn) {
|
||||
const unsigned preserved_flags = txn->flags & txn_rw_begin_flags;
|
||||
/* void *const preserved_context = txn->userctx; */
|
||||
int rc = txn_basal_end(txn, false);
|
||||
if (likely(rc == MDBX_SUCCESS))
|
||||
/* txn->userctx = preserved_context; */
|
||||
rc = txn_basal_start(txn, preserved_flags | txn_rw_already_locked);
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* Merge pageset of the nested transaction into parent */
|
||||
static void nested_merge(MDBX_txn *const parent, MDBX_txn *const nested, const size_t parent_retired_len) {
|
||||
tASSERT(nested, (nested->flags & MDBX_WRITEMAP) == 0);
|
||||
@@ -37958,6 +38004,7 @@ int txn_nested_create(MDBX_txn *parent, bool readonly) {
|
||||
|
||||
static int nested_undo(MDBX_txn *nested) {
|
||||
tASSERT(nested, !nested->nested && !(nested->flags & MDBX_TXN_HAS_CHILD));
|
||||
tASSERT(nested, rkl_empty(&nested->wr.gc.comeback));
|
||||
if (nested->flags & txn_may_have_cursors)
|
||||
txn_done_cursors(nested);
|
||||
if (nested->flags & MDBX_TXN_DIRTY)
|
||||
@@ -38039,6 +38086,7 @@ static int nested_join(MDBX_txn *nested, struct commit_timestamp *ts) {
|
||||
eASSERT(env, txn_dpl_check(nested));
|
||||
tASSERT(nested, pnl_check_allocated(nested->wr.repnl, nested->geo.first_unallocated - MDBX_ENABLE_REFUND));
|
||||
tASSERT(nested, memcmp(&nested->wr.troika, &parent->wr.troika, sizeof(troika_t)) == 0);
|
||||
tASSERT(nested, rkl_empty(&nested->wr.gc.comeback));
|
||||
|
||||
//-------------------------------------------------------------------------
|
||||
// Preserve space for page lists in the parent transaction.
|
||||
@@ -38158,7 +38206,7 @@ int txn_nested_commit(MDBX_txn *nested, struct commit_timestamp *ts) {
|
||||
int txn_nested_checkpoint(MDBX_txn *nested, struct commit_timestamp *ts) {
|
||||
MDBX_txn *parent = nested->parent;
|
||||
if (unlikely(!parent || parent->nested != nested || parent->env != nested->env)) {
|
||||
ERROR("attempt to commit %s txn %p", "strange nested", __Wpedantic_format_voidptr(nested));
|
||||
ERROR("attempt to %s %s txn %p", "commit", "strange nested", __Wpedantic_format_voidptr(nested));
|
||||
return MDBX_PROBLEM;
|
||||
}
|
||||
|
||||
@@ -38194,6 +38242,31 @@ int txn_nested_fakero_end(MDBX_txn *nested) {
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
int txn_nested_rollback(MDBX_txn *nested) {
|
||||
tASSERT(nested, nested->flags & txn_ro_nested);
|
||||
tASSERT(nested, rkl_empty(&nested->wr.gc.comeback));
|
||||
MDBX_txn *parent = nested->parent;
|
||||
if (unlikely(!parent || parent->nested != nested || parent->env != nested->env)) {
|
||||
ERROR("attempt to %s %s txn %p", "rollback", "strange nested", __Wpedantic_format_voidptr(nested));
|
||||
return MDBX_PROBLEM;
|
||||
}
|
||||
|
||||
if (unlikely(F_ISSET(nested->flags, txn_ro_nested | MDBX_TXN_DIRTY))) {
|
||||
ERROR("unable to %s %s txn %p", "rollback", "dirty nested fake-readonly", __Wpedantic_format_voidptr(nested));
|
||||
return MDBX_BAD_TXN;
|
||||
}
|
||||
|
||||
const unsigned preserved_flags = nested->flags & txn_ro_nested;
|
||||
int rc = nested_undo(nested);
|
||||
if (likely(rc == MDBX_SUCCESS))
|
||||
rc = nested_start(nested, parent);
|
||||
if (likely(rc == MDBX_SUCCESS))
|
||||
nested->flags |= preserved_flags;
|
||||
else
|
||||
txn_nested_abort(nested);
|
||||
return rc;
|
||||
}
|
||||
|
||||
static inline mdbx_pid_t ro_slot_pid(const reader_slot_t *slot) { return slot->pid.weak; }
|
||||
|
||||
static inline uint64_t ro_slot_tid(const reader_slot_t *slot) { return slot->tid.weak; }
|
||||
@@ -39668,10 +39741,10 @@ __dll_export
|
||||
0,
|
||||
14,
|
||||
1,
|
||||
449,
|
||||
453,
|
||||
"", /* pre-release suffix of SemVer
|
||||
0.14.1.449 */
|
||||
{"2026-03-06T22:09:32+03:00", "722d2f848a0f79d9bec0116ca398f146b041f3ed", "a2319c949e5a2fc30ea7a36432dd7faeb248b94f", "v0.14.1-449-ga2319c94"},
|
||||
0.14.1.453 */
|
||||
{"2026-03-08T20:32:09+03:00", "1d75989481133843e97103dabd0f5dfa8d7481ac", "a529b6d02d5e628738207dc39331c9186d164f88", "v0.14.1-453-ga529b6d0"},
|
||||
sourcery};
|
||||
|
||||
__dll_export
|
||||
|
||||
2
mdbx.c++
2
mdbx.c++
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
35
mdbx.h
35
mdbx.h
@@ -1,4 +1,4 @@
|
||||
/** This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/** This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
|
||||
\file mdbx.h
|
||||
\brief The libmdbx C API header file.
|
||||
@@ -4197,6 +4197,7 @@ typedef struct MDBX_commit_latency MDBX_commit_latency;
|
||||
* \see mdbx_txn_begin_ex()
|
||||
* \see mdbx_txn_abort()
|
||||
* \see mdbx_txn_abort_ex()
|
||||
* \see mdbx_txn_rollback()
|
||||
*
|
||||
* If the current thread is not eligible to manage the transaction then
|
||||
* the \ref MDBX_THREAD_MISMATCH error will returned. Otherwise the transaction
|
||||
@@ -4252,6 +4253,7 @@ LIBMDBX_API int mdbx_txn_commit_ex(MDBX_txn *txn, MDBX_commit_latency *latency);
|
||||
* \see mdbx_txn_commit_ex()
|
||||
* \see mdbx_txn_refresh()
|
||||
* \see mdbx_txn_begin()
|
||||
* \see mdbx_txn_rollback()
|
||||
*
|
||||
* \param [in, out] txn A transaction handle returned by \ref mdbx_txn_begin().
|
||||
* \param [in] weakening_durability Additional flags to weaken durability for committing changes.
|
||||
@@ -4331,6 +4333,7 @@ LIBMDBX_API int mdbx_txn_commit_embark_read(MDBX_txn **ptxn, MDBX_commit_latency
|
||||
*
|
||||
* \see mdbx_txn_commit_embark_read()
|
||||
* \see mdbx_txn_checkpoint()
|
||||
* \see mdbx_txn_rollback()
|
||||
* \see mdbx_txn_commit_ex()
|
||||
* \see mdbx_txn_refresh()
|
||||
* \see mdbx_txn_begin_ex()
|
||||
@@ -4376,11 +4379,39 @@ LIBMDBX_API int mdbx_txn_commit_embark_read(MDBX_txn **ptxn, MDBX_commit_latency
|
||||
* \warning This function may be changed in future releases. */
|
||||
LIBMDBX_API int mdbx_txn_amend(MDBX_txn *read_txn, MDBX_txn **ptr_write_txn, MDBX_txn_flags_t flags, void *context);
|
||||
|
||||
/** \brief Rolls back all uncommitted changes within the write transaction and keeps it running.
|
||||
* \ingroup c_transactions
|
||||
*
|
||||
* Aborts and then restarts the transaction, rolling back all uncommitted changes.
|
||||
* If the current thread is not eligible to manage the transaction then
|
||||
* the \ref MDBX_THREAD_MISMATCH error will returned.
|
||||
*
|
||||
* \param [in] txn A transaction handle returned by \ref mdbx_txn_begin().
|
||||
*
|
||||
* \returns A non-zero error value on failure and 0 on success, some possibilities are:
|
||||
* \retval MDBX_RESULT_TRUE A more recent MVCC-snapshot has been committed after reading transaction
|
||||
* was started and data cannot be amended based on the desired data snapshot,
|
||||
* no actions have been performed.
|
||||
* \retval MDBX_TXN_OVERLAPPING The current thread is already executing a write transaction.
|
||||
* \retval MDBX_PANIC A fatal error occurred earlier and
|
||||
* the environment must be shut down.
|
||||
* \retval MDBX_BAD_TXN Unexpected or wrong transaction state.
|
||||
* \retval MDBX_EBADSIGN Transaction object has invalid signature,
|
||||
* e.g. transaction was already terminated
|
||||
* or memory was corrupted.
|
||||
* \retval MDBX_THREAD_MISMATCH Given transaction is not owned
|
||||
* by current thread.
|
||||
* \retval MDBX_EINVAL Transaction handle is NULL.
|
||||
*
|
||||
* \warning This function may be changed in future releases. */
|
||||
LIBMDBX_API int mdbx_txn_rollback(MDBX_txn *txn);
|
||||
|
||||
/** \brief Commits all the operations of the transaction into the database.
|
||||
* \ingroup c_transactions
|
||||
*
|
||||
* \see mdbx_txn_commit_embark_read()
|
||||
* \see mdbx_txn_checkpoint()
|
||||
* \see mdbx_txn_rollback()
|
||||
* \see mdbx_txn_commit_ex()
|
||||
* \see mdbx_txn_refresh()
|
||||
* \see mdbx_txn_begin_ex()
|
||||
@@ -4435,6 +4466,7 @@ LIBMDBX_INLINE_API(int, mdbx_txn_commit, (MDBX_txn * txn)) { return mdbx_txn_com
|
||||
* \see mdbx_txn_commit_ex()
|
||||
* \see mdbx_txn_checkpoint()
|
||||
* \see mdbx_txn_commit_embark_read()
|
||||
* \see mdbx_txn_rollback()
|
||||
* \see mdbx_txn_amend()
|
||||
* \warning This function may be changed in future releases. */
|
||||
LIBMDBX_API int mdbx_txn_abort_ex(MDBX_txn *txn, MDBX_commit_latency *latency);
|
||||
@@ -4466,6 +4498,7 @@ LIBMDBX_API int mdbx_txn_abort_ex(MDBX_txn *txn, MDBX_commit_latency *latency);
|
||||
* \see mdbx_txn_commit()
|
||||
* \see mdbx_txn_refresh()
|
||||
* \see mdbx_txn_reset()
|
||||
* \see mdbx_txn_rollback()
|
||||
*
|
||||
* \param [in] txn A transaction handle returned by \ref mdbx_txn_begin().
|
||||
*
|
||||
|
||||
2
mdbx.h++
2
mdbx.h++
@@ -1,4 +1,4 @@
|
||||
/// This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/// This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
/// \file mdbx.h++
|
||||
/// \brief The libmdbx C++ API header file.
|
||||
///
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-449-ga2319c94 at 2026-03-06T22:09:32+03:00).
|
||||
/* This file is part of the libmdbx amalgamated source code (v0.14.1-453-ga529b6d0 at 2026-03-08T20:32:09+03:00).
|
||||
*
|
||||
* libmdbx (aka MDBX) is an extremely fast, compact, powerful, embeddedable, transactional key-value storage engine with
|
||||
* open-source code. MDBX has a specific set of properties and capabilities, focused on creating unique lightweight
|
||||
|
||||
Reference in New Issue
Block a user