13 Commits

Author SHA1 Message Date
71c39f9955 Opt-in to rpm/deb default package filenames
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-29 15:56:58 -07:00
8cc17158fd Fix preprocessing instructions for linux
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 14:58:29 -07:00
ab211c646a Apply compiler-appeasing syntax changes from Taoxi 2024-03-28 14:57:31 -07:00
7af961f141 Fix jenkins build
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 11:44:01 -07:00
a91df62608 Add USE_SIMD_FALLBACK build in jenkins
Some checks failed
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1096, passed: 1096
weaselab/conflict-set/pipeline/head There was a failure building this commit
2024-03-28 11:33:53 -07:00
0a1843a161 Add USE_SIMD_FALLBACK
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-28 11:12:50 -07:00
4edf0315d9 Find insertion point for Node16 with simd
Closes #13
2024-03-28 10:47:20 -07:00
14515e186a Update readme benchmarks again
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
I think the last skiplisttest benchmark looked bad because I had vscode
+ firefox + ?? open
2024-03-27 16:47:36 -07:00
b0085df5ad Update symbols.txt
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
2024-03-27 16:29:30 -07:00
76a7e17b29 Update readme benchmarks
Some checks failed
Tests / Clang total: 1096, failed: 2, passed: 1094
Tests / Release [gcc] total: 1096, failed: 2, passed: 1094
Tests / Release [gcc,aarch64] total: 824, failed: 2, passed: 822
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head There was a failure building this commit
I was incorrectly linking to an old build of conflict set, before the
conflict-set name change. I don't know what the regression is from, but
update the README for transparency now.
2024-03-27 16:12:45 -07:00
5cf43d1bfa Add weaselab namespace 2024-03-27 16:07:05 -07:00
25cc427ec5 Assert safe_free size is correct in debug builds
All checks were successful
Tests / Clang total: 1096, passed: 1096
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc] total: 1096, passed: 1096
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 824, passed: 824
Tests / Coverage total: 823, passed: 823
weaselab/conflict-set/pipeline/head This commit looks good
Closes #16
2024-03-27 15:34:24 -07:00
c15c2e7b44 Remove redundant static assert
Closes #14
2024-03-27 12:41:45 -07:00
11 changed files with 173 additions and 162 deletions

View File

@@ -34,7 +34,7 @@ ConflictSet::ReadRange singleton(Arena &arena, std::span<const uint8_t> key) {
std::span<uint8_t>(new (arena) uint8_t[key.size() + 1], key.size() + 1); std::span<uint8_t>(new (arena) uint8_t[key.size() + 1], key.size() + 1);
memcpy(r.data(), key.data(), key.size()); memcpy(r.data(), key.data(), key.size());
r[key.size()] = 0; r[key.size()] = 0;
return {key.data(), int(key.size()), r.data(), int(r.size())}; return {{key.data(), int(key.size())}, {r.data(), int(r.size())}, 0};
} }
ConflictSet::ReadRange prefixRange(Arena &arena, std::span<const uint8_t> key) { ConflictSet::ReadRange prefixRange(Arena &arena, std::span<const uint8_t> key) {
@@ -52,7 +52,7 @@ ConflictSet::ReadRange prefixRange(Arena &arena, std::span<const uint8_t> key) {
auto r = std::span<uint8_t>(new (arena) uint8_t[index + 1], index + 1); auto r = std::span<uint8_t>(new (arena) uint8_t[index + 1], index + 1);
memcpy(r.data(), key.data(), index + 1); memcpy(r.data(), key.data(), index + 1);
r[r.size() - 1]++; r[r.size() - 1]++;
return {key.data(), int(key.size()), r.data(), int(r.size())}; return {{key.data(), int(key.size())}, {r.data(), int(r.size())}, 0};
} }
void benchConflictSet() { void benchConflictSet() {

View File

@@ -25,6 +25,9 @@ endif()
add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum
-Werror=switch-enum) -Werror=switch-enum)
option(USE_SIMD_FALLBACK
"Use fallback implementations of functions that use SIMD" OFF)
# This is encouraged according to # This is encouraged according to
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq # https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/valgrind) include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/valgrind)
@@ -43,18 +46,20 @@ endif()
include(CheckIncludeFileCXX) include(CheckIncludeFileCXX)
include(CMakePushCheckState) include(CMakePushCheckState)
cmake_push_check_state() if(NOT USE_SIMD_FALLBACK)
list(APPEND CMAKE_REQUIRED_FLAGS -mavx) cmake_push_check_state()
check_include_file_cxx("immintrin.h" HAS_AVX) list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
if(HAS_AVX) check_include_file_cxx("immintrin.h" HAS_AVX)
add_compile_options(-mavx) if(HAS_AVX)
add_compile_definitions(HAS_AVX) add_compile_options(-mavx)
endif() add_compile_definitions(HAS_AVX)
cmake_pop_check_state() endif()
cmake_pop_check_state()
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON) check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
if(HAS_ARM_NEON) if(HAS_ARM_NEON)
add_compile_definitions(HAS_ARM_NEON) add_compile_definitions(HAS_ARM_NEON)
endif()
endif() endif()
set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "") set(CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "")
@@ -267,6 +272,10 @@ set(CPACK_RESOURCE_FILE_README "${CMAKE_CURRENT_SOURCE_DIR}/README.md")
set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR}) set(CPACK_RPM_PACKAGE_ARCHITECTURE ${CMAKE_SYSTEM_PROCESSOR})
set(CPACK_RPM_SPEC_INSTALL_POST "/bin/true") # avoid stripping set(CPACK_RPM_SPEC_INSTALL_POST "/bin/true") # avoid stripping
set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0") set(CPACK_RPM_PACKAGE_LICENSE "Apache 2.0")
set(CPACK_RPM_FILE_NAME RPM-DEFAULT)
# deb
set(CPACK_DEBIAN_FILE_NAME DEB-DEFAULT)
include(CPack) include(CPack)

View File

@@ -29,6 +29,7 @@ limitations under the License.
#include <span> #include <span>
#include <string> #include <string>
#include <string_view> #include <string_view>
#include <type_traits>
#include <utility> #include <utility>
#ifdef HAS_AVX #ifdef HAS_AVX
@@ -39,6 +40,8 @@ limitations under the License.
#include <memcheck.h> #include <memcheck.h>
using namespace weaselab;
// Use assert for checking potentially complex properties during tests. // Use assert for checking potentially complex properties during tests.
// Use assume to hint simple properties to the optimizer. // Use assume to hint simple properties to the optimizer.
@@ -558,7 +561,6 @@ template <class T> struct BoundedFreeListAllocator {
} }
void release(T *p) { void release(T *p) {
static_assert(std::is_trivially_destructible_v<T>);
if (freeListBytes >= kFreeListMaxMemory) { if (freeListBytes >= kFreeListMaxMemory) {
removeNode(p); removeNode(p);
return safe_free(p, sizeof(T) + p->partialKeyCapacity); return safe_free(p, sizeof(T) + p->partialKeyCapacity);
@@ -953,6 +955,42 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
assert(self->getType() == Type_Node16); assert(self->getType() == Type_Node16);
++self->numChildren; ++self->numChildren;
#ifdef HAS_AVX
__m128i key_vec = _mm_set1_epi8(index);
__m128i indices;
memcpy(&indices, self16->index, sizeof(self16->index));
__m128i results = _mm_cmpeq_epi8(key_vec, _mm_min_epu8(key_vec, indices));
int mask = (1 << (self->numChildren - 1)) - 1;
uint32_t bitfield = _mm_movemask_epi8(results) & mask;
bitfield |= uint32_t(1) << (self->numChildren - 1);
int i = std::countr_zero(bitfield);
if (i < self->numChildren - 1) {
memmove(self16->index + i + 1, self16->index + i,
self->numChildren - (i + 1));
memmove(self16->children + i + 1, self16->children + i,
(self->numChildren - (i + 1)) * sizeof(Child));
}
#elif defined(HAS_ARM_NEON)
uint8x16_t indices;
memcpy(&indices, self16->index, sizeof(self16->index));
// 0xff for each leq
auto results = vcleq_u8(vdupq_n_u8(index), indices);
uint64_t mask = (uint64_t(1) << ((self->numChildren - 1) * 4)) - 1;
// 0xf for each 0xff (within mask)
uint64_t bitfield =
vget_lane_u64(
vreinterpret_u64_u8(vshrn_n_u16(vreinterpretq_u16_u8(results), 4)),
0) &
mask;
bitfield |= uint64_t(0xf) << ((self->numChildren - 1) * 4);
int i = std::countr_zero(bitfield) / 4;
if (i < self->numChildren - 1) {
memmove(self16->index + i + 1, self16->index + i,
self->numChildren - (i + 1));
memmove(self16->children + i + 1, self16->children + i,
(self->numChildren - (i + 1)) * sizeof(Child));
}
#else
int i = 0; int i = 0;
for (; i < int(self->numChildren) - 1; ++i) { for (; i < int(self->numChildren) - 1; ++i) {
if (int(self16->index[i]) > int(index)) { if (int(self16->index[i]) > int(index)) {
@@ -963,6 +1001,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
break; break;
} }
} }
#endif
self16->index[i] = index; self16->index[i] = index;
auto &result = self16->children[i].child; auto &result = self16->children[i].child;
result = nullptr; result = nullptr;
@@ -978,8 +1017,8 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
self = newSelf; self = newSelf;
goto insert256; goto insert256;
} }
insert48:
insert48:
auto *self48 = static_cast<Node48 *>(self); auto *self48 = static_cast<Node48 *>(self);
self48->bitSet.set(index); self48->bitSet.set(index);
++self->numChildren; ++self->numChildren;
@@ -991,6 +1030,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
return result; return result;
} }
case Type_Node256: { case Type_Node256: {
insert256: insert256:
auto *self256 = static_cast<Node256 *>(self); auto *self256 = static_cast<Node256 *>(self);
++self->numChildren; ++self->numChildren;
@@ -2857,8 +2897,8 @@ Iterator firstGeq(Node *n, std::string_view key) {
} }
} }
bool checkCorrectness(Node *node, int64_t oldestVersion, [[maybe_unused]] bool checkCorrectness(Node *node, int64_t oldestVersion,
ConflictSet::Impl *impl) { ConflictSet::Impl *impl) {
bool success = true; bool success = true;
checkParentPointers(node, success); checkParentPointers(node, success);

View File

@@ -2,6 +2,8 @@
#include "ConflictSet.h" #include "ConflictSet.h"
using namespace weaselab;
#include <bit> #include <bit>
#include <cassert> #include <cassert>
#include <compare> #include <compare>
@@ -60,6 +62,10 @@ inline int64_t peakMallocBytes = 0;
inline thread_local int64_t mallocBytesDelta = 0; inline thread_local int64_t mallocBytesDelta = 0;
#ifndef NDEBUG
constexpr auto kMallocHeaderSize = 16;
#endif
// malloc that aborts on OOM and thus always returns a non-null pointer. Must be // malloc that aborts on OOM and thus always returns a non-null pointer. Must be
// paired with `safe_free`. // paired with `safe_free`.
__attribute__((always_inline)) inline void *safe_malloc(size_t s) { __attribute__((always_inline)) inline void *safe_malloc(size_t s) {
@@ -69,18 +75,20 @@ __attribute__((always_inline)) inline void *safe_malloc(size_t s) {
if (mallocBytes > peakMallocBytes) { if (mallocBytes > peakMallocBytes) {
peakMallocBytes = mallocBytes; peakMallocBytes = mallocBytes;
} }
void *p = malloc(s);
if (p == nullptr) {
abort();
}
return p;
#else
void *p = malloc(s);
if (p == nullptr) {
abort();
}
return p;
#endif #endif
void *p = malloc(s
#ifndef NDEBUG
+ kMallocHeaderSize
#endif
);
if (p == nullptr) {
abort();
}
#ifndef NDEBUG
memcpy(p, &s, sizeof(s));
(char *&)p += kMallocHeaderSize;
#endif
return p;
} }
// Must be paired with `safe_malloc`. // Must be paired with `safe_malloc`.
@@ -93,6 +101,12 @@ __attribute__((always_inline)) inline void safe_free(void *p, size_t s) {
mallocBytes -= s; mallocBytes -= s;
free(p); free(p);
#else #else
#ifndef NDEBUG
(char *&)p -= kMallocHeaderSize;
size_t expected;
memcpy(&expected, p, sizeof(expected));
assert(s == expected);
#endif
free(p); free(p);
#endif #endif
} }

11
Jenkinsfile vendored
View File

@@ -48,6 +48,17 @@ pipeline {
recordIssues(tools: [clang()]) recordIssues(tools: [clang()])
} }
} }
stage('SIMD fallback') {
agent {
dockerfile {
args '-v /home/jenkins/ccache:/ccache'
reuseNode true
}
}
steps {
CleanBuildAndTest("-DUSE_SIMD_FALLBACK=ON")
}
}
stage('Release [gcc]') { stage('Release [gcc]') {
agent { agent {
dockerfile { dockerfile {

View File

@@ -9,23 +9,23 @@ Hardware for all benchmarks is a mac m1 2020.
## Skip list ## Skip list
``` ```
New conflict set: 1.962 sec New conflict set: 1.957 sec
0.637 Mtransactions/sec 0.639 Mtransactions/sec
2.548 Mkeys/sec 2.555 Mkeys/sec
Detect only: 1.842 sec Detect only: 1.845 sec
0.679 Mtransactions/sec 0.678 Mtransactions/sec
2.714 Mkeys/sec 2.710 Mkeys/sec
Skiplist only: 1.261 sec Skiplist only: 1.263 sec
0.991 Mtransactions/sec 0.990 Mtransactions/sec
3.964 Mkeys/sec 3.960 Mkeys/sec
Performance counters: Performance counters:
Build: 0.0597 Build: 0.0546
Add: 0.0587 Add: 0.0563
Detect: 1.84 Detect: 1.84
D.Sort: 0.411 D.Sort: 0.412
D.Combine: 0.0136 D.Combine: 0.0141
D.CheckRead: 0.67 D.CheckRead: 0.671
D.CheckIntraBatch: 0.00671 D.CheckIntraBatch: 0.0068
D.MergeWrite: 0.592 D.MergeWrite: 0.592
D.RemoveBefore: 0.146 D.RemoveBefore: 0.146
``` ```
@@ -33,25 +33,25 @@ Performance counters:
## Radix tree (this implementation) ## Radix tree (this implementation)
``` ```
New conflict set: 1.285 sec New conflict set: 1.366 sec
0.973 Mtransactions/sec 0.915 Mtransactions/sec
3.892 Mkeys/sec 3.660 Mkeys/sec
Detect only: 1.196 sec Detect only: 1.248 sec
1.045 Mtransactions/sec 1.002 Mtransactions/sec
4.180 Mkeys/sec 4.007 Mkeys/sec
Skiplist only: 0.539 sec Skiplist only: 0.573 sec
2.320 Mtransactions/sec 2.182 Mtransactions/sec
9.281 Mkeys/sec 8.730 Mkeys/sec
Performance counters: Performance counters:
Build: 0.0377 Build: 0.0594
Add: 0.0493 Add: 0.0572
Detect: 1.2 Detect: 1.25
D.Sort: 0.41 D.Sort: 0.418
D.Combine: 0.0135 D.Combine: 0.0149
D.CheckRead: 0.219 D.CheckRead: 0.232
D.CheckIntraBatch: 0.00654 D.CheckIntraBatch: 0.0067
D.MergeWrite: 0.319 D.MergeWrite: 0.341
D.RemoveBefore: 0.224 D.RemoveBefore: 0.232
``` ```
# Our benchmark # Our benchmark

View File

@@ -8,6 +8,8 @@
#include <unistd.h> #include <unistd.h>
#include <vector> #include <vector>
using namespace weaselab;
double now() { double now() {
return std::chrono::duration_cast<std::chrono::nanoseconds>( return std::chrono::duration_cast<std::chrono::nanoseconds>(
std::chrono::steady_clock::now().time_since_epoch()) std::chrono::steady_clock::now().time_since_epoch())
@@ -28,7 +30,7 @@ constexpr inline size_t rightAlign(size_t offset, size_t alignment) {
int main(int argc, const char **argv) { int main(int argc, const char **argv) {
// Use with this dataset https://snap.stanford.edu/data/memetracker9.html // Use with this dataset https://snap.stanford.edu/data/memetracker9.html
// Preprocess the files with `sed -i '' '/^Q/d'` // Preprocess the files with `sed -i'' '/^Q/d'`
double checkTime = 0; double checkTime = 0;
double addTime = 0; double addTime = 0;

View File

@@ -2,6 +2,8 @@
#include <cassert> #include <cassert>
using namespace weaselab;
int main(void) { int main(void) {
ConflictSet cs(0); ConflictSet cs(0);
ConflictSet::WriteRange w; ConflictSet::WriteRange w;

View File

@@ -1,32 +1,19 @@
giff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt diff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
index 3f353c2ef..cd0834761 100644 index 3f353c2ef..074a18628 100644
--- a/fdbserver/CMakeLists.txt --- a/fdbserver/CMakeLists.txt
+++ b/fdbserver/CMakeLists.txt +++ b/fdbserver/CMakeLists.txt
@@ -22,6 +22,9 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/workloads) @@ -22,6 +22,9 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/workloads)
add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS}) add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS})
+find_package(ConflictSet) +find_package(conflict-set)
+target_link_libraries(fdbserver PRIVATE conflict_set_static) +target_link_libraries(fdbserver PRIVATE conflict-set-static)
+ +
if (WITH_SWIFT) if (WITH_SWIFT)
# Setup the Swift sources in FDBServer. # Setup the Swift sources in FDBServer.
include(FindSwiftLibs) include(FindSwiftLibs)
diff --git a/fdbserver/Resolver.actor.cpp b/fdbserver/Resolver.actor.cpp
index bf4118f5f..d3b4eaad8 100644
--- a/fdbserver/Resolver.actor.cpp
+++ b/fdbserver/Resolver.actor.cpp
@@ -132,7 +132,7 @@ struct Resolver : ReferenceCounted<Resolver> {
AsyncVar<int64_t> totalStateBytes;
AsyncTrigger checkNeededVersion;
std::map<NetworkAddress, ProxyRequestsInfo> proxyInfoMap;
- ConflictSet* conflictSet;
+ ConflictSet2* conflictSet;
TransientStorageMetricSample iopsSample;
// Use LogSystem as backend for txnStateStore. However, the real commit
diff --git a/fdbserver/SkipList.cpp b/fdbserver/SkipList.cpp diff --git a/fdbserver/SkipList.cpp b/fdbserver/SkipList.cpp
index b48d32c6b..da106b5d2 100644 index b48d32c6b..da99e03aa 100644
--- a/fdbserver/SkipList.cpp --- a/fdbserver/SkipList.cpp
+++ b/fdbserver/SkipList.cpp +++ b/fdbserver/SkipList.cpp
@@ -25,6 +25,7 @@ @@ -25,6 +25,7 @@
@@ -46,50 +33,35 @@ index b48d32c6b..da106b5d2 100644
static std::vector<PerfDoubleCounter*> skc; static std::vector<PerfDoubleCounter*> skc;
static thread_local uint32_t g_seed = 0; static thread_local uint32_t g_seed = 0;
@@ -782,26 +785,34 @@ private: @@ -783,10 +786,14 @@ private:
}
}; };
-struct ConflictSet { struct ConflictSet {
- ConflictSet() : removalKey(makeString(0)), oldestVersion(0) {} - ConflictSet() : removalKey(makeString(0)), oldestVersion(0) {}
- ~ConflictSet() {} + ConflictSet() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
+struct ConflictSet2 { ~ConflictSet() {}
+ ConflictSet2() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
+ ~ConflictSet2() {}
+#if USE_RADIX_TREE +#if USE_RADIX_TREE
+ ConflictSet versionHistory; + weaselab::ConflictSet versionHistory;
+#else +#else
SkipList versionHistory; SkipList versionHistory;
+#endif +#endif
Key removalKey; Key removalKey;
Version oldestVersion; Version oldestVersion;
}; };
@@ -795,7 +802,11 @@ ConflictSet* newConflictSet() {
-ConflictSet* newConflictSet() { return new ConflictSet;
- return new ConflictSet;
+ConflictSet2* newConflictSet() {
+ return new ConflictSet2;
} }
-void clearConflictSet(ConflictSet* cs, Version v) { void clearConflictSet(ConflictSet* cs, Version v) {
- SkipList(v).swap(cs->versionHistory); - SkipList(v).swap(cs->versionHistory);
+void clearConflictSet(ConflictSet2* cs, Version v) {
+#if USE_RADIX_TREE +#if USE_RADIX_TREE
+ cs->versionHistory = ConflictSet{ 0 }; + cs->versionHistory = weaselab::ConflictSet{ 0 };
+#else +#else
+ SkipList().swap(cs->versionHistory); + SkipList().swap(cs->versionHistory);
+#endif +#endif
} }
-void destroyConflictSet(ConflictSet* cs) { void destroyConflictSet(ConflictSet* cs) {
+void destroyConflictSet(ConflictSet2* cs) {
delete cs; delete cs;
}
-ConflictBatch::ConflictBatch(ConflictSet* cs,
+ConflictBatch::ConflictBatch(ConflictSet2* cs,
std::map<int, VectorRef<int>>* conflictingKeyRangeMap,
Arena* resolveBatchReplyArena)
: cs(cs), transactionCount(0), conflictingKeyRangeMap(conflictingKeyRangeMap),
@@ -971,11 +982,15 @@ void ConflictBatch::detectConflicts(Version now, @@ -971,11 +982,15 @@ void ConflictBatch::detectConflicts(Version now,
t = timer(); t = timer();
if (newOldestVersion > cs->oldestVersion) { if (newOldestVersion > cs->oldestVersion) {
@@ -112,7 +84,7 @@ index b48d32c6b..da106b5d2 100644
+#if USE_RADIX_TREE +#if USE_RADIX_TREE
+ Arena arena; + Arena arena;
+ auto* reads = new (arena) ConflictSet::ReadRange[combinedReadConflictRanges.size()]; + auto* reads = new (arena) weaselab::ConflictSet::ReadRange[combinedReadConflictRanges.size()];
+ +
+ for (int i = 0; i < combinedReadConflictRanges.size(); ++i) { + for (int i = 0; i < combinedReadConflictRanges.size(); ++i) {
+ auto& read = reads[i]; + auto& read = reads[i];
@@ -122,11 +94,11 @@ index b48d32c6b..da106b5d2 100644
+ read.end.p = combinedReadConflictRanges[i].end.begin(); + read.end.p = combinedReadConflictRanges[i].end.begin();
+ read.end.len = combinedReadConflictRanges[i].end.size(); + read.end.len = combinedReadConflictRanges[i].end.size();
+ } + }
+ auto* results = new (arena) ConflictSet::Result[combinedReadConflictRanges.size()]; + auto* results = new (arena) weaselab::ConflictSet::Result[combinedReadConflictRanges.size()];
+ cs->versionHistory.check(reads, results, combinedReadConflictRanges.size()); + cs->versionHistory.check(reads, results, combinedReadConflictRanges.size());
+ +
+ for (int i = 0; i < combinedReadConflictRanges.size(); ++i) { + for (int i = 0; i < combinedReadConflictRanges.size(); ++i) {
+ if (results[i] == ConflictSet::Conflict) { + if (results[i] == weaselab::ConflictSet::Conflict) {
+ transactionConflictStatus[combinedReadConflictRanges[i].transaction] = true; + transactionConflictStatus[combinedReadConflictRanges[i].transaction] = true;
+ if (combinedReadConflictRanges[i].conflictingKeyRange != nullptr) { + if (combinedReadConflictRanges[i].conflictingKeyRange != nullptr) {
+ combinedReadConflictRanges[i].conflictingKeyRange->push_back(*combinedReadConflictRanges[i].cKRArena, + combinedReadConflictRanges[i].conflictingKeyRange->push_back(*combinedReadConflictRanges[i].cKRArena,
@@ -147,7 +119,7 @@ index b48d32c6b..da106b5d2 100644
+#if USE_RADIX_TREE +#if USE_RADIX_TREE
+ Arena arena; + Arena arena;
+ auto* writes = new (arena) ConflictSet::WriteRange[combinedWriteConflictRanges.size()]; + auto* writes = new (arena) weaselab::ConflictSet::WriteRange[combinedWriteConflictRanges.size()];
+ +
+ for (int i = 0; i < combinedWriteConflictRanges.size(); ++i) { + for (int i = 0; i < combinedWriteConflictRanges.size(); ++i) {
+ auto& write = writes[i]; + auto& write = writes[i];
@@ -164,15 +136,6 @@ index b48d32c6b..da106b5d2 100644
} }
void ConflictBatch::combineWriteConflictRanges() { void ConflictBatch::combineWriteConflictRanges() {
@@ -1115,7 +1171,7 @@ void skipListTest() {
double start;
- ConflictSet* cs = newConflictSet();
+ ConflictSet2* cs = newConflictSet();
Arena testDataArena;
VectorRef<VectorRef<KeyRangeRef>> testData;
@@ -1197,6 +1253,4 @@ void skipListTest() { @@ -1197,6 +1253,4 @@ void skipListTest() {
for (const auto& counter : skc) { for (const auto& counter : skc) {
printf("%20s: %s\n", counter->getMetric().name().c_str(), counter->getMetric().formatted().c_str()); printf("%20s: %s\n", counter->getMetric().name().c_str(), counter->getMetric().formatted().c_str());
@@ -180,35 +143,3 @@ index b48d32c6b..da106b5d2 100644
- -
- printf("%d entries in version history\n", cs->versionHistory.count()); - printf("%d entries in version history\n", cs->versionHistory.count());
} }
diff --git a/fdbserver/include/fdbserver/ConflictSet.h b/fdbserver/include/fdbserver/ConflictSet.h
index 90ed2c406..b7e31217c 100644
--- a/fdbserver/include/fdbserver/ConflictSet.h
+++ b/fdbserver/include/fdbserver/ConflictSet.h
@@ -28,13 +28,13 @@
#include "fdbclient/CommitTransaction.h"
#include "fdbserver/ResolverBug.h"
-struct ConflictSet;
-ConflictSet* newConflictSet();
-void clearConflictSet(ConflictSet*, Version);
-void destroyConflictSet(ConflictSet*);
+struct ConflictSet2;
+ConflictSet2* newConflictSet();
+void clearConflictSet(ConflictSet2*, Version);
+void destroyConflictSet(ConflictSet2*);
struct ConflictBatch {
- explicit ConflictBatch(ConflictSet*,
+ explicit ConflictBatch(ConflictSet2*,
std::map<int, VectorRef<int>>* conflictingKeyRangeMap = nullptr,
Arena* resolveBatchReplyArena = nullptr);
~ConflictBatch();
@@ -54,7 +54,7 @@ struct ConflictBatch {
void GetTooOldTransactions(std::vector<int>& tooOldTransactions);
private:
- ConflictSet* cs;
+ ConflictSet2* cs;
Standalone<VectorRef<struct TransactionInfo*>> transactionInfo;
std::vector<struct KeyInfo> points;
int transactionCount;

View File

@@ -19,6 +19,7 @@ limitations under the License.
#include <stdint.h> #include <stdint.h>
#ifdef __cplusplus #ifdef __cplusplus
namespace weaselab {
/** A data structure for optimistic concurrency control on ranges of /** A data structure for optimistic concurrency control on ranges of
* bitwise-lexicographically-ordered keys. * bitwise-lexicographically-ordered keys.
* *
@@ -100,6 +101,7 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
private: private:
Impl *impl; Impl *impl;
}; };
} /* namespace weaselab */
#else #else

View File

@@ -4,14 +4,14 @@ ConflictSet_create
ConflictSet_destroy ConflictSet_destroy
ConflictSet_getBytes ConflictSet_getBytes
ConflictSet_setOldestVersion ConflictSet_setOldestVersion
_ZN11ConflictSet16setOldestVersionEl _ZN8weaselab11ConflictSet16setOldestVersionEl
_ZN11ConflictSet9addWritesEPKNS_10WriteRangeEil _ZN8weaselab11ConflictSet9addWritesEPKNS0_10WriteRangeEil
_ZN11ConflictSetaSEOS_ _ZN8weaselab11ConflictSetaSEOS0_
_ZN11ConflictSetC1El _ZN8weaselab11ConflictSetC1El
_ZN11ConflictSetC1EOS_ _ZN8weaselab11ConflictSetC1EOS0_
_ZN11ConflictSetC2El _ZN8weaselab11ConflictSetC2El
_ZN11ConflictSetC2EOS_ _ZN8weaselab11ConflictSetC2EOS0_
_ZN11ConflictSetD1Ev _ZN8weaselab11ConflictSetD1Ev
_ZN11ConflictSetD2Ev _ZN8weaselab11ConflictSetD2Ev
_ZNK11ConflictSet5checkEPKNS_9ReadRangeEPNS_6ResultEi _ZNK8weaselab11ConflictSet5checkEPKNS0_9ReadRangeEPNS0_6ResultEi
_ZNK11ConflictSet8getBytesEv _ZNK8weaselab11ConflictSet8getBytesEv