Update some of the invariant checks to account for leaves
Some checks failed
Tests / 64 bit versions total: 8331, passed: 8331
Tests / Debug total: 8329, passed: 8329
Tests / SIMD fallback total: 8331, passed: 8331
weaselab/conflict-set/pipeline/head There was a failure building this commit

This commit is contained in:
2024-11-22 18:39:45 -08:00
parent 235938b5aa
commit 55e23bafba

View File

@@ -269,14 +269,22 @@ struct TaggedNodePointer {
TaggedNodePointer(const TaggedNodePointer &) = default;
TaggedNodePointer &operator=(const TaggedNodePointer &) = default;
/*implicit*/ TaggedNodePointer(Node *n);
// Leaf constructor
TaggedNodePointer(InternalVersionT rangeVersion, struct Node *parent);
void prefetch() {
// __builtin_prefetch is ok even if argument isn't addressable
__builtin_prefetch((void *)withoutType());
}
bool isLeaf() { return getType() > Type_Node256; }
bool isLeaf() { return (p & uintptr_t(15)) > Type_Node256; }
InternalVersionT rangeVersion() {
assert(isLeaf());
return InternalVersionT(p >> 32);
}
private:
TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) {
@@ -323,6 +331,12 @@ private:
TaggedNodePointer::TaggedNodePointer(Node *n)
: TaggedNodePointer(n, n->getType()) {}
TaggedNodePointer::TaggedNodePointer(InternalVersionT rangeVersion, Node *n) {
p = rangeVersion.toInt64();
p <<= 32;
p |= n->getType();
}
Type TaggedNodePointer::getType() {
assert(p != 0);
prefetch();
@@ -6096,18 +6110,27 @@ void checkVersionsGeqOldestExtant(Node *n,
[[maybe_unused]] auto *self = static_cast<Node3 *>(n);
for (int i = 0; i < 3; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
}
} break;
case Type_Node16: {
[[maybe_unused]] auto *self = static_cast<Node16 *>(n);
for (int i = 0; i < 16; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
}
} break;
case Type_Node48: {
auto *self = static_cast<Node48 *>(n);
for (int i = 0; i < 48; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (i < self->numChildren && self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
}
for ([[maybe_unused]] auto m : self->maxOfMax) {
assert(m >= oldestExtantVersion);
@@ -6117,11 +6140,18 @@ void checkVersionsGeqOldestExtant(Node *n,
auto *self = static_cast<Node256 *>(n);
for (int i = 0; i < 256; ++i) {
assert(self->childMaxVersion[i] >= oldestExtantVersion);
if (self->children[i].isLeaf()) {
assert(self->children[i].rangeVersion() >= oldestExtantVersion);
}
}
for ([[maybe_unused]] auto m : self->maxOfMax) {
assert(m >= oldestExtantVersion);
}
} break;
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
default:
abort();
}
@@ -6180,9 +6210,10 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
return total;
}
[[maybe_unused]] void checkMemoryBoundInvariants(Node *node, bool &success) {
[[maybe_unused]] void checkMemoryBoundInvariants(TaggedNodePointer node,
bool &success) {
int minNumChildren;
switch (node->getType()) {
switch (node.getType()) {
case Type_Node0:
minNumChildren = kMinChildrenNode0;
break;
@@ -6198,6 +6229,11 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
case Type_Node256:
minNumChildren = kMinChildrenNode256;
break;
case Type_Leaf3:
case Type_Leaf16:
case Type_Leaf48:
case Type_Leaf256:
return;
default:
abort();
}
@@ -6219,8 +6255,9 @@ checkMaxVersion(Node *root, Node *node, InternalVersionT oldestVersion,
success = false;
}
for (auto child = getChildGeq(node, 0); child != nullptr;
child = getChildGeq(node, child->parentsIndex + 1)) {
// Safety: if node were a leaf we would have returned by now
for (auto child = getChildGeq(node.asNodeUnsafe(), 0); child != nullptr;
child = getChildGeq(node.asNodeUnsafe(), child->parentsIndex + 1)) {
checkMemoryBoundInvariants(child, success);
}
}