forked from weaselab/conflict-set
Vectorize all bounds checks for Node256 scan
This commit is contained in:
+36
-12
@@ -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.
|
// [begin, end) is now the half-open interval of children we're interested in.
|
||||||
|
assert(begin < end);
|
||||||
|
|
||||||
const unsigned shiftUpperBound = end - begin;
|
const unsigned shiftUpperBound = end - begin;
|
||||||
const unsigned shiftAmount = 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 firstPage = begin >> Node256::kMaxOfMaxShift;
|
||||||
const int lastPage = (end - 1) >> 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
|
// Check the first page
|
||||||
if (self->maxOfMax[firstPage] > readVersion) {
|
if (self->maxOfMax[firstPage] > readVersion) {
|
||||||
bool result = true;
|
uint64_t conflict = 0;
|
||||||
for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
|
for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
|
||||||
int j = (begin & ~(Node256::kMaxOfMaxPageSize - 1)) + i;
|
int j = (firstPage << Node256::kMaxOfMaxShift) + i;
|
||||||
result &= !((self->childMaxVersion[j] > readVersion) & inBounds(j));
|
conflict |= (self->childMaxVersion[j] > readVersion) << i;
|
||||||
}
|
}
|
||||||
if (!result) {
|
const int intraPageBegin = begin & (Node256::kMaxOfMaxPageSize - 1);
|
||||||
return result;
|
conflict >>= intraPageBegin;
|
||||||
|
if (conflict) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Check the last page
|
// Check the last page
|
||||||
if (self->maxOfMax[lastPage] > readVersion) {
|
if (self->maxOfMax[lastPage] > readVersion) {
|
||||||
bool result = true;
|
uint64_t conflict = 0;
|
||||||
for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
|
for (int i = 0; i < Node256::kMaxOfMaxPageSize; ++i) {
|
||||||
int j = ((end - 1) & ~(Node256::kMaxOfMaxPageSize - 1)) + i;
|
int j = (lastPage << Node256::kMaxOfMaxShift) + i;
|
||||||
result &= !((self->childMaxVersion[j] > readVersion) & inBounds(j));
|
conflict |= (self->childMaxVersion[j] > readVersion) << i;
|
||||||
}
|
}
|
||||||
if (!result) {
|
const int intraPageEnd = end - (lastPage << Node256::kMaxOfMaxShift);
|
||||||
return result;
|
conflict &= (1 << intraPageEnd) - 1;
|
||||||
|
if (conflict) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
uint64_t conflict = 0;
|
uint64_t conflict = 0;
|
||||||
// Check all pages
|
// Check all possible inner pages
|
||||||
for (int i = 0; i < Node256::kMaxOfMaxTotalPages; ++i) {
|
for (int i = 1; i < Node256::kMaxOfMaxTotalPages - 1; ++i) {
|
||||||
conflict |= (self->maxOfMax[i] > readVersion) << i;
|
conflict |= (self->maxOfMax[i] > readVersion) << i;
|
||||||
}
|
}
|
||||||
// Only keep inner pages
|
// Only keep inner pages
|
||||||
|
|||||||
Reference in New Issue
Block a user