From eb93157ddf81edd88bd456141542525049c8be89 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Thu, 14 Mar 2024 18:49:49 -0700 Subject: [PATCH] Improve codegen in freeAndMakeCapacityAtLeast --- ConflictSet.cpp | 38 +++++++++++++++++++++++--------------- 1 file changed, 23 insertions(+), 15 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index ceb3b71..01d3a48 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -215,9 +215,6 @@ struct Node { uint8_t parentsIndex; /* end section that's copied to the next node */ - // These survive the free list round trip unscathed, and are only written by - // BoundedFreeListAllocator - uint8_t *partialKey(); Type getType() const { return type; } @@ -252,8 +249,17 @@ struct Node3 : Node { uint8_t index[kMaxNodes]; Child children[kMaxNodes]; uint8_t *partialKey() { return (uint8_t *)(this + 1); } + + void copyChildrenAndKeyFrom(const Node3 &other); }; +void Node3::copyChildrenAndKeyFrom(const Node3 &other) { + assert(numChildren == other.numChildren); + assert(partialKeyLen == other.partialKeyLen); + memcpy(index, other.index, + sizeof(*this) - offsetof(Node3, index) + partialKeyLen); +} + struct Node16 : Node { constexpr static auto kType = Type_Node16; constexpr static auto kMaxNodes = 16; @@ -261,8 +267,20 @@ struct Node16 : Node { uint8_t index[kMaxNodes]; Child children[kMaxNodes]; uint8_t *partialKey() { return (uint8_t *)(this + 1); } + + void copyChildrenAndKeyFrom(const Node16 &other); }; +void Node16::copyChildrenAndKeyFrom(const Node16 &other) { + assert(numChildren == other.numChildren); + assert(partialKeyLen == other.partialKeyLen); + memcpy(index, other.index, sizeof(index)); + for (int i = 0; i < numChildren; ++i) { + children[i] = other.children[i]; + } + memcpy(partialKey(), &other + 1, partialKeyLen); +} + struct Node48 : Node { constexpr static auto kType = Type_Node48; BitSet bitSet; @@ -859,12 +877,7 @@ void freeAndMakeCapacityAtLeast(Node *&self, int capacity, auto *newSelf = allocators->node3.allocate(capacity); memcpy((char *)newSelf + kNodeCopyBegin, (char *)self + kNodeCopyBegin, kNodeCopySize); - memcpy(newSelf->partialKey(), self3->partialKey(), self->partialKeyLen); - // TODO replace with memcpy? - for (int i = 0; i < Node3::kMaxNodes; ++i) { - newSelf->index[i] = self3->index[i]; - newSelf->children[i] = self3->children[i]; - } + newSelf->copyChildrenAndKeyFrom(*self3); getInTree(self, impl) = newSelf; setChildrenParents(newSelf); if constexpr (kUseFreeList) { @@ -880,12 +893,7 @@ void freeAndMakeCapacityAtLeast(Node *&self, int capacity, auto *newSelf = allocators->node16.allocate(capacity); memcpy((char *)newSelf + kNodeCopyBegin, (char *)self + kNodeCopyBegin, kNodeCopySize); - memcpy(newSelf->partialKey(), self16->partialKey(), self->partialKeyLen); - // TODO replace with memcpy? - for (int i = 0; i < Node16::kMaxNodes; ++i) { - newSelf->index[i] = self16->index[i]; - newSelf->children[i] = self16->children[i]; - } + newSelf->copyChildrenAndKeyFrom(*self16); getInTree(self, impl) = newSelf; setChildrenParents(newSelf); if constexpr (kUseFreeList) {