From 13a7157cec8ba31bc98ae6fc8df3d7eb74c49119 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: Fri, 2 Jan 2026 23:50:13 +0300 Subject: [PATCH] mdbx: provide initial `ut_and_examples` within a distribution. 2026-01-02 mdbx-make: provide `test` and `dist` targets for amalgamated sources. 2026-01-02 mdbx-cmake: enable `MDBX_ENABLE_TESTS` by default for amalgamated sources. 2026-01-02 mdbx-dist: add an `examples` directory to the distribution. 2026-01-02 mdbx: minor clarification and reformat of comments (cosmetics). 2026-01-02 mdbx: update (C) 2026. --- CMakeLists.txt | 124 ++++-------------------- COPYRIGHT | 2 +- GNUmakefile | 46 ++++++++- NOTICE | 2 +- VERSION.json | 2 +- cmake/compiler.cmake | 2 +- cmake/profile.cmake | 2 +- cmake/utils.cmake | 2 +- config.h.in | 9 +- man1/mdbx_chk.1 | 2 +- man1/mdbx_copy.1 | 2 +- man1/mdbx_drop.1 | 2 +- man1/mdbx_dump.1 | 2 +- man1/mdbx_load.1 | 2 +- man1/mdbx_stat.1 | 2 +- mdbx.c | 110 +++++++++++----------- mdbx.c++ | 6 +- mdbx.h | 5 +- mdbx.h++ | 2 +- mdbx_chk.c | 6 +- mdbx_copy.c | 6 +- mdbx_drop.c | 6 +- mdbx_dump.c | 6 +- mdbx_load.c | 6 +- mdbx_stat.c | 6 +- ut_and_examples/CMakeLists.txt | 18 ++++ ut_and_examples/README.md | 11 +++ ut_and_examples/example-mdbx.c | 167 +++++++++++++++++++++++++++++++++ 28 files changed, 355 insertions(+), 203 deletions(-) create mode 100644 ut_and_examples/CMakeLists.txt create mode 100644 ut_and_examples/README.md create mode 100644 ut_and_examples/example-mdbx.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c39c3912..f179c3b0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -# Copyright (c) 2020-2025 Леонид Юрьев aka Leonid Yuriev ############################################### +# Copyright (c) 2020-2026 Леонид Юрьев aka Leonid Yuriev ############################################### # SPDX-License-Identifier: Apache-2.0 # # Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Всё будет хорошо! @@ -12,10 +12,8 @@ # The next version is under active non-public development and will be released as MithrilDB and libmithrildb for # libraries & packages. Admittedly mythical Mithril is resembling silver but being stronger and lighter than steel. # Therefore MithrilDB is rightly relevant name. -# -# MithrilDB will be radically different from libmdbx by the new database format and API based on C++17, as well as the -# Apache 2.0 License. The goal of this revolution is to provide a clearer and robust API, add more features and new -# valuable properties of database. +# MithrilDB will be radically different from libmdbx by the new database format and API based on C++20. +# The goal of this revolution is to provide a clearer and robust API, add more features and new valuable properties. if(CMAKE_VERSION VERSION_LESS 3.8.2) cmake_minimum_required(VERSION 3.0.2) @@ -97,9 +95,6 @@ endif() if(DEFINED PROJECT_NAME AND NOT MDBX_FORCE_BUILD_AS_MAIN_PROJECT) set(SUBPROJECT ON) set(NOT_SUBPROJECT OFF) - if(NOT MDBX_AMALGAMATED_SOURCE AND NOT DEFINED BUILD_TESTING) - set(BUILD_TESTING OFF) - endif() enable_language(C) else() set(SUBPROJECT OFF) @@ -121,23 +116,20 @@ else() project(libmdbx C) endif() -if(MDBX_AMALGAMATED_SOURCE - AND DEFINED MDBX_ENABLE_TESTS - AND MDBX_ENABLE_TESTS) - message(WARNING "MDBX_ENABLE_TESTS=${MDBX_ENABLE_TESTS}: But amalgamated source code don't includes tests.") - set(MDBX_ENABLE_TESTS OFF) -endif() - if(NOT CMAKE_VERSION VERSION_LESS 3.8.2) source_group("markdown" FILES REGULAR_EXPRESSION ".*[.]md") endif() +if(NOT ((DEFINED BUILD_TESTING AND NOT BUILD_TESTING) OR (DEFINED MDBX_ENABLE_TESTS AND NOT MDBX_ENABLE_TESTS))) + include(CTest) + option(MDBX_ENABLE_TESTS "Build MDBX tests" ${BUILD_TESTING}) +endif() + # Try to find a C++ compiler unless sure that this is unnecessary. if(NOT CMAKE_CXX_COMPILER_LOADED) include(CheckLanguage) - if(NOT DEFINED MDBX_BUILD_CXX - OR MDBX_BUILD_CXX - OR (NOT MDBX_AMALGAMATED_SOURCE AND (NOT DEFINED MDBX_ENABLE_TESTS OR MDBX_ENABLE_TESTS))) + if(NOT (DEFINED MDBX_BUILD_CXX AND NOT MDBX_BUILD_CXX) + OR NOT (DEFINED MDBX_ENABLE_TESTS AND NOT MDBX_ENABLE_TESTS)) check_language(CXX) if(CMAKE_CXX_COMPILER) enable_language(CXX) @@ -321,72 +313,6 @@ else() set(LTO_ENABLED FALSE) endif() - if(NOT MDBX_AMALGAMATED_SOURCE) - if(NOT WIN32) - if(NOT MEMORYCHECK_COMMAND) - find_program(MEMORYCHECK_COMMAND valgrind) - endif() - if(MEMORYCHECK_COMMAND) - # (LY) cmake is ugly and nasty. Therefore memcheck-options should be defined before including ctest. Otherwise - # ctest may ignore it. - set(MEMORYCHECK_SUPPRESSIONS_FILE - "${CMAKE_CURRENT_SOURCE_DIR}/test/valgrind_suppress.txt" - CACHE FILEPATH "Suppressions file for Valgrind" FORCE) - set(MEMORYCHECK_COMMAND_OPTIONS - "--trace-children=yes --leak-check=full --track-origins=yes --expensive-definedness-checks=yes --error-exitcode=42 --error-markers=@VALGRIND --errors-for-leak-kinds=definite --fair-sched=yes --suppressions=${MEMORYCHECK_SUPPRESSIONS_FILE}" - CACHE STRING "Valgrind options" FORCE) - set(MEMORYCHECK_COMMAND_OPTIONS - "${MEMORYCHECK_COMMAND_OPTIONS}" - CACHE STRING "Valgrind options" FORCE) - endif() - endif() - - # Enable 'make tags' target. - find_program(CTAGS ctags) - if(CTAGS) - add_custom_target( - tags - COMMAND ${CTAGS} -R -f tags - WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}) - add_custom_target(ctags DEPENDS tags) - endif(CTAGS) - - if(UNIX) - find_program(CLANG_FORMAT NAMES clang-format-13 clang-format) - if(CLANG_FORMAT) - execute_process(COMMAND ${CLANG_FORMAT} "--version" OUTPUT_VARIABLE clang_format_version_info) - string(REGEX MATCH "version ([0-9]+)\\.([0-9]+)\\.([0-9]+)(.*)?" clang_format_version_info CLANG_FORMAT_VERSION) - if(clang_format_version_info AND NOT CLANG_FORMAT_VERSION VERSION_LESS 13.0) - # Enable 'make reformat' target. - add_custom_target( - reformat - VERBATIM - COMMAND git ls-files | grep -E \\.\(c|cxx|cc|cpp|h|hxx|hpp\)\(\\.in\)?\$ | xargs ${CLANG_FORMAT} -i - --style=file - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) - endif() - endif() - endif() - - if(NOT "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}") - add_custom_target(distclean) - add_custom_command( - TARGET distclean - POST_BUILD - COMMAND ${CMAKE_COMMAND} -E remove_directory "${PROJECT_BINARY_DIR}" - COMMENT "Removing the build directory and its content") - elseif(IS_DIRECTORY .git AND GIT) - add_custom_target(distclean) - add_custom_command( - TARGET distclean - POST_BUILD - WORKING_DIRECTORY ${PROJECT_SOURCE_DIR} - COMMAND ${GIT} submodule foreach --recursive git clean -f -X -d - COMMAND ${GIT} clean -f -X -d - COMMENT "Removing all build files from the source directory") - endif() - endif(NOT MDBX_AMALGAMATED_SOURCE) - set(MDBX_MANAGE_BUILD_FLAGS_DEFAULT ON) endif(SUBPROJECT) @@ -584,32 +510,21 @@ add_option(MDBX ENABLE_DBI_LOCKFREE "Support for deferred releasing and a lockfr add_option(MDBX USE_FALLOCATE "Using posix_fallocate() or fcntl(F_PREALLOCATE) on OSX" AUTO) mark_as_advanced(MDBX_USE_FALLOCATE) -if(NOT MDBX_AMALGAMATED_SOURCE) - if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "DEBUG") - set(MDBX_ALLOY_BUILD_DEFAULT OFF) - else() - set(MDBX_ALLOY_BUILD_DEFAULT ON) - endif() - add_option(MDBX ALLOY_BUILD "Build MDBX library through single/alloyed object file" ${MDBX_ALLOY_BUILD_DEFAULT}) -endif() - if((MDBX_BUILD_TOOLS OR MDBX_ENABLE_TESTS) AND MDBX_BUILD_SHARED_LIBRARY) add_option(MDBX LINK_TOOLS_NONSTATIC "Link MDBX tools with non-static libmdbx" OFF) else() unset(MDBX_LINK_TOOLS_NONSTATIC CACHE) endif() +set(MDBX_CXX_AVAILABLE FALSE) if(CMAKE_CXX_COMPILER_LOADED AND MDBX_CXX_STANDARD LESS 83 AND NOT MDBX_CXX_STANDARD LESS 11) - if(NOT MDBX_AMALGAMATED_SOURCE) - include(CTest) - option(MDBX_ENABLE_TESTS "Build MDBX tests" ${BUILD_TESTING}) - endif() if(NOT MDBX_WITHOUT_MSVC_CRT AND NOT (CMAKE_COMPILER_IS_GNUCXX AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 4.8) AND NOT (CMAKE_COMPILER_IS_CLANG AND CMAKE_CXX_COMPILER_VERSION VERSION_LESS 3.9) AND NOT (MSVC AND MSVC_VERSION LESS 1900)) + set(MDBX_CXX_AVAILABLE TRUE) option(MDBX_BUILD_CXX "Build C++ portion" ON) else() if(DEFINED MDBX_BUILD_CXX AND MDBX_BUILD_CXX) @@ -628,9 +543,6 @@ else() if(DEFINED MDBX_BUILD_CXX AND MDBX_BUILD_CXX) message(WARNING "MDBX_BUILD_CXX=${MDBX_BUILD_CXX}: But there is no suitable C++ compiler available.") endif() - if(DEFINED MDBX_ENABLE_TESTS AND MDBX_ENABLE_TESTS) - message(WARNING "MDBX_ENABLE_TESTS=${MDBX_ENABLE_TESTS}: But there is no suitable C++ compiler available.") - endif() set(MDBX_ENABLE_TESTS OFF) set(MDBX_BUILD_CXX OFF) endif() @@ -641,8 +553,8 @@ endif() # ###################################################################################################################### -if(MDBX_BUILD_CXX AND NOT CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "MDBX_BUILD_CXX=${MDBX_BUILD_CXX}: The C++ compiler is required to build the C++API.") +if(MDBX_BUILD_CXX AND NOT MDBX_CXX_AVAILABLE) + message(FATAL_ERROR "MDBX_BUILD_CXX=${MDBX_BUILD_CXX}: The C++ 11 compiler is required to build the C++API.") endif() if(MDBX_BUILD_CXX) @@ -744,8 +656,10 @@ target_setup_options(mdbx-static) libmdbx_setup_libs(mdbx-static INTERFACE) if(MDBX_BUILD_SHARED_LIBRARY) set_target_properties(mdbx-static PROPERTIES OUTPUT_NAME mdbx-static) + set(MDBX_LIBRARY mdbx) else() set_target_properties(mdbx-static PROPERTIES OUTPUT_NAME mdbx) + set(MDBX_LIBRARY mdbx-static) endif() target_include_directories(mdbx-static INTERFACE "${CMAKE_CURRENT_SOURCE_DIR}") @@ -1050,10 +964,8 @@ add_definitions(-DMDBX_CONFIG_H="${CMAKE_CURRENT_BINARY_DIR}/config-cmake.h") # ###################################################################################################################### -if(NOT MDBX_AMALGAMATED_SOURCE AND MDBX_ENABLE_TESTS) - if(NOT CMAKE_CXX_COMPILER_LOADED) - message(FATAL_ERROR "MDBX_ENABLE_TESTS=${MDBX_ENABLE_TESTS}: The C++ compiler is required to build the tests.") - endif() +if(MDBX_ENABLE_TESTS) + add_subdirectory(ut_and_examples) endif() # ###################################################################################################################### diff --git a/COPYRIGHT b/COPYRIGHT index fb29a937..09de19ba 100644 --- a/COPYRIGHT +++ b/COPYRIGHT @@ -1,4 +1,4 @@ -Copyright (c) 2015-2025 Леонид Юрьев aka Leonid Yuriev +Copyright (c) 2015-2026 Леонид Юрьев aka Leonid Yuriev Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/GNUmakefile b/GNUmakefile index 33332db8..25436eee 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -52,7 +52,7 @@ CC ?= gcc CXX ?= g++ CFLAGS_EXTRA ?= LD ?= ld -CMAKE ?= cmake +CMAKE ?= "$(shell which cmake 2>&-)" CMAKE_OPT ?= CTEST ?= ctest CTEST_OPT ?= @@ -142,7 +142,7 @@ MDBX_TOOLS := $(addprefix mdbx_,$(TOOLS)) MANPAGES := mdbx_stat.1 mdbx_copy.1 mdbx_dump.1 mdbx_load.1 mdbx_chk.1 mdbx_drop.1 TIP := // TIP: -.PHONY: all help options lib libs tools clean install uninstall check_buildflags_tag tools-static +.PHONY: all help options lib libs tools clean install uninstall check_buildflags_tag tools-static run-ut .PHONY: install-strip install-no-strip strip libmdbx mdbx show-options lib-static lib-shared cmake-build ninja boolean = $(if $(findstring $(strip $($1)),YES Yes yes y ON On on 1 true True TRUE),1,$(if $(findstring $(strip $($1)),NO No no n OFF Off off 0 false False FALSE),,$(error Wrong value `$($1)` of $1 for YES/NO option))) @@ -192,6 +192,11 @@ help: @echo " make bench-triplet - run ioarena-benchmark for mdbx, lmdb, sqlite3" @echo " make bench-quartet - run ioarena-benchmark for mdbx, lmdb, rocksdb, wiredtiger" @echo " make bench-clean - remove temp database(s) after benchmark" + @echo " make test - basic test(s)" + @echo " make build-test - build test(s) executable(s)" + @echo " make test-asan - build with AddressSanitizer and run basic test" + @echo " make test-leak - build with LeakSanitizer and run basic test" + @echo " make test-ubsan - build with UndefinedBehaviourSanitizer and run basic test" show-options: @echo " MDBX_BUILD_OPTIONS = $(MDBX_BUILD_OPTIONS)" @@ -280,10 +285,47 @@ ctest: cmake-build @echo " RUN: ctest .." $(QUIET)$(CTEST) --test-dir @cmake-ninja-build --parallel `(nproc | sysctl -n hw.ncpu | echo 2) 2>/dev/null` --schedule-random $(CTEST_OPT) +run-ut: mdbx_example + $(QUIET)for UT in $^; do echo " Running $$UT" && ./$${UT} || exit -1; done + +TEST_TARGETS := mdbx_example +TEST_BUILD_TARGETS := test-build +ifneq ($(CMAKE),"") +TEST_TARGETS += ctest +TEST_BUILD_TARGETS += cmake-build +endif + +.PHONY: ninja-assertions ninja-debug ninja $(TEST_TARGETS) $(TEST_BUILD_TARGETS) test-ubsan test-asan test-asan test-leak test-assertion test build-test smoke check +test smoke check: $(TEST_TARGETS) +build-test: $(TEST_BUILD_TARGETS) + +test-assertion: MDBX_BUILD_OPTIONS += -DMDBX_FORCE_ASSERTIONS=1 -UNDEBUG -DMDBX_DEBUG=0 +test-assertion: smoke + +test-ubsan: + @echo ' RE-TEST with `-fsanitize=undefined` option...' + $(QUIET)$(MAKE) IOARENA=false CXXSTD=$(CXXSTD) CFLAGS_EXTRA="-DENABLE_UBSAN -Ofast -fsanitize=undefined -fsanitize-undefined-trap-on-error" test + +test-asan: + @echo ' RE-TEST with `-fsanitize=address` option...' + $(QUIET)$(MAKE) IOARENA=false CXXSTD=$(CXXSTD) CFLAGS_EXTRA="-Os -fsanitize=address" test + +test-leak: + @echo ' RE-TEST with `-fsanitize=leak` option...' + $(QUIET)$(MAKE) IOARENA=false CXXSTD=$(CXXSTD) CFLAGS_EXTRA="-fsanitize=leak" test + +mdbx_example: mdbx.h ut_and_examples/example-mdbx.c libmdbx.$(SO_SUFFIX) + @echo ' CC+LD $@' + $(QUIET)$(CC) $(CFLAGS) -I. ut_and_examples/example-mdbx.c ./libmdbx.$(SO_SUFFIX) -o $@ + ################################################################################ # Amalgamated source code, i.e. distributed after `make dist` MAN_SRCDIR := man1/ +dist: + @echo ' Starting 2026 libmdbx is distrubuted in an amalgamated source code form.' + @echo ' So amalgamation is no longer required. Please update your build scripts.' + config-gnumake.h: @buildflags.tag $(WAIT) mdbx.c $(lastword $(MAKEFILE_LIST)) LICENSE NOTICE COPYRIGHT @echo ' MAKE $@' $(QUIET)(echo '#define MDBX_BUILD_TIMESTAMP "$(MDBX_BUILD_TIMESTAMP)"' \ diff --git a/NOTICE b/NOTICE index b232ec72..3f2c9ceb 100644 --- a/NOTICE +++ b/NOTICE @@ -11,7 +11,7 @@ to the Telegram' group https://t.me/libmdbx. Donations are welcome to the Ethereum/ERC-20 `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. Всё будет хорошо! -Copyright 2015-2025 Леонид Юрьев aka Leonid Yuriev +Copyright 2015-2026 Леонид Юрьев aka Leonid Yuriev SPDX-License-Identifier: Apache-2.0 For notes about the license change, credits and acknowledgments, please refer to the COPYRIGHT file within libmdbx source. diff --git a/VERSION.json b/VERSION.json index 8abe9bfa..1b293d08 100644 --- a/VERSION.json +++ b/VERSION.json @@ -1 +1 @@ -{ "git_describe": "v0.14.1-215-g541e81ed", "git_timestamp": "2026-01-01T01:10:47+03:00", "git_tree": "0d2ce6d87b92a6e4230b34454a2285496f8a75f2", "git_commit": "541e81ed1c8e47d5cbdb050a2102263a255002d4", "semver": "0.14.1.215" } +{ "git_describe": "v0.14.1-220-g0f8b288c", "git_timestamp": "2026-01-02T23:27:02+03:00", "git_tree": "d490bb4b78537c494ffecf7b31b961c48a715d94", "git_commit": "0f8b288ce9d1e1028f8bb760f5f87eafa8e94bfe", "semver": "0.14.1.220" } diff --git a/cmake/compiler.cmake b/cmake/compiler.cmake index a3d789ce..1165bb3b 100644 --- a/cmake/compiler.cmake +++ b/cmake/compiler.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2010-2025 Леонид Юрьев aka Leonid Yuriev ############################################### +# Copyright (c) 2010-2026 Леонид Юрьев aka Leonid Yuriev ############################################### # SPDX-License-Identifier: Apache-2.0 if(CMAKE_VERSION VERSION_LESS 3.8.2) diff --git a/cmake/profile.cmake b/cmake/profile.cmake index 6a8a466e..e2aad1bb 100644 --- a/cmake/profile.cmake +++ b/cmake/profile.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2025 Леонид Юрьев aka Leonid Yuriev ############################################### +# Copyright (c) 2012-2026 Леонид Юрьев aka Leonid Yuriev ############################################### # SPDX-License-Identifier: Apache-2.0 if(CMAKE_VERSION VERSION_LESS 3.8.2) diff --git a/cmake/utils.cmake b/cmake/utils.cmake index d852b51b..2bd0680b 100644 --- a/cmake/utils.cmake +++ b/cmake/utils.cmake @@ -1,4 +1,4 @@ -# Copyright (c) 2012-2025 Леонид Юрьев aka Leonid Yuriev ############################################### +# Copyright (c) 2012-2026 Леонид Юрьев aka Leonid Yuriev ############################################### # SPDX-License-Identifier: Apache-2.0 if(CMAKE_VERSION VERSION_LESS 3.8.2) diff --git a/config.h.in b/config.h.in index 447c699d..8af2e181 100644 --- a/config.h.in +++ b/config.h.in @@ -11,8 +11,10 @@ #cmakedefine ENABLE_ASAN #cmakedefine ENABLE_UBSAN #cmakedefine01 MDBX_FORCE_ASSERTIONS + +/* allowing override MDBX_BUILD_CXX=OFF to build the C++ API in "private" mode only for tests */ #if !defined(MDBX_BUILD_TEST) && !defined(MDBX_BUILD_CXX) -#cmakedefine01 MDBX_BUILD_CXX +#cmakedefine01 MDBX_BUILD_CXX /* using MDBX_BUILD_CXX CMake's option */ #endif /* Common */ @@ -39,10 +41,11 @@ #cmakedefine01 MDBX_ENABLE_DBI_LOCKFREE /* Windows */ +/* allowing override MDBX_WITHOUT_MSVC_CRT=ON to build the C++ API in "private" mode only for tests */ #if defined(MDBX_BUILD_TEST) || !defined(MDBX_BUILD_CXX) || MDBX_BUILD_CXX -#define MDBX_WITHOUT_MSVC_CRT 0 +#define MDBX_WITHOUT_MSVC_CRT /* hardcoded zero */ 0 #else -#cmakedefine01 MDBX_WITHOUT_MSVC_CRT +#cmakedefine01 MDBX_WITHOUT_MSVC_CRT /* using MDBX_WITHOUT_MSVC_CRT CMake's option */ #endif /* MDBX_WITHOUT_MSVC_CRT */ /* MacOS & iOS */ diff --git a/man1/mdbx_chk.1 b/man1/mdbx_chk.1 index ffcd25ab..4489bc39 100644 --- a/man1/mdbx_chk.1 +++ b/man1/mdbx_chk.1 @@ -1,4 +1,4 @@ -.\" Copyright 2015-2025 Leonid Yuriev . +.\" Copyright 2015-2026 Leonid Yuriev . .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .TH MDBX_CHK 1 "2025-01-14" "MDBX 0.14" .SH NAME diff --git a/man1/mdbx_copy.1 b/man1/mdbx_copy.1 index dbdd5ab1..ea686bc3 100644 --- a/man1/mdbx_copy.1 +++ b/man1/mdbx_copy.1 @@ -1,4 +1,4 @@ -.\" Copyright 2015-2025 Leonid Yuriev . +.\" Copyright 2015-2026 Leonid Yuriev . .\" Copyright 2015,2016 Peter-Service R&D LLC . .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. diff --git a/man1/mdbx_drop.1 b/man1/mdbx_drop.1 index 0a697edb..ed45183a 100644 --- a/man1/mdbx_drop.1 +++ b/man1/mdbx_drop.1 @@ -1,4 +1,4 @@ -.\" Copyright 2021-2025 Leonid Yuriev . +.\" Copyright 2021-2026 Leonid Yuriev . .\" Copyright 2014-2021 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. .TH MDBX_DROP 1 "2025-01-14" "MDBX 0.14" diff --git a/man1/mdbx_dump.1 b/man1/mdbx_dump.1 index 39e917ce..325b89f3 100644 --- a/man1/mdbx_dump.1 +++ b/man1/mdbx_dump.1 @@ -1,4 +1,4 @@ -.\" Copyright 2015-2025 Leonid Yuriev . +.\" Copyright 2015-2026 Leonid Yuriev . .\" Copyright 2015,2016 Peter-Service R&D LLC . .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. diff --git a/man1/mdbx_load.1 b/man1/mdbx_load.1 index cad8c310..4e4c4b6d 100644 --- a/man1/mdbx_load.1 +++ b/man1/mdbx_load.1 @@ -1,4 +1,4 @@ -.\" Copyright 2015-2025 Leonid Yuriev . +.\" Copyright 2015-2026 Leonid Yuriev . .\" Copyright 2015,2016 Peter-Service R&D LLC . .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. diff --git a/man1/mdbx_stat.1 b/man1/mdbx_stat.1 index bacfaf02..7000e18c 100644 --- a/man1/mdbx_stat.1 +++ b/man1/mdbx_stat.1 @@ -1,4 +1,4 @@ -.\" Copyright 2015-2025 Leonid Yuriev . +.\" Copyright 2015-2026 Leonid Yuriev . .\" Copyright 2015,2016 Peter-Service R&D LLC . .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. diff --git a/mdbx.c b/mdbx.c index 61a329d5..1da8d4b2 100644 --- a/mdbx.c +++ b/mdbx.c @@ -1,10 +1,10 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /* clang-format off */ #define xMDBX_ALLOY 1 /* alloyed build */ -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED @@ -7130,7 +7130,7 @@ MDBX_INTERNAL int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl); #pragma warning(pop) #endif /* MSVC */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold size_t mdbx_default_pagesize(void) { size_t pagesize = globals.sys_pagesize; @@ -7673,7 +7673,7 @@ LIBMDBX_API __cold intptr_t mdbx_limits_pgsize_max(void) { return __inline_mdbx_ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 typedef struct compacting_context { MDBX_env *env; @@ -8582,7 +8582,7 @@ __cold int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest_path, MDBX_copy_fla return LOG_IFERR(rc); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 MDBX_cursor *mdbx_cursor_create(void *context) { cursor_couple_t *couple = osal_calloc(1, sizeof(cursor_couple_t)); @@ -9429,7 +9429,7 @@ int mdbx_cursor_bunch_delete(MDBX_cursor *mc, MDBX_bunch_action_t action, uint64 return LOG_IFERR(rc); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 int mdbx_dbi_open2(MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags, MDBX_dbi *dbi) { return LOG_IFERR(dbi_open(txn, name, flags, dbi, nullptr, nullptr)); @@ -9721,7 +9721,7 @@ bailout: return LOG_IFERR(rc); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold static intptr_t reasonable_db_maxsize(void) { static intptr_t cached_result; @@ -11170,7 +11170,7 @@ __cold int mdbx_env_stat_ex(const MDBX_env *env, const MDBX_txn *txn, MDBX_stat return LOG_IFERR(rc); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /*------------------------------------------------------------------------------ * Readers API */ @@ -11359,7 +11359,7 @@ __cold const char *mdbx_ratio2percents(uint64_t value, uint64_t whole, char *buf return ratio2percent(value, whole, (ratio2digits_buffer_t *)buffer); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static inline double key2double(const int64_t key) { union { @@ -11554,7 +11554,7 @@ int64_t mdbx_int64_from_key(const MDBX_val v) { return (int64_t)(unaligned_peek_u64(2, v.iov_base) - UINT64_C(0x8000000000000000)); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold int mdbx_is_readahead_reasonable(size_t volume, intptr_t redundancy) { if (volume <= 1024 * 1024 * 4ul) @@ -11837,7 +11837,7 @@ const char *mdbx_strerror_ANSI2OEM(int errnum) { } #endif /* Bit of madness for Windows */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static pgno_t env_max_pgno(const MDBX_env *env) { return env->ps ? bytes2pgno(env, env->geo_in_bytes.upper ? env->geo_in_bytes.upper : MAX_MAPSIZE) : PAGELIST_LIMIT; @@ -12413,7 +12413,7 @@ __cold int mdbx_env_get_option(const MDBX_env *env, const MDBX_option_t option, return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 typedef struct diff_result { ptrdiff_t diff; @@ -12776,7 +12776,7 @@ __hot int mdbx_estimate_range(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold int mdbx_dbi_dupsort_depthmask(const MDBX_txn *txn, MDBX_dbi dbi, uint32_t *mask) { if (unlikely(!mask)) @@ -13228,7 +13228,7 @@ int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *new return mdbx_replace_ex(txn, dbi, key, new_data, old_data, flags, default_value_preserver, nullptr); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #ifdef __SANITIZE_THREAD__ /* LY: avoid tsan-trap by txn, mm_last_pg and geo.first_unallocated */ @@ -13765,7 +13765,7 @@ int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, bool scan_rlt) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 struct audit_ctx { size_t used; @@ -13870,7 +13870,7 @@ __cold int audit_ex(MDBX_txn *txn, size_t retired_stored, bool dont_filter_gc) { return rc; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 typedef struct MDBX_chk_internal { MDBX_chk_context_t *usr; @@ -15772,7 +15772,7 @@ __cold int mdbx_env_chk(MDBX_env *env, const struct MDBX_chk_callbacks *cb, MDBX return LOG_IFERR(rc); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /*------------------------------------------------------------------------------ * Pack/Unpack 16-bit values for Grow step & Shrink threshold */ @@ -16098,7 +16098,7 @@ uint32_t combine_durability_flags(const uint32_t a, const uint32_t b) { return r; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /* check against https://libmdbx.dqdkfa.ru/dead-github/issues/269 */ static bool coherency_check(const MDBX_env *env, const txnid_t txnid, const volatile tree_t *trees, @@ -16260,7 +16260,7 @@ bool coherency_check_meta(const MDBX_env *env, const volatile meta_t *meta, bool /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold int cursor_validate(const MDBX_cursor *mc) { if (!mc->txn->wr.dirtylist) { @@ -18627,7 +18627,7 @@ int cursor_check(const MDBX_cursor *mc, int txn_bad_bits) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static defer_free_item_t *dbi_close_locked(MDBX_env *env, MDBX_dbi dbi); @@ -19395,7 +19395,7 @@ __cold const tree_t *dbi_dig(const MDBX_txn *txn, const size_t dbi, tree_t *fall int dbi_close_release(MDBX_env *env, MDBX_dbi dbi) { return dbi_defer_release(env, dbi_close_locked(env, dbi)); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static inline size_t dpl_size2bytes(ptrdiff_t size) { assert(size > CURSOR_STACK_SIZE && (size_t)size <= PAGELIST_LIMIT); @@ -19881,7 +19881,7 @@ void dpl_release_shadows(MDBX_txn *txn) { dpl_clear(dl); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold int dxb_read_header(MDBX_env *env, meta_t *dest, const int lck_exclusive, const mdbx_mode_t mode_bits) { memset(dest, 0, sizeof(meta_t)); @@ -21215,7 +21215,7 @@ fail: return rc; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 MDBX_txn *env_owned_wrtxn(const MDBX_env *env) { if (likely(env->basal_txn)) { @@ -21822,7 +21822,7 @@ __cold int env_close(MDBX_env *env, bool resurrect_after_fork) { return rc; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #if MDBX_USE_MINCORE /*------------------------------------------------------------------------------ @@ -24707,7 +24707,7 @@ bailout: #pragma pop_macro("LOG_ENABLED") #endif /* MDBX_DEBUG_GCU */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static void mdbx_init(void); static void mdbx_fini(void); @@ -25197,7 +25197,7 @@ const char *__asan_default_options(void) { #endif /* __SANITIZE_ADDRESS__ */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #if !(defined(_WIN32) || defined(_WIN64)) /*----------------------------------------------------------------------------* @@ -26067,7 +26067,7 @@ void lck_txn_unlock(MDBX_env *env) { #endif /* !Windows LCK-implementation */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #if defined(_WIN32) || defined(_WIN64) @@ -26689,7 +26689,7 @@ int lck_rpid_check(MDBX_env *env, uint32_t pid) { #endif /* Windows */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold static int lck_setup_locked(MDBX_env *env) { int err = rthc_register(env); @@ -26861,7 +26861,7 @@ void mincore_clean_cache(const MDBX_env *const env) { memset(env->lck->mincore_cache.begin, -1, sizeof(env->lck->mincore_cache.begin)); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /*------------------------------------------------------------------------------ logging */ @@ -27112,7 +27112,7 @@ __cold void page_list(page_t *mp) { total, page_room(mp)); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 typedef struct meta_snap { uint64_t txnid; @@ -27766,7 +27766,7 @@ __cold int meta_validate_copy(MDBX_env *env, const meta_t *meta, meta_t *dest) { return meta_validate(env, dest, payload2page(meta), bytes2pgno(env, ptr_dist(meta, env->dxb_mmap.base)), nullptr); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 bsr_t mvcc_bind_slot(MDBX_env *env) { eASSERT(env, env->lck_mmap.lck); @@ -28180,7 +28180,7 @@ __cold bool mvcc_kick_laggards(MDBX_env *env, const txnid_t straggler) { /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __hot int __must_check_result node_add_dupfix(MDBX_cursor *mc, size_t indx, const MDBX_val *key) { page_t *mp = mc->pg[mc->top]; @@ -28543,7 +28543,7 @@ __hot struct node_search_result node_search(MDBX_cursor *mc, const MDBX_val *key return ret; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// https://en.wikipedia.org/wiki/Operating_system_abstraction_layer @@ -32122,7 +32122,7 @@ void osal_ctor(void) { void osal_dtor(void) {} /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __cold int MDBX_PRINTF_ARGS(2, 3) bad_page(const page_t *mp, const char *fmt, ...) { if (LOG_ENABLED(MDBX_LOG_ERROR)) { @@ -32605,7 +32605,7 @@ pgr_t page_get_large(const MDBX_cursor *const mc, const pgno_t pgno, const txnid return page_get_inline(P_ILL_BITS | P_BRANCH | P_LEAF | P_DUPFIX, mc, pgno, front); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 int iov_init(MDBX_txn *const txn, iov_ctx_t *ctx, size_t items, size_t npages, mdbx_filehandle_t fd, bool check_coherence) { @@ -32788,7 +32788,7 @@ int iov_page(MDBX_txn *txn, iov_ctx_t *ctx, page_t *dp, size_t npages) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static inline tree_t *outer_tree(MDBX_cursor *mc) { cASSERT(mc, (mc->flags & z_inner) != 0); @@ -33534,7 +33534,7 @@ size_t page_subleaf2_reserve(const MDBX_env *env, size_t host_page_room, size_t return reserve + (subpage_len & 1); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 pnl_t pnl_alloc(size_t size) { size_t bytes = pnl_size2bytes(size); @@ -33790,7 +33790,7 @@ size_t pnl_maxspan(const pnl_t pnl) { return len; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #if MDBX_ENABLE_REFUND static void refund_reclaimed(MDBX_txn *txn) { @@ -34000,7 +34000,7 @@ bool txn_refund(MDBX_txn *txn) { #endif /* MDBX_ENABLE_REFUND */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2025-2026 static inline size_t rkl_size2bytes(const size_t size) { assert(size > 0 && size <= txl_max * 2); @@ -34644,7 +34644,7 @@ bool rkl_check(const rkl_t *rkl) { return true; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 void spill_remove(MDBX_txn *txn, size_t idx, size_t npages) { tASSERT(txn, idx > 0 && idx <= pnl_size(txn->wr.spilled.list) && txn->wr.spilled.least_removed > 0); @@ -35075,7 +35075,7 @@ done: : MDBX_TXN_FULL; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 int tbl_setup(const MDBX_env *env, volatile kvx_t *const kvx, const tree_t *const db) { osal_memory_fence(mo_AcquireRelease, false); @@ -35239,7 +35239,7 @@ int tbl_purge(MDBX_cursor *mc) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 typedef struct rthc_entry { MDBX_env *env; @@ -35794,7 +35794,7 @@ __cold void rthc_dtor(const uint32_t current_pid) { /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static MDBX_cursor *cursor_clone(const MDBX_cursor *csrc, cursor_couple_t *couple) { cASSERT(csrc, csrc->txn->txnid >= csrc->txn->env->lck->cached_oldest.weak); @@ -37374,7 +37374,7 @@ int tree_propagate_key(MDBX_cursor *mc, const MDBX_val *key) { /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /* Search for the lowest key under the current branch page. * This just bypasses a numkeys check in the current page @@ -37544,7 +37544,7 @@ __hot __noinline int tree_search_finalize(MDBX_cursor *mc, const MDBX_val *key, return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static inline size_t txl_size2bytes(const size_t size) { assert(size > 0 && size <= txl_max * 2); @@ -37641,7 +37641,7 @@ __hot bool txl_contain(const txl_t txl, txnid_t id) { return false; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static int txn_write(MDBX_txn *txn, iov_ctx_t *ctx) { tASSERT(txn, (txn->flags & MDBX_WRITEMAP) == 0 || MDBX_AVOID_MSYNC); @@ -38013,7 +38013,7 @@ int txn_basal_commit(MDBX_txn *txn, struct commit_timestamp *ts) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /* Merge pageset of the nested txn into parent */ static void txn_merge(MDBX_txn *const parent, MDBX_txn *const txn, const size_t parent_retired_len) { @@ -38613,7 +38613,7 @@ int txn_nested_join(MDBX_txn *txn, struct commit_timestamp *ts) { return MDBX_SUCCESS; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static inline int txn_ro_rslot(MDBX_txn *txn) { reader_slot_t *slot = txn->ro.slot; @@ -38909,7 +38909,7 @@ int txn_ro_unpark(MDBX_txn *txn) { return err ? err : MDBX_OUSTED; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 __hot bool txn_gc_detent(const MDBX_txn *const txn) { const txnid_t detent = mvcc_shapshot_oldest(txn->env, txn->wr.troika.txnid[txn->wr.troika.prefer_steady]); @@ -39358,7 +39358,7 @@ MDBX_txn *txn_alloc(const MDBX_txn_flags_t flags, MDBX_env *env) { return txn; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 MDBX_NOTHROW_CONST_FUNCTION MDBX_MAYBE_UNUSED unsigned ceil_log2n(size_t value_uintptr) { assert(value_uintptr > 0 && value_uintptr < INT32_MAX); @@ -39448,7 +39448,7 @@ __cold char *ratio2percent(uint64_t value, uint64_t whole, ratio2digits_buffer_t return ratio2digits(value * 100, whole, buffer, rough ? 1 : 2); } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 static page_type_t walk_page_type(const page_t *mp) { if (mp) @@ -39726,7 +39726,7 @@ __cold int walk_pages(MDBX_txn *txn, walk_func *visitor, void *user, walk_option return rc; } /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 #if defined(_WIN32) || defined(_WIN64) @@ -39904,10 +39904,10 @@ __dll_export 0, 14, 1, - 215, + 220, "", /* pre-release suffix of SemVer - 0.14.1.215 */ - {"2026-01-01T01:10:47+03:00", "0d2ce6d87b92a6e4230b34454a2285496f8a75f2", "541e81ed1c8e47d5cbdb050a2102263a255002d4", "v0.14.1-215-g541e81ed"}, + 0.14.1.220 */ + {"2026-01-02T23:27:02+03:00", "d490bb4b78537c494ffecf7b31b961c48a715d94", "0f8b288ce9d1e1028f8bb760f5f87eafa8e94bfe", "v0.14.1-220-g0f8b288c"}, sourcery}; __dll_export diff --git a/mdbx.c++ b/mdbx.c++ index 8c47bda9..62e49253 100644 --- a/mdbx.c++ +++ b/mdbx.c++ @@ -1,8 +1,8 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /* clang-format off */ -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED @@ -7128,7 +7128,7 @@ MDBX_INTERNAL int walk_tbl(walk_ctx_t *ctx, walk_tbl_t *tbl); #pragma warning(pop) #endif /* MSVC */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2020-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2020-2026 /// /// \brief Non-inline part of the libmdbx C++ API /// diff --git a/mdbx.h b/mdbx.h index 4826a982..093fdea0 100644 --- a/mdbx.h +++ b/mdbx.h @@ -28,7 +28,7 @@ and https://sourcecraft.dev/dqdkfa/libmdbx for the source code. \section copyright LICENSE & COPYRIGHT \copyright SPDX-License-Identifier: Apache-2.0 \note Please refer to the COPYRIGHT file for explanations license change, credits and acknowledgments. -\author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +\author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 *******************************************************************************/ @@ -2538,8 +2538,7 @@ typedef enum MDBX_env_delete_mode { /** \brief Make sure that the environment is not being used by other * processes, or return an error otherwise. */ MDBX_ENV_ENSURE_UNUSED = 1, - /** \brief Wait until other processes closes the environment before deletion. - */ + /** \brief Wait until other processes closes the environment before deletion. */ MDBX_ENV_WAIT_FOR_UNUSED = 2, } MDBX_env_delete_mode_t; diff --git a/mdbx.h++ b/mdbx.h++ index c2982fe8..30e6965c 100644 --- a/mdbx.h++ +++ b/mdbx.h++ @@ -1,5 +1,5 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2020-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2020-2026 /// /// Donations are welcome to ETH `0xD104d8f8B2dC312aaD74899F83EBf3EEBDC1EA3A`. /// Всё будет хорошо! diff --git a/mdbx_chk.c b/mdbx_chk.c index dfe10c5d..84f0201d 100644 --- a/mdbx_chk.c +++ b/mdbx_chk.c @@ -1,5 +1,5 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/mdbx_copy.c b/mdbx_copy.c index d976d7f6..6aacb646 100644 --- a/mdbx_copy.c +++ b/mdbx_copy.c @@ -1,7 +1,7 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// mdbx_copy.c - memory-mapped database backup tool /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/mdbx_drop.c b/mdbx_drop.c index 23df9b73..50ecb9a7 100644 --- a/mdbx_drop.c +++ b/mdbx_drop.c @@ -1,7 +1,7 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2021-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2021-2026 /// /// mdbx_drop.c - memory-mapped database delete tool /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/mdbx_dump.c b/mdbx_dump.c index 1fa6857b..0c1a6f3f 100644 --- a/mdbx_dump.c +++ b/mdbx_dump.c @@ -1,7 +1,7 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// mdbx_dump.c - memory-mapped database dump tool /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/mdbx_load.c b/mdbx_load.c index b9e1abc3..5536661c 100644 --- a/mdbx_load.c +++ b/mdbx_load.c @@ -1,7 +1,7 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// mdbx_load.c - memory-mapped database load tool /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/mdbx_stat.c b/mdbx_stat.c index cc58438c..f7a0604d 100644 --- a/mdbx_stat.c +++ b/mdbx_stat.c @@ -1,7 +1,7 @@ /// \copyright SPDX-License-Identifier: Apache-2.0 /// \note Please refer to the COPYRIGHT file for explanations license change, /// credits and acknowledgments. -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 /// /// mdbx_stat.c - memory-mapped database status tool /// @@ -16,9 +16,9 @@ #define xMDBX_TOOLS /* Avoid using internal eASSERT() */ /// \copyright SPDX-License-Identifier: Apache-2.0 -/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2025 +/// \author Леонид Юрьев aka Leonid Yuriev \date 2015-2026 -#define MDBX_BUILD_SOURCERY f7f5123962e752f13134b4013b9332f1b311a5f0dd19f3d45ba4e65d806a3545_v0_14_1_215_g541e81ed +#define MDBX_BUILD_SOURCERY e30d838fb2509384f10339f050c97b34b790926488f78b959203d21608b421aa_v0_14_1_220_g0f8b288c #define LIBMDBX_INTERNALS #define MDBX_DEPRECATED diff --git a/ut_and_examples/CMakeLists.txt b/ut_and_examples/CMakeLists.txt new file mode 100644 index 00000000..60a4e916 --- /dev/null +++ b/ut_and_examples/CMakeLists.txt @@ -0,0 +1,18 @@ +# Copyright (c) 2020-2026 Леонид Юрьев aka Leonid Yuriev ############################################### +# SPDX-License-Identifier: Apache-2.0 +# +project(mdbx_ut_and_examples) + +add_executable(mdbx_example example-mdbx.c) +if(NOT DEFINED MDBX_LIBRARY) + set(MDBX_LIBRARY mdbx) +endif() +target_link_libraries(mdbx_example ${MDBX_LIBRARY}) + +if(CMAKE_CROSSCOMPILING AND NOT CMAKE_CROSSCOMPILING_EMULATOR) + message(WARNING "No emulator to run cross-compiled tests") + add_test(NAME fake_since_no_crosscompiling_emulator COMMAND ${CMAKE_COMMAND} -E echo + "No emulator to run cross-compiled tests") +else() + add_test(NAME example_c_api COMMAND mdbx_example) +endif() diff --git a/ut_and_examples/README.md b/ut_and_examples/README.md new file mode 100644 index 00000000..cdfff30d --- /dev/null +++ b/ut_and_examples/README.md @@ -0,0 +1,11 @@ +## Examples & Unit tests + +This set of examples will be updated, and most of the examples are also publicly available tests. + +### C API +The [`example-mdbx.c`](example-mdbx.c) is the example of using the C API. +However, it is strongly recommended to use the modern [C++ API](https://libmdbx.dqdkfa.ru/group__cxx__api.html), which requires less effort +and insures against many errors related to resource leaks. + +### Berkeley DB +If you have already used Berkeley DB, then it will be useful to make a line-by-line comparison of [`example-mdbx.c`](example-mdbx.c) and the [`sample-bdb.txt`](sample-bdb.txt) file. diff --git a/ut_and_examples/example-mdbx.c b/ut_and_examples/example-mdbx.c new file mode 100644 index 00000000..8308257d --- /dev/null +++ b/ut_and_examples/example-mdbx.c @@ -0,0 +1,167 @@ +/* The example of using the libmdbx C API. + * However, it is strongly recommended to use the modern C++ API, which requires less effort + * and insures against many errors related to resource leaks. + * + * If you have already used Berkeley DB, + * it will be useful to make a line-by-line comparison of this example and the sample-bdb.txt + */ + +/* + * Copyright 2015-2026 Leonid Yuriev . + * Copyright 2017 Ilya Shipitsin . + * Copyright 2012-2015 Howard Chu, Symas Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . + */ + +#if (defined(__MINGW__) || defined(__MINGW32__) || defined(__MINGW64__)) && !defined(__USE_MINGW_ANSI_STDIO) +#define __USE_MINGW_ANSI_STDIO 1 +#endif /* MinGW */ + +#include "mdbx.h" + +#include +#include +#include +#include + +int main(int argc, char *argv[]) { + (void)argc; + (void)argv; + + int rc; + MDBX_env *env = NULL; + MDBX_dbi dbi = 0; + MDBX_val key, data; + MDBX_txn *txn = NULL; + MDBX_cursor *cursor = NULL; + char sval[32]; + + printf("MDBX limits:\n"); +#if UINTPTR_MAX > 0xffffFFFFul || ULONG_MAX > 0xffffFFFFul + const double scale_factor = 1099511627776.0; + const char *const scale_unit = "TiB"; +#else + const double scale_factor = 1073741824.0; + const char *const scale_unit = "GiB"; +#endif + const size_t pagesize_min = mdbx_limits_pgsize_min(); + const size_t pagesize_max = mdbx_limits_pgsize_max(); + const size_t pagesize_default = mdbx_default_pagesize(); + + printf("\tPage size: a power of 2, minimum %zu, maximum %zu bytes," + " default %zu bytes.\n", + pagesize_min, pagesize_max, pagesize_default); + printf("\tKey size: minimum %zu, maximum ≈¼ pagesize (%zu bytes for default" + " %zuK pagesize, %zu bytes for %zuK pagesize).\n", + (size_t)0, mdbx_limits_keysize_max(-1, MDBX_DB_DEFAULTS), pagesize_default / 1024, + mdbx_limits_keysize_max(pagesize_max, MDBX_DB_DEFAULTS), pagesize_max / 1024); + printf("\tValue size: minimum %zu, maximum %zu (0x%08zX) bytes for maps," + " ≈¼ pagesize for multimaps (%zu bytes for default %zuK pagesize," + " %zu bytes for %zuK pagesize).\n", + (size_t)0, mdbx_limits_valsize_max(pagesize_min, MDBX_DB_DEFAULTS), + mdbx_limits_valsize_max(pagesize_min, MDBX_DB_DEFAULTS), mdbx_limits_valsize_max(-1, MDBX_DUPSORT), + pagesize_default / 1024, mdbx_limits_valsize_max(pagesize_max, MDBX_DUPSORT), pagesize_max / 1024); + printf("\tWrite transaction size: up to %zu (0x%zX) pages (%f %s for default " + "%zuK pagesize, %f %s for %zuK pagesize).\n", + mdbx_limits_txnsize_max(pagesize_min) / pagesize_min, mdbx_limits_txnsize_max(pagesize_min) / pagesize_min, + mdbx_limits_txnsize_max(-1) / scale_factor, scale_unit, pagesize_default / 1024, + mdbx_limits_txnsize_max(pagesize_max) / scale_factor, scale_unit, pagesize_max / 1024); + printf("\tDatabase size: up to %zu pages (%f %s for default %zuK " + "pagesize, %f %s for %zuK pagesize).\n", + mdbx_limits_dbsize_max(pagesize_min) / pagesize_min, mdbx_limits_dbsize_max(-1) / scale_factor, scale_unit, + pagesize_default / 1024, mdbx_limits_dbsize_max(pagesize_max) / scale_factor, scale_unit, pagesize_max / 1024); + printf("\tMaximum sub-databases: %u.\n", MDBX_MAX_DBI); + printf("-----\n"); + + rc = mdbx_env_create(&env); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_env_create: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + + /* This deletion is not necessary, but it has been added here for full reproducibility of the conditions when running + * this example again as a simplest test. */ + rc = mdbx_env_delete("./example-db", MDBX_ENV_JUST_DELETE); + if (rc != /* file was successfully deleted */ MDBX_SUCCESS && + rc != /* nothing has been done because the file is missing */ MDBX_RESULT_TRUE) { + fprintf(stderr, "mdbx_env_delete: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + + rc = mdbx_env_open(env, "./example-db", MDBX_NOSUBDIR | MDBX_LIFORECLAIM, 0664); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_env_open: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + + rc = mdbx_txn_begin(env, NULL, 0, &txn); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + rc = mdbx_dbi_open(txn, NULL, 0, &dbi); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_dbi_open: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + + key.iov_len = sizeof(int); + key.iov_base = sval; + data.iov_len = sizeof(sval); + data.iov_base = sval; + + snprintf(sval, sizeof(sval), "%03x %d foo bar", 32, 3141592); + rc = mdbx_put(txn, dbi, &key, &data, 0); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_put: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + rc = mdbx_txn_commit(txn); + if (rc) { + fprintf(stderr, "mdbx_txn_commit: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + txn = NULL; + + rc = mdbx_txn_begin(env, NULL, MDBX_TXN_RDONLY, &txn); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_txn_begin: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + rc = mdbx_cursor_open(txn, dbi, &cursor); + if (rc != MDBX_SUCCESS) { + fprintf(stderr, "mdbx_cursor_open: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } + + int found = 0; + while ((rc = mdbx_cursor_get(cursor, &key, &data, MDBX_NEXT)) == 0) { + printf("key: %p %.*s, data: %p %.*s\n", key.iov_base, (int)key.iov_len, (char *)key.iov_base, data.iov_base, + (int)data.iov_len, (char *)data.iov_base); + found += 1; + } + if (rc != MDBX_NOTFOUND || found == 0) { + fprintf(stderr, "mdbx_cursor_get: (%d) %s\n", rc, mdbx_strerror(rc)); + goto bailout; + } else { + rc = MDBX_SUCCESS; + } +bailout: + if (cursor) + mdbx_cursor_close(cursor); + if (txn) + mdbx_txn_abort(txn); + if (dbi) + mdbx_dbi_close(env, dbi); + if (env) + mdbx_env_close(env); + return (rc != MDBX_SUCCESS) ? EXIT_FAILURE : EXIT_SUCCESS; +}