diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 856c077..41b0078 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -216,6 +216,9 @@ enum Type : int8_t { template struct NodeAllocator; +// Make sure tag fits in low 4 bits +static_assert(alignof(std::max_align_t) >= 16); + struct TaggedNodePointer { TaggedNodePointer() = default; operator struct Node *() { return (struct Node *)withoutType(); } @@ -271,11 +274,11 @@ struct TaggedNodePointer { private: TaggedNodePointer(struct Node *p, Type t) : p((uintptr_t)p) { - assert((this->p & 7) == 0); + assert((this->p & 15) == 0); this->p |= t; assume(p != 0); } - uintptr_t withoutType() const { return p & ~uintptr_t(7); } + uintptr_t withoutType() const { return p & ~uintptr_t(15); } uintptr_t p; }; @@ -317,7 +320,7 @@ TaggedNodePointer::TaggedNodePointer(Node *n) Type TaggedNodePointer::getType() { assert(p != 0); prefetch(); - return Type(p & uintptr_t(7)); + return Type(p & uintptr_t(15)); } // copyChildrenAndKeyFrom is responsible for copying all @@ -1882,6 +1885,59 @@ void downsize(Node *self, WriteContext *writeContext) { } } +template struct Iterator; + +// Higher-level handle to a position in the tree +struct IteratorBase { + + explicit IteratorBase(Node *node) : node(node) {} + + bool entryPresent() { return node->entryPresent; } + Entry getEntry() { + assert(node->entryPresent); + return node->entry; + } + void setEntry(Entry e) { + node->entryPresent = true; + node->entry = e; + } + + bool operator==(const IteratorBase &other) const { + assert(!node->releaseDeferred); + assert(!other.node->releaseDeferred); + return node == other.node; + } + + bool valid() { return node != nullptr; } + + void followForwardingPointers() { + while (node->releaseDeferred) [[unlikely]] { + node = node->forwardTo; + } + } + + Type getType() { return node->getType(); } + + template Iterator as() { + assert(getType() == T::kType); + return static_cast>(*this); + } + + IteratorBase nextLogical(); + IteratorBase nextPhysical(); + InternalVersionT getMaxVersion(); + InternalVersionT exchangeMaxVersion(InternalVersionT); + InternalVersionT setMaxVersion(); + TrivialSpan partialKey(); + +private: + Node *node; + // index into children array of particular leaf type + int index; +}; + +template struct Iterator : IteratorBase {}; + // Precondition: self is not the root. May invalidate nodes along the search // path to self. May invalidate children of self->parent. Returns a pointer to // the node after self. Precondition: `self->entryPresent`