diff --git a/ConflictSet.cpp b/ConflictSet.cpp index d7470e1..cd51279 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1779,6 +1779,7 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, } // [begin, end) is now the half-open interval of children we're interested in. + assert(begin < end); const unsigned shiftUpperBound = end - begin; const unsigned shiftAmount = begin; @@ -1825,31 +1826,54 @@ bool checkMaxBetweenExclusive(Node *n, int begin, int end, } const int firstPage = begin >> Node256::kMaxOfMaxShift; const int lastPage = (end - 1) >> Node256::kMaxOfMaxShift; + if (firstPage == lastPage) { + if (self->maxOfMax[firstPage] <= readVersion) { + return true; + } + uint64_t conflict = 0; + // Check all in page + for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) { + conflict |= + (self->childMaxVersion[(firstPage << Node256::kMaxOfMaxShift) + i] > + readVersion) + << i; + } + // Mask away out of bounds + const int intraPageBegin = begin & (Node256::kMaxOfMaxPageSize - 1); + const int intraPageEnd = end - (lastPage << Node256::kMaxOfMaxShift); + conflict &= (1 << intraPageEnd) - 1; + conflict >>= intraPageBegin; + return !conflict; + } // Check the first page if (self->maxOfMax[firstPage] > readVersion) { - bool result = true; + uint64_t conflict = 0; for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) { - int j = (begin & ~(Node256::kMaxOfMaxPageSize - 1)) + i; - result &= !((self->childMaxVersion[j] > readVersion) & inBounds(j)); + int j = (firstPage << Node256::kMaxOfMaxShift) + i; + conflict |= (self->childMaxVersion[j] > readVersion) << i; } - if (!result) { - return result; + const int intraPageBegin = begin & (Node256::kMaxOfMaxPageSize - 1); + conflict >>= intraPageBegin; + if (conflict) { + return false; } } // Check the last page if (self->maxOfMax[lastPage] > readVersion) { - bool result = true; + uint64_t conflict = 0; for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) { - int j = ((end - 1) & ~(Node256::kMaxOfMaxPageSize - 1)) + i; - result &= !((self->childMaxVersion[j] > readVersion) & inBounds(j)); + int j = (lastPage << Node256::kMaxOfMaxShift) + i; + conflict |= (self->childMaxVersion[j] > readVersion) << i; } - if (!result) { - return result; + const int intraPageEnd = end - (lastPage << Node256::kMaxOfMaxShift); + conflict &= (1 << intraPageEnd) - 1; + if (conflict) { + return false; } } uint64_t conflict = 0; - // Check all pages - for (int i = 0; i < Node256::kMaxOfMaxTotalPages; ++i) { + // Check all possible inner pages + for (int i = 1; i < Node256::kMaxOfMaxTotalPages - 1; ++i) { conflict |= (self->maxOfMax[i] > readVersion) << i; } // Only keep inner pages