Skip checking for partial key match if partial key len == 0

This saves instructions according to cachegrind
This commit is contained in:
2024-02-23 14:27:20 -08:00
parent db60782c48
commit 305c218888

View File

@@ -1411,39 +1411,44 @@ bool checkRangeRead(Node *n, std::span<const uint8_t> begin,
template <bool kBegin> template <bool kBegin>
[[nodiscard]] Node *insert(Node **self, std::span<const uint8_t> key, [[nodiscard]] Node *insert(Node **self, std::span<const uint8_t> key,
int64_t writeVersion, NodeAllocators *allocators) { int64_t writeVersion, NodeAllocators *allocators) {
for (;;) { for (;;) {
// Handle an existing partial key
int commonLen = std::min<int>((*self)->partialKeyLen, key.size());
int partialKeyIndex = longestCommonPrefixPartialKey((*self)->partialKey,
key.data(), commonLen);
if (partialKeyIndex < (*self)->partialKeyLen) {
auto *old = *self;
*self = allocators->node4.allocate(); if ((*self)->partialKeyLen > 0) {
// Handle an existing partial key
int commonLen = std::min<int>((*self)->partialKeyLen, key.size());
int partialKeyIndex = longestCommonPrefixPartialKey(
(*self)->partialKey, key.data(), commonLen);
if (partialKeyIndex < (*self)->partialKeyLen) {
auto *old = *self;
memcpy((void *)*self, old, offsetof(Node, type)); *self = allocators->node4.allocate();
(*self)->partialKeyLen = partialKeyIndex;
(*self)->entryPresent = false;
(*self)->numChildren = 0;
getOrCreateChild(*self, old->partialKey[partialKeyIndex], allocators) = memcpy((void *)*self, old, offsetof(Node, type));
old; (*self)->partialKeyLen = partialKeyIndex;
old->parent = *self; (*self)->entryPresent = false;
old->parentsIndex = old->partialKey[partialKeyIndex]; (*self)->numChildren = 0;
memmove(old->partialKey, old->partialKey + partialKeyIndex + 1, getOrCreateChild(*self, old->partialKey[partialKeyIndex], allocators) =
old->partialKeyLen - (partialKeyIndex + 1)); old;
old->partialKeyLen -= partialKeyIndex + 1; old->parent = *self;
} old->parentsIndex = old->partialKey[partialKeyIndex];
key = key.subspan(partialKeyIndex, key.size() - partialKeyIndex);
// Consider adding a partial key memmove(old->partialKey, old->partialKey + partialKeyIndex + 1,
if ((*self)->numChildren == 0 && !(*self)->entryPresent) { old->partialKeyLen - (partialKeyIndex + 1));
(*self)->partialKeyLen = old->partialKeyLen -= partialKeyIndex + 1;
std::min<int>(key.size(), (*self)->kPartialKeyMaxLen); }
memcpy((*self)->partialKey, key.data(), (*self)->partialKeyLen); key = key.subspan(partialKeyIndex, key.size() - partialKeyIndex);
key = key.subspan((*self)->partialKeyLen,
key.size() - (*self)->partialKeyLen); } else {
// Consider adding a partial key
if ((*self)->numChildren == 0 && !(*self)->entryPresent) {
(*self)->partialKeyLen =
std::min<int>(key.size(), (*self)->kPartialKeyMaxLen);
memcpy((*self)->partialKey, key.data(), (*self)->partialKeyLen);
key = key.subspan((*self)->partialKeyLen,
key.size() - (*self)->partialKeyLen);
}
} }
if constexpr (kBegin) { if constexpr (kBegin) {
@@ -1458,10 +1463,10 @@ template <bool kBegin>
(*self)->maxVersion = std::max((*self)->maxVersion, writeVersion); (*self)->maxVersion = std::max((*self)->maxVersion, writeVersion);
} }
auto &child = getOrCreateChild((*self), key.front(), allocators); auto &child = getOrCreateChild(*self, key.front(), allocators);
if (!child) { if (!child) {
child = allocators->node4.allocate(); child = allocators->node4.allocate();
child->parent = (*self); child->parent = *self;
child->parentsIndex = key.front(); child->parentsIndex = key.front();
child->maxVersion = child->maxVersion =
kBegin ? writeVersion : std::numeric_limits<int64_t>::lowest(); kBegin ? writeVersion : std::numeric_limits<int64_t>::lowest();