mirror of
https://gitflic.ru/project/erthink/libmdbx.git
synced 2025-01-25 09:36:08 +00:00
mdbx: переработка инициализации, проверки и импорта dbi-хендлов в транзакциях.
Ранее инициализация в транзакциях структур данных, связанных с dbi-хендлами и subDb, выполнялась непосредственно при запуске транзакций. Что в сценариях с большим кол-вом dbi-дексприторов (например libfpta) порождало заметные накладные расходы, которые расли линейно от общего кол-ва открытых subDb, а не от реально используемых в транзакции. При использовании одной-двух сотен хендлов, при старте каждой транзакции могли копироваться и/или обнуляться десятки килобайт. Теперь этот недостаток устранен. Изменена схема инициализации, валидации и импорта хендлов открытых после старта транзакции: 1) Инициализация теперь выполняется отложенна, а при старте транзации обнуляется только массив с однобайтовыми статустами dbi-хендлов. При этом доступнва опция сборки `MDBX_ENABLE_DBI_SPARSE`, при активации которой используется битовая карты, что снижает объем инициализации при старте транзакции в 8 раз (CHAR_BIT). 2) Переработана валидация dbi-хендлов на входах API, с уменьшением кол-ва проверок и ветвлений до теоретического минимума. 3) Переработ импорт dbi-хендов открытых после старта транзакци, теперь при этом не захватывается мьютекс.
This commit is contained in:
parent
796e56b9b9
commit
e6af7d7c53
@ -531,6 +531,7 @@ add_mdbx_option(MDBX_ENABLE_BIGFOOT "Chunking long list of retired pages during
|
||||
add_mdbx_option(MDBX_ENABLE_PGOP_STAT "Gathering statistics for page operations" ON)
|
||||
add_mdbx_option(MDBX_ENABLE_PROFGC "Profiling of GC search and updates" OFF)
|
||||
mark_as_advanced(MDBX_ENABLE_PROFGC)
|
||||
add_mdbx_option(MDBX_ENABLE_DBI_SPARSE "FIXME" ON)
|
||||
|
||||
if(NOT MDBX_AMALGAMATED_SOURCE)
|
||||
if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE_UPPERCASE STREQUAL "DEBUG")
|
||||
|
8
mdbx.h
8
mdbx.h
@ -1921,7 +1921,7 @@ enum MDBX_error_t {
|
||||
MDBX_TOO_LARGE = -30417,
|
||||
|
||||
/** A thread has attempted to use a not owned object,
|
||||
* e.g. a transaction that started by another thread. */
|
||||
* e.g. a transaction that started by another thread */
|
||||
MDBX_THREAD_MISMATCH = -30416,
|
||||
|
||||
/** Overlapping read and write transactions for the current thread */
|
||||
@ -1936,8 +1936,12 @@ enum MDBX_error_t {
|
||||
/** Alternative/Duplicate LCK-file is exists and should be removed manually */
|
||||
MDBX_DUPLICATED_CLK = -30413,
|
||||
|
||||
/** Some cursors and/or other resources should be closed before subDb or
|
||||
* corresponding DBI-handle could be (re)used */
|
||||
MDBX_DANGLING_DBI = -30412,
|
||||
|
||||
/* The last of MDBX-added error codes */
|
||||
MDBX_LAST_ADDED_ERRCODE = MDBX_DUPLICATED_CLK,
|
||||
MDBX_LAST_ADDED_ERRCODE = MDBX_DANGLING_DBI,
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
MDBX_ENODATA = ERROR_HANDLE_EOF,
|
||||
|
1
mdbx.h++
1
mdbx.h++
@ -559,6 +559,7 @@ MDBX_DECLARE_EXCEPTION(thread_mismatch);
|
||||
MDBX_DECLARE_EXCEPTION(transaction_full);
|
||||
MDBX_DECLARE_EXCEPTION(transaction_overlapping);
|
||||
MDBX_DECLARE_EXCEPTION(duplicated_lck_file);
|
||||
MDBX_DECLARE_EXCEPTION(dangling_map_id);
|
||||
#undef MDBX_DECLARE_EXCEPTION
|
||||
|
||||
[[noreturn]] LIBMDBX_API void throw_too_small_target_buffer();
|
||||
|
@ -5,9 +5,9 @@ N | MASK | ENV | TXN | DB | PUT | DBI | NOD
|
||||
2 |0000 0004|ALLOC_COLSC|TXN_DIRTY |DUPSORT | |DBI_FRESH |F_DUPDATA|P_OVERFLOW| |
|
||||
3 |0000 0008|ALLOC_SSCAN|TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
|
||||
4 |0000 0010|ALLOC_FIFO |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
|
||||
5 |0000 0020| |TXN_DRAINED_GC|INTEGERDUP|NODUPDATA |DBI_USRVALID| |P_LEAF2 | |
|
||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_DUPDATA | |P_SUBP | |
|
||||
7 |0000 0080| | | |ALLDUPS |DBI_AUDITED | | | |
|
||||
5 |0000 0020| |TXN_DRAINED_GC|INTEGERDUP|NODUPDATA | | |P_LEAF2 | |
|
||||
6 |0000 0040| | |REVERSEDUP|CURRENT |DBI_OLDEN | |P_SUBP | |
|
||||
7 |0000 0080| | | |ALLDUPS |DBI_LINDO | | | |
|
||||
8 |0000 0100| _MAY_MOVE | | | | | | | <= |
|
||||
9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
|
||||
10|0000 0400| | | | | | | | |
|
||||
|
@ -33,6 +33,7 @@
|
||||
#cmakedefine01 MDBX_ENABLE_BIGFOOT
|
||||
#cmakedefine01 MDBX_ENABLE_PGOP_STAT
|
||||
#cmakedefine01 MDBX_ENABLE_PROFGC
|
||||
#cmakedefine01 MDBX_ENABLE_DBI_SPARSE
|
||||
|
||||
/* Windows */
|
||||
#cmakedefine01 MDBX_WITHOUT_MSVC_CRT
|
||||
|
1803
src/core.c
1803
src/core.c
File diff suppressed because it is too large
Load Diff
@ -1192,19 +1192,23 @@ struct MDBX_txn {
|
||||
/* Array of MDBX_db records for each known DB */
|
||||
MDBX_db *mt_dbs;
|
||||
|
||||
#if MDBX_ENABLE_DBI_SPARSE
|
||||
unsigned *mt_dbi_sparse;
|
||||
#endif /* MDBX_ENABLE_DBI_SPARSE */
|
||||
|
||||
/* Non-shared DBI state flags inside transaction */
|
||||
#define DBI_DIRTY 0x01 /* DB was written in this txn */
|
||||
#define DBI_STALE 0x02 /* Named-DB record is older than txnID */
|
||||
#define DBI_FRESH 0x04 /* Named-DB handle opened in this txn */
|
||||
#define DBI_CREAT 0x08 /* Named-DB handle created in this txn */
|
||||
#define DBI_VALID 0x10 /* Handle is valid, see also DB_VALID */
|
||||
#define DBI_USRVALID 0x20 /* As DB_VALID, but not set for FREE_DBI */
|
||||
#define DBI_AUDIT 0x40 /* Internal flag for accounting during audit */
|
||||
#define DBI_DIRTY 0x01 /* DB was written in this txn */
|
||||
#define DBI_STALE 0x02 /* Named-DB record is older than txnID */
|
||||
#define DBI_FRESH 0x04 /* Named-DB handle opened in this txn */
|
||||
#define DBI_CREAT 0x08 /* Named-DB handle created in this txn */
|
||||
#define DBI_VALID 0x10 /* Handle is valid, see also DB_VALID */
|
||||
#define DBI_OLDEN 0x40 /* Handle was closed/reopened outside txn */
|
||||
#define DBI_LINDO 0x80 /* Lazy initialization done for DBI-slot */
|
||||
/* Array of non-shared txn's flags of DBI */
|
||||
uint8_t *mt_dbi_state;
|
||||
|
||||
/* Array of sequence numbers for each DB handle. */
|
||||
MDBX_atomic_uint32_t *mt_dbi_seqs;
|
||||
uint32_t *mt_dbi_seqs;
|
||||
MDBX_cursor **mt_cursors;
|
||||
|
||||
MDBX_canary mt_canary;
|
||||
@ -1660,7 +1664,8 @@ typedef struct MDBX_node {
|
||||
/* mdbx_dbi_open() flags */
|
||||
#define DB_USABLE_FLAGS (DB_PERSISTENT_FLAGS | MDBX_CREATE | MDBX_DB_ACCEDE)
|
||||
|
||||
#define DB_VALID 0x8000 /* DB handle is valid, for me_db_flags */
|
||||
#define DB_VALID 0x8000u /* DB handle is valid, for me_db_flags */
|
||||
#define DB_POISON 0x7fffu /* update pending */
|
||||
#define DB_INTERNAL_FLAGS DB_VALID
|
||||
|
||||
#if DB_INTERNAL_FLAGS & DB_USABLE_FLAGS
|
||||
|
@ -286,6 +286,8 @@ DEFINE_EXCEPTION(thread_mismatch)
|
||||
DEFINE_EXCEPTION(transaction_full)
|
||||
DEFINE_EXCEPTION(transaction_overlapping)
|
||||
DEFINE_EXCEPTION(duplicated_lck_file)
|
||||
DEFINE_EXCEPTION(dangling_map_id)
|
||||
|
||||
#undef DEFINE_EXCEPTION
|
||||
|
||||
__cold const char *error::what() const noexcept {
|
||||
@ -372,6 +374,7 @@ __cold void error::throw_exception() const {
|
||||
CASE_EXCEPTION(transaction_full, MDBX_TXN_FULL);
|
||||
CASE_EXCEPTION(transaction_overlapping, MDBX_TXN_OVERLAPPING);
|
||||
CASE_EXCEPTION(duplicated_lck_file, MDBX_DUPLICATED_CLK);
|
||||
CASE_EXCEPTION(dangling_map_id, MDBX_DANGLING_DBI);
|
||||
#undef CASE_EXCEPTION
|
||||
default:
|
||||
if (is_mdbx_error())
|
||||
|
@ -163,6 +163,13 @@
|
||||
#error MDBX_AVOID_MSYNC must be defined as 0 or 1
|
||||
#endif /* MDBX_AVOID_MSYNC */
|
||||
|
||||
/** FIXME */
|
||||
#ifndef MDBX_ENABLE_DBI_SPARSE
|
||||
#define MDBX_ENABLE_DBI_SPARSE 1
|
||||
#elif !(MDBX_ENABLE_DBI_SPARSE == 0 || MDBX_ENABLE_DBI_SPARSE == 1)
|
||||
#error MDBX_ENABLE_DBI_SPARSE must be defined as 0 or 1
|
||||
#endif /* MDBX_ENABLE_DBI_SPARSE */
|
||||
|
||||
/** 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 built with
|
||||
|
Loading…
Reference in New Issue
Block a user