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.
- package/.github/workflows/ci.yml +32 -0
- package/.github/workflows/publish.yml +27 -0
- package/.gitmodules +3 -0
- package/CMakeLists.txt +53 -0
- package/LICENSE +201 -0
- package/README.md +639 -0
- package/build.js +11 -0
- package/deps/libmdbx/.clang-format +3 -0
- package/deps/libmdbx/.cmake-format.yaml +3 -0
- package/deps/libmdbx/.le.ini +40 -0
- package/deps/libmdbx/CMakeLists.txt +1269 -0
- package/deps/libmdbx/COPYRIGHT +159 -0
- package/deps/libmdbx/ChangeLog.md +2786 -0
- package/deps/libmdbx/GNUmakefile +950 -0
- package/deps/libmdbx/LICENSE +177 -0
- package/deps/libmdbx/Makefile +16 -0
- package/deps/libmdbx/NOTICE +39 -0
- package/deps/libmdbx/README.md +863 -0
- package/deps/libmdbx/TODO.md +43 -0
- package/deps/libmdbx/cmake/compiler.cmake +1221 -0
- package/deps/libmdbx/cmake/profile.cmake +58 -0
- package/deps/libmdbx/cmake/utils.cmake +524 -0
- package/deps/libmdbx/conanfile.py +323 -0
- package/deps/libmdbx/docs/Doxyfile.in +2734 -0
- package/deps/libmdbx/docs/_preface.md +47 -0
- package/deps/libmdbx/docs/_restrictions.md +248 -0
- package/deps/libmdbx/docs/_starting.md +245 -0
- package/deps/libmdbx/docs/_toc.md +34 -0
- package/deps/libmdbx/docs/header.html +96 -0
- package/deps/libmdbx/example/CMakeLists.txt +6 -0
- package/deps/libmdbx/example/README.md +1 -0
- package/deps/libmdbx/example/example-mdbx.c +154 -0
- package/deps/libmdbx/example/sample-bdb.txt +77 -0
- package/deps/libmdbx/mdbx.h +6655 -0
- package/deps/libmdbx/mdbx.h++ +6428 -0
- package/deps/libmdbx/packages/buildroot/0001-package-libmdbx-new-package-library-database.patch +173 -0
- package/deps/libmdbx/src/alloy.c +54 -0
- package/deps/libmdbx/src/api-cold.c +543 -0
- package/deps/libmdbx/src/api-copy.c +912 -0
- package/deps/libmdbx/src/api-cursor.c +754 -0
- package/deps/libmdbx/src/api-dbi.c +315 -0
- package/deps/libmdbx/src/api-env.c +1434 -0
- package/deps/libmdbx/src/api-extra.c +165 -0
- package/deps/libmdbx/src/api-key-transform.c +197 -0
- package/deps/libmdbx/src/api-misc.c +286 -0
- package/deps/libmdbx/src/api-opts.c +575 -0
- package/deps/libmdbx/src/api-range-estimate.c +365 -0
- package/deps/libmdbx/src/api-txn-data.c +454 -0
- package/deps/libmdbx/src/api-txn.c +921 -0
- package/deps/libmdbx/src/atomics-ops.h +364 -0
- package/deps/libmdbx/src/atomics-types.h +97 -0
- package/deps/libmdbx/src/audit.c +109 -0
- package/deps/libmdbx/src/bits.md +34 -0
- package/deps/libmdbx/src/chk.c +1796 -0
- package/deps/libmdbx/src/cogs.c +309 -0
- package/deps/libmdbx/src/cogs.h +506 -0
- package/deps/libmdbx/src/coherency.c +170 -0
- package/deps/libmdbx/src/config.h.in +88 -0
- package/deps/libmdbx/src/cursor.c +2396 -0
- package/deps/libmdbx/src/cursor.h +391 -0
- package/deps/libmdbx/src/dbi.c +717 -0
- package/deps/libmdbx/src/dbi.h +142 -0
- package/deps/libmdbx/src/debug_begin.h +36 -0
- package/deps/libmdbx/src/debug_end.h +15 -0
- package/deps/libmdbx/src/dpl.c +486 -0
- package/deps/libmdbx/src/dpl.h +134 -0
- package/deps/libmdbx/src/dxb.c +1335 -0
- package/deps/libmdbx/src/env.c +607 -0
- package/deps/libmdbx/src/essentials.h +125 -0
- package/deps/libmdbx/src/gc-get.c +1345 -0
- package/deps/libmdbx/src/gc-put.c +970 -0
- package/deps/libmdbx/src/gc.h +40 -0
- package/deps/libmdbx/src/global.c +474 -0
- package/deps/libmdbx/src/internals.h +585 -0
- package/deps/libmdbx/src/layout-dxb.h +288 -0
- package/deps/libmdbx/src/layout-lck.h +289 -0
- package/deps/libmdbx/src/lck-posix.c +859 -0
- package/deps/libmdbx/src/lck-windows.c +607 -0
- package/deps/libmdbx/src/lck.c +174 -0
- package/deps/libmdbx/src/lck.h +110 -0
- package/deps/libmdbx/src/logging_and_debug.c +250 -0
- package/deps/libmdbx/src/logging_and_debug.h +159 -0
- package/deps/libmdbx/src/man1/mdbx_chk.1 +106 -0
- package/deps/libmdbx/src/man1/mdbx_copy.1 +95 -0
- package/deps/libmdbx/src/man1/mdbx_drop.1 +48 -0
- package/deps/libmdbx/src/man1/mdbx_dump.1 +101 -0
- package/deps/libmdbx/src/man1/mdbx_load.1 +105 -0
- package/deps/libmdbx/src/man1/mdbx_stat.1 +86 -0
- package/deps/libmdbx/src/mdbx.c++ +1837 -0
- package/deps/libmdbx/src/meta.c +656 -0
- package/deps/libmdbx/src/meta.h +168 -0
- package/deps/libmdbx/src/mvcc-readers.c +414 -0
- package/deps/libmdbx/src/node.c +365 -0
- package/deps/libmdbx/src/node.h +102 -0
- package/deps/libmdbx/src/ntdll.def +1246 -0
- package/deps/libmdbx/src/options.h +534 -0
- package/deps/libmdbx/src/osal.c +3485 -0
- package/deps/libmdbx/src/osal.h +587 -0
- package/deps/libmdbx/src/page-get.c +483 -0
- package/deps/libmdbx/src/page-iov.c +185 -0
- package/deps/libmdbx/src/page-iov.h +34 -0
- package/deps/libmdbx/src/page-ops.c +744 -0
- package/deps/libmdbx/src/page-ops.h +142 -0
- package/deps/libmdbx/src/pnl.c +236 -0
- package/deps/libmdbx/src/pnl.h +146 -0
- package/deps/libmdbx/src/preface.h +990 -0
- package/deps/libmdbx/src/proto.h +105 -0
- package/deps/libmdbx/src/refund.c +212 -0
- package/deps/libmdbx/src/sort.h +484 -0
- package/deps/libmdbx/src/spill.c +431 -0
- package/deps/libmdbx/src/spill.h +74 -0
- package/deps/libmdbx/src/table.c +107 -0
- package/deps/libmdbx/src/tls.c +551 -0
- package/deps/libmdbx/src/tls.h +43 -0
- package/deps/libmdbx/src/tools/chk.c +673 -0
- package/deps/libmdbx/src/tools/copy.c +166 -0
- package/deps/libmdbx/src/tools/drop.c +199 -0
- package/deps/libmdbx/src/tools/dump.c +515 -0
- package/deps/libmdbx/src/tools/load.c +831 -0
- package/deps/libmdbx/src/tools/stat.c +516 -0
- package/deps/libmdbx/src/tools/wingetopt.c +87 -0
- package/deps/libmdbx/src/tools/wingetopt.h +30 -0
- package/deps/libmdbx/src/tree-ops.c +1554 -0
- package/deps/libmdbx/src/tree-search.c +140 -0
- package/deps/libmdbx/src/txl.c +99 -0
- package/deps/libmdbx/src/txl.h +26 -0
- package/deps/libmdbx/src/txn.c +1083 -0
- package/deps/libmdbx/src/unaligned.h +205 -0
- package/deps/libmdbx/src/utils.c +32 -0
- package/deps/libmdbx/src/utils.h +76 -0
- package/deps/libmdbx/src/version.c.in +44 -0
- package/deps/libmdbx/src/walk.c +290 -0
- package/deps/libmdbx/src/walk.h +20 -0
- package/deps/libmdbx/src/windows-import.c +152 -0
- package/deps/libmdbx/src/windows-import.h +128 -0
- package/deps/libmdbx/test/CMakeLists.txt +317 -0
- package/deps/libmdbx/test/append.c++ +237 -0
- package/deps/libmdbx/test/base.h++ +92 -0
- package/deps/libmdbx/test/battery-tmux.sh +64 -0
- package/deps/libmdbx/test/cases.c++ +118 -0
- package/deps/libmdbx/test/chrono.c++ +134 -0
- package/deps/libmdbx/test/chrono.h++ +85 -0
- package/deps/libmdbx/test/config.c++ +643 -0
- package/deps/libmdbx/test/config.h++ +334 -0
- package/deps/libmdbx/test/copy.c++ +62 -0
- package/deps/libmdbx/test/dead.c++ +39 -0
- package/deps/libmdbx/test/dump-load.sh +40 -0
- package/deps/libmdbx/test/extra/crunched_delete.c++ +409 -0
- package/deps/libmdbx/test/extra/cursor_closing.c++ +410 -0
- package/deps/libmdbx/test/extra/dbi.c++ +229 -0
- package/deps/libmdbx/test/extra/doubtless_positioning.c++ +253 -0
- package/deps/libmdbx/test/extra/dupfix_addodd.c +94 -0
- package/deps/libmdbx/test/extra/dupfix_multiple.c++ +311 -0
- package/deps/libmdbx/test/extra/early_close_dbi.c++ +137 -0
- package/deps/libmdbx/test/extra/hex_base64_base58.c++ +118 -0
- package/deps/libmdbx/test/extra/maindb_ordinal.c++ +61 -0
- package/deps/libmdbx/test/extra/open.c++ +96 -0
- package/deps/libmdbx/test/extra/pcrf/README.md +2 -0
- package/deps/libmdbx/test/extra/pcrf/pcrf_test.c +380 -0
- package/deps/libmdbx/test/extra/probe.c++ +10 -0
- package/deps/libmdbx/test/extra/txn.c++ +407 -0
- package/deps/libmdbx/test/extra/upsert_alldups.c +193 -0
- package/deps/libmdbx/test/fork.c++ +263 -0
- package/deps/libmdbx/test/hill.c++ +447 -0
- package/deps/libmdbx/test/jitter.c++ +197 -0
- package/deps/libmdbx/test/keygen.c++ +393 -0
- package/deps/libmdbx/test/keygen.h++ +130 -0
- package/deps/libmdbx/test/log.c++ +358 -0
- package/deps/libmdbx/test/log.h++ +91 -0
- package/deps/libmdbx/test/main.c++ +706 -0
- package/deps/libmdbx/test/nested.c++ +318 -0
- package/deps/libmdbx/test/osal-unix.c++ +647 -0
- package/deps/libmdbx/test/osal-windows.c++ +440 -0
- package/deps/libmdbx/test/osal.h++ +41 -0
- package/deps/libmdbx/test/stochastic.sh +690 -0
- package/deps/libmdbx/test/stub/LICENSE +24 -0
- package/deps/libmdbx/test/stub/README.md +8 -0
- package/deps/libmdbx/test/stub/pthread_barrier.c +104 -0
- package/deps/libmdbx/test/stub/pthread_barrier.h +77 -0
- package/deps/libmdbx/test/test.c++ +1551 -0
- package/deps/libmdbx/test/test.h++ +298 -0
- package/deps/libmdbx/test/tmux.conf +3 -0
- package/deps/libmdbx/test/try.c++ +30 -0
- package/deps/libmdbx/test/ttl.c++ +240 -0
- package/deps/libmdbx/test/utils.c++ +203 -0
- package/deps/libmdbx/test/utils.h++ +326 -0
- package/deps/libmdbx/test/valgrind_suppress.txt +536 -0
- package/lib/mdbx_evn_async.js +211 -0
- package/lib/mdbx_worker.js +195 -0
- package/lib/nativemou.js +6 -0
- package/package.json +38 -0
- package/src/async/envmou_close.cpp +34 -0
- package/src/async/envmou_close.hpp +32 -0
- package/src/async/envmou_copy_to.cpp +29 -0
- package/src/async/envmou_copy_to.hpp +38 -0
- package/src/async/envmou_keys.cpp +201 -0
- package/src/async/envmou_keys.hpp +50 -0
- package/src/async/envmou_open.cpp +38 -0
- package/src/async/envmou_open.hpp +33 -0
- package/src/async/envmou_query.cpp +167 -0
- package/src/async/envmou_query.hpp +53 -0
- package/src/dbimou.cpp +522 -0
- package/src/dbimou.hpp +82 -0
- package/src/env_arg0.hpp +24 -0
- package/src/envmou.cpp +445 -0
- package/src/envmou.hpp +116 -0
- package/src/modulemou.cpp +113 -0
- package/src/querymou.cpp +177 -0
- package/src/querymou.hpp +93 -0
- package/src/txnmou.cpp +254 -0
- package/src/txnmou.hpp +122 -0
- package/src/typemou.hpp +239 -0
- package/src/valuemou.hpp +194 -0
- package/test/async.js +67 -0
- package/test/e3.js +38 -0
- package/test/e4.js +89 -0
- package/test/e5.js +162 -0
- package/test/test-batch-ops.js +243 -0
- package/test/test-cursor-mode.js +84 -0
- 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);
|