Compare commits

..

53 Commits

Author SHA1 Message Date
Leonid Yuriev
8f5ae79b51 mdbx: bump version to 0.7.x
Change-Id: I6cb06fbd7119eed086b54a9760db1e0edf5de07b
2020-03-18 17:19:12 +03:00
Leonid Yuriev
86b1f2017a mdbx: add note about Wine limitations.
Change-Id: I0d09c6161f3ed8eacbbedbb9f274d81cd5cfdd2c
2020-03-18 17:19:12 +03:00
Leonid Yuriev
9b1cddf520 mdbx-doc: update Rust bindings info.
Resolves https://github.com/erthink/libmdbx/issues/85

Change-Id: I3df494eddeab6dab3dc8b82e5949e627917e3aca
2020-03-02 13:52:23 +03:00
Leonid Yuriev
251d34d6e6 mdbx-doc: more for custom comparators.
Change-Id: I3326c5bdedbbdb01b1865bff68aa7ba8bc7056cc
2020-03-02 13:50:33 +03:00
Leo Yuriev
8358dda7f1 mdbx-doc: add link to telegram group.
Change-Id: I6440939d3150af7dedbbcd0e855f3032c5229064
2020-02-29 00:57:22 +03:00
Leo Yuriev
76e29c21f1 mdbx: merge branch 'devel' (crutches for Wine).
Change-Id: I1779bc6987449e403216584cdd2846e910f34c8a
2020-02-28 19:05:47 +03:00
Leo Yuriev
56222db3ba mdbx-test: follow MDBX_UNABLE_EXTEND_MAPSIZE changes.
Change-Id: I3c0074db11e229c5a7aaac6a589a42c041666b17
2020-02-28 17:39:52 +03:00
Leo Yuriev
5072b45026 mdbx: rename MDBX_MAP_RESIZED to MDBX_UNABLE_EXTEND_MAPSIZE.
Change-Id: I22fbdb4f08fd7a6ae37da42e6827677ae8a8337b
2020-02-28 16:40:56 +03:00
Leo Yuriev
63449a44c5 mdbx-cmake: #if/#endif instead of cmake-conditions for posix/windows sources.
Change-Id: Ic95bd3ba345160cf1d68c79f11d6560d4c41cb2b
2020-02-28 15:51:12 +03:00
Leonid Yuriev
ecffc831fa mdbx-tools: avoids extra error messages "bad txn" from mdbx_chk when DB is corrupted.
Change-Id: I6b92aced83bcf7e0c8e5c7108ddcf60714c9b30c
2020-02-27 16:04:00 +03:00
Leonid Yuriev
6c76af5181 mdbx-doc: refine prev commit.
Change-Id: I3ec7544eeee5a2ebfa268d667a1724e8251e7e2e
2020-02-25 15:19:49 +03:00
Leonid Yuriev
061d3cc8fd mdbx-doc: clarify ACI for no-sync modes, reformat text.
Change-Id: I56b4f167eb334b4903d121f7cd6f33aa0b612dcd
2020-02-25 15:02:20 +03:00
Leonid Yuriev
6248b67f75 mdbx-windows: more for running under Wine.
Wine unable create mapped-view large tran secton size.

More for https://github.com/erthink/libmdbx/issues/83

Change-Id: I93e98d58a827c785f8257cd9cac387a333e59621
2020-02-24 20:46:36 +03:00
Leonid Yuriev
fbf55e17cb mdbx-windows: one more workaround for Wine.
SetFileInformationByHandle() is not implemented by Wine.

Change-Id: I61783c8d173397094cd6cbad7efc9d7aac57b470
002c:Call KERNEL32.SetFileInformationByHandle(00000060,00000006,0022f890,00000008) ret=127dd1b2
002c:fixme:file:SetFileInformationByHandle 0000000000000060, 6, 000000000022F890, 8
002c:Ret  KERNEL32.SetFileInformationByHandle() retval=00000000 ret=127dd1b2

Related to https://github.com/erthink/libmdbx/issues/83
2020-02-22 20:02:17 +03:00
Leonid Yuriev
289f2896d0 mdbx-windows: more for Wine.
Related to https://github.com/erthink/libmdbx/issues/83.

UnlockFile() cold return ERROR_LOCK_VIOLATION when file not locked, instead of ERROR_NOT_LOCKED.
Current versions of Wine seem to work correctly.

Change-Id: Ibc5bd4352184efc7f88705e7ae04d6656286a96e
2020-02-21 19:58:32 +03:00
Leonid Yuriev
4fed2d9fc0 mdbx-windows: minor workaround for MSVC "unresolved external symbol __except1 ..."
Workaround for MSVC error LNK2019: unresolved external symbol __except1 referenced in function __ftol3_except.
2020-02-19 16:31:25 +03:00
Leo Yuriev
9aa816dc73 mdbx-windows: using RegGetValueA() instead of wchar_t version.
Change-Id: I0848eaf2083985ae27fec605358329830b0733c2
2020-02-19 16:00:40 +03:00
Leo Yuriev
f750086bc1 mdbx-windows: rework workaround for Wine.
Resolves https://github.com/erthink/libmdbx/issues/83
in accordance with https://bugs.winehq.org/show_bug.cgi?id=48620

Change-Id: Ieb4385efdcd86c865184a783363cf6e90da14f61
2020-02-18 22:51:34 +03:00
Leonid Yuriev
bd3f234bce mdbx: update github repo address.
Change-Id: Ifa8bf0e09b297ba6f495dd8e04e5c67f6626d9cb
2020-02-18 02:22:47 +03:00
Leonid Yuriev
dbf9873e63 mdbx: clarify "mirroring" note.
Change-Id: Id0b26900828ea081327945fa111cfb1a1dca74b0
2020-02-18 01:42:58 +03:00
Leo Yuriev
4bd194f4c1 mdbx-cmake: fix CMAKE_RANLIB variable name typo.
Change-Id: Iafefa3b921ad356bc87c7c39161e78fd71580fe8
2020-02-17 22:55:36 +03:00
Leo Yuriev
8a6de15346 mdbx-cmake: drop openmp detection and flags.
Change-Id: Iead999c356f683df36183df729dbc0a94e32c420
2020-02-17 22:55:36 +03:00
Leo Yuriev
60a6560a3b mdbx: workaround for NtExtendSection() on Wine.
This fixes https://github.com/erthink/libmdbx/issues/83

Change-Id: I8e00aa91c86348fad9dbe4285143671d9cb3f802
2020-02-17 22:55:17 +03:00
Leo Yuriev
d1173a1596 mdbx: drop unused WindowsNT API prototypes.
Change-Id: Ic929646653d0576671d6150a698e892d2145ae30
2020-02-17 19:44:05 +03:00
Leonid Yuriev
2356f3281b mdbx: use underscores for GNU-attributes.
Change-Id: Iefd371dd91da1db8ee86554208536b3004535317
2020-02-17 14:01:11 +03:00
Leo Yuriev
2db93efb14 mdbx: move internal markdown-required-extension inside README. 2020-02-06 19:46:59 +03:00
Leonid Yuriev
cd0d84dbb6 mdbx: fix error message typo.
Change-Id: I25db309ff4fb063893c7c39d623e62eaceb8b60f
2020-02-03 23:35:43 +03:00
Leonid Yuriev
8214d674be mdbx: refine SEARCH_IMPL macro.
Change-Id: I975e480c047b88e0200aaf889334e8b83ab760ad
2020-02-03 18:13:17 +03:00
Leonid Yuriev
0714c07e28 mdbx: minor clarify MDBX_EKEYMISMATCH description.
Change-Id: I310feb62bc849e01dc3faf0b93a16b654b53d3bd
2020-02-03 17:07:41 +03:00
Leonid Yuriev
62a39d84b3 mdbx: fix aligned_alloc() usage. 2020-02-02 20:49:51 +03:00
Leonid Yuriev
6009bac1ed mdbx: move is_powerof2() and roundup_powerof2() into header. 2020-02-02 20:41:04 +03:00
Leonid Yuriev
e475db7ade mdbx: add MDBX_DBG_LEGACY_OVERLAP.
Change-Id: I7aecb925b553587efd6698dc3d52682ca98aa950
2020-02-02 15:07:04 +03:00
Leonid Yuriev
01f65bc872 mdbx: more info about "one threat - one transaction".
Change-Id: I070750b081e02113577dac13488d01f9d18e759b
2020-02-02 02:46:41 +03:00
Leonid Yuriev
49d9779c84 mdbx: remove obsolete ASAN-related comment.
Corresponding drawback was fixed by 8c7cdfdc79

Change-Id: I43ccf508377dc4b0bf5de6245e88c58dde0fc63e
2020-02-02 02:46:41 +03:00
Leonid Yuriev
a594f79e5f mdbx: refine/clarify error messages.
Change-Id: If2a38bdfb4a9fce176acb87fa452709bcfc5c972
2020-02-02 02:46:41 +03:00
Leonid Yuriev
17fe5f106b mdbx: check read/write txn overlapping for the same thread (MDBX_TXN_OVERLAPPING).
Change-Id: If3488df96bd1903d5e4ca0a1fea504075dbd4a20
2020-02-02 02:46:41 +03:00
Leonid Yuriev
db27654330 mdbx: rename MDBX_LAST_LMDB_ERRCODE and fix description.
Change-Id: I9a855871ae8821d0d10472c48b5467fd507c01a5
2020-02-02 02:46:41 +03:00
Leonid Yuriev
1cbad5bd3f mdbx: don't store thread-id into reader lock-slot in MDBX_NOTLS mode.
Change-Id: I8453565a8c0a7c56b6dbd383c31ff5be828c8679
2020-02-01 23:08:07 +03:00
Leonid Yuriev
08753b46a1 mdbx: cleanup tabs (cosmetics).
Change-Id: If941ea89d844f98f274da4ddfc3f2ae97986eeb7
2020-02-01 20:44:29 +03:00
Leonid Yuriev
aeda2aa8c5 mdbx-test: minor cleanup pcrf-test/example.
Change-Id: Ie4d56592c8dd561d49ca423c2a8ac653a9e853ee
2020-02-01 20:43:18 +03:00
Leonid Yuriev
fb1d600597 mdbx: speedup debug/checked build.
This resolves https://github.com/leo-yuriev/libmdbx/issues/80

Change-Id: I20596f87db17ce01379dae5f58f4c2b158a04a4a
2020-01-29 03:29:42 +03:00
Leonid Yuriev
c1ad86c368 mdbx: fixes for modern Coverity.
This resolves https://github.com/leo-yuriev/libmdbx/issues/81

Change-Id: Id501bf49055b54240da14723aef0115fc3a27672
2020-01-28 19:37:56 +03:00
Leonid Yuriev
7ea1a4e0e8 mdbx: fix key_from_jsonInteger() for MSVC.
Change-Id: I3fc6a6da57707750cb2e8429bbaf10ff1de2dde2
2020-01-28 01:47:50 +03:00
Leonid Yuriev
2c08ec21fd mdbx: fix compatibility (use zero for invalid DBI).
Change-Id: I4ab6430eb96d97991cbd0c151dfd98a9930805d2
2020-01-27 03:00:13 +03:00
Leonid Yuriev
d159a8252d mdbx: refine network-sorting.
Change-Id: I086626c3da05b11362612d87eae23371f67ea1b0
2020-01-27 00:47:18 +03:00
Leonid Yuriev
308548e226 mdbx: minor refine/speedup mdbx_page_get().
Change-Id: Ia11a76f0255db1a56948438cdc333ebd67d88193
2020-01-26 19:07:00 +03:00
Leonid Yuriev
a8c5daf46a mdbx: minor refine/speedup mdbx_node_search().
Change-Id: Ie3dd42de25e37bff177018cd15108b97cfcb049c
2020-01-26 18:00:35 +03:00
Leonid Yuriev
898b6ee433 mdbx: fix mdbx_env_copy() argument description.
This resolves https://github.com/leo-yuriev/libmdbx/issues/78

Change-Id: I4d92f3939f617ffd11941793e819a0513649fed8
2020-01-26 15:27:30 +03:00
Leonid Yuriev
2ce9ace4d3 mdbx: documenting and checking key and value alignment for MDBX_INTEGERKEY and MDBX_INTEGERDUP.
This resolves https://github.com/leo-yuriev/libmdbx/issues/79.

Change-Id: I819a6eca3018361e5896d5ccce7e4c0ca57c8b38
2020-01-26 14:54:40 +03:00
Leonid Yuriev
1ee1b269e6 mdbx: minor optimization around memcpy().
Change-Id: Id0dd4ac693a4ddb6294bdb0f2fc5d2aec69d0efd
2020-01-26 14:44:50 +03:00
Leonid Yuriev
ebcbcbfe31 mdbx: avoud int64-to-double conversion key_from_jsonInteger().
More for https://github.com/leo-yuriev/libmdbx/issues/76

This is expected to be a workaround for the MSVC2019 bug
"MSVCRT.lib(ftol3.obj) : error LNK2001: unresolved external symbol __except1".
https://ci.appveyor.com/project/leo-yuriev/libmdbx/builds/30273569/job/lurrftum1nkbu5a3#L109

Change-Id: Ie6da02b14d0b973c7172af063caf4fdc44bf89ac
2020-01-22 19:41:01 +03:00
Leonid Yuriev
b77f4faadd mdbx: fix major typo in prev commit.
More for https://github.com/leo-yuriev/libmdbx/issues/76

Change-Id: I9a3d1adf1467a542b36330978d53cc15f4afbbdb
2020-01-22 03:51:12 +03:00
Leonid Yuriev
bf28856ac5 mdbx: add key-making functions.
Related to https://github.com/leo-yuriev/libmdbx/issues/76

Change-Id: I1edc8efd323af9adb53e6c2155e2ea39a1e575f4
2020-01-22 03:43:09 +03:00
24 changed files with 1274 additions and 541 deletions

View File

@@ -25,7 +25,7 @@
##
## libmdbx = { Revised and extended descendant of Symas LMDB. }
## Please see README.md at https://github.com/leo-yuriev/libmdbx
## 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

View File

@@ -14,7 +14,7 @@
##
## libmdbx = { Revised and extended descendant of Symas LMDB. }
## Please see README.md at https://github.com/leo-yuriev/libmdbx
## 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

View File

@@ -236,10 +236,7 @@ dist/@tmp-shared_internals.inc: src/elements/version.c $(ALLOY_DEPS) $(lastword
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 \
&& echo '#if defined(_WIN32) || defined(_WIN64)' \
&& cat src/elements/lck-windows.c && echo '#else /* LCK-implementation */' \
&& cat src/elements/lck-posix.c && echo '#endif /* LCK-implementation */' \
&& cat src/elements/core.c src/elements/osal.c src/elements/version.c src/elements/lck-windows.c src/elements/lck-posix.c \
) | grep -v -e '#include "' -e '#pragma once' | sed 's|@INCLUDE|#include|' > $@
define dist-tool-rule

View File

@@ -1,3 +1,5 @@
<!-- Required extensions: pymdownx.betterem, pymdownx.tilde, pymdownx.emoji, pymdownx.tasklist, pymdownx.superfences -->
libmdbx
=======
@@ -7,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.
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).
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.
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
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
@@ -47,8 +59,9 @@ _MithrilDB_ is rightly relevant name.
> revolution is to provide a clearer and robust API, add more features and
> new valuable properties of database.
[![Build Status](https://travis-ci.org/leo-yuriev/libmdbx.svg?branch=master)](https://travis-ci.org/leo-yuriev/libmdbx)
[![Build status](https://ci.appveyor.com/api/projects/status/ue94mlopn50dqiqg/branch/master?svg=true)](https://ci.appveyor.com/project/leo-yuriev/libmdbx/branch/master)
[![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)
*The Future will (be) [Positive](https://www.ptsecurity.com). Всё будет хорошо.*
@@ -183,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
@@ -266,12 +282,12 @@ named mutexes are used.
### History
At first the development was carried out within the
[ReOpenLDAP](https://github.com/leo-yuriev/ReOpenLDAP) project. About a
[ReOpenLDAP](https://github.com/erthink/ReOpenLDAP) project. About a
year later _libmdbx_ was separated into standalone project, which was
[presented at Highload++ 2015
conference](http://www.highload.ru/2015/abstracts/1831.html).
Since 2017 _libmdbx_ is used in [Fast Positive Tables](https://github.com/leo-yuriev/libfpta),
Since 2017 _libmdbx_ is used in [Fast Positive Tables](https://github.com/erthink/libfpta),
and development is funded by [Positive Technologies](https://www.ptsecurity.com).
### Acknowledgments
@@ -407,9 +423,9 @@ For more information and API description see the [mdbx.h](mdbx.h) header.
| 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) |
--------------------------------------------------------------------------------
@@ -443,7 +459,7 @@ Here showed sum of performance metrics in 3 benchmarks:
2. Performance gap is too high to compare in any meaningful way.
![Comparison #1: Integral Performance](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-1.png)
![Comparison #1: Integral Performance](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-1.png)
--------------------------------------------------------------------------------
@@ -452,7 +468,7 @@ Here showed sum of performance metrics in 3 benchmarks:
Summary performance with concurrent read/search queries in 1-2-4-8
threads on 4 CPU cores machine.
![Comparison #2: Read Scalability](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-2.png)
![Comparison #2: Read Scalability](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-2.png)
--------------------------------------------------------------------------------
@@ -474,7 +490,7 @@ In the benchmark each transaction contains combined CRUD operations (2
inserts, 1 read, 1 update, 1 delete). Benchmark starts on empty database
and after full run the database contains 10,000 small key-value records.
![Comparison #3: Sync-write mode](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-3.png)
![Comparison #3: Sync-write mode](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-3.png)
--------------------------------------------------------------------------------
@@ -501,7 +517,7 @@ and after full run the database contains 100,000 small key-value
records.
![Comparison #4: Lazy-write mode](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-4.png)
![Comparison #4: Lazy-write mode](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-4.png)
--------------------------------------------------------------------------------
@@ -525,7 +541,7 @@ In the benchmark each transaction contains combined CRUD operations (2
inserts, 1 read, 1 update, 1 delete). Benchmark starts on empty database
and after full run the database contains 10,000 small key-value records.
![Comparison #5: Async-write mode](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-5.png)
![Comparison #5: Async-write mode](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-5.png)
--------------------------------------------------------------------------------
@@ -549,9 +565,8 @@ All benchmark data is gathered by
[getrusage()](http://man7.org/linux/man-pages/man2/getrusage.2.html)
syscall and by scanning data directory.
![Comparison #6: Cost comparison](https://raw.githubusercontent.com/wiki/leo-yuriev/libmdbx/img/perf-slide-6.png)
![Comparison #6: Cost comparison](https://raw.githubusercontent.com/wiki/erthink/libmdbx/img/perf-slide-6.png)
--------------------------------------------------------------------------------
### The [repository now only mirrored on the Github](https://abf.io/erthink/libmdbx) due to illegal discriminatory restrictions for Russian Crimea and for sovereign crimeans.
<!-- Required extensions: pymdownx.betterem, pymdownx.tilde, pymdownx.emoji, pymdownx.tasklist, pymdownx.superfences -->
#### 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.

View File

@@ -1,4 +1,4 @@
version: 0.6.0.{build}
version: 0.7.0.{build}
environment:
matrix:

View File

@@ -214,14 +214,6 @@ 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 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
@@ -367,7 +359,7 @@ if(CMAKE_COMPILER_IS_CLANG)
set(CMAKE_CLANG_NM ${CMAKE_NM})
endif()
if (NOT CMAKE_CLANG_RANLIB)
set(CMAKE_CLANG_RANLIB ${CMAKE_RANLIB })
set(CMAKE_CLANG_RANLIB ${CMAKE_RANLIB})
endif()
message(STATUS "Assume Link-Time Optimization by CLANG/LLVM is available via ${CMAKE_TOOLCHAIN_FILE}")
else()
@@ -534,10 +526,6 @@ macro(setup_compile_flags)
endif()
endif()
if(HAVE_OPENMP)
add_compile_flags("C;CXX" "-fopenmp")
endif()
if (ENABLE_ASAN)
add_compile_flags("C;CXX" -fsanitize=address)
endif()

245
mdbx.h
View File

@@ -201,6 +201,14 @@
* necessary) in a child process would be both extreme complicated and so
* fragile.
*
* Do not start more than one transaction for a one thread. If you think about
* this, it's really strange to do something with two data snapshots at once,
* which may be different. MDBX checks and preventing this by returning
* corresponding error code (MDBX_TXN_OVERLAPPING, MDBX_BAD_RSLOT, MDBX_BUSY)
* unless you using MDBX_NOTLS option on the environment. Nonetheless, with the
* MDBX_NOTLS option, you must know exactly what you are doing, otherwise you
* will get deadlocks or reading an alien data.
*
* Also note that a transaction is tied to one thread by default using Thread
* Local Storage. If you want to pass read-only transactions across threads,
* you can use the MDBX_NOTLS option on the environment. Nevertheless, a write
@@ -298,19 +306,19 @@
* - optimize (bulk) loading speed
* - (temporarily) reduce robustness to gain even more speed
* - gather statistics about the database
* - define custom sort orders
* - estimate size of range query result
* - double perfomance by LIFO reclaiming on storages with write-back
* - use sequences and canary markers
* - use lack-of-space callback (aka OOM-KICK)
* - use exclusive mode
* - define custom sort orders (but this is recommended to be avoided)
*
*
**** RESTRICTIONS & CAVEATS ***************************************************
* in addition to those listed for some functions.
*
* - Troubleshooting the LCK-file.
* 1. A broken LCK-file can cause sync issues, including appearance of
* 1. A broken LCK-file can cause sync issues, including appearance of
* wrong/inconsistent data for readers. When database opened in the
* cooperative read-write mode the LCK-file requires to be mapped to
* memory in read-write access. In this case it is always possible for
@@ -327,14 +335,14 @@
* Workaround: Just make all programs using the database close it;
* the LCK-file is always reset on first open.
*
* 2. Stale reader transactions left behind by an aborted program cause
* 2. Stale reader transactions left behind by an aborted program cause
* further writes to grow the database quickly, and stale locks can
* block further operation.
* MDBX checks for stale readers while opening environment and before
* growth the database. But in some cases, this may not be enough.
*
* Workaround: Check for stale readers periodically, using the
* mdbx_reader_check() function or the mdbx_stat tool.
* mdbx_reader_check() function or the mdbx_stat tool.
*
* 3. Stale writers will be cleared automatically by MDBX on supprted
* platforms. But this is platform-specific, especially of
@@ -379,10 +387,18 @@
* The "next" version of libmdbx (MithrilDB) will solve this issue.
*
* - A thread can only use one transaction at a time, plus any nested
* read-write transactions in the non-writemap mode. Each transaction
* read-write transactions in the non-writemap mode. Each transaction
* belongs to one thread. The MDBX_NOTLS flag changes this for read-only
* transactions. See below.
*
* Do not start more than one transaction for a one thread. If you think
* about this, it's really strange to do something with two data snapshots
* at once, which may be different. MDBX checks and preventing this by
* returning corresponding error code (MDBX_TXN_OVERLAPPING, MDBX_BAD_RSLOT,
* MDBX_BUSY) unless you using MDBX_NOTLS option on the environment.
* Nonetheless, with the MDBX_NOTLS option, you must know exactly what you
* are doing, otherwise you will get deadlocks or reading an alien data.
*
* - Do not have open an MDBX database twice in the same process at the same
* time. By default MDBX prevent this in most cases by tracking databases
* opening and return MDBX_BUSY if anyone LCK-file is already open.
@@ -451,7 +467,7 @@
* above.
*
* - An MDBX database configuration will often reserve considerable unused
* memory address space and maybe file size for future growth. This does
* memory address space and maybe file size for future growth. This does
* not use actual memory or disk space, but users may need to understand
* the difference so they won't be scared off.
*
@@ -607,8 +623,8 @@ typedef pthread_t mdbx_tid_t;
#ifndef __dll_export
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(__GNUC__) || __has_attribute(dllexport)
#define __dll_export __attribute__((dllexport))
#if defined(__GNUC__) || __has_attribute(__dllexport__)
#define __dll_export __attribute__((__dllexport__))
#elif defined(_MSC_VER)
#define __dll_export __declspec(dllexport)
#else
@@ -623,8 +639,8 @@ typedef pthread_t mdbx_tid_t;
#ifndef __dll_import
#if defined(_WIN32) || defined(__CYGWIN__)
#if defined(__GNUC__) || __has_attribute(dllimport)
#define __dll_import __attribute__((dllimport))
#if defined(__GNUC__) || __has_attribute(__dllimport__)
#define __dll_import __attribute__((__dllimport__))
#elif defined(_MSC_VER)
#define __dll_import __declspec(dllimport)
#else
@@ -637,8 +653,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)
@@ -817,13 +834,24 @@ typedef struct iovec MDBX_val;
* but MDBX_DBG_ASSERT, MDBX_DBG_AUDIT and MDBX_DBG_JITTER only if libmdbx
* builded with MDBX_DEBUG. */
#define MDBX_DBG_ASSERT 1 /* Enable assertion checks */
#define MDBX_DBG_AUDIT 2 /* Enable pages usage audit at commit transactions */
#define MDBX_DBG_JITTER 4 /* Enable small random delays in critical points */
#define MDBX_DBG_DUMP /* Include or not meta-pages in coredump files, MAY \
affect performance in MDBX_WRITEMAP mode */ \
8
#define MDBX_DBG_LEGACY_MULTIOPEN 16 /* Enable multi-opening environment(s) */
/* Enable assertion checks */
#define MDBX_DBG_ASSERT 1
/* Enable pages usage audit at commit transactions */
#define MDBX_DBG_AUDIT 2
/* Enable small random delays in critical points */
#define MDBX_DBG_JITTER 4
/* Include or not meta-pages in coredump files,
* MAY affect performance in MDBX_WRITEMAP mode */
#define MDBX_DBG_DUMP 8
/* Allow multi-opening environment(s) */
#define MDBX_DBG_LEGACY_MULTIOPEN 16
/* Allow read and write transactions overlapping for the same thread */
#define MDBX_DBG_LEGACY_OVERLAP 32
/* A debug-logger callback function,
* called before printing the message and aborting.
@@ -833,7 +861,12 @@ typedef struct iovec MDBX_val;
typedef void MDBX_debug_func(int loglevel, const char *function, int line,
const char *msg, va_list args);
/* FIXME: Complete description */
/* Don't change current settings */
#define MDBX_LOG_DONTCHANGE (-1)
#define MDBX_DBG_DONTCHANGE (-1)
#define MDBX_LOGGER_DONTCHANGE ((MDBX_debug_func *)(intptr_t)-1)
/* Setup global log-level, debug options and debug logger. */
LIBMDBX_API int mdbx_setup_debug(int loglevel, int flags,
MDBX_debug_func *logger);
@@ -1170,10 +1203,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()
@@ -1285,17 +1319,26 @@ LIBMDBX_API const char *mdbx_dump_val(const MDBX_val *key, char *const buf,
/**** DATABASE FLAGS **********************************************************/
/* Use reverse string keys */
#define MDBX_REVERSEKEY 0x02u
/* Use sorted duplicates */
#define MDBX_DUPSORT 0x04u
/* Numeric keys in native byte order, either uint32_t or uint64_t.
* The keys must all be of the same size. */
* The keys must all be of the same size and must be aligned while passing as
* arguments. */
#define MDBX_INTEGERKEY 0x08u
/* With MDBX_DUPSORT, sorted dup items have fixed size */
#define MDBX_DUPFIXED 0x10u
/* With MDBX_DUPSORT, dups are MDBX_INTEGERKEY-style integers */
/* With MDBX_DUPSORT, dups are MDBX_INTEGERKEY-style integers.
* The data values must all be of the same size and must be aligned while
* passing as arguments. */
#define MDBX_INTEGERDUP 0x20u
/* With MDBX_DUPSORT, use reverse string dups */
#define MDBX_REVERSEDUP 0x40u
/* Create DB if not already existing */
#define MDBX_CREATE 0x40000u
@@ -1375,56 +1418,87 @@ typedef enum MDBX_cursor_op {
/* key/data pair already exists */
#define MDBX_KEYEXIST (-30799)
/* key/data pair not found (EOF) */
#define MDBX_NOTFOUND (-30798)
/* Requested page not found - this usually indicates corruption */
#define MDBX_PAGE_NOTFOUND (-30797)
/* Database is corrupted (page was wrong type and so on) */
#define MDBX_CORRUPTED (-30796)
/* Environment had fatal error (i.e. update of meta page failed and so on) */
#define MDBX_PANIC (-30795)
/* DB file version mismatch with libmdbx */
#define MDBX_VERSION_MISMATCH (-30794)
/* File is not a valid MDBX file */
#define MDBX_INVALID (-30793)
/* Environment mapsize reached */
#define MDBX_MAP_FULL (-30792)
/* Environment maxdbs reached */
#define MDBX_DBS_FULL (-30791)
/* Environment maxreaders reached */
#define MDBX_READERS_FULL (-30790)
/* Txn has too many dirty pages */
/* Transaction has too many dirty pages, i.e transaction too big */
#define MDBX_TXN_FULL (-30788)
/* Cursor stack too deep - internal error */
#define MDBX_CURSOR_FULL (-30787)
/* Page has not enough space - internal error */
#define MDBX_PAGE_FULL (-30786)
/* Database contents grew beyond environment mapsize */
#define MDBX_MAP_RESIZED (-30785)
/* Operation and DB incompatible, or DB type changed. This can mean:
/* Database engine was unable to extend mapping, e.g. since address space
* is unavailable or busy. This can mean:
* - Database size extended by other process beyond to environment mapsize
* and engine was unable to extend mapping while starting read transaction.
* Environment should be reopened to continue.
* - Engine was unable to extend mapping during write transaction
* or explicit call of mdbx_env_set_geometry(). */
#define MDBX_UNABLE_EXTEND_MAPSIZE (-30785)
/* 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.
* - Opening a named DB when the unnamed DB has MDBX_DUPSORT/MDBX_INTEGERKEY.
* - Accessing a data record as a database, or vice versa.
* - The database was dropped and recreated with different flags. */
#define MDBX_INCOMPATIBLE (-30784)
/* Invalid reuse of reader locktable slot */
/* Invalid reuse of reader locktable slot,
* e.g. read-transaction already run for current thread */
#define MDBX_BAD_RSLOT (-30783)
/* Transaction must abort, has a child, or is invalid */
/* Transaction is not valid for requested operation,
* e.g. had errored and be must aborted, has a child, or is invalid */
#define MDBX_BAD_TXN (-30782)
/* Unsupported size of key/DB name/data, or wrong DUPFIXED size */
/* Invalid size or alignment of key or data for target database,
* either invalid subDB name */
#define MDBX_BAD_VALSIZE (-30781)
/* The specified DBI was changed unexpectedly */
/* The specified DBI-handle is invalid
* or changed by another thread/transaction */
#define MDBX_BAD_DBI (-30780)
/* Unexpected problem - txn should abort */
/* Unexpected internal error, transaction should be aborted */
#define MDBX_PROBLEM (-30779)
/* The last LMDB-compatible defined error code */
#define MDBX_LAST_LMDB_ERRCODE MDBX_PROBLEM
/* Another write transaction is running or environment is already used while
* opening with MDBX_EXCLUSIVE flag */
#define MDBX_BUSY (-30778)
/* The last defined error code */
#define MDBX_LAST_ERRCODE MDBX_BUSY
/* The mdbx_put() or mdbx_replace() was called for key,
* that has more that one associated value. */
/* The specified key has more than one associated value */
#define MDBX_EMULTIVAL (-30421)
/* Bad signature of a runtime object(s), this can mean:
@@ -1432,12 +1506,11 @@ typedef enum MDBX_cursor_op {
* - ABI version mismatch (rare case); */
#define MDBX_EBADSIGN (-30420)
/* Database should be recovered, but this could NOT be done automatically
* right now (e.g. in readonly mode and so forth). */
/* Database should be recovered, but this could NOT be done for now
* since it opened in read-only mode */
#define MDBX_WANNA_RECOVERY (-30419)
/* The given key value is mismatched to the current cursor position,
* when mdbx_cursor_put() called with MDBX_CURRENT option. */
/* The given key value is mismatched to the current cursor position */
#define MDBX_EKEYMISMATCH (-30418)
/* Database is too large for current system,
@@ -1448,6 +1521,9 @@ typedef enum MDBX_cursor_op {
* e.g. a transaction that started by another thread. */
#define MDBX_THREAD_MISMATCH (-30416)
/* Overlapping read and write transactions for the current thread */
#define MDBX_TXN_OVERLAPPING (-30415)
/**** FUNCTIONS & RELATED STRUCTURES ******************************************/
/* Return a string describing a given error code.
@@ -1574,8 +1650,8 @@ LIBMDBX_API int mdbx_env_open(MDBX_env *env, const char *pathname,
*
* [in] env An environment handle returned by mdbx_env_create(). It must
* have already been opened successfully.
* [in] dest The directory in which the copy will reside. This directory
* must already exist and be writable but must otherwise be empty.
* [in] dest The pathname of a file in which the copy will reside. This file
* must not be already exist, but parent directory must be writable.
* [in] flags Special options for this operation. This parameter must be set
* to 0 or by bitwise OR'ing together one or more of the values
* described here:
@@ -1958,9 +2034,9 @@ LIBMDBX_API int mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *fd);
* size. Besides, the upper bound defines the linear address space
* reservation in each process that opens the database. Therefore changing
* the upper bound is costly and may be required reopening environment in
* case of MDBX_MAP_RESIZED errors, and so on. Therefore, this value should
* be chosen reasonable as large as possible, to accommodate future growth
* of the database.
* case of MDBX_UNABLE_EXTEND_MAPSIZE errors, and so on. Therefore, this
* value should be chosen reasonable as large as possible, to accommodate
* future growth of the database.
* - The growth step must be greater than zero to allow the database to grow,
* but also reasonable not too small, since increasing the size by little
* steps will result a large overhead.
@@ -1980,6 +2056,7 @@ LIBMDBX_API int mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *fd);
* - Windows does not provide the usual API to augment a memory-mapped file
* (that is, a memory-mapped partition), but only by using "Native API"
* in an undocumented way.
*
* MDBX bypasses all Windows issues, but at a cost:
* - Ability to resize database on the fly requires an additional lock
* and release SlimReadWriteLock during each read-only transaction.
@@ -2000,10 +2077,10 @@ LIBMDBX_API int mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *fd);
*
* If the mapsize is increased by another process, MDBX silently and
* transparently adopt these changes at next transaction start. However,
* mdbx_txn_begin() will return MDBX_MAP_RESIZED if new mapping size could not
* be applied for current process (for instance if address space is busy).
* Therefore, in the case of MDBX_MAP_RESIZED error you need close and reopen
* the environment to resolve error.
* mdbx_txn_begin() will return MDBX_UNABLE_EXTEND_MAPSIZE if new mapping size
* could not be applied for current process (for instance if address space
* is busy). Therefore, in the case of MDBX_UNABLE_EXTEND_MAPSIZE error you
* need close and reopen the environment to resolve error.
*
* NOTE: Actual values may be different than your have specified because of
* rounding to specified database page size, the system page size and/or the
@@ -2034,13 +2111,13 @@ LIBMDBX_API int mdbx_env_get_fd(MDBX_env *env, mdbx_filehandle_t *fd);
* database is used by other processes or threaded
* (i.e. just pass -1 in this argument except absolutely
* necessity). Otherwise you must be ready for
* MDBX_MAP_RESIZED error(s), unexpected pauses during
* remapping and/or system errors like "addtress busy",
* and so on. In other words, there is no way to handle
* a growth of the upper bound robustly because there may
* be a lack of appropriate system resources (which are
* extremely volatile in a multi-process multi-threaded
* environment).
* MDBX_UNABLE_EXTEND_MAPSIZE error(s), unexpected pauses
* during remapping and/or system errors like "addtress
* busy", and so on. In other words, there is no way to
* handle a growth of the upper bound robustly because
* there may be a lack of appropriate system resources
* (which are extremely volatile in a multi-process
* multi-threaded environment).
*
* [in] growth_step The growth step in bytes, must be greater than zero
* to allow the database to grow.
@@ -2232,7 +2309,8 @@ LIBMDBX_API void *mdbx_env_get_userctx(MDBX_env *env);
* possible errors are:
* - MDBX_PANIC = a fatal error occurred earlier and the environment
* must be shut down.
* - MDBX_MAP_RESIZED = another process wrote data beyond this MDBX_env's
* - MDBX_UNABLE_EXTEND_MAPSIZE
* = another process wrote data beyond this MDBX_env's
* mapsize and this environment's map must be resized
* as well. See mdbx_env_set_mapsize().
* - MDBX_READERS_FULL = a read-only transaction was requested and the reader
@@ -2466,9 +2544,6 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
* In contrast to LMDB, the MDBX allow this function to be called from multiple
* concurrent transactions or threads in the same process.
*
* Legacy mdbx_dbi_open() correspond to calling mdbx_dbi_open_ex() with the null
* keycmp and datacmp arguments.
*
* To use named database (with name != NULL), mdbx_env_set_maxdbs()
* must be called before opening the environment. Table names are
* keys in the internal unnamed database, and may be read but not written.
@@ -2490,7 +2565,7 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
* - MDBX_INTEGERKEY
* Keys are binary integers in native byte order, either uin32_t or
* uint64_t, and will be sorted as such. The keys must all be of the
* same size.
* same size and must be aligned while passing as arguments.
* - MDBX_DUPFIXED
* This flag may only be used in combination with MDBX_DUPSORT. This
* option tells the library that the data items for this database are
@@ -2500,7 +2575,8 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
* to retrieve multiple items at once.
* - MDBX_INTEGERDUP
* This option specifies that duplicate data items are binary integers,
* similar to MDBX_INTEGERKEY keys.
* similar to MDBX_INTEGERKEY keys. The data values must all be of the
* same size and must be aligned while passing as arguments.
* - MDBX_REVERSEDUP
* This option specifies that duplicate data items should be compared as
* strings in reverse order (the comparison is performed in the direction
@@ -2509,10 +2585,24 @@ typedef int(MDBX_cmp_func)(const MDBX_val *a, const MDBX_val *b);
* Create the named database if it doesn't exist. This option is not
* allowed in a read-only transaction or a read-only environment.
*
* [out] dbi Address where the new MDBX_dbi handle will be stored.
*
* For mdbx_dbi_open_ex() additional arguments allow you to set custom
* 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 (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
* effect only if database was opened with the MDB_DUPSORT flag.
* [out] dbi Address where the new MDBX_dbi handle will be stored.
*
* Returns A non-zero error value on failure and 0 on success, some
* possible errors are:
@@ -2530,6 +2620,25 @@ LIBMDBX_API int mdbx_dbi_open_ex(MDBX_txn *txn, const char *name,
LIBMDBX_API int mdbx_dbi_open(MDBX_txn *txn, const char *name, unsigned flags,
MDBX_dbi *dbi);
/* Key-making functions to avoid custom comparators.
*
* The mdbx_key_from_jsonInteger() build key which are comparable with
* keys created by mdbx_key_from_double(). So this allow mix int64 and IEEE754
* double values in one index for JSON-numbers with restriction for integer
* numbers range corresponding to RFC-7159 (i.e. [-(2**53)+1, (2**53)-1].
* See bottom of page 6 at https://tools.ietf.org/html/rfc7159 */
LIBMDBX_API uint64_t mdbx_key_from_jsonInteger(const int64_t json_integer);
LIBMDBX_API uint64_t mdbx_key_from_double(const double ieee754_64bit);
LIBMDBX_API uint64_t mdbx_key_from_ptrdouble(const double *const ieee754_64bit);
LIBMDBX_API uint32_t mdbx_key_from_float(const float ieee754_32bit);
LIBMDBX_API uint32_t mdbx_key_from_ptrfloat(const float *const ieee754_32bit);
__inline uint64_t mdbx_key_from_int64(const int64_t i64) {
return UINT64_C(0x8000000000000000) + i64;
}
__inline uint32_t mdbx_key_from_int32(const int32_t i32) {
return UINT32_C(0x80000000) + i32;
}
/* Retrieve statistics for a database.
*
* [in] txn A transaction handle returned by mdbx_txn_begin().
@@ -3377,7 +3486,7 @@ typedef uint_fast64_t mdbx_attr_t;
* [in] flags Options for this operation. This parameter must be set to 0
* or one of the values described here:
*
* - MDBX_CURRENT
* - MDBX_CURRENT
* Replace the item at the current cursor position. The key parameter
* must still be provided, and must match it, otherwise the function
* return MDBX_EKEYMISMATCH.
@@ -3459,8 +3568,8 @@ LIBMDBX_API int mdbx_put_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
*
* Returns A non-zero error value on failure and 0 on success, some
* possible errors are:
* - MDBX_NOTFOUND = the key-value pair was not in the database.
* - MDBX_EINVAL = an invalid parameter was specified. */
* - MDBX_NOTFOUND = the key-value pair was not in the database.
* - MDBX_EINVAL = an invalid parameter was specified. */
LIBMDBX_API int mdbx_set_attr(MDBX_txn *txn, MDBX_dbi dbi, MDBX_val *key,
MDBX_val *data, mdbx_attr_t attr);

View File

@@ -19,14 +19,9 @@ message(STATUS "libmdbx version is ${MDBX_VERSION}")
if(MDBX_ALLOY_MODE)
set(LIBMDBX_SOURCES alloy.c)
else()
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
set(LIBMDBX_OSAL windows)
else()
set(LIBMDBX_OSAL posix)
endif()
set(LIBMDBX_SOURCES
elements/options.h elements/defs.h elements/internals.h elements/osal.h
elements/core.c elements/osal.c elements/lck-${LIBMDBX_OSAL}.c)
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"

File diff suppressed because it is too large Load Diff

View File

@@ -118,10 +118,8 @@
# define __noinline __attribute__((__noinline__))
# elif defined(_MSC_VER)
# define __noinline __declspec(noinline)
# elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
# define __noinline inline
# elif !defined(__INTEL_COMPILER)
# define __noinline /* FIXME ? */
# else
# define __noinline
# endif
#endif /* __noinline */
@@ -142,33 +140,33 @@
#endif /* __maybe_unused */
#if !defined(__noop) && !defined(_MSC_VER)
# define __noop(...) do {} while(0)
# define __noop(...) do {} while(0)
#endif /* __noop */
#ifndef __fallthrough
# if __GNUC_PREREQ(7, 0) || __has_attribute(__fallthrough__)
# define __fallthrough __attribute__((__fallthrough__))
# else
# define __fallthrough __noop()
# endif
# if __GNUC_PREREQ(7, 0) || __has_attribute(__fallthrough__)
# define __fallthrough __attribute__((__fallthrough__))
# else
# define __fallthrough __noop()
# endif
#endif /* __fallthrough */
#ifndef __unreachable
# if __GNUC_PREREQ(4,5) || __has_builtin(__builtin_unreachable)
# define __unreachable() __builtin_unreachable()
# elif defined(_MSC_VER)
# define __unreachable() __assume(0)
# else
# define __unreachable() __noop()
# endif
# if __GNUC_PREREQ(4,5) || __has_builtin(__builtin_unreachable)
# define __unreachable() __builtin_unreachable()
# elif defined(_MSC_VER)
# define __unreachable() __assume(0)
# else
# define __unreachable() __noop()
# endif
#endif /* __unreachable */
#ifndef __prefetch
# if defined(__GNUC__) || defined(__clang__)
# define __prefetch(ptr) __builtin_prefetch(ptr)
# else
# define __prefetch(ptr) __noop(ptr)
# endif
# if defined(__GNUC__) || defined(__clang__) || __has_builtin(__builtin_prefetch)
# define __prefetch(ptr) __builtin_prefetch(ptr)
# else
# define __prefetch(ptr) __noop(ptr)
# endif
#endif /* __prefetch */
#ifndef __noreturn
@@ -237,15 +235,13 @@
#ifndef __optimize
# if defined(__OPTIMIZE__)
# if defined(__clang__) && !__has_attribute(__optimize__)
# define __optimize(ops)
# elif defined(__GNUC__) || __has_attribute(__optimize__)
# if (defined(__GNUC__) && !defined(__clang__)) || __has_attribute(__optimize__)
# define __optimize(ops) __attribute__((__optimize__(ops)))
# else
# define __optimize(ops)
# endif
# else
# define __optimize(ops)
# define __optimize(ops)
# endif
#endif /* __optimize */
@@ -309,21 +305,10 @@
# endif
#endif /* unlikely */
/* Workaround for Coverity Scan */
#if defined(__COVERITY__) && __GNUC_PREREQ(7, 0) && !defined(__cplusplus)
typedef float _Float32;
typedef double _Float32x;
typedef double _Float64;
typedef long double _Float64x;
typedef float _Float128 __attribute__((__mode__(__TF__)));
typedef __complex__ float __cfloat128 __attribute__ ((__mode__ (__TC__)));
typedef _Complex float __cfloat128 __attribute__ ((__mode__ (__TC__)));
#endif /* Workaround for Coverity Scan */
#ifndef __printf_args
# if defined(__GNUC__) || __has_attribute(__format__)
# define __printf_args(format_index, first_arg) \
__attribute__((__format__(printf, format_index, first_arg)))
__attribute__((__format__(__printf__, format_index, first_arg)))
# else
# define __printf_args(format_index, first_arg)
# endif

View File

@@ -1165,7 +1165,7 @@ MDBX_INTERNAL_FUNC void mdbx_rthc_thread_dtor(void *ptr);
((rc) != MDBX_RESULT_TRUE && (rc) != MDBX_RESULT_FALSE)
/* Internal error codes, not exposed outside libmdbx */
#define MDBX_NO_ROOT (MDBX_LAST_ERRCODE + 10)
#define MDBX_NO_ROOT (MDBX_LAST_LMDB_ERRCODE + 10)
/* Debugging output value of a cursor DBI: Negative in a sub-cursor. */
#define DDBI(mc) \
@@ -1318,3 +1318,14 @@ static __maybe_unused __inline void mdbx_jitter4testing(bool tiny) {
(void)tiny;
#endif
}
static __pure_function __always_inline __maybe_unused bool
is_powerof2(size_t x) {
return (x & (x - 1)) == 0;
}
static __pure_function __always_inline __maybe_unused size_t
roundup_powerof2(size_t value, size_t granularity) {
assert(is_powerof2(granularity));
return (value + granularity - 1) & ~(granularity - 1);
}

View File

@@ -12,6 +12,8 @@
* <http://www.OpenLDAP.org/license.html>.
*/
#if !(defined(_WIN32) || defined(_WIN64)) /* !Windows LCK-implementation */
#include "internals.h"
#include <sys/sem.h>
@@ -803,3 +805,10 @@ void mdbx_txn_unlock(MDBX_env *env) {
mdbx_panic("%s() failed: err %d\n", __func__, rc);
mdbx_jitter4testing(true);
}
#else
#ifdef _MSC_VER
#pragma warning(disable : 4206) /* nonstandard extension used: translation \
unit is empty */
#endif /* _MSC_VER (warnings) */
#endif /* !Windows LCK-implementation */

View File

@@ -12,17 +12,15 @@
* <http://www.OpenLDAP.org/license.html>.
*/
#include "internals.h"
#if defined(_WIN32) || defined(_WIN64) /* Windows LCK-implementation */
/* PREAMBLE FOR WINDOWS:
*
* We are not concerned for performance here.
* If you are running Windows a performance could NOT be the goal.
* Otherwise please use Linux.
*
* Regards,
* LY
*/
* Otherwise please use Linux. */
#include "internals.h"
static void mdbx_winnt_import(void);
@@ -367,22 +365,24 @@ mdbx_resume_threads_after_remap(mdbx_handle_array_t *array) {
*/
static void lck_unlock(MDBX_env *env) {
int rc;
int err;
if (env->me_lfd != INVALID_HANDLE_VALUE) {
/* double `unlock` for robustly remove overlapped shared/exclusive locks */
while (funlock(env->me_lfd, LCK_LOWER))
;
rc = GetLastError();
assert(rc == ERROR_NOT_LOCKED);
(void)rc;
err = GetLastError();
assert(err == ERROR_NOT_LOCKED ||
(mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION));
(void)err;
SetLastError(ERROR_SUCCESS);
while (funlock(env->me_lfd, LCK_UPPER))
;
rc = GetLastError();
assert(rc == ERROR_NOT_LOCKED);
(void)rc;
err = GetLastError();
assert(err == ERROR_NOT_LOCKED ||
(mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION));
(void)err;
SetLastError(ERROR_SUCCESS);
}
@@ -391,23 +391,26 @@ static void lck_unlock(MDBX_env *env) {
* releases such locks via deferred queues) */
while (funlock(env->me_lazy_fd, LCK_BODY))
;
rc = GetLastError();
assert(rc == ERROR_NOT_LOCKED);
(void)rc;
err = GetLastError();
assert(err == ERROR_NOT_LOCKED ||
(mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION));
(void)err;
SetLastError(ERROR_SUCCESS);
while (funlock(env->me_lazy_fd, LCK_META))
;
rc = GetLastError();
assert(rc == ERROR_NOT_LOCKED);
(void)rc;
err = GetLastError();
assert(err == ERROR_NOT_LOCKED ||
(mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION));
(void)err;
SetLastError(ERROR_SUCCESS);
while (funlock(env->me_lazy_fd, LCK_WHOLE))
;
rc = GetLastError();
assert(rc == ERROR_NOT_LOCKED);
(void)rc;
err = GetLastError();
assert(err == ERROR_NOT_LOCKED ||
(mdbx_RunningUnderWine() && err == ERROR_LOCK_VIOLATION));
(void)err;
SetLastError(ERROR_SUCCESS);
}
}
@@ -717,6 +720,7 @@ static uint64_t WINAPI stub_GetTickCount64(void) {
/*----------------------------------------------------------------------------*/
#ifndef MDBX_ALLOY
MDBX_NtExtendSection mdbx_NtExtendSection;
MDBX_GetFileInformationByHandleEx mdbx_GetFileInformationByHandleEx;
MDBX_GetVolumeInformationByHandleW mdbx_GetVolumeInformationByHandleW;
MDBX_GetFinalPathNameByHandleW mdbx_GetFinalPathNameByHandleW;
@@ -732,7 +736,47 @@ MDBX_ReclaimVirtualMemory mdbx_ReclaimVirtualMemory;
#endif /* MDBX_ALLOY */
static void mdbx_winnt_import(void) {
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
#define GET_PROC_ADDR(dll, ENTRY) \
mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(dll, #ENTRY)
if (GetProcAddress(hNtdll, "wine_get_version")) {
assert(mdbx_RunningUnderWine());
} else {
GET_PROC_ADDR(hNtdll, NtFsControlFile);
GET_PROC_ADDR(hNtdll, NtExtendSection);
assert(!mdbx_RunningUnderWine());
}
const HINSTANCE hKernel32dll = GetModuleHandleA("kernel32.dll");
GET_PROC_ADDR(hKernel32dll, GetFileInformationByHandleEx);
GET_PROC_ADDR(hKernel32dll, GetTickCount64);
if (!mdbx_GetTickCount64)
mdbx_GetTickCount64 = stub_GetTickCount64;
if (!mdbx_RunningUnderWine()) {
GET_PROC_ADDR(hKernel32dll, SetFileInformationByHandle);
GET_PROC_ADDR(hKernel32dll, GetVolumeInformationByHandleW);
GET_PROC_ADDR(hKernel32dll, GetFinalPathNameByHandleW);
GET_PROC_ADDR(hKernel32dll, PrefetchVirtualMemory);
}
#if 0 /* LY: unused for now */
if (!mdbx_RunningUnderWine()) {
GET_PROC_ADDR(hKernel32dll, DiscardVirtualMemory);
GET_PROC_ADDR(hKernel32dll, OfferVirtualMemory);
GET_PROC_ADDR(hKernel32dll, ReclaimVirtualMemory);
}
if (!mdbx_DiscardVirtualMemory)
mdbx_DiscardVirtualMemory = stub_DiscardVirtualMemory;
if (!mdbx_OfferVirtualMemory)
mdbx_OfferVirtualMemory = stub_OfferVirtualMemory;
if (!mdbx_ReclaimVirtualMemory)
mdbx_ReclaimVirtualMemory = stub_ReclaimVirtualMemory;
#endif /* unused for now */
#undef GET_PROC_ADDR
const MDBX_srwlock_function init =
(MDBX_srwlock_function)GetProcAddress(hKernel32dll, "InitializeSRWLock");
if (init != NULL) {
@@ -752,27 +796,6 @@ static void mdbx_winnt_import(void) {
mdbx_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive;
mdbx_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive;
}
#define GET_KERNEL32_PROC(ENTRY) \
mdbx_##ENTRY = (MDBX_##ENTRY)GetProcAddress(hKernel32dll, #ENTRY)
GET_KERNEL32_PROC(GetFileInformationByHandleEx);
GET_KERNEL32_PROC(GetVolumeInformationByHandleW);
GET_KERNEL32_PROC(GetFinalPathNameByHandleW);
GET_KERNEL32_PROC(SetFileInformationByHandle);
GET_KERNEL32_PROC(PrefetchVirtualMemory);
GET_KERNEL32_PROC(GetTickCount64);
if (!mdbx_GetTickCount64)
mdbx_GetTickCount64 = stub_GetTickCount64;
#if 0 /* LY: unused for now */
GET_KERNEL32_PROC(DiscardVirtualMemory);
if (!mdbx_DiscardVirtualMemory)
mdbx_DiscardVirtualMemory = stub_DiscardVirtualMemory;
GET_KERNEL32_PROC(OfferVirtualMemory);
GET_KERNEL32_PROC(ReclaimVirtualMemory);
#endif /* unused for now */
#undef GET_KERNEL32_PROC
const HINSTANCE hNtdll = GetModuleHandleA("ntdll.dll");
mdbx_NtFsControlFile =
(MDBX_NtFsControlFile)GetProcAddress(hNtdll, "NtFsControlFile");
}
#endif /* Windows LCK-implementation */

View File

@@ -67,23 +67,6 @@ typedef struct _SECTION_BASIC_INFORMATION {
LARGE_INTEGER SectionSize;
} SECTION_BASIC_INFORMATION, *PSECTION_BASIC_INFORMATION;
typedef enum _SECTION_INFORMATION_CLASS {
SectionBasicInformation,
SectionImageInformation,
SectionRelocationInformation, // name:wow64:whNtQuerySection_SectionRelocationInformation
MaxSectionInfoClass
} SECTION_INFORMATION_CLASS;
extern NTSTATUS NTAPI NtQuerySection(
IN HANDLE SectionHandle, IN SECTION_INFORMATION_CLASS InformationClass,
OUT PVOID InformationBuffer, IN ULONG InformationBufferSize,
OUT PULONG ResultLength OPTIONAL);
extern NTSTATUS NTAPI NtExtendSection(IN HANDLE SectionHandle,
IN PLARGE_INTEGER NewSectionSize);
typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 } SECTION_INHERIT;
extern NTSTATUS NTAPI NtMapViewOfSection(
IN HANDLE SectionHandle, IN HANDLE ProcessHandle, IN OUT PVOID *BaseAddress,
IN ULONG_PTR ZeroBits, IN SIZE_T CommitSize,
@@ -324,12 +307,13 @@ MDBX_INTERNAL_FUNC int mdbx_asprintf(char **strp, const char *fmt, ...) {
#ifndef mdbx_memalign_alloc
MDBX_INTERNAL_FUNC int mdbx_memalign_alloc(size_t alignment, size_t bytes,
void **result) {
assert(is_powerof2(alignment) && alignment >= sizeof(void *));
#if defined(_WIN32) || defined(_WIN64)
(void)alignment;
*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, bytes);
*result = aligned_alloc(alignment, roundup_powerof2(bytes, alignment));
return *result ? MDBX_SUCCESS : errno;
#elif _POSIX_VERSION >= 200112L
*result = nullptr;
@@ -1001,6 +985,9 @@ MDBX_INTERNAL_FUNC int mdbx_check_fs_rdonly(mdbx_filehandle_t handle,
static int mdbx_check_fs_local(mdbx_filehandle_t handle, int flags) {
#if defined(_WIN32) || defined(_WIN64)
if (mdbx_RunningUnderWine() && !(flags & MDBX_EXCLUSIVE))
return ERROR_NOT_CAPABLE /* workaround for Wine */;
if (GetFileType(handle) != FILE_TYPE_DISK)
return ERROR_FILE_OFFLINE;
@@ -1313,7 +1300,8 @@ MDBX_INTERNAL_FUNC int mdbx_mmap(const int flags, mdbx_mmap_t *map,
if (!NT_SUCCESS(err))
return ntstatus2errcode(err);
SIZE_T ViewSize = (flags & MDBX_RDONLY) ? 0 : limit;
SIZE_T ViewSize =
(flags & MDBX_RDONLY) ? 0 : mdbx_RunningUnderWine() ? size : limit;
err = NtMapViewOfSection(
map->section, GetCurrentProcess(), &map->address,
/* ZeroBits */ 0,
@@ -1415,8 +1403,10 @@ MDBX_INTERNAL_FUNC int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size,
if (!(flags & MDBX_RDONLY) && limit == map->limit && size > map->current) {
/* growth rw-section */
if (!mdbx_NtExtendSection)
return MDBX_UNABLE_EXTEND_MAPSIZE /* workaround for Wine */;
SectionSize.QuadPart = size;
status = NtExtendSection(map->section, &SectionSize);
status = mdbx_NtExtendSection(map->section, &SectionSize);
if (!NT_SUCCESS(status))
return ntstatus2errcode(status);
map->current = size;
@@ -1432,7 +1422,7 @@ MDBX_INTERNAL_FUNC int mdbx_mresize(int flags, mdbx_mmap_t *map, size_t size,
status = NtAllocateVirtualMemory(GetCurrentProcess(), &BaseAddress, 0,
&RegionSize, MEM_RESERVE, PAGE_NOACCESS);
if (status == /* STATUS_CONFLICTING_ADDRESSES */ 0xC0000018)
return MDBX_RESULT_TRUE;
return MDBX_UNABLE_EXTEND_MAPSIZE;
if (!NT_SUCCESS(status))
return ntstatus2errcode(status);
@@ -1550,8 +1540,8 @@ retry_mapview:;
if (map->address && (size != map->current || limit != map->limit)) {
/* try remap with previously size and limit,
* but will return MDBX_RESULT_TRUE on success */
rc = MDBX_RESULT_TRUE;
* but will return MDBX_UNABLE_EXTEND_MAPSIZE on success */
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
size = map->current;
limit = map->limit;
goto retry_file_and_section;
@@ -1574,7 +1564,7 @@ retry_mapview:;
if (flags & MDBX_RDONLY) {
map->current = (filesize > limit) ? limit : (size_t)filesize;
if (map->current != size)
rc = MDBX_RESULT_TRUE;
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
} else if (filesize != size) {
rc = mdbx_ftruncate(map->fd, size);
if (rc != MDBX_SUCCESS)
@@ -1591,7 +1581,7 @@ retry_mapview:;
case EAGAIN:
case ENOMEM:
case EFAULT /* MADV_DODUMP / MADV_DONTDUMP are mixed for mmap-range */:
rc = MDBX_RESULT_TRUE;
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
}
return rc;
}
@@ -1610,7 +1600,7 @@ retry_mapview:;
#else /* MREMAP_MAYMOVE */
/* TODO: Perhaps here it is worth to implement suspend/resume threads
* and perform unmap/map as like for Windows. */
rc = MDBX_RESULT_TRUE;
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
#endif /* !MREMAP_MAYMOVE */
}
#endif
@@ -1806,20 +1796,20 @@ static uint64_t windows_bootime(void) {
return 0;
}
static LSTATUS mdbx_RegGetValue(HKEY hkey, LPCWSTR lpSubKey, LPCWSTR lpValue,
static LSTATUS mdbx_RegGetValue(HKEY hkey, LPCSTR lpSubKey, LPCSTR lpValue,
DWORD dwFlags, LPDWORD pdwType, PVOID pvData,
LPDWORD pcbData) {
LSTATUS rc =
RegGetValueW(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
RegGetValueA(hkey, lpSubKey, lpValue, dwFlags, pdwType, pvData, pcbData);
if (rc != ERROR_FILE_NOT_FOUND)
return rc;
rc = RegGetValueW(hkey, lpSubKey, lpValue,
rc = RegGetValueA(hkey, lpSubKey, lpValue,
dwFlags | 0x00010000 /* RRF_SUBKEY_WOW6464KEY */, pdwType,
pvData, pcbData);
if (rc != ERROR_FILE_NOT_FOUND)
return rc;
return RegGetValueW(hkey, lpSubKey, lpValue,
return RegGetValueA(hkey, lpSubKey, lpValue,
dwFlags | 0x00020000 /* RRF_SUBKEY_WOW6432KEY */, pdwType,
pvData, pcbData);
}
@@ -1932,30 +1922,30 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
char DigitalProductId[248];
} buf;
static const wchar_t HKLM_MicrosoftCryptography[] =
L"SOFTWARE\\Microsoft\\Cryptography";
static const char HKLM_MicrosoftCryptography[] =
"SOFTWARE\\Microsoft\\Cryptography";
DWORD len = sizeof(buf);
/* Windows is madness and must die */
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_MicrosoftCryptography,
L"MachineGuid", RRF_RT_ANY, NULL, &buf.MachineGuid,
"MachineGuid", RRF_RT_ANY, NULL, &buf.MachineGuid,
&len) == ERROR_SUCCESS &&
len > 42 && len < sizeof(buf))
got_machineid = bootid_parse_uuid(&bin, &buf.MachineGuid, len);
if (!got_machineid) {
/* again, Windows is madness */
static const wchar_t HKLM_WindowsNT[] =
L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
static const wchar_t HKLM_WindowsNT_DPK[] =
L"SOFTWARE\\Microsoft\\Windows "
L"NT\\CurrentVersion\\DefaultProductKey";
static const wchar_t HKLM_WindowsNT_DPK2[] =
L"SOFTWARE\\Microsoft\\Windows "
L"NT\\CurrentVersion\\DefaultProductKey2";
static const char HKLM_WindowsNT[] =
"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion";
static const char HKLM_WindowsNT_DPK[] =
"SOFTWARE\\Microsoft\\Windows "
"NT\\CurrentVersion\\DefaultProductKey";
static const char HKLM_WindowsNT_DPK2[] =
"SOFTWARE\\Microsoft\\Windows "
"NT\\CurrentVersion\\DefaultProductKey2";
len = sizeof(buf);
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT,
L"DigitalProductId", RRF_RT_ANY, NULL,
"DigitalProductId", RRF_RT_ANY, NULL,
&buf.DigitalProductId, &len) == ERROR_SUCCESS &&
len > 42 && len < sizeof(buf)) {
bootid_collect(&bin, &buf.DigitalProductId, len);
@@ -1963,7 +1953,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
}
len = sizeof(buf);
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT_DPK,
L"DigitalProductId", RRF_RT_ANY, NULL,
"DigitalProductId", RRF_RT_ANY, NULL,
&buf.DigitalProductId, &len) == ERROR_SUCCESS &&
len > 42 && len < sizeof(buf)) {
bootid_collect(&bin, &buf.DigitalProductId, len);
@@ -1971,7 +1961,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
}
len = sizeof(buf);
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_WindowsNT_DPK2,
L"DigitalProductId", RRF_RT_ANY, NULL,
"DigitalProductId", RRF_RT_ANY, NULL,
&buf.DigitalProductId, &len) == ERROR_SUCCESS &&
len > 42 && len < sizeof(buf)) {
bootid_collect(&bin, &buf.DigitalProductId, len);
@@ -1979,11 +1969,11 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
}
}
static const wchar_t HKLM_PrefetcherParams[] =
L"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory "
L"Management\\PrefetchParameters";
static const char HKLM_PrefetcherParams[] =
"SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Memory "
"Management\\PrefetchParameters";
len = sizeof(buf);
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, L"BootId",
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BootId",
RRF_RT_DWORD, NULL, &buf.BootId,
&len) == ERROR_SUCCESS &&
len > 1 && len < sizeof(buf)) {
@@ -1992,7 +1982,7 @@ __cold MDBX_INTERNAL_FUNC bin128_t mdbx_osal_bootid(void) {
}
len = sizeof(buf);
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, L"BaseTime",
if (mdbx_RegGetValue(HKEY_LOCAL_MACHINE, HKLM_PrefetcherParams, "BaseTime",
RRF_RT_DWORD, NULL, &buf.BaseTime,
&len) == ERROR_SUCCESS &&
len >= sizeof(buf.BaseTime) && buf.BaseTime) {

View File

@@ -760,6 +760,7 @@ MDBX_INTERNAL_FUNC int mdbx_rpid_clear(MDBX_env *env);
MDBX_INTERNAL_FUNC int mdbx_rpid_check(MDBX_env *env, uint32_t pid);
#if defined(_WIN32) || defined(_WIN64)
typedef union MDBX_srwlock {
struct {
long volatile readerCount;
@@ -849,6 +850,16 @@ typedef DWORD(WINAPI *MDBX_OfferVirtualMemory(
MDBX_INTERNAL_VAR MDBX_OfferVirtualMemory mdbx_OfferVirtualMemory;
#endif /* unused for now */
typedef enum _SECTION_INHERIT { ViewShare = 1, ViewUnmap = 2 } SECTION_INHERIT;
typedef NTSTATUS(NTAPI *MDBX_NtExtendSection)(IN HANDLE SectionHandle,
IN PLARGE_INTEGER NewSectionSize);
MDBX_INTERNAL_VAR MDBX_NtExtendSection mdbx_NtExtendSection;
static __inline bool mdbx_RunningUnderWine(void) {
return !mdbx_NtExtendSection;
}
#endif /* Windows */
/*----------------------------------------------------------------------------*/

View File

@@ -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
@@ -84,4 +84,4 @@ if no quiet mode was requested.
.BR mdbx_dump (1),
.BR mdbx_load (1)
.SH AUTHOR
Leonid Yuriev <https://github.com/leo-yuriev>
Leonid Yuriev <https://github.com/erthink>

View File

@@ -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
@@ -63,4 +63,4 @@ free during copying cannot be reused until the copy is done.
.BR mdbx_load (1)
.SH AUTHOR
Howard Chu of Symas Corporation <http://www.symas.com>,
Leonid Yuriev <https://github.com/leo-yuriev>
Leonid Yuriev <https://github.com/erthink>

View File

@@ -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
@@ -88,4 +88,4 @@ utility to load the database using the correct comparison functions.
.BR mdbx_stat (1)
.SH AUTHOR
Howard Chu of Symas Corporation <http://www.symas.com>,
Leonid Yuriev <https://github.com/leo-yuriev>
Leonid Yuriev <https://github.com/erthink>

View File

@@ -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
@@ -99,4 +99,4 @@ a diagnostic message being written to standard error.
.BR mdbx_copy (1)
.SH AUTHOR
Howard Chu of Symas Corporation <http://www.symas.com>,
Leonid Yuriev <https://github.com/leo-yuriev>
Leonid Yuriev <https://github.com/erthink>

View File

@@ -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
@@ -72,4 +72,4 @@ a diagnostic message being written to standard error.
.BR mdbx_load (1)
.SH AUTHOR
Howard Chu of Symas Corporation <http://www.symas.com>,
Leonid Yuriev <https://github.com/leo-yuriev>
Leonid Yuriev <https://github.com/erthink>

View File

@@ -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) {

View File

@@ -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"

View File

@@ -53,7 +53,7 @@ bool testcase_jitter::run() {
err = mdbx_env_set_geometry(
db_guard.get(), -1, -1,
coin4size ? upper_limit * 2 / 3 : upper_limit * 3 / 2, -1, -1, -1);
if (err != MDBX_SUCCESS && err != MDBX_RESULT_TRUE &&
if (err != MDBX_SUCCESS && err != MDBX_UNABLE_EXTEND_MAPSIZE &&
err != MDBX_MAP_FULL && err != MDBX_TOO_LARGE)
failure_perror("mdbx_env_set_geometry-1", err);
}
@@ -62,7 +62,7 @@ bool testcase_jitter::run() {
err = mdbx_env_set_geometry(
db_guard.get(), -1, -1,
!coin4size ? upper_limit * 2 / 3 : upper_limit * 3 / 2, -1, -1, -1);
if (err != MDBX_SUCCESS && err != MDBX_RESULT_TRUE &&
if (err != MDBX_SUCCESS && err != MDBX_UNABLE_EXTEND_MAPSIZE &&
err != MDBX_MAP_FULL && err != MDBX_TOO_LARGE)
failure_perror("mdbx_env_set_geometry-2", err);
@@ -76,7 +76,7 @@ bool testcase_jitter::run() {
jitter_delay();
err =
mdbx_env_set_geometry(db_guard.get(), -1, -1, upper_limit, -1, -1, -1);
if (err != MDBX_SUCCESS && err != MDBX_RESULT_TRUE &&
if (err != MDBX_SUCCESS && err != MDBX_UNABLE_EXTEND_MAPSIZE &&
err != MDBX_MAP_FULL && err != MDBX_TOO_LARGE)
failure_perror("mdbx_env_set_geometry-3", err);

View File

@@ -336,20 +336,22 @@ static void periodic_stat(void) {
prev_del_time = mdbx_del_time;
}
// static void periodic_add_rec() {
// for (int i = 0; i < 10240; i++) {
// if (ids_count <= REC_COUNT) {
// int64_t id = obj_id++;
// create_record(id);
// add_id_to_pool(id);
// }
// if (ids_count > REC_COUNT) {
// int64_t id = get_id_from_pool();
// delete_record(id);
// }
// }
// periodic_stat();
//}
#if 0 /* unused */
static void periodic_add_rec() {
for (int i = 0; i < 10240; i++) {
if (ids_count <= REC_COUNT) {
int64_t id = obj_id++;
create_record(id);
add_id_to_pool(id);
}
if (ids_count > REC_COUNT) {
int64_t id = get_id_from_pool();
delete_record(id);
}
}
periodic_stat();
}
#endif
int main(int argc, char **argv) {
(void)argc;
@@ -358,14 +360,12 @@ int main(int argc, char **argv) {
char filename[PATH_MAX];
int i;
mkdir(opt_db_path, 0775);
strcpy(filename, opt_db_path);
strcat(filename, "/mdbx.dat");
strcat(filename, MDBX_DATANAME);
remove(filename);
strcpy(filename, opt_db_path);
strcat(filename, "/mdbx.lck");
strcat(filename, MDBX_LOCKNAME);
remove(filename);
puts("Open DB...");
@@ -394,14 +394,14 @@ int main(int argc, char **argv) {
id = get_id_from_pool();
delete_record(id);
}
// for (i = 0; i < 50; i++) {
// int64_t id = obj_id++;
// create_record(id);
// add_id_to_pool(id);
// }
// int64_t id = obj_id++;
// create_record(id);
// add_id_to_pool(id);
for (i = 0; i < 50; i++) {
int64_t id = obj_id++;
create_record(id);
add_id_to_pool(id);
}
int64_t id = obj_id++;
create_record(id);
add_id_to_pool(id);
int64_t now = getClockUs();
if ((now - t) > 10000000L) {
periodic_stat();