Compare commits
13 Commits
a4d1f91670
...
v0.0.1
Author | SHA1 | Date | |
---|---|---|---|
71c39f9955 | |||
8cc17158fd | |||
ab211c646a | |||
7af961f141 | |||
a91df62608 | |||
0a1843a161 | |||
4edf0315d9 | |||
14515e186a | |||
b0085df5ad | |||
76a7e17b29 | |||
5cf43d1bfa | |||
25cc427ec5 | |||
c15c2e7b44 |
@@ -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);
|
||||
memcpy(r.data(), key.data(), key.size());
|
||||
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) {
|
||||
@@ -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);
|
||||
memcpy(r.data(), key.data(), index + 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() {
|
||||
@@ -258,4 +258,4 @@ void benchConflictSet() {
|
||||
}
|
||||
}
|
||||
|
||||
int main(void) { benchConflictSet(); }
|
||||
int main(void) { benchConflictSet(); }
|
||||
|
@@ -25,6 +25,9 @@ endif()
|
||||
add_compile_options(-fdata-sections -ffunction-sections -Wswitch-enum
|
||||
-Werror=switch-enum)
|
||||
|
||||
option(USE_SIMD_FALLBACK
|
||||
"Use fallback implementations of functions that use SIMD" OFF)
|
||||
|
||||
# This is encouraged according to
|
||||
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
|
||||
include_directories(SYSTEM ${CMAKE_SOURCE_DIR}/third_party/valgrind)
|
||||
@@ -43,18 +46,20 @@ endif()
|
||||
include(CheckIncludeFileCXX)
|
||||
include(CMakePushCheckState)
|
||||
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
|
||||
check_include_file_cxx("immintrin.h" HAS_AVX)
|
||||
if(HAS_AVX)
|
||||
add_compile_options(-mavx)
|
||||
add_compile_definitions(HAS_AVX)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
if(NOT USE_SIMD_FALLBACK)
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_FLAGS -mavx)
|
||||
check_include_file_cxx("immintrin.h" HAS_AVX)
|
||||
if(HAS_AVX)
|
||||
add_compile_options(-mavx)
|
||||
add_compile_definitions(HAS_AVX)
|
||||
endif()
|
||||
cmake_pop_check_state()
|
||||
|
||||
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
|
||||
if(HAS_ARM_NEON)
|
||||
add_compile_definitions(HAS_ARM_NEON)
|
||||
check_include_file_cxx("arm_neon.h" HAS_ARM_NEON)
|
||||
if(HAS_ARM_NEON)
|
||||
add_compile_definitions(HAS_ARM_NEON)
|
||||
endif()
|
||||
endif()
|
||||
|
||||
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_SPEC_INSTALL_POST "/bin/true") # avoid stripping
|
||||
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)
|
||||
|
||||
|
@@ -29,6 +29,7 @@ limitations under the License.
|
||||
#include <span>
|
||||
#include <string>
|
||||
#include <string_view>
|
||||
#include <type_traits>
|
||||
#include <utility>
|
||||
|
||||
#ifdef HAS_AVX
|
||||
@@ -39,6 +40,8 @@ limitations under the License.
|
||||
|
||||
#include <memcheck.h>
|
||||
|
||||
using namespace weaselab;
|
||||
|
||||
// Use assert for checking potentially complex properties during tests.
|
||||
// Use assume to hint simple properties to the optimizer.
|
||||
|
||||
@@ -558,7 +561,6 @@ template <class T> struct BoundedFreeListAllocator {
|
||||
}
|
||||
|
||||
void release(T *p) {
|
||||
static_assert(std::is_trivially_destructible_v<T>);
|
||||
if (freeListBytes >= kFreeListMaxMemory) {
|
||||
removeNode(p);
|
||||
return safe_free(p, sizeof(T) + p->partialKeyCapacity);
|
||||
@@ -953,6 +955,42 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
|
||||
assert(self->getType() == Type_Node16);
|
||||
|
||||
++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;
|
||||
for (; i < int(self->numChildren) - 1; ++i) {
|
||||
if (int(self16->index[i]) > int(index)) {
|
||||
@@ -963,6 +1001,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
self16->index[i] = index;
|
||||
auto &result = self16->children[i].child;
|
||||
result = nullptr;
|
||||
@@ -978,8 +1017,8 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
|
||||
self = newSelf;
|
||||
goto insert256;
|
||||
}
|
||||
insert48:
|
||||
|
||||
insert48:
|
||||
auto *self48 = static_cast<Node48 *>(self);
|
||||
self48->bitSet.set(index);
|
||||
++self->numChildren;
|
||||
@@ -991,6 +1030,7 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
|
||||
return result;
|
||||
}
|
||||
case Type_Node256: {
|
||||
|
||||
insert256:
|
||||
auto *self256 = static_cast<Node256 *>(self);
|
||||
++self->numChildren;
|
||||
@@ -2857,8 +2897,8 @@ Iterator firstGeq(Node *n, std::string_view key) {
|
||||
}
|
||||
}
|
||||
|
||||
bool checkCorrectness(Node *node, int64_t oldestVersion,
|
||||
ConflictSet::Impl *impl) {
|
||||
[[maybe_unused]] bool checkCorrectness(Node *node, int64_t oldestVersion,
|
||||
ConflictSet::Impl *impl) {
|
||||
bool success = true;
|
||||
|
||||
checkParentPointers(node, success);
|
||||
|
36
Internal.h
36
Internal.h
@@ -2,6 +2,8 @@
|
||||
|
||||
#include "ConflictSet.h"
|
||||
|
||||
using namespace weaselab;
|
||||
|
||||
#include <bit>
|
||||
#include <cassert>
|
||||
#include <compare>
|
||||
@@ -60,6 +62,10 @@ inline int64_t peakMallocBytes = 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
|
||||
// paired with `safe_free`.
|
||||
__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) {
|
||||
peakMallocBytes = mallocBytes;
|
||||
}
|
||||
void *p = malloc(s);
|
||||
if (p == nullptr) {
|
||||
abort();
|
||||
}
|
||||
return p;
|
||||
#else
|
||||
void *p = malloc(s);
|
||||
if (p == nullptr) {
|
||||
abort();
|
||||
}
|
||||
return p;
|
||||
#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`.
|
||||
@@ -93,6 +101,12 @@ __attribute__((always_inline)) inline void safe_free(void *p, size_t s) {
|
||||
mallocBytes -= s;
|
||||
free(p);
|
||||
#else
|
||||
#ifndef NDEBUG
|
||||
(char *&)p -= kMallocHeaderSize;
|
||||
size_t expected;
|
||||
memcpy(&expected, p, sizeof(expected));
|
||||
assert(s == expected);
|
||||
#endif
|
||||
free(p);
|
||||
#endif
|
||||
}
|
||||
|
11
Jenkinsfile
vendored
11
Jenkinsfile
vendored
@@ -48,6 +48,17 @@ pipeline {
|
||||
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]') {
|
||||
agent {
|
||||
dockerfile {
|
||||
|
66
README.md
66
README.md
@@ -9,23 +9,23 @@ Hardware for all benchmarks is a mac m1 2020.
|
||||
## Skip list
|
||||
|
||||
```
|
||||
New conflict set: 1.962 sec
|
||||
0.637 Mtransactions/sec
|
||||
2.548 Mkeys/sec
|
||||
Detect only: 1.842 sec
|
||||
0.679 Mtransactions/sec
|
||||
2.714 Mkeys/sec
|
||||
Skiplist only: 1.261 sec
|
||||
0.991 Mtransactions/sec
|
||||
3.964 Mkeys/sec
|
||||
New conflict set: 1.957 sec
|
||||
0.639 Mtransactions/sec
|
||||
2.555 Mkeys/sec
|
||||
Detect only: 1.845 sec
|
||||
0.678 Mtransactions/sec
|
||||
2.710 Mkeys/sec
|
||||
Skiplist only: 1.263 sec
|
||||
0.990 Mtransactions/sec
|
||||
3.960 Mkeys/sec
|
||||
Performance counters:
|
||||
Build: 0.0597
|
||||
Add: 0.0587
|
||||
Build: 0.0546
|
||||
Add: 0.0563
|
||||
Detect: 1.84
|
||||
D.Sort: 0.411
|
||||
D.Combine: 0.0136
|
||||
D.CheckRead: 0.67
|
||||
D.CheckIntraBatch: 0.00671
|
||||
D.Sort: 0.412
|
||||
D.Combine: 0.0141
|
||||
D.CheckRead: 0.671
|
||||
D.CheckIntraBatch: 0.0068
|
||||
D.MergeWrite: 0.592
|
||||
D.RemoveBefore: 0.146
|
||||
```
|
||||
@@ -33,25 +33,25 @@ Performance counters:
|
||||
## Radix tree (this implementation)
|
||||
|
||||
```
|
||||
New conflict set: 1.285 sec
|
||||
0.973 Mtransactions/sec
|
||||
3.892 Mkeys/sec
|
||||
Detect only: 1.196 sec
|
||||
1.045 Mtransactions/sec
|
||||
4.180 Mkeys/sec
|
||||
Skiplist only: 0.539 sec
|
||||
2.320 Mtransactions/sec
|
||||
9.281 Mkeys/sec
|
||||
New conflict set: 1.366 sec
|
||||
0.915 Mtransactions/sec
|
||||
3.660 Mkeys/sec
|
||||
Detect only: 1.248 sec
|
||||
1.002 Mtransactions/sec
|
||||
4.007 Mkeys/sec
|
||||
Skiplist only: 0.573 sec
|
||||
2.182 Mtransactions/sec
|
||||
8.730 Mkeys/sec
|
||||
Performance counters:
|
||||
Build: 0.0377
|
||||
Add: 0.0493
|
||||
Detect: 1.2
|
||||
D.Sort: 0.41
|
||||
D.Combine: 0.0135
|
||||
D.CheckRead: 0.219
|
||||
D.CheckIntraBatch: 0.00654
|
||||
D.MergeWrite: 0.319
|
||||
D.RemoveBefore: 0.224
|
||||
Build: 0.0594
|
||||
Add: 0.0572
|
||||
Detect: 1.25
|
||||
D.Sort: 0.418
|
||||
D.Combine: 0.0149
|
||||
D.CheckRead: 0.232
|
||||
D.CheckIntraBatch: 0.0067
|
||||
D.MergeWrite: 0.341
|
||||
D.RemoveBefore: 0.232
|
||||
```
|
||||
|
||||
# Our benchmark
|
||||
|
@@ -8,6 +8,8 @@
|
||||
#include <unistd.h>
|
||||
#include <vector>
|
||||
|
||||
using namespace weaselab;
|
||||
|
||||
double now() {
|
||||
return std::chrono::duration_cast<std::chrono::nanoseconds>(
|
||||
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) {
|
||||
// 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 addTime = 0;
|
||||
|
@@ -2,6 +2,8 @@
|
||||
|
||||
#include <cassert>
|
||||
|
||||
using namespace weaselab;
|
||||
|
||||
int main(void) {
|
||||
ConflictSet cs(0);
|
||||
ConflictSet::WriteRange w;
|
||||
|
107
fdb-patch.txt
107
fdb-patch.txt
@@ -1,32 +1,19 @@
|
||||
giff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
|
||||
index 3f353c2ef..cd0834761 100644
|
||||
diff --git a/fdbserver/CMakeLists.txt b/fdbserver/CMakeLists.txt
|
||||
index 3f353c2ef..074a18628 100644
|
||||
--- a/fdbserver/CMakeLists.txt
|
||||
+++ b/fdbserver/CMakeLists.txt
|
||||
@@ -22,6 +22,9 @@ file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/workloads)
|
||||
|
||||
add_flow_target(EXECUTABLE NAME fdbserver SRCS ${FDBSERVER_SRCS})
|
||||
|
||||
+find_package(ConflictSet)
|
||||
+target_link_libraries(fdbserver PRIVATE conflict_set_static)
|
||||
+find_package(conflict-set)
|
||||
+target_link_libraries(fdbserver PRIVATE conflict-set-static)
|
||||
+
|
||||
if (WITH_SWIFT)
|
||||
# Setup the Swift sources in FDBServer.
|
||||
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
|
||||
index b48d32c6b..da106b5d2 100644
|
||||
index b48d32c6b..da99e03aa 100644
|
||||
--- a/fdbserver/SkipList.cpp
|
||||
+++ b/fdbserver/SkipList.cpp
|
||||
@@ -25,6 +25,7 @@
|
||||
@@ -46,50 +33,35 @@ index b48d32c6b..da106b5d2 100644
|
||||
static std::vector<PerfDoubleCounter*> skc;
|
||||
|
||||
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() {}
|
||||
+struct ConflictSet2 {
|
||||
+ ConflictSet2() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
|
||||
+ ~ConflictSet2() {}
|
||||
+ ConflictSet() : versionHistory(0), removalKey(makeString(0)), oldestVersion(0) {}
|
||||
~ConflictSet() {}
|
||||
|
||||
+#if USE_RADIX_TREE
|
||||
+ ConflictSet versionHistory;
|
||||
+ weaselab::ConflictSet versionHistory;
|
||||
+#else
|
||||
SkipList versionHistory;
|
||||
+#endif
|
||||
Key removalKey;
|
||||
Version oldestVersion;
|
||||
};
|
||||
|
||||
-ConflictSet* newConflictSet() {
|
||||
- return new ConflictSet;
|
||||
+ConflictSet2* newConflictSet() {
|
||||
+ return new ConflictSet2;
|
||||
@@ -795,7 +802,11 @@ ConflictSet* newConflictSet() {
|
||||
return new ConflictSet;
|
||||
}
|
||||
-void clearConflictSet(ConflictSet* cs, Version v) {
|
||||
void clearConflictSet(ConflictSet* cs, Version v) {
|
||||
- SkipList(v).swap(cs->versionHistory);
|
||||
+void clearConflictSet(ConflictSet2* cs, Version v) {
|
||||
+#if USE_RADIX_TREE
|
||||
+ cs->versionHistory = ConflictSet{ 0 };
|
||||
+ cs->versionHistory = weaselab::ConflictSet{ 0 };
|
||||
+#else
|
||||
+ SkipList().swap(cs->versionHistory);
|
||||
+#endif
|
||||
}
|
||||
-void destroyConflictSet(ConflictSet* cs) {
|
||||
+void destroyConflictSet(ConflictSet2* cs) {
|
||||
void destroyConflictSet(ConflictSet* 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,
|
||||
t = timer();
|
||||
if (newOldestVersion > cs->oldestVersion) {
|
||||
@@ -112,7 +84,7 @@ index b48d32c6b..da106b5d2 100644
|
||||
|
||||
+#if USE_RADIX_TREE
|
||||
+ 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) {
|
||||
+ auto& read = reads[i];
|
||||
@@ -122,11 +94,11 @@ index b48d32c6b..da106b5d2 100644
|
||||
+ read.end.p = combinedReadConflictRanges[i].end.begin();
|
||||
+ 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());
|
||||
+
|
||||
+ for (int i = 0; i < combinedReadConflictRanges.size(); ++i) {
|
||||
+ if (results[i] == ConflictSet::Conflict) {
|
||||
+ if (results[i] == weaselab::ConflictSet::Conflict) {
|
||||
+ transactionConflictStatus[combinedReadConflictRanges[i].transaction] = true;
|
||||
+ if (combinedReadConflictRanges[i].conflictingKeyRange != nullptr) {
|
||||
+ combinedReadConflictRanges[i].conflictingKeyRange->push_back(*combinedReadConflictRanges[i].cKRArena,
|
||||
@@ -147,7 +119,7 @@ index b48d32c6b..da106b5d2 100644
|
||||
|
||||
+#if USE_RADIX_TREE
|
||||
+ 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) {
|
||||
+ auto& write = writes[i];
|
||||
@@ -164,15 +136,6 @@ index b48d32c6b..da106b5d2 100644
|
||||
}
|
||||
|
||||
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() {
|
||||
for (const auto& counter : skc) {
|
||||
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());
|
||||
}
|
||||
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;
|
||||
|
@@ -19,6 +19,7 @@ limitations under the License.
|
||||
#include <stdint.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
namespace weaselab {
|
||||
/** A data structure for optimistic concurrency control on ranges of
|
||||
* bitwise-lexicographically-ordered keys.
|
||||
*
|
||||
@@ -100,6 +101,7 @@ struct __attribute__((__visibility__("default"))) ConflictSet {
|
||||
private:
|
||||
Impl *impl;
|
||||
};
|
||||
} /* namespace weaselab */
|
||||
|
||||
#else
|
||||
|
||||
|
22
symbols.txt
22
symbols.txt
@@ -4,14 +4,14 @@ ConflictSet_create
|
||||
ConflictSet_destroy
|
||||
ConflictSet_getBytes
|
||||
ConflictSet_setOldestVersion
|
||||
_ZN11ConflictSet16setOldestVersionEl
|
||||
_ZN11ConflictSet9addWritesEPKNS_10WriteRangeEil
|
||||
_ZN11ConflictSetaSEOS_
|
||||
_ZN11ConflictSetC1El
|
||||
_ZN11ConflictSetC1EOS_
|
||||
_ZN11ConflictSetC2El
|
||||
_ZN11ConflictSetC2EOS_
|
||||
_ZN11ConflictSetD1Ev
|
||||
_ZN11ConflictSetD2Ev
|
||||
_ZNK11ConflictSet5checkEPKNS_9ReadRangeEPNS_6ResultEi
|
||||
_ZNK11ConflictSet8getBytesEv
|
||||
_ZN8weaselab11ConflictSet16setOldestVersionEl
|
||||
_ZN8weaselab11ConflictSet9addWritesEPKNS0_10WriteRangeEil
|
||||
_ZN8weaselab11ConflictSetaSEOS0_
|
||||
_ZN8weaselab11ConflictSetC1El
|
||||
_ZN8weaselab11ConflictSetC1EOS0_
|
||||
_ZN8weaselab11ConflictSetC2El
|
||||
_ZN8weaselab11ConflictSetC2EOS0_
|
||||
_ZN8weaselab11ConflictSetD1Ev
|
||||
_ZN8weaselab11ConflictSetD2Ev
|
||||
_ZNK8weaselab11ConflictSet5checkEPKNS0_9ReadRangeEPNS0_6ResultEi
|
||||
_ZNK8weaselab11ConflictSet8getBytesEv
|
||||
|
Reference in New Issue
Block a user