mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-21 22:33:17 +08:00
Preserve key string generation behavior of mako.c
This commit is contained in:
parent
50dcde0ca5
commit
d202d482d9
@ -102,10 +102,11 @@ void ResumableStateForRunWorkload::postNextTick() {
|
|||||||
|
|
||||||
void ResumableStateForRunWorkload::runOneTick() {
|
void ResumableStateForRunWorkload::runOneTick() {
|
||||||
assert(iter != OpEnd);
|
assert(iter != OpEnd);
|
||||||
|
if (iter.step == 0 /* first step */)
|
||||||
|
prepareKeys(iter.op, key1, key2, args);
|
||||||
watch_step.start();
|
watch_step.start();
|
||||||
if (iter.step == 0 /* first step */) {
|
if (iter.step == 0)
|
||||||
watch_op = Stopwatch(watch_step.getStart());
|
watch_op = Stopwatch(watch_step.getStart());
|
||||||
}
|
|
||||||
auto f = Future{};
|
auto f = Future{};
|
||||||
// to minimize context switch overhead, repeat immediately completed ops
|
// to minimize context switch overhead, repeat immediately completed ops
|
||||||
// in a loop, not an async continuation.
|
// in a loop, not an async continuation.
|
||||||
|
@ -237,8 +237,10 @@ transaction_begin:
|
|||||||
while (op_iter != OpEnd) {
|
while (op_iter != OpEnd) {
|
||||||
const auto& [op, count, step] = op_iter;
|
const auto& [op, count, step] = op_iter;
|
||||||
const auto step_kind = opTable[op].stepKind(step);
|
const auto step_kind = opTable[op].stepKind(step);
|
||||||
auto watch_step = Stopwatch(StartAtCtor{});
|
|
||||||
if (step == 0 /* first step */)
|
if (step == 0 /* first step */)
|
||||||
|
prepareKeys(op, key1, key2, args);
|
||||||
|
auto watch_step = Stopwatch(StartAtCtor{});
|
||||||
|
if (step == 0)
|
||||||
watch_op = Stopwatch(watch_step.getStart());
|
watch_op = Stopwatch(watch_step.getStart());
|
||||||
auto f = opTable[op].stepFunction(step)(tx, args, key1, key2, val);
|
auto f = opTable[op].stepFunction(step)(tx, args, key1, key2, val);
|
||||||
auto future_rc = FutureRC::OK;
|
auto future_rc = FutureRC::OK;
|
||||||
|
@ -81,6 +81,10 @@ enum ArgKind {
|
|||||||
ARG_BG_FILE_PATH // if blob granule files are stored locally, mako will read and materialize them if this is set
|
ARG_BG_FILE_PATH // if blob granule files are stored locally, mako will read and materialize them if this is set
|
||||||
};
|
};
|
||||||
|
|
||||||
|
constexpr const int OP_COUNT = 0;
|
||||||
|
constexpr const int OP_RANGE = 1;
|
||||||
|
constexpr const int OP_REVERSE = 2;
|
||||||
|
|
||||||
/* transaction specification */
|
/* transaction specification */
|
||||||
enum OpKind {
|
enum OpKind {
|
||||||
OP_GETREADVERSION,
|
OP_GETREADVERSION,
|
||||||
|
@ -23,7 +23,6 @@
|
|||||||
#include "mako.hpp"
|
#include "mako.hpp"
|
||||||
#include "logger.hpp"
|
#include "logger.hpp"
|
||||||
#include "utils.hpp"
|
#include "utils.hpp"
|
||||||
#include "fdbclient/zipf.h"
|
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
extern thread_local mako::Logger logr;
|
extern thread_local mako::Logger logr;
|
||||||
@ -32,12 +31,6 @@ namespace mako {
|
|||||||
|
|
||||||
using namespace fdb;
|
using namespace fdb;
|
||||||
|
|
||||||
inline int nextKey(Arguments const& args) {
|
|
||||||
if (args.zipf)
|
|
||||||
return zipfian_next();
|
|
||||||
return urand(0, args.rows - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::array<Operation, MAX_OP> opTable{
|
const std::array<Operation, MAX_OP> opTable{
|
||||||
{ { "GRV",
|
{ { "GRV",
|
||||||
{ { StepKind::READ,
|
{ { StepKind::READ,
|
||||||
@ -54,8 +47,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "GET",
|
{ "GET",
|
||||||
{ { StepKind::READ,
|
{ { StepKind::READ,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
||||||
const auto num = nextKey(args);
|
|
||||||
genKey(key, KEY_PREFIX, args, num);
|
|
||||||
return tx.get(key, false /*snapshot*/).eraseType();
|
return tx.get(key, false /*snapshot*/).eraseType();
|
||||||
},
|
},
|
||||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||||
@ -68,12 +59,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "GETRANGE",
|
{ "GETRANGE",
|
||||||
{ { StepKind::READ,
|
{ { StepKind::READ,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
||||||
const auto num_begin = nextKey(args);
|
|
||||||
genKey(begin, KEY_PREFIX, args, num_begin);
|
|
||||||
auto num_end = num_begin + args.txnspec.ops[OP_GETRANGE][OP_RANGE] - 1;
|
|
||||||
if (num_end > args.rows - 1)
|
|
||||||
num_end = args.rows - 1;
|
|
||||||
genKey(end, KEY_PREFIX, args, num_end);
|
|
||||||
return tx
|
return tx
|
||||||
.getRange<key_select::Inclusive, key_select::Inclusive>(begin,
|
.getRange<key_select::Inclusive, key_select::Inclusive>(begin,
|
||||||
end,
|
end,
|
||||||
@ -95,8 +80,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "SGET",
|
{ "SGET",
|
||||||
{ { StepKind::READ,
|
{ { StepKind::READ,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
||||||
const auto num = nextKey(args);
|
|
||||||
genKey(key, KEY_PREFIX, args, num);
|
|
||||||
return tx.get(key, true /*snapshot*/).eraseType();
|
return tx.get(key, true /*snapshot*/).eraseType();
|
||||||
},
|
},
|
||||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||||
@ -111,12 +94,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
|
|
||||||
StepKind::READ,
|
StepKind::READ,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
||||||
const auto num_begin = nextKey(args);
|
|
||||||
genKey(begin, KEY_PREFIX, args, num_begin);
|
|
||||||
auto num_end = num_begin + args.txnspec.ops[OP_SGETRANGE][OP_RANGE] - 1;
|
|
||||||
if (num_end > args.rows - 1)
|
|
||||||
num_end = args.rows - 1;
|
|
||||||
genKey(end, KEY_PREFIX, args, num_end);
|
|
||||||
return tx
|
return tx
|
||||||
.getRange<key_select::Inclusive, key_select::Inclusive>(begin,
|
.getRange<key_select::Inclusive, key_select::Inclusive>(begin,
|
||||||
end,
|
end,
|
||||||
@ -138,8 +115,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "UPDATE",
|
{ "UPDATE",
|
||||||
{ { StepKind::READ,
|
{ { StepKind::READ,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
||||||
const auto num = nextKey(args);
|
|
||||||
genKey(key, KEY_PREFIX, args, num);
|
|
||||||
return tx.get(key, false /*snapshot*/).eraseType();
|
return tx.get(key, false /*snapshot*/).eraseType();
|
||||||
},
|
},
|
||||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||||
@ -192,7 +167,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "OVERWRITE",
|
{ "OVERWRITE",
|
||||||
{ { StepKind::IMM,
|
{ { StepKind::IMM,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) {
|
||||||
genKey(key, KEY_PREFIX, args, nextKey(args));
|
|
||||||
randomString(value, args.value_length);
|
randomString(value, args.value_length);
|
||||||
tx.set(key, value);
|
tx.set(key, value);
|
||||||
return Future();
|
return Future();
|
||||||
@ -202,7 +176,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "CLEAR",
|
{ "CLEAR",
|
||||||
{ { StepKind::IMM,
|
{ { StepKind::IMM,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString&) {
|
||||||
genKey(key, KEY_PREFIX, args, nextKey(args));
|
|
||||||
tx.clear(key);
|
tx.clear(key);
|
||||||
return Future();
|
return Future();
|
||||||
} } },
|
} } },
|
||||||
@ -213,7 +186,7 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) {
|
[](Transaction& tx, Arguments const& args, ByteString& key, ByteString&, ByteString& value) {
|
||||||
genKeyPrefix(key, KEY_PREFIX, args);
|
genKeyPrefix(key, KEY_PREFIX, args);
|
||||||
const auto prefix_len = static_cast<int>(key.size());
|
const auto prefix_len = static_cast<int>(key.size());
|
||||||
randomString<false /*append-after-clear*/>(key, args.key_length - prefix_len);
|
randomString<false /*clear-before-append*/>(key, args.key_length - prefix_len);
|
||||||
randomString(value, args.value_length);
|
randomString(value, args.value_length);
|
||||||
tx.set(key, value);
|
tx.set(key, value);
|
||||||
return tx.commit().eraseType();
|
return tx.commit().eraseType();
|
||||||
@ -229,11 +202,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "CLEARRANGE",
|
{ "CLEARRANGE",
|
||||||
{ { StepKind::IMM,
|
{ { StepKind::IMM,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
||||||
const auto num_begin = nextKey(args);
|
|
||||||
genKey(begin, KEY_PREFIX, args, num_begin);
|
|
||||||
const auto range = args.txnspec.ops[OP_CLEARRANGE][OP_RANGE];
|
|
||||||
assert(range > 0);
|
|
||||||
genKey(end, KEY_PREFIX, args, std::min(args.rows - 1, num_begin + range - 1));
|
|
||||||
tx.clearRange(begin, end);
|
tx.clearRange(begin, end);
|
||||||
return Future();
|
return Future();
|
||||||
} } },
|
} } },
|
||||||
@ -278,11 +246,6 @@ const std::array<Operation, MAX_OP> opTable{
|
|||||||
{ "READBLOBGRANULE",
|
{ "READBLOBGRANULE",
|
||||||
{ { StepKind::ON_ERROR,
|
{ { StepKind::ON_ERROR,
|
||||||
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
[](Transaction& tx, Arguments const& args, ByteString& begin, ByteString& end, ByteString&) {
|
||||||
const auto num_begin = nextKey(args);
|
|
||||||
genKey(begin, KEY_PREFIX, args, num_begin);
|
|
||||||
const auto range = args.txnspec.ops[OP_READ_BG][OP_RANGE];
|
|
||||||
assert(range > 0);
|
|
||||||
genKey(end, KEY_PREFIX, args, std::min(args.rows - 1, num_begin + range - 1));
|
|
||||||
auto err = Error{};
|
auto err = Error{};
|
||||||
|
|
||||||
err = tx.setOptionNothrow(FDB_TR_OPTION_READ_YOUR_WRITES_DISABLE, BytesRef());
|
err = tx.setOptionNothrow(FDB_TR_OPTION_READ_YOUR_WRITES_DISABLE, BytesRef());
|
||||||
|
@ -33,10 +33,6 @@
|
|||||||
|
|
||||||
namespace mako {
|
namespace mako {
|
||||||
|
|
||||||
constexpr const int OP_COUNT = 0;
|
|
||||||
constexpr const int OP_RANGE = 1;
|
|
||||||
constexpr const int OP_REVERSE = 2;
|
|
||||||
|
|
||||||
// determines how resultant future will be handled
|
// determines how resultant future will be handled
|
||||||
enum class StepKind {
|
enum class StepKind {
|
||||||
NONE, ///< not part of the table: OP_TRANSACTION, OP_COMMIT
|
NONE, ///< not part of the table: OP_TRANSACTION, OP_COMMIT
|
||||||
|
@ -27,25 +27,7 @@
|
|||||||
|
|
||||||
namespace mako {
|
namespace mako {
|
||||||
|
|
||||||
/* uniform-distribution random */
|
|
||||||
int urand(int low, int high) {
|
|
||||||
double r = rand() / (1.0 + RAND_MAX);
|
|
||||||
int range = high - low + 1;
|
|
||||||
return (int)((r * range) + low);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the first key to be inserted */
|
|
||||||
int insertBegin(int rows, int p_idx, int t_idx, int total_p, int total_t) {
|
|
||||||
double interval = (double)rows / total_p / total_t;
|
|
||||||
return (int)(round(interval * ((p_idx * total_t) + t_idx)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* return the last key to be inserted */
|
/* return the last key to be inserted */
|
||||||
int insertEnd(int rows, int p_idx, int t_idx, int total_p, int total_t) {
|
|
||||||
double interval = (double)rows / total_p / total_t;
|
|
||||||
return (int)(round(interval * ((p_idx * total_t) + t_idx + 1) - 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* devide val equally among threads */
|
/* devide val equally among threads */
|
||||||
int computeThreadPortion(int val, int p_idx, int t_idx, int total_p, int total_t) {
|
int computeThreadPortion(int val, int p_idx, int t_idx, int total_p, int total_t) {
|
||||||
int interval = val / total_p / total_t;
|
int interval = val / total_p / total_t;
|
||||||
|
@ -22,7 +22,9 @@
|
|||||||
#define UTILS_HPP
|
#define UTILS_HPP
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
|
#include "macro.hpp"
|
||||||
#include "mako.hpp"
|
#include "mako.hpp"
|
||||||
|
#include "fdbclient/zipf.h"
|
||||||
#include <cassert>
|
#include <cassert>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
@ -34,7 +36,17 @@ namespace mako {
|
|||||||
|
|
||||||
/* uniform-distribution random */
|
/* uniform-distribution random */
|
||||||
/* return a uniform random number between low and high, both inclusive */
|
/* return a uniform random number between low and high, both inclusive */
|
||||||
int urand(int low, int high);
|
force_inline int urand(int low, int high) {
|
||||||
|
double r = rand() / (1.0 + RAND_MAX);
|
||||||
|
int range = high - low + 1;
|
||||||
|
return (int)((r * range) + low);
|
||||||
|
}
|
||||||
|
|
||||||
|
force_inline int nextKey(Arguments const& args) {
|
||||||
|
if (args.zipf)
|
||||||
|
return zipfian_next();
|
||||||
|
return urand(0, args.rows - 1);
|
||||||
|
}
|
||||||
|
|
||||||
/* random string */
|
/* random string */
|
||||||
template <bool Clear = true, typename Char>
|
template <bool Clear = true, typename Char>
|
||||||
@ -65,10 +77,16 @@ void randomNumericString(std::basic_string<Char>& str, int len) {
|
|||||||
* and the total number of processes, total_p, and threads, total_t,
|
* and the total number of processes, total_p, and threads, total_t,
|
||||||
* returns the first row number assigned to this partition.
|
* returns the first row number assigned to this partition.
|
||||||
*/
|
*/
|
||||||
int insertBegin(int rows, int p_idx, int t_idx, int total_p, int total_t);
|
force_inline int insertBegin(int rows, int p_idx, int t_idx, int total_p, int total_t) {
|
||||||
|
double interval = (double)rows / total_p / total_t;
|
||||||
|
return (int)(round(interval * ((p_idx * total_t) + t_idx)));
|
||||||
|
}
|
||||||
|
|
||||||
/* similar to insertBegin, insertEnd returns the last row numer */
|
/* similar to insertBegin, insertEnd returns the last row numer */
|
||||||
int insertEnd(int rows, int p_idx, int t_idx, int total_p, int total_t);
|
force_inline int insertEnd(int rows, int p_idx, int t_idx, int total_p, int total_t) {
|
||||||
|
double interval = (double)rows / total_p / total_t;
|
||||||
|
return (int)(round(interval * ((p_idx * total_t) + t_idx + 1) - 1));
|
||||||
|
}
|
||||||
|
|
||||||
/* devide a value equally among threads */
|
/* devide a value equally among threads */
|
||||||
int computeThreadPortion(int val, int p_idx, int t_idx, int total_p, int total_t);
|
int computeThreadPortion(int val, int p_idx, int t_idx, int total_p, int total_t);
|
||||||
@ -121,6 +139,16 @@ void genKey(std::basic_string<Char>& str, std::string_view prefix, Arguments con
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename Char>
|
||||||
|
void prepareKeys(int op, std::basic_string<Char>& key1, std::basic_string<Char>& key2, Arguments const& args) {
|
||||||
|
const auto key1_num = nextKey(args);
|
||||||
|
genKey(key1, 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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// invoke user-provided callable when object goes out of scope.
|
// invoke user-provided callable when object goes out of scope.
|
||||||
template <typename Func>
|
template <typename Func>
|
||||||
class ExitGuard {
|
class ExitGuard {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user