diff --git a/Bench.cpp b/Bench.cpp index 280e5d0..9336dae 100644 --- a/Bench.cpp +++ b/Bench.cpp @@ -2,6 +2,7 @@ #include "Internal.h" #include #include +#include #define ANKERL_NANOBENCH_IMPLEMENT #include "third_party/nanobench.h" @@ -598,6 +599,24 @@ private: SkipList skipList; }; +ConflictSet::ReadRange prefixRange(Arena &arena, std::span key) { + int index; + for (index = key.size() - 1; index >= 0; index--) + if ((key[index]) != 255) + break; + + // Must not be called with a string that consists only of zero or more '\xff' + // bytes. + if (index < 0) { + assert(false); + } + + auto r = std::span(new (arena) uint8_t[index + 1], index + 1); + memcpy(r.data(), key.data(), index + 1); + r[r.size() - 1]++; + return {key.data(), int(key.size()), r.data(), int(r.size())}; +} + } // namespace constexpr int kNumKeys = 1000000; @@ -606,19 +625,13 @@ constexpr int kOpsPerTx = 100; constexpr int kPrefixLen = 0; -std::span makeKey(Arena &arena, int64_t index) { +std::span makeKey(Arena &arena, int index) { - // auto result = - // std::span{new (arena) uint8_t[4 + kPrefixLen], 4 + - // kPrefixLen}; - // index = __builtin_bswap32(index); - // memset(result.data(), 0, kPrefixLen); - // memcpy(result.data() + kPrefixLen, &index, 4); - - auto result = std::span{new (arena) uint8_t[64], 64}; - for (int i = 0; i < 64; ++i) { - result[i] = index & (1 << (64 - 1 - i)) ? '1' : '0'; - } + auto result = + std::span{new (arena) uint8_t[4 + kPrefixLen], 4 + kPrefixLen}; + index = __builtin_bswap32(index); + memset(result.data(), 0, kPrefixLen); + memcpy(result.data() + kPrefixLen, &index, 4); return result; } @@ -628,6 +641,7 @@ template void benchConflictSet(const std::string &name) { ConflictSet_ cs{0}; bench.batch(kOpsPerTx); + bench.minEpochIterations(2000); int64_t version = 0; @@ -702,6 +716,22 @@ template void benchConflictSet(const std::string &name) { [&]() { cs.check(reads.data(), results, kOpsPerTx); }); } + { + std::vector reads; + auto iter = points.begin(); + for (int i = 0; i < kOpsPerTx; ++i) { + auto r = prefixRange(arena, *iter); + r.readVersion = version - 1; + reads.push_back(r); + ++iter; + } + + auto *results = new (arena) ConflictSet::Result[kOpsPerTx]; + + bench.run(name + " (prefix reads)", + [&]() { cs.check(reads.data(), results, kOpsPerTx); }); + } + { std::vector reads; auto iter = points.begin(); @@ -744,6 +774,29 @@ template void benchConflictSet(const std::string &name) { }); } + { + std::vector writes; + auto iter = points.begin(); + for (int i = 0; i < kOpsPerTx; ++i) { + ConflictSet::WriteRange w; + auto r = prefixRange(arena, *iter); + w.begin.p = r.begin.p; + w.begin.len = r.begin.len; + w.end.p = r.end.p; + w.end.len = r.end.len; + writes.push_back(w); + ++iter; + } + + bench.run(name + " (prefix writes)", [&]() { + auto v = ++version; + for (auto &w : writes) { + w.writeVersion = v; + } + cs.addWrites(writes.data(), writes.size()); + }); + } + { std::vector writes; auto iter = points.begin();