Compare commits
77 Commits
v0.0.6
...
88bcc7b75c
| Author | SHA1 | Date | |
|---|---|---|---|
| 88bcc7b75c | |||
| 3e6be6bd83 | |||
| e59fee39c7 | |||
| 3e2c8310bb | |||
| 8264f1342d | |||
| 5d7e9c6f85 | |||
| cdf42fcb34 | |||
| cbe40b5dba | |||
| a04e81b3ff | |||
| 0be97a34b6 | |||
| 68ab9a9f08 | |||
| 01488880ef | |||
| bb84792cff | |||
| 1f421e95ff | |||
| 66bd799f05 | |||
| 2646d5eaf1 | |||
| 0367ba9856 | |||
| 9dec45317e | |||
| a68ad5dd17 | |||
| 8e3eacb54f | |||
| 0184e1d7f6 | |||
| c52d50f4f9 | |||
| 447da11d59 | |||
| daa8e02d4f | |||
| fd3ea2c2a8 | |||
| 0b839b9d7e | |||
| 11a022dcf7 | |||
| 94da4c72a5 | |||
| 461e07822a | |||
| 75499543e7 | |||
| 81f44d352f | |||
| 45da8fb996 | |||
| 4958a4cced | |||
| 587874841f | |||
| 648b0b9238 | |||
| d3f4afa167 | |||
| f762add4d6 | |||
| b311e5f1f0 | |||
| ff81890921 | |||
| 0e96177f5c | |||
| efb0e52a0a | |||
| 2df7000090 | |||
| 5378a06c39 | |||
| 12c6ed2568 | |||
| a2bf839b19 | |||
| c065b185ae | |||
| 639518bed4 | |||
| 7de983cc15 | |||
| 1b4b61ddc6 | |||
| bff7b85de2 | |||
| 9108ee209a | |||
| f8bf1c6eb4 | |||
| 4da2a01614 | |||
| bb0e654040 | |||
| cce7d29410 | |||
| 13f8d3fa8a | |||
| 02866a8cae | |||
| fa86d3e707 | |||
| 7d1d1d7b2a | |||
| 789ecc29b3 | |||
| 08f2998a85 | |||
| c882d7663d | |||
| bfea4384ba | |||
| 6520e3d734 | |||
| 23ace8aac5 | |||
| 62e35de320 | |||
| 22e4ab01a1 | |||
| b3aeed0caa | |||
| 5f3833e965 | |||
| 8b1cd9c052 | |||
| bb9bc3d7b5 | |||
| 89b3354a80 | |||
| 488c723726 | |||
| 76d0785b33 | |||
| add0af11ad | |||
| 2c0adf4a8b | |||
| e8ac78cce6 |
@@ -258,4 +258,107 @@ void benchConflictSet() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int main(void) { benchConflictSet(); }
|
constexpr int kKeyLenForWorstCase = 50;
|
||||||
|
|
||||||
|
ConflictSet worstCaseConflictSetForRadixRangeRead(int cardinality) {
|
||||||
|
ConflictSet cs{0};
|
||||||
|
|
||||||
|
for (int i = 0; i < kKeyLenForWorstCase; ++i) {
|
||||||
|
for (int j = 0; j < cardinality; ++j) {
|
||||||
|
auto b = std::vector<uint8_t>(i, 0);
|
||||||
|
b.push_back(j);
|
||||||
|
auto e = std::vector<uint8_t>(i, 255);
|
||||||
|
e.push_back(255 - j);
|
||||||
|
weaselab::ConflictSet::WriteRange w[] = {{
|
||||||
|
{b.data(), int(b.size())},
|
||||||
|
{nullptr, 0},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{e.data(), int(e.size())},
|
||||||
|
{nullptr, 0},
|
||||||
|
}};
|
||||||
|
std::sort(std::begin(w), std::end(w),
|
||||||
|
[](const auto &lhs, const auto &rhs) {
|
||||||
|
int cl = std::min(lhs.begin.len, rhs.begin.len);
|
||||||
|
if (cl > 0) {
|
||||||
|
int c = memcmp(lhs.begin.p, rhs.begin.p, cl);
|
||||||
|
if (c != 0) {
|
||||||
|
return c < 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return lhs.begin.len < rhs.begin.len;
|
||||||
|
});
|
||||||
|
cs.addWrites(w, sizeof(w) / sizeof(w[0]), 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defeat short-circuiting on the left
|
||||||
|
{
|
||||||
|
auto k = std::vector<uint8_t>(kKeyLenForWorstCase, 0);
|
||||||
|
weaselab::ConflictSet::WriteRange w[] = {
|
||||||
|
{
|
||||||
|
{k.data(), int(k.size())},
|
||||||
|
{nullptr, 0},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cs.addWrites(w, sizeof(w) / sizeof(w[0]), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Defeat short-circuiting on the right
|
||||||
|
{
|
||||||
|
auto k = std::vector<uint8_t>(kKeyLenForWorstCase, 255);
|
||||||
|
weaselab::ConflictSet::WriteRange w[] = {
|
||||||
|
{
|
||||||
|
{k.data(), int(k.size())},
|
||||||
|
{nullptr, 0},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
cs.addWrites(w, sizeof(w) / sizeof(w[0]), 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return cs;
|
||||||
|
}
|
||||||
|
|
||||||
|
void benchWorstCaseForRadixRangeRead() {
|
||||||
|
ankerl::nanobench::Bench bench;
|
||||||
|
|
||||||
|
std::unique_ptr<ConflictSet> cs[256];
|
||||||
|
for (int i = 0; i < 256; ++i) {
|
||||||
|
cs[i] =
|
||||||
|
std::make_unique<ConflictSet>(worstCaseConflictSetForRadixRangeRead(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
auto begin = std::vector<uint8_t>(kKeyLenForWorstCase - 1, 0);
|
||||||
|
begin.push_back(1);
|
||||||
|
auto end = std::vector<uint8_t>(kKeyLenForWorstCase - 1, 255);
|
||||||
|
end.push_back(254);
|
||||||
|
|
||||||
|
weaselab::ConflictSet::Result result;
|
||||||
|
weaselab::ConflictSet::ReadRange r{
|
||||||
|
{begin.data(), int(begin.size())}, {end.data(), int(end.size())}, 0};
|
||||||
|
|
||||||
|
bench.run("worst case for radix tree", [&]() {
|
||||||
|
for (int i = 0; i < 256; ++i) {
|
||||||
|
result = weaselab::ConflictSet::TooOld;
|
||||||
|
cs[i]->check(&r, &result, 1);
|
||||||
|
if (result != weaselab::ConflictSet::Commit) {
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// for (int i = 0; i < 256; ++i) {
|
||||||
|
// bench.run("worst case for radix tree, span " + std::to_string(i), [&]() {
|
||||||
|
// result = weaselab::ConflictSet::TooOld;
|
||||||
|
// cs[i]->check(&r, &result, 1);
|
||||||
|
// if (result != weaselab::ConflictSet::Commit) {
|
||||||
|
// abort();
|
||||||
|
// }
|
||||||
|
// });
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(void) {
|
||||||
|
benchConflictSet();
|
||||||
|
benchWorstCaseForRadixRangeRead();
|
||||||
|
}
|
||||||
|
|||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
cmake_minimum_required(VERSION 3.18)
|
cmake_minimum_required(VERSION 3.18)
|
||||||
project(
|
project(
|
||||||
conflict-set
|
conflict-set
|
||||||
VERSION 0.0.6
|
VERSION 0.0.7
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
|
"A data structure for optimistic concurrency control on ranges of bitwise-lexicographically-ordered keys."
|
||||||
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
|
HOMEPAGE_URL "https://git.weaselab.dev/weaselab/conflict-set"
|
||||||
|
|||||||
+1260
-618
File diff suppressed because it is too large
Load Diff
+23
-12
@@ -467,13 +467,15 @@ inline uint32_t Arbitrary::bounded(uint32_t s) {
|
|||||||
// ==================== END ARBITRARY IMPL ====================
|
// ==================== END ARBITRARY IMPL ====================
|
||||||
|
|
||||||
struct ReferenceImpl {
|
struct ReferenceImpl {
|
||||||
explicit ReferenceImpl(int64_t oldestVersion) : oldestVersion(oldestVersion) {
|
explicit ReferenceImpl(int64_t oldestVersion)
|
||||||
|
: oldestVersion(oldestVersion), newestVersion(oldestVersion) {
|
||||||
writeVersionMap[""] = oldestVersion;
|
writeVersionMap[""] = oldestVersion;
|
||||||
}
|
}
|
||||||
void check(const ConflictSet::ReadRange *reads, ConflictSet::Result *results,
|
void check(const ConflictSet::ReadRange *reads, ConflictSet::Result *results,
|
||||||
int count) const {
|
int count) const {
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (reads[i].readVersion < oldestVersion) {
|
if (reads[i].readVersion < oldestVersion ||
|
||||||
|
reads[i].readVersion < newestVersion - 2e9) {
|
||||||
results[i] = ConflictSet::TooOld;
|
results[i] = ConflictSet::TooOld;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -495,6 +497,8 @@ struct ReferenceImpl {
|
|||||||
}
|
}
|
||||||
void addWrites(const ConflictSet::WriteRange *writes, int count,
|
void addWrites(const ConflictSet::WriteRange *writes, int count,
|
||||||
int64_t writeVersion) {
|
int64_t writeVersion) {
|
||||||
|
assert(writeVersion >= newestVersion);
|
||||||
|
newestVersion = writeVersion;
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
auto begin =
|
auto begin =
|
||||||
std::string((const char *)writes[i].begin.p, writes[i].begin.len);
|
std::string((const char *)writes[i].begin.p, writes[i].begin.len);
|
||||||
@@ -519,6 +523,7 @@ struct ReferenceImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t oldestVersion;
|
int64_t oldestVersion;
|
||||||
|
int64_t newestVersion;
|
||||||
std::map<std::string, int64_t> writeVersionMap;
|
std::map<std::string, int64_t> writeVersionMap;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -578,8 +583,8 @@ template <class ConflictSetImpl> struct TestDriver {
|
|||||||
explicit TestDriver(const uint8_t *data, size_t size)
|
explicit TestDriver(const uint8_t *data, size_t size)
|
||||||
: arbitrary({data, size}) {}
|
: arbitrary({data, size}) {}
|
||||||
|
|
||||||
int64_t writeVersion = 100;
|
|
||||||
int64_t oldestVersion = 0;
|
int64_t oldestVersion = 0;
|
||||||
|
int64_t writeVersion = 0;
|
||||||
ConflictSetImpl cs{oldestVersion};
|
ConflictSetImpl cs{oldestVersion};
|
||||||
ReferenceImpl refImpl{oldestVersion};
|
ReferenceImpl refImpl{oldestVersion};
|
||||||
|
|
||||||
@@ -593,6 +598,7 @@ template <class ConflictSetImpl> struct TestDriver {
|
|||||||
// Call until it returns true, for "done". Check internal invariants etc
|
// Call until it returns true, for "done". Check internal invariants etc
|
||||||
// between calls to next.
|
// between calls to next.
|
||||||
bool next() {
|
bool next() {
|
||||||
|
assert(cs.getBytes() >= 0);
|
||||||
if (!arbitrary.hasEntropy()) {
|
if (!arbitrary.hasEntropy()) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -600,7 +606,9 @@ template <class ConflictSetImpl> struct TestDriver {
|
|||||||
{
|
{
|
||||||
int numPointWrites = arbitrary.bounded(100);
|
int numPointWrites = arbitrary.bounded(100);
|
||||||
int numRangeWrites = arbitrary.bounded(100);
|
int numRangeWrites = arbitrary.bounded(100);
|
||||||
int64_t v = (writeVersion += arbitrary.bounded(10));
|
int64_t v =
|
||||||
|
(writeVersion += arbitrary.bounded(10) == 0 ? arbitrary.bounded(10)
|
||||||
|
: arbitrary.next());
|
||||||
auto *writes =
|
auto *writes =
|
||||||
new (arena) ConflictSet::WriteRange[numPointWrites + numRangeWrites];
|
new (arena) ConflictSet::WriteRange[numPointWrites + numRangeWrites];
|
||||||
auto keys = set<std::string_view>(arena);
|
auto keys = set<std::string_view>(arena);
|
||||||
@@ -642,18 +650,21 @@ template <class ConflictSetImpl> struct TestDriver {
|
|||||||
}
|
}
|
||||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
if (writes[i].end.len == 0) {
|
if (writes[i].end.len == 0) {
|
||||||
fprintf(stderr, "Write: {%s} -> %" PRId64 "\n",
|
fprintf(stderr, "Write: {%s}\n", printable(writes[i].begin).c_str());
|
||||||
printable(writes[i].begin).c_str(), writeVersion);
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Write: [%s, %s) -> %" PRId64 "\n",
|
fprintf(stderr, "Write: [%s, %s)\n",
|
||||||
printable(writes[i].begin).c_str(),
|
printable(writes[i].begin).c_str(),
|
||||||
printable(writes[i].end).c_str(), writeVersion);
|
printable(writes[i].end).c_str());
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
assert(iter == keys.end());
|
assert(iter == keys.end());
|
||||||
assert(i == numPointWrites + numRangeWrites);
|
assert(i == numPointWrites + numRangeWrites);
|
||||||
|
|
||||||
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
|
fprintf(stderr, "Write @ %" PRId64 "\n", v);
|
||||||
|
#endif
|
||||||
|
|
||||||
CALLGRIND_START_INSTRUMENTATION;
|
CALLGRIND_START_INSTRUMENTATION;
|
||||||
cs.addWrites(writes, numPointWrites + numRangeWrites, v);
|
cs.addWrites(writes, numPointWrites + numRangeWrites, v);
|
||||||
CALLGRIND_STOP_INSTRUMENTATION;
|
CALLGRIND_STOP_INSTRUMENTATION;
|
||||||
@@ -710,12 +721,12 @@ template <class ConflictSetImpl> struct TestDriver {
|
|||||||
reads[i].readVersion = v;
|
reads[i].readVersion = v;
|
||||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
if (reads[i].end.len == 0) {
|
if (reads[i].end.len == 0) {
|
||||||
fprintf(stderr, "Read: {%s} @ %d\n",
|
fprintf(stderr, "Read: {%s} @ %" PRId64 "\n",
|
||||||
printable(reads[i].begin).c_str(), int(reads[i].readVersion));
|
printable(reads[i].begin).c_str(), reads[i].readVersion);
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "Read: [%s, %s) @ %d\n",
|
fprintf(stderr, "Read: [%s, %s) @ %" PRId64 "\n",
|
||||||
printable(reads[i].begin).c_str(),
|
printable(reads[i].begin).c_str(),
|
||||||
printable(reads[i].end).c_str(), int(reads[i].readVersion));
|
printable(reads[i].end).c_str(), reads[i].readVersion);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+14
-2
@@ -59,6 +59,17 @@ pipeline {
|
|||||||
CleanBuildAndTest("-DUSE_SIMD_FALLBACK=ON")
|
CleanBuildAndTest("-DUSE_SIMD_FALLBACK=ON")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
stage('32-bit versions') {
|
||||||
|
agent {
|
||||||
|
dockerfile {
|
||||||
|
args '-v /home/jenkins/ccache:/ccache'
|
||||||
|
reuseNode true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
steps {
|
||||||
|
CleanBuildAndTest("-DUSE_32_BIT_VERSIONS=ON")
|
||||||
|
}
|
||||||
|
}
|
||||||
stage('Release [gcc]') {
|
stage('Release [gcc]') {
|
||||||
agent {
|
agent {
|
||||||
dockerfile {
|
dockerfile {
|
||||||
@@ -110,9 +121,10 @@ pipeline {
|
|||||||
sh '''
|
sh '''
|
||||||
gcovr -f ConflictSet.cpp --cobertura > build/coverage.xml
|
gcovr -f ConflictSet.cpp --cobertura > build/coverage.xml
|
||||||
'''
|
'''
|
||||||
cobertura autoUpdateHealth: false, autoUpdateStability: false, coberturaReportFile: 'build/coverage.xml', conditionalCoverageTargets: '70, 0, 0', failUnhealthy: false, failUnstable: false, lineCoverageTargets: '80, 0, 0', maxNumberOfBuilds: 0, methodCoverageTargets: '80, 0, 0', onlyStable: false, sourceEncoding: 'ASCII', zoomCoverageChart: false
|
recordCoverage qualityGates: [[criticality: 'NOTE', metric: 'MODULE']], tools: [[parser: 'COBERTURA', pattern: 'build/coverage.xml']]
|
||||||
sh '''
|
sh '''
|
||||||
gcovr -f ConflictSet.cpp --fail-under-line 100 > /dev/null
|
# Suppress again, because we haven't dealt with function multi-versioning for x86 yet
|
||||||
|
# gcovr -f ConflictSet.cpp --fail-under-line 100 > /dev/null
|
||||||
'''
|
'''
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -58,27 +58,29 @@ Performance counters:
|
|||||||
|
|
||||||
## Skip list
|
## Skip list
|
||||||
|
|
||||||
| ns/op | op/s | err% | total | benchmark |
|
| ns/op | op/s | err% | total | benchmark
|
||||||
| -----: | -----------: | ---: | ----: | :---------------------------------- |
|
|--------------------:|--------------------:|--------:|----------:|:----------
|
||||||
| 246.99 | 4,048,700.59 | 0.2% | 0.01 | `point reads` |
|
| 256.89 | 3,892,784.92 | 0.3% | 0.01 | `point reads`
|
||||||
| 260.16 | 3,843,784.65 | 0.1% | 0.01 | `prefix reads` |
|
| 272.90 | 3,664,395.04 | 0.2% | 0.01 | `prefix reads`
|
||||||
| 493.35 | 2,026,953.19 | 0.1% | 0.01 | `range reads` |
|
| 507.22 | 1,971,549.50 | 0.7% | 0.01 | `range reads`
|
||||||
| 462.05 | 2,164,289.23 | 0.6% | 0.01 | `point writes` |
|
| 452.66 | 2,209,181.91 | 0.5% | 0.01 | `point writes`
|
||||||
| 448.19 | 2,231,205.25 | 0.9% | 0.01 | `prefix writes` |
|
| 438.09 | 2,282,619.96 | 0.4% | 0.01 | `prefix writes`
|
||||||
| 255.83 | 3,908,845.72 | 1.5% | 0.02 | `range writes` |
|
| 253.33 | 3,947,420.36 | 2.5% | 0.02 | `range writes`
|
||||||
| 582.63 | 1,716,349.02 | 1.3% | 0.01 | `monotonic increasing point writes` |
|
| 574.07 | 1,741,936.71 | 0.3% | 0.01 | `monotonic increasing point writes`
|
||||||
|
| 151,562.50 | 6,597.94 | 1.5% | 0.01 | `worst case for radix tree`
|
||||||
|
|
||||||
## Radix tree (this implementation)
|
## Radix tree (this implementation)
|
||||||
|
|
||||||
| ns/op | op/s | err% | total | benchmark |
|
| ns/op | op/s | err% | total | benchmark
|
||||||
| -----: | ------------: | ---: | ----: | :---------------------------------- |
|
|--------------------:|--------------------:|--------:|----------:|:----------
|
||||||
| 19.42 | 51,483,206.67 | 0.3% | 0.01 | `point reads` |
|
| 19.83 | 50,420,955.28 | 0.1% | 0.01 | `point reads`
|
||||||
| 58.43 | 17,115,612.57 | 0.1% | 0.01 | `prefix reads` |
|
| 55.95 | 17,872,542.40 | 0.5% | 0.01 | `prefix reads`
|
||||||
| 216.09 | 4,627,766.60 | 0.2% | 0.01 | `range reads` |
|
| 88.28 | 11,327,709.50 | 0.4% | 0.01 | `range reads`
|
||||||
| 28.35 | 35,267,567.72 | 0.2% | 0.01 | `point writes` |
|
| 29.15 | 34,309,531.64 | 0.5% | 0.01 | `point writes`
|
||||||
| 43.43 | 23,026,226.17 | 0.2% | 0.01 | `prefix writes` |
|
| 42.36 | 23,607,424.27 | 1.1% | 0.01 | `prefix writes`
|
||||||
| 50.00 | 20,000,000.00 | 0.0% | 0.01 | `range writes` |
|
| 50.00 | 20,000,000.00 | 0.0% | 0.01 | `range writes`
|
||||||
| 92.38 | 10,824,863.69 | 4.1% | 0.01 | `monotonic increasing point writes` |
|
| 93.52 | 10,692,413.79 | 3.3% | 0.01 | `monotonic increasing point writes`
|
||||||
|
| 2,388,417.00 | 418.69 | 0.4% | 0.03 | `worst case for radix tree`
|
||||||
|
|
||||||
# "Real data" test
|
# "Real data" test
|
||||||
|
|
||||||
|
|||||||
+8
-2
@@ -577,7 +577,8 @@ struct SkipListConflictSet {};
|
|||||||
|
|
||||||
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||||
Impl(int64_t oldestVersion)
|
Impl(int64_t oldestVersion)
|
||||||
: oldestVersion(oldestVersion), skipList(oldestVersion) {}
|
: oldestVersion(oldestVersion), newestVersion(oldestVersion),
|
||||||
|
skipList(oldestVersion) {}
|
||||||
void check(const ConflictSet::ReadRange *reads, ConflictSet::Result *results,
|
void check(const ConflictSet::ReadRange *reads, ConflictSet::Result *results,
|
||||||
int count) const {
|
int count) const {
|
||||||
Arena arena;
|
Arena arena;
|
||||||
@@ -592,7 +593,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
}
|
}
|
||||||
skipList.detectConflicts(ranges, count, results);
|
skipList.detectConflicts(ranges, count, results);
|
||||||
for (int i = 0; i < count; ++i) {
|
for (int i = 0; i < count; ++i) {
|
||||||
if (reads[i].readVersion < oldestVersion) {
|
if (reads[i].readVersion < oldestVersion ||
|
||||||
|
reads[i].readVersion < newestVersion - 2e9) {
|
||||||
results[i] = TooOld;
|
results[i] = TooOld;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -600,6 +602,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
|
|
||||||
void addWrites(const ConflictSet::WriteRange *writes, int count,
|
void addWrites(const ConflictSet::WriteRange *writes, int count,
|
||||||
int64_t writeVersion) {
|
int64_t writeVersion) {
|
||||||
|
assert(writeVersion >= newestVersion);
|
||||||
|
newestVersion = writeVersion;
|
||||||
Arena arena;
|
Arena arena;
|
||||||
const int stringCount = count * 2;
|
const int stringCount = count * 2;
|
||||||
|
|
||||||
@@ -630,6 +634,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setOldestVersion(int64_t oldestVersion) {
|
void setOldestVersion(int64_t oldestVersion) {
|
||||||
|
assert(oldestVersion >= this->oldestVersion);
|
||||||
this->oldestVersion = oldestVersion;
|
this->oldestVersion = oldestVersion;
|
||||||
SkipList::Finger finger;
|
SkipList::Finger finger;
|
||||||
int temp;
|
int temp;
|
||||||
@@ -648,6 +653,7 @@ private:
|
|||||||
Arena removalArena;
|
Arena removalArena;
|
||||||
std::span<const uint8_t> removalKey;
|
std::span<const uint8_t> removalKey;
|
||||||
int64_t oldestVersion;
|
int64_t oldestVersion;
|
||||||
|
int64_t newestVersion;
|
||||||
SkipList skipList;
|
SkipList skipList;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
___stack_chk_fail
|
||||||
|
___stack_chk_guard
|
||||||
__tlv_bootstrap
|
__tlv_bootstrap
|
||||||
_abort
|
_abort
|
||||||
_bzero
|
_bzero
|
||||||
|
|||||||
+3
-1
@@ -115,7 +115,9 @@ class ConflictSet:
|
|||||||
|
|
||||||
def check(self, *reads: ReadRange) -> list[Result]:
|
def check(self, *reads: ReadRange) -> list[Result]:
|
||||||
r = (ctypes.c_int * len(reads))()
|
r = (ctypes.c_int * len(reads))()
|
||||||
self._lib.ConflictSet_check(self.p, *reads, r, 1)
|
self._lib.ConflictSet_check(
|
||||||
|
self.p, (ReadRange * len(reads))(*reads), r, len(reads)
|
||||||
|
)
|
||||||
return [Result(x) for x in r]
|
return [Result(x) for x in r]
|
||||||
|
|
||||||
def setOldestVersion(self, version: int) -> None:
|
def setOldestVersion(self, version: int) -> None:
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
Before Width: | Height: | Size: 1.6 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
After Width: | Height: | Size: 27 B |
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user