Speed up maxBetweenExclusive

This commit is contained in:
2024-02-15 17:03:19 -08:00
parent e30922ab9c
commit 4506b460eb

View File

@@ -100,6 +100,8 @@ struct BitSet {
}
int firstSetGeq(int i) const {
assert(0 <= i);
assert(i < 256);
if (i < 128) {
int a = std::countr_zero(lo >> i);
if (a < 128) {
@@ -126,7 +128,10 @@ struct Node48 : Node {
Node *children[48] = {};
int8_t nextFree = 0;
int8_t index[256];
Node48() { this->type = Type::Node48; }
Node48() {
memset(index, -1, 256);
this->type = Type::Node48;
}
};
struct Node256 : Node {
@@ -443,7 +448,7 @@ void eraseChild(Node *self, uint8_t index) {
} else if (self->type == Type::Node48) {
auto *self48 = static_cast<Node48 *>(self);
self48->bitSet.reset(index);
int8_t toRemoveChildrenIndex = self48->index[index];
int8_t toRemoveChildrenIndex = std::exchange(self48->index[index], -1);
int8_t lastChildrenIndex = --self48->nextFree;
assert(toRemoveChildrenIndex >= 0);
assert(lastChildrenIndex >= 0);
@@ -730,18 +735,60 @@ downLeftSpine:
}
int64_t maxBetweenExclusive(Node *n, int begin, int end) {
assert(-1 <= begin);
assert(begin <= 256);
assert(-1 <= end);
assert(end <= 256);
assert(begin < end);
int64_t result = std::numeric_limits<int64_t>::lowest();
int next = begin;
for (;;) {
next = getChildGeq(n, next + 1);
if (next < 0 || next >= end) {
break;
{
int c = getChildGeq(n, begin + 1);
if (c >= 0 && c < end) {
auto *child = getChildExists(n, c);
if (child->entryPresent) {
result = std::max(result, child->entry.rangeVersion);
}
}
auto *child = getChildExists(n, next);
if (child->entryPresent) {
result = std::max(result, child->entry.rangeVersion);
}
switch (n->type) {
case Type::Node4: {
auto *self = static_cast<Node4 *>(n);
for (int i = 0; i < self->numChildren && self->index[i] < end; ++i) {
if (begin < self->index[i]) {
result = std::max(result, self->children[i]->maxVersion);
}
}
result = std::max(result, child->maxVersion);
break;
}
case Type::Node16: {
auto *self = static_cast<Node16 *>(n);
for (int i = 0; i < self->numChildren && self->index[i] < end; ++i) {
if (begin < self->index[i]) {
result = std::max(result, self->children[i]->maxVersion);
}
}
break;
}
case Type::Node48: {
auto *self = static_cast<Node48 *>(n);
for (int i = begin + 1; i < end; ++i) {
if (self->index[i] != -1) {
result = std::max(result, self->children[self->index[i]]->maxVersion);
}
}
break;
}
case Type::Node256: {
auto *self = static_cast<Node256 *>(n);
for (int i = begin + 1; i < end; ++i) {
if (self->children[i] != nullptr) {
result = std::max(result, self->children[i]->maxVersion);
}
}
break;
}
case Type::Invalid:
__builtin_unreachable(); // GCOVR_EXCL_LINE
}
#if DEBUG_VERBOSE && !defined(NDEBUG)
fprintf(stderr, "At `%s', max version in (%02x, %02x) is %" PRId64 "\n",