diff options
author | George Hazan <ghazan@miranda.im> | 2020-04-25 11:57:29 +0300 |
---|---|---|
committer | George Hazan <ghazan@miranda.im> | 2020-04-25 11:57:29 +0300 |
commit | a4b13dbed9ff21c3b992ee21ba708730186296e4 (patch) | |
tree | 41d97e2c924929a9da7d740aa3353598ea9cc64d /libs/libmdbx | |
parent | c0f6475d8f49a0d97428c674cc3ec938fe78213b (diff) |
libmdbx: merge with 0.7 final version
Diffstat (limited to 'libs/libmdbx')
-rw-r--r-- | libs/libmdbx/libmdbx.vcxproj | 11 | ||||
-rw-r--r-- | libs/libmdbx/src/CMakeLists.dist-minimal | 308 | ||||
-rw-r--r-- | libs/libmdbx/src/CMakeLists.txt | 613 | ||||
-rw-r--r-- | libs/libmdbx/src/GNUmakefile | 101 | ||||
-rw-r--r-- | libs/libmdbx/src/README.md | 54 | ||||
-rw-r--r-- | libs/libmdbx/src/appveyor.yml | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/cmake/compiler.cmake | 106 | ||||
-rw-r--r-- | libs/libmdbx/src/cmake/utils.cmake | 47 | ||||
-rw-r--r-- | libs/libmdbx/src/config.h (renamed from libs/libmdbx/src/src/elements/config.h) | 18 | ||||
-rw-r--r-- | libs/libmdbx/src/mdbx.h | 131 | ||||
-rw-r--r-- | libs/libmdbx/src/src/CMakeLists.txt | 263 | ||||
-rw-r--r-- | libs/libmdbx/src/src/alloy.c | 14 | ||||
-rw-r--r-- | libs/libmdbx/src/src/config.h.in (renamed from libs/libmdbx/src/src/elements/config.h.in) | 8 | ||||
-rw-r--r-- | libs/libmdbx/src/src/core.c (renamed from libs/libmdbx/src/src/elements/core.c) | 385 | ||||
-rw-r--r-- | libs/libmdbx/src/src/debug_begin.h (renamed from libs/libmdbx/src/src/elements/debug_begin.h) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/debug_end.h (renamed from libs/libmdbx/src/src/elements/debug_end.h) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/defs.h (renamed from libs/libmdbx/src/src/elements/defs.h) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/internals.h (renamed from libs/libmdbx/src/src/elements/internals.h) | 47 | ||||
-rw-r--r-- | libs/libmdbx/src/src/lck-posix.c (renamed from libs/libmdbx/src/src/elements/lck-posix.c) | 27 | ||||
-rw-r--r-- | libs/libmdbx/src/src/lck-windows.c (renamed from libs/libmdbx/src/src/elements/lck-windows.c) | 4 | ||||
-rw-r--r-- | libs/libmdbx/src/src/man1/mdbx_chk.1 | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/man1/mdbx_copy.1 | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/man1/mdbx_dump.1 | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/man1/mdbx_load.1 | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/man1/mdbx_stat.1 | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/mdbx_chk.c (renamed from libs/libmdbx/src/src/tools/mdbx_chk.c) | 8 | ||||
-rw-r--r-- | libs/libmdbx/src/src/mdbx_copy.c (renamed from libs/libmdbx/src/src/tools/mdbx_copy.c) | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/mdbx_dump.c (renamed from libs/libmdbx/src/src/tools/mdbx_dump.c) | 2 | ||||
-rw-r--r-- | libs/libmdbx/src/src/mdbx_load.c (renamed from libs/libmdbx/src/src/tools/mdbx_load.c) | 5 | ||||
-rw-r--r-- | libs/libmdbx/src/src/mdbx_stat.c (renamed from libs/libmdbx/src/src/tools/mdbx_stat.c) | 8 | ||||
-rw-r--r-- | libs/libmdbx/src/src/ntdll.def (renamed from libs/libmdbx/src/src/elements/ntdll.def) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/options.h (renamed from libs/libmdbx/src/src/elements/options.h) | 6 | ||||
-rw-r--r-- | libs/libmdbx/src/src/osal.c (renamed from libs/libmdbx/src/src/elements/osal.c) | 33 | ||||
-rw-r--r-- | libs/libmdbx/src/src/osal.h (renamed from libs/libmdbx/src/src/elements/osal.h) | 27 | ||||
-rw-r--r-- | libs/libmdbx/src/src/tools/CMakeLists.txt | 60 | ||||
-rw-r--r-- | libs/libmdbx/src/src/version.c.in (renamed from libs/libmdbx/src/src/elements/version.c.in) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/wingetopt.c (renamed from libs/libmdbx/src/src/tools/wingetopt.c) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/src/wingetopt.h (renamed from libs/libmdbx/src/src/tools/wingetopt.h) | 0 | ||||
-rw-r--r-- | libs/libmdbx/src/test/CMakeLists.txt | 23 | ||||
-rw-r--r-- | libs/libmdbx/src/test/base.h | 6 | ||||
-rw-r--r-- | libs/libmdbx/src/test/osal-unix.cc | 4 | ||||
-rw-r--r-- | libs/libmdbx/src/test/osal-windows.cc | 12 | ||||
-rw-r--r-- | libs/libmdbx/src/test/pcrf/CMakeLists.txt | 5 | ||||
-rw-r--r-- | libs/libmdbx/src/version.c (renamed from libs/libmdbx/src/src/elements/version.c) | 12 |
44 files changed, 1181 insertions, 1181 deletions
diff --git a/libs/libmdbx/libmdbx.vcxproj b/libs/libmdbx/libmdbx.vcxproj index e7d489ca88..6f690abef4 100644 --- a/libs/libmdbx/libmdbx.vcxproj +++ b/libs/libmdbx/libmdbx.vcxproj @@ -26,23 +26,20 @@ <Import Project="$(ProjectDir)..\..\build\vc.common\lib.props" /> <ItemDefinitionGroup> <ClCompile> - <PreprocessorDefinitions>MDBX_CONFIG_MANUAL_TLS_CALLBACK=1;MDBX_DEBUG=1;LIBMDBX_EXPORTS;%(PreprocessorDefinitions)</PreprocessorDefinitions> + <PreprocessorDefinitions>MDBX_CONFIG_MANUAL_TLS_CALLBACK=1;MDBX_DEBUG=1;LIBMDBX_EXPORTS;__STDC_FORMAT_MACROS=1;__STDC_LIMIT_MACROS=1;__STDC_CONSTANT_MACROS=1;_HAS_EXCEPTIONS=1;MDBX_CONFIG_H=1;%(PreprocessorDefinitions)</PreprocessorDefinitions> </ClCompile> <Link> <AdditionalDependencies>ntdll.lib;%(AdditionalDependencies)</AdditionalDependencies> </Link> </ItemDefinitionGroup> <ItemGroup> - <ClCompile Include="src\src\elements\lck-windows.c"> + <ClCompile Include="src\src\lck-windows.c"> <PrecompiledHeader>NotUsing</PrecompiledHeader> </ClCompile> - <ClCompile Include="src\src\elements\core.c"> + <ClCompile Include="src\src\core.c"> <PrecompiledHeader>NotUsing</PrecompiledHeader> </ClCompile> - <ClCompile Include="src\src\elements\osal.c"> - <PrecompiledHeader>NotUsing</PrecompiledHeader> - </ClCompile> - <ClCompile Include="src\src\elements\version.c"> + <ClCompile Include="src\src\osal.c"> <PrecompiledHeader>NotUsing</PrecompiledHeader> </ClCompile> </ItemGroup> diff --git a/libs/libmdbx/src/CMakeLists.dist-minimal b/libs/libmdbx/src/CMakeLists.dist-minimal deleted file mode 100644 index fdcd41d308..0000000000 --- a/libs/libmdbx/src/CMakeLists.dist-minimal +++ /dev/null @@ -1,308 +0,0 @@ -## -## This is the minimal template for CMakeList.txt which could be used -## to build libmdbx from the "amalgamated form" of libmdbx's source code. -## -## The amalgamated form is intended to embedding libmdbx in other projects -## in cases when using as git-submodule is not acceptable or inconveniently. -## -## The amalgamated form could be generated from full git repository -## on Linux just by `make dist`. -## - -## -## Copyright 2020 Leonid Yuriev <leo@yuriev.ru> -## and other libmdbx authors: please see AUTHORS file. -## 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 -## <http://www.OpenLDAP.org/license.html>. -## - -## -## libmdbx = { Revised and extended descendant of Symas LMDB. } -## Please see README.md at https://github.com/erthink/libmdbx -## -## Libmdbx is superior to LMDB in terms of features and reliability, -## not inferior in performance. libmdbx works on Linux, FreeBSD, MacOS X -## and other systems compliant with POSIX.1-2008, but also support Windows -## as a complementary platform. -## -## 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. -## -## The Future will (be) Positive. Всё будет хорошо. -## - -cmake_minimum_required(VERSION 3.8.2) -cmake_policy(PUSH) -cmake_policy(VERSION 3.8.2) -if(NOT CMAKE_VERSION VERSION_LESS 3.9) - cmake_policy(SET CMP0069 NEW) -endif() -if(NOT CMAKE_VERSION VERSION_LESS 3.12) - cmake_policy(SET CMP0075 NEW) -endif() -if(NOT CMAKE_VERSION VERSION_LESS 3.13) - cmake_policy(SET CMP0077 NEW) -endif() - -if(DEFINED PROJECT_NAME) - set(SUBPROJECT ON) - set(NOT_SUBPROJECT OFF) -else() - set(SUBPROJECT OFF) - set(NOT_SUBPROJECT ON) - project(libmdbx C CXX) -endif() - -find_package(Threads REQUIRED) - -if(NOT CMAKE_BUILD_TYPE) - set(CMAKE_BUILD_TYPE MinSizeRel CACHE STRING - "Choose the type of build, options are: Debug Release RelWithDebInfo MinSizeRel." - FORCE) -endif() - -list(FIND CMAKE_C_COMPILE_FEATURES c_std_11 HAS_C11) -if(NOT HAS_C11 LESS 0) - set(MDBX_C_STANDARD 11) -else() - set(MDBX_C_STANDARD 99) -endif() -message(STATUS "Use C${MDBX_C_STANDARD} for libmdbx") - -# not supported by this (minimal) script -add_definitions(-DMDBX_AVOID_CRT=0) - -# provide build timestamp -string(TIMESTAMP MDBX_BUILD_TIMESTAMP UTC) -add_definitions(-DMDBX_BUILD_TIMESTAMP="${MDBX_BUILD_TIMESTAMP}") - -# provide compiler info -execute_process(COMMAND sh -c "${CMAKE_C_COMPILER} --version | head -1" - OUTPUT_VARIABLE MDBX_BUILD_COMPILER - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - RESULT_VARIABLE rc) -if(rc OR NOT MDBX_BUILD_COMPILER) - string(STRIP "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}" MDBX_BUILD_COMPILER) -endif() -add_definitions(-DMDBX_BUILD_COMPILER="${MDBX_BUILD_COMPILER}") - -# provide cpu/arch-system pair -if(CMAKE_C_COMPILER_TARGET) - set(MDBX_BUILD_TARGET "${CMAKE_C_COMPILER_TARGET}") -elseif(CMAKE_C_PLATFORM_ID AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) - string(STRIP "${CMAKE_C_PLATFORM_ID}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_LIBRARY_ARCHITECTURE) - string(STRIP "${CMAKE_LIBRARY_ARCHITECTURE}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_GENERATOR_PLATFORM AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) - string(STRIP "${CMAKE_GENERATOR_PLATFORM}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_SYSTEM_ARCH) - string(STRIP "${CMAKE_SYSTEM_ARCH}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -else() - string(STRIP "${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -endif() -add_definitions(-DMDBX_BUILD_TARGET="${MDBX_BUILD_TARGET}") - -# provide build target-config -if(CMAKE_CONFIGURATION_TYPES) - add_definitions(-DMDBX_BUILD_CONFIG="$<CONFIG>") -else() - add_definitions(-DMDBX_BUILD_CONFIG="${CMAKE_BUILD_TYPE}") -endif() - -# provide build cflags -set(MDBX_BUILD_FLAGS "") -list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_FLAGS}) -list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_DEFINES}) -if(CMAKE_CONFIGURATION_TYPES) - add_definitions(-DMDBX_BUILD_FLAGS_CONFIG="$<$<CONFIG:Debug>:${CMAKE_C_FLAGS_DEBUG} ${CMAKE_C_DEFINES_DEBUG}>$<$<CONFIG:Release>:${CMAKE_C_FLAGS_RELEASE} ${CMAKE_C_DEFINES_RELEASE}>$<$<CONFIG:RelWithDebInfo>:${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CMAKE_C_DEFINES_RELWITHDEBINFO}>$<$<CONFIG:MinSizeRel>:${CMAKE_C_FLAGS_MINSIZEREL} ${CMAKE_C_DEFINES_MINSIZEREL}>") -else() - string(TOUPPER ${CMAKE_BUILD_TYPE} CMAKE_BUILD_TYPE_UPPERCASE) - list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}) - list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_DEFINES_${CMAKE_BUILD_TYPE_UPPERCASE}}) -endif() -list(REMOVE_DUPLICATES MDBX_BUILD_FLAGS) -string(REPLACE ";" " " MDBX_BUILD_FLAGS "${MDBX_BUILD_FLAGS}") -add_definitions(-DMDBX_BUILD_FLAGS="${MDBX_BUILD_FLAGS}") - -# shared library -if(NOT DEFINED MDBX_BUILD_SHARED_LIBRARY) - if(DEFINED BUILD_SHARED_LIBS) - option(MDBX_BUILD_SHARED_LIBRARY "Build libmdbx as shared library (DLL)" ${BUILD_SHARED_LIBS}) - else() - option(MDBX_BUILD_SHARED_LIBRARY "Build libmdbx as shared library (DLL)" ON) - endif() -endif() -if(MDBX_BUILD_SHARED_LIBRARY) - add_library(mdbx SHARED mdbx.c mdbx.h) - set_target_properties(mdbx PROPERTIES - C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON - PUBLIC_HEADER mdbx.h) - target_compile_definitions(mdbx PRIVATE LIBMDBX_EXPORTS INTERFACE LIBMDBX_IMPORTS) - if(DEFINED INTERPROCEDURAL_OPTIMIZATION) - set_target_properties(mdbx PROPERTIES - INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}>) - endif() - target_link_libraries(mdbx PRIVATE ${CMAKE_THREAD_LIBS_INIT}) - if(WIN32) - target_link_libraries(mdbx PRIVATE ntdll.lib) - endif() - if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Solaris") - target_link_libraries(mdbx PRIVATE kstat) - endif() -endif() - -# static library used for tools, to avoid rpath/dll-path troubles -add_library(mdbx-static STATIC mdbx.c mdbx.h) -set_target_properties(mdbx-static PROPERTIES - C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON - PUBLIC_HEADER mdbx.h) -target_link_libraries(mdbx-static INTERFACE ${CMAKE_THREAD_LIBS_INIT}) -if(DEFINED INTERPROCEDURAL_OPTIMIZATION) - set_target_properties(mdbx-static PROPERTIES - INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}>) -endif() -if(WIN32) - target_link_libraries(mdbx-static INTERFACE ntdll.lib) -endif() -if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Solaris") - target_link_libraries(mdbx-static INTERFACE kstat) -endif() - -# mdbx-tools -foreach(TOOL mdbx_chk mdbx_copy mdbx_stat mdbx_dump mdbx_load) - add_executable(${TOOL} ${TOOL}.c) - set_target_properties(${TOOL} PROPERTIES - C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON) - if(DEFINED INTERPROCEDURAL_OPTIMIZATION) - set_target_properties(${TOOL} PROPERTIES - INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}>) - endif() - target_link_libraries(${TOOL} mdbx-static) -endforeach() - -# installation -if(MDBX_BUILD_SHARED_LIBRARY) - if(CMAKE_VERSION VERSION_LESS 3.12) - install(TARGETS mdbx EXPORT libmdbx - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) - else() - install(TARGETS mdbx EXPORT libmdbx - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - NAMELINK_COMPONENT devel - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) - endif() -endif() - -if(CMAKE_VERSION VERSION_LESS 3.12) - install(TARGETS mdbx-static EXPORT libmdbx EXCLUDE_FROM_ALL - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) -else() - install(TARGETS mdbx-static EXPORT libmdbx EXCLUDE_FROM_ALL - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - NAMELINK_COMPONENT devel - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) -endif() - -install( - TARGETS - mdbx_chk - mdbx_stat - mdbx_copy - mdbx_dump - mdbx_load - RUNTIME - DESTINATION bin - COMPONENT runtime) - -install( - FILES - man1/mdbx_chk.1 - man1/mdbx_stat.1 - man1/mdbx_copy.1 - man1/mdbx_dump.1 - man1/mdbx_load.1 - DESTINATION man/man1 - COMPONENT doc) - -cmake_policy(POP) diff --git a/libs/libmdbx/src/CMakeLists.txt b/libs/libmdbx/src/CMakeLists.txt index e67cdbe92a..a17bd35ab6 100644 --- a/libs/libmdbx/src/CMakeLists.txt +++ b/libs/libmdbx/src/CMakeLists.txt @@ -35,6 +35,7 @@ ## cmake_minimum_required(VERSION 3.8.2) + cmake_policy(PUSH) cmake_policy(VERSION 3.8.2) if(NOT CMAKE_VERSION VERSION_LESS 3.13) @@ -51,17 +52,42 @@ else() set(CMAKE_INTERPROCEDURAL_OPTIMIZATION_AVAILABLE FALSE) endif() +if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/test/CMakeLists.txt" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/core.c" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/alloy.c" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/config.h.in" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/version.c.in" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/man1" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/src/mdbx_chk.c") + set(MDBX_AMALGAMATED_SOURCE FALSE) + find_program(GIT git) + if(NOT GIT) + message(SEND_ERROR "Git command-line tool not found") + endif() + set(MDBX_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}/src") +elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx.c" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/config.h.in" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/man1" AND + EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/mdbx_chk.c") + set(MDBX_AMALGAMATED_SOURCE TRUE) + set(MDBX_SOURCE_DIR "${CMAKE_CURRENT_SOURCE_DIR}") +else() + message(FATAL_ERROR "Please use libmdbx as a git-submodule or the amalgamated source code") +endif() + if(DEFINED PROJECT_NAME) set(SUBPROJECT ON) set(NOT_SUBPROJECT OFF) - if(NOT DEFINED BUILD_TESTING) + if(NOT MDBX_AMALGAMATED_SOURCE AND NOT DEFINED BUILD_TESTING) set(BUILD_TESTING OFF) endif() else() set(SUBPROJECT OFF) set(NOT_SUBPROJECT ON) project(libmdbx C CXX) - if(NOT DEFINED BUILD_TESTING) + if(NOT MDBX_AMALGAMATED_SOURCE AND NOT DEFINED BUILD_TESTING) set(BUILD_TESTING ON) endif() endif() @@ -72,17 +98,19 @@ if(NOT CMAKE_BUILD_TYPE) FORCE) endif() -macro(add_mdbx_option NAME DESCRIPTION DEFAULT) - list(APPEND MDBX_BUILD_OPTIONS ${NAME}) - if(NOT ${DEFAULT} STREQUAL "AUTO") - option(${NAME} "${DESCRIPTION}" ${DEFAULT}) - elseif(NOT DEFINED ${NAME}) - set(${NAME}_AUTO ON) - endif() -endmacro() +if(NOT_SUBPROJECT AND (CMAKE_CROSSCOMPILING OR IOS)) + set(CMAKE_TRY_COMPILE_TARGET_TYPE STATIC_LIBRARY) +endif() -# only for compatibility testing -# set(CMAKE_CXX_STANDARD 14) +if(IOS) + set(MDBX_BUILD_TOOLS_DEFAULT OFF) + if(NOT_SUBPROJECT) + cmake_policy(SET CMP0006 OLD) + set(CMAKE_XCODE_ATTRIBUTE_CODE_SIGNING_ALLOWED "NO") + endif() +else() + set(MDBX_BUILD_TOOLS_DEFAULT ON) +endif() if(NOT "$ENV{TEAMCITY_PROCESS_FLOW_ID}" STREQUAL "") set(CI TEAMCITY) @@ -113,19 +141,8 @@ set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${MDBX_OUTPUT_DIR}) set(CMAKE_PDB_OUTPUT_DIRECTORY ${MDBX_OUTPUT_DIR}) set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${MDBX_OUTPUT_DIR}) -include(CheckLibraryExists) -include(CheckIncludeFiles) -include(CheckCCompilerFlag) -include(CheckSymbolExists) -include(CheckCSourceRuns) -include(CheckCXXSourceRuns) -include(CheckCSourceCompiles) -include(CheckCXXSourceCompiles) -include(TestBigEndian) include(CheckFunctionExists) include(FindPackageMessage) -include(CheckStructHasMember) -include(CMakeDependentOption) include(GNUInstallDirs) if(CMAKE_C_COMPILER_ID STREQUAL "MSVC" AND MSVC_VERSION LESS 1900) @@ -145,15 +162,6 @@ include(cmake/utils.cmake) include(cmake/compiler.cmake) include(cmake/profile.cmake) -find_program(ECHO echo) -find_program(CAT cat) -find_program(GIT git) -find_program(LD ld) - -# CHECK_INCLUDE_FILES(unistd.h HAVE_UNISTD_H) -# CHECK_INCLUDE_FILES(sys/uio.h HAVE_SYS_UIO_H) -# CHECK_INCLUDE_FILES(sys/stat.h HAVE_SYS_STAT_H) - CHECK_FUNCTION_EXISTS(pow NOT_NEED_LIBM) if(NOT_NEED_LIBM) set(LIB_MATH "") @@ -222,57 +230,56 @@ else() set(LTO_ENABLED FALSE) endif() - find_program(VALGRIND valgrind) - if(VALGRIND) - # LY: cmake is ugly and nasty. - # - therefore memcheck-options should be defined before including ctest; - # - otherwise ctest may ignore it. - set(MEMORYCHECK_SUPPRESSIONS_FILE - "${PROJECT_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 --error-exitcode=42 --error-markers=@ --errors-for-leak-kinds=definite --fair-sched=yes --suppressions=${MEMORYCHECK_SUPPRESSIONS_FILE}" - CACHE STRING "Valgrind options" FORCE) - set(VALGRIND_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS}" CACHE STRING "Valgrind options" FORCE) - endif() + if(NOT MDBX_AMALGAMATED_SOURCE) + find_program(VALGRIND valgrind) + if(VALGRIND) + # 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 --error-exitcode=42 --error-markers=@ --errors-for-leak-kinds=definite --fair-sched=yes --suppressions=${MEMORYCHECK_SUPPRESSIONS_FILE}" + CACHE STRING "Valgrind options" FORCE) + set(VALGRIND_COMMAND_OPTIONS "${MEMORYCHECK_COMMAND_OPTIONS}" CACHE STRING "Valgrind options" FORCE) + endif() - # - # Enable 'make tags' target. - find_program(CTAGS ctags) - if(CTAGS) - add_custom_target(tags COMMAND ${CTAGS} -R -f tags - WORKING_DIRECTORY ${CMAKE_SOURCE_DIR}) - add_custom_target(ctags DEPENDS tags) - endif(CTAGS) - - # - # Enable 'make reformat' target. - find_program(CLANG_FORMAT - NAMES clang-format-6.0 clang-format-5.0 clang-format-4.0 - clang-format-3.9 clang-format-3.8 clang-format-3.7 clang-format) - if(CLANG_FORMAT AND UNIX) - 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() + # 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) + + # Enable 'make reformat' target. + find_program(CLANG_FORMAT + NAMES clang-format-11.0 clang-format-10.0 clang-format-9.0 clang-format-8.0 clang-format) + if(CLANG_FORMAT AND UNIX) + 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_CURRENT_SOURCE_DIR}) + endif() - if(NOT "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}") - add_custom_target(distclean) - add_custom_command(TARGET distclean - 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 - 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() + if(NOT "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}") + add_custom_target(distclean) + add_custom_command(TARGET distclean + 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 + 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) setup_compile_flags() endif(SUBPROJECT) @@ -285,6 +292,66 @@ else() endif() message(STATUS "Use C${MDBX_C_STANDARD} for libmdbx") +if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows" AND EXISTS "${MDBX_SOURCE_DIR}/ntdll.def") + if(MSVC) + if(NOT MSVC_LIB_EXE) + # Find lib.exe + get_filename_component(CL_NAME ${CMAKE_C_COMPILER} NAME) + string(REPLACE cl.exe lib.exe MSVC_LIB_EXE ${CL_NAME}) + find_program(MSVC_LIB_EXE ${MSVC_LIB_EXE}) + endif() + if(MSVC_LIB_EXE) + message(STATUS "Found MSVC's lib tool: ${MSVC_LIB_EXE}") + set(MDBX_NTDLL_EXTRA_IMPLIB "${CMAKE_CURRENT_BINARY_DIR}/mdbx_ntdll_extra.lib") + add_custom_command(OUTPUT "${MDBX_NTDLL_EXTRA_IMPLIB}" + COMMENT "Create extra-import-library for ntdll.dll" + MAIN_DEPENDENCY "${MDBX_SOURCE_DIR}/ntdll.def" + COMMAND ${MSVC_LIB_EXE} /def:"${MDBX_SOURCE_DIR}/ntdll.def" /out:"${MDBX_NTDLL_EXTRA_IMPLIB}" ${INITIAL_CMAKE_STATIC_LINKER_FLAGS}) + else() + message(WARNING "MSVC's lib tool not found") + endif() + elseif(MINGW OR MINGW64) + if(NOT DLLTOOL) + # Find dlltool + get_filename_component(GCC_NAME ${CMAKE_C_COMPILER} NAME) + string(REPLACE gcc dlltool DLLTOOL_NAME ${GCC_NAME}) + find_program(DLLTOOL NAMES ${DLLTOOL_NAME}) + endif() + if(DLLTOOL) + message(STATUS "Found dlltool: ${DLLTOOL}") + set(MDBX_NTDLL_EXTRA_IMPLIB "${CMAKE_CURRENT_BINARY_DIR}/mdbx_ntdll_extra.a") + add_custom_command(OUTPUT "${MDBX_NTDLL_EXTRA_IMPLIB}" + COMMENT "Create extra-import-library for ntdll.dll" + MAIN_DEPENDENCY "${MDBX_SOURCE_DIR}/ntdll.def" + COMMAND ${DLLTOOL} -d "${MDBX_SOURCE_DIR}/ntdll.def" -l "${MDBX_NTDLL_EXTRA_IMPLIB}") + else() + message(WARNING "dlltool not found") + endif() + endif() + + if(MDBX_NTDLL_EXTRA_IMPLIB) + # LY: Sometimes CMake requires a nightmarish magic for simple things. + # 1) create a target out of the library compilation result + add_custom_target(ntdll_extra_target DEPENDS "${MDBX_NTDLL_EXTRA_IMPLIB}") + # 2) create an library target out of the library compilation result + add_library(ntdll_extra STATIC IMPORTED GLOBAL) + add_dependencies(ntdll_extra ntdll_extra_target) + # 3) specify where the library is (and where to find the headers) + set_target_properties(ntdll_extra + PROPERTIES + IMPORTED_LOCATION "${MDBX_NTDLL_EXTRA_IMPLIB}") + endif() +endif() + +macro(add_mdbx_option NAME DESCRIPTION DEFAULT) + list(APPEND MDBX_BUILD_OPTIONS ${NAME}) + if(NOT ${DEFAULT} STREQUAL "AUTO") + option(${NAME} "${DESCRIPTION}" ${DEFAULT}) + elseif(NOT DEFINED ${NAME}) + set(${NAME}_AUTO ON) + endif() +endmacro() + ################################################################################ ################################################################################ # @@ -297,42 +364,400 @@ message(STATUS "Use C${MDBX_C_STANDARD} for libmdbx") # set(MDBX_BUILD_OPTIONS ENABLE_ASAN MDBX_USE_VALGRIND ENABLE_GPROF ENABLE_GCOV) +add_mdbx_option(MDBX_INSTALL_STATIC "Build and install libmdbx for static linking" OFF) add_mdbx_option(MDBX_BUILD_SHARED_LIBRARY "Build libmdbx as shared library (DLL)" ${BUILD_SHARED_LIBS}) -add_mdbx_option(MDBX_ALLOY_BUILD "Build MDBX library as single object file" ON) +add_mdbx_option(MDBX_BUILD_TOOLS "Build MDBX tools (mdbx_chk/stat/dump/load/copy)" ${MDBX_BUILD_TOOLS_DEFAULT}) add_mdbx_option(MDBX_TXN_CHECKOWNER "Checking transaction matches the calling thread inside libmdbx's API" ON) add_mdbx_option(MDBX_TXN_CHECKPID "Paranoid checking PID inside libmdbx's API" AUTO) mark_as_advanced(MDBX_TXN_CHECKPID) if(${CMAKE_SYSTEM_NAME} STREQUAL "Linux") - add_mdbx_option(MDBX_DISABLE_GNU_SOURCE "Don't use nonstandard GNU/Linux extension functions" OFF) + add_mdbx_option(MDBX_DISABLE_GNU_SOURCE "Don't use GNU/Linux libc extensions" OFF) mark_as_advanced(MDBX_DISABLE_GNU_SOURCE) endif() -if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") +if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin" OR IOS) add_mdbx_option(MDBX_OSX_SPEED_INSTEADOF_DURABILITY "Disable use fcntl(F_FULLFSYNC) in favor of speed" OFF) mark_as_advanced(MDBX_OSX_SPEED_INSTEADOF_DURABILITY) endif() if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - add_mdbx_option(MDBX_AVOID_CRT "Avoid dependence from MSVC CRT" ${NOT_SUBPROJECT}) - if(NOT MDBX_BUILD_SHARED_LIBRARY) - add_mdbx_option(MDBX_CONFIG_MANUAL_TLS_CALLBACK - "Provide mdbx_dll_handler() for manual initialization" OFF) - mark_as_advanced(MDBX_CONFIG_MANUAL_TLS_CALLBACK) + if(MDBX_NTDLL_EXTRA_IMPLIB) + add_mdbx_option(MDBX_AVOID_CRT "Avoid dependence from MSVC CRT and use ntdll.dll instead" ${NOT_SUBPROJECT}) endif() + add_mdbx_option(MDBX_CONFIG_MANUAL_TLS_CALLBACK + "Provide mdbx_dll_handler() for manual initialization" OFF) + mark_as_advanced(MDBX_CONFIG_MANUAL_TLS_CALLBACK) else() add_mdbx_option(MDBX_USE_OFDLOCKS "Use Open file description locks (aka OFD locks, non-POSIX)" AUTO) mark_as_advanced(MDBX_USE_OFDLOCKS) endif() add_mdbx_option(MDBX_LOCKING "Locking method (Win32=-1, SysV=5, POSIX=1988, POSIX=2001, POSIX=2008, Futexes=1995)" AUTO) mark_as_advanced(MDBX_LOCKING) -add_mdbx_option(MDBX_TRUST_RTC "Does a system have battery-backed Real-Time Clock or just a fake." AUTO) +add_mdbx_option(MDBX_TRUST_RTC "Does a system have battery-backed Real-Time Clock or just a fake" AUTO) mark_as_advanced(MDBX_TRUST_RTC) -option(MDBX_ENABLE_TESTS "Build MDBX tests." ${BUILD_TESTING}) -option(MDBX_FORCE_ASSERTIONS "Force enable assertion checking." OFF) +option(MDBX_FORCE_ASSERTIONS "Force enable assertion checking" OFF) + +if(NOT MDBX_AMALGAMATED_SOURCE) + add_mdbx_option(MDBX_ALLOY_BUILD "Build MDBX library through single/alloyed object file" ON) + option(MDBX_ENABLE_TESTS "Build MDBX tests" ${BUILD_TESTING}) +endif(NOT MDBX_AMALGAMATED_SOURCE) + +if((MDBX_BUILD_TOOLS OR MDBX_ENABLE_TESTS) AND MDBX_BUILD_SHARED_LIBRARY) + add_mdbx_option(MDBX_LINK_TOOLS_NONSTATIC "Link MDBX tools with non-static libmdbx" OFF) +else() + unset(MDBX_LINK_TOOLS_NONSTATIC CACHE) +endif() ################################################################################ ################################################################################ -add_subdirectory(src) -if(MDBX_ENABLE_TESTS) +# Get version +fetch_version(MDBX "${CMAKE_CURRENT_SOURCE_DIR}/VERSION" FALSE) +message(STATUS "libmdbx version is ${MDBX_VERSION}") + +# sources list +set(LIBMDBX_SOURCES mdbx.h "${CMAKE_CURRENT_BINARY_DIR}/config.h") +if(MDBX_AMALGAMATED_SOURCE) + list(APPEND LIBMDBX_SOURCES mdbx.c) +else() + # generate version file + configure_file("${MDBX_SOURCE_DIR}/version.c.in" + "${CMAKE_CURRENT_BINARY_DIR}/version.c" ESCAPE_QUOTES) + file(SHA256 "${CMAKE_CURRENT_BINARY_DIR}/version.c" MDBX_SOURCERY_DIGEST) + string(MAKE_C_IDENTIFIER "${MDBX_GIT_DESCRIBE}" MDBX_SOURCERY_SUFFIX) + set(MDBX_BUILD_SOURCERY "${MDBX_SOURCERY_DIGEST}_${MDBX_SOURCERY_SUFFIX}") + + if(MDBX_ALLOY_BUILD) + list(APPEND LIBMDBX_SOURCES ${MDBX_SOURCE_DIR}/alloy.c) + include_directories("${MDBX_SOURCE_DIR}" "${CMAKE_CURRENT_BINARY_DIR}") + else() + list(APPEND LIBMDBX_SOURCES + "${CMAKE_CURRENT_BINARY_DIR}/version.c" + "${MDBX_SOURCE_DIR}/options.h" "${MDBX_SOURCE_DIR}/defs.h" + "${MDBX_SOURCE_DIR}/internals.h" "${MDBX_SOURCE_DIR}/osal.h" + "${MDBX_SOURCE_DIR}/core.c" "${MDBX_SOURCE_DIR}/osal.c" + "${MDBX_SOURCE_DIR}/lck-posix.c" "${MDBX_SOURCE_DIR}/lck-windows.c") + include_directories("${MDBX_SOURCE_DIR}") + endif() +endif(MDBX_AMALGAMATED_SOURCE) + +macro(target_setup_options TARGET) + if(DEFINED INTERPROCEDURAL_OPTIMIZATION) + set_target_properties(${TARGET} PROPERTIES + INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}>) + endif() + if(CC_HAS_FASTMATH) + target_compile_options(${TARGET} PRIVATE "-ffast-math") + endif() + if(CC_HAS_VISIBILITY) + target_compile_options(${TARGET} PRIVATE "-fvisibility=hidden") + endif() + if(BUILD_FOR_NATIVE_CPU AND CC_HAS_ARCH_NATIVE) + target_compile_options(${TARGET} PUBLIC "-march=native") + endif() +endmacro() + +macro(libmdbx_setup_libs TARGET MODE) + target_link_libraries(${TARGET} ${MODE} ${CMAKE_THREAD_LIBS_INIT}) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + target_link_libraries(${TARGET} ${MODE} ntdll.lib) + if(MDBX_NTDLL_EXTRA_IMPLIB) + target_link_libraries(${TARGET} ${MODE} ntdll_extra) + endif() + elseif(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Solaris") + target_link_libraries(${TARGET} ${MODE} kstat) + elseif(${CMAKE_SYSTEM_NAME} STREQUAL "Android") + target_link_libraries(${TARGET} ${MODE} log) + endif() +endmacro() + +# build static library +if(MDBX_INSTALL_STATIC) + add_library(mdbx-static STATIC ${LIBMDBX_SOURCES}) +else() + add_library(mdbx-static STATIC EXCLUDE_FROM_ALL ${LIBMDBX_SOURCES}) +endif() +set_target_properties(mdbx-static PROPERTIES + C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON + PUBLIC_HEADER mdbx.h) +target_compile_definitions(mdbx-static PRIVATE MDBX_BUILD_SHARED_LIBRARY=0) +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) +else() + set_target_properties(mdbx-static PROPERTIES OUTPUT_NAME mdbx) +endif() + +################################################################################ + +# build shared library +if(MDBX_BUILD_SHARED_LIBRARY) + add_library(mdbx SHARED ${LIBMDBX_SOURCES}) + set_target_properties(mdbx PROPERTIES + C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON + PUBLIC_HEADER mdbx.h) + target_compile_definitions(mdbx PRIVATE LIBMDBX_EXPORTS MDBX_BUILD_SHARED_LIBRARY=1 INTERFACE LIBMDBX_IMPORTS) + target_setup_options(mdbx) + libmdbx_setup_libs(mdbx PRIVATE) + if(CC_HAS_VISIBILITY AND (LTO_ENABLED OR INTERPROCEDURAL_OPTIMIZATION)) + set_target_properties(mdbx PROPERTIES LINK_FLAGS "-fvisibility=hidden") + endif() + list(APPEND MDBX_BUILD_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}) +endif() + +if(MDBX_BUILD_SHARED_LIBRARY AND MDBX_LINK_TOOLS_NONSTATIC) + set(TOOL_MDBX_LIB mdbx) + + # use, i.e. don't skip the full RPATH for the build tree + set(CMAKE_SKIP_BUILD_RPATH FALSE) + + # when building, don't use the install RPATH already (but later on when installing) + set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) + + # add the automatically determined parts of the RPATH + # which point to directories outside the build tree to the install RPATH + set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) + + # the RPATH to be used when installing, but only if it's not a system directory + list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) + if(isSystemDir EQUAL -1) + if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") + set(CMAKE_INSTALL_RPATH "@executable_path/../lib") + else() + set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib") + endif() + endif() +else() + set(TOOL_MDBX_LIB mdbx-static) +endif() + +# build mdbx-tools +if(MDBX_BUILD_TOOLS) + if(NOT MDBX_AMALGAMATED_SOURCE AND ${CMAKE_SYSTEM_NAME} STREQUAL "Windows") + set(WINGETOPT_SRC ${MDBX_SOURCE_DIR}/wingetopt.c ${MDBX_SOURCE_DIR}/wingetopt.h) + else() + set(WINGETOPT_SRC "") + endif() + + foreach(TOOL mdbx_chk mdbx_copy mdbx_stat mdbx_dump mdbx_load) + add_executable(${TOOL} mdbx.h ${MDBX_SOURCE_DIR}/${TOOL}.c ${WINGETOPT_SRC}) + set_target_properties(${TOOL} PROPERTIES + C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON) + target_setup_options(${TOOL}) + target_link_libraries(${TOOL} ${TOOL_MDBX_LIB}) + endforeach() + if(LIB_MATH) + target_link_libraries(mdbx_chk ${LIB_MATH}) + target_link_libraries(mdbx_stat ${LIB_MATH}) + endif() +endif() + +################################################################################ + +# mdbx-shared-lib installation +if(MDBX_BUILD_SHARED_LIBRARY) + if(CMAKE_VERSION VERSION_LESS 3.12) + install(TARGETS mdbx EXPORT libmdbx + RUNTIME + DESTINATION bin + COMPONENT runtime + LIBRARY + DESTINATION lib + COMPONENT runtime + OBJECTS + DESTINATION lib + COMPONENT devel + ARCHIVE + DESTINATION lib + COMPONENT devel + PUBLIC_HEADER + DESTINATION include + COMPONENT devel + INCLUDES + DESTINATION include + COMPONENT devel) + else() + install(TARGETS mdbx EXPORT libmdbx + RUNTIME + DESTINATION bin + COMPONENT runtime + LIBRARY + DESTINATION lib + COMPONENT runtime + NAMELINK_COMPONENT devel + OBJECTS + DESTINATION lib + COMPONENT devel + ARCHIVE + DESTINATION lib + COMPONENT devel + PUBLIC_HEADER + DESTINATION include + COMPONENT devel + INCLUDES + DESTINATION include + COMPONENT devel) + endif() +endif(MDBX_BUILD_SHARED_LIBRARY) + +# mdbx-tools installation +if(MDBX_BUILD_TOOLS) + install( + TARGETS + mdbx_chk + mdbx_stat + mdbx_copy + mdbx_dump + mdbx_load + RUNTIME + DESTINATION bin + COMPONENT runtime) + install( + FILES + "${MDBX_SOURCE_DIR}/man1/mdbx_chk.1" + "${MDBX_SOURCE_DIR}/man1/mdbx_stat.1" + "${MDBX_SOURCE_DIR}/man1/mdbx_copy.1" + "${MDBX_SOURCE_DIR}/man1/mdbx_dump.1" + "${MDBX_SOURCE_DIR}/man1/mdbx_load.1" + DESTINATION man/man1 + COMPONENT doc) +endif(MDBX_BUILD_TOOLS) + +# mdbx-static-lib installation +if(MDBX_INSTALL_STATIC) + if(CMAKE_VERSION VERSION_LESS 3.12) + install(TARGETS mdbx-static EXPORT libmdbx + RUNTIME + DESTINATION bin + COMPONENT runtime + LIBRARY + DESTINATION lib + COMPONENT runtime + OBJECTS + DESTINATION lib + COMPONENT devel + ARCHIVE + DESTINATION lib + COMPONENT devel + PUBLIC_HEADER + DESTINATION include + COMPONENT devel + INCLUDES + DESTINATION include + COMPONENT devel) + else() + install(TARGETS mdbx-static EXPORT libmdbx + RUNTIME + DESTINATION bin + COMPONENT runtime + LIBRARY + DESTINATION lib + COMPONENT runtime + NAMELINK_COMPONENT devel + OBJECTS + DESTINATION lib + COMPONENT devel + ARCHIVE + DESTINATION lib + COMPONENT devel + PUBLIC_HEADER + DESTINATION include + COMPONENT devel + INCLUDES + DESTINATION include + COMPONENT devel) + endif() +endif(MDBX_INSTALL_STATIC) + +################################################################################ + +# collect options & build info +string(TIMESTAMP MDBX_BUILD_TIMESTAMP UTC) +set(MDBX_BUILD_FLAGS ${CMAKE_C_FLAGS}) + +# append cmake's build-type flags and defines +if(NOT CMAKE_CONFIGURATION_TYPES) + list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}) +endif() + +# get definitions +get_target_property(defs_list mdbx-static COMPILE_DEFINITIONS) +if(defs_list) + list(APPEND MDBX_BUILD_FLAGS ${defs_list}) +endif() + +# get target compile options +get_target_property(options_list mdbx-static COMPILE_OPTIONS) +if(options_list) + list(APPEND MDBX_BUILD_FLAGS ${options_list}) +endif() + +list(REMOVE_DUPLICATES MDBX_BUILD_FLAGS) +string(REPLACE ";" " " MDBX_BUILD_FLAGS "${MDBX_BUILD_FLAGS}") +if(CMAKE_CONFIGURATION_TYPES) + # add dynamic part via per-configuration define + message(STATUS "MDBX Compile Flags: ${MDBX_BUILD_FLAGS} <AND CONFIGURATION DEPENDENT>") + add_definitions(-DMDBX_BUILD_FLAGS_CONFIG="$<$<CONFIG:Debug>:${CMAKE_C_FLAGS_DEBUG} ${CMAKE_C_DEFINES_DEBUG}>$<$<CONFIG:Release>:${CMAKE_C_FLAGS_RELEASE} ${CMAKE_C_DEFINES_RELEASE}>$<$<CONFIG:RelWithDebInfo>:${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CMAKE_C_DEFINES_RELWITHDEBINFO}>$<$<CONFIG:MinSizeRel>:${CMAKE_C_FLAGS_MINSIZEREL} ${CMAKE_C_DEFINES_MINSIZEREL}>") +else() + message(STATUS "MDBX Compile Flags: ${MDBX_BUILD_FLAGS}") +endif() + +# get compiler info +execute_process(COMMAND sh -c "${CMAKE_C_COMPILER} --version | head -1" + OUTPUT_VARIABLE MDBX_BUILD_COMPILER + OUTPUT_STRIP_TRAILING_WHITESPACE + ERROR_QUIET + RESULT_VARIABLE rc) +if(rc OR NOT MDBX_BUILD_COMPILER) + string(STRIP "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}" MDBX_BUILD_COMPILER) +endif() + +# make a build-target triplet +if(CMAKE_C_COMPILER_TARGET) + set(MDBX_BUILD_TARGET "${CMAKE_C_COMPILER_TARGET}") +elseif(CMAKE_C_PLATFORM_ID AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) + string(STRIP "${CMAKE_C_PLATFORM_ID}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) +elseif(CMAKE_LIBRARY_ARCHITECTURE) + string(STRIP "${CMAKE_LIBRARY_ARCHITECTURE}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) +elseif(CMAKE_GENERATOR_PLATFORM AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) + string(STRIP "${CMAKE_GENERATOR_PLATFORM}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) +elseif(CMAKE_SYSTEM_ARCH) + string(STRIP "${CMAKE_SYSTEM_ARCH}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) +else() + string(STRIP "${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) +endif() + +# provide build-type +if(CMAKE_CONFIGURATION_TYPES) + add_definitions(-DMDBX_BUILD_TYPE="$<CONFIG>") +else() + set(MDBX_BUILD_TYPE ${CMAKE_BUILD_TYPE}) +endif() + +# options +set(options VERSION C_COMPILER CXX_COMPILER) +foreach(item IN LISTS options) + if(DEFINED ${item}) + set(value "${${item}}") + elseif(DEFINED MDBX_${item}) + set(item MDBX_${item}) + set(value "${${item}}") + elseif(DEFINED CMAKE_${item}) + set(item CMAKE_${item}) + set(value "${${item}}") + else() + set(value "undefined") + endif() + message(STATUS "${item}: ${value}") +endforeach(item) + +# provide config.h for library build info +configure_file("${MDBX_SOURCE_DIR}/config.h.in" + "${CMAKE_CURRENT_BINARY_DIR}/config.h" ESCAPE_QUOTES) +add_definitions(-DMDBX_CONFIG_H="${CMAKE_CURRENT_BINARY_DIR}/config.h") + +################################################################################ + +if(NOT MDBX_AMALGAMATED_SOURCE AND MDBX_ENABLE_TESTS) add_subdirectory(test) endif() diff --git a/libs/libmdbx/src/GNUmakefile b/libs/libmdbx/src/GNUmakefile index 5d9d25b9bf..6aeb1f92ee 100644 --- a/libs/libmdbx/src/GNUmakefile +++ b/libs/libmdbx/src/GNUmakefile @@ -9,7 +9,7 @@ SHELL := env bash # install sandbox -SANDBOX ?= +DESTDIR ?= # install prefixes (inside sandbox) prefix ?= /usr/local @@ -19,9 +19,10 @@ mandir ?= $(prefix)/man suffix ?= CC ?= gcc +CFLAGS_EXTRA ?= LD ?= ld MDBX_OPTIONS ?= -DNDEBUG=1 -CFLAGS ?= -O2 -g -Wall -Werror -Wextra -Wpedantic -ffunction-sections -fPIC -fvisibility=hidden -std=gnu11 -pthread -Wno-error=attributes +CFLAGS ?= -O2 -g -Wall -Werror -Wextra -Wpedantic -ffunction-sections -fPIC -fvisibility=hidden -std=gnu11 -pthread -Wno-error=attributes $(CFLAGS_EXTRA) # -Wno-tautological-compare # HINT: Try append '--no-as-needed,-lrt' for ability to built with modern glibc, but then run with the old. @@ -61,7 +62,7 @@ strip: all clean: rm -rf $(TOOLS) mdbx_test @* *.[ao] *.[ls]o *~ tmp.db/* \ *.gcov *.log *.err src/*.o test/*.o mdbx_example dist \ - config.h src/elements/config.h src/elements/version.c *.tar* + config.h src/config.h src/version.c *.tar* libmdbx.a: mdbx-static.o $(AR) rs $@ $? @@ -112,7 +113,8 @@ define uname2titer esac endef -DIST_EXTRA := LICENSE README.md CMakeLists.txt GNUmakefile Makefile $(addprefix man1/, $(MANPAGES)) +DIST_EXTRA := LICENSE README.md CMakeLists.txt GNUmakefile Makefile VERSION config.h.in \ + $(addprefix man1/, $(MANPAGES)) cmake/compiler.cmake cmake/profile.cmake cmake/utils.cmake DIST_SRC := mdbx.h mdbx.c $(addsuffix .c, $(TOOLS)) TEST_DB ?= $(shell [ -d /dev/shm ] && echo /dev/shm || echo /tmp)/mdbx-test.db @@ -125,14 +127,16 @@ TEST_OBJ := $(patsubst %.cc,%.o,$(TEST_SRC)) CXX ?= g++ CXXSTD ?= $(shell $(CXX) -std=c++27 -c test/test.cc -o /dev/null 2>/dev/null && echo -std=c++17 || echo -std=c++11) CXXFLAGS := $(CXXSTD) $(filter-out -std=gnu11,$(CFLAGS)) +TAR ?= $(shell which gnu-tar || echo tar) MAN_SRCDIR := src/man1/ -ALLOY_DEPS := $(wildcard src/elements/*) +ALLOY_DEPS := $(wildcard src/*) MDBX_VERSION_GIT = ${shell set -o pipefail; git describe --tags | sed -n 's|^v*\([0-9]\{1,\}\.[0-9]\{1,\}\.[0-9]\{1,\}\)\(.*\)|\1|p' || echo 'Please fetch tags and/or install latest git version'} +MDBX_REVISION_GIT = $(shell git rev-list --count --no-merges HEAD || echo 'Please fetch tags and/or install latest git version') MDBX_GIT_TIMESTAMP = $(shell git show --no-patch --format=%cI HEAD || echo 'Please install latest get version') MDBX_GIT_DESCRIBE = $(shell git describe --tags --long --dirty=-dirty || echo 'Please fetch tags and/or install latest git version') MDBX_VERSION_SUFFIX = $(shell set -o pipefail; echo -n '$(MDBX_GIT_DESCRIBE)' | tr -c -s '[a-zA-Z0-9]' _) -MDBX_BUILD_SOURCERY = $(shell set -o pipefail; $(MAKE) -s src/elements/version.c && (openssl dgst -r -sha256 src/elements/version.c || sha256sum src/elements/version.c || shasum -a 256 src/elements/version.c) 2>/dev/null | cut -d ' ' -f 1 || echo 'Please install openssl or sha256sum or shasum')_$(MDBX_VERSION_SUFFIX) +MDBX_BUILD_SOURCERY = $(shell set -o pipefail; $(MAKE) -s src/version.c && (openssl dgst -r -sha256 src/version.c || sha256sum src/version.c || shasum -a 256 src/version.c) 2>/dev/null | cut -d ' ' -f 1 || echo 'Please install openssl or sha256sum or shasum')_$(MDBX_VERSION_SUFFIX) check: test mdbx_example dist @@ -175,7 +179,7 @@ $(patsubst %.cc,%.o,$(1)): $(1) $(TEST_INC) mdbx.h $(lastword $(MAKEFILE_LIST)) endef $(foreach file,$(TEST_SRC),$(eval $(call test-rule,$(file)))) -mdbx_%: src/tools/mdbx_%.c libmdbx.a +mdbx_%: src/mdbx_%.c libmdbx.a $(CC) $(CFLAGS) $(MDBX_OPTIONS) '-DMDBX_CONFIG_H="config.h"' $^ $(EXE_LDFLAGS) $(LIBS) -o $@ mdbx_test: $(TEST_OBJ) libmdbx.$(SO_SUFFIX) @@ -183,7 +187,7 @@ mdbx_test: $(TEST_OBJ) libmdbx.$(SO_SUFFIX) git_DIR := $(shell if [ -d .git ]; then echo .git; elif [ -s .git -a -f .git ]; then grep '^gitdir: ' .git | cut -d ':' -f 2; else echo "Please use libmdbx as a git-submodule or the amalgamated source code" >&2 && echo git_directory; fi) -src/elements/version.c: src/elements/version.c.in $(lastword $(MAKEFILE_LIST)) $(git_DIR)/HEAD $(git_DIR)/index $(git_DIR)/refs/tags +src/version.c: src/version.c.in $(lastword $(MAKEFILE_LIST)) $(git_DIR)/HEAD $(git_DIR)/index $(git_DIR)/refs/tags sed \ -e "s|@MDBX_GIT_TIMESTAMP@|$(MDBX_GIT_TIMESTAMP)|" \ -e "s|@MDBX_GIT_TREE@|$(shell git show --no-patch --format=%T HEAD || echo 'Please install latest get version')|" \ @@ -192,10 +196,10 @@ src/elements/version.c: src/elements/version.c.in $(lastword $(MAKEFILE_LIST)) $ -e "s|\$${MDBX_VERSION_MAJOR}|$(shell echo '$(MDBX_VERSION_GIT)' | cut -d . -f 1)|" \ -e "s|\$${MDBX_VERSION_MINOR}|$(shell echo '$(MDBX_VERSION_GIT)' | cut -d . -f 2)|" \ -e "s|\$${MDBX_VERSION_RELEASE}|$(shell echo '$(MDBX_VERSION_GIT)' | cut -d . -f 3)|" \ - -e "s|\$${MDBX_VERSION_REVISION}|$(shell git rev-list --count --no-merges HEAD || echo 'Please fetch tags and/or install latest git version')|" \ - src/elements/version.c.in > $@ + -e "s|\$${MDBX_VERSION_REVISION}|$(MDBX_REVISION_GIT)|" \ + src/version.c.in > $@ -src/elements/config.h: src/elements/version.c $(lastword $(MAKEFILE_LIST)) +src/config.h: src/version.c $(lastword $(MAKEFILE_LIST)) (echo '#define MDBX_BUILD_TIMESTAMP "$(shell date +%Y-%m-%dT%H:%M:%S%z)"' \ && echo '#define MDBX_BUILD_FLAGS "$(CFLAGS) $(LDFLAGS) $(LIBS)"' \ && echo '#define MDBX_BUILD_COMPILER "$(shell set -o pipefail; $(CC) --version | head -1 || echo 'Please use GCC or CLANG compatible compiler')"' \ @@ -203,63 +207,65 @@ src/elements/config.h: src/elements/version.c $(lastword $(MAKEFILE_LIST)) && echo '#define MDBX_BUILD_SOURCERY $(MDBX_BUILD_SOURCERY)' \ ) > $@ -mdbx-dylib.o: src/elements/config.h src/elements/version.c src/alloy.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) +mdbx-dylib.o: src/config.h src/version.c src/alloy.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) $(CC) $(CFLAGS) $(MDBX_OPTIONS) '-DMDBX_CONFIG_H="config.h"' -DLIBMDBX_EXPORTS=1 -c src/alloy.c -o $@ -mdbx-static.o: src/elements/config.h src/elements/version.c src/alloy.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) +mdbx-static.o: src/config.h src/version.c src/alloy.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) $(CC) $(CFLAGS) $(MDBX_OPTIONS) '-DMDBX_CONFIG_H="config.h"' -ULIBMDBX_EXPORTS -c src/alloy.c -o $@ .PHONY: dist dist: libmdbx-sources-$(MDBX_VERSION_SUFFIX).tar.gz $(lastword $(MAKEFILE_LIST)) libmdbx-sources-$(MDBX_VERSION_SUFFIX).tar.gz: $(addprefix dist/, $(DIST_SRC) $(DIST_EXTRA)) $(addprefix dist/man1/,$(MANPAGES)) - tar -c --owner=0 --group=0 -C dist $(DIST_SRC) $(DIST_EXTRA) -f - | gzip -c > $@ \ + $(TAR) -c $(shell LC_ALL=C $(TAR) --help | grep -q -- '--owner' && echo '--owner=0 --group=0') -f - -C dist $(DIST_SRC) $(DIST_EXTRA) | gzip -c > $@ \ && rm dist/@tmp-shared_internals.inc -dist/mdbx.h: mdbx.h src/elements/version.c $(lastword $(MAKEFILE_LIST)) +dist/mdbx.h: mdbx.h src/version.c $(lastword $(MAKEFILE_LIST)) mkdir -p dist && cp $< $@ -dist/Makefile: Makefile - mkdir -p dist && cp $< $@ - -dist/GNUmakefile: GNUmakefile - mkdir -p dist && sed -e '/^#> dist-cutoff-begin/,/^#< dist-cutoff-end/d' $< > $@ - -dist/@tmp-shared_internals.inc: src/elements/version.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) +dist/@tmp-shared_internals.inc: src/version.c $(ALLOY_DEPS) $(lastword $(MAKEFILE_LIST)) mkdir -p dist && sed \ -e 's|#pragma once|#define MDBX_ALLOY 1\n#define MDBX_BUILD_SOURCERY $(MDBX_BUILD_SOURCERY)|' \ - -e 's|#include "../../mdbx.h"|@INCLUDE "mdbx.h"|' \ - -e '/#include "defs.h"/r src/elements/defs.h' \ - -e '/#include "osal.h"/r src/elements/osal.h' \ - -e '/#include "options.h"/r src/elements/options.h' \ - src/elements/internals.h > $@ + -e 's|#include "../mdbx.h"|@INCLUDE "mdbx.h"|' \ + -e '/#include "defs.h"/r src/defs.h' \ + -e '/#include "osal.h"/r src/osal.h' \ + -e '/#include "options.h"/r src/options.h' \ + src/internals.h > $@ dist/mdbx.c: dist/@tmp-shared_internals.inc $(lastword $(MAKEFILE_LIST)) mkdir -p dist && (cat dist/@tmp-shared_internals.inc \ - && cat src/elements/core.c src/elements/osal.c src/elements/version.c src/elements/lck-windows.c src/elements/lck-posix.c \ + && cat src/core.c src/osal.c src/version.c src/lck-windows.c src/lck-posix.c \ ) | grep -v -e '#include "' -e '#pragma once' | sed 's|@INCLUDE|#include|' > $@ define dist-tool-rule -dist/$(1).c: src/tools/$(1).c src/tools/wingetopt.h src/tools/wingetopt.c \ +dist/$(1).c: src/$(1).c src/wingetopt.h src/wingetopt.c \ dist/@tmp-shared_internals.inc $(lastword $(MAKEFILE_LIST)) mkdir -p dist && sed \ - -e '/#include "..\/elements\/internals.h"/r dist/@tmp-shared_internals.inc' \ - -e '/#include "wingetopt.h"/r src/tools/wingetopt.c' \ - src/tools/$(1).c \ + -e '/#include "internals.h"/r dist/@tmp-shared_internals.inc' \ + -e '/#include "wingetopt.h"/r src/wingetopt.c' \ + src/$(1).c \ | grep -v -e '#include "' -e '#pragma once' -e '#define MDBX_ALLOY' \ | sed 's|@INCLUDE|#include|' > $$@ endef $(foreach file,$(TOOLS),$(eval $(call dist-tool-rule,$(file)))) +define dist-extra-rule +dist/$(1): $(1) + mkdir -p $$(dir $$@) && sed -e '/^#> dist-cutoff-begin/,/^#< dist-cutoff-end/d' $$< > $$@ + +endef +$(foreach file,$(filter-out man1/% VERSION %.in,$(DIST_EXTRA)),$(eval $(call dist-extra-rule,$(file)))) + +dist/VERSION: src/version.c + mkdir -p dist/ && echo "$(MDBX_VERSION_GIT).$(MDBX_REVISION_GIT)" > $@ + +dist/config.h.in: src/config.h.in + mkdir -p dist/cmake/ && cp $< $@ + dist/man1/mdbx_%.1: src/man1/mdbx_%.1 mkdir -p dist/man1/ && cp $< $@ -dist/LICENSE: LICENSE - mkdir -p dist/man1/ && cp $< $@ -dist/README.md: README.md - mkdir -p dist/man1/ && cp $< $@ -dist/CMakeLists.txt: CMakeLists.dist-minimal - mkdir -p dist/man1/ && cp $< $@ + endif ################################################################################ @@ -302,14 +308,17 @@ cross-qemu: #< dist-cutoff-end install: $(LIBRARIES) $(TOOLS) $(HEADERS) - mkdir -p $(SANDBOX)$(prefix)/bin$(suffix) \ - && cp -t $(SANDBOX)$(prefix)/bin$(suffix) $(TOOLS) && \ - mkdir -p $(SANDBOX)$(prefix)/lib$(suffix) \ - && cp -t $(SANDBOX)$(prefix)/lib$(suffix) $(LIBRARIES) && \ - mkdir -p $(SANDBOX)$(prefix)/include \ - && cp -t $(SANDBOX)$(prefix)/include $(HEADERS) && \ - mkdir -p $(SANDBOX)$(mandir)/man1 \ - && cp -t $(SANDBOX)$(mandir)/man1 $(addprefix $(MAN_SRCDIR), $(MANPAGES)) + install -D -p -s -t $(DESTDIR)$(prefix)/bin$(suffix) $(TOOLS) && \ + install -D -p -s -t $(DESTDIR)$(prefix)/lib$(suffix) $(filter-out libmdbx.a,$(LIBRARIES)) && \ + install -D -p -t $(DESTDIR)$(prefix)/lib$(suffix) libmdbx.a && \ + install -D -p -m 444 -t $(DESTDIR)$(prefix)/include $(HEADERS) && \ + install -D -p -m 444 -t $(DESTDIR)$(mandir)/man1 $(addprefix $(MAN_SRCDIR), $(MANPAGES)) + +uninstall: + rm -f $(addprefix $(DESTDIR)$(prefix)/bin$(suffix)/,$(TOOLS)) \ + $(addprefix $(DESTDIR)$(prefix)/lib$(suffix)/,$(LIBRARIES)) \ + $(addprefix $(DESTDIR)$(prefix)/include/,$(HEADERS)) \ + $(addprefix $(DESTDIR)$(mandir)/man1/,$(MANPAGES)) ################################################################################ # Benchmarking by ioarena diff --git a/libs/libmdbx/src/README.md b/libs/libmdbx/src/README.md index 4cbea049c2..9685648bb4 100644 --- a/libs/libmdbx/src/README.md +++ b/libs/libmdbx/src/README.md @@ -9,15 +9,25 @@ database, with [permissive license](LICENSE). _MDBX_ has a specific set of properties and capabilities, focused on creating unique lightweight solutions with extraordinary performance. -1. Allows **swarm of multi-threaded processes to [ACID]((https://en.wikipedia.org/wiki/ACID))ly read and update** several key-value [maps](https://en.wikipedia.org/wiki/Associative_array) and [multimaps](https://en.wikipedia.org/wiki/Multimap) in a localy-shared database. - -2. Provides **extraordinary performance**, minimal overhead through [Memory-Mapping](https://en.wikipedia.org/wiki/Memory-mapped_file) and `Olog(N)` operations costs by virtue of [B+ tree](https://en.wikipedia.org/wiki/B%2B_tree). - -3. Requires **no maintenance and no crash recovery** since doesn't use [WAL](https://en.wikipedia.org/wiki/Write-ahead_logging), but that might be a caveat for write-intensive workloads. - -4. **Compact and friendly for fully embeddeding**. Only 25KLOC of `C11`, 64K x86 binary code, -no internal threads neither processes, but implements a simplified variant of the -[Berkeley DB](https://en.wikipedia.org/wiki/Berkeley_DB) and +1. Allows **swarm of multi-threaded processes to +[ACID]((https://en.wikipedia.org/wiki/ACID))ly read and update** several +key-value [maps](https://en.wikipedia.org/wiki/Associative_array) and +[multimaps](https://en.wikipedia.org/wiki/Multimap) in a localy-shared +database. + +2. Provides **extraordinary performance**, minimal overhead through +[Memory-Mapping](https://en.wikipedia.org/wiki/Memory-mapped_file) and +`Olog(N)` operations costs by virtue of [B+ +tree](https://en.wikipedia.org/wiki/B%2B_tree). + +3. Requires **no maintenance and no crash recovery** since doesn't use +[WAL](https://en.wikipedia.org/wiki/Write-ahead_logging), but that might +be a caveat for write-intensive workloads with durability requirements. + +4. **Compact and friendly for fully embeddeding**. Only 25KLOC of `C11`, +64K x86 binary code, no internal threads neither processes, but +implements a simplified variant of the [Berkeley +DB](https://en.wikipedia.org/wiki/Berkeley_DB) and [dbm](https://en.wikipedia.org/wiki/DBM_(computing)) API. 5. Enforces [serializability](https://en.wikipedia.org/wiki/Serializability) for @@ -30,7 +40,7 @@ for parallel readers without atomic/interlocked operations, while 6. **Guarantee data integrity** after crash unless this was explicitly neglected in favour of write performance. -7. Supports Linux, Windows, MacOS, FreeBSD, DragonFly, Solaris, +7. Supports Linux, Windows, MacOS, Android, iOS, FreeBSD, DragonFly, Solaris, OpenSolaris, OpenIndiana, NetBSD, OpenBSD and other systems compliant with **POSIX.1-2008**. @@ -49,6 +59,7 @@ _MithrilDB_ is rightly relevant name. > revolution is to provide a clearer and robust API, add more features and > new valuable properties of database. +[![https://t.me/libmdbx](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/telegram.png)](https://t.me/libmdbx) [![Build Status](https://travis-ci.org/erthink/libmdbx.svg?branch=master)](https://travis-ci.org/erthink/libmdbx) [![Build status](https://ci.appveyor.com/api/projects/status/ue94mlopn50dqiqg/branch/master?svg=true)](https://ci.appveyor.com/project/erthink/libmdbx/branch/master) [![Coverity Scan Status](https://scan.coverity.com/projects/12915/badge.svg)](https://scan.coverity.com/projects/reopen-libmdbx) @@ -185,6 +196,9 @@ the user's point of view. > _libmdbx_ manage the database size according to parameters specified > by `mdbx_env_set_geometry()` function, > ones include the growth step and the truncation threshold. + > + > Unfortunately, on-the-fly database size adjustment doesn't work under [Wine](https://en.wikipedia.org/wiki/Wine_(software)) + > due to its internal limitations and unimplemented functions, i.e. the `MDBX_UNABLE_EXTEND_MAPSIZE` error will be returned. 4. Automatic continuous zero-overhead database compactification. > During each commit _libmdbx_ merges suitable freeing pages into unallocated area @@ -402,16 +416,34 @@ will need to install the current (not outdated) version of recommend that you install [Homebrew](https://brew.sh/) and then execute `brew install bash`. +### Android +We recommend using CMake to build _libmdbx_ for Android. +Please refer to the [official guide](https://developer.android.com/studio/projects/add-native-code). + +### iOS +To build _libmdbx_ for iOS, we recommend using CMake with the +"[toolchain file](https://cmake.org/cmake/help/latest/variable/CMAKE_TOOLCHAIN_FILE.html)" +from the [ios-cmake](https://github.com/leetal/ios-cmake) project. + +### Windows Subsystem for Linux +_libmdbx_ could be using in [WSL2](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_2) +but NOT in [WSL1](https://en.wikipedia.org/wiki/Windows_Subsystem_for_Linux#WSL_1) environment. +This is a consequence of the fundamental shortcomings of _WSL1_ and cannot be fixed. +To avoid data loss, _libmdbx_ returns the `ENOLCK` (37, "No record locks available") +error when opening the database in a _WSL1_ environment. + ## API description For more information and API description see the [mdbx.h](mdbx.h) header. +Please do not hesitate to point out errors in the documentation, +including creating [PR](https://help.github.com/en/github/collaborating-with-issues-and-pull-requests/proposing-changes-to-your-work-with-pull-requests) with corrections and improvements. ## Bindings | Runtime | GitHub | Author | | -------- | ------ | ------ | + | Rust | [mdbx-rs](https://github.com/Kerollmops/mdbx-rs) | [@Kerollmops](https://github.com/Kerollmops) | | Java | [mdbxjni](https://github.com/castortech/mdbxjni) | [Castor Technologies](https://castortech.com/) | | .NET | [mdbx.NET](https://github.com/wangjia184/mdbx.NET) | [Jerry Wang](https://github.com/wangjia184) | - | Rust | [mdbx-rs](https://github.com/Kerollmops/mdbx-rs) | [Clément Renault](https://github.com/Kerollmops) | -------------------------------------------------------------------------------- diff --git a/libs/libmdbx/src/appveyor.yml b/libs/libmdbx/src/appveyor.yml index c1b1085cd7..efdeae648d 100644 --- a/libs/libmdbx/src/appveyor.yml +++ b/libs/libmdbx/src/appveyor.yml @@ -1,4 +1,4 @@ -version: 0.6.0.{build} +version: 0.7.0.{build} environment: matrix: diff --git a/libs/libmdbx/src/cmake/compiler.cmake b/libs/libmdbx/src/cmake/compiler.cmake index 93c2c9f18b..a3bca1ac29 100644 --- a/libs/libmdbx/src/cmake/compiler.cmake +++ b/libs/libmdbx/src/cmake/compiler.cmake @@ -17,17 +17,15 @@ cmake_minimum_required(VERSION 3.8.2) cmake_policy(PUSH) cmake_policy(VERSION 3.8.2) -if (CMAKE_VERSION MATCHES ".*MSVC.*") +if(CMAKE_VERSION MATCHES ".*MSVC.*" AND CMAKE_VERSION VERSION_LESS 3.16) message(FATAL_ERROR "CMake from MSVC kit is unfit! " - "Please use the original CMake from https://cmake.org/download/") + "Please use MSVC2019 with modern CMake the original CMake from https://cmake.org/download/") endif() -if (NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)) +if(NOT (CMAKE_C_COMPILER_LOADED OR CMAKE_CXX_COMPILER_LOADED)) message(FATAL_ERROR "This module required C or C++ to be enabled") endif() -include(CMakeDependentOption) - if(CMAKE_CXX_COMPILER_LOADED) include(CheckCXXSourceRuns) include(CheckCXXSourceCompiles) @@ -38,6 +36,9 @@ if(CMAKE_C_COMPILER_LOADED) include(CheckCSourceCompiles) include(CheckCCompilerFlag) endif() +include(CMakeDependentOption) +include(CheckLibraryExists) +include(CheckIncludeFiles) # Check if the same compile family is used for both C and CXX if(CMAKE_C_COMPILER_LOADED AND CMAKE_CXX_COMPILER_LOADED AND @@ -150,6 +151,16 @@ if(WIN32 AND CMAKE_COMPILER_IS_GNU${CMAKE_PRIMARY_LANG}) unset(__GCC_TARGET_MACHINE) endif() +if(NOT DEFINED IOS) + if(APPLE AND (CMAKE_SYSTEM_NAME STREQUAL "iOS" + OR DEFINED CMAKE_IOS_DEVELOPER_ROOT + OR DEFINED IOS_PLATFORM OR DEFINED IOS_ARCH)) + set(IOS TRUE) + else() + set(IOS FALSE) + endif() +endif() + if(CMAKE_COMPILER_IS_ELBRUSC OR CMAKE_SYSTEM_PROCESSOR MATCHES "e2k.*|E2K.*|elbrus.*|ELBRUS.*") set(E2K TRUE) set(CMAKE_SYSTEM_ARCH "Elbrus") @@ -214,6 +225,15 @@ else() check_compiler_flag("-Ominimal" CC_HAS_OMINIMAL) check_compiler_flag("-ffunction-sections -fdata-sections" CC_HAS_SECTIONS) check_compiler_flag("-ffast-math" CC_HAS_FASTMATH) + check_compiler_flag("-Wno-attributes" CC_HAS_WNO_ATTRIBUTES) + + # Check for an omp support + set(CMAKE_REQUIRED_FLAGS "-fopenmp -Werror") + check_cxx_source_compiles("int main(void) { + #pragma omp parallel + return 0; + }" HAVE_OPENMP) + set(CMAKE_REQUIRED_FLAGS "") endif() # Check for LTO support by GCC @@ -276,7 +296,7 @@ if(CMAKE_COMPILER_IS_GNU${CMAKE_PRIMARY_LANG}) endif() # check for LTO by MSVC -if(MSVC) +if(MSVC AND NOT CMAKE_COMPILER_IS_CLANG) if(NOT MSVC_VERSION LESS 1600) set(MSVC_LTO_AVAILABLE TRUE) message(STATUS "Link-Time Optimization by MSVC is available") @@ -290,25 +310,37 @@ endif() if(CMAKE_COMPILER_IS_CLANG) if(NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 3.5) execute_process(COMMAND ${CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER} -print-search-dirs - OUTPUT_VARIABLE clang_search_dirs) + OUTPUT_VARIABLE clang_search_dirs RESULT_VARIABLE clang_probe_result ERROR_QUIET) unset(clang_bindir) unset(clang_libdir) - string(REGEX MATCH "^(.*programs: =)([^:]*:)*([^:]+/llvm[-.0-9]+/bin[^:]*)(:[^:]*)*(\n.+)$" clang_bindir_valid ${clang_search_dirs}) - if(clang_bindir_valid) - string(REGEX REPLACE "^(.*programs: =)([^:]*:)*([^:]+/llvm[-.0-9]+/bin[^:]*)(:[^:]*)*(\n.+)$" "\\3" clang_bindir ${clang_search_dirs}) - get_filename_component(clang_libdir "${clang_bindir}/../lib" REALPATH) - if(clang_libdir) - message(STATUS "Found CLANG/LLVM directories: ${clang_bindir}, ${clang_libdir}") + if(clang_probe_result EQUAL 0) + string(REGEX MATCH "^(.*programs: =)([^:]*:)*([^:]+/llvm[-.0-9]+/bin[^:]*)(:[^:]*)*(\n.+)$" clang_bindir_valid ${clang_search_dirs}) + if(clang_bindir_valid) + string(REGEX REPLACE "^(.*programs: =)([^:]*:)*([^:]+/llvm[-.0-9]+/bin[^:]*)(:[^:]*)*(\n.+)$" "\\3" clang_bindir ${clang_search_dirs}) + if(CMAKE_SYSTEM_NAME STREQUAL "WINDOWS") + set(clang_libdir ${clang_bindir}) + else() + get_filename_component(clang_libdir "${clang_bindir}/../lib" REALPATH) + endif() + endif() + else() + get_filename_component(clang_bindir ${CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER} DIRECTORY) + if(CMAKE_HOST_SYSTEM_NAME STREQUAL "Windows") + set(clang_libdir ${clang_bindir}) + else() + get_filename_component(clang_libdir "${clang_bindir}/../lib" REALPATH) endif() endif() - if(NOT (clang_bindir AND clang_libdir)) + if(clang_bindir AND clang_libdir) + message(STATUS "Found CLANG/LLVM directories: ${clang_bindir}, ${clang_libdir}") + else() message(STATUS "Could NOT find CLANG/LLVM directories (bin and/or lib).") endif() if(NOT CMAKE_CLANG_LD AND clang_bindir) - find_program(CMAKE_CLANG_LD NAMES llvm-link link llvm-ld ld PATHS ${clang_bindir} NO_DEFAULT_PATH) + find_program(CMAKE_CLANG_LD NAMES lld-link ld.lld ld64.lld lld-link llvm-link link llvm-ld ld PATHS ${clang_bindir} NO_DEFAULT_PATH) endif() if(NOT CMAKE_CLANG_AR AND clang_bindir) find_program(CMAKE_CLANG_AR NAMES llvm-ar ar PATHS ${clang_bindir} NO_DEFAULT_PATH) @@ -346,19 +378,19 @@ if(CMAKE_COMPILER_IS_CLANG) unset(clang_search_dirs) endif() - if((CLANG_LTO_PLUGIN AND CMAKE_LD_GOLD) AND + if((CLANG_LTO_PLUGIN AND CMAKE_LD_GOLD) OR (CMAKE_CLANG_LD AND CMAKE_CLANG_AR AND CMAKE_CLANG_NM AND CMAKE_CLANG_RANLIB)) set(CLANG_LTO_AVAILABLE TRUE) message(STATUS "Link-Time Optimization by CLANG/LLVM is available") elseif(CMAKE_TOOLCHAIN_FILE AND NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 7.0) set(CLANG_LTO_AVAILABLE TRUE) - if (NOT CMAKE_CLANG_AR) + if(NOT CMAKE_CLANG_AR) set(CMAKE_CLANG_AR ${CMAKE_AR}) endif() - if (NOT CMAKE_CLANG_NM) + if(NOT CMAKE_CLANG_NM) set(CMAKE_CLANG_NM ${CMAKE_NM}) endif() - if (NOT CMAKE_CLANG_RANLIB) + if(NOT CMAKE_CLANG_RANLIB) set(CMAKE_CLANG_RANLIB ${CMAKE_RANLIB}) endif() message(STATUS "Assume Link-Time Optimization by CLANG/LLVM is available via ${CMAKE_TOOLCHAIN_FILE}") @@ -408,7 +440,7 @@ if(ENABLE_BACKTRACE) endif() macro(setup_compile_flags) - # LY: save initial C/CXX flags + # save initial C/CXX flags if(NOT INITIAL_CMAKE_FLAGS_SAVED) if(MSVC) string(REGEX REPLACE "^(.*)(/EHsc)( *)(.*)$" "\\1/EHs\\3\\4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}") @@ -422,7 +454,7 @@ macro(setup_compile_flags) set(INITIAL_CMAKE_FLAGS_SAVED TRUE CACHE INTERNAL "State of initial CMake's flags" FORCE) endif() - # LY: reset C/CXX flags + # reset C/CXX flags set(CXX_FLAGS ${INITIAL_CMAKE_CXX_FLAGS}) set(C_FLAGS ${INITIAL_CMAKE_C_FLAGS}) set(EXE_LINKER_FLAGS ${INITIAL_CMAKE_EXE_LINKER_FLAGS}) @@ -437,6 +469,12 @@ macro(setup_compile_flags) add_compile_flags("CXX" "-fcxx-exceptions -frtti") endif() + if(CC_HAS_WNO_ATTRIBUTES AND CMAKE_COMPILER_IS_GNU${CMAKE_PRIMARY_LANG} + AND CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 9) + # GCC < 9.x generates false-positive warnings for optimization attributes + add_compile_flags("C;CXX" "-Wno-attributes") + endif() + # In C a global variable without a storage specifier (static/extern) and # without an initialiser is called a ’tentative definition’. The # language permits multiple tentative definitions in the single @@ -482,7 +520,7 @@ macro(setup_compile_flags) endif() if(MSVC) - if (MSVC_VERSION LESS 1900) + if(MSVC_VERSION LESS 1900) message(FATAL_ERROR "At least \"Microsoft C/C++ Compiler\" version 19.0.24234.1 (Visual Studio 2015 Update 3) is required.") endif() add_compile_flags("CXX" "/Zc:__cplusplus") @@ -514,11 +552,11 @@ macro(setup_compile_flags) if(MSVC) add_compile_flags("C;CXX" "/WX") elseif(CMAKE_COMPILER_IS_CLANG) - if (NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 6) + if(NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 6) add_compile_flags("C;CXX" "-Werror") endif() elseif(CMAKE_COMPILER_IS_GNUCC) - if (NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 6) + if(NOT CMAKE_${CMAKE_PRIMARY_LANG}_COMPILER_VERSION VERSION_LESS 6) add_compile_flags("C;CXX" "-Werror") endif() else() @@ -526,7 +564,7 @@ macro(setup_compile_flags) endif() endif() - if (ENABLE_ASAN) + if(ENABLE_ASAN) add_compile_flags("C;CXX" -fsanitize=address) endif() @@ -564,7 +602,7 @@ macro(setup_compile_flags) endif() endif() - if(MSVC AND LTO_ENABLED) + if(MSVC AND NOT CMAKE_COMPILER_IS_CLANG AND LTO_ENABLED) add_compile_flags("C;CXX" "/GL") foreach(linkmode IN ITEMS EXE SHARED STATIC MODULE) set(${linkmode}_LINKER_FLAGS "${${linkmode}_LINKER_FLAGS} /LTCG") @@ -617,12 +655,14 @@ macro(setup_compile_flags) set(CLANG_LTO_FLAG "-flto=thin") endif() add_compile_flags("C;CXX" ${CLANG_LTO_FLAG}) - set(EXE_LINKER_FLAGS "${EXE_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm -fwhole-program") - set(SHARED_LINKER_FLAGS "${SHARED_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm") - set(MODULE_LINKER_FLAGS "${MODULE_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm") + if(NOT MSVC) + set(EXE_LINKER_FLAGS "${EXE_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm -fwhole-program") + set(SHARED_LINKER_FLAGS "${SHARED_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm") + set(MODULE_LINKER_FLAGS "${MODULE_LINKER_FLAGS} ${CLANG_LTO_FLAG} -fverbose-asm") + endif() endif() - # LY: push C/CXX flags into the cache + # push C/CXX flags into the cache set(CMAKE_CXX_FLAGS ${CXX_FLAGS} CACHE STRING "Flags used by the C++ compiler during all build types" FORCE) set(CMAKE_C_FLAGS ${C_FLAGS} CACHE STRING "Flags used by the C compiler during all build types" FORCE) set(CMAKE_EXE_LINKER_FLAGS ${EXE_LINKER_FLAGS} CACHE STRING "Flags used by the linker" FORCE) @@ -640,11 +680,11 @@ endmacro(setup_compile_flags) # determine library for for std::filesystem set(LIBCXX_FILESYSTEM "") if(CMAKE_COMPILER_IS_GNUCXX) - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 9.0) set(LIBCXX_FILESYSTEM "stdc++fs") endif() -elseif (CMAKE_COMPILER_IS_CLANG) - if (CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) +elseif(CMAKE_COMPILER_IS_CLANG) + if(CMAKE_CXX_COMPILER_VERSION VERSION_LESS 5.0) set(LIBCXX_FILESYSTEM "c++experimental") else() set(LIBCXX_FILESYSTEM "stdc++fs") diff --git a/libs/libmdbx/src/cmake/utils.cmake b/libs/libmdbx/src/cmake/utils.cmake index 22e0d72f57..13add097dc 100644 --- a/libs/libmdbx/src/cmake/utils.cmake +++ b/libs/libmdbx/src/cmake/utils.cmake @@ -61,7 +61,7 @@ macro(set_source_files_compile_flags) unset(_lang) endmacro(set_source_files_compile_flags) -macro(fetch_version name version_file) +macro(fetch_version name version_file parent_scope) set(${name}_VERSION "") set(${name}_GIT_DESCRIBE "") set(${name}_GIT_TIMESTAMP "") @@ -69,7 +69,7 @@ macro(fetch_version name version_file) set(${name}_GIT_COMMIT "") set(${name}_GIT_REVISION 0) set(${name}_GIT_VERSION "") - if(GIT) + if(GIT AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") execute_process(COMMAND ${GIT} describe --tags --long --dirty=-dirty OUTPUT_VARIABLE ${name}_GIT_DESCRIBE OUTPUT_STRIP_TRAILING_WHITESPACE @@ -137,7 +137,9 @@ macro(fetch_version name version_file) endif() if(NOT ${name}_GIT_VERSION OR NOT ${name}_GIT_TIMESTAMP OR NOT ${name}_GIT_REVISION) - message(WARNING "Unable to retrive ${name} version from git.") + if(GIT AND EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git") + message(WARNING "Unable to retrive ${name} version from git.") + endif() set(${name}_GIT_VERSION "0;0;0;0") set(${name}_GIT_TIMESTAMP "") set(${name}_GIT_REVISION 0) @@ -166,18 +168,33 @@ macro(fetch_version name version_file) list(GET ${name}_VERSION_LIST 2 "${name}_VERSION_RELEASE") list(GET ${name}_VERSION_LIST 3 "${name}_VERSION_REVISION") - set(${name}_VERSION_MAJOR ${${name}_VERSION_MAJOR} PARENT_SCOPE) - set(${name}_VERSION_MINOR ${${name}_VERSION_MINOR} PARENT_SCOPE) - set(${name}_VERSION_RELEASE ${${name}_VERSION_RELEASE} PARENT_SCOPE) - set(${name}_VERSION_REVISION ${${name}_VERSION_REVISION} PARENT_SCOPE) - set(${name}_VERSION ${${name}_VERSION} PARENT_SCOPE) - - set(${name}_GIT_DESCRIBE ${${name}_GIT_DESCRIBE} PARENT_SCOPE) - set(${name}_GIT_TIMESTAMP ${${name}_GIT_TIMESTAMP} PARENT_SCOPE) - set(${name}_GIT_TREE ${${name}_GIT_TREE} PARENT_SCOPE) - set(${name}_GIT_COMMIT ${${name}_GIT_COMMIT} PARENT_SCOPE) - set(${name}_GIT_REVISION ${${name}_GIT_REVISION} PARENT_SCOPE) - set(${name}_GIT_VERSION ${${name}_GIT_VERSION} PARENT_SCOPE) + if(parent_scope) + set(${name}_VERSION_MAJOR ${${name}_VERSION_MAJOR} PARENT_SCOPE) + set(${name}_VERSION_MINOR ${${name}_VERSION_MINOR} PARENT_SCOPE) + set(${name}_VERSION_RELEASE ${${name}_VERSION_RELEASE} PARENT_SCOPE) + set(${name}_VERSION_REVISION ${${name}_VERSION_REVISION} PARENT_SCOPE) + set(${name}_VERSION ${${name}_VERSION} PARENT_SCOPE) + + set(${name}_GIT_DESCRIBE ${${name}_GIT_DESCRIBE} PARENT_SCOPE) + set(${name}_GIT_TIMESTAMP ${${name}_GIT_TIMESTAMP} PARENT_SCOPE) + set(${name}_GIT_TREE ${${name}_GIT_TREE} PARENT_SCOPE) + set(${name}_GIT_COMMIT ${${name}_GIT_COMMIT} PARENT_SCOPE) + set(${name}_GIT_REVISION ${${name}_GIT_REVISION} PARENT_SCOPE) + set(${name}_GIT_VERSION ${${name}_GIT_VERSION} PARENT_SCOPE) + else() + set(${name}_VERSION_MAJOR ${${name}_VERSION_MAJOR}) + set(${name}_VERSION_MINOR ${${name}_VERSION_MINOR}) + set(${name}_VERSION_RELEASE ${${name}_VERSION_RELEASE}) + set(${name}_VERSION_REVISION ${${name}_VERSION_REVISION}) + set(${name}_VERSION ${${name}_VERSION}) + + set(${name}_GIT_DESCRIBE ${${name}_GIT_DESCRIBE}) + set(${name}_GIT_TIMESTAMP ${${name}_GIT_TIMESTAMP}) + set(${name}_GIT_TREE ${${name}_GIT_TREE}) + set(${name}_GIT_COMMIT ${${name}_GIT_COMMIT}) + set(${name}_GIT_REVISION ${${name}_GIT_REVISION}) + set(${name}_GIT_VERSION ${${name}_GIT_VERSION}) + endif() endmacro(fetch_version) cmake_policy(POP) diff --git a/libs/libmdbx/src/src/elements/config.h b/libs/libmdbx/src/config.h index f05ba6fc85..cc79caf8ed 100644 --- a/libs/libmdbx/src/src/elements/config.h +++ b/libs/libmdbx/src/config.h @@ -4,9 +4,6 @@ /* *INDENT-OFF* */ /* clang-format off */ -/* #undef HAVE_VALGRIND_MEMCHECK_H */ -/* #undef HAS_RELAXED_CONSTEXPR */ - #define LTO_ENABLED /* #undef MDBX_USE_VALGRIND */ /* #undef ENABLE_GPROF */ @@ -20,7 +17,6 @@ #ifndef MDBX_TXN_CHECKPID_AUTO #define MDBX_TXN_CHECKPID 0 #endif -#define MDBX_BUILD_SHARED_LIBRARY 1 #define MDBX_LOCKING_AUTO #ifndef MDBX_LOCKING_AUTO /* #undef MDBX_LOCKING */ @@ -31,10 +27,10 @@ #endif /* Windows */ -#define MDBX_CONFIG_MANUAL_TLS_CALLBACK 0 +#define MDBX_CONFIG_MANUAL_TLS_CALLBACK 1 #define MDBX_AVOID_CRT 1 -/* MacOS */ +/* MacOS & iOS */ #define MDBX_OSX_SPEED_INSTEADOF_DURABILITY 0 /* POSIX */ @@ -45,12 +41,12 @@ #endif /* Build Info */ -#define MDBX_BUILD_TIMESTAMP "2020-03-20T14:47:36Z" +#define MDBX_BUILD_TIMESTAMP "2020-04-25T08:31:34Z" #define MDBX_BUILD_TARGET "x86_64-Windows" -/* #undef MDBX_BUILD_CONFIG */ -#define MDBX_BUILD_COMPILER "MSVC-19.25.28610.4" -#define MDBX_BUILD_FLAGS "LIBMDBX_EXPORTS" -#define MDBX_BUILD_SOURCERY b8a401ae08d0312d6e5365c29bb58adea2e44dbc7e3d808df4a0de2fefcc65ca_v0_6_0_45_gc20ba1e +/* #undef MDBX_BUILD_TYPE */ +#define MDBX_BUILD_COMPILER "MSVC-19.25.28614.0" +#define MDBX_BUILD_FLAGS "/DWIN32 /D_WINDOWS /W3 /Gy /W4 /utf-8 /WX /GL MDBX_BUILD_SHARED_LIBRARY=0" +#define MDBX_BUILD_SOURCERY 51d296e8c57b5c01204315d0ea2160b23cf3eb40509644354cc038e3f67d61d4_v0_7_0_39_gca8fa31 /* *INDENT-ON* */ /* clang-format on */ diff --git a/libs/libmdbx/src/mdbx.h b/libs/libmdbx/src/mdbx.h index 971b009402..c7a6ab3f43 100644 --- a/libs/libmdbx/src/mdbx.h +++ b/libs/libmdbx/src/mdbx.h @@ -555,6 +555,11 @@ #include <windows.h> #include <winnt.h> + +#ifndef FSCTL_GET_EXTERNAL_BACKING +#define FSCTL_GET_EXTERNAL_BACKING CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 196, METHOD_BUFFERED, FILE_ANY_ACCESS) +#endif + #ifndef __mode_t_defined typedef unsigned short mode_t; #endif @@ -653,8 +658,9 @@ typedef pthread_t mdbx_tid_t; /*----------------------------------------------------------------------------*/ +/* MDBX version 0.7.0, released 2020-03-18 */ #define MDBX_VERSION_MAJOR 0 -#define MDBX_VERSION_MINOR 6 +#define MDBX_VERSION_MINOR 7 #ifndef LIBMDBX_API #if defined(LIBMDBX_EXPORTS) @@ -1202,10 +1208,11 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf, * In case single transaction after mdbx_env_sync, you may lose * transaction itself, but not a whole database. * - * Nevertheless, MDBX_UTTERLY_NOSYNC provides ACID in case of a application - * crash, and therefore may be very useful in scenarios where data - * durability is not required over a system failure (e.g for short-lived - * data), or if you can ignore such risk. + * Nevertheless, MDBX_UTTERLY_NOSYNC provides "weak" durability in case of + * an application crash (but no durability on system failure), and + * therefore may be very useful in scenarios where data durability is not + * required over a system failure (e.g for short-lived data), or if you can + * take such risk. * * MDBX_UTTERLY_NOSYNC flag may be changed at any time using * mdbx_env_set_flags(), but don't has effect if passed to mdbx_txn_begin() @@ -1447,7 +1454,8 @@ typedef enum MDBX_cursor_op { /* Transaction has too many dirty pages, i.e transaction too big */ #define MDBX_TXN_FULL (-30788) -/* Cursor stack too deep - internal error */ +/* Cursor stack too deep - this usually indicates corruption, + * i.e branch-pages loop */ #define MDBX_CURSOR_FULL (-30787) /* Page has not enough space - internal error */ @@ -1462,6 +1470,13 @@ typedef enum MDBX_cursor_op { * or explicit call of mdbx_env_set_geometry(). */ #define MDBX_UNABLE_EXTEND_MAPSIZE (-30785) +/* MDBX_MAP_RESIZED is deprecated. + * Please review your code to use MDBX_UNABLE_EXTEND_MAPSIZE instead. */ +static __inline int __deprecated MDBX_MAP_RESIZED() { + return MDBX_UNABLE_EXTEND_MAPSIZE; +} +#define MDBX_MAP_RESIZED MDBX_MAP_RESIZED() + /* Environment or database is not compatible with the requested operation * or the specified flags. This can mean: * - The operation expects an MDBX_DUPSORT / MDBX_DUPFIXED database. @@ -1904,14 +1919,17 @@ LIBMDBX_API int mdbx_env_set_syncperiod(MDBX_env *env, * * Returns A non-zero error value on failure and 0 on success. * Some possible errors are: - * - MDBX_BUSY = The write transaction is running by other thread, in such - * case MDBX_env instance has NOT be destroyed not released! - * NOTE: if any OTHER error code was returned then given - * MDBX_env instance has been destroyed and released. - * - MDBX_PANIC = If mdbx_env_close_ex() was called in the child process - * after fork(). In this case MDBX_PANIC is a expecte, - * i.e. MDBX_env instance was freed in proper manner. - * - MDBX_EIO = an error occurred during synchronization. */ + * - MDBX_BUSY = The write transaction is running by other thread, in such + * case MDBX_env instance has NOT be destroyed not released! + * NOTE: if any OTHER error code was returned then given + * MDBX_env instance has been destroyed and released. + * - MDBX_EBADSIGN = Environment handle already closed (i.e. mdbx_env_close() + * was already called or not valid (i.e. was not created + * by mdbx_env_create()). + * - MDBX_PANIC = If mdbx_env_close_ex() was called in the child process + * after fork(). In this case MDBX_PANIC is a expecte, + * i.e. MDBX_env instance was freed in proper manner. + * - MDBX_EIO = an error occurred during synchronization. */ LIBMDBX_API int mdbx_env_close_ex(MDBX_env *env, int dont_sync); LIBMDBX_API int mdbx_env_close(MDBX_env *env); @@ -1942,7 +1960,7 @@ LIBMDBX_API int mdbx_env_set_flags(MDBX_env *env, unsigned flags, int onoff); * Returns A non-zero error value on failure and 0 on success, some * possible errors are: * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_env_get_flags(MDBX_env *env, unsigned *flags); +LIBMDBX_API int mdbx_env_get_flags(const MDBX_env *env, unsigned *flags); /* Return the path that was used in mdbx_env_open(). * @@ -1954,7 +1972,7 @@ LIBMDBX_API int mdbx_env_get_flags(MDBX_env *env, unsigned *flags); * Returns A non-zero error value on failure and 0 on success, some * possible errors are: * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_env_get_path(MDBX_env *env, const char **dest); +LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest); /* Return the file descriptor for the given environment. * @@ -1967,7 +1985,7 @@ LIBMDBX_API int mdbx_env_get_path(MDBX_env *env, const char **dest); * Returns A non-zero error value on failure and 0 on success, some * possible errors are: * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *fd); +LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd); /* Set all size-related parameters of environment, including page size and the * min/max size of the memory map. @@ -2220,7 +2238,7 @@ LIBMDBX_API int mdbx_env_set_maxreaders(MDBX_env *env, unsigned readers); * Returns A non-zero error value on failure and 0 on success, some * possible errors are: * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_env_get_maxreaders(MDBX_env *env, unsigned *readers); +LIBMDBX_API int mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers); /* Set the maximum number of named databases for the environment. * @@ -2251,9 +2269,9 @@ LIBMDBX_API int mdbx_env_set_maxdbs(MDBX_env *env, MDBX_dbi dbs); * * Returns The maximum size of a key we can write, * or -1 if something is wrong. */ -LIBMDBX_API int mdbx_env_get_maxkeysize_ex(MDBX_env *env, unsigned flags); -LIBMDBX_API int mdbx_env_get_maxvalsize_ex(MDBX_env *env, unsigned flags); -__deprecated LIBMDBX_API int mdbx_env_get_maxkeysize(MDBX_env *env); +LIBMDBX_API int mdbx_env_get_maxkeysize_ex(const MDBX_env *env, unsigned flags); +LIBMDBX_API int mdbx_env_get_maxvalsize_ex(const MDBX_env *env, unsigned flags); +__deprecated LIBMDBX_API int mdbx_env_get_maxkeysize(const MDBX_env *env); /* Set application information associated with the MDBX_env. * @@ -2267,7 +2285,7 @@ LIBMDBX_API int mdbx_env_set_userctx(MDBX_env *env, void *ctx); * * [in] env An environment handle returned by mdbx_env_create() * Returns The pointer set by mdbx_env_set_userctx(). */ -LIBMDBX_API void *mdbx_env_get_userctx(MDBX_env *env); +LIBMDBX_API void *mdbx_env_get_userctx(const MDBX_env *env); /* Create a transaction for use with the environment. * @@ -2380,12 +2398,13 @@ typedef struct MDBX_txn_info { * not needed (see description of MDBX_txn_info above). * * Returns A non-zero error value on failure and 0 on success. */ -LIBMDBX_API int mdbx_txn_info(MDBX_txn *txn, MDBX_txn_info *info, int scan_rlt); +LIBMDBX_API int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, + int scan_rlt); /* Returns the transaction's MDBX_env. * * [in] txn A transaction handle returned by mdbx_txn_begin() */ -LIBMDBX_API MDBX_env *mdbx_txn_env(MDBX_txn *txn); +LIBMDBX_API MDBX_env *mdbx_txn_env(const MDBX_txn *txn); /* Return the transaction's flags. * @@ -2395,7 +2414,7 @@ LIBMDBX_API MDBX_env *mdbx_txn_env(MDBX_txn *txn); * * Returns A transaction flags, valid if input is an valid transaction, * otherwise -1. */ -LIBMDBX_API int mdbx_txn_flags(MDBX_txn *txn); +LIBMDBX_API int mdbx_txn_flags(const MDBX_txn *txn); /* Return the transaction's ID. * @@ -2407,7 +2426,7 @@ LIBMDBX_API int mdbx_txn_flags(MDBX_txn *txn); * * Returns A transaction ID, valid if input is an active transaction, * otherwise 0. */ -LIBMDBX_API uint64_t mdbx_txn_id(MDBX_txn *txn); +LIBMDBX_API uint64_t mdbx_txn_id(const MDBX_txn *txn); /* Commit all the operations of a transaction into the database. * @@ -2514,7 +2533,7 @@ LIBMDBX_API int mdbx_canary_put(MDBX_txn *txn, const mdbx_canary *canary); * will be copied. * * Returns A non-zero error value on failure and 0 on success. */ -LIBMDBX_API int mdbx_canary_get(MDBX_txn *txn, mdbx_canary *canary); +LIBMDBX_API int mdbx_canary_get(const MDBX_txn *txn, mdbx_canary *canary); /* A callback function used to compare two keys in a database */ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b); @@ -2589,9 +2608,14 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b); * comparison functions for keys and values (for multimaps). * However, I recommend not using custom comparison functions, but instead * converting the keys to one of the forms that are suitable for built-in - * comparators. The main reason for this is that you can't use mdbx_chk tools - * with a custom comparators. For instance take look to the mdbx_key_from_xxx() - * functions. + * comparators (for instance take look to the mdbx_key_from_xxx() + * functions). The reasons to not using custom comparators are: + * - The order of records could not be validated without your code. + * So mdbx_chk utility will reports "wrong order" errors + * and the '-i' option is required to ignore ones. + * - A records could not be ordered or sorted without your code. + * So mdbx_load utility should be used with '-a' option to preserve + * input data order. * * [in] keycmp Optional custom key comparison function for a database. * [in] datacmp Optional custom data comparison function for a database, takes @@ -2725,7 +2749,7 @@ LIBMDBX_API int mdbx_drop(MDBX_txn *txn, MDBX_dbi dbi, int del); * possible errors are: * - MDBX_NOTFOUND = the key was not in the database. * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, +LIBMDBX_API int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data); /* Get items from a database and optionaly number of data items for a given key. @@ -2837,7 +2861,7 @@ LIBMDBX_API int mdbx_get_nearest(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * - MDBX_TXN_FULL = the transaction has too many dirty pages. * - MDBX_EACCES = an attempt was made to write in a read-only transaction. * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, +LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, unsigned flags); /* Replace items in a database. @@ -2876,7 +2900,7 @@ LIBMDBX_API int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * multi-value/duplicates. * * Returns A non-zero error value on failure and 0 on success. */ -LIBMDBX_API int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, +LIBMDBX_API int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *new_data, MDBX_val *old_data, unsigned flags); @@ -2900,8 +2924,8 @@ LIBMDBX_API int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, * possible errors are: * - MDBX_EACCES = an attempt was made to write in a read-only transaction. * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, - MDBX_val *data); +LIBMDBX_API int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, + const MDBX_val *data); /* Create a cursor handle. * @@ -2965,12 +2989,12 @@ LIBMDBX_API int mdbx_cursor_renew(MDBX_txn *txn, MDBX_cursor *cursor); /* Return the cursor's transaction handle. * * [in] cursor A cursor handle returned by mdbx_cursor_open(). */ -LIBMDBX_API MDBX_txn *mdbx_cursor_txn(MDBX_cursor *cursor); +LIBMDBX_API MDBX_txn *mdbx_cursor_txn(const MDBX_cursor *cursor); /* Return the cursor's database handle. * * [in] cursor A cursor handle returned by mdbx_cursor_open(). */ -LIBMDBX_API MDBX_dbi mdbx_cursor_dbi(MDBX_cursor *cursor); +LIBMDBX_API MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *cursor); /* Retrieve by cursor. * @@ -2997,11 +3021,11 @@ LIBMDBX_API int mdbx_cursor_get(MDBX_cursor *cursor, MDBX_val *key, * This function stores key/data pairs into the database. The cursor is * positioned at the new item, or on failure usually near it. * - * [in] cursor A cursor handle returned by mdbx_cursor_open(). - * [in] key The key operated on. - * [in] data The data operated on. - * [in] flags Options for this operation. This parameter - * must be set to 0 or one of the values described here: + * [in] cursor A cursor handle returned by mdbx_cursor_open(). + * [in] key The key operated on. + * [in,out] data The data operated on. + * [in] flags Options for this operation. This parameter + * must be set to 0 or one of the values described here: * * - MDBX_CURRENT * Replace the item at the current cursor position. The key parameter @@ -3058,7 +3082,7 @@ LIBMDBX_API int mdbx_cursor_get(MDBX_cursor *cursor, MDBX_val *key, * - MDBX_TXN_FULL = the transaction has too many dirty pages. * - MDBX_EACCES = an attempt was made to write in a read-only transaction. * - MDBX_EINVAL = an invalid parameter was specified. */ -LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, MDBX_val *key, +LIBMDBX_API int mdbx_cursor_put(MDBX_cursor *cursor, const MDBX_val *key, MDBX_val *data, unsigned flags); /* Delete current key/data pair. @@ -3094,7 +3118,7 @@ LIBMDBX_API int mdbx_cursor_del(MDBX_cursor *cursor, unsigned flags); * possible errors are: * - MDBX_EINVAL = cursor is not initialized, or an invalid parameter * was specified. */ -LIBMDBX_API int mdbx_cursor_count(MDBX_cursor *cursor, size_t *countp); +LIBMDBX_API int mdbx_cursor_count(const MDBX_cursor *cursor, size_t *countp); /* Determines whether the cursor is pointed to a key-value pair or not, * i.e. was not positioned or points to the end of data. @@ -3105,7 +3129,7 @@ LIBMDBX_API int mdbx_cursor_count(MDBX_cursor *cursor, size_t *countp); * - MDBX_RESULT_TRUE = no more data available or cursor not positioned; * - MDBX_RESULT_FALSE = data available; * - Otherwise the error code. */ -LIBMDBX_API int mdbx_cursor_eof(MDBX_cursor *mc); +LIBMDBX_API int mdbx_cursor_eof(const MDBX_cursor *mc); /* Determines whether the cursor is pointed to the first key-value pair or not. * @@ -3115,7 +3139,7 @@ LIBMDBX_API int mdbx_cursor_eof(MDBX_cursor *mc); * - MDBX_RESULT_TRUE = cursor positioned to the first key-value pair. * - MDBX_RESULT_FALSE = cursor NOT positioned to the first key-value pair. * - Otherwise the error code. */ -LIBMDBX_API int mdbx_cursor_on_first(MDBX_cursor *mc); +LIBMDBX_API int mdbx_cursor_on_first(const MDBX_cursor *mc); /* Determines whether the cursor is pointed to the last key-value pair or not. * @@ -3125,7 +3149,7 @@ LIBMDBX_API int mdbx_cursor_on_first(MDBX_cursor *mc); * - MDBX_RESULT_TRUE = cursor positioned to the last key-value pair. * - MDBX_RESULT_FALSE = cursor NOT positioned to the last key-value pair. * - Otherwise the error code. */ -LIBMDBX_API int mdbx_cursor_on_last(MDBX_cursor *mc); +LIBMDBX_API int mdbx_cursor_on_last(const MDBX_cursor *mc); /* Estimates the distance between cursors as a number of elements. The results * of such estimation can be used to build and/or optimize query execution @@ -3280,7 +3304,7 @@ LIBMDBX_API int mdbx_dbi_sequence(MDBX_txn *txn, MDBX_dbi dbi, uint64_t *result, * [in] b The second item to compare. * * Returns < 0 if a < b, 0 if a == b, > 0 if a > b */ -LIBMDBX_API int mdbx_cmp(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, +LIBMDBX_API int mdbx_cmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b); /* Compare two data items according to a particular database. @@ -3294,7 +3318,7 @@ LIBMDBX_API int mdbx_cmp(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, * [in] b The second item to compare. * * Returns < 0 if a < b, 0 if a == b, > 0 if a > b */ -LIBMDBX_API int mdbx_dcmp(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, +LIBMDBX_API int mdbx_dcmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b); /* A callback function used to enumerate the reader lock table. @@ -3330,8 +3354,8 @@ typedef int(MDBX_reader_list_func)(void *ctx, int num, int slot, mdbx_pid_t pid, * * Returns A non-zero error value on failure and 0 on success, * or MDBX_RESULT_TRUE (-1) if the reader lock table is empty. */ -LIBMDBX_API int mdbx_reader_list(MDBX_env *env, MDBX_reader_list_func *func, - void *ctx); +LIBMDBX_API int mdbx_reader_list(const MDBX_env *env, + MDBX_reader_list_func *func, void *ctx); /* Check for stale entries in the reader lock table. * @@ -3353,7 +3377,8 @@ LIBMDBX_API int mdbx_reader_check(MDBX_env *env, int *dead); * * Returns Number of transactions committed after the given was started for * read, or negative value on failure. */ -__deprecated LIBMDBX_API int mdbx_txn_straggler(MDBX_txn *txn, int *percent); +__deprecated LIBMDBX_API int mdbx_txn_straggler(const MDBX_txn *txn, + int *percent); /* A lack-of-space callback function to resolve issues with a laggard readers. * @@ -3426,7 +3451,7 @@ LIBMDBX_API int mdbx_env_set_oomfunc(MDBX_env *env, MDBX_oom_func *oom_func); * [in] env An environment handle returned by mdbx_env_create(). * * Returns A MDBX_oom_func function or NULL if disabled. */ -LIBMDBX_API MDBX_oom_func *mdbx_env_get_oomfunc(MDBX_env *env); +LIBMDBX_API MDBX_oom_func *mdbx_env_get_oomfunc(const MDBX_env *env); /**** B-tree Traversal ********************************************************* * This is internal API for mdbx_chk tool. You should avoid to use it, except diff --git a/libs/libmdbx/src/src/CMakeLists.txt b/libs/libmdbx/src/src/CMakeLists.txt deleted file mode 100644 index 8a33ede361..0000000000 --- a/libs/libmdbx/src/src/CMakeLists.txt +++ /dev/null @@ -1,263 +0,0 @@ -## -## Copyright 2020 Leonid Yuriev <leo@yuriev.ru> -## and other libmdbx authors: please see AUTHORS file. -## 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 -## <http://www.OpenLDAP.org/license.html>. -## - -# Get version -fetch_version(MDBX "${CMAKE_CURRENT_SOURCE_DIR}/../VERSION") -message(STATUS "libmdbx version is ${MDBX_VERSION}") - -if(MDBX_ALLOY_MODE) - set(LIBMDBX_SOURCES alloy.c) -else() - set(LIBMDBX_SOURCES - elements/options.h elements/defs.h elements/internals.h elements/osal.h - elements/core.c elements/osal.c elements/lck-posix.c elements/lck-windows.c) -endif() -list(APPEND LIBMDBX_SOURCES ../mdbx.h - "${CMAKE_CURRENT_SOURCE_DIR}/elements/version.c" - "${CMAKE_CURRENT_SOURCE_DIR}/elements/config.h") - -if(MDBX_BUILD_SHARED_LIBRARY) - add_library(mdbx SHARED ${LIBMDBX_SOURCES}) - target_compile_definitions(mdbx PRIVATE LIBMDBX_EXPORTS INTERFACE LIBMDBX_IMPORTS) - set(MDBX_LIBDEP_MODE PRIVATE) -else() - add_library(mdbx STATIC ${LIBMDBX_SOURCES}) - set(MDBX_LIBDEP_MODE PUBLIC) -endif() - -if(CC_HAS_VISIBILITY AND (LTO_ENABLED OR INTERPROCEDURAL_OPTIMIZATION)) - set_target_properties(mdbx PROPERTIES LINK_FLAGS "-fvisibility=hidden") -endif() - -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - if(MSVC) - if(NOT MSVC_LIB_EXE) - # Find lib.exe - get_filename_component(CL_NAME ${CMAKE_C_COMPILER} NAME) - string(REPLACE cl.exe lib.exe MSVC_LIB_EXE ${CL_NAME}) - find_program(MSVC_LIB_EXE ${MSVC_LIB_EXE}) - endif() - if(MSVC_LIB_EXE) - message(STATUS "Found MSVC's lib tool: ${MSVC_LIB_EXE}") - set(MDBX_NTDLL_EXTRA_IMPLIB ${CMAKE_CURRENT_BINARY_DIR}/mdbx_ntdll_extra.lib) - add_custom_command(OUTPUT ${MDBX_NTDLL_EXTRA_IMPLIB} - COMMENT "Create extra-import-library for ntdll.dll" - MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/elements/ntdll.def" - COMMAND ${MSVC_LIB_EXE} /def:"${CMAKE_CURRENT_SOURCE_DIR}/elements/ntdll.def" /out:"${MDBX_NTDLL_EXTRA_IMPLIB}" ${INITIAL_CMAKE_STATIC_LINKER_FLAGS}) - else() - message(SEND_ERROR "MSVC's lib tool not found") - endif() - elseif(MINGW OR MINGW64) - if(NOT DLLTOOL) - # Find dlltool - get_filename_component(GCC_NAME ${CMAKE_C_COMPILER} NAME) - string(REPLACE gcc dlltool DLLTOOL_NAME ${GCC_NAME}) - find_program(DLLTOOL NAMES ${DLLTOOL_NAME}) - endif() - if(DLLTOOL) - message(STATUS "Found dlltool: ${DLLTOOL}") - set(MDBX_NTDLL_EXTRA_IMPLIB "${CMAKE_CURRENT_BINARY_DIR}/mdbx_ntdll_extra.a") - add_custom_command(OUTPUT ${MDBX_NTDLL_EXTRA_IMPLIB} - COMMENT "Create extra-import-library for ntdll.dll" - MAIN_DEPENDENCY "${CMAKE_CURRENT_SOURCE_DIR}/elements/ntdll.def" - COMMAND ${DLLTOOL} -d "${CMAKE_CURRENT_SOURCE_DIR}/elements/ntdll.def" -l "${MDBX_NTDLL_EXTRA_IMPLIB}") - else() - message(SEND_ERROR "dlltool not found") - endif() - endif() -endif() - -target_link_libraries(mdbx ${MDBX_LIBDEP_MODE} ${CMAKE_THREAD_LIBS_INIT}) -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - target_link_libraries(mdbx ${MDBX_LIBDEP_MODE} ntdll.lib) - if(MDBX_NTDLL_EXTRA_IMPLIB) - # LY: Sometimes Cmake requires a nightmarish magic for simple things. - # 1) create a target out of the library compilation result - add_custom_target(ntdll_extra_target DEPENDS ${MDBX_NTDLL_EXTRA_IMPLIB}) - # 2) create an library target out of the library compilation result - add_library(ntdll_extra STATIC IMPORTED GLOBAL) - add_dependencies(ntdll_extra ntdll_extra_target) - # 3) specify where the library is (and where to find the headers) - set_target_properties(ntdll_extra - PROPERTIES - IMPORTED_LOCATION ${MDBX_NTDLL_EXTRA_IMPLIB}) - target_link_libraries(mdbx ${MDBX_LIBDEP_MODE} ntdll_extra) - endif() -endif() - -if(${CMAKE_SYSTEM_NAME} STREQUAL "SunOS" OR ${CMAKE_SYSTEM_NAME} STREQUAL "Solaris") - target_link_libraries(mdbx ${MDBX_LIBDEP_MODE} kstat) -endif() - -set_target_properties(mdbx PROPERTIES - INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}> - C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON - PUBLIC_HEADER "../mdbx.h") - -if(CC_HAS_FASTMATH) - target_compile_options(mdbx PRIVATE "-ffast-math") -endif() -if(BUILD_FOR_NATIVE_CPU AND CC_HAS_ARCH_NATIVE) - target_compile_options(mdbx PUBLIC "-march=native") -endif() -if(CC_HAS_VISIBILITY) - target_compile_options(mdbx PRIVATE "-fvisibility=hidden") -endif() - -################################################################################ -# -# library build info (used in library version output) -# -set(MDBX_BUILD_FLAGS "") - -# append cmake's build-type flags and defines -if(NOT CMAKE_CONFIGURATION_TYPES) - list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_FLAGS_${CMAKE_BUILD_TYPE_UPPERCASE}}) - list(APPEND MDBX_BUILD_FLAGS ${CMAKE_C_DEFINES_${CMAKE_BUILD_TYPE_UPPERCASE}}) -endif() - -# append linker dll's options -if(LIBMDBX_TYPE STREQUAL "SHARED") - list(APPEND MDBX_BUILD_FLAGS ${CMAKE_SHARED_LINKER_FLAGS}) -endif() - -# get definitions -get_target_property(defs_list mdbx COMPILE_DEFINITIONS) -if(defs_list) - list(APPEND MDBX_BUILD_FLAGS ${defs_list}) -endif() - -# get target compile options -get_target_property(options_list mdbx COMPILE_OPTIONS) -if(options_list) - list(APPEND MDBX_BUILD_FLAGS ${options_list}) -endif() - -list(REMOVE_DUPLICATES MDBX_BUILD_FLAGS) -string(REPLACE ";" " " MDBX_BUILD_FLAGS "${MDBX_BUILD_FLAGS}") -if(CMAKE_CONFIGURATION_TYPES) - # add dynamic part via per-configuration define - message(STATUS "MDBX Compile Flags: ${MDBX_BUILD_FLAGS} <AND CONFIGURATION DEPENDENT>") - add_definitions(-DMDBX_BUILD_FLAGS_CONFIG="$<$<CONFIG:Debug>:${CMAKE_C_FLAGS_DEBUG} ${CMAKE_C_DEFINES_DEBUG}>$<$<CONFIG:Release>:${CMAKE_C_FLAGS_RELEASE} ${CMAKE_C_DEFINES_RELEASE}>$<$<CONFIG:RelWithDebInfo>:${CMAKE_C_FLAGS_RELWITHDEBINFO} ${CMAKE_C_DEFINES_RELWITHDEBINFO}>$<$<CONFIG:MinSizeRel>:${CMAKE_C_FLAGS_MINSIZEREL} ${CMAKE_C_DEFINES_MINSIZEREL}>") -else() - message(STATUS "MDBX Compile Flags: ${MDBX_BUILD_FLAGS}") -endif() - -# get compiler info -execute_process(COMMAND sh -c "${CMAKE_C_COMPILER} --version | head -1" - OUTPUT_VARIABLE MDBX_BUILD_COMPILER - OUTPUT_STRIP_TRAILING_WHITESPACE - ERROR_QUIET - RESULT_VARIABLE rc) -if(rc OR NOT MDBX_BUILD_COMPILER) - string(STRIP "${CMAKE_C_COMPILER_ID}-${CMAKE_C_COMPILER_VERSION}" MDBX_BUILD_COMPILER) -endif() - -# make a build-target triplet -if(CMAKE_C_COMPILER_TARGET) - set(MDBX_BUILD_TARGET "${CMAKE_C_COMPILER_TARGET}") -elseif(CMAKE_C_PLATFORM_ID AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) - string(STRIP "${CMAKE_C_PLATFORM_ID}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_LIBRARY_ARCHITECTURE) - string(STRIP "${CMAKE_LIBRARY_ARCHITECTURE}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_GENERATOR_PLATFORM AND NOT CMAKE_C_PLATFORM_ID STREQUAL CMAKE_SYSTEM_NAME) - string(STRIP "${CMAKE_GENERATOR_PLATFORM}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -elseif(CMAKE_SYSTEM_ARCH) - string(STRIP "${CMAKE_SYSTEM_ARCH}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -else() - string(STRIP "${CMAKE_SYSTEM_PROCESSOR}-${CMAKE_SYSTEM_NAME}" MDBX_BUILD_TARGET) -endif() -if(CMAKE_CONFIGURATION_TYPES) - add_definitions(-DMDBX_BUILD_CONFIG="$<CONFIG>") -else() - set(MDBX_BUILD_CONFIG ${CMAKE_BUILD_TYPE}) -endif() - -# options -string(TIMESTAMP MDBX_BUILD_TIMESTAMP UTC) -set(options VERSION C_COMPILER CXX_COMPILER) -foreach(item IN LISTS options) - if(DEFINED ${item}) - set(value "${${item}}") - elseif(DEFINED MDBX_${item}) - set(item MDBX_${item}) - set(value "${${item}}") - elseif(DEFINED CMAKE_${item}) - set(item CMAKE_${item}) - set(value "${${item}}") - else() - set(value "undefined") - endif() - message(STATUS "${item}: ${value}") -endforeach(item) - -# generate version and config files -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/elements/version.c.in" - "${CMAKE_CURRENT_SOURCE_DIR}/elements/version.c" ESCAPE_QUOTES) - -file(SHA256 "${CMAKE_CURRENT_SOURCE_DIR}/elements/version.c" MDBX_SOURCERY_DIGEST) -string(MAKE_C_IDENTIFIER "${MDBX_GIT_DESCRIBE}" MDBX_SOURCERY_SUFFIX) -set(MDBX_BUILD_SOURCERY "${MDBX_SOURCERY_DIGEST}_${MDBX_SOURCERY_SUFFIX}") - -configure_file("${CMAKE_CURRENT_SOURCE_DIR}/elements/config.h.in" - "${CMAKE_CURRENT_SOURCE_DIR}/elements/config.h" ESCAPE_QUOTES) -add_definitions(-DMDBX_CONFIG_H="config.h") - -# installation -if(MDBX_BUILD_SHARED_LIBRARY) - if(CMAKE_VERSION VERSION_LESS 3.12) - install(TARGETS mdbx EXPORT libmdbx - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) - else() - install(TARGETS mdbx EXPORT libmdbx - RUNTIME - DESTINATION bin - COMPONENT runtime - LIBRARY - DESTINATION lib - COMPONENT runtime - NAMELINK_COMPONENT devel - OBJECTS - DESTINATION lib - COMPONENT devel - ARCHIVE - DESTINATION lib - COMPONENT devel - PUBLIC_HEADER - DESTINATION include - COMPONENT devel - INCLUDES - DESTINATION include - COMPONENT devel) - endif() -endif() - -add_subdirectory(tools) diff --git a/libs/libmdbx/src/src/alloy.c b/libs/libmdbx/src/src/alloy.c index befdf8be45..c2b512005d 100644 --- a/libs/libmdbx/src/src/alloy.c +++ b/libs/libmdbx/src/src/alloy.c @@ -11,15 +11,15 @@ * top-level directory of the distribution or, alternatively, at * <http://www.OpenLDAP.org/license.html>. */ -#define MDBX_ALLOY 1 /* amalgamated build */ -#include "elements/internals.h" /* must be included first */ +#define MDBX_ALLOY 1 /* alloyed build */ +#include "internals.h" /* must be included first */ -#include "elements/core.c" -#include "elements/osal.c" -#include "elements/version.c" +#include "core.c" +#include "osal.c" +#include "version.c" #if defined(_WIN32) || defined(_WIN64) -#include "elements/lck-windows.c" +#include "lck-windows.c" #else -#include "elements/lck-posix.c" +#include "lck-posix.c" #endif diff --git a/libs/libmdbx/src/src/elements/config.h.in b/libs/libmdbx/src/src/config.h.in index b8776d98a2..12f3dc635c 100644 --- a/libs/libmdbx/src/src/elements/config.h.in +++ b/libs/libmdbx/src/src/config.h.in @@ -4,9 +4,6 @@ /* *INDENT-OFF* */ /* clang-format off */ -#cmakedefine HAVE_VALGRIND_MEMCHECK_H -#cmakedefine HAS_RELAXED_CONSTEXPR - #cmakedefine LTO_ENABLED #cmakedefine MDBX_USE_VALGRIND #cmakedefine ENABLE_GPROF @@ -20,7 +17,6 @@ #ifndef MDBX_TXN_CHECKPID_AUTO #cmakedefine01 MDBX_TXN_CHECKPID #endif -#cmakedefine01 MDBX_BUILD_SHARED_LIBRARY #cmakedefine MDBX_LOCKING_AUTO #ifndef MDBX_LOCKING_AUTO #cmakedefine MDBX_LOCKING @MDBX_LOCKING@ @@ -34,7 +30,7 @@ #cmakedefine01 MDBX_CONFIG_MANUAL_TLS_CALLBACK #cmakedefine01 MDBX_AVOID_CRT -/* MacOS */ +/* MacOS & iOS */ #cmakedefine01 MDBX_OSX_SPEED_INSTEADOF_DURABILITY /* POSIX */ @@ -47,7 +43,7 @@ /* Build Info */ #cmakedefine MDBX_BUILD_TIMESTAMP "@MDBX_BUILD_TIMESTAMP@" #cmakedefine MDBX_BUILD_TARGET "@MDBX_BUILD_TARGET@" -#cmakedefine MDBX_BUILD_CONFIG "@MDBX_BUILD_CONFIG@" +#cmakedefine MDBX_BUILD_TYPE "@MDBX_BUILD_TYPE@" #cmakedefine MDBX_BUILD_COMPILER "@MDBX_BUILD_COMPILER@" #cmakedefine MDBX_BUILD_FLAGS "@MDBX_BUILD_FLAGS@" #cmakedefine MDBX_BUILD_SOURCERY @MDBX_BUILD_SOURCERY@ diff --git a/libs/libmdbx/src/src/elements/core.c b/libs/libmdbx/src/src/core.c index 6a5b079493..098da86f45 100644 --- a/libs/libmdbx/src/src/elements/core.c +++ b/libs/libmdbx/src/src/core.c @@ -328,17 +328,17 @@ node_largedata_pgno(const MDBX_node *const __restrict node) { */ #define PAGEROOM(pagesize) ((pagesize)-PAGEHDRSZ) -#define EVEN_FLOOR(n) ((n) & ~1ul) +#define EVEN_FLOOR(n) ((n) & ~(size_t)1) #define BRANCH_NODEMAX(pagesize) \ (EVEN_FLOOR(PAGEROOM(pagesize) / (MDBX_MINKEYS * 2 - 1)) - sizeof(indx_t)) #define LEAF_NODEMAX(pagesize) (PAGEROOM(pagesize) - sizeof(indx_t)) #define MAX_GC1OVPAGE(pagesize) (PAGEROOM(pagesize) / sizeof(pgno_t) - 1) -__cold int mdbx_env_get_maxkeysize(MDBX_env *env) { +__cold int mdbx_env_get_maxkeysize(const MDBX_env *env) { return mdbx_env_get_maxkeysize_ex(env, MDBX_DUPSORT); } -__cold int mdbx_env_get_maxkeysize_ex(MDBX_env *env, unsigned flags) { +__cold int mdbx_env_get_maxkeysize_ex(const MDBX_env *env, unsigned flags) { if (unlikely(!env || env->me_signature != MDBX_ME_SIGNATURE)) return -1; @@ -370,7 +370,7 @@ __cold intptr_t mdbx_limits_keysize_max(intptr_t pagesize, unsigned flags) { return BRANCH_NODEMAX(pagesize) - NODESIZE - sizeof(pgno_t); } -__cold int mdbx_env_get_maxvalsize_ex(MDBX_env *env, unsigned flags) { +__cold int mdbx_env_get_maxvalsize_ex(const MDBX_env *env, unsigned flags) { if (unlikely(!env || env->me_signature != MDBX_ME_SIGNATURE)) return -1; @@ -489,7 +489,7 @@ static __pure_function __always_inline pgno_t bytes2pgno(const MDBX_env *env, static __pure_function size_t pgno_align2os_bytes(const MDBX_env *env, pgno_t pgno) { - return roundup_powerof2(pgno2bytes(env, pgno), env->me_os_psize); + return ceil_powerof2(pgno2bytes(env, pgno), env->me_os_psize); } static __pure_function pgno_t pgno_align2os_pgno(const MDBX_env *env, @@ -499,8 +499,7 @@ static __pure_function pgno_t pgno_align2os_pgno(const MDBX_env *env, static __pure_function size_t bytes_align2os_bytes(const MDBX_env *env, size_t bytes) { - return roundup_powerof2(roundup_powerof2(bytes, env->me_psize), - env->me_os_psize); + return ceil_powerof2(ceil_powerof2(bytes, env->me_psize), env->me_os_psize); } /* Address of first usable data byte in a page, after the header */ @@ -1012,13 +1011,13 @@ static __inline int thread_key_create(mdbx_thread_key_t *key) { #else rc = pthread_key_create(key, nullptr); #endif - mdbx_trace("&key = %p, value 0x%x, rc %d", __Wpedantic_format_voidptr(key), - (unsigned)*key, rc); + mdbx_trace("&key = %p, value %" PRIuPTR ", rc %d", + __Wpedantic_format_voidptr(key), (uintptr_t)*key, rc); return rc; } static __inline void thread_key_delete(mdbx_thread_key_t key) { - mdbx_trace("key = 0x%x", (unsigned)key); + mdbx_trace("key = %" PRIuPTR, (uintptr_t)key); #if defined(_WIN32) || defined(_WIN64) mdbx_ensure(nullptr, TlsFree(key)); #else @@ -1045,7 +1044,7 @@ static void thread_rthc_set(mdbx_thread_key_t key, const void *value) { static __thread uint32_t thread_registration_state; if (value && unlikely(thread_registration_state == MDBX_THREAD_RTHC_ZERO)) { thread_registration_state = MDBX_THREAD_RTHC_REGISTERD; - mdbx_trace("thread registered 0x%" PRIxPTR, (uintptr_t)mdbx_thread_self()); + mdbx_trace("thread registered 0x%" PRIxPTR, mdbx_thread_self()); if (&__cxa_thread_atexit_impl == nullptr || __cxa_thread_atexit_impl(mdbx_rthc_thread_dtor, &thread_registration_state, @@ -1055,8 +1054,8 @@ static void thread_rthc_set(mdbx_thread_key_t key, const void *value) { thread_registration_state = MDBX_THREAD_RTHC_COUNTED; const unsigned count_before = atomic_add32(&rthc_pending, 1); mdbx_ensure(nullptr, count_before < INT_MAX); - mdbx_trace("fallback to pthreads' tsd, key 0x%x, count %u", - (unsigned)rthc_key, count_before); + mdbx_trace("fallback to pthreads' tsd, key %" PRIuPTR ", count %u", + (uintptr_t)rthc_key, count_before); (void)count_before; } } @@ -1098,7 +1097,7 @@ __cold void mdbx_rthc_global_init(void) { __cold void mdbx_rthc_thread_dtor(void *ptr) { rthc_lock(); mdbx_trace(">> pid %d, thread 0x%" PRIxPTR ", rthc %p", mdbx_getpid(), - (uintptr_t)mdbx_thread_self(), ptr); + mdbx_thread_self(), ptr); const uint32_t self_pid = mdbx_getpid(); for (unsigned i = 0; i < rthc_count; ++i) { @@ -1112,7 +1111,7 @@ __cold void mdbx_rthc_thread_dtor(void *ptr) { if (pthread_setspecific(key, nullptr) != 0) { mdbx_trace("== thread 0x%" PRIxPTR ", rthc %p: ignore race with tsd-key deletion", - (uintptr_t)mdbx_thread_self(), ptr); + mdbx_thread_self(), ptr); continue /* ignore race with tsd-key deletion by mdbx_env_close() */; } #endif @@ -1120,39 +1119,35 @@ __cold void mdbx_rthc_thread_dtor(void *ptr) { mdbx_trace("== thread 0x%" PRIxPTR ", rthc %p, [%i], %p ... %p (%+i), rtch-pid %i, " "current-pid %i", - (uintptr_t)mdbx_thread_self(), __Wpedantic_format_voidptr(rthc), - i, __Wpedantic_format_voidptr(rthc_table[i].begin), + mdbx_thread_self(), __Wpedantic_format_voidptr(rthc), i, + __Wpedantic_format_voidptr(rthc_table[i].begin), __Wpedantic_format_voidptr(rthc_table[i].end), (int)(rthc - rthc_table[i].begin), rthc->mr_pid, self_pid); if (rthc->mr_pid == self_pid) { mdbx_trace("==== thread 0x%" PRIxPTR ", rthc %p, cleanup", - (uintptr_t)mdbx_thread_self(), - __Wpedantic_format_voidptr(rthc)); + mdbx_thread_self(), __Wpedantic_format_voidptr(rthc)); rthc->mr_pid = 0; } } #if defined(_WIN32) || defined(_WIN64) - mdbx_trace("<< thread 0x%" PRIxPTR ", rthc %p", (uintptr_t)mdbx_thread_self(), - ptr); + mdbx_trace("<< thread 0x%" PRIxPTR ", rthc %p", mdbx_thread_self(), ptr); rthc_unlock(); #else const char self_registration = *(char *)ptr; *(char *)ptr = MDBX_THREAD_RTHC_ZERO; mdbx_trace("== thread 0x%" PRIxPTR ", rthc %p, pid %d, self-status %d", - (uintptr_t)mdbx_thread_self(), ptr, mdbx_getpid(), - self_registration); + mdbx_thread_self(), ptr, mdbx_getpid(), self_registration); if (self_registration == MDBX_THREAD_RTHC_COUNTED) mdbx_ensure(nullptr, atomic_sub32(&rthc_pending, 1) > 0); if (rthc_pending == 0) { mdbx_trace("== thread 0x%" PRIxPTR ", rthc %p, pid %d, wake", - (uintptr_t)mdbx_thread_self(), ptr, mdbx_getpid()); + mdbx_thread_self(), ptr, mdbx_getpid()); mdbx_ensure(nullptr, pthread_cond_broadcast(&rthc_cond) == 0); } - mdbx_trace("<< thread 0x%" PRIxPTR ", rthc %p", (uintptr_t)mdbx_thread_self(), - ptr); + mdbx_trace("<< thread 0x%" PRIxPTR ", rthc %p", mdbx_thread_self(), ptr); /* Allow tail call optimization, i.e. gcc should generate the jmp instruction * instead of a call for pthread_mutex_unlock() and therefore CPU could not * return to current DSO's code section, which may be unloaded immediately @@ -1168,7 +1163,7 @@ __cold void mdbx_rthc_global_dtor(void) { #if !defined(_WIN32) && !defined(_WIN64) char *rthc = (char *)pthread_getspecific(rthc_key); mdbx_trace("== thread 0x%" PRIxPTR ", rthc %p, pid %d, self-status %d", - (uintptr_t)mdbx_thread_self(), __Wpedantic_format_voidptr(rthc), + mdbx_thread_self(), __Wpedantic_format_voidptr(rthc), mdbx_getpid(), rthc ? *rthc : -1); if (rthc) { const char self_registration = *(char *)rthc; @@ -1205,9 +1200,9 @@ __cold void mdbx_rthc_global_dtor(void) { thread_key_delete(key); for (MDBX_reader *rthc = rthc_table[i].begin; rthc < rthc_table[i].end; ++rthc) { - mdbx_trace("== [%i] = key %zu, %p ... %p, rthc %p (%+i), " + mdbx_trace("== [%i] = key %" PRIuPTR ", %p ... %p, rthc %p (%+i), " "rthc-pid %i, current-pid %i", - i, (size_t)key, + i, (uintptr_t)key, __Wpedantic_format_voidptr(rthc_table[i].begin), __Wpedantic_format_voidptr(rthc_table[i].end), __Wpedantic_format_voidptr(rthc), @@ -1251,8 +1246,8 @@ __cold int mdbx_rthc_alloc(mdbx_thread_key_t *key, MDBX_reader *begin, rthc_lock(); const mdbx_thread_key_t new_key = key ? *key : 0; - mdbx_trace(">> key %zu, rthc_count %u, rthc_limit %u", (size_t)new_key, - rthc_count, rthc_limit); + mdbx_trace(">> key %" PRIuPTR ", rthc_count %u, rthc_limit %u", + (uintptr_t)new_key, rthc_count, rthc_limit); if (rthc_count == rthc_limit) { rthc_entry_t *new_table = mdbx_realloc((rthc_table == rthc_table_static) ? nullptr : rthc_table, @@ -1266,16 +1261,16 @@ __cold int mdbx_rthc_alloc(mdbx_thread_key_t *key, MDBX_reader *begin, rthc_table = new_table; rthc_limit *= 2; } - mdbx_trace("== [%i] = key %zu, %p ... %p", rthc_count, (size_t)new_key, - __Wpedantic_format_voidptr(begin), + mdbx_trace("== [%i] = key %" PRIuPTR ", %p ... %p", rthc_count, + (uintptr_t)new_key, __Wpedantic_format_voidptr(begin), __Wpedantic_format_voidptr(end)); rthc_table[rthc_count].key_valid = key ? true : false; rthc_table[rthc_count].thr_tls_key = key ? new_key : 0; rthc_table[rthc_count].begin = begin; rthc_table[rthc_count].end = end; ++rthc_count; - mdbx_trace("<< key %zu, rthc_count %u, rthc_limit %u", (size_t)new_key, - rthc_count, rthc_limit); + mdbx_trace("<< key %" PRIuPTR ", rthc_count %u, rthc_limit %u", + (uintptr_t)new_key, rthc_count, rthc_limit); rthc_unlock(); return MDBX_SUCCESS; @@ -1324,7 +1319,7 @@ __cold void mdbx_rthc_remove(const mdbx_thread_key_t key) { //------------------------------------------------------------------------------ -#define RTHC_ENVLIST_END ((MDBX_env *)((size_t)50459)) +#define RTHC_ENVLIST_END ((MDBX_env *)((uintptr_t)50459)) static MDBX_env *inprocess_lcklist_head = RTHC_ENVLIST_END; static __inline void lcklist_lock(void) { @@ -1378,8 +1373,8 @@ static int uniq_peek(const mdbx_mmap_t *pending, mdbx_mmap_t *scan) { static int uniq_poke(const mdbx_mmap_t *pending, mdbx_mmap_t *scan, uint64_t *abra) { if (*abra == 0) { - const size_t tid = mdbx_thread_self(); - size_t uit = 0; + const uintptr_t tid = mdbx_thread_self(); + uintptr_t uit = 0; memcpy(&uit, &tid, (sizeof(tid) < sizeof(uit)) ? sizeof(tid) : sizeof(uit)); *abra = rrxmrrxmsx_0(mdbx_osal_monotime() + UINT64_C(5873865991930747) * uit); @@ -2539,10 +2534,10 @@ static int lcklist_detach_locked(MDBX_env *env) { static __always_inline size_t pnl2bytes(const size_t size) { assert(size > 0 && size <= MDBX_PNL_MAX * 2); - size_t bytes = roundup_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + - sizeof(pgno_t) * (size + 2), - MDBX_PNL_GRANULATE * sizeof(pgno_t)) - - MDBX_ASSUME_MALLOC_OVERHEAD; + size_t bytes = + ceil_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + sizeof(pgno_t) * (size + 2), + MDBX_PNL_GRANULATE * sizeof(pgno_t)) - + MDBX_ASSUME_MALLOC_OVERHEAD; return bytes; } @@ -2806,10 +2801,10 @@ static __hot unsigned mdbx_pnl_exist(MDBX_PNL pnl, pgno_t id) { static __always_inline size_t txl2bytes(const size_t size) { assert(size > 0 && size <= MDBX_TXL_MAX * 2); - size_t bytes = roundup_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + - sizeof(txnid_t) * (size + 2), - MDBX_TXL_GRANULATE * sizeof(txnid_t)) - - MDBX_ASSUME_MALLOC_OVERHEAD; + size_t bytes = + ceil_powerof2(MDBX_ASSUME_MALLOC_OVERHEAD + sizeof(txnid_t) * (size + 2), + MDBX_TXL_GRANULATE * sizeof(txnid_t)) - + MDBX_ASSUME_MALLOC_OVERHEAD; return bytes; } @@ -3135,8 +3130,8 @@ static int __must_check_result mdbx_page_check(MDBX_env *env, static int __must_check_result mdbx_cursor_check(MDBX_cursor *mc, bool pending); static int __must_check_result mdbx_cursor_del0(MDBX_cursor *mc); static int __must_check_result mdbx_del0(MDBX_txn *txn, MDBX_dbi dbi, - MDBX_val *key, MDBX_val *data, - unsigned flags); + const MDBX_val *key, + const MDBX_val *data, unsigned flags); static int __must_check_result mdbx_cursor_sibling(MDBX_cursor *mc, int move_right); static int __must_check_result mdbx_cursor_next(MDBX_cursor *mc, MDBX_val *key, @@ -3185,7 +3180,8 @@ static const char *__mdbx_strerr(int errnum) { NULL /* MDBX_TLS_FULL (-30789): unused in MDBX */, "MDBX_TXN_FULL: Transaction has too many dirty pages," " i.e transaction is too big", - "MDBX_CURSOR_FULL: Internal error - Cursor stack limit reached", + "MDBX_CURSOR_FULL: Cursor stack limit reachedn - this usually indicates" + " corruption, i.e branch-pages loop", "MDBX_PAGE_FULL: Internal error - Page has no more space", "MDBX_UNABLE_EXTEND_MAPSIZE: Database engine was unable to extend" " mapping, e.g. since address space is unavailable or busy," @@ -3522,13 +3518,13 @@ static __maybe_unused void mdbx_page_list(MDBX_page *mp) { *tp = tracked->mc_next; \ } while (0) -int mdbx_cmp(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, +int mdbx_cmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b) { mdbx_assert(NULL, txn->mt_signature == MDBX_MT_SIGNATURE); return txn->mt_dbxs[dbi].md_cmp(a, b); } -int mdbx_dcmp(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, +int mdbx_dcmp(const MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *a, const MDBX_val *b) { mdbx_assert(NULL, txn->mt_signature == MDBX_MT_SIGNATURE); return txn->mt_dbxs[dbi].md_dcmp(a, b); @@ -4143,7 +4139,8 @@ mark_done: * [in] data For a put operation, the data being stored. * * Returns 0 on success, non-zero on failure. */ -static int mdbx_page_spill(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data) { +static int mdbx_page_spill(MDBX_cursor *mc, const MDBX_val *key, + const MDBX_val *data) { if (mc->mc_flags & C_SUB) return MDBX_SUCCESS; @@ -4438,7 +4435,7 @@ static const char *mdbx_durable_str(const MDBX_meta *const meta) { /*----------------------------------------------------------------------------*/ /* Find oldest txnid still referenced. */ -static txnid_t mdbx_find_oldest(MDBX_txn *txn) { +static txnid_t mdbx_find_oldest(const MDBX_txn *txn) { mdbx_tassert(txn, (txn->mt_flags & MDBX_RDONLY) == 0); MDBX_env *env = txn->mt_env; const txnid_t edge = mdbx_recent_steady_txnid(env); @@ -4835,7 +4832,9 @@ __cold static int mdbx_wipe_steady(MDBX_env *env, const txnid_t last_steady) { if (unlikely(err != MDBX_SUCCESS)) return err; } else { -#if (defined(__linux__) || defined(__gnu_linux__)) && !defined(MDBX_SAFE4QEMU) +#if (defined(__linux__) || defined(__gnu_linux__)) && \ + (!defined(__ANDROID_API__) || __ANDROID_API__ >= 26) && \ + defined(_GNU_SOURCE) && !defined(MDBX_SAFE4QEMU) if (sync_file_range(env->me_lazy_fd, 0, pgno2bytes(env, NUM_METAS), SYNC_FILE_RANGE_WRITE | SYNC_FILE_RANGE_WAIT_AFTER)) err = errno; @@ -4937,7 +4936,7 @@ skip_cache: goto fail; } - MDBX_cursor recur; + MDBX_cursor_couple recur; for (MDBX_cursor_op op = MDBX_FIRST;; op = (flags & MDBX_LIFORECLAIM) ? MDBX_PREV : MDBX_NEXT) { MDBX_val key, data; @@ -4983,7 +4982,7 @@ skip_cache: /* Prepare to fetch more and coalesce */ oldest = (flags & MDBX_LIFORECLAIM) ? mdbx_find_oldest(txn) : *env->me_oldest; - rc = mdbx_cursor_init(&recur, txn, FREE_DBI); + rc = mdbx_cursor_init(&recur.outer, txn, FREE_DBI); if (unlikely(rc != MDBX_SUCCESS)) goto fail; if (flags & MDBX_LIFORECLAIM) { @@ -5011,7 +5010,7 @@ skip_cache: } } - rc = mdbx_cursor_get(&recur, &key, NULL, op); + rc = mdbx_cursor_get(&recur.outer, &key, NULL, op); if (rc == MDBX_NOTFOUND && (flags & MDBX_LIFORECLAIM)) { if (op == MDBX_SET_RANGE) continue; @@ -5022,7 +5021,7 @@ skip_cache: key.iov_base = &last; key.iov_len = sizeof(last); op = MDBX_SET_RANGE; - rc = mdbx_cursor_get(&recur, &key, NULL, op); + rc = mdbx_cursor_get(&recur.outer, &key, NULL, op); } } if (unlikely(rc)) { @@ -5062,9 +5061,10 @@ skip_cache: } /* Reading next GC record */ - np = recur.mc_pg[recur.mc_top]; + np = recur.outer.mc_pg[recur.outer.mc_top]; if (unlikely((rc = mdbx_node_read( - &recur, page_node(np, recur.mc_ki[recur.mc_top]), + &recur.outer, + page_node(np, recur.outer.mc_ki[recur.outer.mc_top]), &data)) != MDBX_SUCCESS)) goto fail; @@ -5352,8 +5352,8 @@ __hot static void mdbx_page_copy(MDBX_page *dst, MDBX_page *src, size_t psize) { /* If page isn't full, just copy the used portion. Adjust * alignment so memcpy may copy words instead of bytes. */ if (unused >= MDBX_CACHELINE_SIZE * 2) { - lower = roundup_powerof2(lower + PAGEHDRSZ, sizeof(void *)); - upper = (upper + PAGEHDRSZ) & ~(sizeof(void *) - 1); + lower = ceil_powerof2(lower + PAGEHDRSZ, sizeof(void *)); + upper = floor_powerof2(upper + PAGEHDRSZ, sizeof(void *)); memcpy(dst, src, lower); dst = (void *)((char *)dst + upper); src = (void *)((char *)src + upper); @@ -5528,20 +5528,8 @@ fail: return rc; } -__cold int mdbx_env_sync_ex(MDBX_env *env, int force, int nonblock) { - if (unlikely(!env)) - return MDBX_EINVAL; - - if (unlikely(env->me_signature != MDBX_ME_SIGNATURE)) - return MDBX_EBADSIGN; - -#if MDBX_TXN_CHECKPID - if (unlikely(env->me_pid != mdbx_getpid())) { - env->me_flags |= MDBX_FATAL_ERROR; - return MDBX_PANIC; - } -#endif /* MDBX_TXN_CHECKPID */ - +__cold static int mdbx_env_sync_internal(MDBX_env *env, int force, + int nonblock) { unsigned flags = env->me_flags & ~MDBX_NOMETASYNC; if (unlikely(flags & (MDBX_RDONLY | MDBX_FATAL_ERROR))) return MDBX_EACCESS; @@ -5636,6 +5624,23 @@ fastpath: return rc; } +__cold int mdbx_env_sync_ex(MDBX_env *env, int force, int nonblock) { + if (unlikely(!env)) + return MDBX_EINVAL; + + if (unlikely(env->me_signature != MDBX_ME_SIGNATURE)) + return MDBX_EBADSIGN; + +#if MDBX_TXN_CHECKPID + if (unlikely(env->me_pid != mdbx_getpid())) { + env->me_flags |= MDBX_FATAL_ERROR; + return MDBX_PANIC; + } +#endif /* MDBX_TXN_CHECKPID */ + + return mdbx_env_sync_internal(env, force, nonblock); +} + __cold int mdbx_env_sync(MDBX_env *env) { return mdbx_env_sync_ex(env, true, false); } @@ -5775,6 +5780,9 @@ static void mdbx_txn_valgrind(MDBX_env *env, MDBX_txn *txn) { /* inside write-txn */ MDBX_meta *head = mdbx_meta_head(env); last = head->mm_geo.next; + } else if (env->me_flags & MDBX_RDONLY) { + /* read-only mode, no write-txn, no wlock mutex */ + last = NUM_METAS; } else if (mdbx_txn_lock(env, true) == MDBX_SUCCESS) { /* no write-txn */ last = NUM_METAS; @@ -5827,12 +5835,12 @@ static int mdbx_txn_renew0(MDBX_txn *txn, unsigned flags) { mdbx_assert(env, (flags & ~(MDBX_TXN_BEGIN_FLAGS | MDBX_TXN_SPILLS | MDBX_WRITEMAP)) == 0); - const size_t tid = mdbx_thread_self(); + const uintptr_t tid = mdbx_thread_self(); if (flags & MDBX_RDONLY) { txn->mt_flags = MDBX_RDONLY | (env->me_flags & (MDBX_NOTLS | MDBX_WRITEMAP)); MDBX_reader *r = txn->to.reader; - STATIC_ASSERT(sizeof(size_t) == sizeof(r->mr_tid)); + STATIC_ASSERT(sizeof(uintptr_t) == sizeof(r->mr_tid)); if (likely(env->me_flags & MDBX_ENV_TXKEY)) { mdbx_assert(env, !(env->me_flags & MDBX_NOTLS)); r = thread_rthc_get(env->me_txkey); @@ -6315,7 +6323,7 @@ int mdbx_txn_begin(MDBX_env *env, MDBX_txn *parent, unsigned flags, return rc; } -int mdbx_txn_info(MDBX_txn *txn, MDBX_txn_info *info, int scan_rlt) { +int mdbx_txn_info(const MDBX_txn *txn, MDBX_txn_info *info, int scan_rlt) { int rc = check_txn(txn, MDBX_TXN_BLOCKED - MDBX_TXN_HAS_CHILD); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -6429,20 +6437,20 @@ int mdbx_txn_info(MDBX_txn *txn, MDBX_txn_info *info, int scan_rlt) { return MDBX_SUCCESS; } -MDBX_env *mdbx_txn_env(MDBX_txn *txn) { +MDBX_env *mdbx_txn_env(const MDBX_txn *txn) { if (unlikely(!txn || txn->mt_signature != MDBX_MT_SIGNATURE || txn->mt_env->me_signature != MDBX_ME_SIGNATURE)) return NULL; return txn->mt_env; } -uint64_t mdbx_txn_id(MDBX_txn *txn) { +uint64_t mdbx_txn_id(const MDBX_txn *txn) { if (unlikely(!txn || txn->mt_signature != MDBX_MT_SIGNATURE)) return 0; return txn->mt_txnid; } -int mdbx_txn_flags(MDBX_txn *txn) { +int mdbx_txn_flags(const MDBX_txn *txn) { if (unlikely(!txn || txn->mt_signature != MDBX_MT_SIGNATURE)) return -1; return txn->mt_flags; @@ -8145,7 +8153,7 @@ static int __cold mdbx_validate_meta(MDBX_env *env, MDBX_meta *const meta, const uint64_t mapsize_max = meta->mm_geo.upper * (uint64_t)meta->mm_psize; STATIC_ASSERT(MIN_MAPSIZE < MAX_MAPSIZE); if (mapsize_max > MAX_MAPSIZE || - MAX_PAGENO < roundup_powerof2((size_t)mapsize_max, env->me_os_psize) / + MAX_PAGENO < ceil_powerof2((size_t)mapsize_max, env->me_os_psize) / (size_t)meta->mm_psize) { if (meta->mm_geo.next - 1 > MAX_PAGENO || used_bytes > MAX_MAPSIZE) { mdbx_notice("meta[%u] has too large max-mapsize (%" PRIu64 "), skip it", @@ -8407,27 +8415,26 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, #endif /* MDBX_USE_VALGRIND || __SANITIZE_ADDRESS__ */ #if defined(MADV_DONTNEED) const size_t largest_bytes = pgno2bytes(env, largest_pgno); - const size_t madvise_gap = (largest_bytes < 65536 * 256) - ? 65536 - : (largest_bytes > MEGABYTE * 4 * 256) - ? MEGABYTE * 4 - : largest_bytes >> 8; + /* threshold to avoid unreasonable frequent madvise() calls */ + const size_t madvise_treshold = (largest_bytes < 65536 * 256) + ? 65536 + : (largest_bytes > MEGABYTE * 4 * 256) + ? MEGABYTE * 4 + : largest_bytes >> 10; const size_t discard_edge_bytes = bytes_align2os_bytes( - env, - (MDBX_RDONLY & (env->me_lck ? env->me_lck->mti_envmode : env->me_flags)) - ? largest_bytes - : largest_bytes + madvise_gap); + env, ((MDBX_RDONLY & + (env->me_lck ? env->me_lck->mti_envmode : env->me_flags)) + ? largest_bytes + : largest_bytes + madvise_treshold)); const pgno_t discard_edge_pgno = bytes2pgno(env, discard_edge_bytes); const pgno_t prev_discarded_pgno = *env->me_discarded_tail; - if (prev_discarded_pgno > - discard_edge_pgno + - /* threshold to avoid unreasonable frequent madvise() calls */ - bytes2pgno(env, madvise_gap)) { + if (prev_discarded_pgno >= + discard_edge_pgno + bytes2pgno(env, madvise_treshold)) { mdbx_notice("open-MADV_%s %u..%u", "DONTNEED", *env->me_discarded_tail, largest_pgno); *env->me_discarded_tail = discard_edge_pgno; const size_t prev_discarded_bytes = - pgno2bytes(env, prev_discarded_pgno) & ~(env->me_os_psize - 1); + ceil_powerof2(pgno2bytes(env, prev_discarded_pgno), env->me_os_psize); mdbx_ensure(env, prev_discarded_bytes > discard_edge_bytes); int advise = MADV_DONTNEED; #if defined(MADV_FREE) && \ @@ -8482,7 +8489,8 @@ static int mdbx_sync_locked(MDBX_env *env, unsigned flags, mdbx_assert(env, ((flags ^ env->me_flags) & MDBX_WRITEMAP) == 0); MDBX_meta *const recent_steady_meta = mdbx_meta_steady(env); if (flags & MDBX_WRITEMAP) { - const size_t begin = pgno2bytes(env, NUM_METAS) & ~(env->me_os_psize - 1); + const size_t begin = + floor_powerof2(pgno2bytes(env, NUM_METAS), env->me_os_psize); const size_t end = pgno_align2os_bytes(env, pending->mm_geo.next); if (end > begin) { rc = mdbx_msync(&env->me_dxb_mmap, begin, end - begin, @@ -8926,9 +8934,9 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, const size_t unit = (env->me_os_psize > (size_t)pagesize) ? env->me_os_psize : pagesize; - size_lower = roundup_powerof2(size_lower, unit); - size_upper = roundup_powerof2(size_upper, unit); - size_now = roundup_powerof2(size_now, unit); + size_lower = ceil_powerof2(size_lower, unit); + size_upper = ceil_powerof2(size_upper, unit); + size_now = ceil_powerof2(size_now, unit); /* LY: подбираем значение size_upper: * - кратное размеру страницы @@ -8963,13 +8971,13 @@ mdbx_env_set_geometry(MDBX_env *env, intptr_t size_lower, intptr_t size_now, } if (growth_step == 0 && shrink_threshold > 0) growth_step = 1; - growth_step = roundup_powerof2(growth_step, unit); + growth_step = ceil_powerof2(growth_step, unit); if (bytes2pgno(env, growth_step) > UINT16_MAX) growth_step = pgno2bytes(env, UINT16_MAX); if (shrink_threshold < 0) shrink_threshold = growth_step + growth_step; - shrink_threshold = roundup_powerof2(shrink_threshold, unit); + shrink_threshold = ceil_powerof2(shrink_threshold, unit); if (bytes2pgno(env, shrink_threshold) > UINT16_MAX) shrink_threshold = pgno2bytes(env, UINT16_MAX); @@ -9145,7 +9153,7 @@ int __cold mdbx_env_set_maxreaders(MDBX_env *env, unsigned readers) { return MDBX_SUCCESS; } -int __cold mdbx_env_get_maxreaders(MDBX_env *env, unsigned *readers) { +int __cold mdbx_env_get_maxreaders(const MDBX_env *env, unsigned *readers) { if (!env || !readers) return MDBX_EINVAL; @@ -9209,7 +9217,7 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) { mdbx_setup_pagesize(env, meta.mm_psize); const size_t used_bytes = pgno2bytes(env, meta.mm_geo.next); const size_t used_aligned2os_bytes = - roundup_powerof2(used_bytes, env->me_os_psize); + ceil_powerof2(used_bytes, env->me_os_psize); if ((env->me_flags & MDBX_RDONLY) /* readonly */ || lck_rc != MDBX_RESULT_TRUE /* not exclusive */) { /* use present params from db */ @@ -9434,8 +9442,8 @@ static int __cold mdbx_setup_dxb(MDBX_env *env, const int lck_rc) { head->mm_datasync_sign = MDBX_DATASIGN_WEAK; head->mm_txnid_b.inconsistent = undo_txnid; const size_t offset = (uint8_t *)data_page(head) - env->me_dxb_mmap.dxb; - const size_t paged_offset = offset & ~(env->me_os_psize - 1); - const size_t paged_length = roundup_powerof2( + const size_t paged_offset = floor_powerof2(offset, env->me_os_psize); + const size_t paged_length = ceil_powerof2( env->me_psize + offset - paged_offset, env->me_os_psize); err = mdbx_msync(&env->me_dxb_mmap, paged_offset, paged_length, false); } else { @@ -9665,9 +9673,9 @@ static int __cold mdbx_setup_lck(MDBX_env *env, char *lck_pathname, goto bailout; if (lck_seize_rc == MDBX_RESULT_TRUE) { - size = roundup_powerof2(env->me_maxreaders * sizeof(MDBX_reader) + - sizeof(MDBX_lockinfo), - env->me_os_psize); + size = ceil_powerof2(env->me_maxreaders * sizeof(MDBX_reader) + + sizeof(MDBX_lockinfo), + env->me_os_psize); mdbx_jitter4testing(false); } else { if (env->me_flags & MDBX_EXCLUSIVE) { @@ -10149,12 +10157,13 @@ int __cold mdbx_env_open(MDBX_env *env, const char *pathname, unsigned flags, #endif bailout: -#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__) - mdbx_txn_valgrind(env, nullptr); -#endif - if (rc) { + if (rc != MDBX_SUCCESS) { rc = mdbx_env_close0(env) ? MDBX_PANIC : rc; env->me_flags = saved_me_flags | MDBX_FATAL_ERROR; + } else { +#if defined(MDBX_USE_VALGRIND) || defined(__SANITIZE_ADDRESS__) + mdbx_txn_valgrind(env, nullptr); +#endif } mdbx_free(lck_pathname); return rc; @@ -10167,6 +10176,7 @@ static int __cold mdbx_env_close0(MDBX_env *env) { return MDBX_SUCCESS; } + env->me_signature = 0; env->me_flags &= ~MDBX_ENV_ACTIVE; env->me_oldest = nullptr; env->me_sync_timestamp = nullptr; @@ -10251,37 +10261,34 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) { if ((env->me_flags & (MDBX_RDONLY | MDBX_FATAL_ERROR)) == 0 && env->me_txn0) { if (env->me_txn0->mt_owner && env->me_txn0->mt_owner != mdbx_thread_self()) return MDBX_BUSY; - if (!dont_sync) { + } else + dont_sync = true; + + if (!atomic_cas32(&env->me_signature, MDBX_ME_SIGNATURE, 0)) + return MDBX_EBADSIGN; + + if (!dont_sync) { #if defined(_WIN32) || defined(_WIN64) - /* On windows, without blocking is impossible to determine whether another - * process is running a writing transaction or not. - * Because in the "owner died" condition kernel don't release - * file lock immediately. */ - rc = mdbx_env_sync_ex(env, true, false); - rc = (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; + /* On windows, without blocking is impossible to determine whether another + * process is running a writing transaction or not. + * Because in the "owner died" condition kernel don't release + * file lock immediately. */ + rc = mdbx_env_sync_internal(env, true, false); + rc = (rc == MDBX_RESULT_TRUE) ? MDBX_SUCCESS : rc; #else - struct stat st; - if (unlikely(fstat(env->me_lazy_fd, &st))) - rc = errno; - else if (st.st_nlink > 0 /* don't sync deleted files */) { - rc = mdbx_env_sync_ex(env, true, true); - rc = (rc == MDBX_BUSY || rc == EAGAIN || rc == EACCES || rc == EBUSY || - rc == EWOULDBLOCK || rc == MDBX_RESULT_TRUE) - ? MDBX_SUCCESS - : rc; - } -#endif + struct stat st; + if (unlikely(fstat(env->me_lazy_fd, &st))) + rc = errno; + else if (st.st_nlink > 0 /* don't sync deleted files */) { + rc = mdbx_env_sync_internal(env, true, true); + rc = (rc == MDBX_BUSY || rc == EAGAIN || rc == EACCES || rc == EBUSY || + rc == EWOULDBLOCK || rc == MDBX_RESULT_TRUE) + ? MDBX_SUCCESS + : rc; } +#endif } - while ((dp = env->me_dpages) != NULL) { - ASAN_UNPOISON_MEMORY_REGION(&dp->mp_next, sizeof(dp->mp_next)); - VALGRIND_MAKE_MEM_DEFINED(&dp->mp_next, sizeof(dp->mp_next)); - env->me_dpages = dp->mp_next; - mdbx_free(dp); - } - VALGRIND_DESTROY_MEMPOOL(env); - rc = mdbx_env_close0(env) ? MDBX_PANIC : rc; mdbx_ensure(env, mdbx_fastmutex_destroy(&env->me_dbi_lock) == MDBX_SUCCESS); #if defined(_WIN32) || defined(_WIN64) @@ -10296,9 +10303,15 @@ int __cold mdbx_env_close_ex(MDBX_env *env, int dont_sync) { mdbx_ensure(env, mdbx_ipclock_destroy(&env->me_lckless_stub.wlock) == 0); #endif /* MDBX_LOCKING */ + while ((dp = env->me_dpages) != NULL) { + ASAN_UNPOISON_MEMORY_REGION(&dp->mp_next, sizeof(dp->mp_next)); + VALGRIND_MAKE_MEM_DEFINED(&dp->mp_next, sizeof(dp->mp_next)); + env->me_dpages = dp->mp_next; + mdbx_free(dp); + } + VALGRIND_DESTROY_MEMPOOL(env); mdbx_ensure(env, env->me_lcklist_next == nullptr); env->me_pid = 0; - env->me_signature = 0; mdbx_free(env); return rc; @@ -10837,7 +10850,7 @@ static __always_inline int mdbx_node_read(MDBX_cursor *mc, MDBX_node *node, return MDBX_SUCCESS; } -int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data) { +int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data) { DKBUF; mdbx_debug("===> get db %u key [%s]", dbi, DKEY(key)); @@ -10857,7 +10870,7 @@ int mdbx_get(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data) { return rc; int exact = 0; - return mdbx_cursor_set(&cx.outer, key, data, MDBX_SET, &exact); + return mdbx_cursor_set(&cx.outer, (MDBX_val *)key, data, MDBX_SET, &exact); } int mdbx_get_nearest(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, @@ -11679,7 +11692,7 @@ static int mdbx_cursor_touch(MDBX_cursor *mc) { return rc; } -int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, +int mdbx_cursor_put(MDBX_cursor *mc, const MDBX_val *key, MDBX_val *data, unsigned flags) { MDBX_env *env; MDBX_page *sub_root = NULL; @@ -11829,7 +11842,7 @@ int mdbx_cursor_put(MDBX_cursor *mc, MDBX_val *key, MDBX_val *data, } } } else { - rc = mdbx_cursor_set(mc, key, &d2, MDBX_SET, &exact); + rc = mdbx_cursor_set(mc, (MDBX_val *)key, &d2, MDBX_SET, &exact); } if ((flags & MDBX_NOOVERWRITE) && (rc == MDBX_SUCCESS || rc == MDBX_EKEYMISMATCH)) { @@ -12752,7 +12765,7 @@ static void mdbx_node_shrink(MDBX_page *mp, unsigned indx) { /* Prepare to shift upward, set len = length(subpage part to shift) */ if (IS_LEAF2(sp)) { - delta &= /* do not make the node uneven-sized */ ~1u; + delta &= /* do not make the node uneven-sized */ ~(size_t)1; if (unlikely(delta) == 0) return; nsize = node_ds(node) - delta; @@ -13003,7 +13016,7 @@ int mdbx_cursor_renew(MDBX_txn *txn, MDBX_cursor *mc) { } /* Return the count of duplicate data items for the current key */ -int mdbx_cursor_count(MDBX_cursor *mc, size_t *countp) { +int mdbx_cursor_count(const MDBX_cursor *mc, size_t *countp) { if (unlikely(mc == NULL)) return MDBX_EINVAL; @@ -13067,7 +13080,7 @@ void mdbx_cursor_close(MDBX_cursor *mc) { } } -MDBX_txn *mdbx_cursor_txn(MDBX_cursor *mc) { +MDBX_txn *mdbx_cursor_txn(const MDBX_cursor *mc) { if (unlikely(!mc || mc->mc_signature != MDBX_MC_SIGNATURE)) return NULL; MDBX_txn *txn = mc->mc_txn; @@ -13078,7 +13091,7 @@ MDBX_txn *mdbx_cursor_txn(MDBX_cursor *mc) { return txn; } -MDBX_dbi mdbx_cursor_dbi(MDBX_cursor *mc) { +MDBX_dbi mdbx_cursor_dbi(const MDBX_cursor *mc) { if (unlikely(!mc || mc->mc_signature != MDBX_MC_SIGNATURE)) return UINT_MAX; return mc->mc_dbi; @@ -14304,7 +14317,8 @@ static int mdbx_cursor_del0(MDBX_cursor *mc) { return rc; } -int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data) { +int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, + const MDBX_val *data) { int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -14321,8 +14335,8 @@ int mdbx_del(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data) { return mdbx_del0(txn, dbi, key, data, 0); } -static int mdbx_del0(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, - unsigned flags) { +static int mdbx_del0(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, + const MDBX_val *data, unsigned flags) { MDBX_cursor_couple cx; MDBX_cursor_op op; MDBX_val rdata; @@ -14344,7 +14358,8 @@ static int mdbx_del0(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, op = MDBX_SET; flags |= MDBX_NODUPDATA; } - rc = mdbx_cursor_set(&cx.outer, key, data, op, &exact); + rc = + mdbx_cursor_set(&cx.outer, (MDBX_val *)key, (MDBX_val *)data, op, &exact); if (likely(rc == MDBX_SUCCESS)) { /* let mdbx_page_split know about this cursor if needed: * delete will trigger a rebalance; if it needs to move @@ -14844,7 +14859,7 @@ done: return rc; } -int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, +int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, MDBX_val *data, unsigned flags) { int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) @@ -14872,7 +14887,7 @@ int mdbx_put(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *data, /* LY: support for update (explicit overwrite) */ if (flags & MDBX_CURRENT) { - rc = mdbx_cursor_get(&cx.outer, key, NULL, MDBX_SET); + rc = mdbx_cursor_get(&cx.outer, (MDBX_val *)key, NULL, MDBX_SET); if (likely(rc == MDBX_SUCCESS) && (txn->mt_dbs[dbi].md_flags & MDBX_DUPSORT)) { /* LY: allows update (explicit overwrite) only for unique keys */ @@ -15177,7 +15192,7 @@ static int __cold mdbx_env_compact(MDBX_env *env, MDBX_txn *read_txn, const bool dest_is_pipe) { const size_t meta_bytes = pgno2bytes(env, NUM_METAS); uint8_t *const data_buffer = - buffer + roundup_powerof2(meta_bytes, env->me_os_psize); + buffer + ceil_powerof2(meta_bytes, env->me_os_psize); MDBX_meta *const meta = mdbx_init_metas(env, buffer); /* copy canary sequenses if present */ if (read_txn->mt_canary.v) { @@ -15343,10 +15358,12 @@ static int __cold mdbx_env_copy_asis(MDBX_env *env, MDBX_txn *read_txn, rc = mdbx_write(fd, buffer, meta_bytes); uint8_t *const data_buffer = - buffer + roundup_powerof2(meta_bytes, env->me_os_psize); + buffer + ceil_powerof2(meta_bytes, env->me_os_psize); for (size_t offset = meta_bytes; rc == MDBX_SUCCESS && offset < used_size;) { if (dest_is_pipe) { -#if defined(__linux__) || defined(__gnu_linux__) && !defined(MDBX_SAFE4QEMU) +#if (defined(__linux__) || defined(__gnu_linux__)) && \ + (!defined(__ANDROID_API__) || __ANDROID_API__ >= 21) && \ + !defined(MDBX_SAFE4QEMU) off_t in_offset = offset; const intptr_t written = sendfile(fd, env->me_lazy_fd, &in_offset, used_size - offset); @@ -15420,8 +15437,8 @@ int __cold mdbx_env_copy2fd(MDBX_env *env, mdbx_filehandle_t fd, const size_t buffer_size = pgno_align2os_bytes(env, NUM_METAS) + - roundup_powerof2(((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : MDBX_WBUF), - env->me_os_psize); + ceil_powerof2(((flags & MDBX_CP_COMPACT) ? MDBX_WBUF * 2 : MDBX_WBUF), + env->me_os_psize); uint8_t *buffer = NULL; int rc = mdbx_memalign_alloc(env->me_os_psize, buffer_size, (void **)&buffer); @@ -15531,7 +15548,7 @@ int __cold mdbx_env_set_flags(MDBX_env *env, unsigned flags, int onoff) { return MDBX_SUCCESS; } -int __cold mdbx_env_get_flags(MDBX_env *env, unsigned *arg) { +int __cold mdbx_env_get_flags(const MDBX_env *env, unsigned *arg) { if (unlikely(!env || !arg)) return MDBX_EINVAL; @@ -15553,7 +15570,7 @@ int __cold mdbx_env_set_userctx(MDBX_env *env, void *ctx) { return MDBX_SUCCESS; } -void *__cold mdbx_env_get_userctx(MDBX_env *env) { +void *__cold mdbx_env_get_userctx(const MDBX_env *env) { return env ? env->me_userctx : NULL; } @@ -15573,7 +15590,7 @@ int __cold mdbx_env_set_assert(MDBX_env *env, MDBX_assert_func *func) { #endif } -int __cold mdbx_env_get_path(MDBX_env *env, const char **arg) { +int __cold mdbx_env_get_path(const MDBX_env *env, const char **arg) { if (unlikely(!env || !arg)) return MDBX_EINVAL; @@ -15584,7 +15601,7 @@ int __cold mdbx_env_get_path(MDBX_env *env, const char **arg) { return MDBX_SUCCESS; } -int __cold mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *arg) { +int __cold mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *arg) { if (unlikely(!env || !arg)) return MDBX_EINVAL; @@ -16310,7 +16327,7 @@ int mdbx_set_dupsort(MDBX_txn *txn, MDBX_dbi dbi, MDBX_cmp_func *cmp) { return MDBX_SUCCESS; } -int __cold mdbx_reader_list(MDBX_env *env, MDBX_reader_list_func *func, +int __cold mdbx_reader_list(const MDBX_env *env, MDBX_reader_list_func *func, void *ctx) { if (unlikely(!env || !func)) return MDBX_EINVAL; @@ -16701,7 +16718,7 @@ int __cold mdbx_env_set_oomfunc(MDBX_env *env, MDBX_oom_func *oomfunc) { return MDBX_SUCCESS; } -MDBX_oom_func *__cold mdbx_env_get_oomfunc(MDBX_env *env) { +MDBX_oom_func *__cold mdbx_env_get_oomfunc(const MDBX_env *env) { return likely(env && env->me_signature == MDBX_ME_SIGNATURE) ? env->me_oom_func : NULL; @@ -16711,7 +16728,7 @@ MDBX_oom_func *__cold mdbx_env_get_oomfunc(MDBX_env *env) { /* LY: avoid tsan-trap by me_txn, mm_last_pg and mt_next_pgno */ __attribute__((__no_sanitize_thread__, __noinline__)) #endif -int mdbx_txn_straggler(MDBX_txn *txn, int *percent) +int mdbx_txn_straggler(const MDBX_txn *txn, int *percent) { int rc = check_txn(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) @@ -17022,7 +17039,7 @@ int mdbx_canary_put(MDBX_txn *txn, const mdbx_canary *canary) { return MDBX_SUCCESS; } -int mdbx_canary_get(MDBX_txn *txn, mdbx_canary *canary) { +int mdbx_canary_get(const MDBX_txn *txn, mdbx_canary *canary) { int rc = check_txn(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -17034,7 +17051,7 @@ int mdbx_canary_get(MDBX_txn *txn, mdbx_canary *canary) { return MDBX_SUCCESS; } -int mdbx_cursor_on_first(MDBX_cursor *mc) { +int mdbx_cursor_on_first(const MDBX_cursor *mc) { if (unlikely(mc == NULL)) return MDBX_EINVAL; @@ -17052,7 +17069,7 @@ int mdbx_cursor_on_first(MDBX_cursor *mc) { return MDBX_RESULT_TRUE; } -int mdbx_cursor_on_last(MDBX_cursor *mc) { +int mdbx_cursor_on_last(const MDBX_cursor *mc) { if (unlikely(mc == NULL)) return MDBX_EINVAL; @@ -17071,7 +17088,7 @@ int mdbx_cursor_on_last(MDBX_cursor *mc) { return MDBX_RESULT_TRUE; } -int mdbx_cursor_eof(MDBX_cursor *mc) { +int mdbx_cursor_eof(const MDBX_cursor *mc) { if (unlikely(mc == NULL)) return MDBX_EINVAL; @@ -17503,8 +17520,8 @@ int mdbx_estimate_range(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *begin_key, * - внешняя аллокация курсоров, в том числе на стеке (без malloc). * - получения статуса страницы по адресу (знать о P_DIRTY). */ -int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key, MDBX_val *new_data, - MDBX_val *old_data, unsigned flags) { +int mdbx_replace(MDBX_txn *txn, MDBX_dbi dbi, const MDBX_val *key, + MDBX_val *new_data, MDBX_val *old_data, unsigned flags) { int rc = check_txn_rw(txn, MDBX_TXN_BLOCKED); if (unlikely(rc != MDBX_SUCCESS)) return rc; @@ -18086,8 +18103,8 @@ __dll_export #ifdef MDBX_BUILD_TARGET MDBX_BUILD_TARGET #else - #if defined(__ANDROID__) - "Android" + #if defined(__ANDROID_API__) + "Android" STRINGIFY(__ANDROID_API__) #elif defined(__linux__) || defined(__gnu_linux__) "Linux" #elif defined(EMSCRIPTEN) || defined(__EMSCRIPTEN__) @@ -18177,12 +18194,12 @@ __dll_export #endif #endif /* MDBX_BUILD_TARGET */ -#ifdef MDBX_BUILD_CONFIG +#ifdef MDBX_BUILD_TYPE # if defined(_MSC_VER) -# pragma message("Configuration-depended MDBX_BUILD_CONFIG: " MDBX_BUILD_CONFIG) +# pragma message("Configuration-depended MDBX_BUILD_TYPE: " MDBX_BUILD_TYPE) # endif - "-" MDBX_BUILD_CONFIG -#endif /* MDBX_BUILD_CONFIG */ + "-" MDBX_BUILD_TYPE +#endif /* MDBX_BUILD_TYPE */ , "MDBX_DEBUG=" STRINGIFY(MDBX_DEBUG) #ifdef MDBX_LOGLEVEL_BUILD @@ -18267,12 +18284,16 @@ __dll_export #endif #endif /* MDBX_BUILD_COMPILER */ , -#ifdef MDBX_BUILD_FLAGS - MDBX_BUILD_FLAGS -#endif /* MDBX_BUILD_FLAGS */ #ifdef MDBX_BUILD_FLAGS_CONFIG MDBX_BUILD_FLAGS_CONFIG #endif /* MDBX_BUILD_FLAGS_CONFIG */ +#ifdef MDBX_BUILD_FLAGS + MDBX_BUILD_FLAGS +#endif /* MDBX_BUILD_FLAGS */ +#if !(defined(MDBX_BUILD_FLAGS_CONFIG) || defined(MDBX_BUILD_FLAGS)) + "undefined (please use correct build script)" +#warning "Build flags undefined. Please use correct build script" +#endif }; #ifdef __SANITIZE_ADDRESS__ diff --git a/libs/libmdbx/src/src/elements/debug_begin.h b/libs/libmdbx/src/src/debug_begin.h index f3306b5dc0..f3306b5dc0 100644 --- a/libs/libmdbx/src/src/elements/debug_begin.h +++ b/libs/libmdbx/src/src/debug_begin.h diff --git a/libs/libmdbx/src/src/elements/debug_end.h b/libs/libmdbx/src/src/debug_end.h index e361119bc0..e361119bc0 100644 --- a/libs/libmdbx/src/src/elements/debug_end.h +++ b/libs/libmdbx/src/src/debug_end.h diff --git a/libs/libmdbx/src/src/elements/defs.h b/libs/libmdbx/src/src/defs.h index b2710eede8..b2710eede8 100644 --- a/libs/libmdbx/src/src/elements/defs.h +++ b/libs/libmdbx/src/src/defs.h diff --git a/libs/libmdbx/src/src/elements/internals.h b/libs/libmdbx/src/src/internals.h index 62552de95e..7ef818ca35 100644 --- a/libs/libmdbx/src/src/elements/internals.h +++ b/libs/libmdbx/src/src/internals.h @@ -13,7 +13,7 @@ #pragma once #ifdef MDBX_CONFIG_H -#include MDBX_CONFIG_H +#include "../config.h" #endif /* *INDENT-OFF* */ @@ -90,7 +90,7 @@ #pragma warning(disable : 4200) /* nonstandard extension used: zero-sized array in struct/union */ #endif /* _MSC_VER (warnings) */ -#include "../../mdbx.h" +#include "../mdbx.h" #include "defs.h" #if defined(__GNUC__) && !__GNUC_PREREQ(4,2) @@ -862,15 +862,7 @@ typedef struct MDBX_cursor_couple { /* The database environment. */ struct MDBX_env { #define MDBX_ME_SIGNATURE UINT32_C(0x9A899641) - size_t me_signature; - mdbx_mmap_t me_dxb_mmap; /* The main data file */ -#define me_map me_dxb_mmap.dxb -#define me_lazy_fd me_dxb_mmap.fd - mdbx_filehandle_t me_dsync_fd; - mdbx_mmap_t me_lck_mmap; /* The lock file */ -#define me_lfd me_lck_mmap.fd -#define me_lck me_lck_mmap.lck - + uint32_t me_signature; /* Failed to update the meta page. Probably an I/O error. */ #define MDBX_FATAL_ERROR UINT32_C(0x80000000) /* Additional flag for mdbx_sync_locked() */ @@ -879,7 +871,15 @@ struct MDBX_env { #define MDBX_ENV_ACTIVE UINT32_C(0x20000000) /* me_txkey is set */ #define MDBX_ENV_TXKEY UINT32_C(0x10000000) - uint32_t me_flags; /* see mdbx_env */ + uint32_t me_flags; + mdbx_mmap_t me_dxb_mmap; /* The main data file */ +#define me_map me_dxb_mmap.dxb +#define me_lazy_fd me_dxb_mmap.fd + mdbx_filehandle_t me_dsync_fd; + mdbx_mmap_t me_lck_mmap; /* The lock file */ +#define me_lfd me_lck_mmap.fd +#define me_lck me_lck_mmap.lck + unsigned me_psize; /* DB page size, inited from me_os_psize */ unsigned me_psize2log; /* log2 of DB page size */ unsigned me_os_psize; /* OS page size, from mdbx_syspagesize() */ @@ -991,8 +991,6 @@ MDBX_INTERNAL_FUNC void mdbx_debug_log(int type, const char *function, int line, const char *fmt, ...) __printf_args(4, 5); -MDBX_INTERNAL_FUNC void mdbx_panic(const char *fmt, ...) __printf_args(1, 2); - #if MDBX_DEBUG #define mdbx_assert_enabled() unlikely(mdbx_runtime_flags &MDBX_DBG_ASSERT) @@ -1024,8 +1022,20 @@ MDBX_INTERNAL_FUNC void mdbx_panic(const char *fmt, ...) __printf_args(1, 2); #endif /* MDBX_DEBUG */ +#if defined(__ANDROID_API__) +#define mdbx_panic(fmt, ...) \ + __android_log_assert("panic", "mdbx", fmt, __VA_ARGS__) +#else +MDBX_INTERNAL_FUNC void mdbx_panic(const char *fmt, ...) __printf_args(1, 2); +#endif + +#if !MDBX_DEBUG && defined(__ANDROID_API__) +#define mdbx_assert_fail(env, msg, func, line) \ + __android_log_assert(msg, "mdbx", "%s:%u", func, line) +#else MDBX_INTERNAL_FUNC void mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func, int line); +#endif #define mdbx_debug_extra(fmt, ...) \ do { \ @@ -1325,7 +1335,12 @@ is_powerof2(size_t x) { } static __pure_function __always_inline __maybe_unused size_t -roundup_powerof2(size_t value, size_t granularity) { +floor_powerof2(size_t value, size_t granularity) { assert(is_powerof2(granularity)); - return (value + granularity - 1) & ~(granularity - 1); + return value & ~(granularity - 1); +} + +static __pure_function __always_inline __maybe_unused size_t +ceil_powerof2(size_t value, size_t granularity) { + return floor_powerof2(value + granularity - 1, granularity); } diff --git a/libs/libmdbx/src/src/elements/lck-posix.c b/libs/libmdbx/src/src/lck-posix.c index 3754c25393..6b6127bd4b 100644 --- a/libs/libmdbx/src/src/elements/lck-posix.c +++ b/libs/libmdbx/src/src/lck-posix.c @@ -21,10 +21,20 @@ /* global constructor/destructor */ #if defined(__linux__) || defined(__gnu_linux__) + #include <sys/utsname.h> + #ifndef MDBX_ALLOY uint32_t mdbx_linux_kernel_version; +bool mdbx_RunningOnWSL; #endif /* MDBX_ALLOY */ + +static __cold bool probe_for_WSL(const char *tag) { + /* "Official" way of detecting WSL but not WSL2 + * https://github.com/Microsoft/WSL/issues/423#issuecomment-221627364 */ + return strstr(tag, "Microsoft") || strstr(tag, "WSL"); +} + #endif /* Linux */ static __cold __attribute__((__constructor__)) void @@ -32,6 +42,9 @@ mdbx_global_constructor(void) { #if defined(__linux__) || defined(__gnu_linux__) struct utsname buffer; if (uname(&buffer) == 0) { + mdbx_RunningOnWSL = probe_for_WSL(buffer.version) || + probe_for_WSL(buffer.sysname) || + probe_for_WSL(buffer.release); int i = 0; char *p = buffer.release; while (*p && i < 4) { @@ -123,7 +136,8 @@ static void __cold choice_fcntl() { #if defined(__linux__) || defined(__gnu_linux__) && mdbx_linux_kernel_version > 0x030f0000 /* OFD locks are available since 3.15, but engages here - only for 3.16 and larer kernels (LTS) for reliability reasons */ + only for 3.16 and later kernels (i.e. LTS) because + of reliability reasons */ #endif /* linux */ ) { op_setlk = F_OFD_SETLK; @@ -291,6 +305,17 @@ MDBX_INTERNAL_FUNC int __cold mdbx_lck_seize(MDBX_env *env) { #endif /* MDBX_USE_OFDLOCKS */ int rc = MDBX_SUCCESS; +#if defined(__linux__) || defined(__gnu_linux__) + if (unlikely(mdbx_RunningOnWSL)) { + rc = ENOLCK /* No record locks available */; + mdbx_error("%s, err %u", + "WSL (Windows Subsystem for Linux) is mad and trouble-full, " + "injecting failure to avoid data loss", + rc); + return rc; + } +#endif /* Linux */ + if (env->me_lfd == INVALID_HANDLE_VALUE) { /* LY: without-lck mode (e.g. exclusive or on read-only filesystem) */ rc = diff --git a/libs/libmdbx/src/src/elements/lck-windows.c b/libs/libmdbx/src/src/lck-windows.c index 13178139ea..19a71cc337 100644 --- a/libs/libmdbx/src/src/elements/lck-windows.c +++ b/libs/libmdbx/src/src/lck-windows.c @@ -243,13 +243,13 @@ static int suspend_and_append(mdbx_handle_array_t **array, MDBX_INTERNAL_FUNC int mdbx_suspend_threads_before_remap(MDBX_env *env, mdbx_handle_array_t **array) { - const size_t CurrentTid = GetCurrentThreadId(); + const uintptr_t CurrentTid = GetCurrentThreadId(); int rc; if (env->me_lck) { /* Scan LCK for threads of the current process */ const MDBX_reader *const begin = env->me_lck->mti_readers; const MDBX_reader *const end = begin + env->me_lck->mti_numreaders; - const size_t WriteTxnOwner = env->me_txn0 ? env->me_txn0->mt_owner : 0; + const uintptr_t WriteTxnOwner = env->me_txn0 ? env->me_txn0->mt_owner : 0; for (const MDBX_reader *reader = begin; reader < end; ++reader) { if (reader->mr_pid != env->me_pid || !reader->mr_tid) { skip_lck: diff --git a/libs/libmdbx/src/src/man1/mdbx_chk.1 b/libs/libmdbx/src/src/man1/mdbx_chk.1 index 4cd0a3a838..d2d03684e2 100644 --- a/libs/libmdbx/src/src/man1/mdbx_chk.1 +++ b/libs/libmdbx/src/src/man1/mdbx_chk.1 @@ -1,6 +1,6 @@ .\" Copyright 2015-2020 Leonid Yuriev <leo@yuriev.ru>. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. -.TH MDBX_CHK 1 "2020-01-20" "MDBX 0.6.x" +.TH MDBX_CHK 1 "2020-03-18" "MDBX 0.7.x" .SH NAME mdbx_chk \- MDBX checking tool .SH SYNOPSIS diff --git a/libs/libmdbx/src/src/man1/mdbx_copy.1 b/libs/libmdbx/src/src/man1/mdbx_copy.1 index 863a58add5..a8427bb4df 100644 --- a/libs/libmdbx/src/src/man1/mdbx_copy.1 +++ b/libs/libmdbx/src/src/man1/mdbx_copy.1 @@ -2,7 +2,7 @@ .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. -.TH MDBX_COPY 1 "2020-01-20" "MDBX 0.6.x" +.TH MDBX_COPY 1 "2020-03-18" "MDBX 0.7.x" .SH NAME mdbx_copy \- MDBX environment copy tool .SH SYNOPSIS diff --git a/libs/libmdbx/src/src/man1/mdbx_dump.1 b/libs/libmdbx/src/src/man1/mdbx_dump.1 index 7cf708ab94..9985127f00 100644 --- a/libs/libmdbx/src/src/man1/mdbx_dump.1 +++ b/libs/libmdbx/src/src/man1/mdbx_dump.1 @@ -2,7 +2,7 @@ .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. -.TH MDBX_DUMP 1 "2020-01-20" "MDBX 0.6.x" +.TH MDBX_DUMP 1 "2020-03-18" "MDBX 0.7.x" .SH NAME mdbx_dump \- MDBX environment export tool .SH SYNOPSIS diff --git a/libs/libmdbx/src/src/man1/mdbx_load.1 b/libs/libmdbx/src/src/man1/mdbx_load.1 index 473f9303ef..b401b38715 100644 --- a/libs/libmdbx/src/src/man1/mdbx_load.1 +++ b/libs/libmdbx/src/src/man1/mdbx_load.1 @@ -2,7 +2,7 @@ .\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. -.TH MDBX_LOAD 1 "2020-01-20" "MDBX 0.6.x" +.TH MDBX_LOAD 1 "2020-03-18" "MDBX 0.7.x" .SH NAME mdbx_load \- MDBX environment import tool .SH SYNOPSIS diff --git a/libs/libmdbx/src/src/man1/mdbx_stat.1 b/libs/libmdbx/src/src/man1/mdbx_stat.1 index 80969bb3f1..b7fbeb0833 100644 --- a/libs/libmdbx/src/src/man1/mdbx_stat.1 +++ b/libs/libmdbx/src/src/man1/mdbx_stat.1 @@ -2,7 +2,7 @@ .\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved. .\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>. .\" Copying restrictions apply. See COPYRIGHT/LICENSE. -.TH MDBX_STAT 1 "2020-01-20" "MDBX 0.6.x" +.TH MDBX_STAT 1 "2020-03-18" "MDBX 0.7.x" .SH NAME mdbx_stat \- MDBX environment status tool .SH SYNOPSIS diff --git a/libs/libmdbx/src/src/tools/mdbx_chk.c b/libs/libmdbx/src/src/mdbx_chk.c index e5dd539af5..64c1d333bc 100644 --- a/libs/libmdbx/src/src/tools/mdbx_chk.c +++ b/libs/libmdbx/src/src/mdbx_chk.c @@ -21,7 +21,7 @@ #endif /* _MSC_VER (warnings) */ #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ -#include "../elements/internals.h" +#include "internals.h" typedef struct flagbit { int bit; @@ -559,6 +559,12 @@ static int process_db(MDBX_dbi dbi_handle, char *dbi_name, visitor *handler, uint64_t record_count = 0, dups = 0; uint64_t key_bytes = 0, data_bytes = 0; + if ((MDBX_TXN_FINISHED | MDBX_TXN_ERROR) & mdbx_txn_flags(txn)) { + print(" ! abort processing '%s' due to a previous error\n", + dbi_name ? dbi_name : "@MAIN"); + return MDBX_BAD_TXN; + } + if (dbi_handle == ~0u) { rc = mdbx_dbi_open(txn, dbi_name, 0, &dbi_handle); if (rc) { diff --git a/libs/libmdbx/src/src/tools/mdbx_copy.c b/libs/libmdbx/src/src/mdbx_copy.c index 8545b38809..81d177ab99 100644 --- a/libs/libmdbx/src/src/tools/mdbx_copy.c +++ b/libs/libmdbx/src/src/mdbx_copy.c @@ -21,7 +21,7 @@ #endif /* _MSC_VER (warnings) */ #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ -#include "../elements/internals.h" +#include "internals.h" #if defined(_WIN32) || defined(_WIN64) #include "wingetopt.h" diff --git a/libs/libmdbx/src/src/tools/mdbx_dump.c b/libs/libmdbx/src/src/mdbx_dump.c index 3afabc0b4a..8bb057b2df 100644 --- a/libs/libmdbx/src/src/tools/mdbx_dump.c +++ b/libs/libmdbx/src/src/mdbx_dump.c @@ -21,7 +21,7 @@ #endif /* _MSC_VER (warnings) */ #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ -#include "../elements/internals.h" +#include "internals.h" #include <ctype.h> diff --git a/libs/libmdbx/src/src/tools/mdbx_load.c b/libs/libmdbx/src/src/mdbx_load.c index 449848e7b8..eb39cc1174 100644 --- a/libs/libmdbx/src/src/tools/mdbx_load.c +++ b/libs/libmdbx/src/src/mdbx_load.c @@ -21,7 +21,7 @@ #endif /* _MSC_VER (warnings) */ #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ -#include "../elements/internals.h" +#include "internals.h" #include <ctype.h> @@ -339,7 +339,8 @@ static void usage(void) { "dbpath\n" " -V\t\tprint version and exit\n" " -q\t\tbe quiet\n" - " -a\t\tappend records in input order\n" + " -a\t\tappend records in input order (required for custom " + "comparators)\n" " -f file\tread from file instead of stdin\n" " -s name\tload into named subDB\n" " -N\t\tuse NOOVERWRITE on puts\n" diff --git a/libs/libmdbx/src/src/tools/mdbx_stat.c b/libs/libmdbx/src/src/mdbx_stat.c index 0867aedac3..d1a805f925 100644 --- a/libs/libmdbx/src/src/tools/mdbx_stat.c +++ b/libs/libmdbx/src/src/mdbx_stat.c @@ -21,7 +21,7 @@ #endif /* _MSC_VER (warnings) */ #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ -#include "../elements/internals.h" +#include "internals.h" #if defined(_WIN32) || defined(_WIN64) #include "wingetopt.h" @@ -77,8 +77,8 @@ static int reader_list_func(void *ctx, int num, int slot, mdbx_pid_t pid, "pid", (int)sizeof(size_t) * 2, "thread", "txnid", "lag", "used", "retained"); - printf(" %3d)\t[%d]\t%6" PRIdSIZE " %*" PRIxSIZE, num, slot, (size_t)pid, - (int)sizeof(size_t) * 2, (size_t)thread); + printf(" %3d)\t[%d]\t%6" PRIdSIZE " %*" PRIxPTR, num, slot, (size_t)pid, + (int)sizeof(size_t) * 2, (uintptr_t)thread); if (txnid) printf(" %20" PRIu64 " %10" PRIu64 " %12.1fM %12.1fM\n", txnid, lag, bytes_used / 1048576.0, bytes_retained / 1048576.0); @@ -294,7 +294,7 @@ int main(int argc, char *argv[]) { const pgno_t number = *iptr++; pages += number; - if (envinfo && mei.mi_latter_reader_txnid > *(size_t *)key.iov_base) + if (envinfo && mei.mi_latter_reader_txnid > *(txnid_t *)key.iov_base) reclaimable += number; if (freinfo > 1) { diff --git a/libs/libmdbx/src/src/elements/ntdll.def b/libs/libmdbx/src/src/ntdll.def index e3a6e33c94..e3a6e33c94 100644 --- a/libs/libmdbx/src/src/elements/ntdll.def +++ b/libs/libmdbx/src/src/ntdll.def diff --git a/libs/libmdbx/src/src/elements/options.h b/libs/libmdbx/src/src/options.h index 2694e92011..715f883bfc 100644 --- a/libs/libmdbx/src/src/elements/options.h +++ b/libs/libmdbx/src/src/options.h @@ -79,8 +79,10 @@ /* Some platforms define the EOWNERDEAD error code even though they * don't support Robust Mutexes. If doubt compile with -MDBX_LOCKING=2001. */ #if defined(EOWNERDEAD) && _POSIX_THREAD_PROCESS_SHARED >= 200809L && \ - (defined(_POSIX_THREAD_ROBUST_PRIO_INHERIT) || \ - defined(_POSIX_THREAD_ROBUST_PRIO_PROTECT) || \ + ((defined(_POSIX_THREAD_ROBUST_PRIO_INHERIT) && \ + _POSIX_THREAD_ROBUST_PRIO_INHERIT > 0) || \ + (defined(_POSIX_THREAD_ROBUST_PRIO_PROTECT) && \ + _POSIX_THREAD_ROBUST_PRIO_PROTECT > 0) || \ defined(PTHREAD_MUTEX_ROBUST) || defined(PTHREAD_MUTEX_ROBUST_NP)) && \ (!defined(__GLIBC__) || \ __GLIBC_PREREQ(2, 10) /* troubles with Robust mutexes before 2.10 */) diff --git a/libs/libmdbx/src/src/elements/osal.c b/libs/libmdbx/src/src/osal.c index 06a448cdbc..94902527b1 100644 --- a/libs/libmdbx/src/src/elements/osal.c +++ b/libs/libmdbx/src/src/osal.c @@ -197,6 +197,8 @@ __extern_C void __assert(const char *function, const char *file, int line, #endif /* __assert_fail */ +#if !defined(__ANDROID_API__) || MDBX_DEBUG + MDBX_INTERNAL_FUNC void __cold mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func, int line) { @@ -221,6 +223,8 @@ MDBX_INTERNAL_FUNC void __cold mdbx_assert_fail(const MDBX_env *env, OutputDebugStringA(message); if (IsDebuggerPresent()) DebugBreak(); +#elif defined(__ANDROID_API__) + __android_log_assert(msg, "mdbx", "%s:%u", func, line); #else __assert_fail(msg, "mdbx", line, func); #endif @@ -233,6 +237,10 @@ MDBX_INTERNAL_FUNC void __cold mdbx_assert_fail(const MDBX_env *env, #endif } +#endif /* __ANDROID_API__ || MDBX_DEBUG */ + +#if !defined(__ANDROID_API__) + MDBX_INTERNAL_FUNC __cold void mdbx_panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); @@ -256,6 +264,8 @@ MDBX_INTERNAL_FUNC __cold void mdbx_panic(const char *fmt, ...) { #endif } +#endif /* ! __ANDROID_API__ */ + /*----------------------------------------------------------------------------*/ #ifndef mdbx_vasprintf @@ -313,9 +323,10 @@ MDBX_INTERNAL_FUNC int mdbx_memalign_alloc(size_t alignment, size_t bytes, *result = VirtualAlloc(NULL, bytes, MEM_COMMIT | MEM_RESERVE, PAGE_READWRITE); return *result ? MDBX_SUCCESS : MDBX_ENOMEM /* ERROR_OUTOFMEMORY */; #elif defined(_ISOC11_SOURCE) - *result = aligned_alloc(alignment, roundup_powerof2(bytes, alignment)); + *result = aligned_alloc(alignment, ceil_powerof2(bytes, alignment)); return *result ? MDBX_SUCCESS : errno; -#elif _POSIX_VERSION >= 200112L +#elif _POSIX_VERSION >= 200112L && \ + (!defined(__ANDROID_API__) || __ANDROID_API__ >= 17) *result = nullptr; return posix_memalign(result, alignment, bytes); #elif __GLIBC_PREREQ(2, 16) || __STDC_VERSION__ >= 201112L @@ -753,7 +764,8 @@ MDBX_INTERNAL_FUNC int mdbx_write(mdbx_filehandle_t fd, const void *buf, int mdbx_pwritev(mdbx_filehandle_t fd, struct iovec *iov, int iovcnt, uint64_t offset, size_t expected_written) { -#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) +#if defined(_WIN32) || defined(_WIN64) || defined(__APPLE__) || \ + (defined(__ANDROID_API__) && __ANDROID_API__ < 24) size_t written = 0; for (int i = 0; i < iovcnt; ++i) { int rc = mdbx_pwrite(fd, iov[i].iov_base, iov[i].iov_len, offset); @@ -1098,6 +1110,7 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { mdbx_free(PathBuffer); return rc; } + #else struct statvfs statvfs_info; @@ -1150,6 +1163,9 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { defined(MFSTYPENAMELEN) || defined(VFS_NAMELEN) const char *const name = statfs_info.f_fstypename; const size_t name_len = sizeof(statfs_info.f_fstypename); +#elif defined(__ANDROID_API__) && __ANDROID_API__ < 21 + const char *const name = ""; + const unsigned name_len = 0; #else const char *name = ""; @@ -1168,7 +1184,7 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { mounted = setmntent("/etc/mtab", "r"); if (mounted) { const struct mntent *ent; -#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || \ +#if defined(_BSD_SOURCE) || defined(_SVID_SOURCE) || defined(__BIONIC__) || \ (defined(_DEFAULT_SOURCE) && __GLIBC_PREREQ(2, 19)) struct mntent entbuf; const bool should_copy = false; @@ -1176,7 +1192,7 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { (ent = getmntent_r(mounted, &entbuf, pathbuf, sizeof(pathbuf)))) #else const bool should_copy = true; - while (nullptr != (ent = getmntent(mounted)))) + while (nullptr != (ent = getmntent(mounted))) #endif { struct stat mnt; @@ -1194,7 +1210,7 @@ static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) { } endmntent(mounted); } -#endif /* !xBSD */ +#endif /* !xBSD && !Android/Bionic */ #endif if (name_len) { @@ -1376,7 +1392,10 @@ MDBX_INTERNAL_FUNC int mdbx_mmap(const int flags, mdbx_mmap_t *map, MDBX_INTERNAL_FUNC int mdbx_munmap(mdbx_mmap_t *map) { VALGRIND_MAKE_MEM_NOACCESS(map->address, map->current); - ASAN_POISON_MEMORY_REGION(map->address, map->current); + /* Unpoisoning is required for ASAN to avoid false-positive diagnostic + * when this memory will re-used by malloc or another mmaping. + * See https://github.com/erthink/libmdbx/pull/93#issuecomment-613687203 */ + ASAN_UNPOISON_MEMORY_REGION(map->address, map->limit); #if defined(_WIN32) || defined(_WIN64) if (map->section) NtClose(map->section); diff --git a/libs/libmdbx/src/src/elements/osal.h b/libs/libmdbx/src/src/osal.h index 6e423e98dd..d9012ce768 100644 --- a/libs/libmdbx/src/src/elements/osal.h +++ b/libs/libmdbx/src/src/osal.h @@ -76,6 +76,10 @@ extern "C" { /*----------------------------------------------------------------------------*/ /* Systems includes */ +#ifdef __APPLE__ +#include <TargetConditionals.h> +#endif /* Apple OSX & iOS */ + #if defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__) || \ defined(__BSD__) || defined(__bsdi__) || defined(__DragonFly__) || \ defined(__APPLE__) || defined(__MACH__) @@ -90,7 +94,9 @@ extern "C" { #else #define SYSCTL_LEGACY_NONCONST_MIB #endif +#ifndef __MACH__ #include <sys/vmmeter.h> +#endif #else #include <malloc.h> #if !(defined(__sun) || defined(__SVR4) || defined(__svr4__) || \ @@ -238,6 +244,13 @@ typedef pthread_mutex_t mdbx_fastmutex_t; #define malloc_usable_size(ptr) _msize(ptr) #endif /* malloc_usable_size */ +#ifdef __ANDROID_API__ +#include <android/log.h> +#if __ANDROID_API__ >= 21 +#include <sys/sendfile.h> +#endif +#endif /* Android */ + /* *INDENT-OFF* */ /* clang-format off */ #if defined(HAVE_SYS_STAT_H) || __has_include(<sys/stat.h>) @@ -338,7 +351,7 @@ typedef pthread_mutex_t mdbx_fastmutex_t; /* *INDENT-OFF* */ /* clang-format off */ -#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID__) || \ +#if defined(__GLIBC__) || defined(__GNU_LIBRARY__) || defined(__ANDROID_API__) || \ defined(HAVE_ENDIAN_H) || __has_include(<endian.h>) #include <endian.h> #elif defined(__APPLE__) || defined(__MACH__) || defined(__OpenBSD__) || \ @@ -495,6 +508,8 @@ MDBX_INTERNAL_FUNC int mdbx_vasprintf(char **strp, const char *fmt, va_list ap); #if defined(__linux__) || defined(__gnu_linux__) MDBX_INTERNAL_VAR uint32_t mdbx_linux_kernel_version; +MDBX_INTERNAL_VAR bool + mdbx_RunningOnWSL /* Windows Subsystem for Linux is mad and trouble-full */; #endif /* Linux */ /* Get the size of a memory page for the system. @@ -636,13 +651,15 @@ static __maybe_unused __inline uint32_t mdbx_getpid(void) { #endif } -static __maybe_unused __inline size_t mdbx_thread_self(void) { - STATIC_ASSERT(sizeof(mdbx_tid_t) <= sizeof(size_t)); +static __maybe_unused __inline uintptr_t mdbx_thread_self(void) { + mdbx_tid_t thunk; + STATIC_ASSERT(sizeof(uintptr_t) >= sizeof(thunk)); #if defined(_WIN32) || defined(_WIN64) - return GetCurrentThreadId(); + thunk = GetCurrentThreadId(); #else - return (size_t)pthread_self(); + thunk = pthread_self(); #endif + return (uintptr_t)thunk; } MDBX_INTERNAL_FUNC void __maybe_unused mdbx_osal_jitter(bool tiny); diff --git a/libs/libmdbx/src/src/tools/CMakeLists.txt b/libs/libmdbx/src/src/tools/CMakeLists.txt deleted file mode 100644 index 99167fa86f..0000000000 --- a/libs/libmdbx/src/src/tools/CMakeLists.txt +++ /dev/null @@ -1,60 +0,0 @@ -set(MDBX_TOOLS mdbx_chk mdbx_copy mdbx_dump mdbx_load mdbx_stat) - -# use, i.e. don't skip the full RPATH for the build tree -set(CMAKE_SKIP_BUILD_RPATH FALSE) - -# when building, don't use the install RPATH already (but later on when installing) -set(CMAKE_BUILD_WITH_INSTALL_RPATH FALSE) - -# add the automatically determined parts of the RPATH -# which point to directories outside the build tree to the install RPATH -set(CMAKE_INSTALL_RPATH_USE_LINK_PATH TRUE) - -# the RPATH to be used when installing, but only if it's not a system directory -list(FIND CMAKE_PLATFORM_IMPLICIT_LINK_DIRECTORIES "${CMAKE_INSTALL_PREFIX}/lib" isSystemDir) -if(isSystemDir EQUAL -1) - if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin") - set(CMAKE_INSTALL_RPATH "@executable_path/../lib") - else() - set(CMAKE_INSTALL_RPATH "\$ORIGIN/../lib") - endif() -endif() - -foreach(TOOL ${MDBX_TOOLS}) - if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - add_executable(${TOOL} ${TOOL}.c wingetopt.c wingetopt.h) - else() - add_executable(${TOOL} ${TOOL}.c) - endif() - - target_link_libraries(${TOOL} mdbx ${CMAKE_THREAD_LIBS_INIT}) - set_target_properties(${TOOL} PROPERTIES - C_STANDARD ${MDBX_C_STANDARD} C_STANDARD_REQUIRED ON - INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}>) -endforeach() - -if(LIB_MATH) - target_link_libraries(mdbx_chk ${LIB_MATH}) - target_link_libraries(mdbx_stat ${LIB_MATH}) -endif() - -install( - TARGETS - mdbx_chk - mdbx_stat - mdbx_copy - mdbx_dump - mdbx_load - RUNTIME - DESTINATION bin - COMPONENT runtime) - -install( - FILES - ../man1/mdbx_chk.1 - ../man1/mdbx_stat.1 - ../man1/mdbx_copy.1 - ../man1/mdbx_dump.1 - ../man1/mdbx_load.1 - DESTINATION man/man1 - COMPONENT doc) diff --git a/libs/libmdbx/src/src/elements/version.c.in b/libs/libmdbx/src/src/version.c.in index 2854bd5d9d..2854bd5d9d 100644 --- a/libs/libmdbx/src/src/elements/version.c.in +++ b/libs/libmdbx/src/src/version.c.in diff --git a/libs/libmdbx/src/src/tools/wingetopt.c b/libs/libmdbx/src/src/wingetopt.c index 7feb223fc1..7feb223fc1 100644 --- a/libs/libmdbx/src/src/tools/wingetopt.c +++ b/libs/libmdbx/src/src/wingetopt.c diff --git a/libs/libmdbx/src/src/tools/wingetopt.h b/libs/libmdbx/src/src/wingetopt.h index d328e38ccc..d328e38ccc 100644 --- a/libs/libmdbx/src/src/tools/wingetopt.h +++ b/libs/libmdbx/src/src/wingetopt.h diff --git a/libs/libmdbx/src/test/CMakeLists.txt b/libs/libmdbx/src/test/CMakeLists.txt index 0cc22182c9..2014cb57fa 100644 --- a/libs/libmdbx/src/test/CMakeLists.txt +++ b/libs/libmdbx/src/test/CMakeLists.txt @@ -1,9 +1,3 @@ -if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") - set(TEST_OSAL windows) -else() - set(TEST_OSAL unix) -endif() - add_executable(mdbx_test base.h cases.cc @@ -21,7 +15,8 @@ add_executable(mdbx_test log.h main.cc osal.h - osal-${TEST_OSAL}.cc + osal-unix.cc + osal-windows.cc test.cc test.h try.cc @@ -35,19 +30,15 @@ add_executable(mdbx_test set_target_properties(mdbx_test PROPERTIES INTERPROCEDURAL_OPTIMIZATION $<BOOL:${INTERPROCEDURAL_OPTIMIZATION}> CXX_STANDARD 17 CXX_STANDARD_REQUIRED ON) +target_setup_options(mdbx_test) -if(CC_HAS_FASTMATH) - target_compile_options(mdbx_test PRIVATE "-ffast-math") -endif() -if(CC_HAS_VISIBILITY AND (LTO_ENABLED OR INTERPROCEDURAL_OPTIMIZATION)) - set_target_properties(mdbx_test PROPERTIES LINK_FLAGS "-fvisibility=hidden") -endif() - -target_link_libraries(mdbx_test mdbx ${LIB_MATH} ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(mdbx_test ${TOOL_MDBX_LIB} ${LIB_MATH} ${CMAKE_THREAD_LIBS_INIT}) if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows") target_link_libraries(mdbx_test winmm.lib) endif() if(UNIX AND NOT SUBPROJECT) - add_subdirectory(pcrf) + add_executable(pcrf_test pcrf/pcrf_test.c) + target_include_directories(pcrf_test PRIVATE "${PROJECT_SOURCE_DIR}") + target_link_libraries(pcrf_test ${TOOL_MDBX_LIB}) endif() diff --git a/libs/libmdbx/src/test/base.h b/libs/libmdbx/src/test/base.h index 01cf171455..7fc6cac68c 100644 --- a/libs/libmdbx/src/test/base.h +++ b/libs/libmdbx/src/test/base.h @@ -84,14 +84,14 @@ #define MDBX_INTERNAL_VAR extern #define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ #include "../mdbx.h" -#include "../src/elements/defs.h" -#include "../src/elements/osal.h" +#include "../src/defs.h" +#include "../src/osal.h" #if !defined(__thread) && (defined(_MSC_VER) || defined(__DMC__)) #define __thread __declspec(thread) #endif /* __thread */ -#include "../src/elements/options.h" +#include "../src/options.h" #ifdef _MSC_VER #pragma warning(pop) diff --git a/libs/libmdbx/src/test/osal-unix.cc b/libs/libmdbx/src/test/osal-unix.cc index edc3e91a48..dc0774063a 100644 --- a/libs/libmdbx/src/test/osal-unix.cc +++ b/libs/libmdbx/src/test/osal-unix.cc @@ -14,6 +14,8 @@ #include "test.h" +#if !(defined(_WIN32) || defined(_WIN64)) + #include <pthread.h> #include <signal.h> #include <sys/mman.h> @@ -529,3 +531,5 @@ std::string osal_tempdir(void) { int osal_removefile(const std::string &pathname) { return unlink(pathname.c_str()) ? errno : MDBX_SUCCESS; } + +#endif /* !Windows */ diff --git a/libs/libmdbx/src/test/osal-windows.cc b/libs/libmdbx/src/test/osal-windows.cc index 6de674651b..9bde047a2c 100644 --- a/libs/libmdbx/src/test/osal-windows.cc +++ b/libs/libmdbx/src/test/osal-windows.cc @@ -1,5 +1,5 @@ /* - * Copyright 2017-2019 Leonid Yuriev <leo@yuriev.ru> + * Copyright 2017-2020 Leonid Yuriev <leo@yuriev.ru> * and other libmdbx authors: please see AUTHORS file. * All rights reserved. * @@ -14,6 +14,8 @@ #include "test.h" +#if defined(_WIN32) || defined(_WIN64) + static std::unordered_map<unsigned, HANDLE> events; static HANDLE hBarrierSemaphore, hBarrierEvent; static HANDLE hProgressActiveEvent, hProgressPassiveEvent; @@ -422,16 +424,10 @@ void osal_udelay(unsigned us) { static unsigned threshold_us; if (threshold_us == 0) { -#if 1 unsigned timeslice_ms = 1; while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO) ++timeslice_ms; threshold_us = timeslice_ms * 1500u; -#else - ULONGLONG InterruptTimePrecise_100ns; - QueryInterruptTimePrecise(&InterruptTimePrecise_100ns); - threshold_us = InterruptTimePrecise_100ns / 5; -#endif assert(threshold_us > 0); } @@ -459,3 +455,5 @@ std::string osal_tempdir(void) { int osal_removefile(const std::string &pathname) { return DeleteFileA(pathname.c_str()) ? MDBX_SUCCESS : GetLastError(); } + +#endif /* Windows */ diff --git a/libs/libmdbx/src/test/pcrf/CMakeLists.txt b/libs/libmdbx/src/test/pcrf/CMakeLists.txt deleted file mode 100644 index 8bd3e3d859..0000000000 --- a/libs/libmdbx/src/test/pcrf/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -set(TARGET pcrf_test) -add_executable(${TARGET} pcrf_test.c) -target_include_directories(${TARGET} PRIVATE "${PROJECT_SOURCE_DIR}") -target_link_libraries(${TARGET} mdbx) - diff --git a/libs/libmdbx/src/src/elements/version.c b/libs/libmdbx/src/version.c index 1d964a93a1..d6b952761e 100644 --- a/libs/libmdbx/src/src/elements/version.c +++ b/libs/libmdbx/src/version.c @@ -1,10 +1,10 @@ /* This is CMake-template for libmdbx's version.c ******************************************************************************/ -#include "internals.h" +#include "src/internals.h" #if MDBX_VERSION_MAJOR != 0 || \ - MDBX_VERSION_MINOR != 6 + MDBX_VERSION_MINOR != 7 #error "API version mismatch! Had `git fetch --tags` done?" #endif @@ -24,11 +24,11 @@ __dll_export #endif const mdbx_version_info mdbx_version = { 0, - 6, + 7, 0, - 1935, - {"2020-03-20T17:45:36+03:00", "e01a07c814dffd0b1433ad536da16ab95344615a", "c20ba1e84f51ca9dd10603fe461b1bcc171aa075", - "v0.6.0-45-gc20ba1e"}, + 1981, + {"2020-04-25T11:12:23+03:00", "5c78012e38f306d9601e1f43109c8aecbacb2e14", "ca8fa31c3fe1b4d92278d7a54364f6fb73dbae04", + "v0.7.0-39-gca8fa31"}, sourcery}; __dll_export |