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