mirror of
https://github.com/isar/libmdbx.git
synced 2025-12-15 04:32:21 +08:00
Compare commits
61 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
9b8291457b | ||
|
|
0f13d91a0e | ||
|
|
d40b69ec7a | ||
|
|
7489c8ce28 | ||
|
|
caddf07889 | ||
|
|
74256efc64 | ||
|
|
e47a91bf7c | ||
|
|
3ace3c27b8 | ||
|
|
bcebfb4b4c | ||
|
|
b5400f9a35 | ||
|
|
8a44d57fab | ||
|
|
fdb2b5b0f1 | ||
|
|
95cb73646e | ||
|
|
b2d16d32aa | ||
|
|
e0be0d9a5e | ||
|
|
2ba7051719 | ||
|
|
04ed388761 | ||
|
|
da4e2ab254 | ||
|
|
53177e483c | ||
|
|
ad93633d10 | ||
|
|
f17c55a872 | ||
|
|
7db014c4fc | ||
|
|
22405885f6 | ||
|
|
2ae7bfd9be | ||
|
|
8f87ab252e | ||
|
|
800bd55ab9 | ||
|
|
5c52adf358 | ||
|
|
6d74b10db1 | ||
|
|
359489e271 | ||
|
|
5f690bbc4f | ||
|
|
1b6e32071c | ||
|
|
29d12f1fc3 | ||
|
|
2ea9fbe51b | ||
|
|
57ca0d6e1b | ||
|
|
b8092dd0db | ||
|
|
8fba5ac8d8 | ||
|
|
c9d11cbac1 | ||
|
|
25e958f081 | ||
|
|
7f5ea6d3b8 | ||
|
|
e51140fe48 | ||
|
|
bd35fe8970 | ||
|
|
1684d17b0f | ||
|
|
ebbe98afa5 | ||
|
|
351a30f186 | ||
|
|
2a41b24876 | ||
|
|
fb827959a9 | ||
|
|
209f784ee7 | ||
|
|
68ebbe1fde | ||
|
|
486711945d | ||
|
|
3ade7c7ba1 | ||
|
|
c01f025bfa | ||
|
|
a484a1f89b | ||
|
|
0979a93a78 | ||
|
|
a98c73f4f6 | ||
|
|
9e15bd9b29 | ||
|
|
0159f97e94 | ||
|
|
56050f201f | ||
|
|
525c4a55a4 | ||
|
|
702c67fc38 | ||
|
|
3da23da7b3 | ||
|
|
16cda5c2e8 |
@@ -1,5 +1,5 @@
|
||||
##
|
||||
## Copyright 2020-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
## Copyright 2020-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
## and other libmdbx authors: please see AUTHORS file.
|
||||
## All rights reserved.
|
||||
##
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
Copyright 2011-2015 Howard Chu, Symas Corp.
|
||||
Copyright 2015,2016 Peter-Service R&D LLC.
|
||||
All rights reserved.
|
||||
|
||||
296
ChangeLog.md
296
ChangeLog.md
@@ -5,9 +5,135 @@ English version [by Google](https://gitflic-ru.translate.goog/project/erthink/li
|
||||
and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic.ru/project/erthink/libmdbx/blob?file=ChangeLog.md).
|
||||
|
||||
|
||||
## v0.12.3 (Акула) от 2023-01-07
|
||||
## v0.12.5 "Динамо" от 2023-04-18
|
||||
|
||||
Выпуск с существенными доработками и новой функциональностью в память о закрытом open-source проекте "Акула".
|
||||
Стабилизирующий выпуск с исправлением обнаруженных ошибок и устранением
|
||||
недочетов, в день 100-летнего юбилея спортивного общества [«Динамо»](https://ru.wikipedia.org/wiki/Динамо_(спортивное_общество)).
|
||||
|
||||
```
|
||||
16 files changed, 686 insertions(+), 247 deletions(-)
|
||||
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
```
|
||||
|
||||
Благодарности:
|
||||
|
||||
- Max <maxc0d3r@protonmail.com> за сообщение о проблеме экспорта из DSO/DLL
|
||||
устаревших функций API.
|
||||
- [`@calvin3721`](https://t.me/calvin3721) за сообщение о проблеме работы
|
||||
`MainDB` с флагами не по-умолчанию.
|
||||
|
||||
Исправления:
|
||||
|
||||
- Поправлен экспорт из DSO/DLL устаревших функций,
|
||||
которые заменены на inline в текущем API.
|
||||
- Устранено использование неверного компаратора при создании или пересоздании
|
||||
`MainDB` с флагами/опциями предполагающим использование специфического
|
||||
компаратора (не по-умолчанию).
|
||||
|
||||
Мелочи:
|
||||
|
||||
- Удалена дублирующая диагностика внутри `node_read_bigdata()`.
|
||||
- Исправлены ссылки в описании `mdbx_env_set_geometry()`.
|
||||
- Добавлен отдельный тест `extra/upsert_alldups` для специфического
|
||||
сценария замены/перезаписи одним значением всех multi-значений
|
||||
соответствующих ключу, т.е. замена всех «дубликатов» одним значением.
|
||||
- В C++ API добавлены варианты `buffer::key_from()` с явным именованием по типу данных.
|
||||
- Добавлен отдельный тест `extra/maindb_ordinal` для специфического
|
||||
сценария создания `MainDB` с флагами требующими использования
|
||||
компаратора не по-умолчанию.
|
||||
- Рефакторинг проверки "когерентности" мета-страниц.
|
||||
- Корректировка `osal_vasprintf()` для устранения предупреждений статических анализаторов.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.12.4 "Арта-333" от 2023-03-03
|
||||
|
||||
Стабилизирующий выпуск с исправлением обнаруженных ошибок, устранением
|
||||
недочетов и технических долгов. Ветка 0.12 считается готовой к
|
||||
продуктовому использованию, получает статус стабильной и далее будет
|
||||
получать только исправление ошибок. Разработка будет продолжена в ветке
|
||||
0.13, а ветка 0.11 становится архивной.
|
||||
|
||||
```
|
||||
63 files changed, 1161 insertions(+), 569 deletions(-)
|
||||
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
```
|
||||
|
||||
Благодарности:
|
||||
|
||||
- Max <maxc0d3r@protonmail.com> за сообщение о проблеме ERROR_SHARING_VIOLATION
|
||||
в режиме MDBX_EXCLUSIVE на Windows.
|
||||
- Alisher Ashyrov <https://t.me/a1is43ras4> за сообщение о проблеме
|
||||
с assert-проверкой и содействие в отладке.
|
||||
- Masatoshi Fukunaga <https://gitflic.ru/user/mah0x211> за сообщение о проблеме
|
||||
`put(MDBX_UPSERT+MDBX_ALLDUPS)` для случая замены всех значений в subDb.
|
||||
|
||||
Исправления:
|
||||
|
||||
- Устранен регресс после коммита 474391c83c5f81def6fdf3b0b6f5716a87b78fbf,
|
||||
приводящий к возврату ERROR_SHARING_VIOLATION в Windows при открытии БД
|
||||
в режиме MDBX_EXCLUSIVE для чтения-записи.
|
||||
|
||||
- Добавлено ограничение размера отображения при коротком read-only файле, для
|
||||
предотвращения ошибки ERROR_NOT_ENOUGH_MEMORY в Windows, которая возникает
|
||||
в этом случае и совсем не информативна для пользователя.
|
||||
|
||||
- Произведен рефакторинг `dxb_resize()`, в том числе, для устранения срабатывания
|
||||
assert-проверки `size_bytes == env->me_dxb_mmap.current` в специфических
|
||||
многопоточных сценариях использования. Проверка срабатывала только в
|
||||
отладочных сборках, при специфическом наложении во времени читающей и
|
||||
пишущей транзакции в разных потоках, одновременно с изменением размера БД.
|
||||
Кроме срабатывание проверки, каких-либо других последствий не возникало.
|
||||
|
||||
- Устранена проблема в `put(MDBX_UPSERT+MDBX_ALLDUPS)` для случая замены
|
||||
всех значений единственного ключа в subDb. В ходе этой операции subDb
|
||||
становится полностью пустой, без каких-либо страниц и именно эта
|
||||
ситуация не была учтена в коде, что приводило к повреждению БД
|
||||
при фиксации такой транзакции.
|
||||
|
||||
- Устранена излишняя assert-проверка внутри `override_meta()`.
|
||||
Что в отладочных сборках могло приводить к ложным срабатываниям
|
||||
при восстановлении БД, в том числе при автоматическом откате слабых
|
||||
мета-страниц.
|
||||
|
||||
- Скорректированы макросы `__cold`/`__hot`, в том числе для устранения проблемы
|
||||
`error: inlining failed in call to ‘always_inline FOO(...)’: target specific option mismatch`
|
||||
при сборке посредством GCC >10.x для SH4.
|
||||
|
||||
Ликвидация технических долгов и мелочи:
|
||||
|
||||
- Исправлены многочисленные опечатки в документации.
|
||||
- Доработан тест для полной стохастической проверки `MDBX_EKEYMISMATCH` в режиме `MDBX_APPEND`.
|
||||
- Расширены сценарии запуска `mdbx_chk` из CMake-тестов для проверки как в обычном,
|
||||
так и эксклюзивном режимах чтения-записи.
|
||||
- Уточнены спецификаторы `const` и `noexcept` для нескольких методов в C++ API.
|
||||
- Устранено использование стека под буферы для `wchar`-преобразования путей.
|
||||
- Для Windows добавлена функция `mdbx_env_get_path()` для получения пути к БД
|
||||
в формате многобайтных символов.
|
||||
- Добавлены doxygen-описания для API с широкими символами.
|
||||
- Устранены предупреждения статического анализатора MSVC,
|
||||
все они были несущественные, либо ложные.
|
||||
- Устранено ложное предупреждение GCC при сборке для SH4.
|
||||
- Добавлена поддержка ASAN (Address Sanitizer) при сборке посредством MSVC.
|
||||
- Расширен набор перебираемых режимов в скрипте `test/long_stochastic.sh`,
|
||||
добавлена опция `--extra`.
|
||||
- В C++ API добавлена поддержка расширенных опций времени выполнения `mdbx::extra_runtime_option`,
|
||||
аналогично `enum MDBX_option_t` из C API.
|
||||
- Вывод всех счетчиков page-operations в `mdbx_stat`.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.12.3 "Акула" от 2023-01-07
|
||||
|
||||
Выпуск с существенными доработками и новой функциональностью в память о закрытом open-source
|
||||
[проекте "Акула"](https://erigon.substack.com/p/winding-down-support-for-akula-project).
|
||||
|
||||
Добавлена prefault-запись, переделан контроль “некогерентности” unified page/buffer cache, изменена тактика слияния страниц и т.д.
|
||||
Стало ещё быстрее, в некоторых сценариях вдвое.
|
||||
|
||||
```
|
||||
20 files changed, 4508 insertions(+), 2928 deletions(-)
|
||||
@@ -77,7 +203,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
системах с unified page cache. Такое поведение (без использования
|
||||
`msync(MS_ASYNC)`) соответствует неизменяемой (hardcoded) логике LMDB. В
|
||||
результате, в простых/наивных бенчмарках, libmdbx опережает LMDB
|
||||
примерна также как при реальном применении.
|
||||
примерно также как при реальном применении.
|
||||
|
||||
На всякий случай стоит еще раз отметить/напомнить, что на Windows
|
||||
предположительно libmdbx будет отставать от LMDB в сценариях с
|
||||
@@ -88,7 +214,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
|
||||
- Поддержка не-печатных имен для subDb.
|
||||
|
||||
- Добавлен явный выбор `tls_model("local-dynamic")` для обзода проблемы
|
||||
- Добавлен явный выбор `tls_model("local-dynamic")` для обхода проблемы
|
||||
`relocation R_X86_64_TPOFF32 against FOO cannot be used with -shared`
|
||||
из-за ошибки в CLANG приводящей к использованию неверного режима `ls_model`.
|
||||
|
||||
@@ -144,7 +270,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.12.2 (Иван Ярыгин) от 2022-11-11
|
||||
## v0.12.2 "Иван Ярыгин" от 2022-11-11
|
||||
|
||||
Выпуск с существенными доработками и новой функциональностью
|
||||
в память о российском борце [Иване Сергеевиче Ярыгине](https://ru.wikipedia.org/wiki/Ярыгин,_Иван_Сергеевич).
|
||||
@@ -292,7 +418,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
Мелочи:
|
||||
|
||||
- Исторические ссылки cвязанные с удалённым на ~~github~~ проектом перенаправлены на [web.archive.org](https://web.archive.org/web/https://github.com/erthink/libmdbx).
|
||||
- Синхронизированны конструкции CMake между проектами.
|
||||
- Синхронизированы конструкции CMake между проектами.
|
||||
- Добавлено предупреждение о небезопасности RISC-V.
|
||||
- Добавлено описание параметров `MDBX_debug_func` и `MDBX_debug_func`.
|
||||
- Добавлено обходное решение для минимизации ложно-положительных
|
||||
@@ -314,7 +440,7 @@ Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.12.1 (Positive Proxima) at 2022-08-24
|
||||
## v0.12.1 "Positive Proxima" at 2022-08-24
|
||||
|
||||
The planned frontward release with new superior features on the day of 20 anniversary of [Positive Technologies](https://ptsecurty.com).
|
||||
|
||||
@@ -356,10 +482,54 @@ Fixes:
|
||||
Not a release but preparation for changing feature set and API.
|
||||
|
||||
|
||||
===============================================================================
|
||||
|
||||
|
||||
## v0.11.14 "Sergey Kapitsa" at 2023-02-14
|
||||
|
||||
The stable bugfix release in memory of [Sergey Kapitsa](https://en.wikipedia.org/wiki/Sergey_Kapitsa) on his 95th birthday.
|
||||
|
||||
```
|
||||
22 files changed, 250 insertions(+), 174 deletions(-)
|
||||
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
```
|
||||
|
||||
Fixes:
|
||||
- backport: Fixed insignificant typo of `||` inside `#if` byte-order condition.
|
||||
- backport: Fixed `SIGSEGV` or an erroneous call to `free()` in situations where
|
||||
errors occur when reopening by `mdbx_env_open()` of a previously used
|
||||
environment.
|
||||
- backport: Fixed `cursor_put_nochecklen()` internals for case when dupsort'ed named subDb
|
||||
contains a single key with multiple values (aka duplicates), which are replaced
|
||||
with a single value by put-operation with the `MDBX_UPSERT+MDBX_ALLDUPS` flags.
|
||||
In this case, the database becomes completely empty, without any pages.
|
||||
However exactly this condition was not considered and thus wasn't handled correctly.
|
||||
See [issue#8](https://gitflic.ru/project/erthink/libmdbx/issue/8) for more information.
|
||||
- backport: Fixed extra assertion inside `override_meta()`, which could
|
||||
lead to false-positive failing of the assertion in a debug builds during
|
||||
DB recovery and auto-rollback.
|
||||
- backport: Refined the `__cold`/`__hot` macros to avoid the
|
||||
`error: inlining failed in call to ‘always_inline FOO(...)’: target specific option mismatch`
|
||||
issue during build using GCC >10.x for SH4 arch.
|
||||
|
||||
Minors:
|
||||
|
||||
- backport: Using the https://libmdbx.dqdkfa.ru/dead-github
|
||||
for resources deleted by the Github' administration.
|
||||
- backport: Fixed English typos.
|
||||
- backport: Fixed proto of `__asan_default_options()`.
|
||||
- backport: Fixed doxygen-description of C++ API, especially of C++20 concepts.
|
||||
- backport: Refined `const` and `noexcept` for few C++ API methods.
|
||||
- backport: Fixed copy&paste typo of "Getting started".
|
||||
- backport: Update MithrilDB status.
|
||||
- backport: Resolve false-posirive `used uninitialized` warning from GCC >10.x
|
||||
while build for SH4 arch.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.13 at (Swashplate) 2022-11-10
|
||||
## v0.11.13 at "Swashplate" 2022-11-10
|
||||
|
||||
The stable bugfix release in memory of [Boris Yuryev](https://ru.wikipedia.org/wiki/Юрьев,_Борис_Николаевич) on his 133rd birthday.
|
||||
|
||||
@@ -387,7 +557,10 @@ Minors:
|
||||
- Use `--dont-check-ram-size` for small-tests make-targets (backport).
|
||||
|
||||
|
||||
## v0.11.12 (Эребуни) at 2022-10-12
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.12 "Эребуни" at 2022-10-12
|
||||
|
||||
The stable bugfix release.
|
||||
|
||||
@@ -409,7 +582,10 @@ Minors:
|
||||
- Removed needless `LockFileEx()` inside `mdbx_env_copy()` (backport).
|
||||
|
||||
|
||||
## v0.11.11 (Тендра-1790) at 2022-09-11
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.11 "Тендра-1790" at 2022-09-11
|
||||
|
||||
The stable bugfix release.
|
||||
|
||||
@@ -425,7 +601,10 @@ Fixes:
|
||||
- Fixed derived C++ builds by removing `MDBX_INTERNAL_FUNC` for `mdbx_w2mb()` and `mdbx_mb2w()`.
|
||||
|
||||
|
||||
## v0.11.10 (the TriColor) at 2022-08-22
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.10 "the TriColor" at 2022-08-22
|
||||
|
||||
The stable bugfix release.
|
||||
|
||||
@@ -455,8 +634,10 @@ Minors:
|
||||
- Minor clarified `iov_page()` failure case.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
## v0.11.9 (Чирчик-1992) at 2022-08-02
|
||||
|
||||
## v0.11.9 "Чирчик-1992" at 2022-08-02
|
||||
|
||||
The stable bugfix release.
|
||||
|
||||
@@ -465,7 +646,7 @@ The stable bugfix release.
|
||||
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
|
||||
```
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) and Erigon team for reporting and testing.
|
||||
- [Andrew Ashikhmin](https://gitflic.ru/user/yperbasis) for contributing.
|
||||
@@ -497,11 +678,11 @@ Minors:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.8 (Baked Apple) at 2022-06-12
|
||||
## v0.11.8 "Baked Apple" at 2022-06-12
|
||||
|
||||
The stable release with an important fixes and workaround for the critical macOS thread-local-storage issue.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Masatoshi Fukunaga](https://github.com/mah0x211) for [Lua bindings](https://github.com/mah0x211/lua-libmdbx).
|
||||
|
||||
@@ -550,7 +731,7 @@ Minors:
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.7 (Resurrected Sarmat) at 2022-04-22
|
||||
## v0.11.7 "Resurrected Sarmat" at 2022-04-22
|
||||
|
||||
The stable risen release after the Github's intentional malicious disaster.
|
||||
|
||||
@@ -596,7 +777,7 @@ Minors:
|
||||
- Switched to using `MDBX_EPERM` instead of `MDBX_RESULT_TRUE` to indicate that the geometry cannot be updated.
|
||||
- Added `NULL` checking during memory allocation inside `mdbx_chk`.
|
||||
- Resolved all warnings from MinGW while used without CMake.
|
||||
- Added inheretable `target_include_directories()` to `CMakeLists.txt` for easy integration.
|
||||
- Added inheritable `target_include_directories()` to `CMakeLists.txt` for easy integration.
|
||||
- Added build-time checks and paranoid runtime assertions for the `off_t` arguments of `fcntl()` which are used for locking.
|
||||
- Added `-Wno-lto-type-mismatch` to avoid false-positive warnings from old GCC during LTO-enabled builds.
|
||||
- Added checking for TID (system thread id) to avoid hang on 32-bit Bionic/Android within `pthread_mutex_lock()`.
|
||||
@@ -613,7 +794,7 @@ The stable release with the complete workaround for an incoherence flaw of Linux
|
||||
Nonetheless the cause for this trouble may be an issue of Intel CPU cache/MESI.
|
||||
See [issue#269](https://libmdbx.dqdkfa.ru/dead-github/issues/269) for more information.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [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.
|
||||
@@ -633,12 +814,15 @@ Minors:
|
||||
- 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://libmdbx.dqdkfa.ru/dead-github/issues/269) for more information.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [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/).
|
||||
@@ -662,11 +846,14 @@ Minors:
|
||||
- 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.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Ledgerwatch](https://github.com/ledgerwatch), [Binance](https://github.com/binance-chain) and [Positive Technologies](https://www.ptsecurity.com/) teams for reporting, assistance in investigation and testing.
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) for reporting, testing and provide resources for remote debugging/investigation.
|
||||
@@ -707,9 +894,12 @@ Minors:
|
||||
- Using the `-fno-semantic interposition` option to reduce the overhead to calling self own public functions.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.3 at 2021-12-31
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [gcxfd <i@rmw.link>](https://github.com/gcxfd) for reporting, contributing and testing.
|
||||
- [장세연 (Чан Се Ен)](https://github.com/sasgas) for reporting and testing.
|
||||
@@ -740,9 +930,12 @@ Minors:
|
||||
- For compatibility reverted returning `MDBX_ENODATA`for some cases.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.2 at 2021-12-02
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [장세연 (Чан Се Ен)](https://github.com/sasgas) for contributing to C++ API.
|
||||
- [Alain Picard](https://github.com/castortech) for [Java bindings](https://github.com/castortech/mdbxjni).
|
||||
@@ -766,6 +959,9 @@ Minors:
|
||||
- Remove unneeded `#undef P_DIRTY`.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.11.1 at 2021-10-23
|
||||
|
||||
### Backward compatibility break:
|
||||
@@ -780,12 +976,12 @@ This change is mostly invisible:
|
||||
- previously versions are unable to read/write a new DBs;
|
||||
- but the new release is able to handle an old DBs and will silently upgrade ones.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) for reporting and testing.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
===============================================================================
|
||||
|
||||
|
||||
## v0.10.5 at 2021-10-13 (obsolete, please use v0.11.1)
|
||||
@@ -798,7 +994,7 @@ Unfortunately, the `v0.10.5` accidentally comes not full-compatible with previou
|
||||
This cannot be fixed, as it requires fixing past versions, which as a result we will just get a current version.
|
||||
Therefore, it is recommended to use `v0.11.1` instead of `v0.10.5`.
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Noel Kuntze](https://github.com/Thermi) for immediately bug reporting.
|
||||
|
||||
@@ -814,9 +1010,12 @@ Minors:
|
||||
- Refined providing information for the `@MAIN` and `@GC` sub-databases of a last committed modification transaction's ID.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.10.4 at 2021-10-10
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Artem Vorotnikov](https://github.com/vorot93) for support [Rust wrapper](https://github.com/vorot93/libmdbx-rs).
|
||||
- [Andrew Ashikhmin](https://github.com/yperbasis) for contributing to C++ API.
|
||||
@@ -834,9 +1033,12 @@ Minors:
|
||||
- In debugging builds fixed a too small (single page) by default DB shrink threshold.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.10.3 at 2021-08-27
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Francisco Vallarino](https://github.com/fjvallarino) for [Haskell bindings for libmdbx](https://hackage.haskell.org/package/libmdbx).
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) for reporting and testing.
|
||||
@@ -862,9 +1064,12 @@ Minors:
|
||||
- Fixed CMake warning about compatibility with 3.8.2
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.10.2 at 2021-07-26
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) for reporting and testing.
|
||||
- [Andrea Lanfranchi](https://github.com/AndreaLanfranchi) for reporting bugs.
|
||||
@@ -909,9 +1114,12 @@ Fixes:
|
||||
- Fixed [test framework keygen-related issue](https://libmdbx.dqdkfa.ru/dead-github/issues/127).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.10.1 at 2021-06-01
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Alexey Akhunov](https://github.com/AlexeyAkhunov) and [Alex Sharov](https://github.com/AskAlexSharov) for bug reporting and testing.
|
||||
- [Andrea Lanfranchi](https://github.com/AndreaLanfranchi) for bug reporting and testing related to WSL2.
|
||||
@@ -933,9 +1141,12 @@ Fixes:
|
||||
- Re-Fixed WSL1/WSL2 detection with distinguishing (https://libmdbx.dqdkfa.ru/dead-github/issues/97).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.10.0 at 2021-05-09
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Mahlon E. Smith](https://github.com/mahlonsmith) for [Ruby bindings](https://rubygems.org/gems/mdbx/).
|
||||
- [Alex Sharov](https://github.com/AskAlexSharov) for [mdbx-go](https://github.com/torquem-ch/mdbx-go), bug reporting and testing.
|
||||
@@ -1019,12 +1230,12 @@ Fixes:
|
||||
- Fixed building by MinGW for Windows (https://libmdbx.dqdkfa.ru/dead-github/issues/155).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
===============================================================================
|
||||
|
||||
|
||||
## v0.9.3 at 2021-02-02
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- [Mahlon E. Smith](http://www.martini.nu/) for [FreeBSD port of libmdbx](https://svnweb.freebsd.org/ports/head/databases/mdbx/).
|
||||
- [장세연](http://www.castis.com) for bug fixing and PR.
|
||||
@@ -1080,9 +1291,12 @@ Fixes:
|
||||
- Fixed operation on systems with unusual small/large page size, including PowerPC (https://libmdbx.dqdkfa.ru/dead-github/issues/157).
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.9.2 at 2020-11-27
|
||||
|
||||
Acknowledgements:
|
||||
Acknowledgments:
|
||||
|
||||
- Jens Alfke (Mobile Architect at [Couchbase](https://www.couchbase.com/)) for [NimDBX](https://github.com/snej/nimdbx).
|
||||
- Clément Renault (CTO at [MeiliSearch](https://www.meilisearch.com/)) for [mdbx-rs](https://github.com/Kerollmops/mdbx-rs).
|
||||
@@ -1130,6 +1344,9 @@ Fixes:
|
||||
- Added handling `EXCEPTION_POSSIBLE_DEADLOCK` condition for Windows.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.9.1 2020-09-30
|
||||
|
||||
Added features:
|
||||
@@ -1172,10 +1389,13 @@ Fixes:
|
||||
- Fix a lot of typos & spelling (Thanks to Josh Soref for PR).
|
||||
- Fix `getopt()` messages for Windows (Thanks to Andrey Sporaw for reporting).
|
||||
- Fix MSVC compiler version requirements (Thanks to Andrey Sporaw for reporting).
|
||||
- Workarounds for QEMU's bugs to run tests for cross-builded library under QEMU.
|
||||
- Workarounds for QEMU's bugs to run tests for cross-built[A library under QEMU.
|
||||
- Now C++ compiler optional for building by CMake.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
|
||||
## v0.9.0 2020-07-31 (not a release, but API changes)
|
||||
|
||||
Added features:
|
||||
@@ -1189,7 +1409,7 @@ Deprecated functions and flags:
|
||||
Please use the value-to-key functions to provide keys that are compatible with the built-in libmdbx comparators.
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
===============================================================================
|
||||
|
||||
|
||||
## 2020-07-06
|
||||
@@ -1241,7 +1461,7 @@ Deprecated functions and flags:
|
||||
- Avoid using `pwritev()` for single-writes (up to 10% speedup for some kernels & scenarios).
|
||||
- Avoiding `MDBX_UTTERLY_NOSYNC` as result of flags merge.
|
||||
- Add `mdbx_dbi_dupsort_depthmask()` function.
|
||||
- Add `MDBX_CP_FORCE_RESIZEABLE` option.
|
||||
- Add `MDBX_CP_FORCE_RESIZABLE` option.
|
||||
- Add deprecated `MDBX_MAP_RESIZED` for compatibility.
|
||||
- Add `MDBX_BUILD_TOOLS` option (default `ON`).
|
||||
- Refine `mdbx_dbi_open_ex()` to safe concurrently opening the same handle from different threads.
|
||||
@@ -1329,6 +1549,8 @@ Deprecated functions and flags:
|
||||
- API description.
|
||||
- Checking for non-local filesystems to avoid DB corruption.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
===============================================================================
|
||||
|
||||
|
||||
For early changes see the git commit history.
|
||||
|
||||
24
GNUmakefile
24
GNUmakefile
@@ -6,7 +6,7 @@
|
||||
#
|
||||
################################################################################
|
||||
#
|
||||
# Basic internal definitios. For a customizable variables and options see below.
|
||||
# Basic internal definitions. For a customizable variables and options see below.
|
||||
#
|
||||
$(info // The GNU Make $(MAKE_VERSION))
|
||||
SHELL := $(shell env bash -c 'echo $$BASH')
|
||||
@@ -715,23 +715,23 @@ endif
|
||||
################################################################################
|
||||
# Cross-compilation simple test
|
||||
|
||||
CROSS_LIST = mips-linux-gnu-gcc \
|
||||
CROSS_LIST = \
|
||||
mips64-linux-gnuabi64-gcc mips-linux-gnu-gcc \
|
||||
hppa-linux-gnu-gcc s390x-linux-gnu-gcc \
|
||||
powerpc64-linux-gnu-gcc powerpc-linux-gnu-gcc \
|
||||
arm-linux-gnueabihf-gcc aarch64-linux-gnu-gcc \
|
||||
sh4-linux-gnu-gcc mips64-linux-gnuabi64-gcc \
|
||||
hppa-linux-gnu-gcc s390x-linux-gnu-gcc
|
||||
arm-linux-gnueabihf-gcc aarch64-linux-gnu-gcc
|
||||
|
||||
## On Ubuntu Focal (20.04) with QEMU 4.2 (1:4.2-3ubuntu6.6) & GCC 9.3 (9.3.0-17ubuntu1~20.04)
|
||||
# hppa-linux-gnu-gcc - works (previously: don't supported by qemu)
|
||||
# s390x-linux-gnu-gcc - works (previously: qemu hang/abort)
|
||||
## On Ubuntu Focal (22.04) with QEMU 6.2 (1:6.2+dfsg-2ubuntu6.6) & GCC 11.3 (11.3.0-1ubuntu1~22.04)
|
||||
# sh4-linux-gnu-gcc - coredump (qemu mmap-troubles)
|
||||
# sparc64-linux-gnu-gcc - coredump (qemu mmap-troubles, previously: qemu fails fcntl for F_SETLK/F_GETLK)
|
||||
# alpha-linux-gnu-gcc - coredump (qemu mmap-troubles)
|
||||
CROSS_LIST_NOQEMU = sparc64-linux-gnu-gcc alpha-linux-gnu-gcc riscv64-linux-gnu-gcc
|
||||
# risc64-linux-gnu-gcc - coredump (qemu qemu fails fcntl for F_SETLK/F_GETLK)
|
||||
CROSS_LIST_NOQEMU = sh4-linux-gnu-gcc sparc64-linux-gnu-gcc alpha-linux-gnu-gcc riscv64-linux-gnu-gcc
|
||||
|
||||
cross-gcc:
|
||||
@echo ' Re-building by cross-compiler for: $(CROSS_LIST_NOQEMU) $(CROSS_LIST)'
|
||||
@echo "CORRESPONDING CROSS-COMPILERs ARE REQUIRED."
|
||||
@echo "FOR INSTANCE: apt install g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu g++-sparc64-linux-gnu riscv64-linux-gnu-gcc"
|
||||
@echo "FOR INSTANCE: sudo apt install \$$(apt list 'g++-*' | grep 'g++-[a-z0-9]\+-linux-gnu/' | cut -f 1 -d / | sort -u)"
|
||||
$(QUIET)for CC in $(CROSS_LIST_NOQEMU) $(CROSS_LIST); do \
|
||||
echo "===================== $$CC"; \
|
||||
$(MAKE) IOARENA=false CXXSTD= clean && CC=$$CC CXX=$$(echo $$CC | sed 's/-gcc/-g++/') EXE_LDFLAGS=-static $(MAKE) IOARENA=false all || exit $$?; \
|
||||
@@ -743,8 +743,8 @@ cross-qemu:
|
||||
@echo ' Re-building by cross-compiler and re-check by QEMU for: $(CROSS_LIST)'
|
||||
@echo "CORRESPONDING CROSS-COMPILERs AND QEMUs ARE REQUIRED."
|
||||
@echo "FOR INSTANCE: "
|
||||
@echo " 1) apt install g++-aarch64-linux-gnu g++-alpha-linux-gnu g++-arm-linux-gnueabihf g++-hppa-linux-gnu g++-mips-linux-gnu g++-mips64-linux-gnuabi64 g++-powerpc-linux-gnu g++-powerpc64-linux-gnu g++-s390x-linux-gnu g++-sh4-linux-gnu g++-sparc64-linux-gnu"
|
||||
@echo " 2) apt install binfmt-support qemu-user-static qemu-user qemu-system-arm qemu-system-mips qemu-system-misc qemu-system-ppc qemu-system-sparc"
|
||||
@echo " 1) sudo apt install \$$(apt list 'g++-*' | grep 'g++-[a-z0-9]\+-linux-gnu/' | cut -f 1 -d / | sort -u)"
|
||||
@echo " 2) sudo apt install binfmt-support qemu-user-static qemu-user \$$(apt list 'qemu-system-*' | grep 'qemu-system-[a-z0-9]\+/' | cut -f 1 -d / | sort -u)"
|
||||
$(QUIET)for CC in $(CROSS_LIST); do \
|
||||
echo "===================== $$CC + qemu"; \
|
||||
$(MAKE) IOARENA=false CXXSTD= clean && \
|
||||
|
||||
41
README.md
41
README.md
@@ -81,19 +81,48 @@ Historically, _libmdbx_ is a deeply revised and extended descendant of the amazi
|
||||
[Lightning Memory-Mapped Database](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database).
|
||||
_libmdbx_ inherits all benefits from _LMDB_, but resolves some issues and adds [a set of improvements](#improvements-beyond-lmdb).
|
||||
|
||||
### MithrilDB and Future
|
||||
|
||||
<!-- section-begin mithril -->
|
||||
|
||||
The next version is under active non-public development from scratch and will be
|
||||
The next version is under non-public development from scratch and will be
|
||||
released as **MithrilDB** and `libmithrildb` for libraries & packages.
|
||||
Admittedly mythical [Mithril](https://en.wikipedia.org/wiki/Mithril) is
|
||||
resembling silver but being stronger and lighter than steel. Therefore
|
||||
_MithrilDB_ is a rightly relevant name.
|
||||
|
||||
> _MithrilDB_ will be radically different from _libmdbx_ by the new
|
||||
> database format and API based on C++17, as well as the [Apache 2.0
|
||||
> License](https://www.apache.org/licenses/LICENSE-2.0). The goal of this
|
||||
> revolution is to provide a clearer and robust API, add more features and
|
||||
> new valuable properties of the database.
|
||||
_MithrilDB_ is radically different from _libmdbx_ by the new database
|
||||
format and API based on C++20. The goal of this revolution is to provide
|
||||
a clearer and robust API, add more features and new valuable properties
|
||||
of the database. All fundamental architectural problems of libmdbx/LMDB
|
||||
have been solved there, but now the active development has been
|
||||
suspended for top-three reasons:
|
||||
|
||||
1. For now _libmdbx_ «mostly» enough for all [our products](https://www.ptsecurity.com/ww-en/products/),
|
||||
and I’m busy in development of replication for scalability.
|
||||
2. Waiting for fresh [Elbrus CPU](https://wiki.elbrus.ru/) of [e2k architecture](https://en.wikipedia.org/wiki/Elbrus_2000),
|
||||
especially with hardware acceleration of [Streebog](https://en.wikipedia.org/wiki/Streebog) and
|
||||
[Kuznyechik](https://en.wikipedia.org/wiki/Kuznyechik), which are required for Merkle tree, etc.
|
||||
3. The expectation of needs and opportunities due to the wide use of NVDIMM (aka persistent memory),
|
||||
modern NVMe and [Ангара](https://ru.wikipedia.org/wiki/Ангара_(интерконнект)).
|
||||
|
||||
However, _MithrilDB_ will not be available for countries unfriendly to
|
||||
Russia (i.e. acceded the sanctions, devil adepts and/or NATO). But it is
|
||||
not yet known whether such restriction will be implemented only through
|
||||
a license and support, either the source code will not be open at all.
|
||||
Basically we are not inclined to allow our work to contribute to the
|
||||
profit that goes to weapons that kill our relatives and friends.
|
||||
NO OPTIONS.
|
||||
|
||||
Nonetheless, I try not to make any promises regarding _MithrilDB_ until release.
|
||||
|
||||
Contrary to _MithrilDB_, _libmdbx_ will forever free and open source.
|
||||
Moreover with high-quality support whenever possible. Tu deviens
|
||||
responsable pour toujours de ce que tu as apprivois. So we will continue
|
||||
to comply with the original open license and the principles of
|
||||
constructive cooperation, in spite of outright Github sabotage and
|
||||
sanctions. I will also try to keep (not drop) Windows support, despite
|
||||
it is an unused obsolete technology for us.
|
||||
|
||||
<!-- section-end -->
|
||||
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Copyright (c) 2012-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
## Copyright (c) 2012-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
@@ -348,6 +348,8 @@ endif()
|
||||
|
||||
if(MSVC)
|
||||
check_compiler_flag("/WX" CC_HAS_WERROR)
|
||||
check_compiler_flag("/fsanitize=address" CC_HAS_ASAN)
|
||||
check_compiler_flag("/fsanitize=undefined" CC_HAS_UBSAN)
|
||||
else()
|
||||
#
|
||||
# GCC started to warn for unused result starting from 4.2, and
|
||||
@@ -839,19 +841,26 @@ macro(setup_compile_flags)
|
||||
endif()
|
||||
|
||||
if(ENABLE_ASAN)
|
||||
add_compile_flags("C;CXX" "-fsanitize=address")
|
||||
if(NOT MSVC)
|
||||
add_compile_flags("C;CXX" "-fsanitize=address")
|
||||
else()
|
||||
add_compile_flags("C;CXX" "/fsanitize=address")
|
||||
endif()
|
||||
add_definitions(-DASAN_ENABLED=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_UBSAN)
|
||||
add_compile_flags("C;CXX" "-fsanitize=undefined" "-fsanitize-undefined-trap-on-error")
|
||||
if(NOT MSVC)
|
||||
add_compile_flags("C;CXX" "-fsanitize=undefined" "-fsanitize-undefined-trap-on-error")
|
||||
else()
|
||||
add_compile_flags("C;CXX" "/fsanitize=undefined")
|
||||
endif()
|
||||
add_definitions(-DUBSAN_ENABLED=1)
|
||||
endif()
|
||||
|
||||
if(ENABLE_GCOV)
|
||||
if(NOT HAVE_GCOV)
|
||||
message(FATAL_ERROR
|
||||
"ENABLE_GCOV option requested but gcov library is not found")
|
||||
message(FATAL_ERROR "ENABLE_GCOV option requested but gcov library is not found")
|
||||
endif()
|
||||
|
||||
add_compile_flags("C;CXX" "-fprofile-arcs" "-ftest-coverage")
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Copyright (c) 2012-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
## Copyright (c) 2012-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
## Copyright (c) 2012-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
## Copyright (c) 2012-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
##
|
||||
## Licensed under the Apache License, Version 2.0 (the "License");
|
||||
## you may not use this file except in compliance with the License.
|
||||
|
||||
@@ -67,7 +67,7 @@ the end is hit.
|
||||
To retrieve all keys starting from a specified key value, use \ref MDBX_SET. For
|
||||
more cursor operations, see the \ref c_api reference.
|
||||
|
||||
When using \ref mdbx_cursor_put()\ref , either the function will position the cursor
|
||||
When using \ref mdbx_cursor_put(), either the function will position the cursor
|
||||
for you based on the key, or you can use operation \ref MDBX_CURRENT to use the
|
||||
current position of the cursor. \note Note that key must then match the current
|
||||
position's key.
|
||||
|
||||
@@ -38,4 +38,4 @@ including creating [merge-request](https://gitflic.ru/project/erthink/libmdbx/me
|
||||
|
||||
---
|
||||
|
||||
\section MithrilDB MithrilDB
|
||||
\section MithrilDB MithrilDB and Future
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2017 Ilya Shipitsin <chipitsine@gmail.com>.
|
||||
* Copyright 2012-2015 Howard Chu, Symas Corp.
|
||||
* All rights reserved.
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2012-2015 Howard Chu, Symas Corp.
|
||||
* Copyright 2015,2016 Peter-Service R&D LLC.
|
||||
* All rights reserved.
|
||||
|
||||
83
mdbx.h
83
mdbx.h
@@ -25,7 +25,7 @@ _The Future will (be) [Positive](https://www.ptsecurity.com). Всё будет
|
||||
|
||||
\section copyright LICENSE & COPYRIGHT
|
||||
|
||||
\authors Copyright (c) 2015-2022, Leonid Yuriev <leo@yuriev.ru>
|
||||
\authors Copyright (c) 2015-2023, Leonid Yuriev <leo@yuriev.ru>
|
||||
and other _libmdbx_ authors: please see [AUTHORS](./AUTHORS) file.
|
||||
|
||||
\copyright Redistribution and use in source and binary forms, with or without
|
||||
@@ -695,11 +695,11 @@ extern LIBMDBX_VERINFO_API const struct MDBX_build_info {
|
||||
* automatically (de)initialization, releasing reader lock table slots
|
||||
* and so on.
|
||||
*
|
||||
* If MDBX builded as a DLL this is done out-of-the-box by DllEntry() function,
|
||||
* If MDBX built as a DLL this is done out-of-the-box by DllEntry() function,
|
||||
* which called automatically by Windows core with passing corresponding reason
|
||||
* argument.
|
||||
*
|
||||
* Otherwise, if MDBX was builded not as a DLL, some black magic
|
||||
* Otherwise, if MDBX was built not as a DLL, some black magic
|
||||
* may be required depending of Windows version:
|
||||
*
|
||||
* - Modern Windows versions, including Windows Vista and later, provides
|
||||
@@ -881,7 +881,7 @@ enum MDBX_constants {
|
||||
/* DEBUG & LOGGING ************************************************************/
|
||||
|
||||
/** \addtogroup c_debug
|
||||
* \note Most of debug feature enabled only when libmdbx builded with
|
||||
* \note Most of debug feature enabled only when libmdbx built with
|
||||
* \ref MDBX_DEBUG build option. @{ */
|
||||
|
||||
/** Log level
|
||||
@@ -946,7 +946,7 @@ typedef enum MDBX_log_level_t MDBX_log_level_t;
|
||||
*
|
||||
* \details `MDBX_DBG_DUMP` and `MDBX_DBG_LEGACY_MULTIOPEN` always have an
|
||||
* effect, but `MDBX_DBG_ASSERT`, `MDBX_DBG_AUDIT` and `MDBX_DBG_JITTER` only if
|
||||
* libmdbx builded with \ref MDBX_DEBUG. */
|
||||
* libmdbx built with \ref MDBX_DEBUG. */
|
||||
enum MDBX_debug_flags_t {
|
||||
MDBX_DBG_NONE = 0,
|
||||
|
||||
@@ -1682,7 +1682,7 @@ enum MDBX_copy_flags_t {
|
||||
* pages sequentially */
|
||||
MDBX_CP_COMPACT = 1u,
|
||||
|
||||
/** Force to make resizeable copy, i.e. dynamic size instead of fixed */
|
||||
/** Force to make resizable copy, i.e. dynamic size instead of fixed */
|
||||
MDBX_CP_FORCE_DYNAMIC_SIZE = 2u
|
||||
};
|
||||
#ifndef __cplusplus
|
||||
@@ -2060,7 +2060,9 @@ LIBMDBX_API const char *mdbx_strerror_r_ANSI2OEM(int errnum, char *buf,
|
||||
* \returns a non-zero error value on failure and 0 on success. */
|
||||
LIBMDBX_API int mdbx_env_create(MDBX_env **penv);
|
||||
|
||||
/** \brief MDBX environment options. */
|
||||
/** \brief MDBX environment extra runtime options.
|
||||
* \ingroup c_settings
|
||||
* \see mdbx_env_set_option() \see mdbx_env_get_option() */
|
||||
enum MDBX_option_t {
|
||||
/** \brief Controls the maximum number of named databases for the environment.
|
||||
*
|
||||
@@ -2268,7 +2270,7 @@ enum MDBX_option_t {
|
||||
typedef enum MDBX_option_t MDBX_option_t;
|
||||
#endif
|
||||
|
||||
/** \brief Sets the value of a runtime options for an environment.
|
||||
/** \brief Sets the value of a extra runtime options for an environment.
|
||||
* \ingroup c_settings
|
||||
*
|
||||
* \param [in] env An environment handle returned by \ref mdbx_env_create().
|
||||
@@ -2281,7 +2283,7 @@ typedef enum MDBX_option_t MDBX_option_t;
|
||||
LIBMDBX_API int mdbx_env_set_option(MDBX_env *env, const MDBX_option_t option,
|
||||
uint64_t value);
|
||||
|
||||
/** \brief Gets the value of runtime options from an environment.
|
||||
/** \brief Gets the value of extra runtime options from an environment.
|
||||
* \ingroup c_settings
|
||||
*
|
||||
* \param [in] env An environment handle returned by \ref mdbx_env_create().
|
||||
@@ -2302,6 +2304,8 @@ LIBMDBX_API int mdbx_env_get_option(const MDBX_env *env,
|
||||
* be called later to discard the \ref MDBX_env handle and release associated
|
||||
* resources.
|
||||
*
|
||||
* \note On Windows the \ref mdbx_env_openW() is recommended to use.
|
||||
*
|
||||
* \param [in] env An environment handle returned
|
||||
* by \ref mdbx_env_create()
|
||||
*
|
||||
@@ -2369,8 +2373,11 @@ LIBMDBX_API int mdbx_env_get_option(const MDBX_env *env,
|
||||
LIBMDBX_API int mdbx_env_open(MDBX_env *env, const char *pathname,
|
||||
MDBX_env_flags_t flags, mdbx_mode_t mode);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LIBMDBX_API int mdbx_env_openW(MDBX_env *env, const wchar_t *pathnameW,
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||
/** \copydoc mdbx_env_open()
|
||||
* \note Available only on Windows.
|
||||
* \see mdbx_env_open() */
|
||||
LIBMDBX_API int mdbx_env_openW(MDBX_env *env, const wchar_t *pathname,
|
||||
MDBX_env_flags_t flags, mdbx_mode_t mode);
|
||||
#endif /* Windows */
|
||||
|
||||
@@ -2400,6 +2407,8 @@ typedef enum MDBX_env_delete_mode_t MDBX_env_delete_mode_t;
|
||||
/** \brief Delete the environment's files in a proper and multiprocess-safe way.
|
||||
* \ingroup c_extra
|
||||
*
|
||||
* \note On Windows the \ref mdbx_env_deleteW() is recommended to use.
|
||||
*
|
||||
* \param [in] pathname The pathname for the database or the directory in which
|
||||
* the database files reside.
|
||||
*
|
||||
@@ -2416,8 +2425,12 @@ typedef enum MDBX_env_delete_mode_t MDBX_env_delete_mode_t;
|
||||
* so no deletion was performed. */
|
||||
LIBMDBX_API int mdbx_env_delete(const char *pathname,
|
||||
MDBX_env_delete_mode_t mode);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathnameW,
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||
/** \copydoc mdbx_env_delete()
|
||||
* \note Available only on Windows.
|
||||
* \see mdbx_env_delete() */
|
||||
LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathname,
|
||||
MDBX_env_delete_mode_t mode);
|
||||
#endif /* Windows */
|
||||
|
||||
@@ -2430,6 +2443,8 @@ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathnameW,
|
||||
* parallel with write transactions, because it employs a read-only
|
||||
* transaction. See long-lived transactions under \ref restrictions section.
|
||||
*
|
||||
* \note On Windows the \ref mdbx_env_copyW() is recommended to use.
|
||||
*
|
||||
* \param [in] env An environment handle returned by mdbx_env_create().
|
||||
* It must have already been opened successfully.
|
||||
* \param [in] dest The pathname of a file in which the copy will reside.
|
||||
@@ -2449,12 +2464,16 @@ LIBMDBX_API int mdbx_env_deleteW(const wchar_t *pathnameW,
|
||||
* account skipping free pages.
|
||||
*
|
||||
* - \ref MDBX_CP_FORCE_DYNAMIC_SIZE
|
||||
* Force to make resizeable copy, i.e. dynamic size instead of fixed.
|
||||
* Force to make resizable copy, i.e. dynamic size instead of fixed.
|
||||
*
|
||||
* \returns A non-zero error value on failure and 0 on success. */
|
||||
LIBMDBX_API int mdbx_env_copy(MDBX_env *env, const char *dest,
|
||||
MDBX_copy_flags_t flags);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||
/** \copydoc mdbx_env_copy()
|
||||
* \note Available only on Windows.
|
||||
* \see mdbx_env_copy() */
|
||||
LIBMDBX_API int mdbx_env_copyW(MDBX_env *env, const wchar_t *dest,
|
||||
MDBX_copy_flags_t flags);
|
||||
#endif /* Windows */
|
||||
@@ -2907,7 +2926,7 @@ enum MDBX_warmup_flags_t {
|
||||
MDBX_warmup_lock = 4,
|
||||
|
||||
/** Alters corresponding current resource limits to be enough for lock pages
|
||||
* by \ref MDBX_warmup_lock. However, this option should be used in simpliest
|
||||
* by \ref MDBX_warmup_lock. However, this option should be used in simpler
|
||||
* applications since takes into account only current size of this environment
|
||||
* disregarding all other factors. For real-world database application you
|
||||
* will need full-fledged management of resources and their limits with
|
||||
@@ -2943,7 +2962,7 @@ DEFINE_ENUM_FLAG_OPERATORS(MDBX_warmup_flags_t)
|
||||
* \param [in] timeout_seconds_16dot16 Optional timeout which checking only
|
||||
* during explicitly peeking database pages
|
||||
* for loading ones if the \ref MDBX_warmup_force
|
||||
* option was spefified.
|
||||
* option was specified.
|
||||
*
|
||||
* \returns A non-zero error value on failure and 0 on success.
|
||||
* Some possible errors are:
|
||||
@@ -2995,6 +3014,8 @@ LIBMDBX_API int mdbx_env_get_flags(const MDBX_env *env, unsigned *flags);
|
||||
/** \brief Return the path that was used in mdbx_env_open().
|
||||
* \ingroup c_statinfo
|
||||
*
|
||||
* \note On Windows the \ref mdbx_env_get_pathW() is recommended to use.
|
||||
*
|
||||
* \param [in] env An environment handle returned by \ref mdbx_env_create()
|
||||
* \param [out] dest Address of a string pointer to contain the path.
|
||||
* This is the actual string in the environment, not a
|
||||
@@ -3003,9 +3024,12 @@ LIBMDBX_API int mdbx_env_get_flags(const MDBX_env *env, unsigned *flags);
|
||||
* \returns A non-zero error value on failure and 0 on success,
|
||||
* some possible errors are:
|
||||
* \retval MDBX_EINVAL An invalid parameter was specified. */
|
||||
#if !(defined(_WIN32) || defined(_WIN64))
|
||||
LIBMDBX_API int mdbx_env_get_path(const MDBX_env *env, const char **dest);
|
||||
#else
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||
/** \copydoc mdbx_env_get_path()
|
||||
* \note Available only on Windows.
|
||||
* \see mdbx_env_get_path() */
|
||||
LIBMDBX_API int mdbx_env_get_pathW(const MDBX_env *env, const wchar_t **dest);
|
||||
#endif /* Windows */
|
||||
|
||||
@@ -3033,6 +3057,8 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
|
||||
* it is reasonable to know some details in order to make optimal decisions
|
||||
* when choosing parameters.
|
||||
*
|
||||
* \see mdbx_env_info_ex()
|
||||
*
|
||||
* Both \ref mdbx_env_set_geometry() and legacy \ref mdbx_env_set_mapsize() are
|
||||
* inapplicable to read-only opened environment.
|
||||
*
|
||||
@@ -3071,7 +3097,7 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
|
||||
* was called after \ref mdbx_env_open() but OUTSIDE a write transaction,
|
||||
* then MDBX will execute internal pseudo-transaction to apply new parameters
|
||||
* (but only if anything has been changed), and changes be visible to any
|
||||
* others processes immediately after succesful completion of function.
|
||||
* others processes immediately after successful completion of function.
|
||||
*
|
||||
* Essentially a concept of "automatic size management" is simple and useful:
|
||||
* - There are the lower and upper bounds of the database file size;
|
||||
@@ -3142,7 +3168,7 @@ LIBMDBX_API int mdbx_env_get_fd(const MDBX_env *env, mdbx_filehandle_t *fd);
|
||||
* \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
|
||||
* size of the system virtual memory management unit. You can get actual values
|
||||
* by \ref mdbx_env_sync_ex() or see by using the tool `mdbx_chk` with the `-v`
|
||||
* by \ref mdbx_env_info_ex() or see by using the tool `mdbx_chk` with the `-v`
|
||||
* option.
|
||||
*
|
||||
* Legacy \ref mdbx_env_set_mapsize() correspond to calling
|
||||
@@ -5265,7 +5291,7 @@ mdbx_get_datacmp(MDBX_db_flags_t flags);
|
||||
* \param [in] thread The reader thread ID.
|
||||
* \param [in] bytes_used The number of last used page
|
||||
* in the MVCC-snapshot which being read,
|
||||
* i.e. database file can't shrinked beyond this.
|
||||
* i.e. database file can't be shrunk beyond this.
|
||||
* \param [in] bytes_retained The total size of the database pages that were
|
||||
* retired by committed write transactions after
|
||||
* the reader's MVCC-snapshot,
|
||||
@@ -5511,13 +5537,20 @@ LIBMDBX_API int mdbx_env_pgwalk(MDBX_txn *txn, MDBX_pgvisitor_func *visitor,
|
||||
*
|
||||
* This function mostly of internal API for `mdbx_chk` utility and subject to
|
||||
* change at any time. Do not use this function to avoid shooting your own
|
||||
* leg(s). */
|
||||
* leg(s).
|
||||
*
|
||||
* \note On Windows the \ref mdbx_env_open_for_recoveryW() is recommended
|
||||
* to use. */
|
||||
LIBMDBX_API int mdbx_env_open_for_recovery(MDBX_env *env, const char *pathname,
|
||||
unsigned target_meta,
|
||||
bool writeable);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(DOXYGEN)
|
||||
/** \copydoc mdbx_env_open_for_recovery()
|
||||
* \note Available only on Windows.
|
||||
* \see mdbx_env_open_for_recovery() */
|
||||
LIBMDBX_API int mdbx_env_open_for_recoveryW(MDBX_env *env,
|
||||
const wchar_t *pathnameW,
|
||||
const wchar_t *pathname,
|
||||
unsigned target_meta,
|
||||
bool writeable);
|
||||
#endif /* Windows */
|
||||
|
||||
279
mdbx.h++
279
mdbx.h++
@@ -1,7 +1,7 @@
|
||||
/// \file mdbx.h++
|
||||
/// \brief The libmdbx C++ API header file.
|
||||
///
|
||||
/// \author Copyright (c) 2020-2022, Leonid Yuriev <leo@yuriev.ru>.
|
||||
/// \author Copyright (c) 2020-2023, Leonid Yuriev <leo@yuriev.ru>.
|
||||
/// \copyright SPDX-License-Identifier: Apache-2.0
|
||||
///
|
||||
/// Tested with:
|
||||
@@ -84,6 +84,11 @@
|
||||
#include <experimental/filesystem>
|
||||
#endif
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
#include <chrono>
|
||||
#include <ratio>
|
||||
#endif
|
||||
|
||||
#include "mdbx.h"
|
||||
|
||||
#if (defined(__cpp_lib_bit_cast) && __cpp_lib_bit_cast >= 201806L) || \
|
||||
@@ -223,17 +228,18 @@
|
||||
#endif /* MDBX_CXX20_UNLIKELY */
|
||||
|
||||
#ifndef MDBX_HAVE_CXX20_CONCEPTS
|
||||
#if defined(DOXYGEN) || \
|
||||
(defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L)
|
||||
#if defined(__cpp_lib_concepts) && __cpp_lib_concepts >= 202002L
|
||||
#include <concepts>
|
||||
#define MDBX_HAVE_CXX20_CONCEPTS 1
|
||||
#elif defined(DOXYGEN)
|
||||
#define MDBX_HAVE_CXX20_CONCEPTS 1
|
||||
#else
|
||||
#define MDBX_HAVE_CXX20_CONCEPTS 0
|
||||
#endif /* <concepts> */
|
||||
#endif /* MDBX_HAVE_CXX20_CONCEPTS */
|
||||
|
||||
#ifndef MDBX_CXX20_CONCEPT
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS || defined(DOXYGEN)
|
||||
#define MDBX_CXX20_CONCEPT(CONCEPT, NAME) CONCEPT NAME
|
||||
#else
|
||||
#define MDBX_CXX20_CONCEPT(CONCEPT, NAME) typename NAME
|
||||
@@ -241,7 +247,7 @@
|
||||
#endif /* MDBX_CXX20_CONCEPT */
|
||||
|
||||
#ifndef MDBX_ASSERT_CXX20_CONCEPT_SATISFIED
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS || defined(DOXYGEN)
|
||||
#define MDBX_ASSERT_CXX20_CONCEPT_SATISFIED(CONCEPT, TYPE) \
|
||||
static_assert(CONCEPT<TYPE>)
|
||||
#else
|
||||
@@ -350,6 +356,9 @@ class cursor_managed;
|
||||
__cpp_lib_memory_resource >= 201603L && _GLIBCXX_USE_CXX11_ABI)
|
||||
/// \brief Default polymorphic allocator for modern code.
|
||||
using polymorphic_allocator = ::std::pmr::string::allocator_type;
|
||||
using default_allocator = polymorphic_allocator;
|
||||
#else
|
||||
using default_allocator = legacy_allocator;
|
||||
#endif /* __cpp_lib_memory_resource >= 201603L */
|
||||
|
||||
/// \brief Default singe-byte string.
|
||||
@@ -385,6 +394,11 @@ using path = ::std::wstring;
|
||||
using path = ::std::string;
|
||||
#endif /* mdbx::path */
|
||||
|
||||
#if __cplusplus >= 201103L || defined(DOXYGEN)
|
||||
/// \brief Duration in 1/65536 units of second.
|
||||
using duration = ::std::chrono::duration<unsigned, ::std::ratio<1, 65536>>;
|
||||
#endif /* Duration for C++11 */
|
||||
|
||||
/// \defgroup cxx_exceptions exceptions and errors
|
||||
/// @{
|
||||
|
||||
@@ -551,8 +565,11 @@ static MDBX_CXX14_CONSTEXPR size_t check_length(size_t headroom, size_t payload,
|
||||
/// \defgroup cxx_data slices and buffers
|
||||
/// @{
|
||||
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS
|
||||
#if MDBX_HAVE_CXX20_CONCEPTS || defined(DOXYGEN)
|
||||
|
||||
/** \concept MutableByteProducer
|
||||
* \interface MutableByteProducer
|
||||
* \brief MutableByteProducer C++20 concept */
|
||||
template <typename T>
|
||||
concept MutableByteProducer = requires(T a, char array[42]) {
|
||||
{ a.is_empty() } -> std::same_as<bool>;
|
||||
@@ -560,6 +577,9 @@ concept MutableByteProducer = requires(T a, char array[42]) {
|
||||
{ a.write_bytes(&array[0], size_t(42)) } -> std::same_as<char *>;
|
||||
};
|
||||
|
||||
/** \concept ImmutableByteProducer
|
||||
* \interface ImmutableByteProducer
|
||||
* \brief ImmutableByteProducer C++20 concept */
|
||||
template <typename T>
|
||||
concept ImmutableByteProducer = requires(const T &a, char array[42]) {
|
||||
{ a.is_empty() } -> std::same_as<bool>;
|
||||
@@ -567,6 +587,9 @@ concept ImmutableByteProducer = requires(const T &a, char array[42]) {
|
||||
{ a.write_bytes(&array[0], size_t(42)) } -> std::same_as<char *>;
|
||||
};
|
||||
|
||||
/** \concept SliceTranscoder
|
||||
* \interface SliceTranscoder
|
||||
* \brief SliceTranscoder C++20 concept */
|
||||
template <typename T>
|
||||
concept SliceTranscoder = ImmutableByteProducer<T> &&
|
||||
requires(const slice &source, const T &a) {
|
||||
@@ -2639,45 +2662,69 @@ public:
|
||||
return buffer(src, make_reference);
|
||||
}
|
||||
|
||||
static buffer key_from(const silo &&src) noexcept {
|
||||
static buffer key_from(silo &&src) noexcept {
|
||||
return buffer(::std::move(src));
|
||||
}
|
||||
|
||||
static buffer key_from(const double ieee754_64bit) {
|
||||
static buffer key_from_double(const double ieee754_64bit) {
|
||||
return wrap(::mdbx_key_from_double(ieee754_64bit));
|
||||
}
|
||||
|
||||
static buffer key_from(const double ieee754_64bit) {
|
||||
return key_from_double(ieee754_64bit);
|
||||
}
|
||||
|
||||
static buffer key_from(const double *ieee754_64bit) {
|
||||
return wrap(::mdbx_key_from_ptrdouble(ieee754_64bit));
|
||||
}
|
||||
|
||||
static buffer key_from(const uint64_t unsigned_int64) {
|
||||
static buffer key_from_u64(const uint64_t unsigned_int64) {
|
||||
return wrap(unsigned_int64);
|
||||
}
|
||||
|
||||
static buffer key_from(const int64_t signed_int64) {
|
||||
static buffer key_from(const uint64_t unsigned_int64) {
|
||||
return key_from_u64(unsigned_int64);
|
||||
}
|
||||
|
||||
static buffer key_from_i64(const int64_t signed_int64) {
|
||||
return wrap(::mdbx_key_from_int64(signed_int64));
|
||||
}
|
||||
|
||||
static buffer key_from(const int64_t signed_int64) {
|
||||
return key_from_i64(signed_int64);
|
||||
}
|
||||
|
||||
static buffer key_from_jsonInteger(const int64_t json_integer) {
|
||||
return wrap(::mdbx_key_from_jsonInteger(json_integer));
|
||||
}
|
||||
|
||||
static buffer key_from(const float ieee754_32bit) {
|
||||
static buffer key_from_float(const float ieee754_32bit) {
|
||||
return wrap(::mdbx_key_from_float(ieee754_32bit));
|
||||
}
|
||||
|
||||
static buffer key_from(const float ieee754_32bit) {
|
||||
return key_from_float(ieee754_32bit);
|
||||
}
|
||||
|
||||
static buffer key_from(const float *ieee754_32bit) {
|
||||
return wrap(::mdbx_key_from_ptrfloat(ieee754_32bit));
|
||||
}
|
||||
|
||||
static buffer key_from(const uint32_t unsigned_int32) {
|
||||
static buffer key_from_u32(const uint32_t unsigned_int32) {
|
||||
return wrap(unsigned_int32);
|
||||
}
|
||||
|
||||
static buffer key_from(const int32_t signed_int32) {
|
||||
static buffer key_from(const uint32_t unsigned_int32) {
|
||||
return key_from_u32(unsigned_int32);
|
||||
}
|
||||
|
||||
static buffer key_from_i32(const int32_t signed_int32) {
|
||||
return wrap(::mdbx_key_from_int32(signed_int32));
|
||||
}
|
||||
|
||||
static buffer key_from(const int32_t signed_int32) {
|
||||
return key_from_i32(signed_int32);
|
||||
}
|
||||
};
|
||||
|
||||
template <class ALLOCATOR, class CAPACITY_POLICY,
|
||||
@@ -3106,10 +3153,12 @@ public:
|
||||
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 =
|
||||
false ///< use subdirectory to place the DB files
|
||||
MDBX_env_flags_t make_flags(
|
||||
bool accede = true, ///< Allows accepting incompatible operating options
|
||||
///< in case the database is already being used by
|
||||
///< another process(es) \see MDBX_ACCEDE
|
||||
bool use_subdirectory =
|
||||
false ///< use subdirectory to place the DB files
|
||||
) const;
|
||||
static env::mode mode_from_flags(MDBX_env_flags_t) noexcept;
|
||||
static env::durability durability_from_flags(MDBX_env_flags_t) noexcept;
|
||||
@@ -3334,9 +3383,11 @@ public:
|
||||
|
||||
/// \brief Returns the maximum number of threads/reader slots for the
|
||||
/// environment.
|
||||
/// \see extra_runtime_option::max_readers
|
||||
inline unsigned max_readers() const;
|
||||
|
||||
/// \brief Returns the maximum number of named databases for the environment.
|
||||
/// \see extra_runtime_option::max_maps
|
||||
inline unsigned max_maps() const;
|
||||
|
||||
/// \brief Returns the application context associated with the environment.
|
||||
@@ -3348,59 +3399,117 @@ public:
|
||||
/// \brief Sets threshold to force flush the data buffers to disk, for
|
||||
/// non-sync durability modes.
|
||||
///
|
||||
/// The threshold value affects all processes which operates with given
|
||||
/// environment until the last process close environment or a new value will
|
||||
/// be settled.
|
||||
/// Data is always written to disk when \ref txn_managed::commit() is called,
|
||||
/// but the operating system may keep it buffered. MDBX always flushes the OS
|
||||
/// buffers upon commit as well, unless the environment was opened with \ref
|
||||
/// whole_fragile, \ref lazy_weak_tail or in part \ref
|
||||
/// half_synchronous_weak_last. The default is 0, than mean no any threshold
|
||||
/// checked, and no additional flush will be made.
|
||||
/// \details The threshold value affects all processes which operates with
|
||||
/// given environment until the last process close environment or a new value
|
||||
/// will be settled. Data is always written to disk when \ref
|
||||
/// txn_managed::commit() is called, but the operating system may keep it
|
||||
/// buffered. MDBX always flushes the OS buffers upon commit as well, unless
|
||||
/// the environment was opened with \ref whole_fragile, \ref lazy_weak_tail or
|
||||
/// in part \ref half_synchronous_weak_last.
|
||||
///
|
||||
/// The default is 0, than mean no any threshold checked, and no additional
|
||||
/// flush will be made.
|
||||
/// \see extra_runtime_option::sync_bytes
|
||||
inline env &set_sync_threshold(size_t bytes);
|
||||
|
||||
/// \brief Gets threshold used to force flush the data buffers to disk, for
|
||||
/// non-sync durability modes.
|
||||
///
|
||||
/// \copydetails set_sync_threshold()
|
||||
/// \see extra_runtime_option::sync_bytes
|
||||
inline size_t sync_threshold() const;
|
||||
|
||||
#if __cplusplus >= 201103L || defined(DOXYGEN)
|
||||
/// \brief Sets relative period since the last unsteady commit to force flush
|
||||
/// the data buffers to disk, for non-sync durability modes.
|
||||
///
|
||||
/// The relative period value affects all processes which operates with given
|
||||
/// environment until the last process close environment or a new value will
|
||||
/// be settled.
|
||||
/// Data is always written to disk when \ref txn_managed::commit() is called,
|
||||
/// but the operating system may keep it buffered. MDBX always flushes the OS
|
||||
/// buffers upon commit as well, unless the environment was opened with \ref
|
||||
/// whole_fragile, \ref lazy_weak_tail or in part \ref
|
||||
/// half_synchronous_weak_last. Settled period don't checked asynchronously,
|
||||
/// but only by the \ref txn_managed::commit() and \ref env::sync_to_disk()
|
||||
/// functions. Therefore, in cases where transactions are committed
|
||||
/// infrequently and/or irregularly, polling by \ref env::poll_sync_to_disk()
|
||||
/// may be a reasonable solution to timeout enforcement. The default is 0,
|
||||
/// than mean no any timeout checked, and no additional flush will be made.
|
||||
/// \details The relative period value affects all processes which operates
|
||||
/// with given environment until the last process close environment or a new
|
||||
/// value will be settled. Data is always written to disk when \ref
|
||||
/// txn_managed::commit() is called, but the operating system may keep it
|
||||
/// buffered. MDBX always flushes the OS buffers upon commit as well, unless
|
||||
/// the environment was opened with \ref whole_fragile, \ref lazy_weak_tail or
|
||||
/// in part \ref half_synchronous_weak_last. Settled period don't checked
|
||||
/// asynchronously, but only by the \ref txn_managed::commit() and \ref
|
||||
/// env::sync_to_disk() functions. Therefore, in cases where transactions are
|
||||
/// committed infrequently and/or irregularly, polling by \ref
|
||||
/// env::poll_sync_to_disk() may be a reasonable solution to timeout
|
||||
/// enforcement.
|
||||
///
|
||||
/// The default is 0, than mean no any timeout checked, and no additional
|
||||
/// flush will be made.
|
||||
/// \see extra_runtime_option::sync_period
|
||||
inline env &set_sync_period(const duration &period);
|
||||
|
||||
/// \brief Gets relative period since the last unsteady commit that used to
|
||||
/// force flush the data buffers to disk, for non-sync durability modes.
|
||||
/// \copydetails set_sync_period(const duration&)
|
||||
/// \see set_sync_period(const duration&)
|
||||
/// \see extra_runtime_option::sync_period
|
||||
inline duration sync_period() const;
|
||||
#endif
|
||||
|
||||
/// \copydoc set_sync_period(const duration&)
|
||||
/// \param [in] seconds_16dot16 The period in 1/65536 of second when a
|
||||
/// synchronous flush would be made since the last unsteady commit.
|
||||
inline env &set_sync_period(unsigned seconds_16dot16);
|
||||
inline env &set_sync_period__seconds_16dot16(unsigned seconds_16dot16);
|
||||
|
||||
/// \brief Sets relative period since the last unsteady commit to force flush
|
||||
/// the data buffers to disk, for non-sync durability modes.
|
||||
///
|
||||
/// The relative period value affects all processes which operates with given
|
||||
/// environment until the last process close environment or a new value will
|
||||
/// be settled.
|
||||
/// Data is always written to disk when \ref txn_managed::commit() is called,
|
||||
/// but the operating system may keep it buffered. MDBX always flushes the OS
|
||||
/// buffers upon commit as well, unless the environment was opened with \ref
|
||||
/// whole_fragile, \ref lazy_weak_tail or in part \ref
|
||||
/// half_synchronous_weak_last. Settled period don't checked asynchronously,
|
||||
/// but only by the \ref txn_managed::commit() and \ref env::sync_to_disk()
|
||||
/// functions. Therefore, in cases where transactions are committed
|
||||
/// infrequently and/or irregularly, polling by \ref env::poll_sync_to_disk()
|
||||
/// may be a reasonable solution to timeout enforcement. The default is 0,
|
||||
/// than mean no any timeout checked, and no additional flush will be made.
|
||||
///
|
||||
/// \copydoc sync_period()
|
||||
/// \see sync_period__seconds_16dot16(unsigned)
|
||||
inline unsigned sync_period__seconds_16dot16() const;
|
||||
|
||||
/// \copydoc set_sync_period(const duration&)
|
||||
/// \param [in] seconds The period in second when a synchronous flush would
|
||||
/// be made since the last unsteady commit.
|
||||
inline env &set_sync_period(double seconds);
|
||||
inline env &set_sync_period__seconds_double(double seconds);
|
||||
|
||||
/// \copydoc sync_period()
|
||||
/// \see set_sync_period__seconds_double(double)
|
||||
inline double sync_period__seconds_double() const;
|
||||
|
||||
/// \copydoc MDBX_option_t
|
||||
enum class extra_runtime_option {
|
||||
/// \copydoc MDBX_opt_max_db
|
||||
/// \see max_maps() \see env::operate_parameters::max_maps
|
||||
max_maps = MDBX_opt_max_db,
|
||||
/// \copydoc MDBX_opt_max_readers
|
||||
/// \see max_readers() \see env::operate_parameters::max_readers
|
||||
max_readers = MDBX_opt_max_readers,
|
||||
/// \copydoc MDBX_opt_sync_bytes
|
||||
/// \see sync_threshold() \see set_sync_threshold()
|
||||
sync_bytes = MDBX_opt_sync_bytes,
|
||||
/// \copydoc MDBX_opt_sync_period
|
||||
/// \see sync_period() \see set_sync_period()
|
||||
sync_period = MDBX_opt_sync_period,
|
||||
/// \copydoc MDBX_opt_rp_augment_limit
|
||||
rp_augment_limit = MDBX_opt_rp_augment_limit,
|
||||
/// \copydoc MDBX_opt_loose_limit
|
||||
loose_limit = MDBX_opt_loose_limit,
|
||||
/// \copydoc MDBX_opt_dp_reserve_limit
|
||||
dp_reserve_limit = MDBX_opt_dp_reserve_limit,
|
||||
/// \copydoc MDBX_opt_txn_dp_limit
|
||||
dp_limit = MDBX_opt_txn_dp_limit,
|
||||
/// \copydoc MDBX_opt_txn_dp_initial
|
||||
dp_initial = MDBX_opt_txn_dp_initial,
|
||||
/// \copydoc MDBX_opt_spill_max_denominator
|
||||
spill_max_denominator = MDBX_opt_spill_max_denominator,
|
||||
/// \copydoc MDBX_opt_spill_min_denominator
|
||||
spill_min_denominator = MDBX_opt_spill_min_denominator,
|
||||
/// \copydoc MDBX_opt_spill_parent4child_denominator
|
||||
spill_parent4child_denominator = MDBX_opt_spill_parent4child_denominator,
|
||||
/// \copydoc MDBX_opt_merge_threshold_16dot16_percent
|
||||
merge_threshold_16dot16_percent = MDBX_opt_merge_threshold_16dot16_percent,
|
||||
/// \copydoc MDBX_opt_writethrough_threshold
|
||||
writethrough_threshold = MDBX_opt_writethrough_threshold,
|
||||
/// \copydoc MDBX_opt_prefault_write_enable
|
||||
prefault_write_enable = MDBX_opt_prefault_write_enable,
|
||||
};
|
||||
|
||||
/// \copybrief mdbx_env_set_option()
|
||||
inline env &set_extra_option(extra_runtime_option option, uint64_t value);
|
||||
|
||||
/// \copybrief mdbx_env_get_option()
|
||||
inline uint64_t extra_option(extra_runtime_option option) const;
|
||||
|
||||
/// \brief Alter environment flags.
|
||||
inline env &alter_flags(MDBX_env_flags_t flags, bool on_off);
|
||||
@@ -3450,7 +3559,7 @@ public:
|
||||
/// transactions since the current read
|
||||
/// transaction started.
|
||||
size_t bytes_used; ///< The number of last used page in the MVCC-snapshot
|
||||
///< which being read, i.e. database file can't shrinked
|
||||
///< which being read, i.e. database file can't be shrunk
|
||||
///< beyond this.
|
||||
size_t bytes_retained; ///< The total size of the database pages that
|
||||
///< were retired by committed write transactions
|
||||
@@ -3591,7 +3700,7 @@ public:
|
||||
void close(bool dont_sync = false);
|
||||
|
||||
env_managed(env_managed &&) = default;
|
||||
env_managed &operator=(env_managed &&other) {
|
||||
env_managed &operator=(env_managed &&other) noexcept {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
@@ -3890,7 +3999,7 @@ 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 &&other) {
|
||||
txn_managed &operator=(txn_managed &&other) noexcept {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
@@ -4112,7 +4221,7 @@ public:
|
||||
void close();
|
||||
|
||||
cursor_managed(cursor_managed &&) = default;
|
||||
cursor_managed &operator=(cursor_managed &&other) {
|
||||
cursor_managed &operator=(cursor_managed &&other) noexcept {
|
||||
if (MDBX_UNLIKELY(handle_))
|
||||
MDBX_CXX20_UNLIKELY {
|
||||
assert(handle_ != other.handle_);
|
||||
@@ -5056,13 +5165,53 @@ inline env &env::set_sync_threshold(size_t bytes) {
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline env &env::set_sync_period(unsigned seconds_16dot16) {
|
||||
inline size_t env::sync_threshold() const {
|
||||
size_t bytes;
|
||||
error::success_or_throw(::mdbx_env_get_syncbytes(handle_, &bytes));
|
||||
return bytes;
|
||||
}
|
||||
|
||||
inline env &env::set_sync_period__seconds_16dot16(unsigned seconds_16dot16) {
|
||||
error::success_or_throw(::mdbx_env_set_syncperiod(handle_, seconds_16dot16));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline env &env::set_sync_period(double seconds) {
|
||||
return set_sync_period(unsigned(seconds * 65536));
|
||||
inline unsigned env::sync_period__seconds_16dot16() const {
|
||||
unsigned seconds_16dot16;
|
||||
error::success_or_throw(::mdbx_env_get_syncperiod(handle_, &seconds_16dot16));
|
||||
return seconds_16dot16;
|
||||
}
|
||||
|
||||
inline env &env::set_sync_period__seconds_double(double seconds) {
|
||||
return set_sync_period__seconds_16dot16(unsigned(seconds * 65536));
|
||||
}
|
||||
|
||||
inline double env::sync_period__seconds_double() const {
|
||||
return sync_period__seconds_16dot16() / 65536.0;
|
||||
}
|
||||
|
||||
#if __cplusplus >= 201103L
|
||||
inline env &env::set_sync_period(const duration &period) {
|
||||
return set_sync_period__seconds_16dot16(period.count());
|
||||
}
|
||||
|
||||
inline duration env::sync_period() const {
|
||||
return duration(sync_period__seconds_16dot16());
|
||||
}
|
||||
#endif
|
||||
|
||||
inline env &env::set_extra_option(enum env::extra_runtime_option option,
|
||||
uint64_t value) {
|
||||
error::success_or_throw(
|
||||
::mdbx_env_set_option(handle_, ::MDBX_option_t(option), value));
|
||||
return *this;
|
||||
}
|
||||
|
||||
inline uint64_t env::extra_option(enum env::extra_runtime_option option) const {
|
||||
uint64_t value;
|
||||
error::success_or_throw(
|
||||
::mdbx_env_get_option(handle_, ::MDBX_option_t(option), &value));
|
||||
return value;
|
||||
}
|
||||
|
||||
inline env &env::alter_flags(MDBX_env_flags_t flags, bool on_off) {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
42
src/base.h
42
src/base.h
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -572,17 +572,13 @@ __extern_C key_t ftok(const char *, int);
|
||||
|
||||
#ifndef __hot
|
||||
#if defined(__OPTIMIZE__)
|
||||
#if defined(__e2k__)
|
||||
#define __hot __attribute__((__hot__)) __optimize(3)
|
||||
#elif defined(__clang__) && !__has_attribute(__hot_) && \
|
||||
#if defined(__clang__) && !__has_attribute(__hot__) && \
|
||||
__has_attribute(__section__) && \
|
||||
(defined(__linux__) || defined(__gnu_linux__))
|
||||
/* just put frequently used functions in separate section */
|
||||
#define __hot __attribute__((__section__("text.hot"))) __optimize("O3")
|
||||
#elif defined(__LCC__)
|
||||
#define __hot __attribute__((__hot__, __optimize__("Ofast,O4")))
|
||||
#elif defined(__GNUC__) || __has_attribute(__hot__)
|
||||
#define __hot __attribute__((__hot__)) __optimize("O3")
|
||||
#define __hot __attribute__((__hot__))
|
||||
#else
|
||||
#define __hot __optimize("O3")
|
||||
#endif
|
||||
@@ -593,17 +589,13 @@ __extern_C key_t ftok(const char *, int);
|
||||
|
||||
#ifndef __cold
|
||||
#if defined(__OPTIMIZE__)
|
||||
#if defined(__e2k__)
|
||||
#define __cold __attribute__((__cold__)) __optimize(1)
|
||||
#elif defined(__clang__) && !__has_attribute(cold) && \
|
||||
#if defined(__clang__) && !__has_attribute(__cold__) && \
|
||||
__has_attribute(__section__) && \
|
||||
(defined(__linux__) || defined(__gnu_linux__))
|
||||
/* just put infrequently used functions in separate section */
|
||||
#define __cold __attribute__((__section__("text.unlikely"))) __optimize("Os")
|
||||
#elif defined(__LCC__)
|
||||
#define __hot __attribute__((__cold__, __optimize__("Osize")))
|
||||
#elif defined(__GNUC__) || __has_attribute(cold)
|
||||
#define __cold __attribute__((__cold__)) __optimize("Os")
|
||||
#elif defined(__GNUC__) || __has_attribute(__cold__)
|
||||
#define __cold __attribute__((__cold__))
|
||||
#else
|
||||
#define __cold __optimize("Os")
|
||||
#endif
|
||||
@@ -669,6 +661,28 @@ __extern_C key_t ftok(const char *, int);
|
||||
#endif
|
||||
#endif /* MDBX_WEAK_IMPORT_ATTRIBUTE */
|
||||
|
||||
#ifndef MDBX_GOOFY_MSVC_STATIC_ANALYZER
|
||||
#ifdef _PREFAST_
|
||||
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 1
|
||||
#else
|
||||
#define MDBX_GOOFY_MSVC_STATIC_ANALYZER 0
|
||||
#endif
|
||||
#endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */
|
||||
|
||||
#if MDBX_GOOFY_MSVC_STATIC_ANALYZER || (defined(_MSC_VER) && _MSC_VER > 1919)
|
||||
#define MDBX_ANALYSIS_ASSUME(expr) __analysis_assume(expr)
|
||||
#ifdef _PREFAST_
|
||||
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \
|
||||
__pragma(prefast(suppress : warn_id))
|
||||
#else
|
||||
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id) \
|
||||
__pragma(warning(suppress : warn_id))
|
||||
#endif
|
||||
#else
|
||||
#define MDBX_ANALYSIS_ASSUME(expr) assert(expr)
|
||||
#define MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(warn_id)
|
||||
#endif /* MDBX_GOOFY_MSVC_STATIC_ANALYZER */
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
|
||||
#if defined(MDBX_USE_VALGRIND)
|
||||
|
||||
967
src/core.c
967
src/core.c
File diff suppressed because it is too large
Load Diff
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -35,7 +35,7 @@
|
||||
|
||||
/** Disables using GNU/Linux libc extensions.
|
||||
* \ingroup build_option
|
||||
* \note This option couldn't be moved to the options.h since dependant
|
||||
* \note This option couldn't be moved to the options.h since dependent
|
||||
* control macros/defined should be prepared before include the options.h */
|
||||
#ifndef MDBX_DISABLE_GNU_SOURCE
|
||||
#define MDBX_DISABLE_GNU_SOURCE 0
|
||||
@@ -86,14 +86,18 @@
|
||||
#pragma warning(disable : 4464) /* relative include path contains '..' */
|
||||
#endif
|
||||
#if _MSC_VER > 1913
|
||||
#pragma warning(disable : 5045) /* Compiler will insert Spectre mitigation... \
|
||||
*/
|
||||
#pragma warning(disable : 5045) /* will insert Spectre mitigation... */
|
||||
#endif
|
||||
#if _MSC_VER > 1914
|
||||
#pragma warning( \
|
||||
disable : 5105) /* winbase.h(9531): warning C5105: macro expansion \
|
||||
producing 'defined' has undefined behavior */
|
||||
#endif
|
||||
#if _MSC_VER > 1930
|
||||
#pragma warning(disable : 6235) /* <expression> is always a constant */
|
||||
#pragma warning(disable : 6237) /* <expression> is never evaluated and might \
|
||||
have side effects */
|
||||
#endif
|
||||
#pragma warning(disable : 4710) /* 'xyz': function not inlined */
|
||||
#pragma warning(disable : 4711) /* function 'xyz' selected for automatic \
|
||||
inline expansion */
|
||||
@@ -920,7 +924,7 @@ typedef struct MDBX_lockinfo {
|
||||
|
||||
/* Paired counter of processes that have mlock()ed part of mmapped DB.
|
||||
* The (mti_mlcnt[0] - mti_mlcnt[1]) > 0 means at least one process
|
||||
* lock at leat one page, so therefore madvise() could return EINVAL. */
|
||||
* lock at least one page, so therefore madvise() could return EINVAL. */
|
||||
MDBX_atomic_uint32_t mti_mlcnt[2];
|
||||
|
||||
MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
|
||||
@@ -1463,6 +1467,8 @@ struct MDBX_env {
|
||||
osal_srwlock_t me_remap_guard;
|
||||
/* Workaround for LockFileEx and WriteFile multithread bug */
|
||||
CRITICAL_SECTION me_windowsbug_lock;
|
||||
char *me_pathname_char; /* cache of multi-byte representation of pathname
|
||||
to the DB files */
|
||||
#else
|
||||
osal_fastmutex_t me_remap_guard;
|
||||
#endif
|
||||
@@ -1691,14 +1697,14 @@ int64pgno(int64_t i64) {
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
|
||||
pgno_add(size_t base, size_t augend) {
|
||||
assert(base <= MAX_PAGENO + 1 && augend < MAX_PAGENO);
|
||||
return int64pgno(base + augend);
|
||||
return int64pgno((int64_t)base + (int64_t)augend);
|
||||
}
|
||||
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __inline pgno_t
|
||||
pgno_sub(size_t base, size_t subtrahend) {
|
||||
assert(base >= MIN_PAGENO && base <= MAX_PAGENO + 1 &&
|
||||
subtrahend < MAX_PAGENO);
|
||||
return int64pgno(base - subtrahend);
|
||||
return int64pgno((int64_t)base - (int64_t)subtrahend);
|
||||
}
|
||||
|
||||
MDBX_MAYBE_UNUSED MDBX_NOTHROW_CONST_FUNCTION static __always_inline bool
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -175,7 +175,7 @@ static int funlock(mdbx_filehandle_t fd, size_t offset, size_t bytes) {
|
||||
#else
|
||||
#define DXB_MAXLEN UINT32_C(0x7ff00000)
|
||||
#endif
|
||||
#define DXB_BODY (env->me_psize * NUM_METAS), DXB_MAXLEN
|
||||
#define DXB_BODY (env->me_psize * (size_t)NUM_METAS), DXB_MAXLEN
|
||||
#define DXB_WHOLE 0, DXB_MAXLEN
|
||||
|
||||
int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
@@ -194,8 +194,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
}
|
||||
}
|
||||
|
||||
if (env->me_flags & MDBX_EXCLUSIVE)
|
||||
if (env->me_flags & MDBX_EXCLUSIVE) {
|
||||
/* Zap: Failing to release lock 'env->me_windowsbug_lock'
|
||||
* in function 'mdbx_txn_lock' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(26115);
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
const HANDLE fd4data =
|
||||
env->me_overlapped_fd ? env->me_overlapped_fd : env->me_lazy_fd;
|
||||
@@ -213,8 +217,12 @@ int mdbx_txn_lock(MDBX_env *env, bool dontwait) {
|
||||
LCK_EXCLUSIVE | LCK_DONTWAIT, DXB_BODY);
|
||||
}
|
||||
}
|
||||
if (rc == MDBX_SUCCESS)
|
||||
if (rc == MDBX_SUCCESS) {
|
||||
/* Zap: Failing to release lock 'env->me_windowsbug_lock'
|
||||
* in function 'mdbx_txn_lock' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(26115);
|
||||
return rc;
|
||||
}
|
||||
|
||||
LeaveCriticalSection(&env->me_windowsbug_lock);
|
||||
return (!dontwait || rc != ERROR_LOCK_VIOLATION) ? rc : MDBX_BUSY;
|
||||
@@ -281,17 +289,18 @@ static int suspend_and_append(mdbx_handle_array_t **array,
|
||||
const DWORD ThreadId) {
|
||||
const unsigned limit = (*array)->limit;
|
||||
if ((*array)->count == limit) {
|
||||
void *ptr = osal_realloc(
|
||||
(limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) * (limit * 2 - ARRAY_LENGTH((*array)->handles)));
|
||||
mdbx_handle_array_t *const ptr =
|
||||
osal_realloc((limit > ARRAY_LENGTH((*array)->handles))
|
||||
? *array
|
||||
: /* don't free initial array on the stack */ NULL,
|
||||
sizeof(mdbx_handle_array_t) +
|
||||
sizeof(HANDLE) * (limit * (size_t)2 -
|
||||
ARRAY_LENGTH((*array)->handles)));
|
||||
if (!ptr)
|
||||
return MDBX_ENOMEM;
|
||||
if (limit == ARRAY_LENGTH((*array)->handles))
|
||||
memcpy(ptr, *array, sizeof(mdbx_handle_array_t));
|
||||
*array = (mdbx_handle_array_t *)ptr;
|
||||
*ptr = **array;
|
||||
*array = ptr;
|
||||
(*array)->limit = limit * 2;
|
||||
}
|
||||
|
||||
@@ -752,7 +761,7 @@ static void WINAPI stub_srwlock_AcquireShared(osal_srwlock_t *srwl) {
|
||||
// If there's a writer already, spin without unnecessarily
|
||||
// interlocking the CPUs
|
||||
if (srwl->writerCount != 0) {
|
||||
YieldProcessor();
|
||||
SwitchToThread();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -766,7 +775,7 @@ static void WINAPI stub_srwlock_AcquireShared(osal_srwlock_t *srwl) {
|
||||
|
||||
// Remove from the readers list, spin, try again
|
||||
_InterlockedDecrement(&srwl->readerCount);
|
||||
YieldProcessor();
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -782,7 +791,7 @@ static void WINAPI stub_srwlock_AcquireExclusive(osal_srwlock_t *srwl) {
|
||||
// If there's a writer already, spin without unnecessarily
|
||||
// interlocking the CPUs
|
||||
if (srwl->writerCount != 0) {
|
||||
YieldProcessor();
|
||||
SwitchToThread();
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -797,7 +806,7 @@ static void WINAPI stub_srwlock_AcquireExclusive(osal_srwlock_t *srwl) {
|
||||
// that we're the writer.
|
||||
while (srwl->readerCount != 0) {
|
||||
assert(srwl->writerCount >= 0 && srwl->readerCount >= 0);
|
||||
YieldProcessor();
|
||||
SwitchToThread();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -839,38 +848,40 @@ MDBX_SetFileIoOverlappedRange mdbx_SetFileIoOverlappedRange;
|
||||
#endif /* GCC/MINGW */
|
||||
|
||||
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 hNtdll = GetModuleHandleA("ntdll.dll");
|
||||
if (hNtdll) {
|
||||
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);
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange);
|
||||
if (hKernel32dll) {
|
||||
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);
|
||||
GET_PROC_ADDR(hKernel32dll, SetFileIoOverlappedRange);
|
||||
}
|
||||
}
|
||||
|
||||
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
|
||||
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA);
|
||||
#undef GET_PROC_ADDR
|
||||
|
||||
const osal_srwlock_t_function init = (osal_srwlock_t_function)GetProcAddress(
|
||||
hKernel32dll, "InitializeSRWLock");
|
||||
const osal_srwlock_t_function init =
|
||||
(osal_srwlock_t_function)(hKernel32dll
|
||||
? GetProcAddress(hKernel32dll,
|
||||
"InitializeSRWLock")
|
||||
: nullptr);
|
||||
if (init != NULL) {
|
||||
osal_srwlock_Init = init;
|
||||
osal_srwlock_AcquireShared = (osal_srwlock_t_function)GetProcAddress(
|
||||
@@ -888,6 +899,12 @@ static void mdbx_winnt_import(void) {
|
||||
osal_srwlock_AcquireExclusive = stub_srwlock_AcquireExclusive;
|
||||
osal_srwlock_ReleaseExclusive = stub_srwlock_ReleaseExclusive;
|
||||
}
|
||||
|
||||
const HINSTANCE hAdvapi32dll = GetModuleHandleA("advapi32.dll");
|
||||
if (hAdvapi32dll) {
|
||||
GET_PROC_ADDR(hAdvapi32dll, RegGetValueA);
|
||||
}
|
||||
#undef GET_PROC_ADDR
|
||||
}
|
||||
|
||||
#if __GNUC_PREREQ(8, 0)
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_CHK 1 "2022-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_CHK 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_chk \- MDBX checking tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>.
|
||||
.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_COPY 1 "2022-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_COPY 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_copy \- MDBX environment copy tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
.\" Copyright 2021-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2021-2023 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-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_DROP 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_drop \- MDBX database delete tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>.
|
||||
.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_DUMP 1 "2022-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_DUMP 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_dump \- MDBX environment export tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>.
|
||||
.\" Copyright 2014-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_LOAD 1 "2022-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_LOAD 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_load \- MDBX environment import tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
.\" Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
.\" Copyright 2015,2016 Peter-Service R&D LLC <http://billing.ru/>.
|
||||
.\" Copyright 2012-2015 Howard Chu, Symas Corp. All Rights Reserved.
|
||||
.\" Copying restrictions apply. See COPYRIGHT/LICENSE.
|
||||
.TH MDBX_STAT 1 "2022-11-11" "MDBX 0.12.2"
|
||||
.TH MDBX_STAT 1 "2023-04-18" "MDBX 0.12.5"
|
||||
.SH NAME
|
||||
mdbx_stat \- MDBX environment status tool
|
||||
.SH SYNOPSIS
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
//
|
||||
// Copyright (c) 2020-2022, Leonid Yuriev <leo@yuriev.ru>.
|
||||
// Copyright (c) 2020-2023, Leonid Yuriev <leo@yuriev.ru>.
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
// Non-inline part of the libmdbx C++ API
|
||||
@@ -14,6 +14,12 @@
|
||||
#define __USE_MINGW_ANSI_STDIO 1
|
||||
#endif /* MinGW */
|
||||
|
||||
/* Workaround for MSVC' header `extern "C"` vs `std::` redefinition bug */
|
||||
#if defined(_MSC_VER) && defined(__SANITIZE_ADDRESS__) && \
|
||||
!defined(_DISABLE_VECTOR_ANNOTATION)
|
||||
#define _DISABLE_VECTOR_ANNOTATION
|
||||
#endif /* _DISABLE_VECTOR_ANNOTATION */
|
||||
|
||||
#include "../mdbx.h++"
|
||||
|
||||
#include "internals.h"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* mdbx_chk.c - memory-mapped database check tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -153,6 +153,10 @@ static const char *sdb_name(const MDBX_val *val) {
|
||||
return "<nullptr>";
|
||||
if (len > 65536) {
|
||||
static char buf[64];
|
||||
/* NOTE: There is MSYS2 MinGW bug if you here got
|
||||
* the "unknown conversion type character ‘z’ in format [-Werror=format=]"
|
||||
* https://stackoverflow.com/questions/74504432/whats-the-proper-way-to-tell-mingw-based-gcc-to-use-ansi-stdio-output-on-windo
|
||||
*/
|
||||
snprintf(buf, sizeof(buf), "<too-long-%zu>", len);
|
||||
return buf;
|
||||
}
|
||||
@@ -567,8 +571,8 @@ static int pgvisitor(const uint64_t pgno, const unsigned pgnumber,
|
||||
data_tree_problems += !is_gc_tree;
|
||||
gc_tree_problems += is_gc_tree;
|
||||
} else {
|
||||
dbi->payload_bytes += payload_bytes + header_bytes;
|
||||
walk.total_payload_bytes += payload_bytes + header_bytes;
|
||||
dbi->payload_bytes += (uint64_t)payload_bytes + header_bytes;
|
||||
walk.total_payload_bytes += (uint64_t)payload_bytes + header_bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -628,7 +632,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
|
||||
pgno_t prev = MDBX_PNL_ASCENDING ? NUM_METAS - 1 : txn->mt_next_pgno;
|
||||
pgno_t span = 1;
|
||||
for (unsigned i = 0; i < number; ++i) {
|
||||
for (size_t i = 0; i < number; ++i) {
|
||||
if (check_user_break())
|
||||
return MDBX_EINTR;
|
||||
const pgno_t pgno = iptr[i];
|
||||
@@ -647,7 +651,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
if (MDBX_PNL_DISORDERED(prev, pgno)) {
|
||||
bad = " [bad sequence]";
|
||||
problem_add("entry", txnid, "bad sequence",
|
||||
"%" PRIaPGNO " %c [%u].%" PRIaPGNO, prev,
|
||||
"%" PRIaPGNO " %c [%zu].%" PRIaPGNO, prev,
|
||||
(prev == pgno) ? '=' : (MDBX_PNL_ASCENDING ? '>' : '<'),
|
||||
i, pgno);
|
||||
}
|
||||
@@ -673,7 +677,7 @@ static int handle_freedb(const uint64_t record_number, const MDBX_val *key,
|
||||
" pages, maxspan %" PRIaPGNO "%s\n",
|
||||
txnid, number, span, bad);
|
||||
if (verbose > 4) {
|
||||
for (unsigned i = 0; i < number; i += span) {
|
||||
for (size_t i = 0; i < number; i += span) {
|
||||
const pgno_t pgno = iptr[i];
|
||||
for (span = 1;
|
||||
i + span < number &&
|
||||
@@ -1493,7 +1497,7 @@ int main(int argc, char *argv[]) {
|
||||
alloc_pages = backed_pages;
|
||||
}
|
||||
} else {
|
||||
/* LY: DB may be shrinked by writer down to the allocated pages. */
|
||||
/* LY: DB may be shrunk by writer down to the allocated pages. */
|
||||
if (alloc_pages > backed_pages) {
|
||||
print(" ! alloc-pages %" PRIu64 " > backed-pages %" PRIu64 "\n",
|
||||
alloc_pages, backed_pages);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* mdbx_copy.c - memory-mapped database backup tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
/* mdbx_drop.c - memory-mapped database delete tool */
|
||||
|
||||
/*
|
||||
* Copyright 2021 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2021-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
*
|
||||
* Copyright 2016-2022 Howard Chu, Symas Corp.
|
||||
* Copyright 2016-2021 Howard Chu, Symas Corp.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* mdbx_dump.c - memory-mapped database dump tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* mdbx_load.c - memory-mapped database load tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -673,7 +673,7 @@ int main(int argc, char *argv[]) {
|
||||
goto env_close;
|
||||
}
|
||||
|
||||
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + 1;
|
||||
kbuf.iov_len = mdbx_env_get_maxvalsize_ex(env, 0) + (size_t)1;
|
||||
if (kbuf.iov_len >= INTPTR_MAX / 2) {
|
||||
if (!quiet)
|
||||
fprintf(stderr, "mdbx_env_get_maxkeysize() failed, returns %zu\n",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/* mdbx_stat.c - memory-mapped database status tool */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -256,6 +256,17 @@ int main(int argc, char *argv[]) {
|
||||
printf(" WOP: %8" PRIu64
|
||||
"\t// number of explicit write operations (not a pages) to a disk\n",
|
||||
mei.mi_pgop_stat.wops);
|
||||
printf(" PreFault: %8" PRIu64
|
||||
"\t// number of prefault write operations (not a pages)\n",
|
||||
mei.mi_pgop_stat.prefault);
|
||||
printf(" mInCore: %8" PRIu64 "\t// number of mincore() calls\n",
|
||||
mei.mi_pgop_stat.mincore);
|
||||
printf(" mSync: %8" PRIu64
|
||||
"\t// number of explicit msync-to-disk operations (not a pages)\n",
|
||||
mei.mi_pgop_stat.msync);
|
||||
printf(" fSync: %8" PRIu64
|
||||
"\t// number of explicit fsync-to-disk operations (not a pages)\n",
|
||||
mei.mi_pgop_stat.fsync);
|
||||
}
|
||||
|
||||
if (envinfo) {
|
||||
|
||||
@@ -166,7 +166,7 @@
|
||||
|
||||
/** Controls sort order of internal page number lists.
|
||||
* This mostly experimental/advanced option with not for regular MDBX users.
|
||||
* \warning The database format depend on this option and libmdbx builded with
|
||||
* \warning The database format depend on this option and libmdbx built with
|
||||
* different option value are incompatible. */
|
||||
#ifndef MDBX_PNL_ASCENDING
|
||||
#define MDBX_PNL_ASCENDING 0
|
||||
@@ -220,7 +220,11 @@
|
||||
#endif /* MDBX_HAVE_C11ATOMICS */
|
||||
|
||||
/** If defined then enables use the GCC's `__builtin_cpu_supports()`
|
||||
* for runtime dispatching depending on the CPU's capabilities. */
|
||||
* for runtime dispatching depending on the CPU's capabilities.
|
||||
* \note Defining `MDBX_HAVE_BUILTIN_CPU_SUPPORTS` to `0` should avoided unless
|
||||
* build for particular single-target platform, since on AMD64/x86 this disables
|
||||
* dynamic choice (at runtime) of SSE2 / AVX2 / AVX512 instructions
|
||||
* with fallback to non-accelerated baseline code. */
|
||||
#ifndef MDBX_HAVE_BUILTIN_CPU_SUPPORTS
|
||||
#if defined(__APPLE__) || defined(BIONIC)
|
||||
/* Never use any modern features on Apple's or Google's OSes
|
||||
|
||||
164
src/osal.c
164
src/osal.c
@@ -1,7 +1,7 @@
|
||||
/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -48,6 +48,8 @@ static int ntstatus2errcode(NTSTATUS status) {
|
||||
OVERLAPPED ov;
|
||||
memset(&ov, 0, sizeof(ov));
|
||||
ov.Internal = status;
|
||||
/* Zap: '_Param_(1)' could be '0' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6387);
|
||||
return GetOverlappedResult(NULL, &ov, &dummy, FALSE) ? MDBX_SUCCESS
|
||||
: (int)GetLastError();
|
||||
}
|
||||
@@ -82,6 +84,8 @@ extern NTSTATUS NTAPI NtMapViewOfSection(
|
||||
extern NTSTATUS NTAPI NtUnmapViewOfSection(IN HANDLE ProcessHandle,
|
||||
IN OPTIONAL PVOID BaseAddress);
|
||||
|
||||
/* Zap: Inconsistent annotation for 'NtClose'... */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(28251)
|
||||
extern NTSTATUS NTAPI NtClose(HANDLE Handle);
|
||||
|
||||
extern NTSTATUS NTAPI NtAllocateVirtualMemory(
|
||||
@@ -312,17 +316,16 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
|
||||
va_list ap) {
|
||||
va_list ones;
|
||||
va_copy(ones, ap);
|
||||
int needed = vsnprintf(nullptr, 0, fmt, ap);
|
||||
const int needed = vsnprintf(nullptr, 0, fmt, ones);
|
||||
va_end(ones);
|
||||
|
||||
if (unlikely(needed < 0 || needed >= INT_MAX)) {
|
||||
*strp = nullptr;
|
||||
va_end(ones);
|
||||
return needed;
|
||||
}
|
||||
|
||||
*strp = osal_malloc(needed + 1);
|
||||
*strp = osal_malloc(needed + (size_t)1);
|
||||
if (unlikely(*strp == nullptr)) {
|
||||
va_end(ones);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
SetLastError(MDBX_ENOMEM);
|
||||
#else
|
||||
@@ -331,9 +334,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
|
||||
return -1;
|
||||
}
|
||||
|
||||
int actual = vsnprintf(*strp, needed + 1, fmt, ones);
|
||||
va_end(ones);
|
||||
|
||||
const int actual = vsnprintf(*strp, needed + (size_t)1, fmt, ap);
|
||||
assert(actual == needed);
|
||||
if (unlikely(actual < 0)) {
|
||||
osal_free(*strp);
|
||||
@@ -347,7 +348,7 @@ MDBX_INTERNAL_FUNC int osal_vasprintf(char **strp, const char *fmt,
|
||||
MDBX_INTERNAL_FUNC int osal_asprintf(char **strp, const char *fmt, ...) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
int rc = osal_vasprintf(strp, fmt, ap);
|
||||
const int rc = osal_vasprintf(strp, fmt, ap);
|
||||
va_end(ap);
|
||||
return rc;
|
||||
}
|
||||
@@ -546,19 +547,32 @@ MDBX_INTERNAL_FUNC int osal_fastmutex_release(osal_fastmutex_t *fastmutex) {
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
#ifndef WC_ERR_INVALID_CHARS
|
||||
static const DWORD WC_ERR_INVALID_CHARS =
|
||||
(6 /* Windows Vista */ <= /* MajorVersion */ LOBYTE(LOWORD(GetVersion())))
|
||||
? 0x00000080
|
||||
: 0;
|
||||
#endif /* WC_ERR_INVALID_CHARS */
|
||||
MDBX_INTERNAL_FUNC int osal_mb2w(const char *const src, wchar_t **const pdst) {
|
||||
const size_t dst_wlen = MultiByteToWideChar(
|
||||
CP_THREAD_ACP, MB_ERR_INVALID_CHARS, src, -1, nullptr, 0);
|
||||
wchar_t *dst = *pdst;
|
||||
int rc = ERROR_INVALID_NAME;
|
||||
if (unlikely(dst_wlen < 2 || dst_wlen > /* MAX_PATH */ INT16_MAX))
|
||||
goto bailout;
|
||||
|
||||
MDBX_MAYBE_UNUSED MDBX_INTERNAL_FUNC size_t osal_mb2w(wchar_t *dst,
|
||||
size_t dst_n,
|
||||
const char *src,
|
||||
size_t src_n) {
|
||||
return MultiByteToWideChar(CP_THREAD_ACP, MB_ERR_INVALID_CHARS, src,
|
||||
(int)src_n, dst, (int)dst_n);
|
||||
dst = osal_realloc(dst, dst_wlen * sizeof(wchar_t));
|
||||
rc = MDBX_ENOMEM;
|
||||
if (unlikely(!dst))
|
||||
goto bailout;
|
||||
|
||||
*pdst = dst;
|
||||
if (likely(dst_wlen == (size_t)MultiByteToWideChar(CP_THREAD_ACP,
|
||||
MB_ERR_INVALID_CHARS, src,
|
||||
-1, dst, (int)dst_wlen)))
|
||||
return MDBX_SUCCESS;
|
||||
|
||||
rc = ERROR_INVALID_NAME;
|
||||
bailout:
|
||||
if (*pdst) {
|
||||
osal_free(*pdst);
|
||||
*pdst = nullptr;
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif /* Windows */
|
||||
@@ -679,7 +693,7 @@ MDBX_INTERNAL_FUNC int osal_ioring_add(osal_ioring_t *ior, const size_t offset,
|
||||
((bytes | (uintptr_t)data | ior->last_bytes |
|
||||
(uintptr_t)(uint64_t)item->sgv[0].Buffer) &
|
||||
ior_alignment_mask) == 0 &&
|
||||
ior->last_sgvcnt + segments < OSAL_IOV_MAX) {
|
||||
ior->last_sgvcnt + (size_t)segments < OSAL_IOV_MAX) {
|
||||
assert(ior->overlapped_fd);
|
||||
assert((item->single.iov_len & ior_WriteFile_flag) == 0);
|
||||
assert(item->sgv[ior->last_sgvcnt].Buffer == 0);
|
||||
@@ -788,6 +802,8 @@ MDBX_INTERNAL_FUNC void osal_ioring_walk(
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
data = Ptr64ToPtr(item->sgv[0].Buffer);
|
||||
bytes = ior->pagesize;
|
||||
/* Zap: Reading invalid data from 'item->sgv' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6385);
|
||||
while (item->sgv[i].Buffer) {
|
||||
if (data + ior->pagesize != item->sgv[i].Buffer) {
|
||||
callback(ctx, offset, data, bytes);
|
||||
@@ -834,6 +850,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
assert(ior->overlapped_fd && fd == ior->overlapped_fd);
|
||||
bytes = ior->pagesize;
|
||||
/* Zap: Reading invalid data from 'item->sgv' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6385);
|
||||
while (item->sgv[i].Buffer) {
|
||||
bytes += ior->pagesize;
|
||||
++i;
|
||||
@@ -972,6 +990,8 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
|
||||
size_t i = 1, bytes = item->single.iov_len - ior_WriteFile_flag;
|
||||
if (bytes & ior_WriteFile_flag) {
|
||||
bytes = ior->pagesize;
|
||||
/* Zap: Reading invalid data from 'item->sgv' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6385);
|
||||
while (item->sgv[i].Buffer) {
|
||||
bytes += ior->pagesize;
|
||||
++i;
|
||||
@@ -1065,9 +1085,12 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
|
||||
if (item->ov.hEvent && item->ov.hEvent != ior)
|
||||
ior_put_event(ior, item->ov.hEvent);
|
||||
size_t i = 1;
|
||||
if ((item->single.iov_len & ior_WriteFile_flag) == 0)
|
||||
if ((item->single.iov_len & ior_WriteFile_flag) == 0) {
|
||||
/* Zap: Reading invalid data from 'item->sgv' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6385);
|
||||
while (item->sgv[i].Buffer)
|
||||
++i;
|
||||
}
|
||||
item = ior_next(item, i);
|
||||
}
|
||||
}
|
||||
@@ -1082,8 +1105,11 @@ MDBX_INTERNAL_FUNC void osal_ioring_reset(osal_ioring_t *ior) {
|
||||
static void ior_cleanup(osal_ioring_t *ior, const size_t since) {
|
||||
osal_ioring_reset(ior);
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
for (size_t i = since; i < ior->event_stack; ++i)
|
||||
for (size_t i = since; i < ior->event_stack; ++i) {
|
||||
/* Zap: Using uninitialized memory '**ior.event_pool' */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6001);
|
||||
CloseHandle(ior->event_pool[i]);
|
||||
}
|
||||
ior->event_stack = 0;
|
||||
#else
|
||||
(void)since;
|
||||
@@ -1160,7 +1186,7 @@ MDBX_INTERNAL_FUNC void osal_ioring_destroy(osal_ioring_t *ior) {
|
||||
#else
|
||||
osal_free(ior->pool);
|
||||
#endif
|
||||
memset(ior, -1, sizeof(osal_ioring_t));
|
||||
memset(ior, 0, sizeof(osal_ioring_t));
|
||||
}
|
||||
|
||||
/*----------------------------------------------------------------------------*/
|
||||
@@ -2160,9 +2186,8 @@ static int check_mmap_limit(const size_t limit) {
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
|
||||
MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map,
|
||||
const size_t size, const size_t limit,
|
||||
const unsigned options) {
|
||||
MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map, size_t size,
|
||||
const size_t limit, const unsigned options) {
|
||||
assert(size <= limit);
|
||||
map->limit = 0;
|
||||
map->current = 0;
|
||||
@@ -2182,6 +2207,7 @@ MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map,
|
||||
|
||||
if ((flags & MDBX_RDONLY) == 0 && (options & MMAP_OPTION_TRUNCATE) != 0) {
|
||||
err = osal_ftruncate(map->fd, size);
|
||||
VERBOSE("ftruncate %zu, err %d", size, err);
|
||||
if (err != MDBX_SUCCESS)
|
||||
return err;
|
||||
map->filesize = size;
|
||||
@@ -2190,9 +2216,16 @@ MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map,
|
||||
#endif /* !Windows */
|
||||
} else {
|
||||
err = osal_filesize(map->fd, &map->filesize);
|
||||
VERBOSE("filesize %" PRIu64 ", err %d", map->filesize, err);
|
||||
if (err != MDBX_SUCCESS)
|
||||
return err;
|
||||
#if !(defined(_WIN32) || defined(_WIN64))
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
if (map->filesize < size) {
|
||||
WARNING("file size (%zu) less than requested for mapping (%zu)",
|
||||
(size_t)map->filesize, size);
|
||||
size = (size_t)map->filesize;
|
||||
}
|
||||
#else
|
||||
map->current = (map->filesize > limit) ? limit : (size_t)map->filesize;
|
||||
#endif /* !Windows */
|
||||
}
|
||||
@@ -2301,8 +2334,7 @@ MDBX_INTERNAL_FUNC int osal_munmap(osal_mmap_t *map) {
|
||||
VALGRIND_MAKE_MEM_NOACCESS(map->base, map->current);
|
||||
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
||||
* when this memory will re-used by malloc or another mmapping.
|
||||
* See https://libmdbx.dqdkfa.ru/dead-github/pull/93#issuecomment-613687203
|
||||
*/
|
||||
* See https://libmdbx.dqdkfa.ru/dead-github/pull/93#issuecomment-613687203 */
|
||||
MDBX_ASAN_UNPOISON_MEMORY_REGION(
|
||||
map->base, (map->filesize && map->filesize < map->limit) ? map->filesize
|
||||
: map->limit);
|
||||
@@ -2327,25 +2359,38 @@ MDBX_INTERNAL_FUNC int osal_munmap(osal_mmap_t *map) {
|
||||
|
||||
MDBX_INTERNAL_FUNC int osal_mresize(const int flags, osal_mmap_t *map,
|
||||
size_t size, size_t limit) {
|
||||
int rc = osal_filesize(map->fd, &map->filesize);
|
||||
VERBOSE("flags 0x%x, size %zu, limit %zu, filesize %" PRIu64, flags, size,
|
||||
limit, map->filesize);
|
||||
assert(size <= limit);
|
||||
if (rc != MDBX_SUCCESS) {
|
||||
map->filesize = 0;
|
||||
return rc;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
assert(size != map->current || limit != map->limit || size < map->filesize);
|
||||
|
||||
NTSTATUS status;
|
||||
LARGE_INTEGER SectionSize;
|
||||
int err, rc = MDBX_SUCCESS;
|
||||
int err;
|
||||
|
||||
if (!(flags & MDBX_RDONLY) && limit == map->limit && size > map->current &&
|
||||
/* workaround for Wine */ mdbx_NtExtendSection) {
|
||||
/* growth rw-section */
|
||||
SectionSize.QuadPart = size;
|
||||
status = mdbx_NtExtendSection(map->section, &SectionSize);
|
||||
if (!NT_SUCCESS(status))
|
||||
return ntstatus2errcode(status);
|
||||
map->current = size;
|
||||
if (map->filesize < size)
|
||||
map->filesize = size;
|
||||
return MDBX_SUCCESS;
|
||||
if (limit == map->limit && size > map->current) {
|
||||
if ((flags & MDBX_RDONLY) && map->filesize >= size) {
|
||||
map->current = size;
|
||||
return MDBX_SUCCESS;
|
||||
} else if (!(flags & MDBX_RDONLY) &&
|
||||
/* workaround for Wine */ mdbx_NtExtendSection) {
|
||||
/* growth rw-section */
|
||||
SectionSize.QuadPart = size;
|
||||
status = mdbx_NtExtendSection(map->section, &SectionSize);
|
||||
if (!NT_SUCCESS(status))
|
||||
return ntstatus2errcode(status);
|
||||
map->current = size;
|
||||
if (map->filesize < size)
|
||||
map->filesize = size;
|
||||
return MDBX_SUCCESS;
|
||||
}
|
||||
}
|
||||
|
||||
if (limit > map->limit) {
|
||||
@@ -2374,13 +2419,15 @@ MDBX_INTERNAL_FUNC int osal_mresize(const int flags, osal_mmap_t *map,
|
||||
* - change size of mapped view;
|
||||
* - extend read-only mapping;
|
||||
* Therefore we should unmap/map entire section. */
|
||||
if ((flags & MDBX_MRESIZE_MAY_UNMAP) == 0)
|
||||
if ((flags & MDBX_MRESIZE_MAY_UNMAP) == 0) {
|
||||
if (size <= map->current && limit == map->limit)
|
||||
return MDBX_SUCCESS;
|
||||
return MDBX_EPERM;
|
||||
}
|
||||
|
||||
/* Unpoisoning is required for ASAN to avoid false-positive diagnostic
|
||||
* when this memory will re-used by malloc or another mmapping.
|
||||
* See https://libmdbx.dqdkfa.ru/dead-github/pull/93#issuecomment-613687203
|
||||
*/
|
||||
* See https://libmdbx.dqdkfa.ru/dead-github/pull/93#issuecomment-613687203 */
|
||||
MDBX_ASAN_UNPOISON_MEMORY_REGION(map->base, map->limit);
|
||||
status = NtUnmapViewOfSection(GetCurrentProcess(), map->base);
|
||||
if (!NT_SUCCESS(status))
|
||||
@@ -2393,7 +2440,6 @@ MDBX_INTERNAL_FUNC int osal_mresize(const int flags, osal_mmap_t *map,
|
||||
if (!NT_SUCCESS(status)) {
|
||||
bailout_ntstatus:
|
||||
err = ntstatus2errcode(status);
|
||||
bailout:
|
||||
map->base = NULL;
|
||||
map->current = map->limit = 0;
|
||||
if (ReservedAddress) {
|
||||
@@ -2422,10 +2468,6 @@ retry_file_and_section:
|
||||
map->base = NULL;
|
||||
}
|
||||
|
||||
err = osal_filesize(map->fd, &map->filesize);
|
||||
if (err != MDBX_SUCCESS)
|
||||
goto bailout;
|
||||
|
||||
if ((flags & MDBX_RDONLY) == 0 && map->filesize != size) {
|
||||
err = osal_ftruncate(map->fd, size);
|
||||
if (err == MDBX_SUCCESS)
|
||||
@@ -2502,18 +2544,17 @@ retry_mapview:;
|
||||
|
||||
#else /* Windows */
|
||||
|
||||
map->filesize = 0;
|
||||
int rc = osal_filesize(map->fd, &map->filesize);
|
||||
if (rc != MDBX_SUCCESS)
|
||||
return rc;
|
||||
|
||||
if (flags & MDBX_RDONLY) {
|
||||
if (size > map->filesize)
|
||||
rc = MDBX_UNABLE_EXTEND_MAPSIZE;
|
||||
else if (size < map->filesize && map->filesize > limit)
|
||||
rc = MDBX_EPERM;
|
||||
map->current = (map->filesize > limit) ? limit : (size_t)map->filesize;
|
||||
if (map->current != size)
|
||||
rc = (size > map->current) ? MDBX_UNABLE_EXTEND_MAPSIZE : MDBX_EPERM;
|
||||
} else {
|
||||
if (map->filesize != size) {
|
||||
if (size > map->filesize ||
|
||||
(size < map->filesize && (flags & MDBX_SHRINK_ALLOWED))) {
|
||||
rc = osal_ftruncate(map->fd, size);
|
||||
VERBOSE("ftruncate %zu, err %d", size, rc);
|
||||
if (rc != MDBX_SUCCESS)
|
||||
return rc;
|
||||
map->filesize = size;
|
||||
@@ -2706,9 +2747,12 @@ retry_mapview:;
|
||||
|
||||
#endif /* POSIX / Windows */
|
||||
|
||||
/* Zap: Redundant code */
|
||||
MDBX_SUPPRESS_GOOFY_MSVC_ANALYZER(6287);
|
||||
assert(rc != MDBX_SUCCESS ||
|
||||
(map->base != nullptr && map->base != MAP_FAILED &&
|
||||
map->current == size && map->limit == limit));
|
||||
map->current == size && map->limit == limit &&
|
||||
map->filesize >= size));
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
||||
26
src/osal.h
26
src/osal.h
@@ -1,7 +1,7 @@
|
||||
/* https://en.wikipedia.org/wiki/Operating_system_abstraction_layer */
|
||||
|
||||
/*
|
||||
* Copyright 2015-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2015-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -577,9 +577,8 @@ MDBX_INTERNAL_FUNC int osal_lockfile(mdbx_filehandle_t fd, bool wait);
|
||||
|
||||
#define MMAP_OPTION_TRUNCATE 1
|
||||
#define MMAP_OPTION_SEMAPHORE 2
|
||||
MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map,
|
||||
const size_t must, const size_t limit,
|
||||
const unsigned options);
|
||||
MDBX_INTERNAL_FUNC int osal_mmap(const int flags, osal_mmap_t *map, size_t size,
|
||||
const size_t limit, const unsigned options);
|
||||
MDBX_INTERNAL_FUNC int osal_munmap(osal_mmap_t *map);
|
||||
#define MDBX_MRESIZE_MAY_MOVE 0x00000100
|
||||
#define MDBX_MRESIZE_MAY_UNMAP 0x00000200
|
||||
@@ -704,7 +703,7 @@ MDBX_INTERNAL_FUNC int osal_lck_destroy(MDBX_env *env,
|
||||
MDBX_INTERNAL_FUNC int osal_lck_seize(MDBX_env *env);
|
||||
|
||||
/// \brief Downgrades the level of initially acquired lock to
|
||||
/// operational level specified by argument. The reson for such downgrade:
|
||||
/// operational level specified by argument. The reason for such downgrade:
|
||||
/// - unblocking of other processes that are waiting for access, i.e.
|
||||
/// if (env->me_flags & MDBX_EXCLUSIVE) != 0, then other processes
|
||||
/// should be made aware that access is unavailable rather than
|
||||
@@ -758,22 +757,7 @@ MDBX_INTERNAL_FUNC int osal_rpid_check(MDBX_env *env, uint32_t pid);
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
|
||||
MDBX_INTERNAL_FUNC size_t osal_mb2w(wchar_t *dst, size_t dst_n, const char *src,
|
||||
size_t src_n);
|
||||
|
||||
#define OSAL_MB2WIDE(FROM, TO) \
|
||||
do { \
|
||||
const char *const from_tmp = (FROM); \
|
||||
const size_t from_mblen = strlen(from_tmp); \
|
||||
const size_t to_wlen = osal_mb2w(nullptr, 0, from_tmp, from_mblen); \
|
||||
if (to_wlen < 1 || to_wlen > /* MAX_PATH */ INT16_MAX) \
|
||||
return ERROR_INVALID_NAME; \
|
||||
wchar_t *const to_tmp = _alloca((to_wlen + 1) * sizeof(wchar_t)); \
|
||||
if (to_wlen + 1 != \
|
||||
osal_mb2w(to_tmp, to_wlen + 1, from_tmp, from_mblen + 1)) \
|
||||
return ERROR_INVALID_NAME; \
|
||||
(TO) = to_tmp; \
|
||||
} while (0)
|
||||
MDBX_INTERNAL_FUNC int osal_mb2w(const char *const src, wchar_t **const pdst);
|
||||
|
||||
typedef void(WINAPI *osal_srwlock_t_function)(osal_srwlock_t *);
|
||||
MDBX_INTERNAL_VAR osal_srwlock_t_function osal_srwlock_Init,
|
||||
|
||||
@@ -64,9 +64,23 @@ if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
endif()
|
||||
|
||||
if(UNIX AND NOT SUBPROJECT)
|
||||
add_executable(pcrf_test pcrf/pcrf_test.c)
|
||||
target_include_directories(pcrf_test PRIVATE "${PROJECT_SOURCE_DIR}")
|
||||
target_link_libraries(pcrf_test ${TOOL_MDBX_LIB})
|
||||
add_executable(test_extra_pcrf extra/pcrf/pcrf_test.c)
|
||||
target_include_directories(test_extra_pcrf PRIVATE "${PROJECT_SOURCE_DIR}")
|
||||
target_link_libraries(test_extra_pcrf ${TOOL_MDBX_LIB})
|
||||
|
||||
add_executable(test_extra_upsert_alldups extra/upsert_alldups.c)
|
||||
target_include_directories(test_extra_upsert_alldups PRIVATE "${PROJECT_SOURCE_DIR}")
|
||||
target_link_libraries(test_extra_upsert_alldups ${TOOL_MDBX_LIB})
|
||||
|
||||
if(MDBX_BUILD_CXX)
|
||||
add_executable(test_extra_maindb_ordinal extra/maindb_ordinal.c++)
|
||||
target_include_directories(test_extra_maindb_ordinal PRIVATE "${PROJECT_SOURCE_DIR}")
|
||||
target_link_libraries(test_extra_maindb_ordinal ${TOOL_MDBX_LIB})
|
||||
if(MDBX_CXX_STANDARD)
|
||||
set_target_properties(test_extra_maindb_ordinal PROPERTIES
|
||||
CXX_STANDARD ${MDBX_CXX_STANDARD} CXX_STANDARD_REQUIRED ON)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
||||
################################################################################
|
||||
@@ -92,11 +106,13 @@ else()
|
||||
set_tests_properties(smoke_chk PROPERTIES
|
||||
DEPENDS smoke
|
||||
TIMEOUT 60
|
||||
FAIL_REGULAR_EXPRESSION "cooperative mode"
|
||||
REQUIRED_FILES smoke.db)
|
||||
add_test(NAME smoke_chk_copy COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvv smoke.db-copy)
|
||||
set_tests_properties(smoke_chk_copy PROPERTIES
|
||||
DEPENDS smoke
|
||||
TIMEOUT 60
|
||||
FAIL_REGULAR_EXPRESSION "cooperative mode"
|
||||
REQUIRED_FILES smoke.db-copy)
|
||||
endif()
|
||||
|
||||
@@ -109,15 +125,16 @@ else()
|
||||
TIMEOUT 600
|
||||
RUN_SERIAL OFF)
|
||||
if(MDBX_BUILD_TOOLS)
|
||||
add_test(NAME dupsort_writemap_chk COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvv dupsort_writemap.db)
|
||||
add_test(NAME dupsort_writemap_chk COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvvwc dupsort_writemap.db)
|
||||
set_tests_properties(dupsort_writemap_chk PROPERTIES
|
||||
DEPENDS dupsort_writemap
|
||||
TIMEOUT 60
|
||||
REQUIRED_FILES dupsort_writemap.db)
|
||||
add_test(NAME dupsort_writemap_chk_copy COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvv dupsort_writemap.db-copy)
|
||||
add_test(NAME dupsort_writemap_chk_copy COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvvc dupsort_writemap.db-copy)
|
||||
set_tests_properties(dupsort_writemap_chk_copy PROPERTIES
|
||||
DEPENDS dupsort_writemap
|
||||
TIMEOUT 60
|
||||
FAIL_REGULAR_EXPRESSION "monopolistic mode"
|
||||
REQUIRED_FILES dupsort_writemap.db-copy)
|
||||
endif()
|
||||
|
||||
@@ -128,15 +145,17 @@ else()
|
||||
TIMEOUT 1800
|
||||
RUN_SERIAL OFF)
|
||||
if(MDBX_BUILD_TOOLS)
|
||||
add_test(NAME uniq_nested_chk COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvv uniq_nested.db)
|
||||
add_test(NAME uniq_nested_chk COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvvw uniq_nested.db)
|
||||
set_tests_properties(uniq_nested_chk PROPERTIES
|
||||
DEPENDS uniq_nested
|
||||
TIMEOUT 60
|
||||
FAIL_REGULAR_EXPRESSION "cooperative mode"
|
||||
REQUIRED_FILES uniq_nested.db)
|
||||
add_test(NAME uniq_nested_chk_copy COMMAND ${MDBX_OUTPUT_DIR}/mdbx_chk -nvv uniq_nested.db-copy)
|
||||
set_tests_properties(uniq_nested_chk_copy PROPERTIES
|
||||
DEPENDS uniq_nested
|
||||
TIMEOUT 60
|
||||
FAIL_REGULAR_EXPRESSION "cooperative mode"
|
||||
REQUIRED_FILES uniq_nested.db-copy)
|
||||
endif()
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -21,7 +21,14 @@ public:
|
||||
bool run() override;
|
||||
|
||||
static bool review_params(actor_params ¶ms) {
|
||||
return testcase::review_params(params) && params.make_keygen_linear();
|
||||
if (!testcase::review_params(params))
|
||||
return false;
|
||||
const bool ordered = !flipcoin_x3();
|
||||
log_notice("the '%s' key-generation mode is selected",
|
||||
ordered ? "ordered/linear" : "unordered/non-linear");
|
||||
if (ordered && !params.make_keygen_linear())
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
};
|
||||
REGISTER_TESTCASE(append);
|
||||
@@ -133,8 +140,6 @@ bool testcase_append::run() {
|
||||
}
|
||||
} else
|
||||
failure_perror("mdbx_get_equal_or_great()", err);
|
||||
|
||||
assert(!expect_key_mismatch);
|
||||
}
|
||||
|
||||
err = mdbx_cursor_put(cursor_guard.get(), &key->value, &data->value, flags);
|
||||
@@ -148,12 +153,25 @@ bool testcase_append::run() {
|
||||
|
||||
if (!expect_key_mismatch) {
|
||||
if (unlikely(err != MDBX_SUCCESS))
|
||||
failure_perror("mdbx_cursor_put(insert-a)", err);
|
||||
failure_perror("mdbx_cursor_put(append)", err);
|
||||
++inserted_number;
|
||||
inserted_checksum.push((uint32_t)inserted_number, key->value);
|
||||
inserted_checksum.push(10639, data->value);
|
||||
|
||||
if (config.params.speculum) {
|
||||
Item item(iov2dataview(key), iov2dataview(data));
|
||||
const auto insertion_result = speculum.insert(item);
|
||||
if (!insertion_result.second) {
|
||||
char dump_key[32], dump_value[32];
|
||||
log_error(
|
||||
"speculum.append: unexpected %s {%s, %s}", "MDBX_SUCCESS",
|
||||
mdbx_dump_val(&key->value, dump_key, sizeof(dump_key)),
|
||||
mdbx_dump_val(&data->value, dump_value, sizeof(dump_value)));
|
||||
return false;
|
||||
}
|
||||
}
|
||||
} else if (unlikely(err != MDBX_EKEYMISMATCH))
|
||||
failure_perror("mdbx_cursor_put(insert-a) != MDBX_EKEYMISMATCH", err);
|
||||
failure_perror("mdbx_cursor_put(append) != MDBX_EKEYMISMATCH", err);
|
||||
|
||||
if (++txn_nops >= config.params.batch_write) {
|
||||
err = breakable_restart();
|
||||
@@ -166,6 +184,10 @@ bool testcase_append::run() {
|
||||
committed_inserted_number = inserted_number;
|
||||
committed_inserted_checksum = inserted_checksum;
|
||||
txn_nops = 0;
|
||||
if (!speculum_verify()) {
|
||||
log_notice("append: bailout breakable_restart");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
report(1);
|
||||
@@ -181,6 +203,10 @@ bool testcase_append::run() {
|
||||
}
|
||||
//----------------------------------------------------------------------------
|
||||
txn_begin(true);
|
||||
if (!speculum_verify()) {
|
||||
log_notice("append: bailout verify");
|
||||
return false;
|
||||
}
|
||||
cursor_renew();
|
||||
|
||||
MDBX_val check_key, check_data;
|
||||
@@ -209,7 +235,8 @@ bool testcase_append::run() {
|
||||
failure("read_count(%" PRIu64 ") != inserted_number(%" PRIu64 ")",
|
||||
read_count, inserted_number);
|
||||
|
||||
if (unlikely(read_checksum.value != inserted_checksum.value))
|
||||
if (unlikely(read_checksum.value != inserted_checksum.value) &&
|
||||
!keyvalue_maker.is_unordered())
|
||||
failure("read_checksum(0x%016" PRIu64 ") "
|
||||
"!= inserted_checksum(0x%016" PRIu64 ")",
|
||||
read_checksum.value, inserted_checksum.value);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -30,6 +30,10 @@
|
||||
#define _WIN32_WINNT 0x0601 /* Windows 7 */
|
||||
#endif
|
||||
#ifdef _MSC_VER
|
||||
/* Workaround for MSVC' header `extern "C"` vs `std::` redefinition bug */
|
||||
#if defined(__SANITIZE_ADDRESS__) && !defined(_DISABLE_VECTOR_ANNOTATION)
|
||||
#define _DISABLE_VECTOR_ANNOTATION
|
||||
#endif /* _DISABLE_VECTOR_ANNOTATION */
|
||||
#ifndef _CRT_SECURE_NO_WARNINGS
|
||||
#define _CRT_SECURE_NO_WARNINGS
|
||||
#endif /* _CRT_SECURE_NO_WARNINGS */
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -87,10 +87,11 @@ time from_ms(uint64_t ms) {
|
||||
time now_realtime() {
|
||||
#if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
|
||||
static void(WINAPI * query_time)(LPFILETIME);
|
||||
if (!query_time) {
|
||||
query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress(
|
||||
GetModuleHandle(TEXT("kernel32.dll")),
|
||||
"GetSystemTimePreciseAsFileTime");
|
||||
if (unlikely(!query_time)) {
|
||||
HMODULE hModule = GetModuleHandle(TEXT("kernel32.dll"));
|
||||
if (hModule)
|
||||
query_time = (void(WINAPI *)(LPFILETIME))GetProcAddress(
|
||||
hModule, "GetSystemTimePreciseAsFileTime");
|
||||
if (!query_time)
|
||||
query_time = GetSystemTimeAsFileTime;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
59
test/extra/maindb_ordinal.c++
Normal file
59
test/extra/maindb_ordinal.c++
Normal file
@@ -0,0 +1,59 @@
|
||||
#include "mdbx.h++"
|
||||
#include <iostream>
|
||||
#include <unistd.h>
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
unlink("." MDBX_DATANAME);
|
||||
unlink("." MDBX_LOCKNAME);
|
||||
|
||||
mdbx::env_managed env(".", mdbx::env_managed::create_parameters(),
|
||||
mdbx::env::operate_parameters());
|
||||
|
||||
using buffer =
|
||||
mdbx::buffer<mdbx::default_allocator, mdbx::default_capacity_policy>;
|
||||
auto txn = env.start_write();
|
||||
auto map = txn.create_map(nullptr, mdbx::key_mode::ordinal,
|
||||
mdbx::value_mode::single);
|
||||
#if 0 /* workaround */
|
||||
txn.commit();
|
||||
env.close();
|
||||
env = mdbx::env_managed(".", mdbx::env_managed::create_parameters(),
|
||||
mdbx::env::operate_parameters());
|
||||
txn = env.start_write();
|
||||
#endif
|
||||
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(8) << 8 * 0), buffer("a"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(7) << 8 * 1), buffer("b"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(6) << 8 * 2), buffer("c"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(5) << 8 * 3), buffer("d"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(4) << 8 * 4), buffer("e"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(3) << 8 * 5), buffer("f"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(2) << 8 * 6), buffer("g"));
|
||||
txn.insert(map, buffer::key_from_u64(UINT64_C(1) << 8 * 7), buffer("h"));
|
||||
txn.commit();
|
||||
|
||||
txn = env.start_read();
|
||||
auto cursor = txn.open_cursor(map);
|
||||
#if defined(__cpp_lib_string_view) && __cpp_lib_string_view >= 201606L
|
||||
if (cursor.to_first().value.string_view() == "a" &&
|
||||
cursor.to_next().value.string_view() == "b" &&
|
||||
cursor.to_next().value.string_view() == "c" &&
|
||||
cursor.to_next().value.string_view() == "d" &&
|
||||
cursor.to_next().value.string_view() == "e" &&
|
||||
cursor.to_next().value.string_view() == "f" &&
|
||||
cursor.to_next().value.string_view() == "g" &&
|
||||
cursor.to_next().value.string_view() == "h" &&
|
||||
!cursor.to_next(false).done && cursor.eof()) {
|
||||
std::cout << "OK\n";
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
std::cerr << "Fail\n";
|
||||
return EXIT_FAILURE;
|
||||
#else
|
||||
std::cerr << "Skipped since no std::string_view\n";
|
||||
return EXIT_SUCCESS;
|
||||
#endif /* __cpp_lib_string_view >= 201606L */
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2016-2022 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2016-2023 Leonid Yuriev <leo@yuriev.ru>.
|
||||
* Copyright 2015 Vladimir Romanov
|
||||
* <https://www.linkedin.com/in/vladimirromanov>, Yota Lab.
|
||||
*
|
||||
195
test/extra/upsert_alldups.c
Normal file
195
test/extra/upsert_alldups.c
Normal file
@@ -0,0 +1,195 @@
|
||||
//
|
||||
// libmdbx/test/extra/upsert_alldups.c
|
||||
//
|
||||
// Created by Masatoshi Fukunaga <https://gitflic.ru/user/mah0x211>
|
||||
// on 2023-01-31.
|
||||
//
|
||||
|
||||
#include "mdbx.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
static int dump(MDBX_cursor *cur) {
|
||||
MDBX_val key = {};
|
||||
MDBX_val data = {};
|
||||
int rc = mdbx_cursor_get(cur, &key, &data, MDBX_FIRST);
|
||||
|
||||
while (rc == 0) {
|
||||
printf("(%.*s) = (%.*s)\n", (int)key.iov_len, (const char *)key.iov_base,
|
||||
(int)data.iov_len, (const char *)data.iov_base);
|
||||
rc = mdbx_cursor_get(cur, &key, &data, MDBX_NEXT);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
static int clear(MDBX_cursor *cur) {
|
||||
MDBX_val key = {};
|
||||
MDBX_val data = {};
|
||||
int rc = mdbx_cursor_get(cur, &key, &data, MDBX_FIRST);
|
||||
|
||||
while (rc == 0) {
|
||||
rc = mdbx_cursor_del(cur, MDBX_ALLDUPS);
|
||||
if (rc) {
|
||||
return rc;
|
||||
}
|
||||
rc = mdbx_cursor_get(cur, &key, &data, MDBX_NEXT);
|
||||
}
|
||||
return (rc == MDBX_NOTFOUND) ? 0 : rc;
|
||||
}
|
||||
|
||||
static int put(MDBX_txn *txn, MDBX_dbi dbi, const char *k, const char *v,
|
||||
MDBX_put_flags_t flags) {
|
||||
MDBX_val key = {.iov_base = (void *)k, .iov_len = strlen(k)};
|
||||
MDBX_val data = {.iov_base = (void *)v, .iov_len = strlen(v)};
|
||||
return mdbx_put(txn, dbi, &key, &data, flags);
|
||||
}
|
||||
|
||||
int main(int argc, const char *argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
char *errmsg = NULL;
|
||||
MDBX_env *env = NULL;
|
||||
MDBX_txn *txn = NULL;
|
||||
MDBX_cursor *cur = NULL;
|
||||
MDBX_dbi dbi = 0;
|
||||
|
||||
unlink("." MDBX_DATANAME);
|
||||
unlink("." MDBX_LOCKNAME);
|
||||
|
||||
int rc = 0;
|
||||
if ((rc = mdbx_env_create(&env))) {
|
||||
errmsg = "failed to mdbx_env_create: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
if ((rc = mdbx_env_open(
|
||||
env, ".", MDBX_NOSUBDIR | MDBX_COALESCE | MDBX_LIFORECLAIM, 0644))) {
|
||||
errmsg = "failed to mdbx_env_open: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
if ((rc = mdbx_txn_begin(env, NULL, 0, &txn))) {
|
||||
errmsg = "failed to mdbx_txn_begin: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
if ((rc = mdbx_dbi_open(txn, NULL, MDBX_DUPSORT | MDBX_CREATE, &dbi))) {
|
||||
errmsg = "failed to mdbx_dbi_open: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
if ((rc = mdbx_cursor_open(txn, dbi, &cur))) {
|
||||
errmsg = "failed to mdbx_cursor_open: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
|
||||
#define DUMP() \
|
||||
do { \
|
||||
if ((rc = dump(cur)) && rc != MDBX_NOTFOUND) { \
|
||||
errmsg = "failed to mdbx_cursor_get(FIRST): %s\n"; \
|
||||
goto Fail; \
|
||||
} \
|
||||
puts(""); \
|
||||
} while (0)
|
||||
|
||||
#define PUTVAL(k, v, flags) \
|
||||
do { \
|
||||
if ((rc = put(txn, dbi, k, v, flags))) { \
|
||||
errmsg = "failed to mdbx_put: %s\n"; \
|
||||
goto Fail; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
puts("TEST WITH MULTIPLE KEYS ====================");
|
||||
// UPSERTING
|
||||
// MDBX_UPSERT:
|
||||
// Key is absent → Insertion (Insertion)
|
||||
// Key exist → Wanna to add new values (Overwrite by single new value)
|
||||
puts("insert multiple keys and values {");
|
||||
puts(" foo = bar, baz, qux");
|
||||
puts(" hello = world");
|
||||
puts("}");
|
||||
PUTVAL("foo", "bar", MDBX_UPSERT);
|
||||
PUTVAL("foo", "baz", MDBX_UPSERT);
|
||||
PUTVAL("foo", "qux", MDBX_UPSERT);
|
||||
PUTVAL("hello", "world", MDBX_UPSERT);
|
||||
DUMP();
|
||||
//
|
||||
// above code will output the fllowing;
|
||||
//
|
||||
// insert multiple values {
|
||||
// foo = bar, baz, qux
|
||||
// hello = world
|
||||
// }
|
||||
// (foo) = (bar)
|
||||
// (foo) = (baz)
|
||||
// (foo) = (qux)
|
||||
// (hello) = (world)
|
||||
//
|
||||
|
||||
// UPSERTING
|
||||
// MDBX_UPSERT + MDBX_ALLDUPS:
|
||||
// Key exist → Replace all values with a new one (Overwrite by single new
|
||||
// value)
|
||||
puts("overwrite by single new value: MDBX_UPSERT + MDBX_ALLDUPS {");
|
||||
puts(" foo = baa");
|
||||
puts("}");
|
||||
PUTVAL("foo", "baa", MDBX_UPSERT | MDBX_ALLDUPS);
|
||||
DUMP();
|
||||
// above code will output the fllowing;
|
||||
// overwrite by single new value {
|
||||
// foo = baa
|
||||
// }
|
||||
// (foo) = (baa)
|
||||
// (hello) = (world)
|
||||
if ((rc = clear(cur))) {
|
||||
errmsg = "failed to clear: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
DUMP();
|
||||
|
||||
puts("TEST WITH A SINGLE KEY ====================");
|
||||
// UPSERTING
|
||||
// MDBX_UPSERT:
|
||||
// Key is absent → Insertion (Insertion)
|
||||
// Key exist → Wanna to add new values (Overwrite by single new value)
|
||||
puts("insert single key and multiple values {");
|
||||
puts(" foo = bar, baz, qux");
|
||||
puts("}");
|
||||
PUTVAL("foo", "bar", MDBX_UPSERT);
|
||||
PUTVAL("foo", "baz", MDBX_UPSERT);
|
||||
PUTVAL("foo", "qux", MDBX_UPSERT);
|
||||
DUMP();
|
||||
//
|
||||
// above code will output the fllowing;
|
||||
//
|
||||
// insert: foo = bar, baz, qux
|
||||
// foo = bar
|
||||
// foo = baz
|
||||
// foo = qux
|
||||
|
||||
// UPSERTING
|
||||
// MDBX_UPSERT + MDBX_ALLDUPS:
|
||||
// Key exist → Replace all values with a new one (Overwrite by single new
|
||||
// value)
|
||||
puts("overwrite by single new value: MDBX_UPSERT + MDBX_ALLDUPS {");
|
||||
puts(" foo = baa");
|
||||
puts("}");
|
||||
PUTVAL("foo", "baa", MDBX_UPSERT | MDBX_ALLDUPS);
|
||||
DUMP();
|
||||
// above code outputs nothing.
|
||||
// all data associated with key has been deleted.
|
||||
// Is it a bug? Or, am I misunderstanding how to use it?
|
||||
|
||||
if ((rc = mdbx_txn_commit(txn))) {
|
||||
errmsg = "failed to mdbx_txn_commit: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
if ((rc = mdbx_env_close(env))) {
|
||||
errmsg = "failed to mdbx_env_close: %s\n";
|
||||
goto Fail;
|
||||
}
|
||||
return 0;
|
||||
|
||||
Fail:
|
||||
printf(errmsg, mdbx_strerror(rc));
|
||||
return EXIT_FAILURE;
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -227,7 +227,8 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id,
|
||||
|
||||
(void)thread_number;
|
||||
mapping = actor.keygen;
|
||||
salt = (actor.keygen.seed + actor_id) * UINT64_C(14653293970879851569);
|
||||
salt =
|
||||
(actor.keygen.seed + uint64_t(actor_id)) * UINT64_C(14653293970879851569);
|
||||
|
||||
base = actor.serial_base();
|
||||
}
|
||||
@@ -315,11 +316,12 @@ void __hot maker::mk_begin(const serial_t serial, const essentials ¶ms,
|
||||
out.value.iov_len = std::max(unsigned(params.minlen), length(serial));
|
||||
const auto variation = params.maxlen - params.minlen;
|
||||
if (variation) {
|
||||
if (serial % (variation + 1)) {
|
||||
if (serial % (variation + serial_t(1))) {
|
||||
auto refix = serial * UINT64_C(48835288005252737);
|
||||
refix ^= refix >> 32;
|
||||
out.value.iov_len = std::max(
|
||||
out.value.iov_len, params.minlen + 1 + size_t(refix) % variation);
|
||||
out.value.iov_len =
|
||||
std::max(out.value.iov_len,
|
||||
params.minlen + size_t(1) + size_t(refix) % variation);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -142,7 +142,7 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
|
||||
prefix.c_str(), level2str(priority), suffix.c_str());
|
||||
|
||||
va_list ones;
|
||||
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other stupid compilers */;
|
||||
memset(&ones, 0, sizeof(ones)) /* zap MSVC and other goofy compilers */;
|
||||
if (same_or_higher(priority, error))
|
||||
va_copy(ones, ap);
|
||||
vfprintf(last, format, ap);
|
||||
@@ -153,11 +153,11 @@ void output_nocheckloglevel_ap(const logging::loglevel priority,
|
||||
switch (end) {
|
||||
default:
|
||||
putc('\n', last);
|
||||
// fall through
|
||||
MDBX_CXX17_FALLTHROUGH; // fall through
|
||||
case '\n':
|
||||
fflush(last);
|
||||
last = nullptr;
|
||||
// fall through
|
||||
MDBX_CXX17_FALLTHROUGH; // fall through
|
||||
case ' ':
|
||||
case '_':
|
||||
case ':':
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -12,6 +12,7 @@ UNAME="$(uname -s 2>/dev/null || echo Unknown)"
|
||||
DB_UPTO_MB=17408
|
||||
PAGESIZE=min
|
||||
DONT_CHECK_RAM=no
|
||||
EXTRA=no
|
||||
|
||||
while [ -n "$1" ]
|
||||
do
|
||||
@@ -31,8 +32,9 @@ do
|
||||
echo "--dir PATH Specifies directory for test DB and other files (it will be cleared)"
|
||||
echo "--db-upto-mb NN Limits upper size of test DB to the NN megabytes"
|
||||
echo "--no-geometry-jitter Disable jitter for geometry upper-size"
|
||||
echo "--pagesize NN Use specified page size (256 is minimal and used by default) "
|
||||
echo "--dont-check-ram-size Don't check available RAM "
|
||||
echo "--pagesize NN Use specified page size (256 is minimal and used by default)"
|
||||
echo "--dont-check-ram-size Don't check available RAM"
|
||||
echo "--extra Iterate extra modes/flags"
|
||||
echo "--help Print this usage help and exit"
|
||||
exit -2
|
||||
;;
|
||||
@@ -136,7 +138,7 @@ do
|
||||
PAGESIZE=$((1024*64))
|
||||
;;
|
||||
*)
|
||||
echo "Invalig page size '$2'"
|
||||
echo "Invalid page size '$2'"
|
||||
exit -2
|
||||
;;
|
||||
esac
|
||||
@@ -145,6 +147,9 @@ do
|
||||
--dont-check-ram-size)
|
||||
DONT_CHECK_RAM=yes
|
||||
;;
|
||||
--extra)
|
||||
EXTRA=yes
|
||||
;;
|
||||
*)
|
||||
echo "Unknown option '$1'"
|
||||
exit -2
|
||||
@@ -350,9 +355,12 @@ else
|
||||
}
|
||||
fi
|
||||
|
||||
syncmodes=("" ,+nosync-safe ,+nosync-utterly)
|
||||
options=(writemap lifo notls perturb)
|
||||
|
||||
if [ "$EXTRA" != "no" ]; then
|
||||
options=(writemap lifo notls perturb nomeminit nordahead)
|
||||
else
|
||||
options=(writemap lifo notls)
|
||||
fi
|
||||
syncmodes=("" ,+nosync-safe ,+nosync-utterly ,+nometasync)
|
||||
function join { local IFS="$1"; shift; echo "$*"; }
|
||||
|
||||
function bits2options {
|
||||
@@ -414,65 +422,89 @@ for nops in 10 33 100 333 1000 3333 10000 33333 100000 333333 1000000 3333333 10
|
||||
split=30
|
||||
caption="Probe #$((++count)) int-key,with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,int-data, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.integer --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
|
||||
split=24
|
||||
caption="Probe #$((++count)) int-key,with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,int-data, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.integer --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
|
||||
split=16
|
||||
caption="Probe #$((++count)) int-key,w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,int-data, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.integer --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
|
||||
if [ "$EXTRA" != "no" ]; then
|
||||
split=10
|
||||
caption="Probe #$((++count)) int-key,w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,int-data, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.integer --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) with-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
fi
|
||||
|
||||
split=4
|
||||
caption="Probe #$((++count)) int-key,w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) int-key,int-data, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=+key.integer,+data.integer --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=max \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
caption="Probe #$((++count)) w/o-dups, split=${split}, case $((++subcase)) of ${cases}" probe \
|
||||
--pagesize=$PAGESIZE --size-upper-upto=${db_size_mb}M --table=-data.dups --keygen.split=${split} --keylen.min=min --keylen.max=max --datalen.min=min --datalen.max=1111 \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%3]} \
|
||||
--nops=$nops --batch.write=$wbatch --mode=$(bits2options $bits)${syncmodes[count%4]} \
|
||||
--keygen.seed=${seed}
|
||||
done # options
|
||||
loop=$((loop + 1))
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -129,8 +129,7 @@ void actor_params::set_defaults(const std::string &tmpdir) {
|
||||
#endif
|
||||
|
||||
pathname_db = tmpdir + "mdbx-test.db";
|
||||
mode_flags = MDBX_NOSUBDIR | MDBX_WRITEMAP | MDBX_SAFE_NOSYNC |
|
||||
MDBX_NOMEMINIT | MDBX_COALESCE | MDBX_LIFORECLAIM | MDBX_ACCEDE;
|
||||
mode_flags = MDBX_NOSUBDIR | MDBX_WRITEMAP | MDBX_SYNC_DURABLE | MDBX_ACCEDE;
|
||||
table_flags = MDBX_DUPSORT;
|
||||
|
||||
size_lower = -1;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -248,7 +248,7 @@ Environment:
|
||||
CommandLine.push_back('"');
|
||||
|
||||
for (auto It = Argument.begin();; ++It) {
|
||||
unsigned NumberBackslashes = 0;
|
||||
size_t NumberBackslashes = 0;
|
||||
|
||||
while (It != Argument.end() && *It == '\\') {
|
||||
++It;
|
||||
@@ -435,7 +435,7 @@ void osal_udelay(size_t us) {
|
||||
unsigned timeslice_ms = 1;
|
||||
while (timeBeginPeriod(timeslice_ms) == TIMERR_NOCANDO)
|
||||
++timeslice_ms;
|
||||
threshold_us = timeslice_ms * 1500u;
|
||||
threshold_us = timeslice_ms * size_t(1500);
|
||||
assert(threshold_us > 0);
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -100,7 +100,7 @@ int testcase::hsr_callback(const MDBX_env *env, const MDBX_txn *txn,
|
||||
info.mi_geo.current >= info.mi_geo.upper)) {
|
||||
osal_yield();
|
||||
if (retry > 0)
|
||||
osal_udelay(retry * 100);
|
||||
osal_udelay(retry * size_t(100));
|
||||
return MDBX_RESULT_FALSE /* retry / wait until reader done */;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
@@ -101,10 +101,10 @@ class testcase;
|
||||
|
||||
class registry {
|
||||
struct record {
|
||||
actor_testcase id;
|
||||
actor_testcase id = ac_none;
|
||||
std::string name;
|
||||
bool (*review_params)(actor_params &);
|
||||
testcase *(*constructor)(const actor_config &, const mdbx_pid_t);
|
||||
bool (*review_params)(actor_params &) = nullptr;
|
||||
testcase *(*constructor)(const actor_config &, const mdbx_pid_t) = nullptr;
|
||||
};
|
||||
std::unordered_map<std::string, const record *> name2id;
|
||||
std::unordered_map<int, const record *> id2record;
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2017-2022 Leonid Yuriev <leo@yuriev.ru>
|
||||
* Copyright 2017-2023 Leonid Yuriev <leo@yuriev.ru>
|
||||
* and other libmdbx authors: please see AUTHORS file.
|
||||
* All rights reserved.
|
||||
*
|
||||
|
||||
Reference in New Issue
Block a user