diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 31b7eb6..4cb75b1 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -2007,23 +2007,7 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, case Type_Node3: { auto *self = static_cast(n); - { - int c = begin == 255 ? -1 : getChildGeqSimd(self, begin + 1); - if (c >= 0 && c < end) { - auto *child = self->children[getNodeIndex(self, c)]; - if (child->entryPresent) { - if (!(child->entry.rangeVersion <= readVersion)) { - return false; - }; - } - begin = c; - } else { - return true; - } - // [begin, end) is now the half-open interval of children we're interested - // in. - assert(begin < end); - } + ++begin; const unsigned shiftUpperBound = end - begin; const unsigned shiftAmount = begin; @@ -2031,15 +2015,23 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, return c - shiftAmount < shiftUpperBound; }; - uint32_t compared = 0; - for (int i = 0; i < Node3::kMaxNodes; ++i) { - compared |= (self->childMaxVersion[i] > readVersion) << i; - } uint32_t mask = 0; for (int i = 0; i < Node3::kMaxNodes; ++i) { mask |= inBounds(self->index[i]) << i; } - return !(compared & mask); + mask &= (1 << self->numChildren) - 1; + if (!mask) { + return true; + } + auto *child = self->children[__builtin_ctz(mask)]; + const bool firstRangeOk = + !child->entryPresent || child->entry.rangeVersion <= readVersion; + uint32_t compared = 0; + for (int i = 0; i < Node3::kMaxNodes; ++i) { + compared |= (self->childMaxVersion[i] > readVersion) << i; + } + + return !(compared & mask) && firstRangeOk; } case Type_Node16: { auto *self = static_cast(n);