Remove "memcpy common section to next node"

Do it in a simpler, more robust/type safe way
This commit is contained in:
2024-11-21 16:43:07 -08:00
parent 8694ba8b6a
commit 81323972aa
2 changed files with 25 additions and 34 deletions

View File

@@ -102,8 +102,6 @@ option(DISABLE_TSAN "Disable TSAN" OFF)
# https://valgrind.org/docs/manual/manual-core-adv.html#manual-core-adv.clientreq
include_directories(SYSTEM ${CMAKE_CURRENT_SOURCE_DIR}/third_party/valgrind)
add_compile_options($<$<COMPILE_LANGUAGE:CXX>:-Wno-invalid-offsetof>)
if(APPLE)
add_link_options(-Wl,-dead_strip)
else()

View File

@@ -281,7 +281,6 @@ private:
struct Node {
/* begin section that's copied to the next node */
union {
Entry entry;
/* Set to the forwarding point for this node if releaseDeferred is set */
@@ -292,7 +291,6 @@ struct Node {
int16_t numChildren;
bool entryPresent;
uint8_t parentsIndex;
/* end section that's copied to the next node */
/* If set, this node has been replaced and the next node in the forwarding
* chain is `forwardTo`*/
@@ -322,10 +320,6 @@ Type TaggedNodePointer::getType() {
return Type(p & uintptr_t(7));
}
constexpr int kNodeCopyBegin = offsetof(Node, entry);
constexpr int kNodeCopySize =
offsetof(Node, parentsIndex) + sizeof(Node::parentsIndex) - kNodeCopyBegin;
// copyChildrenAndKeyFrom is responsible for copying all
// public members of Node, copying the partial key, logically copying the
// children (converting representation if necessary), and updating all the
@@ -431,27 +425,35 @@ struct Node256 : Node {
size_t size() const { return sizeof(Node256) + getCapacity(); }
};
template <class To, class From>
void copyCommon(To &to, const From &from)
requires(std::is_base_of_v<Node, To> && std::is_base_of_v<Node, From>)
{
memcpy(&to.entry, &from.entry, sizeof(from.entry));
to.parent = from.parent;
to.partialKeyLen = from.partialKeyLen;
to.numChildren = from.numChildren;
to.entryPresent = from.entryPresent;
to.parentsIndex = from.parentsIndex;
}
inline void Node0::copyChildrenAndKeyFrom(const Node0 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(partialKey(), &other + 1, partialKeyLen);
}
inline void Node0::copyChildrenAndKeyFrom(const Node3 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(partialKey(), &other + 1, partialKeyLen);
}
inline void Node3::copyChildrenAndKeyFrom(const Node0 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(partialKey(), &other + 1, partialKeyLen);
}
inline void Node3::copyChildrenAndKeyFrom(const Node3 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(index, other.index, kMaxNodes);
memcpy(children, other.children, kMaxNodes * sizeof(children[0])); // NOLINT
memcpy(childMaxVersion, other.childMaxVersion,
@@ -464,8 +466,7 @@ inline void Node3::copyChildrenAndKeyFrom(const Node3 &other) {
}
inline void Node3::copyChildrenAndKeyFrom(const Node16 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(index, other.index, kMaxNodes);
memcpy(children, other.children, kMaxNodes * sizeof(children[0])); // NOLINT
memcpy(childMaxVersion, other.childMaxVersion,
@@ -478,8 +479,7 @@ inline void Node3::copyChildrenAndKeyFrom(const Node16 &other) {
}
inline void Node16::copyChildrenAndKeyFrom(const Node3 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(index, other.index, Node3::kMaxNodes);
memcpy(children, other.children,
Node3::kMaxNodes * sizeof(children[0])); // NOLINT
@@ -494,8 +494,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node3 &other) {
}
inline void Node16::copyChildrenAndKeyFrom(const Node16 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memcpy(index, other.index, sizeof(index));
for (int i = 0; i < numChildren; ++i) {
children[i] = other.children[i];
@@ -507,8 +506,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node16 &other) {
}
inline void Node16::copyChildrenAndKeyFrom(const Node48 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
int i = 0;
other.bitSet.forEachSet([&](int c) {
// Suppress a false positive -Waggressive-loop-optimizations warning
@@ -525,8 +523,7 @@ inline void Node16::copyChildrenAndKeyFrom(const Node48 &other) {
}
inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
assert(numChildren == Node16::kMaxNodes);
memset(index, -1, sizeof(index));
memset(children, 0, sizeof(children));
@@ -552,8 +549,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node16 &other) {
}
inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
bitSet = other.bitSet;
memcpy(index, other.index, sizeof(index));
memset(children, 0, sizeof(children));
@@ -573,8 +569,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node48 &other) {
}
inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memset(index, -1, sizeof(index));
memset(children, 0, sizeof(children));
const auto z = InternalVersionT::zero;
@@ -601,8 +596,7 @@ inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) {
}
inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
bitSet = other.bitSet;
memset(children, 0, sizeof(children));
const auto z = InternalVersionT::zero;
@@ -624,8 +618,7 @@ inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) {
}
inline void Node256::copyChildrenAndKeyFrom(const Node256 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
copyCommon(*this, other);
memset(children, 0, sizeof(children));
const auto z = InternalVersionT::zero;
for (auto &v : childMaxVersion) {