WIP checkLeftOfPyramid seems to be correct
This commit is contained in:
@@ -60,7 +60,7 @@ target_include_directories(${PROJECT_NAME}_object
|
|||||||
|
|
||||||
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:${PROJECT_NAME}_object>)
|
add_library(${PROJECT_NAME} SHARED $<TARGET_OBJECTS:${PROJECT_NAME}_object>)
|
||||||
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
|
# set_target_properties(${PROJECT_NAME} PROPERTIES LINKER_LANGUAGE C)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT APPLE)
|
if(NOT APPLE)
|
||||||
@@ -71,7 +71,7 @@ endif()
|
|||||||
add_library(${PROJECT_NAME}_static STATIC
|
add_library(${PROJECT_NAME}_static STATIC
|
||||||
$<TARGET_OBJECTS:${PROJECT_NAME}_object>)
|
$<TARGET_OBJECTS:${PROJECT_NAME}_object>)
|
||||||
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
if(NOT CMAKE_BUILD_TYPE STREQUAL Debug)
|
||||||
set_target_properties(${PROJECT_NAME}_static PROPERTIES LINKER_LANGUAGE C)
|
# set_target_properties(${PROJECT_NAME}_static PROPERTIES LINKER_LANGUAGE C)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(NOT APPLE AND CMAKE_OBJCOPY)
|
if(NOT APPLE AND CMAKE_OBJCOPY)
|
||||||
|
104
ConflictSet.cpp
104
ConflictSet.cpp
@@ -736,14 +736,21 @@ int64_t maxRightOf(Node *n, int begin) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Return the maximum version among all keys starting with the search path of
|
||||||
|
// `n` + a child > `begin`
|
||||||
int64_t maxRightOfExclusive(Node *n, int begin) {
|
int64_t maxRightOfExclusive(Node *n, int begin) {
|
||||||
int64_t result = std::numeric_limits<int64_t>::lowest();
|
int64_t result = std::numeric_limits<int64_t>::lowest();
|
||||||
|
int index = begin;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
begin = getChildGeq(n, begin + 1);
|
index = getChildGeq(n, index + 1);
|
||||||
if (begin < 0) {
|
if (index < 0) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
result = std::max(result, getChildExists(n, begin)->maxVersion);
|
auto *child = getChildExists(n, index);
|
||||||
|
if (index > begin + 1 && child->entryPresent) {
|
||||||
|
result = std::max(result, child->entry.rangeVersion);
|
||||||
|
}
|
||||||
|
result = std::max(result, child->maxVersion);
|
||||||
}
|
}
|
||||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
fprintf(stderr, "At `%s', max version right of %02x is %" PRId64 "\n",
|
fprintf(stderr, "At `%s', max version right of %02x is %" PRId64 "\n",
|
||||||
@@ -789,7 +796,8 @@ int64_t maxBetweenExclusive(Node *n, int begin, int end) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the version of all keys >= key in n is <= readVersion
|
// Returns true if the version of all keys >= key in the subtree rooted at n is
|
||||||
|
// <= readVersion
|
||||||
bool checkLeftOfPyramid(Node *n, const std::span<const uint8_t> key,
|
bool checkLeftOfPyramid(Node *n, const std::span<const uint8_t> key,
|
||||||
int64_t readVersion) {
|
int64_t readVersion) {
|
||||||
auto remaining = key;
|
auto remaining = key;
|
||||||
@@ -799,30 +807,36 @@ bool checkLeftOfPyramid(Node *n, const std::span<const uint8_t> key,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if (remaining.size() == 0) {
|
if (remaining.size() == 0) {
|
||||||
if (n->entryPresent) {
|
return n->maxVersion <= readVersion;
|
||||||
return n->entry.pointVersion <= readVersion;
|
}
|
||||||
|
|
||||||
|
auto v = maxRightOfExclusive(n, remaining[0]);
|
||||||
|
if (v > readVersion) {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
{
|
||||||
|
int c = getChildGeq(n, int(remaining[0]) + 1);
|
||||||
|
if (c >= 0) {
|
||||||
|
auto *child = getChildExists(n, c);
|
||||||
|
if (child->entryPresent && child->entry.rangeVersion > readVersion) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int c = getChildGeq(n, 0);
|
|
||||||
assert(c >= 0);
|
|
||||||
n = getChildExists(n, c);
|
|
||||||
goto downLeftSpine;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int c = getChildGeq(n, remaining[0]);
|
int c = getChildGeq(n, remaining[0]);
|
||||||
if (c == remaining[0]) {
|
if (c == remaining[0]) {
|
||||||
auto v = maxRightOfExclusive(n, c);
|
|
||||||
if (v > readVersion) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
n = getChildExists(n, c);
|
n = getChildExists(n, c);
|
||||||
remaining = remaining.subspan(1, remaining.size() - 1);
|
remaining = remaining.subspan(1, remaining.size() - 1);
|
||||||
} else {
|
} else {
|
||||||
if (c >= 0) {
|
if (c >= 0) {
|
||||||
n = getChildExists(n, c);
|
n = getChildExists(n, c);
|
||||||
goto downLeftSpine;
|
if (n->entryPresent && n->entry.rangeVersion > readVersion) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return n->maxVersion <= readVersion;
|
||||||
} else {
|
} else {
|
||||||
n = nextSibling(n);
|
return true;
|
||||||
goto downLeftSpine;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -833,35 +847,26 @@ bool checkLeftOfPyramid(Node *n, const std::span<const uint8_t> key,
|
|||||||
if (c == 0) {
|
if (c == 0) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (c > 0) {
|
if (c < 0) {
|
||||||
goto downLeftSpine;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
n = nextSibling(n);
|
if (n->entryPresent && n->entry.rangeVersion > readVersion) {
|
||||||
goto downLeftSpine;
|
return false;
|
||||||
|
}
|
||||||
|
return n->maxVersion <= readVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (commonLen == n->partialKeyLen) {
|
if (commonLen == n->partialKeyLen) {
|
||||||
// partial key matches
|
// partial key matches
|
||||||
remaining = remaining.subspan(commonLen, remaining.size() - commonLen);
|
remaining = remaining.subspan(commonLen, remaining.size() - commonLen);
|
||||||
} else if (n->partialKeyLen > int(remaining.size())) {
|
} else if (n->partialKeyLen > int(remaining.size())) {
|
||||||
// n is the first physical node greater than remaining, and there's no
|
if (n->entryPresent && n->entry.rangeVersion > readVersion) {
|
||||||
// eq node
|
return false;
|
||||||
goto downLeftSpine;
|
}
|
||||||
|
return n->maxVersion <= readVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
downLeftSpine:
|
|
||||||
if (n == nullptr) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
for (;;) {
|
|
||||||
if (n->entryPresent) {
|
|
||||||
return n->entry.rangeVersion <= readVersion;
|
|
||||||
}
|
|
||||||
int c = getChildGeq(n, 0);
|
|
||||||
assert(c >= 0);
|
|
||||||
n = getChildExists(n, c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns true if the version of all keys < key in n is <= readVersion
|
// Returns true if the version of all keys < key in n is <= readVersion
|
||||||
@@ -1356,20 +1361,19 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
|||||||
reads[i].readVersion))
|
reads[i].readVersion))
|
||||||
? Commit
|
? Commit
|
||||||
: Conflict;
|
: Conflict;
|
||||||
// auto k = std::span<const uint8_t>(reads[i].begin.p,
|
auto k = std::span<const uint8_t>(reads[i].begin.p, reads[i].begin.len);
|
||||||
// reads[i].begin.len); if (k.size() > 0) {
|
if (k.size() > 0) {
|
||||||
// bool expected =
|
bool expected = checkRangeRead(root, k, std::vector<uint8_t>(33, 0xff),
|
||||||
// checkRangeRead(root, {}, k, reads[i].readVersion, arena);
|
reads[i].readVersion, arena);
|
||||||
// bool actual = checkRightOfPyramid(root, k,
|
bool actual = checkLeftOfPyramid(root, k, reads[i].readVersion);
|
||||||
// reads[i].readVersion); if (expected != actual) {
|
if (expected != actual) {
|
||||||
// #if DEBUG_VERBOSE && !defined(NDEBUG)
|
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||||
// fprintf(stderr, "Expected %d, got %d for [,%s)\n",
|
fprintf(stderr, "Expected %d, got %d for [%s,)\n", int(expected),
|
||||||
// int(expected),
|
int(actual), printable(k).c_str());
|
||||||
// int(actual), printable(k).c_str());
|
#endif
|
||||||
// #endif
|
result[i] = TooOld;
|
||||||
// result[i] = TooOld;
|
}
|
||||||
// }
|
}
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user