From 305c2188884e26ad0b4f2b3cd3debeb96c149d2f Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Fri, 23 Feb 2024 14:27:20 -0800 Subject: [PATCH] Skip checking for partial key match if partial key len == 0 This saves instructions according to cachegrind --- ConflictSet.cpp | 63 ++++++++++++++++++++++++++----------------------- 1 file changed, 34 insertions(+), 29 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 86b5b26..cca8b50 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1411,39 +1411,44 @@ bool checkRangeRead(Node *n, std::span begin, template [[nodiscard]] Node *insert(Node **self, std::span key, int64_t writeVersion, NodeAllocators *allocators) { + for (;;) { - // Handle an existing partial key - int commonLen = std::min((*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((*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)->partialKeyLen = partialKeyIndex; - (*self)->entryPresent = false; - (*self)->numChildren = 0; + *self = allocators->node4.allocate(); - getOrCreateChild(*self, old->partialKey[partialKeyIndex], allocators) = - old; - old->parent = *self; - old->parentsIndex = old->partialKey[partialKeyIndex]; + memcpy((void *)*self, old, offsetof(Node, type)); + (*self)->partialKeyLen = partialKeyIndex; + (*self)->entryPresent = false; + (*self)->numChildren = 0; - memmove(old->partialKey, old->partialKey + partialKeyIndex + 1, - old->partialKeyLen - (partialKeyIndex + 1)); - old->partialKeyLen -= partialKeyIndex + 1; - } - key = key.subspan(partialKeyIndex, key.size() - partialKeyIndex); + getOrCreateChild(*self, old->partialKey[partialKeyIndex], allocators) = + old; + old->parent = *self; + old->parentsIndex = old->partialKey[partialKeyIndex]; - // Consider adding a partial key - if ((*self)->numChildren == 0 && !(*self)->entryPresent) { - (*self)->partialKeyLen = - std::min(key.size(), (*self)->kPartialKeyMaxLen); - memcpy((*self)->partialKey, key.data(), (*self)->partialKeyLen); - key = key.subspan((*self)->partialKeyLen, - key.size() - (*self)->partialKeyLen); + memmove(old->partialKey, old->partialKey + partialKeyIndex + 1, + old->partialKeyLen - (partialKeyIndex + 1)); + old->partialKeyLen -= partialKeyIndex + 1; + } + key = key.subspan(partialKeyIndex, key.size() - partialKeyIndex); + + } else { + // Consider adding a partial key + if ((*self)->numChildren == 0 && !(*self)->entryPresent) { + (*self)->partialKeyLen = + std::min(key.size(), (*self)->kPartialKeyMaxLen); + memcpy((*self)->partialKey, key.data(), (*self)->partialKeyLen); + key = key.subspan((*self)->partialKeyLen, + key.size() - (*self)->partialKeyLen); + } } if constexpr (kBegin) { @@ -1458,10 +1463,10 @@ template (*self)->maxVersion = std::max((*self)->maxVersion, writeVersion); } - auto &child = getOrCreateChild((*self), key.front(), allocators); + auto &child = getOrCreateChild(*self, key.front(), allocators); if (!child) { child = allocators->node4.allocate(); - child->parent = (*self); + child->parent = *self; child->parentsIndex = key.front(); child->maxVersion = kBegin ? writeVersion : std::numeric_limits::lowest();