Remove the reverse step for saving scan search path

This commit is contained in:
2024-11-14 16:27:25 -08:00
parent dcc5275ec9
commit 08958d4109

View File

@@ -5347,6 +5347,11 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
gc_iterations_total.add(set_oldest_iterations_accum);
if (n == nullptr) {
removalKey = {};
if (removalBufferSize > kMaxRemovalBufferSize) {
safe_free(removalBuffer, removalBufferSize);
removalBufferSize = kMinRemovalBufferSize;
removalBuffer = (uint8_t *)safe_malloc(removalBufferSize);
}
oldestExtantVersion = oldestVersionAtGcBegin;
oldest_extant_version.set(oldestExtantVersion);
oldestVersionAtGcBegin = oldestVersionFullPrecision;
@@ -5357,12 +5362,47 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
oldestExtantVersion, oldestVersionAtGcBegin);
#endif
} else {
removalKeyArena = Arena();
removalKey = getSearchPath(removalKeyArena, n);
// Store the current search path to resume the scan later
saveRemovalKey(n);
}
return fuel;
}
void saveRemovalKey(Node *n) {
uint8_t *cursor = removalBuffer + removalBufferSize;
int size = 0;
auto reserve = [&](int delta) {
if (size + delta > removalBufferSize) [[unlikely]] {
int newBufSize = std::max(removalBufferSize * 2, size + delta);
uint8_t *newBuf = (uint8_t *)safe_malloc(newBufSize);
memcpy(newBuf + newBufSize - size, cursor, size);
safe_free(removalBuffer, removalBufferSize);
removalBuffer = newBuf;
removalBufferSize = newBufSize;
cursor = newBuf + newBufSize - size;
}
};
for (;;) {
auto partialKey = TrivialSpan{n->partialKey(), n->partialKeyLen};
reserve(partialKey.size());
size += partialKey.size();
cursor -= partialKey.size();
memcpy(cursor, partialKey.data(), partialKey.size());
if (n->parent == nullptr) {
break;
}
reserve(1);
++size;
--cursor;
*cursor = n->parentsIndex;
n = n->parent;
}
removalKey = {cursor, size};
}
void setOldestVersion(int64_t newOldestVersion) {
assert(newOldestVersion >= 0);
assert(newOldestVersion <= newestVersionFullPrecision);
@@ -5413,7 +5453,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
writeContext.~WriteContext();
new (&writeContext) WriteContext();
removalKeyArena = Arena{};
// Leave removalBuffer as is
removalKey = {};
keyUpdates = 10;
@@ -5445,11 +5485,16 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
~Impl() {
eraseTree(root, &writeContext);
safe_free(metrics, metricsCount * sizeof(metrics[0]));
safe_free(removalBuffer, removalBufferSize);
}
WriteContext writeContext;
Arena removalKeyArena;
static constexpr int kMinRemovalBufferSize = 1 << 10;
// Eventually downsize if larger than this value
static constexpr int kMaxRemovalBufferSize = 1 << 16;
uint8_t *removalBuffer = (uint8_t *)safe_malloc(kMinRemovalBufferSize);
int removalBufferSize = kMinRemovalBufferSize;
TrivialSpan removalKey;
int64_t keyUpdates;