From c52d50f4f95f6b6aae4bad2d78d92fde9d007097 Mon Sep 17 00:00:00 2001 From: Andrew Noyes Date: Sat, 29 Jun 2024 22:53:51 -0700 Subject: [PATCH] Remove bounds from forEachInRange --- ConflictSet.cpp | 132 ++++++++++++++++-------------------------------- 1 file changed, 43 insertions(+), 89 deletions(-) diff --git a/ConflictSet.cpp b/ConflictSet.cpp index ac3df16..6f09a34 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -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 void forEachInRange(F f, int begin, int end) const { + template 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); }