From b7e493f03087bad82e0824efbebb97d3f9e71057 Mon Sep 17 00:00:00 2001 From: Junhyun Shim Date: Wed, 20 Apr 2022 16:26:48 +0200 Subject: [PATCH] Simplify string generation --- bindings/c/test/mako/async.cpp | 4 +- bindings/c/test/mako/async.hpp | 10 ++--- bindings/c/test/mako/mako.cpp | 38 +++++++++++-------- bindings/c/test/mako/operations.cpp | 59 +++++++++++------------------ bindings/c/test/mako/utils.hpp | 54 +++++++++++--------------- 5 files changed, 75 insertions(+), 90 deletions(-) diff --git a/bindings/c/test/mako/async.cpp b/bindings/c/test/mako/async.cpp index e3ba4e1584..b4b601e5b0 100644 --- a/bindings/c/test/mako/async.cpp +++ b/bindings/c/test/mako/async.cpp @@ -40,8 +40,8 @@ void ResumableStateForPopulate::postNextTick() { void ResumableStateForPopulate::runOneTick() { const auto num_commit_every = args.txnspec.ops[OP_INSERT][OP_COUNT]; for (auto i = key_checkpoint; i <= key_end; i++) { - genKey(keystr, KEY_PREFIX, args, i); - randomString(valstr, args.value_length); + genKey(keystr.data(), KEY_PREFIX, args, i); + randomString(valstr.data(), args.value_length); tx.set(keystr, valstr); stats.incrOpCount(OP_INSERT); if (i == key_end || (i - key_begin + 1) % num_commit_every == 0) { diff --git a/bindings/c/test/mako/async.hpp b/bindings/c/test/mako/async.hpp index a5025202d8..8105ed72c1 100644 --- a/bindings/c/test/mako/async.hpp +++ b/bindings/c/test/mako/async.hpp @@ -62,8 +62,8 @@ struct ResumableStateForPopulate : std::enable_shared_from_this 0 && xacts >= thread_tps /* throttle */) { if (toIntegerSeconds(watch_throttle.stop().diff()) >= 1) { @@ -369,11 +375,11 @@ int runWorkload(Transaction tx, // reuse memory for keys to avoid realloc overhead auto key1 = ByteString{}; - key1.reserve(args.key_length); + key1.resize(args.key_length); auto key2 = ByteString{}; - key2.reserve(args.key_length); + key2.resize(args.key_length); auto val = ByteString{}; - val.reserve(args.value_length); + val.resize(args.value_length); /* main transaction loop */ while (1) { diff --git a/bindings/c/test/mako/operations.cpp b/bindings/c/test/mako/operations.cpp index 789d311a2e..ab4923638a 100644 --- a/bindings/c/test/mako/operations.cpp +++ b/bindings/c/test/mako/operations.cpp @@ -124,7 +124,7 @@ const std::array opTable{ } }, { StepKind::IMM, [](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) { - randomString(value, args.value_length); + randomString(value.data(), args.value_length); tx.set(key, value); return Future(); } } }, @@ -133,10 +133,9 @@ const std::array opTable{ { "INSERT", { { StepKind::IMM, [](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) { - genKeyPrefix(key, KEY_PREFIX, args); - // concat([padding], key_prefix, random_string): reasonably unique - randomString(key, args.key_length - static_cast(key.size())); - randomString(value, args.value_length); + // key[0..args.key_length] := concat(key_prefix, random_string) + randomString(key.data() + intSize(KEY_PREFIX), args.key_length - intSize(KEY_PREFIX)); + randomString(value.data(), args.value_length); tx.set(key, value); return Future(); } } }, @@ -145,20 +144,17 @@ const std::array opTable{ { "INSERTRANGE", { { StepKind::IMM, [](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) { - genKeyPrefix(key, KEY_PREFIX, args); - const auto prefix_len = static_cast(key.size()); + randomString(value.data(), args.value_length); + + // key[0..args.key_length] := concat(prefix, random_string, num[0..range_digits]) const auto range = args.txnspec.ops[OP_INSERTRANGE][OP_RANGE]; assert(range > 0); const auto range_digits = digits(range); - assert(args.key_length - prefix_len >= range_digits); - const auto rand_len = args.key_length - prefix_len - range_digits; - // concat([padding], prefix, random_string, range_digits) - randomString(key, rand_len); - randomString(value, args.value_length); + const auto random_len = args.key_length - intSize(KEY_PREFIX) - range_digits; + randomString(&key[intSize(KEY_PREFIX)], random_len); for (auto i = 0; i < range; i++) { - fmt::format_to(std::back_inserter(key), "{0:0{1}d}", i, range_digits); + numericWithFill(&key[args.key_length - range_digits], range_digits, i); tx.set(key, value); - key.resize(key.size() - static_cast(range_digits)); } return Future(); } } }, @@ -167,7 +163,7 @@ const std::array opTable{ { "OVERWRITE", { { StepKind::IMM, [](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) { - randomString(value, args.value_length); + randomString(value.data(), args.value_length); tx.set(key, value); return Future(); } } }, @@ -184,10 +180,8 @@ const std::array opTable{ { "SETCLEAR", { { StepKind::COMMIT, [](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) { - genKeyPrefix(key, KEY_PREFIX, args); - const auto prefix_len = static_cast(key.size()); - randomString(key, args.key_length - prefix_len); - randomString(value, args.value_length); + randomString(&key[KEY_PREFIX.size()], args.key_length - intSize(KEY_PREFIX)); + randomString(value.data(), args.value_length); tx.set(key, value); return tx.commit().eraseType(); } }, @@ -210,26 +204,19 @@ const std::array opTable{ { "SETCLEARRANGE", { { StepKind::COMMIT, [](Transaction& tx, Arguments const& args, ByteString& key_begin, ByteString& key, ByteString& value) { - genKeyPrefix(key, KEY_PREFIX, args); - const auto prefix_len = static_cast(key.size()); - const auto range = args.txnspec.ops[OP_SETCLEARRANGE][OP_RANGE]; + randomString(value.data(), args.value_length); + + // key[0..args.key_length] := concat(prefix, random_string, num[0..range_digits]) + const auto range = args.txnspec.ops[OP_INSERTRANGE][OP_RANGE]; assert(range > 0); const auto range_digits = digits(range); - assert(args.key_length - prefix_len >= range_digits); - const auto rand_len = args.key_length - prefix_len - range_digits; - // concat([padding], prefix, random_string, range_digits) - randomString(key, rand_len); - randomString(value, args.value_length); - for (auto i = 0; i <= range; i++) { - fmt::format_to(std::back_inserter(key), "{0:0{1}d}", i, range_digits); - if (i == range) - break; // preserve "exclusive last" - // preserve first key for step 1 - if (i == 0) - key_begin = key; + const auto random_len = args.key_length - intSize(KEY_PREFIX) - range_digits; + randomString(&key[KEY_PREFIX.size()], random_len); + for (auto i = 0; i < range; i++) { + numericWithFill(&key[args.key_length - range_digits], range_digits, i); tx.set(key, value); - // preserve last key for step 1 - key.resize(key.size() - static_cast(range_digits)); + if (i == 0) + key_begin.assign(key); } return tx.commit().eraseType(); } }, diff --git a/bindings/c/test/mako/utils.hpp b/bindings/c/test/mako/utils.hpp index a08b9c0df1..e499160e76 100644 --- a/bindings/c/test/mako/utils.hpp +++ b/bindings/c/test/mako/utils.hpp @@ -28,6 +28,7 @@ #include #include #include +#include #include #include @@ -48,15 +49,16 @@ force_inline int nextKey(Arguments const& args) { return urand(0, args.rows - 1); } +force_inline int intSize(std::string_view sv) { + return static_cast(sv.size()); +} + /* random string */ -template -void randomString(std::basic_string& str, int len) { - if constexpr (Clear) - str.clear(); +template +void randomString(Char* str, int len) { assert(len >= 0); - str.reserve(str.size() + static_cast(len)); for (auto i = 0; i < len; i++) { - str.push_back('!' + urand(0, 'z' - '!')); /* generage a char from '!' to 'z' */ + str[i] = ('!' + urand(0, 'z' - '!')); /* generate a char from '!' to 'z' */ } } @@ -105,47 +107,37 @@ int computeThreadPortion(int val, int p_idx, int t_idx, int total_p, int total_t /* get the number of digits */ int digits(int num); -/* fill (str) with configured key prefix: i.e. non-numeric part - * (str) is appended with concat([padding], PREFIX) - */ -template -void genKeyPrefix(std::basic_string& str, std::string_view prefix, Arguments const& args) { - // concat('x' * padding_len, key_prefix) - if constexpr (Clear) - str.clear(); - const auto padding_len = - args.prefixpadding ? (args.key_length - args.row_digits - static_cast(prefix.size())) : 0; - assert(padding_len >= 0); - str.reserve(str.size() + padding_len + prefix.size()); - for (auto i = 0; i < padding_len; i++) - str.push_back('x'); - str.append(reinterpret_cast(prefix.data()), prefix.size()); +/* fill memory slice [str, str + len) as stringified, zero-padded num */ +template +void numericWithFill(Char* str, int len, int num) { + static_assert(sizeof(Char) == 1); + assert(num >= 0); + for (auto i = len - 1; i >= 0; i--) { + str[i] = (num % 10) + '0'; + num /= 10; + } } /* generate a key for a given key number */ /* prefix is "mako" by default, prefixpadding = 1 means 'x' will be in front rather than trailing the keyname */ template -void genKey(std::basic_string& str, std::string_view prefix, Arguments const& args, int num) { +void genKey(Char* str, std::string_view prefix, Arguments const& args, int num) { static_assert(sizeof(Char) == 1); - str.clear(); - str.resize(args.key_length, 'x'); + memset(str, 'x', args.key_length); const auto prefix_len = static_cast(prefix.size()); auto pos = args.prefixpadding ? (args.key_length - prefix_len - args.row_digits) : 0; - memcpy(&str[pos], prefix.data(), prefix.size()); + memcpy(&str[pos], prefix.data(), prefix_len); pos += prefix_len; - for (auto i = 0; i < args.row_digits; i++) { - str[pos + (args.row_digits - i - 1)] = (num % 10) + '0'; - num /= 10; - } + numericWithFill(&str[pos], args.row_digits, num); } template void prepareKeys(int op, std::basic_string& key1, std::basic_string& key2, Arguments const& args) { const auto key1_num = nextKey(args); - genKey(key1, KEY_PREFIX, args, key1_num); + genKey(key1.data(), KEY_PREFIX, args, key1_num); if (args.txnspec.ops[op][OP_RANGE] > 0) { const auto key2_num = std::min(key1_num + args.txnspec.ops[op][OP_RANGE] - 1, args.rows - 1); - genKey(key2, KEY_PREFIX, args, key2_num); + genKey(key2.data(), KEY_PREFIX, args, key2_num); } }