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