Rename MaxVersionT to InternalVersionT
Some checks failed
Tests / Clang total: 1038, passed: 1038
Clang |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / SIMD fallback total: 1038, passed: 1038
Tests / Release [gcc] total: 1038, passed: 1038
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 775, passed: 775
Tests / Coverage total: 779, passed: 779
weaselab/conflict-set/pipeline/head There was a failure building this commit
Some checks failed
Tests / Clang total: 1038, passed: 1038
Clang |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / SIMD fallback total: 1038, passed: 1038
Tests / Release [gcc] total: 1038, passed: 1038
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend
|:-:|:-:|:-:|:-:|:-:
|0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 775, passed: 775
Tests / Coverage total: 779, passed: 779
weaselab/conflict-set/pipeline/head There was a failure building this commit
This commit is contained in:
104
ConflictSet.cpp
104
ConflictSet.cpp
@@ -72,9 +72,11 @@ constexpr void removeKey(struct Node *) {}
|
||||
|
||||
// ==================== BEGIN IMPLEMENTATION ====================
|
||||
|
||||
using InternalVersionT = int64_t;
|
||||
|
||||
struct Entry {
|
||||
int64_t pointVersion;
|
||||
int64_t rangeVersion;
|
||||
InternalVersionT pointVersion;
|
||||
InternalVersionT rangeVersion;
|
||||
};
|
||||
|
||||
struct BitSet {
|
||||
@@ -242,8 +244,6 @@ constexpr int kNodeCopySize =
|
||||
// children's parent pointers. The caller must then insert the new node into the
|
||||
// tree.
|
||||
|
||||
using MaxVersionT = int64_t;
|
||||
|
||||
struct Node0 : Node {
|
||||
constexpr static auto kType = Type_Node0;
|
||||
uint8_t *partialKey() { return (uint8_t *)(this + 1); }
|
||||
@@ -260,7 +260,7 @@ struct Node3 : Node {
|
||||
// Sorted
|
||||
uint8_t index[kMaxNodes];
|
||||
Node *children[kMaxNodes];
|
||||
MaxVersionT childMaxVersion[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
uint8_t *partialKey() { return (uint8_t *)(this + 1); }
|
||||
|
||||
void copyChildrenAndKeyFrom(const Node0 &other);
|
||||
@@ -276,7 +276,7 @@ struct Node16 : Node {
|
||||
// Sorted
|
||||
uint8_t index[kMaxNodes];
|
||||
Node *children[kMaxNodes];
|
||||
MaxVersionT childMaxVersion[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
uint8_t *partialKey() { return (uint8_t *)(this + 1); }
|
||||
|
||||
void copyChildrenAndKeyFrom(const Node3 &other);
|
||||
@@ -293,13 +293,13 @@ struct Node48 : Node {
|
||||
int8_t nextFree;
|
||||
int8_t index[256];
|
||||
Node *children[kMaxNodes];
|
||||
MaxVersionT childMaxVersion[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
uint8_t reverseIndex[kMaxNodes];
|
||||
constexpr static int kMaxOfMaxPageSize = 16;
|
||||
constexpr static int kMaxOfMaxShift =
|
||||
std::countr_zero(uint32_t(kMaxOfMaxPageSize));
|
||||
constexpr static int kMaxOfMaxTotalPages = kMaxNodes / kMaxOfMaxPageSize;
|
||||
MaxVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
InternalVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
|
||||
uint8_t *partialKey() { return (uint8_t *)(this + 1); }
|
||||
|
||||
@@ -314,12 +314,12 @@ struct Node256 : Node {
|
||||
constexpr static auto kType = Type_Node256;
|
||||
BitSet bitSet;
|
||||
Node *children[256];
|
||||
MaxVersionT childMaxVersion[256];
|
||||
InternalVersionT childMaxVersion[256];
|
||||
constexpr static int kMaxOfMaxPageSize = 16;
|
||||
constexpr static int kMaxOfMaxShift =
|
||||
std::countr_zero(uint32_t(kMaxOfMaxPageSize));
|
||||
constexpr static int kMaxOfMaxTotalPages = 256 / kMaxOfMaxPageSize;
|
||||
MaxVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
InternalVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
uint8_t *partialKey() { return (uint8_t *)(this + 1); }
|
||||
void copyChildrenAndKeyFrom(const Node48 &other);
|
||||
void copyChildrenAndKeyFrom(const Node256 &other);
|
||||
@@ -789,9 +789,9 @@ Node *&getChildExists(Node *self, uint8_t index) {
|
||||
}
|
||||
}
|
||||
|
||||
int64_t maxVersion(Node *n, ConflictSet::Impl *);
|
||||
InternalVersionT maxVersion(Node *n, ConflictSet::Impl *);
|
||||
|
||||
void setMaxVersion(Node *n, ConflictSet::Impl *, int64_t maxVersion);
|
||||
void setMaxVersion(Node *n, ConflictSet::Impl *, InternalVersionT maxVersion);
|
||||
|
||||
Node *&getInTree(Node *n, ConflictSet::Impl *);
|
||||
|
||||
@@ -1269,7 +1269,7 @@ void maybeDownsize(Node *self, NodeAllocators *allocators,
|
||||
getSearchPathPrintable(child).c_str());
|
||||
#endif
|
||||
|
||||
int64_t childMaxVersion = maxVersion(child, impl);
|
||||
InternalVersionT childMaxVersion = maxVersion(child, impl);
|
||||
|
||||
// Construct new partial key for child
|
||||
memmove(child->partialKey() + self3->partialKeyLen + 1,
|
||||
@@ -1638,7 +1638,7 @@ struct SearchStepWise {
|
||||
// point or range version according to cmp, but this version short circuits as
|
||||
// soon as it can prove that there's no conflict.
|
||||
bool checkPointRead(Node *n, const std::span<const uint8_t> key,
|
||||
int64_t readVersion, ConflictSet::Impl *impl) {
|
||||
InternalVersionT readVersion, ConflictSet::Impl *impl) {
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "Check point read: %s\n", printable(key).c_str());
|
||||
#endif
|
||||
@@ -1712,8 +1712,8 @@ downLeftSpine:
|
||||
}
|
||||
|
||||
// Returns true if all in-bounds vs are <= readVersion
|
||||
bool scan16(const MaxVersionT *vs, const uint8_t *is, int begin, int end,
|
||||
int64_t readVersion) {
|
||||
bool scan16(const InternalVersionT *vs, const uint8_t *is, int begin, int end,
|
||||
InternalVersionT readVersion) {
|
||||
|
||||
assert(end - begin < 256);
|
||||
|
||||
@@ -1771,7 +1771,7 @@ bool scan16(const MaxVersionT *vs, const uint8_t *is, int begin, int end,
|
||||
// path of n + [child], where child in (begin, end) is <= readVersion. Does not
|
||||
// account for the range version of firstGt(searchpath(n) + [end - 1])
|
||||
bool checkMaxBetweenExclusive(Node *n, int begin, int end,
|
||||
int64_t readVersion) {
|
||||
InternalVersionT readVersion) {
|
||||
assume(-1 <= begin);
|
||||
assume(begin <= 256);
|
||||
assume(-1 <= end);
|
||||
@@ -1928,7 +1928,7 @@ Vector<uint8_t> getSearchPath(Arena &arena, Node *n) {
|
||||
// Precondition: transitively, no child of n has a search path that's a longer
|
||||
// prefix of key than n
|
||||
bool checkRangeStartsWith(Node *n, std::span<const uint8_t> key, int begin,
|
||||
int end, int64_t readVersion,
|
||||
int end, InternalVersionT readVersion,
|
||||
ConflictSet::Impl *impl) {
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "%s(%02x,%02x)*\n", printable(key).c_str(), begin, end);
|
||||
@@ -2000,7 +2000,7 @@ downLeftSpine:
|
||||
// that are >= key is <= readVersion
|
||||
struct CheckRangeLeftSide {
|
||||
CheckRangeLeftSide(Node *n, std::span<const uint8_t> key, int prefixLen,
|
||||
int64_t readVersion, ConflictSet::Impl *impl)
|
||||
InternalVersionT readVersion, ConflictSet::Impl *impl)
|
||||
: n(n), remaining(key), prefixLen(prefixLen), readVersion(readVersion),
|
||||
impl(impl) {
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
@@ -2013,7 +2013,7 @@ struct CheckRangeLeftSide {
|
||||
Node *n;
|
||||
std::span<const uint8_t> remaining;
|
||||
int prefixLen;
|
||||
int64_t readVersion;
|
||||
InternalVersionT readVersion;
|
||||
ConflictSet::Impl *impl;
|
||||
int searchPathLen = 0;
|
||||
bool ok;
|
||||
@@ -2119,7 +2119,7 @@ struct CheckRangeLeftSide {
|
||||
// that are < key is <= readVersion
|
||||
struct CheckRangeRightSide {
|
||||
CheckRangeRightSide(Node *n, std::span<const uint8_t> key, int prefixLen,
|
||||
int64_t readVersion, ConflictSet::Impl *impl)
|
||||
InternalVersionT readVersion, ConflictSet::Impl *impl)
|
||||
: n(n), key(key), remaining(key), prefixLen(prefixLen),
|
||||
readVersion(readVersion), impl(impl) {
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
@@ -2133,7 +2133,7 @@ struct CheckRangeRightSide {
|
||||
std::span<const uint8_t> key;
|
||||
std::span<const uint8_t> remaining;
|
||||
int prefixLen;
|
||||
int64_t readVersion;
|
||||
InternalVersionT readVersion;
|
||||
ConflictSet::Impl *impl;
|
||||
int searchPathLen = 0;
|
||||
bool ok;
|
||||
@@ -2251,7 +2251,7 @@ struct CheckRangeRightSide {
|
||||
};
|
||||
|
||||
bool checkRangeRead(Node *n, std::span<const uint8_t> begin,
|
||||
std::span<const uint8_t> end, int64_t readVersion,
|
||||
std::span<const uint8_t> end, InternalVersionT readVersion,
|
||||
ConflictSet::Impl *impl) {
|
||||
int lcp = longestCommonPrefix(begin.data(), end.data(),
|
||||
std::min(begin.size(), end.size()));
|
||||
@@ -2328,9 +2328,9 @@ bool checkRangeRead(Node *n, std::span<const uint8_t> begin,
|
||||
// path of the result's parent will have `maxVersion` at least `writeVersion` as
|
||||
// a postcondition. Nodes along the search path to `key` may be invalidated.
|
||||
template <bool kBegin>
|
||||
[[nodiscard]] Node *insert(Node **self, std::span<const uint8_t> key,
|
||||
int64_t writeVersion, NodeAllocators *allocators,
|
||||
ConflictSet::Impl *impl) {
|
||||
[[nodiscard]] Node *
|
||||
insert(Node **self, std::span<const uint8_t> key, InternalVersionT writeVersion,
|
||||
NodeAllocators *allocators, ConflictSet::Impl *impl) {
|
||||
|
||||
for (;;) {
|
||||
|
||||
@@ -2341,7 +2341,7 @@ template <bool kBegin>
|
||||
longestCommonPrefix((*self)->partialKey(), key.data(), commonLen);
|
||||
if (partialKeyIndex < (*self)->partialKeyLen) {
|
||||
auto *old = *self;
|
||||
int64_t oldMaxVersion = maxVersion(old, impl);
|
||||
InternalVersionT oldMaxVersion = maxVersion(old, impl);
|
||||
|
||||
// *self will have one child
|
||||
*self = allocators->node3.allocate(partialKeyIndex);
|
||||
@@ -2440,8 +2440,8 @@ void destroyTree(Node *root) {
|
||||
}
|
||||
}
|
||||
|
||||
void addPointWrite(Node *&root, int64_t oldestVersion,
|
||||
std::span<const uint8_t> key, int64_t writeVersion,
|
||||
void addPointWrite(Node *&root, InternalVersionT oldestVersion,
|
||||
std::span<const uint8_t> key, InternalVersionT writeVersion,
|
||||
NodeAllocators *allocators, ConflictSet::Impl *impl) {
|
||||
auto *n = insert<true>(&root, key, writeVersion, allocators, impl);
|
||||
if (!n->entryPresent) {
|
||||
@@ -2460,9 +2460,9 @@ void addPointWrite(Node *&root, int64_t oldestVersion,
|
||||
}
|
||||
}
|
||||
|
||||
void addWriteRange(Node *&root, int64_t oldestVersion,
|
||||
void addWriteRange(Node *&root, InternalVersionT oldestVersion,
|
||||
std::span<const uint8_t> begin, std::span<const uint8_t> end,
|
||||
int64_t writeVersion, NodeAllocators *allocators,
|
||||
InternalVersionT writeVersion, NodeAllocators *allocators,
|
||||
ConflictSet::Impl *impl) {
|
||||
|
||||
int lcp = longestCommonPrefix(begin.data(), end.data(),
|
||||
@@ -2539,7 +2539,8 @@ void addWriteRange(Node *&root, int64_t oldestVersion,
|
||||
endNode->entry.pointVersion =
|
||||
p != nullptr ? p->entry.rangeVersion : oldestVersion;
|
||||
auto m = maxVersion(endNode, impl);
|
||||
setMaxVersion(endNode, impl, std::max(m, endNode->entry.pointVersion));
|
||||
setMaxVersion(endNode, impl,
|
||||
std::max<InternalVersionT>(m, endNode->entry.pointVersion));
|
||||
}
|
||||
endNode->entry.rangeVersion = writeVersion;
|
||||
|
||||
@@ -2640,7 +2641,8 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
void addWrites(const WriteRange *writes, int count, int64_t writeVersion) {
|
||||
void addWrites(const WriteRange *writes, int count,
|
||||
InternalVersionT writeVersion) {
|
||||
for (int i = 0; i < count; ++i) {
|
||||
const auto &w = writes[i];
|
||||
auto begin = std::span<const uint8_t>(w.begin.p, w.begin.len);
|
||||
@@ -2657,7 +2659,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
}
|
||||
}
|
||||
|
||||
void setOldestVersion(int64_t oldestVersion) {
|
||||
void setOldestVersion(InternalVersionT oldestVersion) {
|
||||
if (oldestVersion <= this->oldestVersion) {
|
||||
return;
|
||||
}
|
||||
@@ -2734,12 +2736,12 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
int64_t keyUpdates = 10;
|
||||
|
||||
Node *root;
|
||||
int64_t rootMaxVersion;
|
||||
int64_t oldestVersion;
|
||||
InternalVersionT rootMaxVersion;
|
||||
InternalVersionT oldestVersion;
|
||||
int64_t totalBytes = 0;
|
||||
};
|
||||
|
||||
int64_t maxVersion(Node *n, ConflictSet::Impl *impl) {
|
||||
InternalVersionT maxVersion(Node *n, ConflictSet::Impl *impl) {
|
||||
int index = n->parentsIndex;
|
||||
n = n->parent;
|
||||
if (n == nullptr) {
|
||||
@@ -2773,7 +2775,7 @@ int64_t maxVersion(Node *n, ConflictSet::Impl *impl) {
|
||||
}
|
||||
}
|
||||
|
||||
void setMaxVersion(Node *n, ConflictSet::Impl *impl, int64_t newMax) {
|
||||
void setMaxVersion(Node *n, ConflictSet::Impl *impl, InternalVersionT newMax) {
|
||||
int index = n->parentsIndex;
|
||||
n = n->parent;
|
||||
if (n == nullptr) {
|
||||
@@ -2800,7 +2802,7 @@ void setMaxVersion(Node *n, ConflictSet::Impl *impl, int64_t newMax) {
|
||||
assert(n48->bitSet.test(index));
|
||||
int i = n48->index[index];
|
||||
n48->childMaxVersion[i] = newMax;
|
||||
n48->maxOfMax[i >> Node48::kMaxOfMaxShift] = std::max<MaxVersionT>(
|
||||
n48->maxOfMax[i >> Node48::kMaxOfMaxShift] = std::max<InternalVersionT>(
|
||||
n48->maxOfMax[i >> Node48::kMaxOfMaxShift], newMax);
|
||||
return;
|
||||
}
|
||||
@@ -2808,8 +2810,9 @@ void setMaxVersion(Node *n, ConflictSet::Impl *impl, int64_t newMax) {
|
||||
auto *n256 = static_cast<Node256 *>(n);
|
||||
assert(n256->bitSet.test(index));
|
||||
n256->childMaxVersion[index] = newMax;
|
||||
n256->maxOfMax[index >> Node256::kMaxOfMaxShift] = std::max<MaxVersionT>(
|
||||
n256->maxOfMax[index >> Node256::kMaxOfMaxShift], newMax);
|
||||
n256->maxOfMax[index >> Node256::kMaxOfMaxShift] =
|
||||
std::max<InternalVersionT>(
|
||||
n256->maxOfMax[index >> Node256::kMaxOfMaxShift], newMax);
|
||||
return;
|
||||
}
|
||||
default: // GCOVR_EXCL_LINE
|
||||
@@ -3023,11 +3026,12 @@ std::string getSearchPath(Node *n) {
|
||||
fprintf(file,
|
||||
" k_%p [label=\"m=%" PRId64 " p=%" PRId64 " r=%" PRId64
|
||||
"\n%s\", pos=\"%d,%d!\"];\n",
|
||||
(void *)n, maxVersion(n, impl), n->entry.pointVersion,
|
||||
n->entry.rangeVersion, getPartialKeyPrintable(n).c_str(), x, y);
|
||||
(void *)n, int64_t(maxVersion(n, impl)),
|
||||
int64_t(n->entry.pointVersion), int64_t(n->entry.rangeVersion),
|
||||
getPartialKeyPrintable(n).c_str(), x, y);
|
||||
} else {
|
||||
fprintf(file, " k_%p [label=\"m=%" PRId64 "\n%s\", pos=\"%d,%d!\"];\n",
|
||||
(void *)n, maxVersion(n, impl),
|
||||
(void *)n, int64_t(maxVersion(n, impl)),
|
||||
getPartialKeyPrintable(n).c_str(), x, y);
|
||||
}
|
||||
x += kSeparation;
|
||||
@@ -3074,14 +3078,15 @@ Iterator firstGeq(Node *n, std::string_view key) {
|
||||
ConflictSet::Impl *impl) {
|
||||
int64_t expected = 0;
|
||||
if (node->entryPresent) {
|
||||
expected = std::max(expected, node->entry.pointVersion);
|
||||
expected = std::max<InternalVersionT>(expected, node->entry.pointVersion);
|
||||
}
|
||||
for (int i = getChildGeq(node, 0); i >= 0; i = getChildGeq(node, i + 1)) {
|
||||
auto *child = getChildExists(node, i);
|
||||
expected = std::max(
|
||||
expected, checkMaxVersion(root, child, oldestVersion, success, impl));
|
||||
if (child->entryPresent) {
|
||||
expected = std::max(expected, child->entry.rangeVersion);
|
||||
expected =
|
||||
std::max<InternalVersionT>(expected, child->entry.rangeVersion);
|
||||
}
|
||||
}
|
||||
auto key = getSearchPath(root);
|
||||
@@ -3090,14 +3095,15 @@ Iterator firstGeq(Node *n, std::string_view key) {
|
||||
if (ok) {
|
||||
auto borrowed = firstGeq(root, inc);
|
||||
if (borrowed.n != nullptr) {
|
||||
expected = std::max(expected, borrowed.n->entry.rangeVersion);
|
||||
expected =
|
||||
std::max<InternalVersionT>(expected, borrowed.n->entry.rangeVersion);
|
||||
}
|
||||
}
|
||||
if (maxVersion(node, impl) > oldestVersion &&
|
||||
maxVersion(node, impl) != expected) {
|
||||
fprintf(stderr, "%s has max version %" PRId64 " . Expected %" PRId64 "\n",
|
||||
getSearchPathPrintable(node).c_str(), maxVersion(node, impl),
|
||||
expected);
|
||||
getSearchPathPrintable(node).c_str(),
|
||||
int64_t(maxVersion(node, impl)), expected);
|
||||
success = false;
|
||||
}
|
||||
return expected;
|
||||
|
Reference in New Issue
Block a user