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

This commit is contained in:
2024-06-28 14:34:48 -07:00
parent 0e96177f5c
commit ff81890921

View File

@@ -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;