Track lcp as loop invariant
This commit is contained in:
@@ -931,6 +931,35 @@ bytes:
|
|||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline void
|
||||||
|
ascend(int &depth, int &lcp, Node *oldNode, Vector<uint8_t> &searchPath) {
|
||||||
|
depth -= 1 + oldNode->partialKeyLen;
|
||||||
|
searchPath.resize(depth);
|
||||||
|
lcp = std::min(lcp, depth);
|
||||||
|
}
|
||||||
|
|
||||||
|
__attribute__((always_inline)) inline void
|
||||||
|
descend(int &depth, int &lcp, Node *newNode, std::span<const uint8_t> end,
|
||||||
|
Vector<uint8_t> &searchPath) {
|
||||||
|
if (depth == lcp) {
|
||||||
|
if (lcp < int(end.size()) && newNode->parentsIndex == end[lcp]) {
|
||||||
|
++lcp;
|
||||||
|
for (int i = 0; i < newNode->partialKeyLen && lcp < int(end.size());
|
||||||
|
++i) {
|
||||||
|
if (newNode->partialKey[i] == end[lcp]) {
|
||||||
|
++lcp;
|
||||||
|
} else {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
depth += 1 + newNode->partialKeyLen;
|
||||||
|
searchPath.push_back(newNode->parentsIndex);
|
||||||
|
searchPath.insert(searchPath.end(), newNode->partialKey,
|
||||||
|
newNode->partialKey + newNode->partialKeyLen);
|
||||||
|
}
|
||||||
|
|
||||||
bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
||||||
const std::span<const uint8_t> end, int64_t readVersion,
|
const std::span<const uint8_t> end, int64_t readVersion,
|
||||||
Arena &arena) {
|
Arena &arena) {
|
||||||
@@ -980,10 +1009,15 @@ bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int depth = searchPath.size();
|
||||||
|
lcp = longestCommonPrefix(searchPath.data(), end.data(),
|
||||||
|
std::min(searchPath.size(), end.size()));
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (auto *iter = left.n; iter != nullptr; first = false) {
|
for (auto *iter = left.n; iter != nullptr; first = false) {
|
||||||
int cl = std::min(searchPath.size(), end.size());
|
int cl = std::min(searchPath.size(), end.size());
|
||||||
int lcp = longestCommonPrefix(searchPath.data(), end.data(), cl);
|
assert(depth == int(searchPath.size()));
|
||||||
|
assert(lcp == longestCommonPrefix(searchPath.data(), end.data(), cl));
|
||||||
|
|
||||||
// if (searchPath >= end) break;
|
// if (searchPath >= end) break;
|
||||||
if ((cl == lcp ? searchPath.size() <=> end.size()
|
if ((cl == lcp ? searchPath.size() <=> end.size()
|
||||||
@@ -1005,7 +1039,7 @@ bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
|||||||
fprintf(stderr, "Max version of keys starting with %s: %" PRId64 "\n",
|
fprintf(stderr, "Max version of keys starting with %s: %" PRId64 "\n",
|
||||||
printable(searchPath).c_str(), iter->maxVersion);
|
printable(searchPath).c_str(), iter->maxVersion);
|
||||||
#endif
|
#endif
|
||||||
if (lcp == int(searchPath.size())) {
|
if (lcp == depth) {
|
||||||
// end starts with searchPath, so end < range
|
// end starts with searchPath, so end < range
|
||||||
if (iter->maxVersion <= readVersion) {
|
if (iter->maxVersion <= readVersion) {
|
||||||
return true;
|
return true;
|
||||||
@@ -1015,17 +1049,15 @@ bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
|||||||
auto nextChild = getChildGeq(iter, index + 1);
|
auto nextChild = getChildGeq(iter, index + 1);
|
||||||
if (nextChild >= 0) {
|
if (nextChild >= 0) {
|
||||||
auto *result = getChildExists(iter, nextChild);
|
auto *result = getChildExists(iter, nextChild);
|
||||||
searchPath.push_back(nextChild);
|
|
||||||
searchPath.insert(searchPath.end(), result->partialKey,
|
|
||||||
result->partialKey + result->partialKeyLen);
|
|
||||||
iter = result;
|
iter = result;
|
||||||
|
descend(depth, lcp, iter, end, searchPath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (iter->parent == nullptr) {
|
if (iter->parent == nullptr) {
|
||||||
iter = nullptr;
|
iter = nullptr;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
searchPath.resize(int(searchPath.size()) - 1 - iter->partialKeyLen);
|
ascend(depth, lcp, iter, searchPath);
|
||||||
index = iter->parentsIndex;
|
index = iter->parentsIndex;
|
||||||
iter = iter->parent;
|
iter = iter->parent;
|
||||||
}
|
}
|
||||||
@@ -1043,15 +1075,13 @@ bool checkRangeRead(Node *n, const std::span<const uint8_t> begin,
|
|||||||
}
|
}
|
||||||
auto next = getChildGeq(iter->parent, iter->parentsIndex + 1);
|
auto next = getChildGeq(iter->parent, iter->parentsIndex + 1);
|
||||||
if (next < 0) {
|
if (next < 0) {
|
||||||
searchPath.resize(int(searchPath.size()) - (1 + iter->partialKeyLen));
|
ascend(depth, lcp, iter, searchPath);
|
||||||
iter = iter->parent;
|
iter = iter->parent;
|
||||||
} else {
|
} else {
|
||||||
searchPath.resize(int(searchPath.size()) - (1 + iter->partialKeyLen));
|
ascend(depth, lcp, iter, searchPath);
|
||||||
auto *result = getChildExists(iter->parent, next);
|
auto *result = getChildExists(iter->parent, next);
|
||||||
searchPath.push_back(next);
|
|
||||||
searchPath.insert(searchPath.end(), result->partialKey,
|
|
||||||
result->partialKey + result->partialKeyLen);
|
|
||||||
iter = result;
|
iter = result;
|
||||||
|
descend(depth, lcp, iter, end, searchPath);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user