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,364 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
3
+
4
+ #pragma once
5
+
6
+ #include "essentials.h"
7
+
8
+ #ifndef __cplusplus
9
+
10
+ #ifdef MDBX_HAVE_C11ATOMICS
11
+ #define osal_memory_fence(order, write) atomic_thread_fence((write) ? mo_c11_store(order) : mo_c11_load(order))
12
+ #else /* MDBX_HAVE_C11ATOMICS */
13
+ #define osal_memory_fence(order, write) \
14
+ do { \
15
+ osal_compiler_barrier(); \
16
+ if (write && order > (MDBX_CPU_WRITEBACK_INCOHERENT ? mo_Relaxed : mo_AcquireRelease)) \
17
+ osal_memory_barrier(); \
18
+ } while (0)
19
+ #endif /* MDBX_HAVE_C11ATOMICS */
20
+
21
+ #if defined(MDBX_HAVE_C11ATOMICS) && defined(__LCC__)
22
+ #define atomic_store32(p, value, order) \
23
+ ({ \
24
+ const uint32_t value_to_store = (value); \
25
+ atomic_store_explicit(MDBX_c11a_rw(uint32_t, p), value_to_store, mo_c11_store(order)); \
26
+ value_to_store; \
27
+ })
28
+ #define atomic_load32(p, order) atomic_load_explicit(MDBX_c11a_ro(uint32_t, p), mo_c11_load(order))
29
+ #define atomic_store64(p, value, order) \
30
+ ({ \
31
+ const uint64_t value_to_store = (value); \
32
+ atomic_store_explicit(MDBX_c11a_rw(uint64_t, p), value_to_store, mo_c11_store(order)); \
33
+ value_to_store; \
34
+ })
35
+ #define atomic_load64(p, order) atomic_load_explicit(MDBX_c11a_ro(uint64_t, p), mo_c11_load(order))
36
+ #endif /* LCC && MDBX_HAVE_C11ATOMICS */
37
+
38
+ #ifndef atomic_store32
39
+ MDBX_MAYBE_UNUSED static __always_inline uint32_t atomic_store32(mdbx_atomic_uint32_t *p, const uint32_t value,
40
+ enum mdbx_memory_order order) {
41
+ STATIC_ASSERT(sizeof(mdbx_atomic_uint32_t) == 4);
42
+ #ifdef MDBX_HAVE_C11ATOMICS
43
+ assert(atomic_is_lock_free(MDBX_c11a_rw(uint32_t, p)));
44
+ atomic_store_explicit(MDBX_c11a_rw(uint32_t, p), value, mo_c11_store(order));
45
+ #else /* MDBX_HAVE_C11ATOMICS */
46
+ if (order != mo_Relaxed)
47
+ osal_compiler_barrier();
48
+ p->weak = value;
49
+ osal_memory_fence(order, true);
50
+ #endif /* MDBX_HAVE_C11ATOMICS */
51
+ return value;
52
+ }
53
+ #endif /* atomic_store32 */
54
+
55
+ #ifndef atomic_load32
56
+ MDBX_MAYBE_UNUSED static __always_inline uint32_t atomic_load32(const volatile mdbx_atomic_uint32_t *p,
57
+ enum mdbx_memory_order order) {
58
+ STATIC_ASSERT(sizeof(mdbx_atomic_uint32_t) == 4);
59
+ #ifdef MDBX_HAVE_C11ATOMICS
60
+ assert(atomic_is_lock_free(MDBX_c11a_ro(uint32_t, p)));
61
+ return atomic_load_explicit(MDBX_c11a_ro(uint32_t, p), mo_c11_load(order));
62
+ #else /* MDBX_HAVE_C11ATOMICS */
63
+ osal_memory_fence(order, false);
64
+ const uint32_t value = p->weak;
65
+ if (order != mo_Relaxed)
66
+ osal_compiler_barrier();
67
+ return value;
68
+ #endif /* MDBX_HAVE_C11ATOMICS */
69
+ }
70
+ #endif /* atomic_load32 */
71
+
72
+ /*------------------------------------------------------------------------------
73
+ * safe read/write volatile 64-bit fields on 32-bit architectures. */
74
+
75
+ /* LY: for testing non-atomic 64-bit txnid on 32-bit arches.
76
+ * #define xMDBX_TXNID_STEP (UINT32_MAX / 3) */
77
+ #ifndef xMDBX_TXNID_STEP
78
+ #if MDBX_64BIT_CAS
79
+ #define xMDBX_TXNID_STEP 1u
80
+ #else
81
+ #define xMDBX_TXNID_STEP 2u
82
+ #endif
83
+ #endif /* xMDBX_TXNID_STEP */
84
+
85
+ #ifndef atomic_store64
86
+ MDBX_MAYBE_UNUSED static __always_inline uint64_t atomic_store64(mdbx_atomic_uint64_t *p, const uint64_t value,
87
+ enum mdbx_memory_order order) {
88
+ STATIC_ASSERT(sizeof(mdbx_atomic_uint64_t) == 8);
89
+ #if MDBX_64BIT_ATOMIC
90
+ #if __GNUC_PREREQ(11, 0)
91
+ STATIC_ASSERT(__alignof__(mdbx_atomic_uint64_t) >= sizeof(uint64_t));
92
+ #endif /* GNU C >= 11 */
93
+ #ifdef MDBX_HAVE_C11ATOMICS
94
+ assert(atomic_is_lock_free(MDBX_c11a_rw(uint64_t, p)));
95
+ atomic_store_explicit(MDBX_c11a_rw(uint64_t, p), value, mo_c11_store(order));
96
+ #else /* MDBX_HAVE_C11ATOMICS */
97
+ if (order != mo_Relaxed)
98
+ osal_compiler_barrier();
99
+ p->weak = value;
100
+ osal_memory_fence(order, true);
101
+ #endif /* MDBX_HAVE_C11ATOMICS */
102
+ #else /* !MDBX_64BIT_ATOMIC */
103
+ osal_compiler_barrier();
104
+ atomic_store32(&p->low, (uint32_t)value, mo_Relaxed);
105
+ jitter4testing(true);
106
+ atomic_store32(&p->high, (uint32_t)(value >> 32), order);
107
+ jitter4testing(true);
108
+ #endif /* !MDBX_64BIT_ATOMIC */
109
+ return value;
110
+ }
111
+ #endif /* atomic_store64 */
112
+
113
+ #ifndef atomic_load64
114
+ MDBX_MAYBE_UNUSED static
115
+ #if MDBX_64BIT_ATOMIC
116
+ __always_inline
117
+ #endif /* MDBX_64BIT_ATOMIC */
118
+ uint64_t
119
+ atomic_load64(const volatile mdbx_atomic_uint64_t *p, enum mdbx_memory_order order) {
120
+ STATIC_ASSERT(sizeof(mdbx_atomic_uint64_t) == 8);
121
+ #if MDBX_64BIT_ATOMIC
122
+ #ifdef MDBX_HAVE_C11ATOMICS
123
+ assert(atomic_is_lock_free(MDBX_c11a_ro(uint64_t, p)));
124
+ return atomic_load_explicit(MDBX_c11a_ro(uint64_t, p), mo_c11_load(order));
125
+ #else /* MDBX_HAVE_C11ATOMICS */
126
+ osal_memory_fence(order, false);
127
+ const uint64_t value = p->weak;
128
+ if (order != mo_Relaxed)
129
+ osal_compiler_barrier();
130
+ return value;
131
+ #endif /* MDBX_HAVE_C11ATOMICS */
132
+ #else /* !MDBX_64BIT_ATOMIC */
133
+ osal_compiler_barrier();
134
+ uint64_t value = (uint64_t)atomic_load32(&p->high, order) << 32;
135
+ jitter4testing(true);
136
+ value |= atomic_load32(&p->low, (order == mo_Relaxed) ? mo_Relaxed : mo_AcquireRelease);
137
+ jitter4testing(true);
138
+ for (;;) {
139
+ osal_compiler_barrier();
140
+ uint64_t again = (uint64_t)atomic_load32(&p->high, order) << 32;
141
+ jitter4testing(true);
142
+ again |= atomic_load32(&p->low, (order == mo_Relaxed) ? mo_Relaxed : mo_AcquireRelease);
143
+ jitter4testing(true);
144
+ if (likely(value == again))
145
+ return value;
146
+ value = again;
147
+ }
148
+ #endif /* !MDBX_64BIT_ATOMIC */
149
+ }
150
+ #endif /* atomic_load64 */
151
+
152
+ MDBX_MAYBE_UNUSED static __always_inline void atomic_yield(void) {
153
+ #if defined(_WIN32) || defined(_WIN64)
154
+ YieldProcessor();
155
+ #elif defined(__ia32__) || defined(__e2k__)
156
+ __builtin_ia32_pause();
157
+ #elif defined(__ia64__)
158
+ #if defined(__HP_cc__) || defined(__HP_aCC__)
159
+ _Asm_hint(_HINT_PAUSE);
160
+ #else
161
+ __asm__ __volatile__("hint @pause");
162
+ #endif
163
+ #elif defined(__aarch64__) || (defined(__ARM_ARCH) && __ARM_ARCH > 6) || defined(__ARM_ARCH_6K__)
164
+ #ifdef __CC_ARM
165
+ __yield();
166
+ #else
167
+ __asm__ __volatile__("yield");
168
+ #endif
169
+ #elif (defined(__mips64) || defined(__mips64__)) && defined(__mips_isa_rev) && __mips_isa_rev >= 2
170
+ __asm__ __volatile__("pause");
171
+ #elif defined(__mips) || defined(__mips__) || defined(__mips64) || defined(__mips64__) || defined(_M_MRX000) || \
172
+ defined(_MIPS_) || defined(__MWERKS__) || defined(__sgi)
173
+ __asm__ __volatile__(".word 0x00000140");
174
+ #elif defined(__linux__) || defined(__gnu_linux__) || defined(_UNIX03_SOURCE)
175
+ sched_yield();
176
+ #elif (defined(_GNU_SOURCE) && __GLIBC_PREREQ(2, 1)) || defined(_OPEN_THREADS)
177
+ pthread_yield();
178
+ #endif
179
+ }
180
+
181
+ #if MDBX_64BIT_CAS
182
+ MDBX_MAYBE_UNUSED static __always_inline bool atomic_cas64(mdbx_atomic_uint64_t *p, uint64_t c, uint64_t v) {
183
+ #ifdef MDBX_HAVE_C11ATOMICS
184
+ STATIC_ASSERT(sizeof(long long) >= sizeof(uint64_t));
185
+ assert(atomic_is_lock_free(MDBX_c11a_rw(uint64_t, p)));
186
+ return atomic_compare_exchange_strong(MDBX_c11a_rw(uint64_t, p), &c, v);
187
+ #elif defined(__GNUC__) || defined(__clang__)
188
+ return __sync_bool_compare_and_swap(&p->weak, c, v);
189
+ #elif defined(_MSC_VER)
190
+ return c == (uint64_t)_InterlockedCompareExchange64((volatile __int64 *)&p->weak, v, c);
191
+ #elif defined(__APPLE__)
192
+ return OSAtomicCompareAndSwap64Barrier(c, v, &p->weak);
193
+ #else
194
+ #error FIXME: Unsupported compiler
195
+ #endif
196
+ }
197
+ #endif /* MDBX_64BIT_CAS */
198
+
199
+ MDBX_MAYBE_UNUSED static __always_inline bool atomic_cas32(mdbx_atomic_uint32_t *p, uint32_t c, uint32_t v) {
200
+ #ifdef MDBX_HAVE_C11ATOMICS
201
+ STATIC_ASSERT(sizeof(int) >= sizeof(uint32_t));
202
+ assert(atomic_is_lock_free(MDBX_c11a_rw(uint32_t, p)));
203
+ return atomic_compare_exchange_strong(MDBX_c11a_rw(uint32_t, p), &c, v);
204
+ #elif defined(__GNUC__) || defined(__clang__)
205
+ return __sync_bool_compare_and_swap(&p->weak, c, v);
206
+ #elif defined(_MSC_VER)
207
+ STATIC_ASSERT(sizeof(volatile long) == sizeof(volatile uint32_t));
208
+ return c == (uint32_t)_InterlockedCompareExchange((volatile long *)&p->weak, v, c);
209
+ #elif defined(__APPLE__)
210
+ return OSAtomicCompareAndSwap32Barrier(c, v, &p->weak);
211
+ #else
212
+ #error FIXME: Unsupported compiler
213
+ #endif
214
+ }
215
+
216
+ MDBX_MAYBE_UNUSED static __always_inline uint32_t atomic_add32(mdbx_atomic_uint32_t *p, uint32_t v) {
217
+ #ifdef MDBX_HAVE_C11ATOMICS
218
+ STATIC_ASSERT(sizeof(int) >= sizeof(uint32_t));
219
+ assert(atomic_is_lock_free(MDBX_c11a_rw(uint32_t, p)));
220
+ return atomic_fetch_add(MDBX_c11a_rw(uint32_t, p), v);
221
+ #elif defined(__GNUC__) || defined(__clang__)
222
+ return __sync_fetch_and_add(&p->weak, v);
223
+ #elif defined(_MSC_VER)
224
+ STATIC_ASSERT(sizeof(volatile long) == sizeof(volatile uint32_t));
225
+ return (uint32_t)_InterlockedExchangeAdd((volatile long *)&p->weak, v);
226
+ #elif defined(__APPLE__)
227
+ return OSAtomicAdd32Barrier(v, &p->weak);
228
+ #else
229
+ #error FIXME: Unsupported compiler
230
+ #endif
231
+ }
232
+
233
+ #define atomic_sub32(p, v) atomic_add32(p, 0 - (v))
234
+
235
+ MDBX_MAYBE_UNUSED static __always_inline uint64_t safe64_txnid_next(uint64_t txnid) {
236
+ txnid += xMDBX_TXNID_STEP;
237
+ #if !MDBX_64BIT_CAS
238
+ /* avoid overflow of low-part in safe64_reset() */
239
+ txnid += (UINT32_MAX == (uint32_t)txnid);
240
+ #endif
241
+ return txnid;
242
+ }
243
+
244
+ /* Atomically make target value >= SAFE64_INVALID_THRESHOLD */
245
+ MDBX_MAYBE_UNUSED static __always_inline void safe64_reset(mdbx_atomic_uint64_t *p, bool single_writer) {
246
+ if (single_writer) {
247
+ #if MDBX_64BIT_ATOMIC && MDBX_WORDBITS >= 64
248
+ atomic_store64(p, UINT64_MAX, mo_AcquireRelease);
249
+ #else
250
+ atomic_store32(&p->high, UINT32_MAX, mo_AcquireRelease);
251
+ #endif /* MDBX_64BIT_ATOMIC && MDBX_WORDBITS >= 64 */
252
+ } else {
253
+ #if MDBX_64BIT_CAS && MDBX_64BIT_ATOMIC
254
+ /* atomically make value >= SAFE64_INVALID_THRESHOLD by 64-bit operation */
255
+ atomic_store64(p, UINT64_MAX, mo_AcquireRelease);
256
+ #elif MDBX_64BIT_CAS
257
+ /* atomically make value >= SAFE64_INVALID_THRESHOLD by 32-bit operation */
258
+ atomic_store32(&p->high, UINT32_MAX, mo_AcquireRelease);
259
+ #else
260
+ /* it is safe to increment low-part to avoid ABA, since xMDBX_TXNID_STEP > 1
261
+ * and overflow was preserved in safe64_txnid_next() */
262
+ STATIC_ASSERT(xMDBX_TXNID_STEP > 1);
263
+ atomic_add32(&p->low, 1) /* avoid ABA in safe64_reset_compare() */;
264
+ atomic_store32(&p->high, UINT32_MAX, mo_AcquireRelease);
265
+ atomic_add32(&p->low, 1) /* avoid ABA in safe64_reset_compare() */;
266
+ #endif /* MDBX_64BIT_CAS && MDBX_64BIT_ATOMIC */
267
+ }
268
+ assert(p->weak >= SAFE64_INVALID_THRESHOLD);
269
+ jitter4testing(true);
270
+ }
271
+
272
+ MDBX_MAYBE_UNUSED static __always_inline bool safe64_reset_compare(mdbx_atomic_uint64_t *p, uint64_t compare) {
273
+ /* LY: This function is used to reset `txnid` from hsr-handler in case
274
+ * the asynchronously cancellation of read transaction. Therefore,
275
+ * there may be a collision between the cleanup performed here and
276
+ * asynchronous termination and restarting of the read transaction
277
+ * in another process/thread. In general we MUST NOT reset the `txnid`
278
+ * if a new transaction was started (i.e. if `txnid` was changed). */
279
+ #if MDBX_64BIT_CAS
280
+ bool rc = atomic_cas64(p, compare, UINT64_MAX);
281
+ #else
282
+ /* LY: There is no gold ratio here since shared mutex is too costly,
283
+ * in such way we must acquire/release it for every update of txnid,
284
+ * i.e. twice for each read transaction). */
285
+ bool rc = false;
286
+ if (likely(atomic_load32(&p->low, mo_AcquireRelease) == (uint32_t)compare &&
287
+ atomic_cas32(&p->high, (uint32_t)(compare >> 32), UINT32_MAX))) {
288
+ if (unlikely(atomic_load32(&p->low, mo_AcquireRelease) != (uint32_t)compare))
289
+ atomic_cas32(&p->high, UINT32_MAX, (uint32_t)(compare >> 32));
290
+ else
291
+ rc = true;
292
+ }
293
+ #endif /* MDBX_64BIT_CAS */
294
+ jitter4testing(true);
295
+ return rc;
296
+ }
297
+
298
+ MDBX_MAYBE_UNUSED static __always_inline void safe64_write(mdbx_atomic_uint64_t *p, const uint64_t v) {
299
+ assert(p->weak >= SAFE64_INVALID_THRESHOLD);
300
+ #if MDBX_64BIT_ATOMIC && MDBX_64BIT_CAS
301
+ atomic_store64(p, v, mo_AcquireRelease);
302
+ #else /* MDBX_64BIT_ATOMIC */
303
+ osal_compiler_barrier();
304
+ /* update low-part but still value >= SAFE64_INVALID_THRESHOLD */
305
+ atomic_store32(&p->low, (uint32_t)v, mo_Relaxed);
306
+ assert(p->weak >= SAFE64_INVALID_THRESHOLD);
307
+ jitter4testing(true);
308
+ /* update high-part from SAFE64_INVALID_THRESHOLD to actual value */
309
+ atomic_store32(&p->high, (uint32_t)(v >> 32), mo_AcquireRelease);
310
+ #endif /* MDBX_64BIT_ATOMIC */
311
+ assert(p->weak == v);
312
+ jitter4testing(true);
313
+ }
314
+
315
+ MDBX_MAYBE_UNUSED static __always_inline uint64_t safe64_read(const mdbx_atomic_uint64_t *p) {
316
+ jitter4testing(true);
317
+ uint64_t v;
318
+ do
319
+ v = atomic_load64(p, mo_AcquireRelease);
320
+ while (!MDBX_64BIT_ATOMIC && unlikely(v != p->weak));
321
+ return v;
322
+ }
323
+
324
+ #if 0 /* unused for now */
325
+ MDBX_MAYBE_UNUSED static __always_inline bool safe64_is_valid(uint64_t v) {
326
+ #if MDBX_WORDBITS >= 64
327
+ return v < SAFE64_INVALID_THRESHOLD;
328
+ #else
329
+ return (v >> 32) != UINT32_MAX;
330
+ #endif /* MDBX_WORDBITS */
331
+ }
332
+
333
+ MDBX_MAYBE_UNUSED static __always_inline bool
334
+ safe64_is_valid_ptr(const mdbx_atomic_uint64_t *p) {
335
+ #if MDBX_64BIT_ATOMIC
336
+ return atomic_load64(p, mo_AcquireRelease) < SAFE64_INVALID_THRESHOLD;
337
+ #else
338
+ return atomic_load32(&p->high, mo_AcquireRelease) != UINT32_MAX;
339
+ #endif /* MDBX_64BIT_ATOMIC */
340
+ }
341
+ #endif /* unused for now */
342
+
343
+ /* non-atomic write with safety for reading a half-updated value */
344
+ MDBX_MAYBE_UNUSED static __always_inline void safe64_update(mdbx_atomic_uint64_t *p, const uint64_t v) {
345
+ #if MDBX_64BIT_ATOMIC
346
+ atomic_store64(p, v, mo_Relaxed);
347
+ #else
348
+ safe64_reset(p, true);
349
+ safe64_write(p, v);
350
+ #endif /* MDBX_64BIT_ATOMIC */
351
+ }
352
+
353
+ /* non-atomic increment with safety for reading a half-updated value */
354
+ MDBX_MAYBE_UNUSED static
355
+ #if MDBX_64BIT_ATOMIC
356
+ __always_inline
357
+ #endif /* MDBX_64BIT_ATOMIC */
358
+ void
359
+ safe64_inc(mdbx_atomic_uint64_t *p, const uint64_t v) {
360
+ assert(v > 0);
361
+ safe64_update(p, safe64_read(p) + v);
362
+ }
363
+
364
+ #endif /* !__cplusplus */
@@ -0,0 +1,97 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
3
+
4
+ #pragma once
5
+
6
+ #include "essentials.h"
7
+
8
+ #ifndef MDBX_64BIT_ATOMIC
9
+ #error "The MDBX_64BIT_ATOMIC must be defined before"
10
+ #endif /* MDBX_64BIT_ATOMIC */
11
+
12
+ #ifndef MDBX_64BIT_CAS
13
+ #error "The MDBX_64BIT_CAS must be defined before"
14
+ #endif /* MDBX_64BIT_CAS */
15
+
16
+ #if defined(__cplusplus) && !defined(__STDC_NO_ATOMICS__) && __has_include(<cstdatomic>)
17
+ #include <cstdatomic>
18
+ #define MDBX_HAVE_C11ATOMICS
19
+ #elif !defined(__cplusplus) && (__STDC_VERSION__ >= 201112L || __has_extension(c_atomic)) && \
20
+ !defined(__STDC_NO_ATOMICS__) && \
21
+ (__GNUC_PREREQ(4, 9) || __CLANG_PREREQ(3, 8) || !(defined(__GNUC__) || defined(__clang__)))
22
+ #include <stdatomic.h>
23
+ #define MDBX_HAVE_C11ATOMICS
24
+ #elif defined(__GNUC__) || defined(__clang__)
25
+ #elif defined(_MSC_VER)
26
+ #pragma warning(disable : 4163) /* 'xyz': not available as an intrinsic */
27
+ #pragma warning(disable : 4133) /* 'function': incompatible types - from \
28
+ 'size_t' to 'LONGLONG' */
29
+ #pragma warning(disable : 4244) /* 'return': conversion from 'LONGLONG' to \
30
+ 'std::size_t', possible loss of data */
31
+ #pragma warning(disable : 4267) /* 'function': conversion from 'size_t' to \
32
+ 'long', possible loss of data */
33
+ #pragma intrinsic(_InterlockedExchangeAdd, _InterlockedCompareExchange)
34
+ #pragma intrinsic(_InterlockedExchangeAdd64, _InterlockedCompareExchange64)
35
+ #elif defined(__APPLE__)
36
+ #include <libkern/OSAtomic.h>
37
+ #else
38
+ #error FIXME atomic-ops
39
+ #endif
40
+
41
+ typedef enum mdbx_memory_order {
42
+ mo_Relaxed,
43
+ mo_AcquireRelease
44
+ /* , mo_SequentialConsistency */
45
+ } mdbx_memory_order_t;
46
+
47
+ typedef union {
48
+ volatile uint32_t weak;
49
+ #ifdef MDBX_HAVE_C11ATOMICS
50
+ volatile _Atomic uint32_t c11a;
51
+ #endif /* MDBX_HAVE_C11ATOMICS */
52
+ } mdbx_atomic_uint32_t;
53
+
54
+ typedef union {
55
+ volatile uint64_t weak;
56
+ #if defined(MDBX_HAVE_C11ATOMICS) && (MDBX_64BIT_CAS || MDBX_64BIT_ATOMIC)
57
+ volatile _Atomic uint64_t c11a;
58
+ #endif
59
+ #if !defined(MDBX_HAVE_C11ATOMICS) || !MDBX_64BIT_CAS || !MDBX_64BIT_ATOMIC
60
+ __anonymous_struct_extension__ struct {
61
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
62
+ mdbx_atomic_uint32_t low, high;
63
+ #elif __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
64
+ mdbx_atomic_uint32_t high, low;
65
+ #else
66
+ #error "FIXME: Unsupported byte order"
67
+ #endif /* __BYTE_ORDER__ */
68
+ };
69
+ #endif
70
+ } mdbx_atomic_uint64_t;
71
+
72
+ #ifdef MDBX_HAVE_C11ATOMICS
73
+
74
+ /* Crutches for C11 atomic compiler's bugs */
75
+ #if defined(__e2k__) && defined(__LCC__) && __LCC__ < /* FIXME */ 127
76
+ #define MDBX_c11a_ro(type, ptr) (&(ptr)->weak)
77
+ #define MDBX_c11a_rw(type, ptr) (&(ptr)->weak)
78
+ #elif defined(__clang__) && __clang__ < 8
79
+ #define MDBX_c11a_ro(type, ptr) ((volatile _Atomic(type) *)&(ptr)->c11a)
80
+ #define MDBX_c11a_rw(type, ptr) (&(ptr)->c11a)
81
+ #else
82
+ #define MDBX_c11a_ro(type, ptr) (&(ptr)->c11a)
83
+ #define MDBX_c11a_rw(type, ptr) (&(ptr)->c11a)
84
+ #endif /* Crutches for C11 atomic compiler's bugs */
85
+
86
+ #define mo_c11_store(fence) \
87
+ (((fence) == mo_Relaxed) ? memory_order_relaxed \
88
+ : ((fence) == mo_AcquireRelease) ? memory_order_release \
89
+ : memory_order_seq_cst)
90
+ #define mo_c11_load(fence) \
91
+ (((fence) == mo_Relaxed) ? memory_order_relaxed \
92
+ : ((fence) == mo_AcquireRelease) ? memory_order_acquire \
93
+ : memory_order_seq_cst)
94
+
95
+ #endif /* MDBX_HAVE_C11ATOMICS */
96
+
97
+ #define SAFE64_INVALID_THRESHOLD UINT64_C(0xffffFFFF00000000)
@@ -0,0 +1,109 @@
1
+ /// \copyright SPDX-License-Identifier: Apache-2.0
2
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
3
+
4
+ #include "internals.h"
5
+
6
+ struct audit_ctx {
7
+ size_t used;
8
+ uint8_t *const done_bitmap;
9
+ };
10
+
11
+ static int audit_dbi(void *ctx, const MDBX_txn *txn, const MDBX_val *name, MDBX_db_flags_t flags,
12
+ const struct MDBX_stat *stat, MDBX_dbi dbi) {
13
+ struct audit_ctx *audit_ctx = ctx;
14
+ (void)name;
15
+ (void)txn;
16
+ (void)flags;
17
+ audit_ctx->used += (size_t)stat->ms_branch_pages + (size_t)stat->ms_leaf_pages + (size_t)stat->ms_overflow_pages;
18
+ if (dbi)
19
+ audit_ctx->done_bitmap[dbi / CHAR_BIT] |= 1 << dbi % CHAR_BIT;
20
+ return MDBX_SUCCESS;
21
+ }
22
+
23
+ static size_t audit_db_used(const tree_t *db) {
24
+ return db ? (size_t)db->branch_pages + (size_t)db->leaf_pages + (size_t)db->large_pages : 0;
25
+ }
26
+
27
+ __cold static int audit_ex_locked(MDBX_txn *txn, size_t retired_stored, bool dont_filter_gc) {
28
+ const MDBX_env *const env = txn->env;
29
+ size_t pending = 0;
30
+ if ((txn->flags & MDBX_TXN_RDONLY) == 0)
31
+ pending = txn->tw.loose_count + MDBX_PNL_GETSIZE(txn->tw.repnl) +
32
+ (MDBX_PNL_GETSIZE(txn->tw.retired_pages) - retired_stored);
33
+
34
+ cursor_couple_t cx;
35
+ int rc = cursor_init(&cx.outer, txn, FREE_DBI);
36
+ if (unlikely(rc != MDBX_SUCCESS))
37
+ return rc;
38
+
39
+ size_t gc = 0;
40
+ MDBX_val key, data;
41
+ rc = outer_first(&cx.outer, &key, &data);
42
+ while (rc == MDBX_SUCCESS) {
43
+ if (!dont_filter_gc) {
44
+ if (unlikely(key.iov_len != sizeof(txnid_t))) {
45
+ ERROR("%s/%d: %s %u", "MDBX_CORRUPTED", MDBX_CORRUPTED, "invalid GC-key size", (unsigned)key.iov_len);
46
+ return MDBX_CORRUPTED;
47
+ }
48
+ txnid_t id = unaligned_peek_u64(4, key.iov_base);
49
+ if (txn->tw.gc.retxl ? txl_contain(txn->tw.gc.retxl, id) : (id <= txn->tw.gc.last_reclaimed))
50
+ goto skip;
51
+ }
52
+ gc += *(pgno_t *)data.iov_base;
53
+ skip:
54
+ rc = outer_next(&cx.outer, &key, &data, MDBX_NEXT);
55
+ }
56
+ tASSERT(txn, rc == MDBX_NOTFOUND);
57
+
58
+ const size_t done_bitmap_size = (txn->n_dbi + CHAR_BIT - 1) / CHAR_BIT;
59
+ if (txn->parent) {
60
+ tASSERT(txn, txn->n_dbi == txn->parent->n_dbi && txn->n_dbi == txn->env->txn->n_dbi);
61
+ #if MDBX_ENABLE_DBI_SPARSE
62
+ tASSERT(txn, txn->dbi_sparse == txn->parent->dbi_sparse && txn->dbi_sparse == txn->env->txn->dbi_sparse);
63
+ #endif /* MDBX_ENABLE_DBI_SPARSE */
64
+ }
65
+
66
+ struct audit_ctx ctx = {0, alloca(done_bitmap_size)};
67
+ memset(ctx.done_bitmap, 0, done_bitmap_size);
68
+ ctx.used =
69
+ NUM_METAS + audit_db_used(dbi_dig(txn, FREE_DBI, nullptr)) + audit_db_used(dbi_dig(txn, MAIN_DBI, nullptr));
70
+
71
+ rc = mdbx_enumerate_tables(txn, audit_dbi, &ctx);
72
+ tASSERT(txn, rc == MDBX_SUCCESS);
73
+
74
+ for (size_t dbi = CORE_DBS; dbi < txn->n_dbi; ++dbi) {
75
+ if (ctx.done_bitmap[dbi / CHAR_BIT] & (1 << dbi % CHAR_BIT))
76
+ continue;
77
+ const tree_t *db = dbi_dig(txn, dbi, nullptr);
78
+ if (db)
79
+ ctx.used += audit_db_used(db);
80
+ else if (dbi_state(txn, dbi))
81
+ WARNING("audit %s@%" PRIaTXN ": unable account dbi %zd / \"%.*s\", state 0x%02x", txn->parent ? "nested-" : "",
82
+ txn->txnid, dbi, (int)env->kvs[dbi].name.iov_len, (const char *)env->kvs[dbi].name.iov_base,
83
+ dbi_state(txn, dbi));
84
+ }
85
+
86
+ if (pending + gc + ctx.used == txn->geo.first_unallocated)
87
+ return MDBX_SUCCESS;
88
+
89
+ if ((txn->flags & MDBX_TXN_RDONLY) == 0)
90
+ ERROR("audit @%" PRIaTXN ": %zu(pending) = %zu(loose) + "
91
+ "%zu(reclaimed) + %zu(retired-pending) - %zu(retired-stored)",
92
+ txn->txnid, pending, txn->tw.loose_count, MDBX_PNL_GETSIZE(txn->tw.repnl),
93
+ txn->tw.retired_pages ? MDBX_PNL_GETSIZE(txn->tw.retired_pages) : 0, retired_stored);
94
+ ERROR("audit @%" PRIaTXN ": %zu(pending) + %zu"
95
+ "(gc) + %zu(count) = %zu(total) <> %zu"
96
+ "(allocated)",
97
+ txn->txnid, pending, gc, ctx.used, pending + gc + ctx.used, (size_t)txn->geo.first_unallocated);
98
+ return MDBX_PROBLEM;
99
+ }
100
+
101
+ __cold int audit_ex(MDBX_txn *txn, size_t retired_stored, bool dont_filter_gc) {
102
+ MDBX_env *const env = txn->env;
103
+ int rc = osal_fastmutex_acquire(&env->dbi_lock);
104
+ if (likely(rc == MDBX_SUCCESS)) {
105
+ rc = audit_ex_locked(txn, retired_stored, dont_filter_gc);
106
+ ENSURE(txn->env, osal_fastmutex_release(&env->dbi_lock) == MDBX_SUCCESS);
107
+ }
108
+ return rc;
109
+ }
@@ -0,0 +1,34 @@
1
+ N | MASK | ENV | TXN | DB | PUT | DBI | NODE | PAGE | MRESIZE |
2
+ --|---------|-----------|--------------|----------|-----------|------------|---------|----------|---------|
3
+ 0 |0000 0001|ALLOC_RSRV |TXN_FINISHED | | |DBI_DIRTY |N_BIG |P_BRANCH | |
4
+ 1 |0000 0002|ALLOC_UNIMP|TXN_ERROR |REVERSEKEY|N_TREE |DBI_STALE |N_TREE |P_LEAF | |
5
+ 2 |0000 0004|ALLOC_COLSC|TXN_DIRTY |DUPSORT | |DBI_FRESH |N_DUP |P_LARGE | |
6
+ 3 |0000 0008|ALLOC_SSCAN|TXN_SPILLS |INTEGERKEY| |DBI_CREAT | |P_META | |
7
+ 4 |0000 0010|ALLOC_FIFO |TXN_HAS_CHILD |DUPFIXED |NOOVERWRITE|DBI_VALID | |P_BAD | |
8
+ 5 |0000 0020| |TXN_PARKED |INTEGERDUP|NODUPDATA | | |P_DUPFIX | |
9
+ 6 |0000 0040| |TXN_AUTOUNPARK|REVERSEDUP|CURRENT |DBI_OLDEN | |P_SUBP | |
10
+ 7 |0000 0080| |TXN_DRAINED_GC|DB_VALID |ALLDUPS |DBI_LINDO | | | |
11
+ 8 |0000 0100| _MAY_MOVE | | | | | | | <= |
12
+ 9 |0000 0200| _MAY_UNMAP| | | | | | | <= |
13
+ 10|0000 0400| | | | | | | | |
14
+ 11|0000 0800| | | | | | | | |
15
+ 12|0000 1000| | | | | | | | |
16
+ 13|0000 2000|VALIDATION | | | | | |P_SPILLED | |
17
+ 14|0000 4000|NOSUBDIR | | | | | |P_LOOSE | |
18
+ 15|0000 8000| | | | | | |P_FROZEN | |
19
+ 16|0001 0000|SAFE_NOSYNC|TXN_NOSYNC | |RESERVE | |RESERVE | | |
20
+ 17|0002 0000|RDONLY |TXN_RDONLY | |APPEND | |APPEND | | <= |
21
+ 18|0004 0000|NOMETASYNC |TXN_NOMETASYNC|CREATE |APPENDDUP | | | | |
22
+ 19|0008 0000|WRITEMAP |<= | |MULTIPLE | | | | <= |
23
+ 20|0010 0000|UTTERLY | | | | | | | <= |
24
+ 21|0020 0000|NOSTICKYTHR|<= | | | | | | |
25
+ 22|0040 0000|EXCLUSIVE | | | | | | | |
26
+ 23|0080 0000|NORDAHEAD | | | | | | | |
27
+ 24|0100 0000|NOMEMINIT |TXN_PREPARE | | | | | | |
28
+ 25|0200 0000|COALESCE | | | | | | | |
29
+ 26|0400 0000|LIFORECLAIM| | | | | | | |
30
+ 27|0800 0000|PAGEPERTURB| | | | | | | |
31
+ 28|1000 0000|ENV_TXKEY |TXN_TRY | | | | | | |
32
+ 29|2000 0000|ENV_ACTIVE | | | | | | | |
33
+ 30|4000 0000|ACCEDE |SHRINK_ALLOWED|DB_ACCEDE | | | | | |
34
+ 31|8000 0000|FATAL_ERROR| | | | | | | |