Remove bounds from forEachInRange
Some checks failed
Tests / Clang total: 1039, passed: 1039
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / SIMD fallback total: 1039, passed: 1039
Tests / 32-bit versions total: 1039, passed: 1039
Tests / Release [gcc] total: 1039, passed: 1039
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 775, passed: 775
Tests / Coverage total: 780, passed: 780
weaselab/conflict-set/pipeline/head There was a failure building this commit

This commit is contained in:
2024-06-29 22:53:51 -07:00
parent 447da11d59
commit c52d50f4f9

View File

@@ -86,7 +86,7 @@ constexpr void removeKey(struct Node *) {}
struct InternalVersionT {
constexpr InternalVersionT() = default;
constexpr explicit InternalVersionT(int64_t value) : value(value) {}
constexpr int64_t toInt64() const { return value; }
constexpr int64_t toInt64() const { return value; } // GCOVR_EXCL_LINE
constexpr auto operator<=>(const InternalVersionT &rhs) const {
// Maintains ordering after overflow, as long as the full-precision versions
// are within ~2e9 of eachother.
@@ -103,7 +103,7 @@ thread_local InternalVersionT InternalVersionT::zero;
struct InternalVersionT {
constexpr InternalVersionT() = default;
constexpr explicit InternalVersionT(int64_t value) : value(value) {}
constexpr int64_t toInt64() const { return value; }
constexpr int64_t toInt64() const { return value; } // GCOVR_EXCL_LINE
constexpr auto operator<=>(const InternalVersionT &rhs) const = default;
constexpr bool operator==(const InternalVersionT &) const = default;
static const InternalVersionT zero;
@@ -126,37 +126,11 @@ struct BitSet {
int firstSetGeq(int i) const;
// Calls `f` with the index of each bit set in [begin, end)
template <class F> void forEachInRange(F f, int begin, int end) const {
template <class F> void forEachSet(F f) const {
// See section 3.1 in https://arxiv.org/pdf/1709.07821.pdf for details about
// this approach
if ((begin >> 6) == (end >> 6)) {
uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63)) &
~(uint64_t(-1) << (end & 63));
while (word) {
uint64_t temp = word & -word;
int index = (begin & ~63) + std::countr_zero(word);
f(index);
word ^= temp;
}
return;
}
// Check begin partial word
if (begin & 63) {
uint64_t word = words[begin >> 6] & (uint64_t(-1) << (begin & 63));
while (word) {
uint64_t temp = word & -word;
int index = (begin & ~63) + std::countr_zero(word);
f(index);
word ^= temp;
}
begin &= ~63;
begin += 64;
}
// Check inner, full words
while (begin != (end & ~63)) {
for (int begin = 0; begin < 256; begin += 64) {
uint64_t word = words[begin >> 6];
while (word) {
uint64_t temp = word & -word;
@@ -164,18 +138,6 @@ struct BitSet {
f(index);
word ^= temp;
}
begin += 64;
}
if (end & 63) {
// Check end partial word
uint64_t word = words[end >> 6] & ~(uint64_t(-1) << (end & 63));
while (word) {
uint64_t temp = word & -word;
int index = begin + std::countr_zero(word);
f(index);
word ^= temp;
}
}
}
@@ -425,19 +387,17 @@ inline void Node16::copyChildrenAndKeyFrom(const Node48 &other) {
memcpy((char *)this + kNodeCopyBegin, (char *)&other + kNodeCopyBegin,
kNodeCopySize);
int i = 0;
other.bitSet.forEachInRange(
[&](int c) {
// Suppress a false positive -Waggressive-loop-optimizations warning
// in gcc
assume(i < Node16::kMaxNodes);
index[i] = c;
children[i] = other.children[other.index[c]];
childMaxVersion[i] = other.childMaxVersion[other.index[c]];
assert(children[i]->parent == &other);
children[i]->parent = this;
++i;
},
0, 256);
other.bitSet.forEachSet([&](int c) {
// Suppress a false positive -Waggressive-loop-optimizations warning
// in gcc
assume(i < Node16::kMaxNodes);
index[i] = c;
children[i] = other.children[other.index[c]];
childMaxVersion[i] = other.childMaxVersion[other.index[c]];
assert(children[i]->parent == &other);
children[i]->parent = this;
++i;
});
memcpy(partialKey(), &other + 1, partialKeyLen);
}
@@ -500,22 +460,20 @@ inline void Node48::copyChildrenAndKeyFrom(const Node256 &other) {
nextFree = other.numChildren;
bitSet = other.bitSet;
int i = 0;
bitSet.forEachInRange(
[&](int c) {
// Suppress a false positive -Waggressive-loop-optimizations warning
// in gcc.
assume(i < Node48::kMaxNodes);
index[c] = i;
children[i] = other.children[c];
childMaxVersion[i] = other.childMaxVersion[c];
assert(children[i]->parent == &other);
children[i]->parent = this;
reverseIndex[i] = c;
maxOfMax[i >> Node48::kMaxOfMaxShift] =
std::max(maxOfMax[i >> Node48::kMaxOfMaxShift], childMaxVersion[i]);
++i;
},
0, 256);
bitSet.forEachSet([&](int c) {
// Suppress a false positive -Waggressive-loop-optimizations warning
// in gcc.
assume(i < Node48::kMaxNodes);
index[c] = i;
children[i] = other.children[c];
childMaxVersion[i] = other.childMaxVersion[c];
assert(children[i]->parent == &other);
children[i]->parent = this;
reverseIndex[i] = c;
maxOfMax[i >> Node48::kMaxOfMaxShift] =
std::max(maxOfMax[i >> Node48::kMaxOfMaxShift], childMaxVersion[i]);
++i;
});
memcpy(partialKey(), &other + 1, partialKeyLen);
}
@@ -530,16 +488,14 @@ inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) {
for (auto &v : maxOfMax) {
v = InternalVersionT::zero;
}
bitSet.forEachInRange(
[&](int c) {
children[c] = other.children[other.index[c]];
childMaxVersion[c] = other.childMaxVersion[other.index[c]];
assert(children[c]->parent == &other);
children[c]->parent = this;
maxOfMax[c >> Node256::kMaxOfMaxShift] = std::max(
maxOfMax[c >> Node256::kMaxOfMaxShift], childMaxVersion[c]);
},
0, 256);
bitSet.forEachSet([&](int c) {
children[c] = other.children[other.index[c]];
childMaxVersion[c] = other.childMaxVersion[other.index[c]];
assert(children[c]->parent == &other);
children[c]->parent = this;
maxOfMax[c >> Node256::kMaxOfMaxShift] =
std::max(maxOfMax[c >> Node256::kMaxOfMaxShift], childMaxVersion[c]);
});
memcpy(partialKey(), &other + 1, partialKeyLen);
}
@@ -551,14 +507,12 @@ inline void Node256::copyChildrenAndKeyFrom(const Node256 &other) {
v = InternalVersionT::zero;
}
bitSet = other.bitSet;
bitSet.forEachInRange(
[&](int c) {
children[c] = other.children[c];
childMaxVersion[c] = other.childMaxVersion[c];
assert(children[c]->parent == &other);
children[c]->parent = this;
},
0, 256);
bitSet.forEachSet([&](int c) {
children[c] = other.children[c];
childMaxVersion[c] = other.childMaxVersion[c];
assert(children[c]->parent == &other);
children[c]->parent = this;
});
memcpy(maxOfMax, other.maxOfMax, sizeof(maxOfMax));
memcpy(partialKey(), &other + 1, partialKeyLen);
}