Skip to content

Commit

Permalink
save
Browse files Browse the repository at this point in the history
  • Loading branch information
AskAlexSharov committed Jul 20, 2024
1 parent a014903 commit 0740b51
Show file tree
Hide file tree
Showing 13 changed files with 179 additions and 101 deletions.
93 changes: 56 additions & 37 deletions mdbx/mdbx.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@

#define xMDBX_ALLOY 1 /* alloyed build */

#define MDBX_BUILD_SOURCERY d79e72327b34c872db0c1e8bde5a171c679a0abe4bf48a8fafb5c6e131edfef6_v0_13_0_76_g32df0ad1
#define MDBX_BUILD_SOURCERY 8a7ed0d2f8aeb7b9717769da24fc25220b34661de75b717be86738f994901302_v0_13_0_86_g22776ad5


#define LIBMDBX_INTERNALS
Expand Down Expand Up @@ -1145,7 +1145,7 @@ typedef CRITICAL_SECTION osal_fastmutex_t;

#if !defined(_MSC_VER) && !defined(__try)
#define __try
#define __except(COND) if (false)
#define __except(COND) if (/* (void)(COND), */ false)
#endif /* stub for MSVC's __try/__except */

#if MDBX_WITHOUT_MSVC_CRT
Expand Down Expand Up @@ -18189,11 +18189,13 @@ __cold int mdbx_enumerate_subdb(const MDBX_txn *txn, MDBX_subdb_enum_func *func,
stat_get(tree, &stat, sizeof(stat));
rc = func(ctx, txn, &name, tree->flags, &stat, dbi);
if (rc != MDBX_SUCCESS)
break;
goto bailout;
}
txn->cursors[MAIN_DBI] = cx.outer.next;
rc = (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;

return (rc == MDBX_NOTFOUND) ? MDBX_SUCCESS : rc;
bailout:
txn->cursors[MAIN_DBI] = cx.outer.next;
return rc;
}
/// \copyright SPDX-License-Identifier: Apache-2.0
/// \author Леонид Юрьев aka Leonid Yuriev <[email protected]> \date 2015-2024
Expand Down Expand Up @@ -29290,11 +29292,10 @@ MDBX_INTERNAL int osal_ioring_add(osal_ioring_t *ior, const size_t offset,
item->sgv[0].Buffer = PtrToPtr64(data);
for (size_t i = 1; i < segments; ++i) {
data = ptr_disp(data, ior->pagesize);
item->sgv[slots_used].Buffer = PtrToPtr64(data);
item->sgv[i].Buffer = PtrToPtr64(data);
}
item->sgv[slots_used].Buffer = 0;
item->sgv[slots_used = segments].Buffer = 0;
assert((item->single.iov_len & ior_WriteFile_flag) == 0);
slots_used = segments;
}
ior->last_bytes = bytes;
ior_last_sgvcnt(ior, item) = slots_used;
Expand Down Expand Up @@ -29358,6 +29359,17 @@ MDBX_INTERNAL void osal_ioring_walk(osal_ioring_t *ior, iov_ctx_t *ctx,
}
}

#if defined(_WIN32) || defined(_WIN64)
static pgno_t safe_get_pgno(const page_t* page) {
SIZE_T NumberOfBytesRead = 0;
pgno_t pgno = P_INVALID;
if (ReadProcessMemory(GetCurrentProcess(), &page->pgno, &pgno, sizeof(pgno), &NumberOfBytesRead)
&& NumberOfBytesRead == sizeof(pgno))
return pgno;
return P_INVALID;
}
#endif

MDBX_INTERNAL osal_ioring_write_result_t
osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
osal_ioring_write_result_t r = {MDBX_SUCCESS, 0};
Expand Down Expand Up @@ -29399,12 +29411,12 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
} else {
r.err = (int)GetLastError();
if (unlikely(r.err != ERROR_IO_PENDING)) {
ERROR("%s: fd %p, item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
void *data = Ptr64ToPtr(item->sgv[0].Buffer);
ERROR("%s: fd %p, item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"WriteFileGather", fd, __Wpedantic_format_voidptr(item),
item - ior->pool, ((page_t *)item->single.iov_base)->pgno,
bytes, item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32),
r.err);
item - ior->pool, data, safe_get_pgno((page_t *)data), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32), r.err);
goto bailout_rc;
}
assert(wait_for > ior->event_pool + ior->event_stack);
Expand All @@ -29421,22 +29433,23 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
r.err = (int)GetLastError();
switch (r.err) {
default:
ERROR("%s: fd %p, item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
ERROR("%s: fd %p, item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"WriteFileEx", fd, __Wpedantic_format_voidptr(item),
item - ior->pool, ((page_t *)item->single.iov_base)->pgno,
bytes, item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32),
r.err);
item - ior->pool, item->single.iov_base,
safe_get_pgno((page_t *)item->single.iov_base), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32), r.err);
goto bailout_rc;
case ERROR_NOT_FOUND:
case ERROR_USER_MAPPED_FILE:
case ERROR_LOCK_VIOLATION:
WARNING(
"%s: fd %p, item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
"WriteFileEx", fd, __Wpedantic_format_voidptr(item),
item - ior->pool, ((page_t *)item->single.iov_base)->pgno, bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32), r.err);
WARNING("%s: fd %p, item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"WriteFileEx", fd, __Wpedantic_format_voidptr(item),
item - ior->pool, item->single.iov_base,
safe_get_pgno((page_t *)item->single.iov_base), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32),
r.err);
SleepEx(0, true);
goto retry;
case ERROR_INVALID_USER_BUFFER:
Expand All @@ -29454,10 +29467,11 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
if (!WriteFile(fd, item->single.iov_base, (DWORD)bytes, &written,
&item->ov)) {
r.err = (int)GetLastError();
ERROR("%s: fd %p, item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
ERROR("%s: fd %p, item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"WriteFile", fd, __Wpedantic_format_voidptr(item),
item - ior->pool, ((page_t *)item->single.iov_base)->pgno, bytes,
item - ior->pool, item->single.iov_base,
safe_get_pgno((page_t *)item->single.iov_base), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32), r.err);
goto bailout_rc;
} else if (unlikely(written != bytes)) {
Expand Down Expand Up @@ -29511,7 +29525,9 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
assert(ior->async_waiting == ior->async_completed);
for (ior_item_t *item = ior->pool; item <= ior->last;) {
size_t i = 1, bytes = item->single.iov_len - ior_WriteFile_flag;
void *data = item->single.iov_base;
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);
Expand All @@ -29522,11 +29538,10 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
if (!HasOverlappedIoCompleted(&item->ov)) {
DWORD written = 0;
if (unlikely(!GetOverlappedResult(fd, &item->ov, &written, true))) {
ERROR("%s: item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
ERROR("%s: item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"GetOverlappedResult", __Wpedantic_format_voidptr(item),
item - ior->pool, ((page_t *)item->single.iov_base)->pgno,
bytes,
item - ior->pool, data, safe_get_pgno((page_t *)data), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32),
(int)GetLastError());
goto bailout_geterr;
Expand All @@ -29544,10 +29559,10 @@ osal_ioring_write(osal_ioring_t *ior, mdbx_filehandle_t fd) {
if ((r.err & 0x80000000) &&
GetOverlappedResult(nullptr, &item->ov, &written, true))
r.err = (int)GetLastError();
ERROR("%s: item %p (%zu), pgno %u, bytes %zu, offset %" PRId64
", err %d",
ERROR("%s: item %p (%zu), addr %p pgno %u, bytes %zu,"
" offset %" PRId64 ", err %d",
"Result", __Wpedantic_format_voidptr(item), item - ior->pool,
((page_t *)item->single.iov_base)->pgno, bytes,
data, safe_get_pgno((page_t *)data), bytes,
item->ov.Offset + ((uint64_t)item->ov.OffsetHigh << 32),
(int)GetLastError());
goto bailout_rc;
Expand Down Expand Up @@ -32040,6 +32055,10 @@ __cold int mdbx_get_sysraminfo(intptr_t *page_size, intptr_t *total_pages,
#include <sys/random.h>
#endif /* sys/random.h */

#if defined(_WIN32) || defined(_WIN64)
#include <wincrypt.h>
#endif /* Windows */

MDBX_INTERNAL bin128_t osal_guid(const MDBX_env *env) {
struct {
uint64_t begin, end, cputime;
Expand Down Expand Up @@ -40268,9 +40287,9 @@ __dll_export
0,
13,
0,
76,
{"2024-07-12T11:43:12+03:00", "3bd50abdfc8d371f58405b04bffa3155cf40536a", "32df0ad1ebcb7d36ec744c94d8fa134873e7f011",
"v0.13.0-76-g32df0ad1"},
86,
{"2024-07-19T21:26:39+03:00", "e20ca6a79c305ac06cad8a8ef3752cf58bccc9d1", "22776ad5bbc3a409bb0be8c28ffb8065a6bc6287",
"v0.13.0-86-g22776ad5"},
sourcery};

__dll_export
Expand Down
21 changes: 16 additions & 5 deletions mdbx/mdbx.h
Original file line number Diff line number Diff line change
Expand Up @@ -4270,9 +4270,10 @@ LIBMDBX_API int mdbx_txn_reset(MDBX_txn *txn);
* или перезапущена в любой момент посредством \ref mdbx_txn_abort(),
* \ref mdbx_txn_reset() и \ref mdbx_txn_renew(), соответственно.
*
* \see long-lived-read
* \see mdbx_txn_unpark()
* \see mdbx_txn_flags()
* \see mdbx_env_set_hsr()
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
*
* \param [in] txn Транзакция чтения запущенная посредством
* \ref mdbx_txn_begin().
Expand All @@ -4293,9 +4294,9 @@ LIBMDBX_API int mdbx_txn_park(MDBX_txn *txn, bool autounpark);
* её перезапуск аналогично \ref mdbx_txn_renew(), либо транзакция сбрасывается
* и возвращается код ошибки \ref MDBX_OUSTED.
*
* \see long-lived-read
* \see mdbx_txn_park()
* \see mdbx_txn_flags()
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
*
* \param [in] txn Транзакция чтения запущенная посредством
* \ref mdbx_txn_begin() и затем припаркованная
Expand Down Expand Up @@ -4583,17 +4584,24 @@ typedef int(MDBX_subdb_enum_func)(void *ctx, const MDBX_txn *txn,
const struct MDBX_stat *stat,
MDBX_dbi dbi) MDBX_CXX17_NOEXCEPT;

/** \brief Enumerate the entries in the reader lock table.
/** \brief Перечисляет пользовательские именнованные таблицы.
*
* Производит перечисление пользовательских именнованных таблиц, вызывая
* специфицируемую пользователем функцию-визитер для каждой именованной таблицы.
* Перечисление продолжается до исчерпания именованных таблиц, либо до возврата
* отличного от нуля результата из заданной пользователем функции, которое будет
* сразу возвращено в качестве результата.
*
* \ingroup c_statinfo
* \see MDBX_subdb_enum_func
*
* \param [in] txn Транзакция запущенная посредством
* \ref mdbx_txn_begin().
* \param [in] func Указатель на пользовательскую функцию-перечислитель
* \param [in] func Указатель на пользовательскую функцию
* с сигнатурой \ref MDBX_subdb_enum_func,
* которая будет вызвана для каждой таблицы.
* \param [in] ctx Указатель на некоторый контект, который будет передан
* в функцию-перечислитель как есть.
* в функцию `func()` как есть.
*
* \returns Ненулевое значение кода ошибки, либо 0 при успешном выполнении. */
LIBMDBX_API int mdbx_enumerate_subdb(const MDBX_txn *txn,
Expand Down Expand Up @@ -6120,6 +6128,7 @@ LIBMDBX_API int mdbx_thread_unregister(const MDBX_env *env);
* with a "long-lived" read transactions.
* \see mdbx_env_set_hsr()
* \see mdbx_env_get_hsr()
* \see mdbx_txn_park()
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
*
* Using this callback you can choose how to resolve the situation:
Expand Down Expand Up @@ -6194,6 +6203,7 @@ typedef int(MDBX_hsr_func)(const MDBX_env *env, const MDBX_txn *txn,
*
* \see MDBX_hsr_func
* \see mdbx_env_get_hsr()
* \see mdbx_txn_park()
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
*
* \param [in] env An environment handle returned
Expand All @@ -6209,6 +6219,7 @@ LIBMDBX_API int mdbx_env_set_hsr(MDBX_env *env, MDBX_hsr_func *hsr_callback);
* recycled.
* \see MDBX_hsr_func
* \see mdbx_env_set_hsr()
* \see mdbx_txn_park()
* \see <a href="intro.html#long-lived-read">Long-lived read transactions</a>
*
* \param [in] env An environment handle returned by \ref mdbx_env_create().
Expand Down
22 changes: 20 additions & 2 deletions mdbxdist/ChangeLog.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
использования блокировок, управляемый опцией сборки
`MDBX_ENABLE_DBI_LOCKFREE`, которая включена по-умолчанию.

- Поддержка "парковки" читающих транзакций с их вытеснением ради
переработки старых MVCC-снимков и предотвращения проблем вызываемых
приостановкой переработки мусора. Механизм парковки и вытеснения
припаркованных транзакций является как дополнением, так и более простой
в использовании альтернативой обратному вызову
[Handle-Slow-Readers](https://libmdbx.dqdkfa.ru/group__c__err.html#ga2cb11b56414c282fe06dd942ae6cade6).
Для удобства функции `mdbx_txn_park()` и `mdbx_txn_unpack()` имеют
дополнительные аргументы, позволяющие запросить автоматическую
"распарковку" припаркованных и перезапуск вытесненных транзакций.

- Расширение API позиционирования курсоров более удобными и очевидными
операциями по аналогии условиям `<`, `<=`, `==`, `>=`, `>` как для
ключей, так и для пар ключ-значение.
Expand Down Expand Up @@ -65,6 +75,9 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
- Функция `mdbx_preopen_snapinfo()` для получения информации о БД без
её открытия.

- Функция `mdbx_enumerate_subdb()` для получение информации
об именованных пользовательских таблицах.

- Поддержка функций логирования обратного вызова без функционала
`vprintf()`, что существенно облегчает использование логирования в
привязках к другим языкам программирования.
Expand All @@ -75,13 +88,17 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic

- Опция `MDBX_opt_prefer_waf_insteadof_balance`.

- Опции `MDBX_opt_subpage_limit`, `MDBX_opt_subpage_room_threshold`, `MDBX_opt_subpage_reserve_prereq`, `MDBX_opt_subpage_reserve_limit`.
- Опции `MDBX_opt_subpage_limit`, `MDBX_opt_subpage_room_threshold`,
`MDBX_opt_subpage_reserve_prereq`, `MDBX_opt_subpage_reserve_limit`.

- Управление основной блокировкой lock/unlock/upgrade/downgrade для координации пишущих транзакций.

- Функции `mdbx_limits_keysize_min()` и `mdbx_limits_valsize_min()` для
получения нижней границы длины ключей и значений.

- Для идентификации БД добавлен UUID доступный в поле `mi_dxbid` структуры `MDBX_envinfo`,
получаемой посредством `mdbx_env_info_ex()`.

- Расширение и доработка C++ API:

- добавлен тип `mdbx::cursor::estimation_result`, а поведение методов
Expand All @@ -97,7 +114,8 @@ and [by Yandex](https://translated.turbopages.org/proxy_u/ru-en.en/https/gitflic
- добавлены статические методы `buffer::hex()`, `base64()`, `base58()`;
- для транзакций и курсоров добавлены методы `get_/set_context`;
- добавлен метод `cursor::clone()`;
- поддержка base58 переработана и приведена в соответствии с черновиком RFC, в текущем понимании теперь это одна из самых высокопроизводительных реализаций;
- поддержка base58 переработана и приведена в соответствии с черновиком RFC,
в текущем понимании теперь это одна из самых высокопроизводительных реализаций base58;
- переработка `to_hex()` и `from_hex()`.

Нарушение совместимости:
Expand Down
2 changes: 1 addition & 1 deletion mdbxdist/VERSION.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
0.13.0.76
0.13.0.86
Loading

0 comments on commit 0740b51

Please sign in to comment.