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,203 @@
1
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
2
+ /// \copyright SPDX-License-Identifier: Apache-2.0
3
+
4
+ #include "test.h++"
5
+ #include <float.h>
6
+ #if defined(HAVE_IEEE754_H) || __has_include(<ieee754.h>)
7
+ #include <ieee754.h>
8
+ #endif
9
+ #if defined(__APPLE__) || defined(__MACH__)
10
+ #include <mach/mach_time.h>
11
+ #endif /* defined(__APPLE__) || defined(__MACH__) */
12
+
13
+ std::string format(const char *fmt, ...) {
14
+ va_list ap, ones;
15
+ va_start(ap, fmt);
16
+ va_copy(ones, ap);
17
+ #ifdef _MSC_VER
18
+ int needed = _vscprintf(fmt, ap);
19
+ #else
20
+ int needed = vsnprintf(nullptr, 0, fmt, ap);
21
+ #endif
22
+ assert(needed >= 0);
23
+ va_end(ap);
24
+ std::string result;
25
+ result.reserve((size_t)needed + 1);
26
+ result.resize((size_t)needed, '\0');
27
+ MDBX_MAYBE_UNUSED int actual = vsnprintf((char *)result.data(), result.capacity(), fmt, ones);
28
+ assert(actual == needed);
29
+ (void)actual;
30
+ va_end(ones);
31
+ return result;
32
+ }
33
+
34
+ std::string data2hex(const void *ptr, size_t bytes, simple_checksum &checksum) {
35
+ std::string result;
36
+ if (bytes > 0) {
37
+ const uint8_t *data = (const uint8_t *)ptr;
38
+ checksum.push(data, bytes);
39
+ result.reserve(bytes * 2);
40
+ const uint8_t *const end = data + bytes;
41
+ do {
42
+ char h = *data >> 4;
43
+ char l = *data & 15;
44
+ result.push_back((l < 10) ? l + '0' : l - 10 + 'a');
45
+ result.push_back((h < 10) ? h + '0' : h - 10 + 'a');
46
+ } while (++data < end);
47
+ }
48
+ assert(result.size() == bytes * 2);
49
+ return result;
50
+ }
51
+
52
+ bool hex2data(const char *hex_begin, const char *hex_end, void *ptr, size_t bytes, simple_checksum &checksum) {
53
+ if (bytes * 2 != (size_t)(hex_end - hex_begin))
54
+ return false;
55
+
56
+ uint8_t *data = (uint8_t *)ptr;
57
+ for (const char *hex = hex_begin; hex != hex_end; hex += 2, ++data) {
58
+ unsigned l = hex[0], h = hex[1];
59
+
60
+ if (l >= '0' && l <= '9')
61
+ l = l - '0';
62
+ else if (l >= 'A' && l <= 'F')
63
+ l = l - 'A' + 10;
64
+ else if (l >= 'a' && l <= 'f')
65
+ l = l - 'a' + 10;
66
+ else
67
+ return false;
68
+
69
+ if (h >= '0' && h <= '9')
70
+ h = h - '0';
71
+ else if (h >= 'A' && h <= 'F')
72
+ h = h - 'A' + 10;
73
+ else if (h >= 'a' && h <= 'f')
74
+ h = h - 'a' + 10;
75
+ else
76
+ return false;
77
+
78
+ uint32_t c = l + (h << 4);
79
+ checksum.push(c);
80
+ *data = (uint8_t)c;
81
+ }
82
+ return true;
83
+ }
84
+
85
+ bool is_samedata(const MDBX_val *a, const MDBX_val *b) {
86
+ return a->iov_len == b->iov_len && memcmp(a->iov_base, b->iov_base, a->iov_len) == 0;
87
+ }
88
+
89
+ //-----------------------------------------------------------------------------
90
+
91
+ uint64_t prng64_white(uint64_t &state) {
92
+ state = prng64_map2_careless(state);
93
+ return bleach64(state);
94
+ }
95
+
96
+ uint32_t prng32_fast(uint64_t &state) { return uint32_t(prng64_careless(state) >> 32); }
97
+
98
+ uint32_t prng32_white(uint64_t &state) { return bleach32(uint32_t(prng64_careless(state) >> 32)); }
99
+
100
+ void prng_fill(uint64_t &state, void *ptr, size_t bytes) {
101
+ uint32_t u32 = prng32_fast(state);
102
+
103
+ while (bytes >= 4) {
104
+ memcpy(ptr, &u32, 4);
105
+ ptr = (uint32_t *)ptr + 1;
106
+ bytes -= 4;
107
+ u32 = prng32_fast(state);
108
+ }
109
+
110
+ switch (bytes & 3) {
111
+ case 3:
112
+ memcpy(ptr, &u32, 3);
113
+ break;
114
+ case 2:
115
+ memcpy(ptr, &u32, 2);
116
+ break;
117
+ case 1:
118
+ memcpy(ptr, &u32, 1);
119
+ break;
120
+ case 0:
121
+ break;
122
+ }
123
+ }
124
+
125
+ /* __thread */ uint64_t prng_state;
126
+
127
+ void prng_seed(uint64_t seed) { prng_state = bleach64(seed); }
128
+
129
+ uint32_t prng32(void) { return prng32_white(prng_state); }
130
+
131
+ uint64_t prng64(void) { return prng64_white(prng_state); }
132
+
133
+ void prng_fill(void *ptr, size_t bytes) { prng_fill(prng_state, ptr, bytes); }
134
+
135
+ double double_from_lower(uint64_t salt) {
136
+ #ifdef IEEE754_DOUBLE_BIAS
137
+ ieee754_double r;
138
+ r.ieee.negative = 0;
139
+ r.ieee.exponent = IEEE754_DOUBLE_BIAS;
140
+ r.ieee.mantissa0 = (unsigned)(salt >> 32);
141
+ r.ieee.mantissa1 = (unsigned)salt;
142
+ return r.d;
143
+ #else
144
+ const uint64_t top = (UINT64_C(1) << DBL_MANT_DIG) - 1;
145
+ const double scale = 1.0 / (double)top;
146
+ return (salt & top) * scale;
147
+ #endif
148
+ }
149
+
150
+ double double_from_upper(uint64_t salt) {
151
+ #ifdef IEEE754_DOUBLE_BIAS
152
+ ieee754_double r;
153
+ r.ieee.negative = 0;
154
+ r.ieee.exponent = IEEE754_DOUBLE_BIAS;
155
+ salt >>= 64 - DBL_MANT_DIG;
156
+ r.ieee.mantissa0 = unsigned(salt >> 32);
157
+ r.ieee.mantissa1 = unsigned(salt);
158
+ return r.d;
159
+ #else
160
+ const uint64_t top = (UINT64_C(1) << DBL_MANT_DIG) - 1;
161
+ const double scale = 1.0 / (double)top;
162
+ return (salt >> (64 - DBL_MANT_DIG)) * scale;
163
+ #endif
164
+ }
165
+
166
+ bool flipcoin() { return prng32() & 1; }
167
+ bool flipcoin_x2() { return (prng32() & 3) == 0; }
168
+ bool flipcoin_x3() { return (prng32() & 7) == 0; }
169
+ bool flipcoin_x4() { return (prng32() & 15) == 0; }
170
+ bool flipcoin_n(unsigned n) { return (prng64() & ((UINT64_C(1) << n) - 1)) == 0; }
171
+
172
+ bool jitter(unsigned probability_percent) {
173
+ const uint32_t top = UINT32_MAX - UINT32_MAX % 100;
174
+ uint32_t dice, edge = (top) / 100 * probability_percent;
175
+ do
176
+ dice = prng32();
177
+ while (dice >= top);
178
+ return dice < edge;
179
+ }
180
+
181
+ void jitter_delay(bool extra) {
182
+ unsigned dice = prng32() & 3;
183
+ if (dice == 0) {
184
+ log_trace("== jitter.no-delay");
185
+ } else {
186
+ log_trace(">> jitter.delay: dice %u", dice);
187
+ do {
188
+ cpu_relax();
189
+ memory_barrier();
190
+ cpu_relax();
191
+ if (dice > 1) {
192
+ osal_yield();
193
+ cpu_relax();
194
+ if (dice > 2) {
195
+ size_t us = prng32() & (extra ? 0xffff /* 656 ms */ : 0x3ff /* 1 ms */);
196
+ log_trace("== jitter.delay: %0.6f", us / 1000000.0);
197
+ osal_udelay(us);
198
+ }
199
+ }
200
+ } while (flipcoin());
201
+ log_trace("<< jitter.delay: dice %u", dice);
202
+ }
203
+ }
@@ -0,0 +1,326 @@
1
+ /// \author Леонид Юрьев aka Leonid Yuriev <leo@yuriev.ru> \date 2015-2025
2
+ /// \copyright SPDX-License-Identifier: Apache-2.0
3
+
4
+ #pragma once
5
+ #include "base.h++"
6
+
7
+ #if !defined(__BYTE_ORDER__) || !defined(__ORDER_LITTLE_ENDIAN__) || !defined(__ORDER_BIG_ENDIAN__)
8
+ #error __BYTE_ORDER__ should be defined.
9
+ #endif
10
+
11
+ #if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ && __BYTE_ORDER__ != __ORDER_BIG_ENDIAN__
12
+ #error Unsupported byte order.
13
+ #endif
14
+
15
+ #if __GNUC_PREREQ(4, 4) || defined(__clang__)
16
+ #ifndef bswap64
17
+ #define bswap64(v) __builtin_bswap64(v)
18
+ #endif
19
+ #ifndef bswap32
20
+ #define bswap32(v) __builtin_bswap32(v)
21
+ #endif
22
+ #if (__GNUC_PREREQ(4, 8) || __has_builtin(__builtin_bswap16)) && !defined(bswap16)
23
+ #define bswap16(v) __builtin_bswap16(v)
24
+ #endif
25
+
26
+ #elif defined(_MSC_VER)
27
+
28
+ #if _MSC_FULL_VER < 190024215
29
+ #pragma message("It is recommended to use Visual Studio 2015 (MSC 19.0) or newer.")
30
+ #endif
31
+
32
+ #define bswap64(v) _byteswap_uint64(v)
33
+ #define bswap32(v) _byteswap_ulong(v)
34
+ #define bswap16(v) _byteswap_ushort(v)
35
+ #define rot64(v, s) _rotr64(v, s)
36
+ #define rot32(v, s) _rotr(v, s)
37
+
38
+ #if defined(_M_X64) || defined(_M_IA64)
39
+ #pragma intrinsic(_umul128)
40
+ #define mul_64x64_128(a, b, ph) _umul128(a, b, ph)
41
+ #pragma intrinsic(__umulh)
42
+ #define mul_64x64_high(a, b) __umulh(a, b)
43
+ #endif
44
+
45
+ #if defined(_M_IX86)
46
+ #pragma intrinsic(__emulu)
47
+ #define mul_32x32_64(a, b) __emulu(a, b)
48
+ #elif defined(_M_ARM)
49
+ #define mul_32x32_64(a, b) _arm_umull(a, b)
50
+ #endif
51
+
52
+ #endif /* compiler */
53
+
54
+ #ifndef bswap64
55
+ #ifdef __bswap_64
56
+ #define bswap64(v) __bswap_64(v)
57
+ #else
58
+ static inline uint64_t bswap64(uint64_t v) {
59
+ return v << 56 | v >> 56 | ((v << 40) & UINT64_C(0x00ff000000000000)) | ((v << 24) & UINT64_C(0x0000ff0000000000)) |
60
+ ((v << 8) & UINT64_C(0x000000ff00000000)) | ((v >> 8) & UINT64_C(0x00000000ff0000000)) |
61
+ ((v >> 24) & UINT64_C(0x0000000000ff0000)) | ((v >> 40) & UINT64_C(0x000000000000ff00));
62
+ }
63
+ #endif
64
+ #endif /* bswap64 */
65
+
66
+ #ifndef bswap32
67
+ #ifdef __bswap_32
68
+ #define bswap32(v) __bswap_32(v)
69
+ #else
70
+ static inline uint32_t bswap32(uint32_t v) {
71
+ return v << 24 | v >> 24 | ((v << 8) & UINT32_C(0x00ff0000)) | ((v >> 8) & UINT32_C(0x0000ff00));
72
+ }
73
+ #endif
74
+ #endif /* bswap32 */
75
+
76
+ #ifndef bswap16
77
+ #ifdef __bswap_16
78
+ #define bswap16(v) __bswap_16(v)
79
+ #else
80
+ static inline uint16_t bswap16(uint16_t v) { return v << 8 | v >> 8; }
81
+ #endif
82
+ #endif /* bswap16 */
83
+
84
+ #define is_byteorder_le() (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
85
+ #define is_byteorder_be() (__BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
86
+
87
+ #ifndef htole16
88
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
89
+ #define htobe16(v) bswap16(v)
90
+ #define htole16(v) (v)
91
+ #define be16toh(v) bswap16(v)
92
+ #define le16toh(v) (v)
93
+ #else
94
+ #define htobe16(v) (v)
95
+ #define htole16(v) bswap16(v)
96
+ #define be16toh(v) (v)
97
+ #define le16toh(v) bswap16(v)
98
+ #endif
99
+ #endif /* htole16 */
100
+
101
+ #ifndef htole32
102
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
103
+ #define htobe32(v) bswap32(v)
104
+ #define htole32(v) (v)
105
+ #define be32toh(v) bswap32(v)
106
+ #define le32toh(v) (v)
107
+ #else
108
+ #define htobe32(v) (v)
109
+ #define htole32(v) bswap32(v)
110
+ #define be32toh(v) (v)
111
+ #define le32toh(v) bswap32(v)
112
+ #endif
113
+ #endif /* htole32 */
114
+
115
+ #ifndef htole64
116
+ #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
117
+ #define htobe64(v) bswap64(v)
118
+ #define htole64(v) (v)
119
+ #define be64toh(v) bswap64(v)
120
+ #define le64toh(v) (v)
121
+ #else
122
+ #define htobe64(v) (v)
123
+ #define htole64(v) bswap_64(v)
124
+ #define be64toh(v) (v)
125
+ #define le64toh(v) bswap_64(v)
126
+ #endif
127
+ #endif /* htole64 */
128
+
129
+ namespace unaligned {
130
+
131
+ template <typename T> static inline T load(const void *ptr) {
132
+ if (MDBX_UNALIGNED_OK >= sizeof(T))
133
+ return *(const T *)ptr;
134
+ else {
135
+ #if defined(__unaligned) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_X64) || defined(_M_IA64)
136
+ return *(const T __unaligned *)ptr;
137
+ #else
138
+ T local;
139
+ memcpy(&local, (const T *)ptr, sizeof(T));
140
+ return local;
141
+ #endif /* _MSC_VER || __unaligned */
142
+ }
143
+ }
144
+
145
+ template <typename T> static inline void store(void *ptr, const T &value) {
146
+ if (MDBX_UNALIGNED_OK >= sizeof(T))
147
+ *(T *)ptr = value;
148
+ else {
149
+ #if defined(__unaligned) || defined(_M_ARM) || defined(_M_ARM64) || defined(_M_X64) || defined(_M_IA64)
150
+ *((T __unaligned *)ptr) = value;
151
+ #else
152
+ memcpy(ptr, &value, sizeof(T));
153
+ #endif /* _MSC_VER || __unaligned */
154
+ }
155
+ }
156
+
157
+ } /* namespace unaligned */
158
+
159
+ //-----------------------------------------------------------------------------
160
+
161
+ #ifndef rot64
162
+ static inline uint64_t rot64(uint64_t v, unsigned s) { return (v >> s) | (v << (64 - s)); }
163
+ #endif /* rot64 */
164
+
165
+ static inline bool is_power2(size_t x) { return (x & (x - 1)) == 0; }
166
+
167
+ #undef roundup2
168
+ static inline size_t roundup2(size_t value, size_t granularity) {
169
+ assert(is_power2(granularity));
170
+ return (value + granularity - 1) & ~(granularity - 1);
171
+ }
172
+
173
+ //-----------------------------------------------------------------------------
174
+
175
+ static inline void memory_barrier(void) {
176
+ #if __has_extension(c_atomic) || __has_extension(cxx_atomic)
177
+ __c11_atomic_thread_fence(__ATOMIC_SEQ_CST);
178
+ #elif defined(__ATOMIC_SEQ_CST)
179
+ __atomic_thread_fence(__ATOMIC_SEQ_CST);
180
+ #elif defined(__clang__) || defined(__GNUC__)
181
+ __sync_synchronize();
182
+ #elif defined(_MSC_VER)
183
+ MemoryBarrier();
184
+ #elif defined(__INTEL_COMPILER) /* LY: Intel Compiler may mimic GCC and MSC */
185
+ #if defined(__ia64__) || defined(__ia64) || defined(_M_IA64)
186
+ __mf();
187
+ #elif defined(__ia32__)
188
+ _mm_mfence();
189
+ #else
190
+ #error "Unknown target for Intel Compiler, please report to us."
191
+ #endif
192
+ #elif defined(__SUNPRO_C) || defined(__sun) || defined(sun)
193
+ __machine_rw_barrier();
194
+ #elif (defined(_HPUX_SOURCE) || defined(__hpux) || defined(__HP_aCC)) && (defined(HP_IA64) || defined(__ia64))
195
+ _Asm_mf();
196
+ #elif defined(_AIX) || defined(__ppc__) || defined(__powerpc__) || defined(__ppc64__) || defined(__powerpc64__)
197
+ __lwsync();
198
+ #else
199
+ #error "Could not guess the kind of compiler, please report to us."
200
+ #endif
201
+ }
202
+
203
+ static inline void cpu_relax() {
204
+ #if defined(__ia32__)
205
+ _mm_pause();
206
+ #elif defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS) || defined(YieldProcessor)
207
+ YieldProcessor();
208
+ #else
209
+ /* nope */
210
+ #endif
211
+ }
212
+
213
+ //-----------------------------------------------------------------------------
214
+
215
+ struct simple_checksum {
216
+ uint64_t value{0};
217
+
218
+ simple_checksum() = default;
219
+
220
+ void push(const uint32_t &data) {
221
+ value += data * UINT64_C(9386433910765580089) + 1;
222
+ value ^= value >> 41;
223
+ value *= UINT64_C(0xBD9CACC22C6E9571);
224
+ }
225
+
226
+ void push(const uint64_t &data) {
227
+ push((uint32_t)data);
228
+ push((uint32_t)(data >> 32));
229
+ }
230
+
231
+ void push(const bool data) { push(data ? UINT32_C(0x780E) : UINT32_C(0xFA18E)); }
232
+
233
+ void push(const void *ptr, size_t bytes) {
234
+ const uint8_t *data = (const uint8_t *)ptr;
235
+ for (size_t i = 0; i < bytes; ++i)
236
+ push((uint32_t)data[i]);
237
+ }
238
+
239
+ void push(const double &data) { push(&data, sizeof(double)); }
240
+ void push(const char *cstr) { push(cstr, strlen(cstr)); }
241
+ void push(const std::string &str) { push(str.data(), str.size()); }
242
+
243
+ void push(unsigned salt, const MDBX_val &val) {
244
+ push(unsigned(val.iov_len));
245
+ push(salt);
246
+ push(val.iov_base, val.iov_len);
247
+ }
248
+
249
+ #if defined(_WIN32) || defined(_WIN64) || defined(_WINDOWS)
250
+ void push(const HANDLE &handle) { push(&handle, sizeof(handle)); }
251
+ #endif /* _WINDOWS */
252
+ };
253
+
254
+ std::string data2hex(const void *ptr, size_t bytes, simple_checksum &checksum);
255
+ bool hex2data(const char *hex_begin, const char *hex_end, void *ptr, size_t bytes, simple_checksum &checksum);
256
+ bool is_samedata(const MDBX_val *a, const MDBX_val *b);
257
+ inline bool is_samedata(const MDBX_val &a, const MDBX_val &b) { return is_samedata(&a, &b); }
258
+ std::string format(const char *fmt, ...);
259
+
260
+ static inline uint64_t bleach64(uint64_t x) {
261
+ // NASAM from Tommy Ettinger,
262
+ // https://www.blogger.com/profile/04953541827437796598
263
+ // http://mostlymangling.blogspot.com/2020/01/nasam-not-another-strange-acronym-mixer.html
264
+ x ^= rot64(x, 25) ^ rot64(x, 47);
265
+ x *= UINT64_C(0x9E6C63D0676A9A99);
266
+ x ^= x >> 23 ^ x >> 51;
267
+ x *= UINT64_C(0x9E6D62D06F6A9A9B);
268
+ x ^= x >> 23 ^ x >> 51;
269
+ return x;
270
+ }
271
+
272
+ static inline uint32_t bleach32(uint32_t x) {
273
+ // https://github.com/skeeto/hash-prospector
274
+ // exact bias: 0.10760229515479501
275
+ x ^= x >> 16;
276
+ x *= UINT32_C(0x21f0aaad);
277
+ x ^= 0x3027C563 ^ (x >> 15);
278
+ x *= UINT32_C(0x0d35a2d97);
279
+ x ^= x >> 15;
280
+ return x;
281
+ }
282
+
283
+ static inline uint64_t prng64_map1_careless(uint64_t state) { return state * UINT64_C(6364136223846793005) + 1; }
284
+
285
+ static inline uint64_t prng64_map2_careless(uint64_t state) {
286
+ return (state + UINT64_C(1442695040888963407)) * UINT64_C(6364136223846793005);
287
+ }
288
+
289
+ static inline uint64_t prng64_map1_white(uint64_t state) { return bleach64(prng64_map1_careless(state)); }
290
+
291
+ static inline uint64_t prng64_map2_white(uint64_t state) { return bleach64(prng64_map2_careless(state)); }
292
+
293
+ static inline uint64_t prng64_careless(uint64_t &state) {
294
+ state = prng64_map1_careless(state);
295
+ return state;
296
+ }
297
+
298
+ static inline double u64_to_double1(uint64_t v) {
299
+ union {
300
+ uint64_t u64;
301
+ double d;
302
+ } casting;
303
+
304
+ casting.u64 = UINT64_C(0x3ff) << 52 | (v >> 12);
305
+ assert(casting.d >= 1.0 && casting.d < 2.0);
306
+ return casting.d - 1.0;
307
+ }
308
+
309
+ uint64_t prng64_white(uint64_t &state);
310
+ uint32_t prng32_white(uint64_t &state);
311
+ uint32_t prng32_fast(uint64_t &state);
312
+ void prng_fill(uint64_t &state, void *ptr, size_t bytes);
313
+
314
+ extern uint64_t prng_state;
315
+ void prng_seed(uint64_t seed);
316
+ uint32_t prng32(void);
317
+ uint64_t prng64(void);
318
+ void prng_fill(void *ptr, size_t bytes);
319
+
320
+ bool flipcoin();
321
+ bool flipcoin_x2();
322
+ bool flipcoin_x3();
323
+ bool flipcoin_x4();
324
+ bool flipcoin_n(unsigned n);
325
+ bool jitter(unsigned probability_percent);
326
+ void jitter_delay(bool extra = false);