From c5ac7b25c90a722c13fdf1a26b340f7663100f45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9B=D0=B5=D0=BE=D0=BD=D0=B8=D0=B4=20=D0=AE=D1=80=D1=8C?= =?UTF-8?q?=D0=B5=D0=B2=20=28Leonid=20Yuriev=29?= Date: Tue, 20 Feb 2024 22:51:35 +0300 Subject: [PATCH] =?UTF-8?q?mdbx-test:=20=D0=B4=D0=BE=D1=80=D0=B0=D0=B1?= =?UTF-8?q?=D0=BE=D1=82=D0=BA=D0=B0=20=D0=B3=D0=B5=D0=BD=D0=B5=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=B0=20=D0=BF=D0=B0=D1=80=20key-value=20?= =?UTF-8?q?=D0=B4=D0=BB=D1=8F=20=D0=BF=D0=BE=D0=B4=D0=B4=D0=B5=D1=80=D0=B6?= =?UTF-8?q?=D0=BA=D0=B8=20=D0=BA=D0=BE=D1=80=D0=BE=D1=82=D0=BA=D0=B8=D1=85?= =?UTF-8?q?=20=D0=BA=D0=BB=D1=8E=D1=87=D0=B5=D0=B9=20=D0=B2=20=D1=80=D0=B5?= =?UTF-8?q?=D0=B6=D0=B8=D0=BC=D0=B5=20`MDBX=5FDUPFIXED`.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- test/keygen.c++ | 56 +++++++++++++++++++++++++++++++++---------------- test/keygen.h++ | 10 +++------ 2 files changed, 41 insertions(+), 25 deletions(-) diff --git a/test/keygen.c++ b/test/keygen.c++ index a6d20f33..1829e0db 100644 --- a/test/keygen.c++ +++ b/test/keygen.c++ @@ -79,7 +79,7 @@ void __hot maker::pair(serial_t serial, const buffer &key, buffer &value, unsigned(MDBX_INTEGERKEY | MDBX_REVERSEKEY | MDBX_DUPSORT)))); assert(!(value_essentials.flags & ~(essentials::prng_fill_flag | - unsigned(MDBX_INTEGERDUP | MDBX_REVERSEDUP)))); + unsigned(MDBX_INTEGERDUP | MDBX_REVERSEDUP | MDBX_DUPFIXED)))); log_trace("keygen-pair: serial %" PRIu64 ", data-age %" PRIu64, serial, value_age); @@ -126,15 +126,14 @@ void __hot maker::pair(serial_t serial, const buffer &key, buffer &value, actor_params::serial_mask(mapping.split); } - value_serial |= 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_begin(key_serial, key_essentials, *key); - mk_begin(value_serial, value_essentials, *value); + key_serial = mk_begin(key_serial, key_essentials, *key); + value_serial = mk_begin(value_serial, value_essentials, *value); #if 0 /* unused for now */ if (key->value.iov_len + value->value.iov_len > pair_maxlen) { @@ -193,11 +192,13 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id, unsigned thread_number) { #if CONSTEXPR_ENUM_FLAGS_OPERATIONS static_assert(unsigned(MDBX_INTEGERKEY | MDBX_REVERSEKEY | MDBX_DUPSORT | - MDBX_INTEGERDUP | MDBX_REVERSEDUP) < UINT16_MAX, + MDBX_DUPFIXED | MDBX_INTEGERDUP | MDBX_REVERSEDUP) < + UINT16_MAX, "WTF?"); #else assert(unsigned(MDBX_INTEGERKEY | MDBX_REVERSEKEY | MDBX_DUPSORT | - MDBX_INTEGERDUP | MDBX_REVERSEDUP) < UINT16_MAX); + MDBX_DUPFIXED | MDBX_INTEGERDUP | MDBX_REVERSEDUP) < + UINT16_MAX); #endif key_essentials.flags = uint16_t( actor.table_flags & @@ -205,20 +206,19 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id, assert(actor.keylen_min <= UINT16_MAX); key_essentials.minlen = uint16_t(actor.keylen_min); assert(actor.keylen_max <= UINT32_MAX); - key_essentials.maxlen = - std::min(uint32_t(actor.keylen_max), - uint32_t(mdbx_limits_keysize_max( - actor.pagesize, MDBX_db_flags_t(key_essentials.flags)))); + key_essentials.maxlen = std::min( + uint32_t(actor.keylen_max), + uint32_t(mdbx_limits_keysize_max(actor.pagesize, actor.table_flags))); value_essentials.flags = uint16_t( - actor.table_flags & MDBX_db_flags_t(MDBX_INTEGERDUP | MDBX_REVERSEDUP)); + actor.table_flags & + MDBX_db_flags_t(MDBX_INTEGERDUP | MDBX_REVERSEDUP | MDBX_DUPFIXED)); assert(actor.datalen_min <= UINT16_MAX); value_essentials.minlen = uint16_t(actor.datalen_min); assert(actor.datalen_max <= UINT32_MAX); - value_essentials.maxlen = - std::min(uint32_t(actor.datalen_max), - uint32_t(mdbx_limits_valsize_max( - actor.pagesize, MDBX_db_flags_t(key_essentials.flags)))); + value_essentials.maxlen = std::min( + uint32_t(actor.datalen_max), + uint32_t(mdbx_limits_valsize_max(actor.pagesize, actor.table_flags))); if (!actor.keygen.zero_fill) { key_essentials.flags |= essentials::prng_fill_flag; @@ -227,6 +227,16 @@ void maker::setup(const config::actor_params_pod &actor, unsigned actor_id, (void)thread_number; mapping = actor.keygen; + while (mapping.split > + essentials::value_age_width + value_essentials.maxlen * CHAR_BIT || + mapping.split >= mapping.width) + mapping.split -= 1; + + while (unsigned((actor.table_flags & MDBX_DUPSORT) + ? mapping.width - mapping.split + : mapping.width) > key_essentials.maxlen * CHAR_BIT) + mapping.width -= 1; + salt = (actor.keygen.seed + uint64_t(actor_id)) * UINT64_C(14653293970879851569); @@ -307,11 +317,20 @@ buffer alloc(size_t limit) { return buffer(ptr); } -void __hot maker::mk_begin(const serial_t serial, const essentials ¶ms, - result &out) { +serial_t __hot maker::mk_begin(serial_t serial, const essentials ¶ms, + result &out) { assert(out.limit >= params.maxlen); assert(params.maxlen >= params.minlen); - assert(params.maxlen >= length(serial)); + if (params.maxlen < sizeof(serial_t)) { + const serial_t max = actor_params::serial_mask(params.maxlen * CHAR_BIT); + if (serial > max) { + serial ^= (serial >> max / 2) * serial_t((sizeof(serial_t) > 4) + ? UINT64_C(40719303417517073) + : UINT32_C(3708688457)); + serial &= max; + } + assert(params.maxlen >= length(serial)); + } out.value.iov_len = std::max(unsigned(params.minlen), length(serial)); const auto variation = params.maxlen - params.minlen; @@ -328,6 +347,7 @@ void __hot maker::mk_begin(const serial_t serial, const essentials ¶ms, assert(length(serial) <= out.value.iov_len); assert(out.value.iov_len >= params.minlen); assert(out.value.iov_len <= params.maxlen); + return serial; } void __hot maker::mk_continue(const serial_t serial, const essentials ¶ms, diff --git a/test/keygen.h++ b/test/keygen.h++ index 9e2410fd..8c49eabb 100644 --- a/test/keygen.h++ +++ b/test/keygen.h++ @@ -108,19 +108,15 @@ class maker { struct essentials { uint16_t minlen{0}; - enum { prng_fill_flag = 1 }; + enum { prng_fill_flag = 1, value_age_width = 8 }; uint16_t flags{0}; uint32_t maxlen{0}; } key_essentials, value_essentials; - static void mk_begin(const serial_t serial, const essentials ¶ms, - result &out); + static serial_t mk_begin(serial_t serial, const essentials ¶ms, + result &out); static void mk_continue(const serial_t serial, const essentials ¶ms, result &out); - static void mk(const serial_t serial, const essentials ¶ms, result &out) { - mk_begin(serial, params, out); - mk_continue(serial, params, out); - } public: void pair(serial_t serial, const buffer &key, buffer &value,