Отложенное освобождение позволяет реализовать безопасное выполнение
fastpath/lockfree при повторном открытии из других потоков/транзакцйий
уже открытых subDB, что и происходит при активации добавленной опции
сборки `MDBX_ENABLE_DBI_LOCKFREE`.
Ранее инициализация в транзакциях структур данных, связанных с
dbi-хендлами и subDb, выполнялась непосредственно при запуске
транзакций. Что в сценариях с большим кол-вом dbi-дексприторов (например
libfpta) порождало заметные накладные расходы, которые расли линейно от
общего кол-ва открытых subDb, а не от реально используемых в транзакции.
При использовании одной-двух сотен хендлов, при старте каждой транзакции
могли копироваться и/или обнуляться десятки килобайт. Теперь этот
недостаток устранен.
Изменена схема инициализации, валидации и импорта хендлов открытых после
старта транзакции:
1) Инициализация теперь выполняется отложенна, а при старте транзации
обнуляется только массив с однобайтовыми статустами dbi-хендлов.
При этом доступнва опция сборки `MDBX_ENABLE_DBI_SPARSE`, при активации
которой используется битовая карты, что снижает объем инициализации
при старте транзакции в 8 раз (CHAR_BIT).
2) Переработана валидация dbi-хендлов на входах API, с уменьшением кол-ва
проверок и ветвлений до теоретического минимума.
3) Переработ импорт dbi-хендов открытых после старта транзакци, теперь
при этом не захватывается мьютекс.
Суть в избавлении от лишнего вызова msync(MS_ASYNC) в режимах
MDBX_WRITEMAP+MDBX_SAFE_NOSYNC и т.п.
Гипотетически могут быть системы/платформы, на которых изменения в
разделяемой памяти не видны другим процессам до вызова msync(MS_ASYNC)
и/или до этого вызова не будет инициироваться вытеснение/запись таких
страниц на диск.
Поэтому использование msync(MS_ASYNC) вынесено под опцию
MDBX_MMAP_USE_MS_ASYNC, которая по-умолчанию включена только на системах
с MDBX_MMAP_INCOHERENT_FILE_WRITE или MDBX_MMAP_INCOHERENT_CPU_CACHE.
Это решает проблему срабатывания проверочного утверждения при сборке для
платформ где тип off_t шире соответствующих полей структуры flock,
используемой для блокировки файлов.
Здесь основная часть изменений преобразующих отладочную проверку страниц
в регулярный и доступный пользователю осторожный/безопасный режим работы
с потенциально поврежденной БД.
Here the major part of the changes that transform a debugging check of
pages into a regular and user-accessible careful/safe mode for working
with a potentially corrupted database.
Chunking long list of retired pages during huge transactions commit
to avoid use sequences of pages:
- splits a long retired page-number-list into chunks
which fits one per single overflow/large page;
- this requires a few unique id for keys
for create such records into GC/freeDB;
- just use the necessary subsequent IDs following the current
transaction ID and then take the last of ones to update a meta-page.
Thus avoids using/allocating/searching a sequence of free pages
but just increase txnid more than one during the commit
a huge write transaction with a long retired-pages-list.
The three points:
- disentangle C11-atomic fences/barriers and pure-functions (with `__attribute__((__pure__))`) to avoid compiler misoptimization;
- fix hypotetic unaligned access to 64-bit dwords on ARM with `__ARM_FEATURE_UNALIGNED` defined;
- reasonable paranoia that makes clarity for code readers.