Compare commits

...

61 Commits

Author SHA1 Message Date
Леонид Юрьев (Leonid Yuriev)
9b8291457b mdbx: выпуск 0.12.5 "Динамо"
Стабилизирующий выпуск с исправлением обнаруженных ошибок и устранением
недочетов, в день 100-летнего юбилея спортивного общества [«Динамо»](https://ru.wikipedia.org/wiki/Динамо_(спортивное_общество)).

Благодарности:
--------------

 - 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()` для устранения предупреждений статических анализаторов.

16 files changed, 686 insertions(+), 247 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
2023-04-18 11:03:31 +03:00
Леонид Юрьев (Leonid Yuriev)
0f13d91a0e mdbx: минорное переформатирование и пополнение ChangeLog для прошлых выпусков. 2023-04-18 10:54:39 +03:00
Леонид Юрьев (Leonid Yuriev)
d40b69ec7a mdbx: обновление ChangeLog. 2023-04-16 21:24:58 +03:00
Леонид Юрьев (Leonid Yuriev)
7489c8ce28 mdbx: рефакторинг проверки "когерентности" мета-страниц. 2023-04-05 21:40:00 +03:00
Леонид Юрьев (Leonid Yuriev)
caddf07889 mdbx: корректировка osal_vasprintf() для устранения предупреждений статических анализаторов. 2023-04-05 21:40:00 +03:00
Леонид Юрьев (Leonid Yuriev)
74256efc64 mdbx: refine comment. 2023-04-05 21:40:00 +03:00
Леонид Юрьев (Leonid Yuriev)
e47a91bf7c mdbx-test: совместимость со libstdc++ без std::string_view. 2023-04-05 08:57:16 +03:00
Леонид Юрьев (Leonid Yuriev)
3ace3c27b8 mdbx++: добавление typename mdbx::default_allocator. 2023-04-01 11:10:40 +03:00
Леонид Юрьев (Leonid Yuriev)
bcebfb4b4c mdbx: дополнение ChangeLog. 2023-03-31 22:49:25 +03:00
Леонид Юрьев (Leonid Yuriev)
b5400f9a35 mdbx-test: добавление мини-теста для проверки MainDB с целочисленными ключами. 2023-03-31 22:31:09 +03:00
Леонид Юрьев (Leonid Yuriev)
8a44d57fab mdbx++: добавление вариантов buffer::key_from() с явным именованием по типу данных. 2023-03-31 00:56:05 +03:00
Леонид Юрьев (Leonid Yuriev)
fdb2b5b0f1 mdbx: обнуление компараторов при пересоздании MainDB. 2023-03-31 00:55:03 +03:00
Леонид Юрьев (Leonid Yuriev)
95cb73646e mdbx: корректировка отладочного кода для устранения срабатывания assert-проверки. 2023-03-26 22:54:50 +03:00
Леонид Юрьев (Leonid Yuriev)
b2d16d32aa mdbx: дополнение ChangeLog. 2023-03-20 15:56:19 +03:00
Леонид Юрьев (Leonid Yuriev)
e0be0d9a5e mdbx: корректировка экспорта устаревших функций API. 2023-03-20 15:48:04 +03:00
Леонид Юрьев (Leonid Yuriev)
2ba7051719 mdbx: удаление из node_read_bigdata() дублирующей диагностики.
Аналогичные проверки и предупреждения выполняются при чтении страниц в режиме `MDBX_VALIDATION`.
2023-03-20 14:39:09 +03:00
Леонид Юрьев (Leonid Yuriev)
04ed388761 mdbx-test: добавление extra/upsert_alldups. 2023-03-20 14:38:02 +03:00
Леонид Юрьев (Leonid Yuriev)
da4e2ab254 mdbx-doc: исправление ссылок в описании mdbx_env_set_geometry(). 2023-03-17 10:54:40 +03:00
Леонид Юрьев (Leonid Yuriev)
53177e483c mdbx: выпуск 0.12.4 "Арта-333"
Стабилизирующий выпуск с исправлением обнаруженных ошибок, устранением
недочетов и технических долгов. Ветка 0.12 считается готовой к
продуктовому использованию, получает статус стабильной и далее будет
получать только исправление ошибок. Разработка будет продолжена в ветке
0.13, а ветка 0.11 становится архивной.

Благодарности:
--------------

 - 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.

Исправления (без корректировок новых функций):
----------------------------------------------

 - Устранен регресс после коммита 474391c83c,
   приводящий к возврату 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`.

63 files changed, 1161 insertions(+), 569 deletions(-)
Signed-off-by: Леонид Юрьев (Leonid Yuriev) <leo@yuriev.ru>
2023-03-03 23:23:08 +03:00
Леонид Юрьев (Leonid Yuriev)
ad93633d10 mdbx-tools: вывод всех счетчиков page-operations в mdbx_stat. 2023-03-03 21:18:35 +03:00
Леонид Юрьев (Leonid Yuriev)
f17c55a872 mdbx: обновление ChangeLog. 2023-03-02 16:34:19 +03:00
Леонид Юрьев (Leonid Yuriev)
7db014c4fc mdbx++: добавление в C++ API поддержки расширенных опций времени выполнения enum MDBX_option_t.
https://gitflic.ru/project/erthink/libmdbx/issue/4
2023-03-01 23:22:50 +03:00
Леонид Юрьев (Leonid Yuriev)
22405885f6 mdbx: корректировка излишней assert-проверки внутри override_meta(). 2023-03-01 01:09:10 +03:00
Леонид Юрьев (Leonid Yuriev)
2ae7bfd9be mdbx-make: актуализация списков для целей cross-gcc и cross-qemu. 2023-02-28 22:52:28 +03:00
Леонид Юрьев (Leonid Yuriev)
8f87ab252e mdbx: дополнение ChangeLog. 2023-02-28 00:52:40 +03:00
Леонид Юрьев (Leonid Yuriev)
800bd55ab9 mdbx-test: добавление опции --extra в скрипт test/long_stochastic.sh 2023-02-28 00:50:48 +03:00
Леонид Юрьев (Leonid Yuriev)
5c52adf358 mdbx-test: расширение набора режимов перебираемых скриптом test/long_stochastic.sh 2023-02-28 00:50:48 +03:00
Leonid Yuriev
6d74b10db1 mdbx: поддержка ASAN (Address Sanitizer) при сборке посредством MSVC. 2023-02-28 00:50:30 +03:00
Леонид Юрьев (Leonid Yuriev)
359489e271 mdbx: исправление семантической опечатки в комментарии о режиме работы. 2023-02-27 16:59:10 +03:00
Леонид Юрьев (Leonid Yuriev)
5f690bbc4f mdbx-test: по-умолчанию работа в режиме MDBX_SYNC_DURABLE. 2023-02-27 16:59:10 +03:00
Леонид Юрьев (Leonid Yuriev)
1b6e32071c mdbx: повторное "устранение" предупреждений MSVC Static Analyzer (aka Prefast).
Никаких значимых изменений, только обход "странностей" в MSVC.

Как оказалось MSVC распространяет действие директивы
`pragma(warning(supppress:#))` строго на следующую строку, даже если эта
строка является продолжением комментария начатого в самой директиве
и/или не содержит синтаксических конструкций языка.

Поэтому большинство из добавленных ранее директив для подавления ложных
предупреждений, перестало работать после переформатирования исходного
кода.
2023-02-27 16:59:06 +03:00
Леонид Юрьев (Leonid Yuriev)
29d12f1fc3 mdbx-doc: добавлено примечание к опции MDBX_HAVE_BUILTIN_CPU_SUPPORTS. 2023-02-14 12:09:44 +03:00
Леонид Юрьев (Leonid Yuriev)
2ea9fbe51b mdbx: дополнение ChangeLog. 2023-02-13 20:57:43 +03:00
Леонид Юрьев (Leonid Yuriev)
57ca0d6e1b mdbx: корректировка макросов __cold/__hot.
В том числе для устранения проблемы
`error: inlining failed in call to ‘always_inline FOO(...)’: target specific option mismatch`
при сборке посредством GCC >10.x для SH4.
2023-02-13 20:57:43 +03:00
Леонид Юрьев (Leonid Yuriev)
b8092dd0db mdbx: устранение ложного предупреждения GCC при сборке для SH4. 2023-02-13 16:29:47 +03:00
Леонид Юрьев (Leonid Yuriev)
8fba5ac8d8 mdbx: устранение излишней assert-проверки внутри override_meta(). 2023-02-12 23:27:39 +03:00
Леонид Юрьев (Leonid Yuriev)
c9d11cbac1 mdbx: дополнение ChangeLog. 2023-02-11 07:35:56 +03:00
Леонид Юрьев (Leonid Yuriev)
25e958f081 mdbx: устранение всех предупреждений статического анализатора MSVC (все несущественные или ложные). 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
7f5ea6d3b8 mdbx: корректировка прототипа __asan_default_options(). 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
e51140fe48 mdbx-doc: корректировка doxygen-описания C++ API, в особенности C++20 concepts. 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
bd35fe8970 mdbx-doc: добавление doxygen-описания для API с широкими символами. 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
1684d17b0f mdbx-windows: поддержка char-версии mdbx_env_get_path(). 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
ebbe98afa5 mdbx-windows: ликвидация макроса OSAL_MB2WIDE(). 2023-02-11 00:26:06 +03:00
Леонид Юрьев (Leonid Yuriev)
351a30f186 mdbx-windows: не расходуем стек под буферы для wchar-преобразования путей. 2023-02-09 22:37:31 +03:00
Леонид Юрьев (Leonid Yuriev)
2a41b24876 mdbx++: уточнение const и noexcept для нескольких методов. 2023-02-09 15:14:39 +03:00
Леонид Юрьев (Leonid Yuriev)
fb827959a9 mdbx: исправление put(MDBX_UPSERT+MDBX_ALLDUPS) для случая замены всех значений в subDb.
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.

Fixes https://gitflic.ru/project/erthink/libmdbx/issue/8

Thanks Masatoshi Fukunaga <https://gitflic.ru/user/mah0x211> for reporting.
2023-02-01 01:04:24 +03:00
Леонид Юрьев (Leonid Yuriev)
209f784ee7 mdbx: исправление assert-проверок внутри dxb_resize().
Устранение регресса после a484a1f89b.

Проверка `prev_limit_pgno >= used_pgno` правомочна только в части сценариев,
но не в общем случае.
2023-01-23 23:54:11 +03:00
Леонид Юрьев (Leonid Yuriev)
68ebbe1fde mdbx: Обновление ChangeLog. 2023-01-18 18:34:52 +03:00
Леонид Юрьев (Leonid Yuriev)
486711945d mdbx-doc: исправление copy&paste опечатки в "Getting started". 2023-01-18 18:34:25 +03:00
Леонид Юрьев (Leonid Yuriev)
3ade7c7ba1 mdbx: обновление статуса MithrilDB. 2023-01-16 19:12:08 +03:00
Леонид Юрьев (Leonid Yuriev)
c01f025bfa mdbx: обновление года на 2023. 2023-01-16 16:32:02 +03:00
Леонид Юрьев (Leonid Yuriev)
a484a1f89b mdbx: рефакторинг dxb_resize() и связанного кода.
В том числе, для устранения срабатывания assert-проверки
`size_bytes == env->me_dxb_mmap.current` в специфических многопоточных
сценариях использования.

Проверка срабатывала только в отладочных сборках, при специфическом
наложении во времени читающей и пишущей транзакции в разных потоках,
одновременно с изменением размера БД.

Кроме срабатывание проверки, каких-либо других последствий не возникало.
2023-01-16 02:20:56 +03:00
Леонид Юрьев (Leonid Yuriev)
0979a93a78 mdbx: добавлено примечание об ошибке MinGW MSYS2. 2023-01-12 17:01:27 +03:00
Леонид Юрьев (Leonid Yuriev)
a98c73f4f6 mdbx-cmake: вызов mdbx_chk в режиме чтения-записи для проверки MDBX_EXCLUSIVE в этом режиме. 2023-01-12 17:01:27 +03:00
Leonid Yuriev
9e15bd9b29 mdbx-windows: устранение регресса ERROR_SHARING_VIOLATION в режиме MDBX_EXCLUSIVE.
Спасибо maxc0d3r@protonmail.com за сообщение о проблеме.
2023-01-12 17:01:27 +03:00
Leonid Yuriev
0159f97e94 mdbx: ограничиваем размер отображения при коротком read-only файле.
Цель в предотвращении ошибки ERROR_NOT_ENOUGH_MEMORY в Windows, которая
совсем не информативна для пользователя и возникает в этом случае (когда
файл открыт read-only и короче запрошенного размера).
2023-01-12 01:53:22 +03:00
Леонид Юрьев (Leonid Yuriev)
56050f201f mdbx: обновление ChangeLog. 2023-01-10 15:03:38 +03:00
Леонид Юрьев (Leonid Yuriev)
525c4a55a4 mdbx: fix English typos.
Thanks to Dimitris Apostolou <dimitris.apostolou@icloud.com>
2023-01-10 14:16:08 +03:00
Леонид Юрьев (Leonid Yuriev)
702c67fc38 mdbx-test: доработка append-теста.
- добавлен speculum-контроль;
- с вероятностью 1/8 генерируются не-последовательные/не-упорядоченные ключи для проверки возврата MDBX_EKEYMISMATH;
- игнорирование расхождение хеша последовательности для не-последовательных ключей.
2023-01-09 23:51:34 +03:00
Леонид Юрьев (Leonid Yuriev)
3da23da7b3 mdbx: косметический рефакторинг контроля MDBX_APPEND. 2023-01-09 21:39:42 +03:00
Леонид Юрьев (Leonid Yuriev)
16cda5c2e8 mdbx: исправление опечаток в ChangeLog. 2023-01-08 12:40:44 +03:00
66 changed files with 1845 additions and 814 deletions

View File

@@ -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.
##

View File

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

View File

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

View File

@@ -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 && \

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -38,4 +38,4 @@ including creating [merge-request](https://gitflic.ru/project/erthink/libmdbx/me
---
\section MithrilDB MithrilDB
\section MithrilDB MithrilDB and Future

View File

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

View File

@@ -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
View File

@@ -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++
View File

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

View File

@@ -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.
*

View File

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

File diff suppressed because it is too large Load Diff

View File

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

View File

@@ -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.
*

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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.
*

View File

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

View File

@@ -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.
*

View File

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

View File

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

View File

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

View File

@@ -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;
}

View File

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

View File

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

View File

@@ -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 &params) {
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);

View File

@@ -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 */

View File

@@ -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.
*

View File

@@ -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;
}

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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.
*

View 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 */
}

View File

@@ -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
View 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;
}

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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 &params,
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);
}
}

View File

@@ -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.
*

View File

@@ -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 ':':

View File

@@ -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.
*

View File

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

View File

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

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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);
}

View File

@@ -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.
*

View File

@@ -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 */;
}

View File

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

View File

@@ -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.
*

View File

@@ -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.
*

View File

@@ -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.
*