WIP add leaf types. Not used yet

This commit is contained in:
2024-11-22 17:59:42 -08:00
parent e5e6402b43
commit 8b71852495
2 changed files with 116 additions and 9 deletions

View File

@@ -32,12 +32,8 @@ if(NOT CMAKE_BUILD_TYPE AND NOT CMAKE_CONFIGURATION_TYPES)
endif()
add_compile_options(
-Werror=switch-enum
-Wswitch-enum
-Wunused-variable
-fPIC
-fdata-sections
-ffunction-sections
# -Werror=switch-enum
-Wswitch-enum -Wunused-variable -fPIC -fdata-sections -ffunction-sections
-fno-jump-tables # https://github.com/llvm/llvm-project/issues/54247
)

View File

@@ -212,6 +212,10 @@ enum Type : int8_t {
Type_Node16,
Type_Node48,
Type_Node256,
Type_Leaf3,
Type_Leaf16,
Type_Leaf48,
Type_Leaf256,
};
template <class T> struct NodeAllocator;
@@ -428,6 +432,22 @@ struct Node256 : Node {
size_t size() const { return sizeof(Node256) + getCapacity(); }
};
struct Leaf3 {
constexpr static auto kType = Type_Leaf3;
};
struct Leaf16 {
constexpr static auto kType = Type_Leaf16;
};
struct Leaf48 {
constexpr static auto kType = Type_Leaf48;
};
struct Leaf256 {
constexpr static auto kType = Type_Leaf256;
};
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>)
@@ -765,6 +785,10 @@ uint8_t *Node::partialKey() {
return ((Node48 *)this)->partialKey();
case Type_Node256:
return ((Node256 *)this)->partialKey();
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1038,6 +1062,10 @@ TaggedNodePointer &getChildExists(Node *self, uint8_t index) {
case Type_Node256: {
return getChildExists(static_cast<Node256 *>(self), index);
}
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1071,12 +1099,15 @@ InternalVersionT maxVersion(Node *n) {
assert(n256->bitSet.test(index));
return n256->childMaxVersion[index];
}
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
}
// Precondition `n` is not the root
InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax) {
int index = n->parentsIndex;
n = n->parent;
@@ -1104,6 +1135,10 @@ InternalVersionT exchangeMaxVersion(Node *n, InternalVersionT newMax) {
assert(n256->bitSet.test(index));
return std::exchange(n256->childMaxVersion[index], newMax);
}
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1149,6 +1184,10 @@ void setMaxVersion(Node *n, InternalVersionT newMax) {
n256->maxOfMax[index >> Node256::kMaxOfMaxShift], newMax);
return;
}
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1185,6 +1224,11 @@ TaggedNodePointer getChild(Node *self, uint8_t index) {
return getChild(static_cast<Node48 *>(self), index);
case Type_Node256:
return getChild(static_cast<Node256 *>(self), index);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return nullptr;
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1200,7 +1244,9 @@ struct ChildAndMaxVersion {
}
};
ChildAndMaxVersion getChildAndMaxVersion(Node0 *, uint8_t) { return {}; }
ChildAndMaxVersion getChildAndMaxVersion(Node0 *, uint8_t) {
return ChildAndMaxVersion::empty();
}
ChildAndMaxVersion getChildAndMaxVersion(Node3 *self, uint8_t index) {
int i = getNodeIndex(self, index);
if (i < 0) {
@@ -1238,6 +1284,11 @@ ChildAndMaxVersion getChildAndMaxVersion(Node *self, uint8_t index) {
return getChildAndMaxVersion(static_cast<Node48 *>(self), index);
case Type_Node256:
return getChildAndMaxVersion(static_cast<Node256 *>(self), index);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return ChildAndMaxVersion::empty();
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1320,6 +1371,11 @@ TaggedNodePointer getChildGeq(Node *self, int child) {
return getChildGeq(static_cast<Node48 *>(self), child);
case Type_Node256:
return getChildGeq(static_cast<Node256 *>(self), child);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return nullptr;
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -1357,6 +1413,11 @@ TaggedNodePointer getFirstChild(Node *self) {
return getFirstChild(static_cast<Node48 *>(self));
case Type_Node256:
return getFirstChild(static_cast<Node256 *>(self));
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return nullptr;
default:
__builtin_unreachable();
}
@@ -2396,6 +2457,10 @@ checkMaxBetweenExclusive(Node *n, int begin, int end,
case Type_Node256:
return checkMaxBetweenExclusiveImpl<true>(static_cast<Node256 *>(n), begin,
end, readVersion);
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2421,6 +2486,10 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end,
case Type_Node256:
return checkMaxBetweenExclusiveImpl<false>(static_cast<Node256 *>(n), begin,
end, readVersion);
case Type_Leaf3: // GCOVR_EXCL_LINE
case Type_Leaf16: // GCOVR_EXCL_LINE
case Type_Leaf48: // GCOVR_EXCL_LINE
case Type_Leaf256: // GCOVR_EXCL_LINE
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2539,6 +2608,11 @@ TrivialSpan IteratorBase::partialKey() {
return as<Node48>().partialKey();
case Type_Node256:
return as<Node256>().partialKey();
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return {};
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2556,6 +2630,11 @@ IteratorBase IteratorBase::getFirstChild() {
return as<Node48>().getFirstChild();
case Type_Node256:
return as<Node256>().getFirstChild();
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return {};
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2574,6 +2653,11 @@ IteratorBase::getChildAndMaxVersion(int index) {
return as<Node48>().getChildAndMaxVersion(index);
case Type_Node256:
return as<Node256>().getChildAndMaxVersion(index);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return {};
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2591,6 +2675,11 @@ IteratorBase IteratorBase::getChildGeq(int index) {
return as<Node48>().getChildGeq(index);
case Type_Node256:
return as<Node256>().getChildGeq(index);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return {};
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
@@ -2608,12 +2697,34 @@ IteratorBase IteratorBase::getChild(int index) {
return as<Node48>().getChild(index);
case Type_Node256:
return as<Node256>().getChild(index);
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return {};
default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
}
InternalVersionT IteratorBase::getMaxVersion() { return ::maxVersion(node); }
InternalVersionT IteratorBase::getMaxVersion() {
switch (type) {
case Type_Node0:
case Type_Node3:
case Type_Node16:
case Type_Node48:
case Type_Node256:
return ::maxVersion(node);
case Type_Leaf3:
return static_cast<Node3 *>(node)->childMaxVersion[index];
case Type_Leaf16:
return static_cast<Node16 *>(node)->childMaxVersion[index];
case Type_Leaf48:
return static_cast<Node48 *>(node)->childMaxVersion[index];
case Type_Leaf256:
return static_cast<Node256 *>(node)->childMaxVersion[index];
}
}
bool IteratorBase::checkRangeVersionOfFirstGeq(InternalVersionT readVersion) {
return ::checkRangeVersionOfFirstGeq(node, readVersion);