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>
#endif
#ifndef __SANITIZE_THREAD__
#if defined(__has_feature)
#if __has_feature(thread_sanitizer)
#define __SANITIZE_THREAD__
#endif
#endif
#endif
#include <memcheck.h>
@@ -1126,9 +1128,12 @@ Node *getFirstChildExists(Node *self) {
// Caller is responsible for assigning a non-null pointer to the returned
// reference if null. Updates child's max version to `newMaxVersion` if child
// 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) {
int index = key.front();
key = key.subspan(1, key.size() - 1);
// Fast path for if it exists already
switch (self->getType()) {
case Type_Node0:
@@ -1181,6 +1186,14 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
__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()) {
case Type_Node0: {
auto *self0 = static_cast<Node0 *>(self);
@@ -1215,8 +1228,10 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
}
self3->index[i + 1] = index;
auto &result = self3->children[i + 1];
result = nullptr;
self3->childMaxVersion[i + 1] = newMaxVersion;
result = newChild;
++self->numChildren;
newChild->parent = self;
return result;
}
case Type_Node16: {
@@ -1243,8 +1258,10 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
}
self16->index[i + 1] = index;
auto &result = self16->children[i + 1];
result = nullptr;
self16->childMaxVersion[i + 1] = newMaxVersion;
result = newChild;
++self->numChildren;
newChild->parent = self;
return result;
}
case Type_Node48: {
@@ -1267,7 +1284,11 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
self48->index[index] = nextFree;
self48->reverseIndex[nextFree] = index;
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;
}
case Type_Node256: {
@@ -1276,7 +1297,13 @@ Node *&getOrCreateChild(Node *&self, uint8_t index,
auto *self256 = static_cast<Node256 *>(self);
++self->numChildren;
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
__builtin_unreachable(); // GCOVR_EXCL_LINE
@@ -2779,18 +2806,9 @@ Node **insert(Node **self, std::span<const uint8_t> key,
return self;
}
int index = key.front();
key = key.subspan(1, key.size() - 1);
auto &child = getOrCreateChild(*self, index, writeVersion, tls);
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);
bool existed = getChild(*self, key.front());
auto &child = getOrCreateChild(*self, key, writeVersion, tls);
if (!existed) {
return &child;
}

View File

@@ -11,6 +11,14 @@
#include <arm_neon.h>
#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)
constexpr int kStride = 64;
#else