mdbx: добавление rkl с итераторами.

RKL — сортированный набор txnid, использующий внутри комбинацию
непрерывного интервала и списка. Обеспечивает хранение id записей при
переработке, очистку и обновлении GC, включая возврат остатков
переработанных страниц.

Итератор для RKL — обеспечивает изоляцию внутреннего устройства rkl от
остального кода, чем существенно его упрощает. Фактически именно
использованием rkl с итераторами ликвидируется "ребус" исторически
образовавшийся в gc-update.

--

При переработке GC записи преимущественно выбираются последовательно, но
это не гарантируется. В LIFO-режиме переработка и добавление записей в
rkl происходит преимущественно в обратном порядке, но из-за завершения
читающих транзакций могут быть «скачки» в прямом направлении. В
FIFO-режиме записи GC перерабатываются в прямом порядке и при этом
линейно, но не обязательно строго последовательно, при этом
гарантируется что между добавляемыми в rkl идентификаторами в GC нет
записей, т.е. между первой (минимальный id) и последней (максимальный
id) в GC нет записей и весь интервал может быть использован для возврата
остатков страниц в GC.

Таким образом, комбинация линейного интервала и списка (отсортированного
в порядке возрастания элементов) является рациональным решением, близким
к теоретически оптимальному пределу.

Реализация rkl достаточно проста/прозрачная, если не считать неочевидную
«магию» обмена непрерывного интервала и образующихся в списке
последовательностей. Однако, именно этот автоматически выполняемый без
лишних операций обмен оправдывает все накладные расходы.
This commit is contained in:
Леонид Юрьев (Leonid Yuriev)
2025-01-30 18:43:30 +03:00
parent db163cbcfd
commit b8c1b835ed
6 changed files with 528 additions and 0 deletions

View File

@@ -46,6 +46,7 @@ typedef struct bind_reader_slot_result {
#include "atomics-ops.h"
#include "proto.h"
#include "rkl.h"
#include "txl.h"
#include "unaligned.h"
#if defined(_WIN32) || defined(_WIN64)
@@ -537,7 +538,9 @@ MDBX_MAYBE_UNUSED static void static_checks(void) {
STATIC_ASSERT(offsetof(lck_t, cached_oldest) % MDBX_CACHELINE_SIZE == 0);
STATIC_ASSERT(offsetof(lck_t, rdt_length) % MDBX_CACHELINE_SIZE == 0);
#endif /* MDBX_LOCKING */
#if FLEXIBLE_ARRAY_MEMBERS
STATIC_ASSERT(offsetof(lck_t, rdt) % MDBX_CACHELINE_SIZE == 0);
#endif /* FLEXIBLE_ARRAY_MEMBERS */
#if FLEXIBLE_ARRAY_MEMBERS
STATIC_ASSERT(NODESIZE == offsetof(node_t, payload));