mdbxmou 0.1.26

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/.github/workflows/ci.yml +32 -0
  2. package/.github/workflows/publish.yml +27 -0
  3. package/.gitmodules +3 -0
  4. package/CMakeLists.txt +53 -0
  5. package/LICENSE +201 -0
  6. package/README.md +639 -0
  7. package/build.js +11 -0
  8. package/deps/libmdbx/.clang-format +3 -0
  9. package/deps/libmdbx/.cmake-format.yaml +3 -0
  10. package/deps/libmdbx/.le.ini +40 -0
  11. package/deps/libmdbx/CMakeLists.txt +1269 -0
  12. package/deps/libmdbx/COPYRIGHT +159 -0
  13. package/deps/libmdbx/ChangeLog.md +2786 -0
  14. package/deps/libmdbx/GNUmakefile +950 -0
  15. package/deps/libmdbx/LICENSE +177 -0
  16. package/deps/libmdbx/Makefile +16 -0
  17. package/deps/libmdbx/NOTICE +39 -0
  18. package/deps/libmdbx/README.md +863 -0
  19. package/deps/libmdbx/TODO.md +43 -0
  20. package/deps/libmdbx/cmake/compiler.cmake +1221 -0
  21. package/deps/libmdbx/cmake/profile.cmake +58 -0
  22. package/deps/libmdbx/cmake/utils.cmake +524 -0
  23. package/deps/libmdbx/conanfile.py +323 -0
  24. package/deps/libmdbx/docs/Doxyfile.in +2734 -0
  25. package/deps/libmdbx/docs/_preface.md +47 -0
  26. package/deps/libmdbx/docs/_restrictions.md +248 -0
  27. package/deps/libmdbx/docs/_starting.md +245 -0
  28. package/deps/libmdbx/docs/_toc.md +34 -0
  29. package/deps/libmdbx/docs/header.html +96 -0
  30. package/deps/libmdbx/example/CMakeLists.txt +6 -0
  31. package/deps/libmdbx/example/README.md +1 -0
  32. package/deps/libmdbx/example/example-mdbx.c +154 -0
  33. package/deps/libmdbx/example/sample-bdb.txt +77 -0
  34. package/deps/libmdbx/mdbx.h +6655 -0
  35. package/deps/libmdbx/mdbx.h++ +6428 -0
  36. package/deps/libmdbx/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +173 -0
  37. package/deps/libmdbx/src/alloy.c +54 -0
  38. package/deps/libmdbx/src/api-cold.c +543 -0
  39. package/deps/libmdbx/src/api-copy.c +912 -0
  40. package/deps/libmdbx/src/api-cursor.c +754 -0
  41. package/deps/libmdbx/src/api-dbi.c +315 -0
  42. package/deps/libmdbx/src/api-env.c +1434 -0
  43. package/deps/libmdbx/src/api-extra.c +165 -0
  44. package/deps/libmdbx/src/api-key-transform.c +197 -0
  45. package/deps/libmdbx/src/api-misc.c +286 -0
  46. package/deps/libmdbx/src/api-opts.c +575 -0
  47. package/deps/libmdbx/src/api-range-estimate.c +365 -0
  48. package/deps/libmdbx/src/api-txn-data.c +454 -0
  49. package/deps/libmdbx/src/api-txn.c +921 -0
  50. package/deps/libmdbx/src/atomics-ops.h +364 -0
  51. package/deps/libmdbx/src/atomics-types.h +97 -0
  52. package/deps/libmdbx/src/audit.c +109 -0
  53. package/deps/libmdbx/src/bits.md +34 -0
  54. package/deps/libmdbx/src/chk.c +1796 -0
  55. package/deps/libmdbx/src/cogs.c +309 -0
  56. package/deps/libmdbx/src/cogs.h +506 -0
  57. package/deps/libmdbx/src/coherency.c +170 -0
  58. package/deps/libmdbx/src/config.h.in +88 -0
  59. package/deps/libmdbx/src/cursor.c +2396 -0
  60. package/deps/libmdbx/src/cursor.h +391 -0
  61. package/deps/libmdbx/src/dbi.c +717 -0
  62. package/deps/libmdbx/src/dbi.h +142 -0
  63. package/deps/libmdbx/src/debug_begin.h +36 -0
  64. package/deps/libmdbx/src/debug_end.h +15 -0
  65. package/deps/libmdbx/src/dpl.c +486 -0
  66. package/deps/libmdbx/src/dpl.h +134 -0
  67. package/deps/libmdbx/src/dxb.c +1335 -0
  68. package/deps/libmdbx/src/env.c +607 -0
  69. package/deps/libmdbx/src/essentials.h +125 -0
  70. package/deps/libmdbx/src/gc-get.c +1345 -0
  71. package/deps/libmdbx/src/gc-put.c +970 -0
  72. package/deps/libmdbx/src/gc.h +40 -0
  73. package/deps/libmdbx/src/global.c +474 -0
  74. package/deps/libmdbx/src/internals.h +585 -0
  75. package/deps/libmdbx/src/layout-dxb.h +288 -0
  76. package/deps/libmdbx/src/layout-lck.h +289 -0
  77. package/deps/libmdbx/src/lck-posix.c +859 -0
  78. package/deps/libmdbx/src/lck-windows.c +607 -0
  79. package/deps/libmdbx/src/lck.c +174 -0
  80. package/deps/libmdbx/src/lck.h +110 -0
  81. package/deps/libmdbx/src/logging_and_debug.c +250 -0
  82. package/deps/libmdbx/src/logging_and_debug.h +159 -0
  83. package/deps/libmdbx/src/man1/mdbx_chk.1 +106 -0
  84. package/deps/libmdbx/src/man1/mdbx_copy.1 +95 -0
  85. package/deps/libmdbx/src/man1/mdbx_drop.1 +48 -0
  86. package/deps/libmdbx/src/man1/mdbx_dump.1 +101 -0
  87. package/deps/libmdbx/src/man1/mdbx_load.1 +105 -0
  88. package/deps/libmdbx/src/man1/mdbx_stat.1 +86 -0
  89. package/deps/libmdbx/src/mdbx.c++ +1837 -0
  90. package/deps/libmdbx/src/meta.c +656 -0
  91. package/deps/libmdbx/src/meta.h +168 -0
  92. package/deps/libmdbx/src/mvcc-readers.c +414 -0
  93. package/deps/libmdbx/src/node.c +365 -0
  94. package/deps/libmdbx/src/node.h +102 -0
  95. package/deps/libmdbx/src/ntdll.def +1246 -0
  96. package/deps/libmdbx/src/options.h +534 -0
  97. package/deps/libmdbx/src/osal.c +3485 -0
  98. package/deps/libmdbx/src/osal.h +587 -0
  99. package/deps/libmdbx/src/page-get.c +483 -0
  100. package/deps/libmdbx/src/page-iov.c +185 -0
  101. package/deps/libmdbx/src/page-iov.h +34 -0
  102. package/deps/libmdbx/src/page-ops.c +744 -0
  103. package/deps/libmdbx/src/page-ops.h +142 -0
  104. package/deps/libmdbx/src/pnl.c +236 -0
  105. package/deps/libmdbx/src/pnl.h +146 -0
  106. package/deps/libmdbx/src/preface.h +990 -0
  107. package/deps/libmdbx/src/proto.h +105 -0
  108. package/deps/libmdbx/src/refund.c +212 -0
  109. package/deps/libmdbx/src/sort.h +484 -0
  110. package/deps/libmdbx/src/spill.c +431 -0
  111. package/deps/libmdbx/src/spill.h +74 -0
  112. package/deps/libmdbx/src/table.c +107 -0
  113. package/deps/libmdbx/src/tls.c +551 -0
  114. package/deps/libmdbx/src/tls.h +43 -0
  115. package/deps/libmdbx/src/tools/chk.c +673 -0
  116. package/deps/libmdbx/src/tools/copy.c +166 -0
  117. package/deps/libmdbx/src/tools/drop.c +199 -0
  118. package/deps/libmdbx/src/tools/dump.c +515 -0
  119. package/deps/libmdbx/src/tools/load.c +831 -0
  120. package/deps/libmdbx/src/tools/stat.c +516 -0
  121. package/deps/libmdbx/src/tools/wingetopt.c +87 -0
  122. package/deps/libmdbx/src/tools/wingetopt.h +30 -0
  123. package/deps/libmdbx/src/tree-ops.c +1554 -0
  124. package/deps/libmdbx/src/tree-search.c +140 -0
  125. package/deps/libmdbx/src/txl.c +99 -0
  126. package/deps/libmdbx/src/txl.h +26 -0
  127. package/deps/libmdbx/src/txn.c +1083 -0
  128. package/deps/libmdbx/src/unaligned.h +205 -0
  129. package/deps/libmdbx/src/utils.c +32 -0
  130. package/deps/libmdbx/src/utils.h +76 -0
  131. package/deps/libmdbx/src/version.c.in +44 -0
  132. package/deps/libmdbx/src/walk.c +290 -0
  133. package/deps/libmdbx/src/walk.h +20 -0
  134. package/deps/libmdbx/src/windows-import.c +152 -0
  135. package/deps/libmdbx/src/windows-import.h +128 -0
  136. package/deps/libmdbx/test/CMakeLists.txt +317 -0
  137. package/deps/libmdbx/test/append.c++ +237 -0
  138. package/deps/libmdbx/test/base.h++ +92 -0
  139. package/deps/libmdbx/test/battery-tmux.sh +64 -0
  140. package/deps/libmdbx/test/cases.c++ +118 -0
  141. package/deps/libmdbx/test/chrono.c++ +134 -0
  142. package/deps/libmdbx/test/chrono.h++ +85 -0
  143. package/deps/libmdbx/test/config.c++ +643 -0
  144. package/deps/libmdbx/test/config.h++ +334 -0
  145. package/deps/libmdbx/test/copy.c++ +62 -0
  146. package/deps/libmdbx/test/dead.c++ +39 -0
  147. package/deps/libmdbx/test/dump-load.sh +40 -0
  148. package/deps/libmdbx/test/extra/crunched_delete.c++ +409 -0
  149. package/deps/libmdbx/test/extra/cursor_closing.c++ +410 -0
  150. package/deps/libmdbx/test/extra/dbi.c++ +229 -0
  151. package/deps/libmdbx/test/extra/doubtless_positioning.c++ +253 -0
  152. package/deps/libmdbx/test/extra/dupfix_addodd.c +94 -0
  153. package/deps/libmdbx/test/extra/dupfix_multiple.c++ +311 -0
  154. package/deps/libmdbx/test/extra/early_close_dbi.c++ +137 -0
  155. package/deps/libmdbx/test/extra/hex_base64_base58.c++ +118 -0
  156. package/deps/libmdbx/test/extra/maindb_ordinal.c++ +61 -0
  157. package/deps/libmdbx/test/extra/open.c++ +96 -0
  158. package/deps/libmdbx/test/extra/pcrf/README.md +2 -0
  159. package/deps/libmdbx/test/extra/pcrf/pcrf_test.c +380 -0
  160. package/deps/libmdbx/test/extra/probe.c++ +10 -0
  161. package/deps/libmdbx/test/extra/txn.c++ +407 -0
  162. package/deps/libmdbx/test/extra/upsert_alldups.c +193 -0
  163. package/deps/libmdbx/test/fork.c++ +263 -0
  164. package/deps/libmdbx/test/hill.c++ +447 -0
  165. package/deps/libmdbx/test/jitter.c++ +197 -0
  166. package/deps/libmdbx/test/keygen.c++ +393 -0
  167. package/deps/libmdbx/test/keygen.h++ +130 -0
  168. package/deps/libmdbx/test/log.c++ +358 -0
  169. package/deps/libmdbx/test/log.h++ +91 -0
  170. package/deps/libmdbx/test/main.c++ +706 -0
  171. package/deps/libmdbx/test/nested.c++ +318 -0
  172. package/deps/libmdbx/test/osal-unix.c++ +647 -0
  173. package/deps/libmdbx/test/osal-windows.c++ +440 -0
  174. package/deps/libmdbx/test/osal.h++ +41 -0
  175. package/deps/libmdbx/test/stochastic.sh +690 -0
  176. package/deps/libmdbx/test/stub/LICENSE +24 -0
  177. package/deps/libmdbx/test/stub/README.md +8 -0
  178. package/deps/libmdbx/test/stub/pthread_barrier.c +104 -0
  179. package/deps/libmdbx/test/stub/pthread_barrier.h +77 -0
  180. package/deps/libmdbx/test/test.c++ +1551 -0
  181. package/deps/libmdbx/test/test.h++ +298 -0
  182. package/deps/libmdbx/test/tmux.conf +3 -0
  183. package/deps/libmdbx/test/try.c++ +30 -0
  184. package/deps/libmdbx/test/ttl.c++ +240 -0
  185. package/deps/libmdbx/test/utils.c++ +203 -0
  186. package/deps/libmdbx/test/utils.h++ +326 -0
  187. package/deps/libmdbx/test/valgrind_suppress.txt +536 -0
  188. package/lib/mdbx_evn_async.js +211 -0
  189. package/lib/mdbx_worker.js +195 -0
  190. package/lib/nativemou.js +6 -0
  191. package/package.json +38 -0
  192. package/src/async/envmou_close.cpp +34 -0
  193. package/src/async/envmou_close.hpp +32 -0
  194. package/src/async/envmou_copy_to.cpp +29 -0
  195. package/src/async/envmou_copy_to.hpp +38 -0
  196. package/src/async/envmou_keys.cpp +201 -0
  197. package/src/async/envmou_keys.hpp +50 -0
  198. package/src/async/envmou_open.cpp +38 -0
  199. package/src/async/envmou_open.hpp +33 -0
  200. package/src/async/envmou_query.cpp +167 -0
  201. package/src/async/envmou_query.hpp +53 -0
  202. package/src/dbimou.cpp +522 -0
  203. package/src/dbimou.hpp +82 -0
  204. package/src/env_arg0.hpp +24 -0
  205. package/src/envmou.cpp +445 -0
  206. package/src/envmou.hpp +116 -0
  207. package/src/modulemou.cpp +113 -0
  208. package/src/querymou.cpp +177 -0
  209. package/src/querymou.hpp +93 -0
  210. package/src/txnmou.cpp +254 -0
  211. package/src/txnmou.hpp +122 -0
  212. package/src/typemou.hpp +239 -0
  213. package/src/valuemou.hpp +194 -0
  214. package/test/async.js +67 -0
  215. package/test/e3.js +38 -0
  216. package/test/e4.js +89 -0
  217. package/test/e5.js +162 -0
  218. package/test/test-batch-ops.js +243 -0
  219. package/test/test-cursor-mode.js +84 -0
  220. package/test/test-multi-mode.js +87 -0
@@ -0,0 +1,288 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \note Please refer to the COPYRIGHT file for explanations license change,
3
+ /// credits and acknowledgments.
4
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
5
+
6
+ #pragma once
7
+
8
+ #include "essentials.h"
9
+
10
+ #pragma pack(push, 4)
11
+
12
+ /* A stamp that identifies a file as an MDBX file.
13
+ * There's nothing special about this value other than that it is easily
14
+ * recognizable, and it will reflect any byte order mismatches. */
15
+ #define MDBX_MAGIC UINT64_C(/* 56-bit prime */ 0x59659DBDEF4C11)
16
+
17
+ /* FROZEN: The version number for a database's datafile format. */
18
+ #define MDBX_DATA_VERSION 3
19
+
20
+ #define MDBX_DATA_MAGIC ((MDBX_MAGIC << 8) + MDBX_PNL_ASCENDING * 64 + MDBX_DATA_VERSION)
21
+ #define MDBX_DATA_MAGIC_LEGACY_COMPAT ((MDBX_MAGIC << 8) + MDBX_PNL_ASCENDING * 64 + 2)
22
+ #define MDBX_DATA_MAGIC_LEGACY_DEVEL ((MDBX_MAGIC << 8) + 255)
23
+
24
+ /* handle for the DB used to track free pages. */
25
+ #define FREE_DBI 0
26
+ /* handle for the default DB. */
27
+ #define MAIN_DBI 1
28
+ /* Number of DBs in metapage (free and main) - also hardcoded elsewhere */
29
+ #define CORE_DBS 2
30
+
31
+ /* Number of meta pages - also hardcoded elsewhere */
32
+ #define NUM_METAS 3
33
+
34
+ /* A page number in the database.
35
+ *
36
+ * MDBX uses 32 bit for page numbers. This limits database
37
+ * size up to 2^44 bytes, in case of 4K pages. */
38
+ typedef uint32_t pgno_t;
39
+ typedef mdbx_atomic_uint32_t atomic_pgno_t;
40
+ #define PRIaPGNO PRIu32
41
+ #define MAX_PAGENO UINT32_C(0x7FFFffff)
42
+ #define MIN_PAGENO NUM_METAS
43
+
44
+ /* An invalid page number.
45
+ * Mainly used to denote an empty tree. */
46
+ #define P_INVALID (~(pgno_t)0)
47
+
48
+ /* A transaction ID. */
49
+ typedef uint64_t txnid_t;
50
+ typedef mdbx_atomic_uint64_t atomic_txnid_t;
51
+ #define PRIaTXN PRIi64
52
+ #define MIN_TXNID UINT64_C(1)
53
+ #define MAX_TXNID (SAFE64_INVALID_THRESHOLD - 1)
54
+ #define INITIAL_TXNID (MIN_TXNID + NUM_METAS - 1)
55
+ #define INVALID_TXNID UINT64_MAX
56
+
57
+ /* Used for offsets within a single page. */
58
+ typedef uint16_t indx_t;
59
+
60
+ typedef struct tree {
61
+ uint16_t flags; /* see mdbx_dbi_open */
62
+ uint16_t height; /* height of this tree */
63
+ uint32_t dupfix_size; /* key-size for MDBX_DUPFIXED (DUPFIX pages) */
64
+ pgno_t root; /* the root page of this tree */
65
+ pgno_t branch_pages; /* number of branch pages */
66
+ pgno_t leaf_pages; /* number of leaf pages */
67
+ pgno_t large_pages; /* number of large pages */
68
+ uint64_t sequence; /* table sequence counter */
69
+ uint64_t items; /* number of data items */
70
+ uint64_t mod_txnid; /* txnid of last committed modification */
71
+ } tree_t;
72
+
73
+ /* database size-related parameters */
74
+ typedef struct geo {
75
+ uint16_t grow_pv; /* datafile growth step as a 16-bit packed (exponential
76
+ quantized) value */
77
+ uint16_t shrink_pv; /* datafile shrink threshold as a 16-bit packed
78
+ (exponential quantized) value */
79
+ pgno_t lower; /* minimal size of datafile in pages */
80
+ pgno_t upper; /* maximal size of datafile in pages */
81
+ union {
82
+ pgno_t now; /* current size of datafile in pages */
83
+ pgno_t end_pgno;
84
+ };
85
+ union {
86
+ pgno_t first_unallocated; /* first unused page in the datafile,
87
+ but actually the file may be shorter. */
88
+ pgno_t next_pgno;
89
+ };
90
+ } geo_t;
91
+
92
+ /* Meta page content.
93
+ * A meta page is the start point for accessing a database snapshot.
94
+ * Pages 0-2 are meta pages. */
95
+ typedef struct meta {
96
+ /* Stamp identifying this as an MDBX file.
97
+ * It must be set to MDBX_MAGIC with MDBX_DATA_VERSION. */
98
+ uint32_t magic_and_version[2];
99
+
100
+ /* txnid that committed this meta, the first of a two-phase-update pair */
101
+ union {
102
+ mdbx_atomic_uint32_t txnid_a[2];
103
+ uint64_t unsafe_txnid;
104
+ };
105
+
106
+ uint16_t reserve16; /* extra flags, zero (nothing) for now */
107
+ uint8_t validator_id; /* ID of checksum and page validation method,
108
+ * zero (nothing) for now */
109
+ int8_t extra_pagehdr; /* extra bytes in the page header,
110
+ * zero (nothing) for now */
111
+
112
+ geo_t geometry; /* database size-related parameters */
113
+
114
+ union {
115
+ struct {
116
+ tree_t gc, main;
117
+ } trees;
118
+ __anonymous_struct_extension__ struct {
119
+ uint16_t gc_flags;
120
+ uint16_t gc_height;
121
+ uint32_t pagesize;
122
+ };
123
+ };
124
+
125
+ MDBX_canary canary;
126
+
127
+ #define DATASIGN_NONE 0u
128
+ #define DATASIGN_WEAK 1u
129
+ #define SIGN_IS_STEADY(sign) ((sign) > DATASIGN_WEAK)
130
+ union {
131
+ uint32_t sign[2];
132
+ uint64_t unsafe_sign;
133
+ };
134
+
135
+ /* txnid that committed this meta, the second of a two-phase-update pair */
136
+ mdbx_atomic_uint32_t txnid_b[2];
137
+
138
+ /* Number of non-meta pages which were put in GC after COW. May be 0 in case
139
+ * DB was previously handled by libmdbx without corresponding feature.
140
+ * This value in couple with reader.snapshot_pages_retired allows fast
141
+ * estimation of "how much reader is restraining GC recycling". */
142
+ uint32_t pages_retired[2];
143
+
144
+ /* The analogue /proc/sys/kernel/random/boot_id or similar to determine
145
+ * whether the system was rebooted after the last use of the database files.
146
+ * If there was no reboot, but there is no need to rollback to the last
147
+ * steady sync point. Zeros mean that no relevant information is available
148
+ * from the system. */
149
+ bin128_t bootid;
150
+
151
+ /* GUID базы данных, начиная с v0.13.1 */
152
+ bin128_t dxbid;
153
+ } meta_t;
154
+
155
+ #pragma pack(1)
156
+
157
+ typedef enum page_type {
158
+ P_BRANCH = 0x01u /* branch page */,
159
+ P_LEAF = 0x02u /* leaf page */,
160
+ P_LARGE = 0x04u /* large/overflow page */,
161
+ P_META = 0x08u /* meta page */,
162
+ P_LEGACY_DIRTY = 0x10u /* legacy P_DIRTY flag prior to v0.10 958fd5b9 */,
163
+ P_BAD = P_LEGACY_DIRTY /* explicit flag for invalid/bad page */,
164
+ P_DUPFIX = 0x20u /* for MDBX_DUPFIXED records */,
165
+ P_SUBP = 0x40u /* for MDBX_DUPSORT sub-pages */,
166
+ P_SPILLED = 0x2000u /* spilled in parent txn */,
167
+ P_LOOSE = 0x4000u /* page was dirtied then freed, can be reused */,
168
+ P_FROZEN = 0x8000u /* used for retire page with known status */,
169
+ P_ILL_BITS = (uint16_t)~(P_BRANCH | P_LEAF | P_DUPFIX | P_LARGE | P_SPILLED),
170
+
171
+ page_broken = 0,
172
+ page_large = P_LARGE,
173
+ page_branch = P_BRANCH,
174
+ page_leaf = P_LEAF,
175
+ page_dupfix_leaf = P_DUPFIX,
176
+ page_sub_leaf = P_SUBP | P_LEAF,
177
+ page_sub_dupfix_leaf = P_SUBP | P_DUPFIX,
178
+ page_sub_broken = P_SUBP,
179
+ } page_type_t;
180
+
181
+ /* Common header for all page types. The page type depends on flags.
182
+ *
183
+ * P_BRANCH and P_LEAF pages have unsorted 'node_t's at the end, with
184
+ * sorted entries[] entries referring to them. Exception: P_DUPFIX pages
185
+ * omit entries and pack sorted MDBX_DUPFIXED values after the page header.
186
+ *
187
+ * P_LARGE records occupy one or more contiguous pages where only the
188
+ * first has a page header. They hold the real data of N_BIG nodes.
189
+ *
190
+ * P_SUBP sub-pages are small leaf "pages" with duplicate data.
191
+ * A node with flag N_DUP but not N_TREE contains a sub-page.
192
+ * (Duplicate data can also go in tables, which use normal pages.)
193
+ *
194
+ * P_META pages contain meta_t, the start point of an MDBX snapshot.
195
+ *
196
+ * Each non-metapage up to meta_t.mm_last_pg is reachable exactly once
197
+ * in the snapshot: Either used by a database or listed in a GC record. */
198
+ typedef struct page {
199
+ uint64_t txnid; /* txnid which created page, maybe zero in legacy DB */
200
+ uint16_t dupfix_ksize; /* key size if this is a DUPFIX page */
201
+ uint16_t flags;
202
+ union {
203
+ uint32_t pages; /* number of overflow pages */
204
+ __anonymous_struct_extension__ struct {
205
+ indx_t lower; /* lower bound of free space */
206
+ indx_t upper; /* upper bound of free space */
207
+ };
208
+ };
209
+ pgno_t pgno; /* page number */
210
+
211
+ #if FLEXIBLE_ARRAY_MEMBERS
212
+ indx_t entries[] /* dynamic size */;
213
+ #endif /* FLEXIBLE_ARRAY_MEMBERS */
214
+ } page_t;
215
+
216
+ /* Size of the page header, excluding dynamic data at the end */
217
+ #define PAGEHDRSZ 20u
218
+
219
+ /* Header for a single key/data pair within a page.
220
+ * Used in pages of type P_BRANCH and P_LEAF without P_DUPFIX.
221
+ * We guarantee 2-byte alignment for 'node_t's.
222
+ *
223
+ * Leaf node flags describe node contents. N_BIG says the node's
224
+ * data part is the page number of an overflow page with actual data.
225
+ * N_DUP and N_TREE can be combined giving duplicate data in
226
+ * a sub-page/table, and named databases (just N_TREE). */
227
+ typedef struct node {
228
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
229
+ union {
230
+ uint32_t dsize;
231
+ uint32_t child_pgno;
232
+ };
233
+ uint8_t flags; /* see node_flags */
234
+ uint8_t extra;
235
+ uint16_t ksize; /* key size */
236
+ #else
237
+ uint16_t ksize; /* key size */
238
+ uint8_t extra;
239
+ uint8_t flags; /* see node_flags */
240
+ union {
241
+ uint32_t child_pgno;
242
+ uint32_t dsize;
243
+ };
244
+ #endif /* __BYTE_ORDER__ */
245
+
246
+ #if FLEXIBLE_ARRAY_MEMBERS
247
+ uint8_t payload[] /* key and data are appended here */;
248
+ #endif /* FLEXIBLE_ARRAY_MEMBERS */
249
+ } node_t;
250
+
251
+ /* Size of the node header, excluding dynamic data at the end */
252
+ #define NODESIZE 8u
253
+
254
+ typedef enum node_flags {
255
+ N_BIG = 0x01 /* data put on large page */,
256
+ N_TREE = 0x02 /* data is a b-tree */,
257
+ N_DUP = 0x04 /* data has duplicates */
258
+ } node_flags_t;
259
+
260
+ #pragma pack(pop)
261
+
262
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint8_t page_type(const page_t *mp) { return mp->flags; }
263
+
264
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline uint8_t page_type_compat(const page_t *mp) {
265
+ /* Drop legacy P_DIRTY flag for sub-pages for compatilibity,
266
+ * for assertions only. */
267
+ return unlikely(mp->flags & P_SUBP) ? mp->flags & ~(P_SUBP | P_LEGACY_DIRTY) : mp->flags;
268
+ }
269
+
270
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline bool is_leaf(const page_t *mp) {
271
+ return (mp->flags & P_LEAF) != 0;
272
+ }
273
+
274
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline bool is_dupfix_leaf(const page_t *mp) {
275
+ return (mp->flags & P_DUPFIX) != 0;
276
+ }
277
+
278
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline bool is_branch(const page_t *mp) {
279
+ return (mp->flags & P_BRANCH) != 0;
280
+ }
281
+
282
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline bool is_largepage(const page_t *mp) {
283
+ return (mp->flags & P_LARGE) != 0;
284
+ }
285
+
286
+ MDBX_MAYBE_UNUSED MDBX_NOTHROW_PURE_FUNCTION static inline bool is_subpage(const page_t *mp) {
287
+ return (mp->flags & P_SUBP) != 0;
288
+ }
@@ -0,0 +1,289 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \note Please refer to the COPYRIGHT file for explanations license change,
3
+ /// credits and acknowledgments.
4
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
5
+
6
+ #pragma once
7
+
8
+ #include "essentials.h"
9
+
10
+ /* The version number for a database's lockfile format. */
11
+ #define MDBX_LOCK_VERSION 6
12
+
13
+ #if MDBX_LOCKING == MDBX_LOCKING_WIN32FILES
14
+
15
+ #define MDBX_LCK_SIGN UINT32_C(0xF10C)
16
+ typedef void osal_ipclock_t;
17
+ #elif MDBX_LOCKING == MDBX_LOCKING_SYSV
18
+
19
+ #define MDBX_LCK_SIGN UINT32_C(0xF18D)
20
+ typedef mdbx_pid_t osal_ipclock_t;
21
+
22
+ #elif MDBX_LOCKING == MDBX_LOCKING_POSIX2001 || MDBX_LOCKING == MDBX_LOCKING_POSIX2008
23
+
24
+ #define MDBX_LCK_SIGN UINT32_C(0x8017)
25
+ typedef pthread_mutex_t osal_ipclock_t;
26
+
27
+ #elif MDBX_LOCKING == MDBX_LOCKING_POSIX1988
28
+
29
+ #define MDBX_LCK_SIGN UINT32_C(0xFC29)
30
+ typedef sem_t osal_ipclock_t;
31
+
32
+ #else
33
+ #error "FIXME"
34
+ #endif /* MDBX_LOCKING */
35
+
36
+ /* Статистика профилирования работы GC */
37
+ typedef struct gc_prof_stat {
38
+ /* Монотонное время по "настенным часам"
39
+ * затраченное на чтение и поиск внутри GC */
40
+ uint64_t rtime_monotonic;
41
+ /* Процессорное время в режим пользователя
42
+ * на подготовку страниц извлекаемых из GC, включая подкачку с диска. */
43
+ uint64_t xtime_cpu;
44
+ /* Количество итераций чтения-поиска внутри GC при выделении страниц */
45
+ uint32_t rsteps;
46
+ /* Количество запросов на выделение последовательностей страниц,
47
+ * т.е. когда запрашивает выделение больше одной страницы */
48
+ uint32_t xpages;
49
+ /* Счетчик выполнения по медленному пути (slow path execution count) */
50
+ uint32_t spe_counter;
51
+ /* page faults (hard page faults) */
52
+ uint32_t majflt;
53
+ /* Для разборок с pnl_merge() */
54
+ struct {
55
+ uint64_t time;
56
+ uint64_t volume;
57
+ uint32_t calls;
58
+ } pnl_merge;
59
+ } gc_prof_stat_t;
60
+
61
+ /* Statistics of pages operations for all transactions,
62
+ * including incomplete and aborted. */
63
+ typedef struct pgops {
64
+ mdbx_atomic_uint64_t newly; /* Quantity of a new pages added */
65
+ mdbx_atomic_uint64_t cow; /* Quantity of pages copied for update */
66
+ mdbx_atomic_uint64_t clone; /* Quantity of parent's dirty pages clones
67
+ for nested transactions */
68
+ mdbx_atomic_uint64_t split; /* Page splits */
69
+ mdbx_atomic_uint64_t merge; /* Page merges */
70
+ mdbx_atomic_uint64_t spill; /* Quantity of spilled dirty pages */
71
+ mdbx_atomic_uint64_t unspill; /* Quantity of unspilled/reloaded pages */
72
+ mdbx_atomic_uint64_t wops; /* Number of explicit write operations (not a pages) to a disk */
73
+ mdbx_atomic_uint64_t msync; /* Number of explicit msync/flush-to-disk operations */
74
+ mdbx_atomic_uint64_t fsync; /* Number of explicit fsync/flush-to-disk operations */
75
+
76
+ mdbx_atomic_uint64_t prefault; /* Number of prefault write operations */
77
+ mdbx_atomic_uint64_t mincore; /* Number of mincore() calls */
78
+
79
+ mdbx_atomic_uint32_t incoherence; /* number of https://libmdbx.dqdkfa.ru/dead-github/issues/269
80
+ caught */
81
+ mdbx_atomic_uint32_t reserved;
82
+
83
+ /* Статистика для профилирования GC.
84
+ * Логически эти данные, возможно, стоит вынести в другую структуру,
85
+ * но разница будет сугубо косметическая. */
86
+ struct {
87
+ /* Затраты на поддержку данных пользователя */
88
+ gc_prof_stat_t work;
89
+ /* Затраты на поддержку и обновления самой GC */
90
+ gc_prof_stat_t self;
91
+ /* Итераций обновления GC,
92
+ * больше 1 если были повторы/перезапуски */
93
+ uint32_t wloops;
94
+ /* Итерации слияния записей GC */
95
+ uint32_t coalescences;
96
+ /* Уничтожения steady-точек фиксации в MDBX_UTTERLY_NOSYNC */
97
+ uint32_t wipes;
98
+ /* Сбросы данные на диск вне MDBX_UTTERLY_NOSYNC */
99
+ uint32_t flushes;
100
+ /* Попытки пнуть тормозящих читателей */
101
+ uint32_t kicks;
102
+ } gc_prof;
103
+ } pgop_stat_t;
104
+
105
+ /* Reader Lock Table
106
+ *
107
+ * Readers don't acquire any locks for their data access. Instead, they
108
+ * simply record their transaction ID in the reader table. The reader
109
+ * mutex is needed just to find an empty slot in the reader table. The
110
+ * slot's address is saved in thread-specific data so that subsequent
111
+ * read transactions started by the same thread need no further locking to
112
+ * proceed.
113
+ *
114
+ * If MDBX_NOSTICKYTHREADS is set, the slot address is not saved in
115
+ * thread-specific data. No reader table is used if the database is on a
116
+ * read-only filesystem.
117
+ *
118
+ * Since the database uses multi-version concurrency control, readers don't
119
+ * actually need any locking. This table is used to keep track of which
120
+ * readers are using data from which old transactions, so that we'll know
121
+ * when a particular old transaction is no longer in use. Old transactions
122
+ * that have discarded any data pages can then have those pages reclaimed
123
+ * for use by a later write transaction.
124
+ *
125
+ * The lock table is constructed such that reader slots are aligned with the
126
+ * processor's cache line size. Any slot is only ever used by one thread.
127
+ * This alignment guarantees that there will be no contention or cache
128
+ * thrashing as threads update their own slot info, and also eliminates
129
+ * any need for locking when accessing a slot.
130
+ *
131
+ * A writer thread will scan every slot in the table to determine the oldest
132
+ * outstanding reader transaction. Any freed pages older than this will be
133
+ * reclaimed by the writer. The writer doesn't use any locks when scanning
134
+ * this table. This means that there's no guarantee that the writer will
135
+ * see the most up-to-date reader info, but that's not required for correct
136
+ * operation - all we need is to know the upper bound on the oldest reader,
137
+ * we don't care at all about the newest reader. So the only consequence of
138
+ * reading stale information here is that old pages might hang around a
139
+ * while longer before being reclaimed. That's actually good anyway, because
140
+ * the longer we delay reclaiming old pages, the more likely it is that a
141
+ * string of contiguous pages can be found after coalescing old pages from
142
+ * many old transactions together. */
143
+
144
+ /* The actual reader record, with cacheline padding. */
145
+ typedef struct reader_slot {
146
+ /* Current Transaction ID when this transaction began, or INVALID_TXNID.
147
+ * Multiple readers that start at the same time will probably have the
148
+ * same ID here. Again, it's not important to exclude them from
149
+ * anything; all we need to know is which version of the DB they
150
+ * started from so we can avoid overwriting any data used in that
151
+ * particular version. */
152
+ atomic_txnid_t txnid;
153
+
154
+ /* The information we store in a single slot of the reader table.
155
+ * In addition to a transaction ID, we also record the process and
156
+ * thread ID that owns a slot, so that we can detect stale information,
157
+ * e.g. threads or processes that went away without cleaning up.
158
+ *
159
+ * NOTE: We currently don't check for stale records.
160
+ * We simply re-init the table when we know that we're the only process
161
+ * opening the lock file. */
162
+
163
+ /* Псевдо thread_id для пометки вытесненных читающих транзакций. */
164
+ #define MDBX_TID_TXN_OUSTED (UINT64_MAX - 1)
165
+
166
+ /* Псевдо thread_id для пометки припаркованных читающих транзакций. */
167
+ #define MDBX_TID_TXN_PARKED UINT64_MAX
168
+
169
+ /* The thread ID of the thread owning this txn. */
170
+ mdbx_atomic_uint64_t tid;
171
+
172
+ /* The process ID of the process owning this reader txn. */
173
+ mdbx_atomic_uint32_t pid;
174
+
175
+ /* The number of pages used in the reader's MVCC snapshot,
176
+ * i.e. the value of meta->geometry.first_unallocated and
177
+ * txn->geo.first_unallocated */
178
+ atomic_pgno_t snapshot_pages_used;
179
+ /* Number of retired pages at the time this reader starts transaction. So,
180
+ * at any time the difference meta.pages_retired -
181
+ * reader.snapshot_pages_retired will give the number of pages which this
182
+ * reader restraining from reuse. */
183
+ mdbx_atomic_uint64_t snapshot_pages_retired;
184
+ } reader_slot_t;
185
+
186
+ /* The header for the reader table (a memory-mapped lock file). */
187
+ typedef struct shared_lck {
188
+ /* Stamp identifying this as an MDBX file.
189
+ * It must be set to MDBX_MAGIC with with MDBX_LOCK_VERSION. */
190
+ uint64_t magic_and_version;
191
+
192
+ /* Format of this lock file. Must be set to MDBX_LOCK_FORMAT. */
193
+ uint32_t os_and_format;
194
+
195
+ /* Flags which environment was opened. */
196
+ mdbx_atomic_uint32_t envmode;
197
+
198
+ /* Threshold of un-synced-with-disk pages for auto-sync feature,
199
+ * zero means no-threshold, i.e. auto-sync is disabled. */
200
+ atomic_pgno_t autosync_threshold;
201
+
202
+ /* Low 32-bit of txnid with which meta-pages was synced,
203
+ * i.e. for sync-polling in the MDBX_NOMETASYNC mode. */
204
+ #define MDBX_NOMETASYNC_LAZY_UNK (UINT32_MAX / 3)
205
+ #define MDBX_NOMETASYNC_LAZY_FD (MDBX_NOMETASYNC_LAZY_UNK + UINT32_MAX / 8)
206
+ #define MDBX_NOMETASYNC_LAZY_WRITEMAP (MDBX_NOMETASYNC_LAZY_UNK - UINT32_MAX / 8)
207
+ mdbx_atomic_uint32_t meta_sync_txnid;
208
+
209
+ /* Period for timed auto-sync feature, i.e. at the every steady checkpoint
210
+ * the mti_unsynced_timeout sets to the current_time + autosync_period.
211
+ * The time value is represented in a suitable system-dependent form, for
212
+ * example clock_gettime(CLOCK_BOOTTIME) or clock_gettime(CLOCK_MONOTONIC).
213
+ * Zero means timed auto-sync is disabled. */
214
+ mdbx_atomic_uint64_t autosync_period;
215
+
216
+ /* Marker to distinguish uniqueness of DB/CLK. */
217
+ mdbx_atomic_uint64_t bait_uniqueness;
218
+
219
+ /* Paired counter of processes that have mlock()ed part of mmapped DB.
220
+ * The (mlcnt[0] - mlcnt[1]) > 0 means at least one process
221
+ * lock at least one page, so therefore madvise() could return EINVAL. */
222
+ mdbx_atomic_uint32_t mlcnt[2];
223
+
224
+ MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
225
+
226
+ /* Statistics of costly ops of all (running, completed and aborted)
227
+ * transactions */
228
+ pgop_stat_t pgops;
229
+
230
+ MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
231
+
232
+ #if MDBX_LOCKING > 0
233
+ /* Write transaction lock. */
234
+ osal_ipclock_t wrt_lock;
235
+ #endif /* MDBX_LOCKING > 0 */
236
+
237
+ atomic_txnid_t cached_oldest;
238
+
239
+ /* Timestamp of entering an out-of-sync state. Value is represented in a
240
+ * suitable system-dependent form, for example clock_gettime(CLOCK_BOOTTIME)
241
+ * or clock_gettime(CLOCK_MONOTONIC). */
242
+ mdbx_atomic_uint64_t eoos_timestamp;
243
+
244
+ /* Number un-synced-with-disk pages for auto-sync feature. */
245
+ mdbx_atomic_uint64_t unsynced_pages;
246
+
247
+ /* Timestamp of the last readers check. */
248
+ mdbx_atomic_uint64_t readers_check_timestamp;
249
+
250
+ /* Number of page which was discarded last time by madvise(DONTNEED). */
251
+ atomic_pgno_t discarded_tail;
252
+
253
+ /* Shared anchor for tracking readahead edge and enabled/disabled status. */
254
+ pgno_t readahead_anchor;
255
+
256
+ /* Shared cache for mincore() results */
257
+ struct {
258
+ pgno_t begin[4];
259
+ uint64_t mask[4];
260
+ } mincore_cache;
261
+
262
+ MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
263
+
264
+ #if MDBX_LOCKING > 0
265
+ /* Readeaders table lock. */
266
+ osal_ipclock_t rdt_lock;
267
+ #endif /* MDBX_LOCKING > 0 */
268
+
269
+ /* The number of slots that have been used in the reader table.
270
+ * This always records the maximum count, it is not decremented
271
+ * when readers release their slots. */
272
+ mdbx_atomic_uint32_t rdt_length;
273
+ mdbx_atomic_uint32_t rdt_refresh_flag;
274
+
275
+ #if FLEXIBLE_ARRAY_MEMBERS
276
+ MDBX_ALIGNAS(MDBX_CACHELINE_SIZE) /* cacheline ----------------------------*/
277
+ reader_slot_t rdt[] /* dynamic size */;
278
+
279
+ /* Lockfile format signature: version, features and field layout */
280
+ #define MDBX_LOCK_FORMAT \
281
+ (MDBX_LCK_SIGN * 27733 + (unsigned)sizeof(reader_slot_t) * 13 + \
282
+ (unsigned)offsetof(reader_slot_t, snapshot_pages_used) * 251 + (unsigned)offsetof(lck_t, cached_oldest) * 83 + \
283
+ (unsigned)offsetof(lck_t, rdt_length) * 37 + (unsigned)offsetof(lck_t, rdt) * 29)
284
+ #endif /* FLEXIBLE_ARRAY_MEMBERS */
285
+ } lck_t;
286
+
287
+ #define MDBX_LOCK_MAGIC ((MDBX_MAGIC << 8) + MDBX_LOCK_VERSION)
288
+
289
+ #define MDBX_READERS_LIMIT 32767