diff --git a/ConflictSet.cpp b/ConflictSet.cpp index a5404bd..9ba21a6 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -309,8 +309,11 @@ struct Node256 : Node { constexpr static auto kType = Type_Node256; BitSet bitSet; Child children[256]; - // Max of each "page" of 16 children - int64_t maxOfMax[16]; + constexpr static int kMaxOfMaxPageSize = 8; + constexpr static int kMaxOfMaxShift = + std::countr_zero(uint32_t(kMaxOfMaxPageSize)); + constexpr static int kMaxOfMaxTotalPages = 256 / kMaxOfMaxPageSize; + int64_t maxOfMax[kMaxOfMaxTotalPages]; uint8_t *partialKey() { return (uint8_t *)(this + 1); } void copyChildrenAndKeyFrom(const Node48 &other); void copyChildrenAndKeyFrom(const Node256 &other); @@ -471,8 +474,9 @@ inline void Node256::copyChildrenAndKeyFrom(const Node48 &other) { children[c] = other.children[other.index[c]]; assert(children[c].child->parent == &other); children[c].child->parent = this; - maxOfMax[c >> 4] = - std::max(maxOfMax[c >> 4], children[c].childMaxVersion); + maxOfMax[c >> Node256::kMaxOfMaxShift] = + std::max(maxOfMax[c >> Node256::kMaxOfMaxShift], + children[c].childMaxVersion); }, 0, 256); memcpy(partialKey(), &other + 1, partialKeyLen); @@ -1713,10 +1717,10 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, case Type_Node256: { auto *self = static_cast(n); // Check the first page - if (self->maxOfMax[begin >> 4] > readVersion) { + if (self->maxOfMax[begin >> Node256::kMaxOfMaxShift] > readVersion) { bool result = true; - for (int i = 0; i < 16; ++i) { - int j = (begin & ~15) + i; + for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) { + int j = (begin & ~(Node256::kMaxOfMaxPageSize - 1)) + i; result &= !((self->children[j].childMaxVersion > readVersion) & (begin <= j) & (j < end)); } @@ -1725,10 +1729,11 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, } } // Check the last page - if (end >= 1 && self->maxOfMax[(end - 1) >> 4] > readVersion) { + if (end >= 1 && + self->maxOfMax[(end - 1) >> Node256::kMaxOfMaxShift] > readVersion) { bool result = true; - for (int i = 0; i < 16; ++i) { - int j = ((end - 1) & ~15) + i; + for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) { + int j = ((end - 1) & ~(Node256::kMaxOfMaxPageSize - 1)) + i; result &= !((self->children[j].childMaxVersion > readVersion) & (begin <= j) & (j < end)); } @@ -1738,9 +1743,10 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, } // Check inner pages bool result = true; - for (int i = 0; i < 16; ++i) { - result &= !((self->maxOfMax[i] > readVersion) & ((begin >> 4) + 1 <= i) & - (i < ((end - 1) >> 4))); + for (int i = 1; i < Node256::kMaxOfMaxTotalPages - 1; ++i) { + result &= !((self->maxOfMax[i] > readVersion) & + ((begin >> Node256::kMaxOfMaxShift) + 1 <= i) & + (i < ((end - 1) >> Node256::kMaxOfMaxShift))); } return result; } @@ -2676,7 +2682,8 @@ void setMaxVersion(Node *n, ConflictSet::Impl *impl, int64_t newMax) { auto *n256 = static_cast(n); assert(n256->bitSet.test(index)); n256->children[index].childMaxVersion = newMax; - n256->maxOfMax[index >> 4] = std::max(n256->maxOfMax[index >> 4], newMax); + n256->maxOfMax[index >> Node256::kMaxOfMaxShift] = + std::max(n256->maxOfMax[index >> Node256::kMaxOfMaxShift], newMax); return; } default: // GCOVR_EXCL_LINE