mirror of
https://github.com/isar/libmdbx.git
synced 2025-01-02 00:34:13 +08:00
mdbx-test: fix/refine keygen.
Change-Id: Ib6d8bb5e438314bf09c1c9466456d8c57623711b
This commit is contained in:
parent
2b305d33a3
commit
99934bc845
@ -134,6 +134,8 @@ struct keygen_params_pod {
|
||||
* Иначе говоря, нет смысла в со-координации генерации паттернов для
|
||||
* ключей и значений. Более того, генерацию значений всегда необходимо
|
||||
* рассматривать в контексте связки с одним значением ключа.
|
||||
* - Тем не менее, во всех случаях достаточно важным является равномерная
|
||||
* всех возможных сочетаний длин ключей и данных.
|
||||
*
|
||||
* width:
|
||||
* Большинство тестов предполагают создание или итерирование некоторого
|
||||
@ -169,7 +171,7 @@ struct keygen_params_pod {
|
||||
* псевдо-случайные значений ключей без псевдо-случайности в значениях.
|
||||
*
|
||||
* Такое ограничение соответствуют внутренней алгоритмике libmdbx. Проще
|
||||
* говоря мы можем проверить движок псевдо-случайной последовательностью
|
||||
* говоря, мы можем проверить движок псевдо-случайной последовательностью
|
||||
* ключей на таблицах без дубликатов (без multi-value), а затем проверить
|
||||
* корректность работу псевдо-случайной последовательностью значений на
|
||||
* таблицах с дубликатами (с multi-value), опционально добавляя
|
||||
|
@ -30,7 +30,7 @@ serial_t injective(const serial_t serial,
|
||||
/* LY: All these "magic" prime numbers were found
|
||||
* and verified with a bit of brute force. */
|
||||
|
||||
static const uint64_t m[64 - serial_minwith] = {
|
||||
static const uint64_t m[64 - serial_minwith + 1] = {
|
||||
/* 8 - 24 */
|
||||
113, 157, 397, 653, 1753, 5641, 9697, 23873, 25693, 80833, 105953, 316937,
|
||||
309277, 834497, 1499933, 4373441, 10184137,
|
||||
@ -43,26 +43,31 @@ serial_t injective(const serial_t serial,
|
||||
2420886491930041, 3601632139991929, 11984491914483833, 21805846439714153,
|
||||
23171543400565993, 53353226456762893, 155627817337932409,
|
||||
227827205384840249, 816509268558278821, 576933057762605689,
|
||||
2623957345935638441, 5048241705479929949, 4634245581946485653};
|
||||
static const uint8_t s[64 - serial_minwith] = {
|
||||
2623957345935638441, 5048241705479929949, 4634245581946485653,
|
||||
4613509448041658233, 4952535426879925961};
|
||||
static const uint8_t s[64 - serial_minwith + 1] = {
|
||||
/* 8 - 24 */
|
||||
2, 3, 4, 4, 2, 4, 3, 3, 7, 3, 3, 4, 8, 3, 10, 3, 11,
|
||||
/* 25 - 64 */
|
||||
11, 9, 9, 9, 11, 10, 5, 14, 11, 16, 14, 12, 13, 16, 19, 10, 10, 21, 7, 20,
|
||||
10, 14, 22, 19, 3, 21, 18, 19, 26, 24, 2, 21, 25, 29, 24, 10, 11, 14};
|
||||
10, 14, 22, 19, 3, 21, 18, 19, 26, 24, 2, 21, 25, 29, 24, 10, 11, 14, 20,
|
||||
19};
|
||||
|
||||
serial_t result = serial * m[bits - 8];
|
||||
const auto mult = m[bits - 8];
|
||||
const auto shift = s[bits - 8];
|
||||
serial_t result = serial * mult;
|
||||
if (salt) {
|
||||
const unsigned left = bits / 2;
|
||||
const unsigned right = bits - left;
|
||||
result = (result << left) | ((result & mask(bits)) >> right);
|
||||
result = (result ^ salt) * m[bits - 8];
|
||||
result = (result ^ salt) * mult;
|
||||
}
|
||||
|
||||
result ^= result << s[bits - 8];
|
||||
result ^= result << shift;
|
||||
result &= mask(bits);
|
||||
log_trace("keygen-injective: serial %" PRIu64 " into %" PRIu64, serial,
|
||||
result);
|
||||
log_trace("keygen-injective: serial %" PRIu64 "/%u @%" PRIx64 ",%u,%" PRIu64
|
||||
" => %" PRIu64 "/%u",
|
||||
serial, bits, mult, shift, salt, result, bits);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -82,19 +87,26 @@ void __hot maker::pair(serial_t serial, const buffer &key, buffer &value,
|
||||
if (mapping.mesh >= serial_minwith) {
|
||||
serial =
|
||||
(serial & ~mask(mapping.mesh)) | injective(serial, mapping.mesh, salt);
|
||||
log_trace("keygen-pair: mesh %" PRIu64, serial);
|
||||
log_trace("keygen-pair: mesh@%u => %" PRIu64, mapping.mesh, serial);
|
||||
}
|
||||
|
||||
if (mapping.rotate) {
|
||||
const unsigned right = mapping.rotate;
|
||||
const unsigned left = mapping.width - right;
|
||||
serial = (serial << left) | ((serial & mask(mapping.width)) >> right);
|
||||
log_trace("keygen-pair: rotate %" PRIu64 ", 0x%" PRIx64, serial, serial);
|
||||
log_trace("keygen-pair: rotate@%u => %" PRIu64 ", 0x%" PRIx64,
|
||||
mapping.rotate, serial, serial);
|
||||
}
|
||||
|
||||
serial = (serial + mapping.offset) & mask(mapping.width);
|
||||
log_trace("keygen-pair: offset %" PRIu64, serial);
|
||||
serial += base;
|
||||
if (mapping.offset) {
|
||||
serial = (serial + mapping.offset) & mask(mapping.width);
|
||||
log_trace("keygen-pair: offset@%" PRIu64 " => %" PRIu64, mapping.offset,
|
||||
serial);
|
||||
}
|
||||
if (base) {
|
||||
serial += base;
|
||||
log_trace("keygen-pair: base@%" PRIu64 " => %" PRIu64, base, serial);
|
||||
}
|
||||
|
||||
serial_t key_serial = serial;
|
||||
serial_t value_serial = value_age;
|
||||
@ -102,11 +114,12 @@ void __hot maker::pair(serial_t serial, const buffer &key, buffer &value,
|
||||
key_serial = serial >> mapping.split;
|
||||
value_serial =
|
||||
(serial & mask(mapping.split)) | (value_age << mapping.split);
|
||||
log_trace("keygen-pair: split@%u => k%" PRIu64 ", v%" PRIu64, mapping.split,
|
||||
key_serial, value_serial);
|
||||
}
|
||||
|
||||
log_trace("keygen-pair: key %" PRIu64 ", value %" PRIu64, key_serial,
|
||||
value_serial);
|
||||
|
||||
mk(key_serial, key_essentials, *key);
|
||||
mk(value_serial, value_essentials, *value);
|
||||
|
||||
|
@ -44,7 +44,7 @@ namespace keygen {
|
||||
* - абсолютное значение ключей или разность между отдельными значениями;
|
||||
*
|
||||
* Соответственно, в общих чертах, схема генерации следующая:
|
||||
* - вводится плоская одномерная "координата" uint64_t;
|
||||
* - вводится плоская одномерная "координата" serial (uint64_t);
|
||||
* - генерация специфических паттернов (последовательностей)
|
||||
* реализуется посредством соответствующих преобразований "координат", при
|
||||
* этом все подобные преобразования выполняются только над "координатой";
|
||||
@ -74,7 +74,7 @@ typedef uint64_t serial_t;
|
||||
enum : serial_t {
|
||||
serial_minwith = 8,
|
||||
serial_maxwith = sizeof(serial_t) * 8,
|
||||
serial_allones = ~(serial_t)0
|
||||
serial_allones = ~(serial_t)0u
|
||||
};
|
||||
|
||||
struct result {
|
||||
|
@ -45,8 +45,8 @@ void actor_params::set_defaults(const std::string &tmpdir) {
|
||||
|
||||
keygen.seed = 1;
|
||||
keygen.keycase = kc_random;
|
||||
keygen.width = 32;
|
||||
keygen.mesh = 32;
|
||||
keygen.width = (table_flags & MDBX_DUPSORT) ? 32 : 64;
|
||||
keygen.mesh = keygen.width;
|
||||
keygen.split = keygen.width / 2;
|
||||
keygen.rotate = 0;
|
||||
keygen.offset = 0;
|
||||
|
Loading…
x
Reference in New Issue
Block a user