WIP create child in getOrCreateChild

This commit is contained in:
2024-08-12 16:11:16 -07:00
parent 8a44055533
commit 567d385fbd
2 changed files with 43 additions and 17 deletions

View File

@@ -40,11 +40,13 @@ limitations under the License.
#include <arm_neon.h> #include <arm_neon.h>
#endif #endif
#ifndef __SANITIZE_THREAD__
#if defined(__has_feature) #if defined(__has_feature)
#if __has_feature(thread_sanitizer) #if __has_feature(thread_sanitizer)
#define __SANITIZE_THREAD__ #define __SANITIZE_THREAD__
#endif #endif
#endif #endif
#endif
#include <memcheck.h> #include <memcheck.h>
@@ -1126,9 +1128,12 @@ Node *getFirstChildExists(Node *self) {
// Caller is responsible for assigning a non-null pointer to the returned // Caller is responsible for assigning a non-null pointer to the returned
// reference if null. Updates child's max version to `newMaxVersion` if child // reference if null. Updates child's max version to `newMaxVersion` if child
// exists but does not have a partial key. // exists but does not have a partial key.
Node *&getOrCreateChild(Node *&self, uint8_t index, Node *&getOrCreateChild(Node *&self, std::span<const uint8_t> &key,
InternalVersionT newMaxVersion, WriteContext *tls) { InternalVersionT newMaxVersion, WriteContext *tls) {
int index = key.front();
key = key.subspan(1, key.size() - 1);
// Fast path for if it exists already // Fast path for if it exists already
switch (self->getType()) { switch (self->getType()) {
case Type_Node0: case Type_Node0:
@@ -1181,6 +1186,14 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
} }
auto *newChild = tls->allocate<Node0>(key.size());
newChild->numChildren = 0;
newChild->entryPresent = false;
newChild->partialKeyLen = key.size();
newChild->parentsIndex = index;
memcpy(newChild->partialKey(), key.data(), key.size());
key = {};
switch (self->getType()) { switch (self->getType()) {
case Type_Node0: { case Type_Node0: {
auto *self0 = static_cast<Node0 *>(self); auto *self0 = static_cast<Node0 *>(self);
@@ -1215,8 +1228,10 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
} }
self3->index[i + 1] = index; self3->index[i + 1] = index;
auto &result = self3->children[i + 1]; auto &result = self3->children[i + 1];
result = nullptr; self3->childMaxVersion[i + 1] = newMaxVersion;
result = newChild;
++self->numChildren; ++self->numChildren;
newChild->parent = self;
return result; return result;
} }
case Type_Node16: { case Type_Node16: {
@@ -1243,8 +1258,10 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
} }
self16->index[i + 1] = index; self16->index[i + 1] = index;
auto &result = self16->children[i + 1]; auto &result = self16->children[i + 1];
result = nullptr; self16->childMaxVersion[i + 1] = newMaxVersion;
result = newChild;
++self->numChildren; ++self->numChildren;
newChild->parent = self;
return result; return result;
} }
case Type_Node48: { case Type_Node48: {
@@ -1267,7 +1284,11 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
self48->index[index] = nextFree; self48->index[index] = nextFree;
self48->reverseIndex[nextFree] = index; self48->reverseIndex[nextFree] = index;
auto &result = self48->children[nextFree]; auto &result = self48->children[nextFree];
result = nullptr; self48->childMaxVersion[nextFree] = newMaxVersion;
self48->maxOfMax[nextFree >> Node48::kMaxOfMaxShift] = std::max(
newMaxVersion, self48->maxOfMax[nextFree >> Node48::kMaxOfMaxShift]);
result = newChild;
newChild->parent = self;
return result; return result;
} }
case Type_Node256: { case Type_Node256: {
@@ -1276,7 +1297,13 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
auto *self256 = static_cast<Node256 *>(self); auto *self256 = static_cast<Node256 *>(self);
++self->numChildren; ++self->numChildren;
self256->bitSet.set(index); self256->bitSet.set(index);
return self256->children[index]; auto &result = self256->children[index];
self256->childMaxVersion[index] = newMaxVersion;
self256->maxOfMax[index >> Node256::kMaxOfMaxShift] = std::max(
newMaxVersion, self256->maxOfMax[index >> Node256::kMaxOfMaxShift]);
result = newChild;
newChild->parent = self;
return result;
} }
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
@@ -2779,18 +2806,9 @@ Node **insert(Node **self, std::span<const uint8_t> key,
return self; return self;
} }
int index = key.front(); bool existed = getChild(*self, key.front());
key = key.subspan(1, key.size() - 1); auto &child = getOrCreateChild(*self, key, writeVersion, tls);
auto &child = getOrCreateChild(*self, index, writeVersion, tls); if (!existed) {
if (!child) {
child = tls->allocate<Node0>(key.size());
child->numChildren = 0;
child->entryPresent = false;
child->partialKeyLen = key.size();
child->parent = *self;
child->parentsIndex = index;
setMaxVersion(child, impl, writeVersion);
memcpy(child->partialKey(), key.data(), child->partialKeyLen);
return &child; return &child;
} }

View File

@@ -11,6 +11,14 @@
#include <arm_neon.h> #include <arm_neon.h>
#endif #endif
#ifndef __SANITIZE_THREAD__
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define __SANITIZE_THREAD__
#endif
#endif
#endif
#if defined(HAS_AVX) || defined(HAS_ARM_NEON) #if defined(HAS_AVX) || defined(HAS_ARM_NEON)
constexpr int kStride = 64; constexpr int kStride = 64;
#else #else