mirror of
https://github.com/isar/libmdbx.git
synced 2025-12-15 04:32:21 +08:00
Compare commits
49 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d5e4c198d8 | ||
|
|
415d0d1dfb | ||
|
|
50d5b2345e | ||
|
|
d13534967a | ||
|
|
43070c7b26 | ||
|
|
45f8197635 | ||
|
|
3db02d2236 | ||
|
|
b79f6712e3 | ||
|
|
de63041b7d | ||
|
|
a5c064c33e | ||
|
|
9c832c24a6 | ||
|
|
c4a5325aaf | ||
|
|
93cf99a07c | ||
|
|
00ed61c685 | ||
|
|
f84d9f6208 | ||
|
|
9569b864ff | ||
|
|
8b69be8def | ||
|
|
4c619e32f7 | ||
|
|
ed86d9c066 | ||
|
|
6fbaa54d3e | ||
|
|
9d8fc7b984 | ||
|
|
8c2efe3aaa | ||
|
|
4b130bd82c | ||
|
|
44fb240955 | ||
|
|
bfea3ca9fb | ||
|
|
7ade182d64 | ||
|
|
4adc7aa58d | ||
|
|
110cf09cf8 | ||
|
|
fb25648b9c | ||
|
|
78170a5750 | ||
|
|
71d07b3a8e | ||
|
|
96c93ac2f1 | ||
|
|
6d61b18325 | ||
|
|
d01e44db0c | ||
|
|
464886ab61 | ||
|
|
3c574fca99 | ||
|
|
6b45498985 | ||
|
|
1fd4101e2e | ||
|
|
77f236db2a | ||
|
|
a0728023cd | ||
|
|
3705d705d3 | ||
|
|
72bc655ece | ||
|
|
c5f1f73fca | ||
|
|
925a673d57 | ||
|
|
c27787eb31 | ||
|
|
2b6fd968d2 | ||
|
|
ef7b4289c0 | ||
|
|
cbbfaf3202 | ||
|
|
f6be8e3e9a |
2
.github/FUNDING.yml
vendored
2
.github/FUNDING.yml
vendored
@@ -9,4 +9,4 @@ community_bridge: # Replace with a single Community Bridge project-name e.g., cl
|
||||
liberapay: # Replace with a single Liberapay username
|
||||
issuehunt: # Replace with a single IssueHunt username
|
||||
otechie: # Replace with a single Otechie username
|
||||
custom: ['https://paypal.me/erthink', 'https://www.blockchain.com/en/eth/address/0x19291d8658f762f3baceae1700c0b9466572ceab', 'https://www.blockchain.com/en/btc/address/152u2KXNWWGHQS3qiBEoQaveWyPvaSWYGC']
|
||||
custom: ['https://www.blockchain.com/en/eth/address/0x19291d8658f762f3baceae1700c0b9466572ceab', 'https://www.blockchain.com/en/btc/address/152u2KXNWWGHQS3qiBEoQaveWyPvaSWYGC']
|
||||
|
||||
22
.github/actions/spelling/expect.txt
vendored
22
.github/actions/spelling/expect.txt
vendored
@@ -1,4 +1,3 @@
|
||||
[200~Alexey
|
||||
aarch
|
||||
abcdef
|
||||
abf
|
||||
@@ -22,6 +21,7 @@ Akhunov
|
||||
Akula
|
||||
Aleksey
|
||||
alevel
|
||||
Alexey
|
||||
alexey
|
||||
Alfke
|
||||
alignas
|
||||
@@ -103,6 +103,8 @@ biarch
|
||||
bibtex
|
||||
BIGDATA
|
||||
bigdata
|
||||
Binance
|
||||
binance
|
||||
bindir
|
||||
binfmt
|
||||
binutils
|
||||
@@ -206,6 +208,8 @@ condattr
|
||||
condpair
|
||||
config
|
||||
constexpr
|
||||
constmeta
|
||||
coprs
|
||||
copyable
|
||||
copydetails
|
||||
copydoc
|
||||
@@ -385,6 +389,7 @@ DVAL
|
||||
DVI
|
||||
dw
|
||||
DWORD
|
||||
dwords
|
||||
dxb
|
||||
dxbfile
|
||||
dylib
|
||||
@@ -508,6 +513,7 @@ FCXX
|
||||
fd
|
||||
fdatasync
|
||||
featuredarticles
|
||||
fedorainfracloud
|
||||
fedotov
|
||||
FEEDNAME
|
||||
feof
|
||||
@@ -662,9 +668,11 @@ hlp
|
||||
HOfynt
|
||||
hostid
|
||||
HOSTUUID
|
||||
hotfix
|
||||
hpp
|
||||
hppa
|
||||
hpux
|
||||
href
|
||||
hrows
|
||||
hsr
|
||||
htags
|
||||
@@ -678,9 +686,11 @@ Hubert's
|
||||
hxx
|
||||
hyc
|
||||
hyperlink
|
||||
hypotetic
|
||||
IBERTY
|
||||
IBMC
|
||||
ibmxl
|
||||
idempotence
|
||||
idl
|
||||
idx
|
||||
ieeetr
|
||||
@@ -754,6 +764,7 @@ IRWXU
|
||||
isa
|
||||
isatty
|
||||
ISDIR
|
||||
iset
|
||||
ISOC
|
||||
isode
|
||||
isprint
|
||||
@@ -783,6 +794,7 @@ jgamble
|
||||
jmp
|
||||
jpg
|
||||
json
|
||||
kaiwetlesen
|
||||
kbuf
|
||||
Kerollmops
|
||||
kerr
|
||||
@@ -812,6 +824,7 @@ Kuntze
|
||||
kurt
|
||||
kuznik
|
||||
kval
|
||||
kwetlesen
|
||||
Lanfranchi
|
||||
largedata
|
||||
largepage
|
||||
@@ -827,7 +840,11 @@ lcklist
|
||||
LDAP
|
||||
LDFLAGS
|
||||
leafnode
|
||||
Ledgerwatch
|
||||
ledgerwatch
|
||||
leetal
|
||||
Leier
|
||||
leisim
|
||||
len
|
||||
lenfast
|
||||
Lenovo
|
||||
@@ -1227,6 +1244,7 @@ oublock
|
||||
OUTOFMEMORY
|
||||
ov
|
||||
overf
|
||||
overrided
|
||||
ovpage
|
||||
pageable
|
||||
pagecache
|
||||
@@ -1477,6 +1495,7 @@ rpath
|
||||
rpb
|
||||
rpcc
|
||||
rpid
|
||||
RPMs
|
||||
rqest
|
||||
rr
|
||||
RRF
|
||||
@@ -1921,6 +1940,7 @@ wdm
|
||||
webassembly
|
||||
webclient
|
||||
WERROR
|
||||
Wetlesen
|
||||
WEXITSTATUS
|
||||
WEXTRA
|
||||
whitelist
|
||||
|
||||
55
ChangeLog.md
55
ChangeLog.md
@@ -17,6 +17,61 @@ ChangeLog
|
||||
- Packages for [Astra Linux](https://astralinux.ru/), [ALT Linux](https://www.altlinux.org/), [ROSA Linux](https://www.rosalinux.ru/), etc.
|
||||
|
||||
|
||||
## v0.11.6 (scheduled for 2022-03-24)
|
||||
|
||||
The stable release with the complete workaround for an incoherence flaw of Linux unified page/buffer cache.
|
||||
Nonetheless the cause for this trouble may be an issue of Intel CPU cache/MESI.
|
||||
See [issue#269](https://github.com/erthink/libmdbx/issues/269) for more information.
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
- [David Bouyssié](https://github.com/david-bouyssie) for [Scala bindings](https://github.com/david-bouyssie/mdbx4s).
|
||||
- [Michelangelo Riccobene](https://github.com/mriccobene) for reporting and testing.
|
||||
|
||||
Fixes:
|
||||
|
||||
- [Added complete workaround](https://github.com/erthink/libmdbx/issues/269) for an incoherence flaw of Linux unified page/buffer cache.
|
||||
- [Fixed](https://github.com/erthink/libmdbx/issues/272) cursor reusing for read-only transactions.
|
||||
- Fixed copy&paste typo inside `mdbx::cursor::find_multivalue()`.
|
||||
|
||||
Minors:
|
||||
|
||||
- Minor refine C++ API for convenience.
|
||||
- Minor internals refines.
|
||||
- Added `lib-static` and `lib-shared` targets for make.
|
||||
- Added minor workaround for AppleClang 13.3 bug.
|
||||
- Clarified error messages of a signature/version mismatch.
|
||||
|
||||
|
||||
## v0.11.5 at 2022-02-23
|
||||
|
||||
The release with the temporary hotfix for a flaw of Linux unified page/buffer cache.
|
||||
See [issue#269](https://github.com/erthink/libmdbx/issues/269) for more information.
|
||||
|
||||
Acknowledgements:
|
||||
|
||||
- [Simon Leier](https://github.com/leisim) for reporting and testing.
|
||||
- [Kai Wetlesen](https://github.com/kaiwetlesen) for [RPMs](http://copr.fedorainfracloud.org/coprs/kwetlesen/libmdbx/).
|
||||
- [Tullio Canepa](https://github.com/canepat) for reporting C++ API issue and contributing.
|
||||
|
||||
Fixes:
|
||||
|
||||
- [Added hotfix](https://github.com/erthink/libmdbx/issues/269) for a flaw of Linux unified page/buffer cache.
|
||||
- [Fixed/Reworked](https://github.com/erthink/libmdbx/pull/270) move-assignment operators for "managed" classes of C++ API.
|
||||
- Fixed potential `SIGSEGV` while open DB with overrided non-default page size.
|
||||
- [Made](https://github.com/erthink/libmdbx/issues/267) `mdbx_env_open()` idempotence in failure cases.
|
||||
- Refined/Fixed pages reservation inside `mdbx_update_gc()` to avoid non-reclamation in a rare cases.
|
||||
- Fixed typo in a retained space calculation for the hsr-callback.
|
||||
|
||||
Minors:
|
||||
|
||||
- Reworked functions for meta-pages, split-off non-volatile.
|
||||
- Disentangled C11-atomic fences/barriers and pure-functions (with `__attribute__((__pure__))`) to avoid compiler misoptimization.
|
||||
- Fixed hypotetic unaligned access to 64-bit dwords on ARM with `__ARM_FEATURE_UNALIGNED` defined.
|
||||
- Reasonable paranoia that makes clarity for code readers.
|
||||
- Minor fixes Doxygen references, comments, descriptions, etc.
|
||||
|
||||
|
||||
## v0.11.4 at 2022-02-02
|
||||
|
||||
The stable release with fixes for large and huge databases sized of 4..128 TiB.
|
||||
|
||||
12
GNUmakefile
12
GNUmakefile
@@ -59,8 +59,8 @@ TOOLS := mdbx_stat mdbx_copy mdbx_dump mdbx_load mdbx_chk mdbx_drop
|
||||
MANPAGES := mdbx_stat.1 mdbx_copy.1 mdbx_dump.1 mdbx_load.1 mdbx_chk.1 mdbx_drop.1
|
||||
TIP := // TIP:
|
||||
|
||||
.PHONY: all help options lib tools clean install uninstall check_buildflags_tag
|
||||
.PHONY: install-strip install-no-strip strip libmdbx mdbx show-options
|
||||
.PHONY: all help options lib libs tools clean install uninstall check_buildflags_tag
|
||||
.PHONY: install-strip install-no-strip strip libmdbx mdbx show-options lib-static lib-shared
|
||||
|
||||
ifeq ("$(origin V)", "command line")
|
||||
MDBX_BUILD_VERBOSE := $(V)
|
||||
@@ -85,7 +85,7 @@ help:
|
||||
@echo " make all - build libraries and tools"
|
||||
@echo " make help - print this help"
|
||||
@echo " make options - list build options"
|
||||
@echo " make lib - build libraries"
|
||||
@echo " make lib - build libraries, also lib-static and lib-shared"
|
||||
@echo " make tools - built tools"
|
||||
@echo " make clean "
|
||||
@echo " make install "
|
||||
@@ -172,7 +172,7 @@ else
|
||||
endif
|
||||
#< dist-cutoff-end
|
||||
|
||||
lib libmdbx mdbx: libmdbx.a libmdbx.$(SO_SUFFIX)
|
||||
lib libs libmdbx mdbx: libmdbx.a libmdbx.$(SO_SUFFIX)
|
||||
|
||||
tools: $(TOOLS)
|
||||
|
||||
@@ -196,11 +196,11 @@ check_buildflags_tag:
|
||||
|
||||
buildflags.tag: check_buildflags_tag
|
||||
|
||||
libmdbx.a: mdbx-static.o mdbx++-static.o
|
||||
lib-static libmdbx.a: mdbx-static.o mdbx++-static.o
|
||||
@echo ' AR $@'
|
||||
$(QUIET)$(AR) rcs $@ $? $(HUSH)
|
||||
|
||||
libmdbx.$(SO_SUFFIX): mdbx-dylib.o mdbx++-dylib.o
|
||||
lib-shared libmdbx.$(SO_SUFFIX): mdbx-dylib.o mdbx++-dylib.o
|
||||
@echo ' LD $@'
|
||||
$(QUIET)$(CXX) $(CXXFLAGS) $^ -pthread -shared $(LDFLAGS) $(LIBS) -o $@
|
||||
|
||||
|
||||
3
Makefile
3
Makefile
@@ -3,7 +3,8 @@
|
||||
all help options \
|
||||
clean install install-no-strip install-strip strip tools uninstall \
|
||||
bench bench-clean bench-couple bench-quartet bench-triplet re-bench \
|
||||
lib libmdbx mdbx mdbx_chk mdbx_copy mdbx_drop mdbx_dump mdbx_load mdbx_stat \
|
||||
lib libs lib-static lib-shared \
|
||||
libmdbx mdbx mdbx_chk mdbx_copy mdbx_drop mdbx_dump mdbx_load mdbx_stat \
|
||||
check dist memcheck cross-gcc cross-qemu doxygen gcc-analyzer reformat \
|
||||
release-assets tags test build-test mdbx_test smoke smoke-fault smoke-singleprocess \
|
||||
test-asan test-leak test-singleprocess test-ubsan test-valgrind:
|
||||
|
||||
@@ -515,7 +515,7 @@ Another ways to build is potentially possible but not supported and will not.
|
||||
The `CMakeLists.txt` or `GNUMakefile` scripts will probably need to be modified accordingly.
|
||||
Using other methods do not forget to add the `ntdll.lib` to linking.
|
||||
|
||||
It should be noted that in _libmdbx_ was efforts to resolve
|
||||
It should be noted that in _libmdbx_ was efforts to avoid
|
||||
runtime dependencies from CRT and other MSVC libraries.
|
||||
For this is enough to pass the `-DMDBX_WITHOUT_MSVC_CRT:BOOL=ON` option
|
||||
during configure by CMake.
|
||||
@@ -571,6 +571,7 @@ Bindings
|
||||
|
||||
| Runtime | Repo | Author |
|
||||
| ------- | ------ | ------ |
|
||||
| Scala | [mdbx4s](https://github.com/david-bouyssie/mdbx4s) | [David Bouyssié](https://github.com/david-bouyssie) |
|
||||
| Haskell | [libmdbx-hs](https://hackage.haskell.org/package/libmdbx) | [Francisco Vallarino](https://github.com/fjvallarino) |
|
||||
| NodeJS, [Deno](https://deno.land/) | [lmdbx-js](https://github.com/kriszyp/lmdbx-js) | [Kris Zyp](https://github.com/kriszyp/)
|
||||
| NodeJS | [node-mdbx](https://www.npmjs.com/package/node-mdbx/) | [Сергей Федотов](mailto:sergey.fedotov@corp.mail.ru) |
|
||||
@@ -731,4 +732,4 @@ syscall and by scanning the data directory.
|
||||
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
#### This is a mirror of the origin repository that was moved to [abf.io](https://abf.io/erthink/) because of discriminatory restrictions for Russian Crimea.
|
||||
#### This is a mirror of the origin repository that was moved to [gitflic.ru](https://gitflic.ru/project/erthink/libmdbx) because of discriminatory restrictions for Russian Crimea.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
version: 0.11.4.{build}
|
||||
version: 0.11.6.{build}
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
|
||||
72
mdbx.h
72
mdbx.h
@@ -784,36 +784,51 @@ enum MDBX_constants {
|
||||
* \note Most of debug feature enabled only when libmdbx builded with
|
||||
* \ref MDBX_DEBUG build option. @{ */
|
||||
|
||||
/** Log level (requires build libmdbx with \ref MDBX_DEBUG option) */
|
||||
/** Log level
|
||||
* \note Levels detailed than (great than) \ref MDBX_LOG_NOTICE
|
||||
* requires build libmdbx with \ref MDBX_DEBUG option. */
|
||||
enum MDBX_log_level_t {
|
||||
/** Critical conditions, i.e. assertion failures */
|
||||
/** Critical conditions, i.e. assertion failures.
|
||||
* \note libmdbx always produces such messages regardless
|
||||
* of \ref MDBX_DEBUG build option. */
|
||||
MDBX_LOG_FATAL = 0,
|
||||
|
||||
/** Enables logging for error conditions and \ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for error conditions
|
||||
* and \ref MDBX_LOG_FATAL.
|
||||
* \note libmdbx always produces such messages regardless
|
||||
* of \ref MDBX_DEBUG build option. */
|
||||
MDBX_LOG_ERROR = 1,
|
||||
|
||||
/** Enables logging for warning conditions and \ref MDBX_LOG_ERROR ...
|
||||
\ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for warning conditions
|
||||
* and \ref MDBX_LOG_ERROR ... \ref MDBX_LOG_FATAL.
|
||||
* \note libmdbx always produces such messages regardless
|
||||
* of \ref MDBX_DEBUG build option. */
|
||||
MDBX_LOG_WARN = 2,
|
||||
|
||||
/** Enables logging for normal but significant condition and
|
||||
\ref MDBX_LOG_WARN ... \ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for normal but significant condition
|
||||
* and \ref MDBX_LOG_WARN ... \ref MDBX_LOG_FATAL.
|
||||
* \note libmdbx always produces such messages regardless
|
||||
* of \ref MDBX_DEBUG build option. */
|
||||
MDBX_LOG_NOTICE = 3,
|
||||
|
||||
/** Enables logging for verbose informational and \ref MDBX_LOG_NOTICE ...
|
||||
\ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for verbose informational
|
||||
* and \ref MDBX_LOG_NOTICE ... \ref MDBX_LOG_FATAL.
|
||||
* \note Requires build libmdbx with \ref MDBX_DEBUG option. */
|
||||
MDBX_LOG_VERBOSE = 4,
|
||||
|
||||
/** Enables logging for debug-level messages and \ref MDBX_LOG_VERBOSE ...
|
||||
\ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for debug-level messages
|
||||
* and \ref MDBX_LOG_VERBOSE ... \ref MDBX_LOG_FATAL.
|
||||
* \note Requires build libmdbx with \ref MDBX_DEBUG option. */
|
||||
MDBX_LOG_DEBUG = 5,
|
||||
|
||||
/** Enables logging for trace debug-level messages and \ref MDBX_LOG_DEBUG ...
|
||||
\ref MDBX_LOG_FATAL */
|
||||
/** Enables logging for trace debug-level messages
|
||||
* and \ref MDBX_LOG_DEBUG ... \ref MDBX_LOG_FATAL.
|
||||
* \note Requires build libmdbx with \ref MDBX_DEBUG option. */
|
||||
MDBX_LOG_TRACE = 6,
|
||||
|
||||
/** Enables extra debug-level messages (dump pgno lists)
|
||||
and all other log-messages */
|
||||
* and all other log-messages.
|
||||
* \note Requires build libmdbx with \ref MDBX_DEBUG option. */
|
||||
MDBX_LOG_EXTRA = 7,
|
||||
|
||||
#ifdef ENABLE_UBSAN
|
||||
@@ -836,30 +851,36 @@ enum MDBX_debug_flags_t {
|
||||
MDBX_DBG_NONE = 0,
|
||||
|
||||
/** Enable assertion checks.
|
||||
* Requires build with \ref MDBX_DEBUG > 0 */
|
||||
* \note Always enabled for builds with `MDBX_FORCE_ASSERTIONS` option,
|
||||
* otherwise requires build with \ref MDBX_DEBUG > 0 */
|
||||
MDBX_DBG_ASSERT = 1,
|
||||
|
||||
/** Enable pages usage audit at commit transactions.
|
||||
* Requires build with \ref MDBX_DEBUG > 0 */
|
||||
* \note Requires build with \ref MDBX_DEBUG > 0 */
|
||||
MDBX_DBG_AUDIT = 2,
|
||||
|
||||
/** Enable small random delays in critical points.
|
||||
* Requires build with \ref MDBX_DEBUG > 0 */
|
||||
* \note Requires build with \ref MDBX_DEBUG > 0 */
|
||||
MDBX_DBG_JITTER = 4,
|
||||
|
||||
/** Include or not meta-pages in coredump files.
|
||||
* May affect performance in \ref MDBX_WRITEMAP mode */
|
||||
* \note May affect performance in \ref MDBX_WRITEMAP mode */
|
||||
MDBX_DBG_DUMP = 8,
|
||||
|
||||
/** Allow multi-opening environment(s) */
|
||||
MDBX_DBG_LEGACY_MULTIOPEN = 16,
|
||||
|
||||
/** Allow read and write transactions overlapping for the same thread */
|
||||
/** Allow read and write transactions overlapping for the same thread. */
|
||||
MDBX_DBG_LEGACY_OVERLAP = 32,
|
||||
|
||||
/** Don't auto-upgrade format signature.
|
||||
* \note However a new write transactions will use and store
|
||||
* the last signature regardless this flag */
|
||||
MDBX_DBG_DONT_UPGRADE = 64,
|
||||
|
||||
#ifdef ENABLE_UBSAN
|
||||
MDBX_DBG_MAX = ((unsigned)MDBX_LOG_MAX) << 16 |
|
||||
63 /* avoid UBSAN false-positive trap by a tests */,
|
||||
127 /* avoid UBSAN false-positive trap by a tests */,
|
||||
#endif /* ENABLE_UBSAN */
|
||||
|
||||
/** for mdbx_setup_debug() only: Don't change current settings */
|
||||
@@ -4898,7 +4919,9 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env);
|
||||
* is not enough space in the database (i.e. before increasing the database size
|
||||
* or before \ref MDBX_MAP_FULL error) and thus can be used to resolve issues
|
||||
* with a "long-lived" read transactions.
|
||||
* \see long-lived-read
|
||||
* \see mdbx_env_set_hsr()
|
||||
* \see mdbx_env_get_hsr()
|
||||
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
|
||||
*
|
||||
* Using this callback you can choose how to resolve the situation:
|
||||
* - abort the write transaction with an error;
|
||||
@@ -4956,8 +4979,6 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env);
|
||||
*
|
||||
* \retval 2 or great The reader process was terminated or killed,
|
||||
* and libmdbx should entirely reset reader registration.
|
||||
*
|
||||
* \see mdbx_env_set_hsr() \see mdbx_env_get_hsr()
|
||||
*/
|
||||
typedef int(MDBX_hsr_func)(const MDBX_env *env, const MDBX_txn *txn,
|
||||
mdbx_pid_t pid, mdbx_tid_t tid, uint64_t laggard,
|
||||
@@ -4971,8 +4992,9 @@ typedef int(MDBX_hsr_func)(const MDBX_env *env, const MDBX_txn *txn,
|
||||
* The callback will only be triggered when the database is full due to a
|
||||
* reader(s) prevents the old data from being recycled.
|
||||
*
|
||||
* \see MDBX_hsr_func
|
||||
* \see mdbx_env_get_hsr()
|
||||
* \see long-lived-read
|
||||
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
|
||||
*
|
||||
* \param [in] env An environment handle returned
|
||||
* by \ref mdbx_env_create().
|
||||
@@ -4985,7 +5007,9 @@ LIBMDBX_API int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr_callback);
|
||||
/** \brief Gets current Handle-Slow-Readers callback used to resolve database
|
||||
* full/overflow issue due to a reader(s) which prevents the old data from being
|
||||
* recycled.
|
||||
* \see MDBX_hsr_func
|
||||
* \see mdbx_env_set_hsr()
|
||||
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
|
||||
*
|
||||
* \param [in] env An environment handle returned by \ref mdbx_env_create().
|
||||
*
|
||||
|
||||
78
mdbx.h++
78
mdbx.h++
@@ -2960,6 +2960,18 @@ public:
|
||||
inline geometry &make_fixed(intptr_t size) noexcept;
|
||||
inline geometry &make_dynamic(intptr_t lower = minimal_value,
|
||||
intptr_t upper = maximal_value) noexcept;
|
||||
MDBX_CXX11_CONSTEXPR geometry() noexcept {}
|
||||
MDBX_CXX11_CONSTEXPR
|
||||
geometry(const geometry &) noexcept = default;
|
||||
MDBX_CXX11_CONSTEXPR geometry(intptr_t size_lower,
|
||||
intptr_t size_now = default_value,
|
||||
intptr_t size_upper = maximal_value,
|
||||
intptr_t growth_step = default_value,
|
||||
intptr_t shrink_threshold = default_value,
|
||||
intptr_t pagesize = default_value) noexcept
|
||||
: size_lower(size_lower), size_now(size_now), size_upper(size_upper),
|
||||
growth_step(growth_step), shrink_threshold(shrink_threshold),
|
||||
pagesize(pagesize) {}
|
||||
};
|
||||
|
||||
/// \brief Operation mode.
|
||||
@@ -2984,6 +2996,10 @@ public:
|
||||
/// \copydoc MDBX_COALESCE
|
||||
bool coalesce{false};
|
||||
MDBX_CXX11_CONSTEXPR reclaiming_options() noexcept {}
|
||||
MDBX_CXX11_CONSTEXPR
|
||||
reclaiming_options(const reclaiming_options &) noexcept = default;
|
||||
MDBX_CXX14_CONSTEXPR reclaiming_options &
|
||||
operator=(const reclaiming_options &) noexcept = default;
|
||||
reclaiming_options(MDBX_env_flags_t) noexcept;
|
||||
};
|
||||
|
||||
@@ -2999,6 +3015,10 @@ public:
|
||||
/// \copydoc MDBX_NOMEMINIT
|
||||
bool disable_clear_memory{false};
|
||||
MDBX_CXX11_CONSTEXPR operate_options() noexcept {}
|
||||
MDBX_CXX11_CONSTEXPR
|
||||
operate_options(const operate_options &) noexcept = default;
|
||||
MDBX_CXX14_CONSTEXPR operate_options &
|
||||
operator=(const operate_options &) noexcept = default;
|
||||
operate_options(MDBX_env_flags_t) noexcept;
|
||||
};
|
||||
|
||||
@@ -3016,6 +3036,19 @@ public:
|
||||
env::operate_options options;
|
||||
|
||||
MDBX_CXX11_CONSTEXPR operate_parameters() noexcept {}
|
||||
MDBX_CXX11_CONSTEXPR
|
||||
operate_parameters(
|
||||
const unsigned max_maps, const unsigned max_readers = 0,
|
||||
const env::mode mode = env::mode::write_mapped_io,
|
||||
env::durability durability = env::durability::robust_synchronous,
|
||||
const env::reclaiming_options &reclaiming = env::reclaiming_options(),
|
||||
const env::operate_options &options = env::operate_options()) noexcept
|
||||
: max_maps(max_maps), max_readers(max_readers), mode(mode),
|
||||
durability(durability), reclaiming(reclaiming), options(options) {}
|
||||
MDBX_CXX11_CONSTEXPR
|
||||
operate_parameters(const operate_parameters &) noexcept = default;
|
||||
MDBX_CXX14_CONSTEXPR operate_parameters &
|
||||
operator=(const operate_parameters &) noexcept = default;
|
||||
MDBX_env_flags_t
|
||||
make_flags(bool accede = true, ///< \copydoc MDBX_ACCEDE
|
||||
bool use_subdirectory =
|
||||
@@ -3027,7 +3060,6 @@ public:
|
||||
reclaiming_from_flags(MDBX_env_flags_t flags) noexcept;
|
||||
inline static env::operate_options
|
||||
options_from_flags(MDBX_env_flags_t flags) noexcept;
|
||||
operate_parameters(const env &);
|
||||
};
|
||||
|
||||
/// \brief Returns current operation parameters.
|
||||
@@ -3423,6 +3455,8 @@ public:
|
||||
env::geometry geometry;
|
||||
mdbx_mode_t file_mode_bits{0640};
|
||||
bool use_subdirectory{false};
|
||||
MDBX_CXX11_CONSTEXPR create_parameters() noexcept = default;
|
||||
create_parameters(const create_parameters &) noexcept = default;
|
||||
};
|
||||
|
||||
/// \brief Create new or open existing database.
|
||||
@@ -3453,7 +3487,15 @@ public:
|
||||
void close(bool dont_sync = false);
|
||||
|
||||
env_managed(env_managed &&) = default;
|
||||
env_managed &operator=(env_managed &&) = default;
|
||||
env_managed &operator=(env_managed &&other) {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
close();
|
||||
}
|
||||
inherited::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
env_managed(const env_managed &) = delete;
|
||||
env_managed &operator=(const env_managed &) = delete;
|
||||
virtual ~env_managed() noexcept;
|
||||
@@ -3744,7 +3786,15 @@ class LIBMDBX_API_TYPE txn_managed : public txn {
|
||||
public:
|
||||
MDBX_CXX11_CONSTEXPR txn_managed() noexcept = default;
|
||||
txn_managed(txn_managed &&) = default;
|
||||
txn_managed &operator=(txn_managed &&) = default;
|
||||
txn_managed &operator=(txn_managed &&other) {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
abort();
|
||||
}
|
||||
inherited::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
txn_managed(const txn_managed &) = delete;
|
||||
txn_managed &operator=(const txn_managed &) = delete;
|
||||
~txn_managed() noexcept;
|
||||
@@ -3939,7 +3989,16 @@ public:
|
||||
void close();
|
||||
|
||||
cursor_managed(cursor_managed &&) = default;
|
||||
cursor_managed &operator=(cursor_managed &&) = default;
|
||||
cursor_managed &operator=(cursor_managed &&other) {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
close();
|
||||
}
|
||||
inherited::operator=(std::move(other));
|
||||
return *this;
|
||||
}
|
||||
|
||||
cursor_managed(const cursor_managed &) = delete;
|
||||
cursor_managed &operator=(const cursor_managed &) = delete;
|
||||
~cursor_managed() noexcept { ::mdbx_cursor_close(handle_); }
|
||||
@@ -4738,7 +4797,12 @@ inline size_t env::limits::transaction_size_max(intptr_t pagesize) {
|
||||
}
|
||||
|
||||
inline env::operate_parameters env::get_operation_parameters() const {
|
||||
return env::operate_parameters(*this);
|
||||
const auto flags = get_flags();
|
||||
return operate_parameters(max_maps(), max_readers(),
|
||||
operate_parameters::mode_from_flags(flags),
|
||||
operate_parameters::durability_from_flags(flags),
|
||||
operate_parameters::reclaiming_from_flags(flags),
|
||||
operate_parameters::options_from_flags(flags));
|
||||
}
|
||||
|
||||
inline env::mode env::get_mode() const {
|
||||
@@ -5603,7 +5667,7 @@ inline cursor::move_result cursor::move(move_operation operation,
|
||||
inline cursor::move_result cursor::find_multivalue(const slice &key,
|
||||
const slice &value,
|
||||
bool throw_notfound) {
|
||||
return move(key_exact, key, value, throw_notfound);
|
||||
return move(multi_find_pair, key, value, throw_notfound);
|
||||
}
|
||||
|
||||
inline cursor::move_result cursor::lower_bound_multivalue(const slice &key,
|
||||
@@ -5794,7 +5858,7 @@ inline bool cursor::erase(const slice &key, bool whole_multivalue) {
|
||||
|
||||
inline bool cursor::erase(const slice &key, const slice &value) {
|
||||
move_result data = find_multivalue(key, value, false);
|
||||
return data.done ? erase() : data.done;
|
||||
return data.done && erase();
|
||||
}
|
||||
|
||||
} // namespace mdbx
|
||||
|
||||
@@ -4,7 +4,7 @@ N | MASK | ENV | TXN | DB | PUT | DBI | NOD
|
||||
1 |0000 0002|ALLOC_GC |TXN_ERROR |REVERSEKEY|F_SUBDATA |DBI_STALE |F_SUBDATA|P_LEAF | |
|
||||
2 |0000 0004|ALLOC_NEW |TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
||||
3 |0000 0008|ALLOC_SLOT |TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
||||
4 |0000 0010| |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||
4 |0000 0010|ALLOC_FAKE |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||
5 |0000 0020| | |INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
||||
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
||||
|
||||
1066
src/core.c
1066
src/core.c
File diff suppressed because it is too large
Load Diff
@@ -445,7 +445,7 @@ typedef struct MDBX_meta {
|
||||
#define MDBX_DATASIGN_WEAK 1u
|
||||
#define SIGN_IS_STEADY(sign) ((sign) > MDBX_DATASIGN_WEAK)
|
||||
#define META_IS_STEADY(meta) \
|
||||
SIGN_IS_STEADY(unaligned_peek_u64(4, (meta)->mm_datasync_sign))
|
||||
SIGN_IS_STEADY(unaligned_peek_u64_volatile(4, (meta)->mm_datasync_sign))
|
||||
uint32_t mm_datasync_sign[2];
|
||||
|
||||
/* txnid that committed this page, the second of a two-phase-update pair */
|
||||
@@ -945,6 +945,7 @@ struct MDBX_txn {
|
||||
size_t mt_owner; /* thread ID that owns this transaction */
|
||||
MDBX_canary mt_canary;
|
||||
void *mt_userctx; /* User-settable context */
|
||||
MDBX_cursor **mt_cursors;
|
||||
|
||||
union {
|
||||
struct {
|
||||
@@ -953,7 +954,6 @@ struct MDBX_txn {
|
||||
} to;
|
||||
struct {
|
||||
/* In write txns, array of cursors for each DB */
|
||||
MDBX_cursor **cursors;
|
||||
pgno_t *reclaimed_pglist; /* Reclaimed GC pages */
|
||||
txnid_t last_reclaimed; /* ID of last used record */
|
||||
#if MDBX_ENABLE_REFUND
|
||||
@@ -1222,25 +1222,21 @@ MDBX_INTERNAL_FUNC void mdbx_debug_log_va(int level, const char *function,
|
||||
int line, const char *fmt,
|
||||
va_list args);
|
||||
|
||||
#define mdbx_log_enabled(msg) unlikely(msg <= mdbx_loglevel)
|
||||
|
||||
#if MDBX_DEBUG
|
||||
|
||||
#define mdbx_assert_enabled() unlikely(mdbx_runtime_flags &MDBX_DBG_ASSERT)
|
||||
|
||||
#define mdbx_audit_enabled() unlikely(mdbx_runtime_flags &MDBX_DBG_AUDIT)
|
||||
|
||||
#define mdbx_log_enabled(msg) unlikely(msg <= mdbx_loglevel)
|
||||
#define mdbx_audit_enabled() unlikely((mdbx_runtime_flags & MDBX_DBG_AUDIT))
|
||||
#else /* MDBX_DEBUG */
|
||||
|
||||
#define mdbx_log_enabled(msg) (msg < MDBX_LOG_VERBOSE && msg <= mdbx_loglevel)
|
||||
#define mdbx_audit_enabled() (0)
|
||||
#endif /* MDBX_DEBUG */
|
||||
|
||||
#if !defined(NDEBUG) || MDBX_FORCE_ASSERTIONS
|
||||
#if MDBX_FORCE_ASSERTIONS
|
||||
#define mdbx_assert_enabled() (1)
|
||||
#elif MDBX_DEBUG
|
||||
#define mdbx_assert_enabled() likely((mdbx_runtime_flags & MDBX_DBG_ASSERT))
|
||||
#else
|
||||
#define mdbx_assert_enabled() (0)
|
||||
#endif /* NDEBUG */
|
||||
|
||||
#endif /* MDBX_DEBUG */
|
||||
#endif /* assertions */
|
||||
|
||||
#if !MDBX_DEBUG && defined(__ANDROID_API__)
|
||||
#define mdbx_assert_fail(env, msg, func, line) \
|
||||
@@ -1252,33 +1248,33 @@ void mdbx_assert_fail(const MDBX_env *env, const char *msg, const char *func,
|
||||
|
||||
#define mdbx_debug_extra(fmt, ...) \
|
||||
do { \
|
||||
if (MDBX_DEBUG && mdbx_log_enabled(MDBX_LOG_EXTRA)) \
|
||||
if (mdbx_log_enabled(MDBX_LOG_EXTRA)) \
|
||||
mdbx_debug_log(MDBX_LOG_EXTRA, __func__, __LINE__, fmt, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mdbx_debug_extra_print(fmt, ...) \
|
||||
do { \
|
||||
if (MDBX_DEBUG && mdbx_log_enabled(MDBX_LOG_EXTRA)) \
|
||||
if (mdbx_log_enabled(MDBX_LOG_EXTRA)) \
|
||||
mdbx_debug_log(MDBX_LOG_EXTRA, NULL, 0, fmt, __VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mdbx_trace(fmt, ...) \
|
||||
do { \
|
||||
if (MDBX_DEBUG && mdbx_log_enabled(MDBX_LOG_TRACE)) \
|
||||
if (mdbx_log_enabled(MDBX_LOG_TRACE)) \
|
||||
mdbx_debug_log(MDBX_LOG_TRACE, __func__, __LINE__, fmt "\n", \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mdbx_debug(fmt, ...) \
|
||||
do { \
|
||||
if (MDBX_DEBUG && mdbx_log_enabled(MDBX_LOG_DEBUG)) \
|
||||
if (mdbx_log_enabled(MDBX_LOG_DEBUG)) \
|
||||
mdbx_debug_log(MDBX_LOG_DEBUG, __func__, __LINE__, fmt "\n", \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
#define mdbx_verbose(fmt, ...) \
|
||||
do { \
|
||||
if (MDBX_DEBUG && mdbx_log_enabled(MDBX_LOG_VERBOSE)) \
|
||||
if (mdbx_log_enabled(MDBX_LOG_VERBOSE)) \
|
||||
mdbx_debug_log(MDBX_LOG_VERBOSE, __func__, __LINE__, fmt "\n", \
|
||||
__VA_ARGS__); \
|
||||
} while (0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_CHK 1 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_CHK 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_chk \- MDBX checking tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -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 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_COPY 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_copy \- MDBX environment copy tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" Copyright 2021-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2014-2021 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_DROP 1 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_DROP 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_drop \- MDBX database delete tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -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 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_DUMP 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_dump \- MDBX environment export tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -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 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_LOAD 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_load \- MDBX environment import tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -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 "2022-02-02" "MDBX 0.11.4"
|
||||
.TH MDBX_STAT 1 "2022-03-24" "MDBX 0.11.6"
|
||||
.SH NAME
|
||||
mdbx_stat \- MDBX environment status tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
11
src/mdbx.c++
11
src/mdbx.c++
@@ -1234,21 +1234,12 @@ env::operate_options::operate_options(MDBX_env_flags_t flags) noexcept
|
||||
disable_readahead((flags & MDBX_NORDAHEAD) ? true : false),
|
||||
disable_clear_memory((flags & MDBX_NOMEMINIT) ? true : false) {}
|
||||
|
||||
env::operate_parameters::operate_parameters(const env &env)
|
||||
: max_maps(env.max_maps()), max_readers(env.max_readers()) {
|
||||
const auto flags = env.get_flags();
|
||||
mode = mode_from_flags(flags);
|
||||
durability = durability_from_flags(flags);
|
||||
reclaiming = reclaiming_from_flags(flags);
|
||||
options = options_from_flags(flags);
|
||||
}
|
||||
|
||||
bool env::is_pristine() const {
|
||||
return get_stat().ms_mod_txnid == 0 &&
|
||||
get_info().mi_recent_txnid == INITIAL_TXNID;
|
||||
}
|
||||
|
||||
bool env::is_empty() const { return get_stat().ms_branch_pages == 0; }
|
||||
bool env::is_empty() const { return get_stat().ms_leaf_pages == 0; }
|
||||
|
||||
#ifdef MDBX_STD_FILESYSTEM_PATH
|
||||
env &env::copy(const ::std::filesystem::path &destination, bool compactify,
|
||||
|
||||
@@ -935,8 +935,8 @@ static void usage(char *prog) {
|
||||
exit(EXIT_INTERRUPTED);
|
||||
}
|
||||
|
||||
static __inline bool meta_ot(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
uint64_t sign_b, const bool wanna_steady) {
|
||||
static bool meta_ot(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
uint64_t sign_b, const bool wanna_steady) {
|
||||
if (txn_a == txn_b)
|
||||
return SIGN_IS_STEADY(sign_b);
|
||||
|
||||
@@ -946,8 +946,8 @@ static __inline bool meta_ot(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
return txn_a < txn_b;
|
||||
}
|
||||
|
||||
static __inline bool meta_eq(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
uint64_t sign_b) {
|
||||
static bool meta_eq(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
uint64_t sign_b) {
|
||||
if (!txn_a || txn_a != txn_b)
|
||||
return false;
|
||||
|
||||
@@ -957,7 +957,7 @@ static __inline bool meta_eq(txnid_t txn_a, uint64_t sign_a, txnid_t txn_b,
|
||||
return true;
|
||||
}
|
||||
|
||||
static __inline int meta_recent(const bool wanna_steady) {
|
||||
static int meta_recent(const bool wanna_steady) {
|
||||
if (meta_ot(envinfo.mi_meta0_txnid, envinfo.mi_meta0_sign,
|
||||
envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign, wanna_steady))
|
||||
return meta_ot(envinfo.mi_meta2_txnid, envinfo.mi_meta2_sign,
|
||||
@@ -971,7 +971,7 @@ static __inline int meta_recent(const bool wanna_steady) {
|
||||
: 0;
|
||||
}
|
||||
|
||||
static __inline int meta_tail(int head) {
|
||||
static int meta_tail(int head) {
|
||||
switch (head) {
|
||||
case 0:
|
||||
return meta_ot(envinfo.mi_meta1_txnid, envinfo.mi_meta1_sign,
|
||||
@@ -1226,7 +1226,7 @@ int main(int argc, char *argv[]) {
|
||||
mdbx_setup_debug((verbose < MDBX_LOG_TRACE - 1)
|
||||
? (MDBX_log_level_t)(verbose + 1)
|
||||
: MDBX_LOG_TRACE,
|
||||
MDBX_DBG_LEGACY_OVERLAP, logger);
|
||||
MDBX_DBG_LEGACY_OVERLAP | MDBX_DBG_DONT_UPGRADE, logger);
|
||||
|
||||
rc = mdbx_env_create(&env);
|
||||
if (rc) {
|
||||
|
||||
@@ -361,17 +361,29 @@
|
||||
#endif /* MDBX_64BIT_CAS */
|
||||
|
||||
#ifndef MDBX_UNALIGNED_OK
|
||||
#ifdef _MSC_VER
|
||||
#define MDBX_UNALIGNED_OK 1 /* avoid MSVC misoptimization */
|
||||
#if defined(__ALIGNED__) || defined(__SANITIZE_UNDEFINED__)
|
||||
#define MDBX_UNALIGNED_OK 0 /* no unaligned access allowed */
|
||||
#elif defined(__ARM_FEATURE_UNALIGNED)
|
||||
#define MDBX_UNALIGNED_OK 4 /* ok unaligned for 32-bit words */
|
||||
#elif __CLANG_PREREQ(5, 0) || __GNUC_PREREQ(5, 0)
|
||||
#define MDBX_UNALIGNED_OK 0 /* expecting optimization is well done */
|
||||
#elif (defined(__ia32__) || defined(__ARM_FEATURE_UNALIGNED)) && \
|
||||
!defined(__ALIGNED__)
|
||||
#define MDBX_UNALIGNED_OK 1
|
||||
#else
|
||||
/* expecting an optimization will well done, also this
|
||||
* hushes false-positives from UBSAN (undefined behaviour sanitizer) */
|
||||
#define MDBX_UNALIGNED_OK 0
|
||||
#elif defined(__e2k__) || defined(__elbrus__)
|
||||
#if __iset__ > 4
|
||||
#define MDBX_UNALIGNED_OK 8 /* ok unaligned for 64-bit words */
|
||||
#else
|
||||
#define MDBX_UNALIGNED_OK 4 /* ok unaligned for 32-bit words */
|
||||
#endif
|
||||
#endif /* MDBX_UNALIGNED_OK */
|
||||
#elif defined(__ia32__)
|
||||
#define MDBX_UNALIGNED_OK 8 /* ok unaligned for 64-bit words */
|
||||
#else
|
||||
#define MDBX_UNALIGNED_OK 0 /* no unaligned access allowed */
|
||||
#endif
|
||||
#elif MDBX_UNALIGNED_OK == 1
|
||||
#undef MDBX_UNALIGNED_OK
|
||||
#define MDBX_UNALIGNED_OK 32 /* any unaligned access allowed */
|
||||
#endif /* MDBX_UNALIGNED_OK */
|
||||
|
||||
#ifndef MDBX_CACHELINE_SIZE
|
||||
#if defined(SYSTEM_CACHE_ALIGNMENT_SIZE)
|
||||
|
||||
@@ -144,9 +144,9 @@ case ${UNAME} in
|
||||
mkdir -p $TESTDB_DIR && rm -f $TESTDB_DIR/*
|
||||
|
||||
if LC_ALL=C free | grep -q -i available; then
|
||||
ram_avail_mb=$(($(LC_ALL=C free | grep -i Mem: | tr -s [:blank:] ' ' | cut -d ' ' -f 7) / 1024))
|
||||
ram_avail_mb=$(($(LC_ALL=C free | grep -i Mem: | tr -s '[:blank:]' ' ' | cut -d ' ' -f 7) / 1024))
|
||||
else
|
||||
ram_avail_mb=$(($(LC_ALL=C free | grep -i Mem: | tr -s [:blank:] ' ' | cut -d ' ' -f 4) / 1024))
|
||||
ram_avail_mb=$(($(LC_ALL=C free | grep -i Mem: | tr -s '[:blank:]' ' ' | cut -d ' ' -f 4) / 1024))
|
||||
fi
|
||||
;;
|
||||
|
||||
|
||||
44
test/utils.h
44
test/utils.h
@@ -148,35 +148,31 @@ static __inline uint16_t bswap16(uint16_t v) { return v << 8 | v >> 8; }
|
||||
namespace unaligned {
|
||||
|
||||
template <typename T> static __inline T load(const void *ptr) {
|
||||
#if defined(_MSC_VER) && \
|
||||
(defined(_M_ARM64) || defined(_M_X64) || defined(_M_IA64))
|
||||
return *(const T __unaligned *)ptr;
|
||||
#elif MDBX_UNALIGNED_OK
|
||||
return *(const T *)ptr;
|
||||
if (MDBX_UNALIGNED_OK >= sizeof(T))
|
||||
return *(const T *)ptr;
|
||||
else {
|
||||
#if defined(__unaligned) || defined(_M_ARM) || defined(_M_ARM64) || \
|
||||
defined(_M_X64) || defined(_M_IA64)
|
||||
return *(const T __unaligned *)ptr;
|
||||
#else
|
||||
T local;
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_memcpy(&local, (const T *)ptr, sizeof(T));
|
||||
#else
|
||||
memcpy(&local, (const T *)ptr, sizeof(T));
|
||||
#endif /* __GNUC__ || __clang__ */
|
||||
return local;
|
||||
#endif /* MDBX_UNALIGNED_OK */
|
||||
T local;
|
||||
memcpy(&local, (const T *)ptr, sizeof(T));
|
||||
return local;
|
||||
#endif /* _MSC_VER || __unaligned */
|
||||
}
|
||||
}
|
||||
|
||||
template <typename T> static __inline void store(void *ptr, const T &value) {
|
||||
#if defined(_MSC_VER) && \
|
||||
(defined(_M_ARM64) || defined(_M_X64) || defined(_M_IA64))
|
||||
*((T __unaligned *)ptr) = value;
|
||||
#elif MDBX_UNALIGNED_OK
|
||||
*(volatile T *)ptr = value;
|
||||
if (MDBX_UNALIGNED_OK >= sizeof(T))
|
||||
*(T *)ptr = value;
|
||||
else {
|
||||
#if defined(__unaligned) || defined(_M_ARM) || defined(_M_ARM64) || \
|
||||
defined(_M_X64) || defined(_M_IA64)
|
||||
*((T __unaligned *)ptr) = value;
|
||||
#else
|
||||
#if defined(__GNUC__) || defined(__clang__)
|
||||
__builtin_memcpy(ptr, &value, sizeof(T));
|
||||
#else
|
||||
memcpy(ptr, &value, sizeof(T));
|
||||
#endif /* __GNUC__ || __clang__ */
|
||||
#endif /* MDBX_UNALIGNED_OK */
|
||||
memcpy(ptr, &value, sizeof(T));
|
||||
#endif /* _MSC_VER || __unaligned */
|
||||
}
|
||||
}
|
||||
|
||||
} /* namespace unaligned */
|
||||
|
||||
@@ -31,6 +31,20 @@
|
||||
fun:mdbx_wipe_steady
|
||||
}
|
||||
|
||||
# memcmp() inside mdbx_iov_write() as workaround for https://github.com/erthink/libmdbx/issues/269
|
||||
{
|
||||
write-page-check-bcmp
|
||||
Memcheck:Cond
|
||||
fun:bcmp
|
||||
fun:mdbx_iov_write
|
||||
}
|
||||
{
|
||||
write-page-check-memcmp
|
||||
Memcheck:Cond
|
||||
fun:memcmp*
|
||||
fun:mdbx_iov_write
|
||||
}
|
||||
|
||||
# single-page flush by pwrite()
|
||||
{
|
||||
pwrite-page-flush
|
||||
|
||||
Reference in New Issue
Block a user