Compare commits
8 Commits
c3190c11ac
...
31ad3e8e1c
Author | SHA1 | Date | |
---|---|---|---|
31ad3e8e1c | |||
e213237698 | |||
a1c61962a1 | |||
a28283748c | |||
cafa540fc8 | |||
b9c642d81d | |||
7abb129f03 | |||
3739ccaaf2 |
@@ -38,6 +38,11 @@ if(NOT APPLE)
|
||||
add_compile_options(-g -fno-omit-frame-pointer)
|
||||
endif()
|
||||
|
||||
# work around lack of musttail for gcc
|
||||
if(CMAKE_CXX_COMPILER_ID STREQUAL "GNU" AND CMAKE_BUILD_TYPE STREQUAL "Debug")
|
||||
add_compile_options(-O1 -foptimize-sibling-calls)
|
||||
endif()
|
||||
|
||||
set(full_relro_flags "-pie;LINKER:-z,relro,-z,now,-z,noexecstack")
|
||||
cmake_push_check_state()
|
||||
list(APPEND CMAKE_REQUIRED_LINK_OPTIONS ${full_relro_flags})
|
||||
|
464
ConflictSet.cpp
464
ConflictSet.cpp
@@ -203,6 +203,62 @@ enum Type : int8_t {
|
||||
|
||||
template <class T> struct BoundedFreeListAllocator;
|
||||
|
||||
struct TaggedNodePointer {
|
||||
TaggedNodePointer() = default;
|
||||
operator struct Node *() { return (struct Node *)withoutType(); }
|
||||
operator struct Node0 *() {
|
||||
assert(getType() == Type_Node0);
|
||||
return (struct Node0 *)withoutType();
|
||||
}
|
||||
operator struct Node3 *() {
|
||||
assert(getType() == Type_Node3);
|
||||
return (struct Node3 *)withoutType();
|
||||
}
|
||||
operator struct Node16 *() {
|
||||
assert(getType() == Type_Node16);
|
||||
return (struct Node16 *)withoutType();
|
||||
}
|
||||
operator struct Node48 *() {
|
||||
assert(getType() == Type_Node48);
|
||||
return (struct Node48 *)withoutType();
|
||||
}
|
||||
operator struct Node256 *() {
|
||||
assert(getType() == Type_Node256);
|
||||
return (struct Node256 *)withoutType();
|
||||
}
|
||||
/*implicit*/ TaggedNodePointer(std::nullptr_t) : p(0) {}
|
||||
/*implicit*/ TaggedNodePointer(Node0 *x)
|
||||
: TaggedNodePointer((struct Node *)x, Type_Node0) {}
|
||||
/*implicit*/ TaggedNodePointer(Node3 *x)
|
||||
: TaggedNodePointer((struct Node *)x, Type_Node3) {}
|
||||
/*implicit*/ TaggedNodePointer(Node16 *x)
|
||||
: TaggedNodePointer((struct Node *)x, Type_Node16) {}
|
||||
/*implicit*/ TaggedNodePointer(Node48 *x)
|
||||
: TaggedNodePointer((struct Node *)x, Type_Node48) {}
|
||||
/*implicit*/ TaggedNodePointer(Node256 *x)
|
||||
: TaggedNodePointer((struct Node *)x, Type_Node256) {}
|
||||
|
||||
bool operator!=(std::nullptr_t) { return p != 0; }
|
||||
bool operator==(std::nullptr_t) { return p == 0; }
|
||||
bool operator==(const TaggedNodePointer &) const = default;
|
||||
bool operator==(Node *n) const { return (uintptr_t)n == withoutType(); }
|
||||
Node *operator->() { return (Node *)withoutType(); }
|
||||
Type getType();
|
||||
|
||||
TaggedNodePointer(const TaggedNodePointer &) = default;
|
||||
TaggedNodePointer &operator=(const TaggedNodePointer &) = default;
|
||||
/*implicit*/ TaggedNodePointer(Node *n);
|
||||
|
||||
private:
|
||||
TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) {
|
||||
assert((this->p & 7) == 0);
|
||||
this->p |= t;
|
||||
assume(p != 0);
|
||||
}
|
||||
uintptr_t withoutType() const { return p & ~uintptr_t(7); }
|
||||
uintptr_t p;
|
||||
};
|
||||
|
||||
struct Node {
|
||||
|
||||
/* begin section that's copied to the next node */
|
||||
@@ -228,6 +284,14 @@ private:
|
||||
int32_t partialKeyCapacity;
|
||||
};
|
||||
|
||||
TaggedNodePointer::TaggedNodePointer(Node *n)
|
||||
: TaggedNodePointer(n, n->getType()) {}
|
||||
|
||||
Type TaggedNodePointer::getType() {
|
||||
assert(p != 0);
|
||||
return Type(p & uintptr_t(7));
|
||||
}
|
||||
|
||||
constexpr int kNodeCopyBegin = offsetof(Node, entry);
|
||||
constexpr int kNodeCopySize =
|
||||
offsetof(Node, parentsIndex) + sizeof(Node::parentsIndex) - kNodeCopyBegin;
|
||||
@@ -251,7 +315,7 @@ struct Node3 : Node {
|
||||
constexpr static auto kMaxNodes = 3;
|
||||
constexpr static auto kType = Type_Node3;
|
||||
|
||||
Node *children[kMaxNodes];
|
||||
TaggedNodePointer children[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
// Sorted
|
||||
uint8_t index[kMaxNodes];
|
||||
@@ -267,7 +331,7 @@ struct Node16 : Node {
|
||||
constexpr static auto kType = Type_Node16;
|
||||
constexpr static auto kMaxNodes = 16;
|
||||
|
||||
Node *children[kMaxNodes];
|
||||
TaggedNodePointer children[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
// Sorted
|
||||
uint8_t index[kMaxNodes];
|
||||
@@ -288,7 +352,7 @@ struct Node48 : Node {
|
||||
constexpr static int kMaxOfMaxTotalPages = kMaxNodes / kMaxOfMaxPageSize;
|
||||
|
||||
BitSet bitSet;
|
||||
Node *children[kMaxNodes];
|
||||
TaggedNodePointer children[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
InternalVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
uint8_t reverseIndex[kMaxNodes];
|
||||
@@ -310,7 +374,7 @@ struct Node256 : Node {
|
||||
constexpr static int kMaxOfMaxTotalPages = kMaxNodes / kMaxOfMaxPageSize;
|
||||
|
||||
BitSet bitSet;
|
||||
Node *children[kMaxNodes];
|
||||
TaggedNodePointer children[kMaxNodes];
|
||||
InternalVersionT childMaxVersion[kMaxNodes];
|
||||
InternalVersionT maxOfMax[kMaxOfMaxTotalPages];
|
||||
|
||||
@@ -888,26 +952,26 @@ int getNodeIndexExists(Node16 *self, uint8_t index) {
|
||||
}
|
||||
|
||||
// Precondition - an entry for index must exist in the node
|
||||
Node *&getChildExists(Node3 *self, uint8_t index) {
|
||||
TaggedNodePointer &getChildExists(Node3 *self, uint8_t index) {
|
||||
return self->children[getNodeIndexExists(self, index)];
|
||||
}
|
||||
// Precondition - an entry for index must exist in the node
|
||||
Node *&getChildExists(Node16 *self, uint8_t index) {
|
||||
TaggedNodePointer &getChildExists(Node16 *self, uint8_t index) {
|
||||
return self->children[getNodeIndexExists(self, index)];
|
||||
}
|
||||
// Precondition - an entry for index must exist in the node
|
||||
Node *&getChildExists(Node48 *self, uint8_t index) {
|
||||
TaggedNodePointer &getChildExists(Node48 *self, uint8_t index) {
|
||||
assert(self->bitSet.test(index));
|
||||
return self->children[self->index[index]];
|
||||
}
|
||||
// Precondition - an entry for index must exist in the node
|
||||
Node *&getChildExists(Node256 *self, uint8_t index) {
|
||||
TaggedNodePointer &getChildExists(Node256 *self, uint8_t index) {
|
||||
assert(self->bitSet.test(index));
|
||||
return self->children[index];
|
||||
}
|
||||
|
||||
// Precondition - an entry for index must exist in the node
|
||||
Node *&getChildExists(Node *self, uint8_t index) {
|
||||
TaggedNodePointer &getChildExists(Node *self, uint8_t index) {
|
||||
switch (self->getType()) {
|
||||
case Type_Node0: // GCOVR_EXCL_LINE
|
||||
__builtin_unreachable(); // GCOVR_EXCL_LINE
|
||||
@@ -1038,24 +1102,26 @@ void setMaxVersion(Node *n, InternalVersionT newMax) {
|
||||
}
|
||||
}
|
||||
|
||||
Node *&getInTree(Node *n, ConflictSet::Impl *);
|
||||
TaggedNodePointer &getInTree(Node *n, ConflictSet::Impl *);
|
||||
|
||||
Node *getChild(Node0 *, uint8_t) { return nullptr; }
|
||||
Node *getChild(Node3 *self, uint8_t index) {
|
||||
TaggedNodePointer getChild(Node0 *, uint8_t) { return nullptr; }
|
||||
TaggedNodePointer getChild(Node3 *self, uint8_t index) {
|
||||
int i = getNodeIndex(self, index);
|
||||
return i < 0 ? nullptr : self->children[i];
|
||||
}
|
||||
Node *getChild(Node16 *self, uint8_t index) {
|
||||
TaggedNodePointer getChild(Node16 *self, uint8_t index) {
|
||||
int i = getNodeIndex(self, index);
|
||||
return i < 0 ? nullptr : self->children[i];
|
||||
}
|
||||
Node *getChild(Node48 *self, uint8_t index) {
|
||||
TaggedNodePointer getChild(Node48 *self, uint8_t index) {
|
||||
int i = self->index[index];
|
||||
return i < 0 ? nullptr : self->children[i];
|
||||
}
|
||||
Node *getChild(Node256 *self, uint8_t index) { return self->children[index]; }
|
||||
TaggedNodePointer getChild(Node256 *self, uint8_t index) {
|
||||
return self->children[index];
|
||||
}
|
||||
|
||||
Node *getChild(Node *self, uint8_t index) {
|
||||
TaggedNodePointer getChild(Node *self, uint8_t index) {
|
||||
switch (self->getType()) {
|
||||
case Type_Node0:
|
||||
return getChild(static_cast<Node0 *>(self), index);
|
||||
@@ -1073,7 +1139,7 @@ Node *getChild(Node *self, uint8_t index) {
|
||||
}
|
||||
|
||||
struct ChildAndMaxVersion {
|
||||
Node *child;
|
||||
TaggedNodePointer child;
|
||||
InternalVersionT maxVersion;
|
||||
};
|
||||
|
||||
@@ -1245,14 +1311,15 @@ Node *getFirstChildExists(Node *self) {
|
||||
}
|
||||
}
|
||||
|
||||
void consumePartialKeyFull(Node *&self, std::span<const uint8_t> &key,
|
||||
void consumePartialKeyFull(TaggedNodePointer &self,
|
||||
std::span<const uint8_t> &key,
|
||||
InternalVersionT writeVersion, WriteContext *tls) {
|
||||
// Handle an existing partial key
|
||||
int commonLen = std::min<int>(self->partialKeyLen, key.size());
|
||||
int partialKeyIndex =
|
||||
longestCommonPrefix(self->partialKey(), key.data(), commonLen);
|
||||
if (partialKeyIndex < self->partialKeyLen) {
|
||||
auto *old = self;
|
||||
Node *old = self;
|
||||
// Since root cannot have a partial key
|
||||
assert(old->parent != nullptr);
|
||||
InternalVersionT oldMaxVersion = exchangeMaxVersion(old, writeVersion);
|
||||
@@ -1290,7 +1357,7 @@ void consumePartialKeyFull(Node *&self, std::span<const uint8_t> &key,
|
||||
// Consume any partial key of `self`, and update `self` and
|
||||
// `key` such that `self` is along the search path of `key`
|
||||
inline __attribute__((always_inline)) void
|
||||
consumePartialKey(Node *&self, std::span<const uint8_t> &key,
|
||||
consumePartialKey(TaggedNodePointer &self, std::span<const uint8_t> &key,
|
||||
InternalVersionT writeVersion, WriteContext *tls) {
|
||||
if (self->partialKeyLen > 0) {
|
||||
consumePartialKeyFull(self, key, writeVersion, tls);
|
||||
@@ -1301,8 +1368,10 @@ consumePartialKey(Node *&self, std::span<const uint8_t> &key,
|
||||
// such that the search path of the result + key is the same as the search path
|
||||
// of self + key before the call. Creates a node if necessary. Updates
|
||||
// `maxVersion` for result.
|
||||
Node *&getOrCreateChild(Node *&self, std::span<const uint8_t> &key,
|
||||
InternalVersionT newMaxVersion, WriteContext *tls) {
|
||||
TaggedNodePointer &getOrCreateChild(TaggedNodePointer &self,
|
||||
std::span<const uint8_t> &key,
|
||||
InternalVersionT newMaxVersion,
|
||||
WriteContext *tls) {
|
||||
|
||||
int index = key.front();
|
||||
key = key.subspan(1, key.size() - 1);
|
||||
@@ -1660,10 +1729,11 @@ void rezero(Node *n, InternalVersionT z) {
|
||||
}
|
||||
#endif
|
||||
|
||||
void mergeWithChild(Node *&self, WriteContext *tls, ConflictSet::Impl *impl,
|
||||
Node *&dontInvalidate, Node3 *self3) {
|
||||
void mergeWithChild(TaggedNodePointer &self, WriteContext *tls,
|
||||
ConflictSet::Impl *impl, Node *&dontInvalidate,
|
||||
Node3 *self3) {
|
||||
assert(!self3->entryPresent);
|
||||
auto *child = self3->children[0];
|
||||
Node *child = self3->children[0];
|
||||
int minCapacity = self3->partialKeyLen + 1 + child->partialKeyLen;
|
||||
|
||||
if (minCapacity > child->getCapacity()) {
|
||||
@@ -1912,7 +1982,8 @@ bool checkPointRead(Node *n, const std::span<const uint8_t> key,
|
||||
goto downLeftSpine;
|
||||
}
|
||||
|
||||
auto [child, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
auto [c, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -1982,7 +2053,8 @@ bool checkPrefixRead(Node *n, const std::span<const uint8_t> key,
|
||||
return maxVersion(n) <= readVersion;
|
||||
}
|
||||
|
||||
auto [child, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
auto [c, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -2255,7 +2327,7 @@ bool checkMaxBetweenExclusiveImpl(Node *n, int begin, int end,
|
||||
if (!mask) {
|
||||
return true;
|
||||
}
|
||||
auto *child = self->children[std::countr_zero(mask)];
|
||||
Node *child = self->children[std::countr_zero(mask)];
|
||||
const bool firstRangeOk =
|
||||
!child->entryPresent || child->entry.rangeVersion <= readVersion;
|
||||
uint32_t compared = 0;
|
||||
@@ -2330,7 +2402,7 @@ bool checkMaxBetweenExclusiveImpl(Node *n, int begin, int end,
|
||||
if (!mask) {
|
||||
return true;
|
||||
}
|
||||
auto *child = self->children[std::countr_zero(mask)];
|
||||
Node *child = self->children[std::countr_zero(mask)];
|
||||
const bool firstRangeOk =
|
||||
!child->entryPresent || child->entry.rangeVersion <= readVersion;
|
||||
|
||||
@@ -2375,7 +2447,7 @@ bool checkMaxBetweenExclusiveImpl(Node *n, int begin, int end,
|
||||
{
|
||||
int c = self->bitSet.firstSetGeq(begin + 1);
|
||||
if (c >= 0 && c < end) {
|
||||
auto *child = self->children[self->index[c]];
|
||||
Node *child = self->children[self->index[c]];
|
||||
if (child->entryPresent && child->entry.rangeVersion > readVersion) {
|
||||
return false;
|
||||
}
|
||||
@@ -2409,7 +2481,7 @@ bool checkMaxBetweenExclusiveImpl(Node *n, int begin, int end,
|
||||
{
|
||||
int c = self->bitSet.firstSetGeq(begin + 1);
|
||||
if (c >= 0 && c < end) {
|
||||
auto *child = self->children[c];
|
||||
Node *child = self->children[c];
|
||||
if (child->entryPresent && child->entry.rangeVersion > readVersion) {
|
||||
return false;
|
||||
}
|
||||
@@ -2509,7 +2581,7 @@ bool checkRangeStartsWith(Node *n, std::span<const uint8_t> key, int begin,
|
||||
return checkMaxBetweenExclusive(n, begin, end, readVersion, tls);
|
||||
}
|
||||
|
||||
auto *child = getChild(n, remaining[0]);
|
||||
Node *child = getChild(n, remaining[0]);
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -2581,7 +2653,8 @@ bool checkRangeLeftSide(Node *n, std::span<const uint8_t> key, int prefixLen,
|
||||
}
|
||||
}
|
||||
|
||||
auto [child, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
auto [c, maxV] = getChildAndMaxVersion(n, remaining[0]);
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -2675,7 +2748,7 @@ bool checkRangeRightSide(Node *n, std::span<const uint8_t> key, int prefixLen,
|
||||
return false;
|
||||
}
|
||||
|
||||
auto *child = getChild(n, remaining[0]);
|
||||
Node *child = getChild(n, remaining[0]);
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -2769,7 +2842,8 @@ bool checkRangeRead(Node *n, std::span<const uint8_t> begin,
|
||||
if (remaining.size() == 0) {
|
||||
break;
|
||||
}
|
||||
auto [child, v] = getChildAndMaxVersion(n, remaining[0]);
|
||||
auto [c, v] = getChildAndMaxVersion(n, remaining[0]);
|
||||
Node *child = c;
|
||||
if (child == nullptr) {
|
||||
break;
|
||||
}
|
||||
@@ -2835,8 +2909,10 @@ checkMaxBetweenExclusiveImpl<true>(Node *n, int begin, int end,
|
||||
// of the result will have `maxVersion` set to `writeVersion` as a
|
||||
// postcondition. Nodes along the search path may be invalidated. Callers must
|
||||
// ensure that the max version of the self argument is updated.
|
||||
[[nodiscard]] Node **insert(Node **self, std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion, WriteContext *tls) {
|
||||
[[nodiscard]] TaggedNodePointer *insert(TaggedNodePointer *self,
|
||||
std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion,
|
||||
WriteContext *tls) {
|
||||
|
||||
for (; key.size() != 0; ++tls->accum.insert_iterations) {
|
||||
self = &getOrCreateChild(*self, key, writeVersion, tls);
|
||||
@@ -2864,17 +2940,23 @@ void eraseTree(Node *root, WriteContext *tls) {
|
||||
} break;
|
||||
case Type_Node3: {
|
||||
auto *n3 = static_cast<Node3 *>(n);
|
||||
toFree.append(std::span<Node *>(n3->children, n3->numChildren));
|
||||
for (int i = 0; i < n3->numChildren; ++i) {
|
||||
toFree.push_back(n3->children[i]);
|
||||
}
|
||||
tls->release(n3);
|
||||
} break;
|
||||
case Type_Node16: {
|
||||
auto *n16 = static_cast<Node16 *>(n);
|
||||
toFree.append(std::span<Node *>(n16->children, n16->numChildren));
|
||||
for (int i = 0; i < n16->numChildren; ++i) {
|
||||
toFree.push_back(n16->children[i]);
|
||||
}
|
||||
tls->release(n16);
|
||||
} break;
|
||||
case Type_Node48: {
|
||||
auto *n48 = static_cast<Node48 *>(n);
|
||||
toFree.append(std::span<Node *>(n48->children, n48->numChildren));
|
||||
for (int i = 0; i < n48->numChildren; ++i) {
|
||||
toFree.push_back(n48->children[i]);
|
||||
}
|
||||
tls->release(n48);
|
||||
} break;
|
||||
case Type_Node256: {
|
||||
@@ -2890,10 +2972,10 @@ void eraseTree(Node *root, WriteContext *tls) {
|
||||
}
|
||||
}
|
||||
|
||||
void addPointWrite(Node *&root, std::span<const uint8_t> key,
|
||||
void addPointWrite(TaggedNodePointer &root, std::span<const uint8_t> key,
|
||||
InternalVersionT writeVersion, WriteContext *tls) {
|
||||
++tls->accum.point_writes;
|
||||
auto *n = *insert(&root, key, writeVersion, tls);
|
||||
auto n = *insert(&root, key, writeVersion, tls);
|
||||
if (!n->entryPresent) {
|
||||
++tls->accum.entries_inserted;
|
||||
auto *p = nextLogical(n);
|
||||
@@ -3011,7 +3093,7 @@ void fixupMaxVersion(Node *node, WriteContext *tls) {
|
||||
setMaxVersion(node, max);
|
||||
}
|
||||
|
||||
void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
void addWriteRange(TaggedNodePointer &root, std::span<const uint8_t> begin,
|
||||
std::span<const uint8_t> end, InternalVersionT writeVersion,
|
||||
WriteContext *tls, ConflictSet::Impl *impl) {
|
||||
|
||||
@@ -3024,12 +3106,12 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
++tls->accum.range_writes;
|
||||
const bool beginIsPrefix = lcp == int(begin.size());
|
||||
|
||||
Node **useAsRoot = insert(&root, begin.subspan(0, lcp), writeVersion, tls);
|
||||
auto useAsRoot = insert(&root, begin.subspan(0, lcp), writeVersion, tls);
|
||||
|
||||
begin = begin.subspan(lcp, begin.size() - lcp);
|
||||
end = end.subspan(lcp, end.size() - lcp);
|
||||
|
||||
auto *beginNode = *insert(useAsRoot, begin, writeVersion, tls);
|
||||
Node *beginNode = *insert(useAsRoot, begin, writeVersion, tls);
|
||||
addKey(beginNode);
|
||||
if (!beginNode->entryPresent) {
|
||||
++tls->accum.entries_inserted;
|
||||
@@ -3040,7 +3122,7 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
}
|
||||
beginNode->entry.pointVersion = writeVersion;
|
||||
|
||||
auto *endNode = *insert(useAsRoot, end, writeVersion, tls);
|
||||
Node *endNode = *insert(useAsRoot, end, writeVersion, tls);
|
||||
addKey(endNode);
|
||||
if (!endNode->entryPresent) {
|
||||
++tls->accum.entries_inserted;
|
||||
@@ -3060,7 +3142,7 @@ void addWriteRange(Node *&root, std::span<const uint8_t> begin,
|
||||
assert(!beginNode->endOfRange);
|
||||
assert(!endNode->endOfRange);
|
||||
endNode->endOfRange = true;
|
||||
auto *iter = beginNode;
|
||||
Node *iter = beginNode;
|
||||
for (iter = nextLogical(iter); !iter->endOfRange;
|
||||
iter = erase(iter, tls, impl, /*logical*/ true)) {
|
||||
assert(!iter->endOfRange);
|
||||
@@ -3080,7 +3162,7 @@ Node *firstGeqPhysical(Node *n, const std::span<const uint8_t> key) {
|
||||
return n;
|
||||
}
|
||||
|
||||
auto *child = getChild(n, remaining[0]);
|
||||
Node *child = getChild(n, remaining[0]);
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
@@ -3126,34 +3208,288 @@ Node *firstGeqPhysical(Node *n, const std::span<const uint8_t> key) {
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef __has_attribute
|
||||
#define __has_attribute(x) 0
|
||||
#endif
|
||||
|
||||
#if __has_attribute(musttail)
|
||||
#define MUSTTAIL __attribute__((musttail))
|
||||
#else
|
||||
#define MUSTTAIL
|
||||
#endif
|
||||
|
||||
#if __has_attribute(preserve_none)
|
||||
#define PRESERVE_NONE __attribute__((preserve_none))
|
||||
#else
|
||||
#define PRESERVE_NONE
|
||||
#endif
|
||||
|
||||
#if __has_attribute(flatten)
|
||||
#define FLATTEN __attribute__((flatten))
|
||||
#else
|
||||
#define FLATTEN
|
||||
#endif
|
||||
|
||||
typedef PRESERVE_NONE void (*Continuation)(struct CheckJob *,
|
||||
struct CheckContext *);
|
||||
|
||||
// State relevant to an individual query
|
||||
struct CheckJob {
|
||||
void setResult(bool ok) {
|
||||
*result = ok ? ConflictSet::Commit : ConflictSet::Conflict;
|
||||
}
|
||||
|
||||
void init(const ConflictSet::ReadRange *read, ConflictSet::Result *result,
|
||||
Node *root, int64_t oldestVersionFullPrecision, ReadContext *tls);
|
||||
|
||||
Node *n;
|
||||
std::span<const uint8_t> begin;
|
||||
InternalVersionT readVersion;
|
||||
ConflictSet::Result *result;
|
||||
Continuation continuation;
|
||||
CheckJob *prev;
|
||||
CheckJob *next;
|
||||
};
|
||||
|
||||
// State relevant to every query
|
||||
struct CheckContext {
|
||||
int count;
|
||||
int64_t oldestVersionFullPrecision;
|
||||
Node *root;
|
||||
const ConflictSet::ReadRange *queries;
|
||||
ConflictSet::Result *results;
|
||||
int64_t started;
|
||||
ReadContext *tls;
|
||||
};
|
||||
|
||||
FLATTEN PRESERVE_NONE void keepGoing(CheckJob *job, CheckContext *context) {
|
||||
job = job->next;
|
||||
MUSTTAIL return job->continuation(job, context);
|
||||
}
|
||||
|
||||
FLATTEN PRESERVE_NONE void complete(CheckJob *job, CheckContext *context) {
|
||||
if (context->started == context->count) {
|
||||
if (job->prev == job) {
|
||||
return;
|
||||
}
|
||||
job->prev->next = job->next;
|
||||
job->next->prev = job->prev;
|
||||
job = job->prev;
|
||||
} else {
|
||||
int temp = context->started++;
|
||||
job->init(context->queries + temp, context->results + temp, context->root,
|
||||
context->oldestVersionFullPrecision, context->tls);
|
||||
}
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
namespace check_point_read_state_machine {
|
||||
|
||||
FLATTEN PRESERVE_NONE void begin(CheckJob *, CheckContext *);
|
||||
|
||||
template <class NodeT>
|
||||
FLATTEN PRESERVE_NONE void iter(CheckJob *, CheckContext *);
|
||||
|
||||
FLATTEN PRESERVE_NONE void down_left_spine(CheckJob *, CheckContext *);
|
||||
|
||||
static Continuation iterTable[] = {iter<Node0>, iter<Node3>, iter<Node16>,
|
||||
iter<Node48>, iter<Node256>};
|
||||
|
||||
void begin(CheckJob *job, CheckContext *context) {
|
||||
++context->tls->point_read_accum;
|
||||
#if DEBUG_VERBOSE && !defined(NDEBUG)
|
||||
fprintf(stderr, "Check point read: %s\n", printable(key).c_str());
|
||||
#endif
|
||||
|
||||
if (job->begin.size() == 0) [[unlikely]] {
|
||||
// We don't erase the root
|
||||
assert(job->n->entryPresent);
|
||||
job->setResult(job->n->entry.pointVersion <= job->readVersion);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
|
||||
auto taggedChild = getChild(job->n, job->begin[0]);
|
||||
Node *child = taggedChild;
|
||||
if (child == nullptr) [[unlikely]] {
|
||||
auto c = getChildGeq(job->n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
// The root never has a next sibling
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
}
|
||||
job->continuation = iterTable[taggedChild.getType()];
|
||||
job->n = child;
|
||||
__builtin_prefetch(child);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
template <class NodeT> void iter(CheckJob *job, CheckContext *context) {
|
||||
|
||||
assert(NodeT::kType == job->n->getType());
|
||||
NodeT *n = static_cast<NodeT *>(job->n);
|
||||
job->begin = job->begin.subspan(1, job->begin.size() - 1);
|
||||
|
||||
if (n->partialKeyLen > 0) {
|
||||
int commonLen = std::min<int>(n->partialKeyLen, job->begin.size());
|
||||
int i = longestCommonPrefix(n->partialKey(), job->begin.data(), commonLen);
|
||||
if (i < commonLen) [[unlikely]] {
|
||||
auto c = n->partialKey()[i] <=> job->begin[i];
|
||||
if (c > 0) {
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(n);
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
if (commonLen == n->partialKeyLen) {
|
||||
// partial key matches
|
||||
job->begin = job->begin.subspan(commonLen, job->begin.size() - commonLen);
|
||||
} else if (n->partialKeyLen > int(job->begin.size())) [[unlikely]] {
|
||||
// n is the first physical node greater than remaining, and there's no
|
||||
// eq node
|
||||
job->continuation = down_left_spine;
|
||||
MUSTTAIL return down_left_spine(job, context);
|
||||
}
|
||||
}
|
||||
|
||||
++context->tls->point_read_iterations_accum;
|
||||
|
||||
if (job->begin.size() == 0) [[unlikely]] {
|
||||
if (n->entryPresent) {
|
||||
job->setResult(n->entry.pointVersion <= job->readVersion);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->n = getFirstChildExists(n);
|
||||
job->continuation = down_left_spine;
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
auto taggedChild = getChild(n, job->begin[0]);
|
||||
Node *child = taggedChild;
|
||||
if (child == nullptr) [[unlikely]] {
|
||||
auto c = getChildGeq(n, job->begin[0]);
|
||||
if (c != nullptr) {
|
||||
job->n = c;
|
||||
job->continuation = down_left_spine;
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
} else {
|
||||
job->n = nextSibling(job->n);
|
||||
if (job->n == nullptr) {
|
||||
job->setResult(true);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->continuation = down_left_spine;
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
}
|
||||
job->continuation = iterTable[taggedChild.getType()];
|
||||
job->n = child;
|
||||
__builtin_prefetch(child);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
void down_left_spine(CheckJob *job, CheckContext *context) {
|
||||
if (job->n->entryPresent) {
|
||||
job->setResult(job->n->entry.rangeVersion <= job->readVersion);
|
||||
MUSTTAIL return complete(job, context);
|
||||
}
|
||||
job->n = getFirstChildExists(job->n);
|
||||
__builtin_prefetch(job->n);
|
||||
MUSTTAIL return keepGoing(job, context);
|
||||
}
|
||||
|
||||
} // namespace check_point_read_state_machine
|
||||
|
||||
void CheckJob::init(const ConflictSet::ReadRange *read,
|
||||
ConflictSet::Result *result, Node *root,
|
||||
int64_t oldestVersionFullPrecision, ReadContext *tls) {
|
||||
auto begin = std::span<const uint8_t>(read->begin.p, read->begin.len);
|
||||
auto end = std::span<const uint8_t>(read->end.p, read->end.len);
|
||||
if (read->readVersion < oldestVersionFullPrecision) [[unlikely]] {
|
||||
*result = ConflictSet::TooOld;
|
||||
continuation = complete;
|
||||
} else if (end.size() == 0) {
|
||||
this->begin = begin;
|
||||
this->n = root;
|
||||
this->readVersion = InternalVersionT(read->readVersion);
|
||||
this->result = result;
|
||||
continuation = check_point_read_state_machine::begin;
|
||||
} else {
|
||||
*result = checkRangeRead(root, begin, end,
|
||||
InternalVersionT(read->readVersion), tls)
|
||||
? ConflictSet::Commit
|
||||
: ConflictSet::Conflict;
|
||||
continuation = complete;
|
||||
}
|
||||
}
|
||||
|
||||
struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
|
||||
void check(const ReadRange *reads, Result *result, int count) {
|
||||
assert(oldestVersionFullPrecision >=
|
||||
newestVersionFullPrecision - kNominalVersionWindow);
|
||||
|
||||
if (count == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
ReadContext tls;
|
||||
tls.impl = this;
|
||||
int64_t check_byte_accum = 0;
|
||||
constexpr int kConcurrent = 16;
|
||||
CheckJob inProgress[kConcurrent];
|
||||
CheckContext context;
|
||||
context.count = count;
|
||||
context.oldestVersionFullPrecision = oldestVersionFullPrecision;
|
||||
context.root = root;
|
||||
context.queries = reads;
|
||||
context.results = result;
|
||||
context.tls = &tls;
|
||||
int64_t started = std::min(kConcurrent, count);
|
||||
context.started = started;
|
||||
for (int i = 0; i < started; i++) {
|
||||
inProgress[i].init(reads + i, result + i, root,
|
||||
oldestVersionFullPrecision, &tls);
|
||||
}
|
||||
for (int i = 0; i < started - 1; i++) {
|
||||
inProgress[i].next = inProgress + i + 1;
|
||||
}
|
||||
for (int i = 1; i < started; i++) {
|
||||
inProgress[i].prev = inProgress + i - 1;
|
||||
}
|
||||
inProgress[0].prev = inProgress + started - 1;
|
||||
inProgress[started - 1].next = inProgress;
|
||||
|
||||
// Kick off the sequence of tail calls that finally returns once all jobs
|
||||
// are done
|
||||
inProgress->continuation(inProgress, &context);
|
||||
|
||||
for (int i = 0; i < count; ++i) {
|
||||
assert(reads[i].readVersion >= 0);
|
||||
assert(reads[i].readVersion <= newestVersionFullPrecision);
|
||||
const auto &r = reads[i];
|
||||
check_byte_accum += r.begin.len + r.end.len;
|
||||
auto begin = std::span<const uint8_t>(r.begin.p, r.begin.len);
|
||||
auto end = std::span<const uint8_t>(r.end.p, r.end.len);
|
||||
assert(oldestVersionFullPrecision >=
|
||||
newestVersionFullPrecision - kNominalVersionWindow);
|
||||
result[i] =
|
||||
reads[i].readVersion < oldestVersionFullPrecision ? TooOld
|
||||
: (end.size() > 0
|
||||
? checkRangeRead(root, begin, end,
|
||||
InternalVersionT(reads[i].readVersion), &tls)
|
||||
: checkPointRead(root, begin,
|
||||
InternalVersionT(reads[i].readVersion), &tls))
|
||||
? Commit
|
||||
: Conflict;
|
||||
tls.commits_accum += result[i] == Commit;
|
||||
tls.conflicts_accum += result[i] == Conflict;
|
||||
tls.too_olds_accum += result[i] == TooOld;
|
||||
}
|
||||
|
||||
point_read_total.add(tls.point_read_accum);
|
||||
prefix_read_total.add(tls.prefix_read_accum);
|
||||
range_read_total.add(tls.range_read_accum);
|
||||
@@ -3375,7 +3711,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
std::span<const uint8_t> removalKey;
|
||||
int64_t keyUpdates;
|
||||
|
||||
Node *root;
|
||||
TaggedNodePointer root;
|
||||
InternalVersionT oldestVersion;
|
||||
int64_t oldestVersionFullPrecision;
|
||||
int64_t oldestExtantVersion;
|
||||
@@ -3456,7 +3792,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl {
|
||||
}
|
||||
};
|
||||
|
||||
Node *&getInTree(Node *n, ConflictSet::Impl *impl) {
|
||||
TaggedNodePointer &getInTree(Node *n, ConflictSet::Impl *impl) {
|
||||
return n->parent == nullptr ? impl->root
|
||||
: getChildExists(n->parent, n->parentsIndex);
|
||||
}
|
||||
@@ -3532,7 +3868,7 @@ Node *firstGeqLogical(Node *n, const std::span<const uint8_t> key) {
|
||||
goto downLeftSpine;
|
||||
}
|
||||
|
||||
auto *child = getChild(n, remaining[0]);
|
||||
Node *child = getChild(n, remaining[0]);
|
||||
if (child == nullptr) {
|
||||
auto c = getChildGeq(n, remaining[0]);
|
||||
if (c != nullptr) {
|
||||
|
BIN
corpus/00533f61fd89afb9deb3dc978b368a3b3abf3992
Normal file
BIN
corpus/00533f61fd89afb9deb3dc978b368a3b3abf3992
Normal file
Binary file not shown.
BIN
corpus/00850bfa9ce0f9e64b8688db48dc6562be637d97
Normal file
BIN
corpus/00850bfa9ce0f9e64b8688db48dc6562be637d97
Normal file
Binary file not shown.
BIN
corpus/03119dd29f68a6a8ff8f67a653e7f4ba01c6847a
Normal file
BIN
corpus/03119dd29f68a6a8ff8f67a653e7f4ba01c6847a
Normal file
Binary file not shown.
BIN
corpus/0370da7797ee28434459cf21350d311df2aed581
Normal file
BIN
corpus/0370da7797ee28434459cf21350d311df2aed581
Normal file
Binary file not shown.
BIN
corpus/037f4bcc441003fb4cc2cbfd4d986c201035a744
Normal file
BIN
corpus/037f4bcc441003fb4cc2cbfd4d986c201035a744
Normal file
Binary file not shown.
BIN
corpus/053c56641f68bea3be49d74416d62ca583d6492e
Normal file
BIN
corpus/053c56641f68bea3be49d74416d62ca583d6492e
Normal file
Binary file not shown.
BIN
corpus/05e78ae4ba5007b2ad39b69b19604f8cb90650bd
Normal file
BIN
corpus/05e78ae4ba5007b2ad39b69b19604f8cb90650bd
Normal file
Binary file not shown.
BIN
corpus/07c638816ecc7071961866ba3ed0aa1168f7e998
Normal file
BIN
corpus/07c638816ecc7071961866ba3ed0aa1168f7e998
Normal file
Binary file not shown.
BIN
corpus/090ffb7c1949db26391498d8c7dc3b8f772b90ce
Normal file
BIN
corpus/090ffb7c1949db26391498d8c7dc3b8f772b90ce
Normal file
Binary file not shown.
BIN
corpus/0aa35cd848f2d94178b87dcf68272c8a3f96c42b
Normal file
BIN
corpus/0aa35cd848f2d94178b87dcf68272c8a3f96c42b
Normal file
Binary file not shown.
BIN
corpus/0b323a04077fd639c7e0a51a750eb1259bb6a4b0
Normal file
BIN
corpus/0b323a04077fd639c7e0a51a750eb1259bb6a4b0
Normal file
Binary file not shown.
BIN
corpus/0b445ea9b2e9cd62d4bd681ab94324aea7fe6b98
Normal file
BIN
corpus/0b445ea9b2e9cd62d4bd681ab94324aea7fe6b98
Normal file
Binary file not shown.
BIN
corpus/0b5969da792544a3fd9bb8f9c7fd0a53ad17b938
Normal file
BIN
corpus/0b5969da792544a3fd9bb8f9c7fd0a53ad17b938
Normal file
Binary file not shown.
BIN
corpus/0ed2d396bc5bd9b396942e6ec5569f46bef2476e
Normal file
BIN
corpus/0ed2d396bc5bd9b396942e6ec5569f46bef2476e
Normal file
Binary file not shown.
BIN
corpus/0eea457d59d763abe2b35aa044d839613f0c1eff
Normal file
BIN
corpus/0eea457d59d763abe2b35aa044d839613f0c1eff
Normal file
Binary file not shown.
BIN
corpus/0f8959089fadd2c5542cc9148d86176e800d92d3
Normal file
BIN
corpus/0f8959089fadd2c5542cc9148d86176e800d92d3
Normal file
Binary file not shown.
BIN
corpus/10244abeda5a403187b940e7cedb7a93189f2e67
Normal file
BIN
corpus/10244abeda5a403187b940e7cedb7a93189f2e67
Normal file
Binary file not shown.
BIN
corpus/10c43175be9f940150eb2ec9e709f8d68a9f1a87
Normal file
BIN
corpus/10c43175be9f940150eb2ec9e709f8d68a9f1a87
Normal file
Binary file not shown.
BIN
corpus/10dc6dd48d5819b353f3cabb844e7fefeed0dbce
Normal file
BIN
corpus/10dc6dd48d5819b353f3cabb844e7fefeed0dbce
Normal file
Binary file not shown.
BIN
corpus/1238ace8238748ab0c4bd4e578fa234cb53280ef
Normal file
BIN
corpus/1238ace8238748ab0c4bd4e578fa234cb53280ef
Normal file
Binary file not shown.
BIN
corpus/12a56e9945424996cd08c04ad3261c4bc80aaa17
Normal file
BIN
corpus/12a56e9945424996cd08c04ad3261c4bc80aaa17
Normal file
Binary file not shown.
BIN
corpus/12c1b23a16916c57fec76f5d7b3cbc7d07ad3a01
Normal file
BIN
corpus/12c1b23a16916c57fec76f5d7b3cbc7d07ad3a01
Normal file
Binary file not shown.
BIN
corpus/12e2003fa4ffdbb09ddf81b89d922a6f26d4bbf5
Normal file
BIN
corpus/12e2003fa4ffdbb09ddf81b89d922a6f26d4bbf5
Normal file
Binary file not shown.
BIN
corpus/12f4b3bc769c43a6be2fd9fd0d488439d0dedc9e
Normal file
BIN
corpus/12f4b3bc769c43a6be2fd9fd0d488439d0dedc9e
Normal file
Binary file not shown.
BIN
corpus/138b50160165c26e8ef6281d7ff2139f0ff3fb4f
Normal file
BIN
corpus/138b50160165c26e8ef6281d7ff2139f0ff3fb4f
Normal file
Binary file not shown.
BIN
corpus/13adf2094a36bc035b200dd1c2c2379150e199bd
Normal file
BIN
corpus/13adf2094a36bc035b200dd1c2c2379150e199bd
Normal file
Binary file not shown.
BIN
corpus/142dcdcceda3b86cb8413b5b6b96d214c99221ae
Normal file
BIN
corpus/142dcdcceda3b86cb8413b5b6b96d214c99221ae
Normal file
Binary file not shown.
BIN
corpus/15a3a8596107199f39bfaaf644e4b4ea8504ea2c
Normal file
BIN
corpus/15a3a8596107199f39bfaaf644e4b4ea8504ea2c
Normal file
Binary file not shown.
BIN
corpus/18623ab97d0842e2709ed2870e705c2eacfbb7c8
Normal file
BIN
corpus/18623ab97d0842e2709ed2870e705c2eacfbb7c8
Normal file
Binary file not shown.
BIN
corpus/19212d70d7ccd20b98fad3ba1edebae4aa6236fd
Normal file
BIN
corpus/19212d70d7ccd20b98fad3ba1edebae4aa6236fd
Normal file
Binary file not shown.
BIN
corpus/1ac17c2eaf93409cdc610efe758dfbeed48b0384
Normal file
BIN
corpus/1ac17c2eaf93409cdc610efe758dfbeed48b0384
Normal file
Binary file not shown.
BIN
corpus/1aeef1ad82d916ac77dc877f92262ab928fbd8bf
Normal file
BIN
corpus/1aeef1ad82d916ac77dc877f92262ab928fbd8bf
Normal file
Binary file not shown.
BIN
corpus/1b258ea18042c48ab6c10f10254e5aaeecb04fd5
Normal file
BIN
corpus/1b258ea18042c48ab6c10f10254e5aaeecb04fd5
Normal file
Binary file not shown.
BIN
corpus/1b802ba6b502b722c2f79dc9b268a78531964cba
Normal file
BIN
corpus/1b802ba6b502b722c2f79dc9b268a78531964cba
Normal file
Binary file not shown.
BIN
corpus/1b8daa16f809a7c53ab46c642d7746223c1e89c3
Normal file
BIN
corpus/1b8daa16f809a7c53ab46c642d7746223c1e89c3
Normal file
Binary file not shown.
BIN
corpus/1cf21168dd261282defc4f9550d5073d7325731d
Normal file
BIN
corpus/1cf21168dd261282defc4f9550d5073d7325731d
Normal file
Binary file not shown.
BIN
corpus/1d32cdfb5c5fda145d32ef98c14df05da43edff9
Normal file
BIN
corpus/1d32cdfb5c5fda145d32ef98c14df05da43edff9
Normal file
Binary file not shown.
BIN
corpus/1da019ba42899360b185febee026bff92598fab6
Normal file
BIN
corpus/1da019ba42899360b185febee026bff92598fab6
Normal file
Binary file not shown.
BIN
corpus/1e466f51834d01097b785bcad601630b2f4c4fb3
Normal file
BIN
corpus/1e466f51834d01097b785bcad601630b2f4c4fb3
Normal file
Binary file not shown.
BIN
corpus/1e844736e6767c7c4a05774df051fb2c40ca8d98
Normal file
BIN
corpus/1e844736e6767c7c4a05774df051fb2c40ca8d98
Normal file
Binary file not shown.
BIN
corpus/1ee13de896e906c111ba949e85ed7f48c846df50
Normal file
BIN
corpus/1ee13de896e906c111ba949e85ed7f48c846df50
Normal file
Binary file not shown.
BIN
corpus/2039e0adf8619ec4ce49fca017aa39a8600dc6c9
Normal file
BIN
corpus/2039e0adf8619ec4ce49fca017aa39a8600dc6c9
Normal file
Binary file not shown.
BIN
corpus/20401e8755bab61ef8e9208db78cdbfb59139177
Normal file
BIN
corpus/20401e8755bab61ef8e9208db78cdbfb59139177
Normal file
Binary file not shown.
BIN
corpus/21a3d4a0eb2aa8fd3097a5abef83805e80110944
Normal file
BIN
corpus/21a3d4a0eb2aa8fd3097a5abef83805e80110944
Normal file
Binary file not shown.
BIN
corpus/2250ec7a5578e9511be3649c14dcdd38697015c1
Normal file
BIN
corpus/2250ec7a5578e9511be3649c14dcdd38697015c1
Normal file
Binary file not shown.
BIN
corpus/23a9e57a66b267ea2fe0060b2894afeff525c635
Normal file
BIN
corpus/23a9e57a66b267ea2fe0060b2894afeff525c635
Normal file
Binary file not shown.
BIN
corpus/24089ab0ce8c12a4c5acb10f273ce53b93a65c08
Normal file
BIN
corpus/24089ab0ce8c12a4c5acb10f273ce53b93a65c08
Normal file
Binary file not shown.
BIN
corpus/2537bc610b792602516186a611cff1ada7795a5d
Normal file
BIN
corpus/2537bc610b792602516186a611cff1ada7795a5d
Normal file
Binary file not shown.
BIN
corpus/258d6fbc15128d65e42ce3e561299c6ee3e3484b
Normal file
BIN
corpus/258d6fbc15128d65e42ce3e561299c6ee3e3484b
Normal file
Binary file not shown.
BIN
corpus/259702095aed49b5aaca540dac6d28269a9fd148
Normal file
BIN
corpus/259702095aed49b5aaca540dac6d28269a9fd148
Normal file
Binary file not shown.
BIN
corpus/2a15e4d22a5a2f9e8ec3de15016621df354e6ac7
Normal file
BIN
corpus/2a15e4d22a5a2f9e8ec3de15016621df354e6ac7
Normal file
Binary file not shown.
BIN
corpus/2b4e9e0a74324bccbe722dfe475bf107df42c6f8
Normal file
BIN
corpus/2b4e9e0a74324bccbe722dfe475bf107df42c6f8
Normal file
Binary file not shown.
BIN
corpus/2f6fd9449cd7733833a5119815b7295b09edc9a1
Normal file
BIN
corpus/2f6fd9449cd7733833a5119815b7295b09edc9a1
Normal file
Binary file not shown.
BIN
corpus/316bb5ed63bcc92e6738ec48f795afe56f7ca10f
Normal file
BIN
corpus/316bb5ed63bcc92e6738ec48f795afe56f7ca10f
Normal file
Binary file not shown.
BIN
corpus/330da62b56b866a713befdae197603e59d2a9ed7
Normal file
BIN
corpus/330da62b56b866a713befdae197603e59d2a9ed7
Normal file
Binary file not shown.
BIN
corpus/3377871a18f22528d60d2b51b9f98fabd8966c1b
Normal file
BIN
corpus/3377871a18f22528d60d2b51b9f98fabd8966c1b
Normal file
Binary file not shown.
BIN
corpus/3466899b673dedf91cede941c314db0dab93131f
Normal file
BIN
corpus/3466899b673dedf91cede941c314db0dab93131f
Normal file
Binary file not shown.
BIN
corpus/34d90eccdcc5635b4f36507a9bd864e022bcc998
Normal file
BIN
corpus/34d90eccdcc5635b4f36507a9bd864e022bcc998
Normal file
Binary file not shown.
BIN
corpus/356a70926f5b508e9542b9399fd5d9eea83450a0
Normal file
BIN
corpus/356a70926f5b508e9542b9399fd5d9eea83450a0
Normal file
Binary file not shown.
BIN
corpus/35771141dfa1b3bd0b784ba469d4d319dd3d7800
Normal file
BIN
corpus/35771141dfa1b3bd0b784ba469d4d319dd3d7800
Normal file
Binary file not shown.
BIN
corpus/3585d81febbf44e5ee5454f5ff8143cacccd62d7
Normal file
BIN
corpus/3585d81febbf44e5ee5454f5ff8143cacccd62d7
Normal file
Binary file not shown.
BIN
corpus/368f8a2a3d60c5f73fa3a67d4c592f81bd5bc439
Normal file
BIN
corpus/368f8a2a3d60c5f73fa3a67d4c592f81bd5bc439
Normal file
Binary file not shown.
BIN
corpus/3ba2186d034e9d95397e53107ba600a622c11505
Normal file
BIN
corpus/3ba2186d034e9d95397e53107ba600a622c11505
Normal file
Binary file not shown.
BIN
corpus/3bab37bbf147f1020d3a877d0ac900fb86f69623
Normal file
BIN
corpus/3bab37bbf147f1020d3a877d0ac900fb86f69623
Normal file
Binary file not shown.
BIN
corpus/3c0ca2c59b7e7b64256aaa3351a398f4e1180ca9
Normal file
BIN
corpus/3c0ca2c59b7e7b64256aaa3351a398f4e1180ca9
Normal file
Binary file not shown.
BIN
corpus/3c756216b5cc814af5985cc6ef2f59a275c51954
Normal file
BIN
corpus/3c756216b5cc814af5985cc6ef2f59a275c51954
Normal file
Binary file not shown.
BIN
corpus/3e8092741539dd51b8561acf2c9f15c395d8cc02
Normal file
BIN
corpus/3e8092741539dd51b8561acf2c9f15c395d8cc02
Normal file
Binary file not shown.
BIN
corpus/3ec746d0473c3c756f741658d0825c2bede2173a
Normal file
BIN
corpus/3ec746d0473c3c756f741658d0825c2bede2173a
Normal file
Binary file not shown.
BIN
corpus/40c0cf24dd0e2809281b06b3917910727f9278c3
Normal file
BIN
corpus/40c0cf24dd0e2809281b06b3917910727f9278c3
Normal file
Binary file not shown.
BIN
corpus/41511ef3a9c4d61cd2adbc9f01ed71cbfe6cf37e
Normal file
BIN
corpus/41511ef3a9c4d61cd2adbc9f01ed71cbfe6cf37e
Normal file
Binary file not shown.
BIN
corpus/41b02632b4a15df12d012fc05af2c696aed8b8e5
Normal file
BIN
corpus/41b02632b4a15df12d012fc05af2c696aed8b8e5
Normal file
Binary file not shown.
BIN
corpus/422f18907a48e21c3e337d50cda73ef663e3beed
Normal file
BIN
corpus/422f18907a48e21c3e337d50cda73ef663e3beed
Normal file
Binary file not shown.
BIN
corpus/42a6681fcbebedcfaf7e46b7d45490a049729299
Normal file
BIN
corpus/42a6681fcbebedcfaf7e46b7d45490a049729299
Normal file
Binary file not shown.
BIN
corpus/43fd041f435b52c980fc578073e3ffece8335b8c
Normal file
BIN
corpus/43fd041f435b52c980fc578073e3ffece8335b8c
Normal file
Binary file not shown.
BIN
corpus/4465f40ff741859bcac88cea6f2d8a5aaf56c7a8
Normal file
BIN
corpus/4465f40ff741859bcac88cea6f2d8a5aaf56c7a8
Normal file
Binary file not shown.
BIN
corpus/48373d39e6d45877f67cf4a318211c2da472fb9b
Normal file
BIN
corpus/48373d39e6d45877f67cf4a318211c2da472fb9b
Normal file
Binary file not shown.
BIN
corpus/4844f12d67b5779bae5ecf3103b01430a2155140
Normal file
BIN
corpus/4844f12d67b5779bae5ecf3103b01430a2155140
Normal file
Binary file not shown.
BIN
corpus/48b4269e026a8e9b26c4c9313a275cdbd8c837aa
Normal file
BIN
corpus/48b4269e026a8e9b26c4c9313a275cdbd8c837aa
Normal file
Binary file not shown.
BIN
corpus/4ae1f7137e89d6f9c9079533187a88ec42321092
Normal file
BIN
corpus/4ae1f7137e89d6f9c9079533187a88ec42321092
Normal file
Binary file not shown.
BIN
corpus/4ae57e7e2877620b1785a857f321f3bb0d9ccf11
Normal file
BIN
corpus/4ae57e7e2877620b1785a857f321f3bb0d9ccf11
Normal file
Binary file not shown.
BIN
corpus/4c48ce66e38ecfe8bf57d16aa9ff2b12eb51e71c
Normal file
BIN
corpus/4c48ce66e38ecfe8bf57d16aa9ff2b12eb51e71c
Normal file
Binary file not shown.
BIN
corpus/4d0a44860dbd150cb132f76d02f7bdfc8589767e
Normal file
BIN
corpus/4d0a44860dbd150cb132f76d02f7bdfc8589767e
Normal file
Binary file not shown.
BIN
corpus/4d790e5e6a410e0793dccf93fb0cb6d2ee264882
Normal file
BIN
corpus/4d790e5e6a410e0793dccf93fb0cb6d2ee264882
Normal file
Binary file not shown.
BIN
corpus/4ed655609f4caeffe8a822eedde67840c1fd0ca8
Normal file
BIN
corpus/4ed655609f4caeffe8a822eedde67840c1fd0ca8
Normal file
Binary file not shown.
BIN
corpus/4f66f912bd5ff8a4b8131b4d20f4c8f62a1a4825
Normal file
BIN
corpus/4f66f912bd5ff8a4b8131b4d20f4c8f62a1a4825
Normal file
Binary file not shown.
BIN
corpus/527e824566feda8073a02ede87ff3ec9e621e54f
Normal file
BIN
corpus/527e824566feda8073a02ede87ff3ec9e621e54f
Normal file
Binary file not shown.
BIN
corpus/52b78ae06aff68fdcb36cb00f98b137239127eca
Normal file
BIN
corpus/52b78ae06aff68fdcb36cb00f98b137239127eca
Normal file
Binary file not shown.
BIN
corpus/5344249e358682e6d840aaa93b83d414add79da8
Normal file
BIN
corpus/5344249e358682e6d840aaa93b83d414add79da8
Normal file
Binary file not shown.
BIN
corpus/55a720d6dd90075ee544e7ae50ab89c007d86c06
Normal file
BIN
corpus/55a720d6dd90075ee544e7ae50ab89c007d86c06
Normal file
Binary file not shown.
BIN
corpus/56634af7a28d613c642bb58915e5bb3592fcb2b4
Normal file
BIN
corpus/56634af7a28d613c642bb58915e5bb3592fcb2b4
Normal file
Binary file not shown.
BIN
corpus/5704d358944faf333ebb393767043ee314eba277
Normal file
BIN
corpus/5704d358944faf333ebb393767043ee314eba277
Normal file
Binary file not shown.
BIN
corpus/58151af8e789122f0ba7077e45220c089e2ba80a
Normal file
BIN
corpus/58151af8e789122f0ba7077e45220c089e2ba80a
Normal file
Binary file not shown.
BIN
corpus/587734e5f77eb5f961af9c77f6a84ad023af1b6b
Normal file
BIN
corpus/587734e5f77eb5f961af9c77f6a84ad023af1b6b
Normal file
Binary file not shown.
BIN
corpus/592e4881bab14fef12117905206ab841f2301876
Normal file
BIN
corpus/592e4881bab14fef12117905206ab841f2301876
Normal file
Binary file not shown.
BIN
corpus/5970a48c9760acb1f2fa411a2ef95e8907416707
Normal file
BIN
corpus/5970a48c9760acb1f2fa411a2ef95e8907416707
Normal file
Binary file not shown.
BIN
corpus/59c67c8877c28bffa7e000dc23fd8073b86154a0
Normal file
BIN
corpus/59c67c8877c28bffa7e000dc23fd8073b86154a0
Normal file
Binary file not shown.
BIN
corpus/5ae29d9bc51a9e69599ab4ddd145741f2b21c09d
Normal file
BIN
corpus/5ae29d9bc51a9e69599ab4ddd145741f2b21c09d
Normal file
Binary file not shown.
BIN
corpus/5ae60ef89dde1e9581a18cee62192376e8d68102
Normal file
BIN
corpus/5ae60ef89dde1e9581a18cee62192376e8d68102
Normal file
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user