diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 1b3ba60..c947a2b 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -1029,6 +1029,43 @@ int getChildGeq(Node *self, int child) { } } +// Precondition: self has a child +Node *getFirstChildExists(Node3 *self) { + assert(self->numChildren > 0); + return self->children[0]; +} +// Precondition: self has a child +Node *getFirstChildExists(Node16 *self) { + assert(self->numChildren > 0); + return self->children[0]; +} +// Precondition: self has a child +Node *getFirstChildExists(Node48 *self) { + return self->children[self->index[self->bitSet.firstSetGeq(0)]]; +} +// Precondition: self has a child +Node *getFirstChildExists(Node256 *self) { + return self->children[self->bitSet.firstSetGeq(0)]; +} + +// Precondition: self has a child +Node *getFirstChildExists(Node *self) { + switch (self->getType()) { + case Type_Node0: // GCOVR_EXCL_LINE + __builtin_unreachable(); // GCOVR_EXCL_LINE + case Type_Node3: + return getFirstChildExists(static_cast(self)); + case Type_Node16: + return getFirstChildExists(static_cast(self)); + case Type_Node48: + return getFirstChildExists(static_cast(self)); + case Type_Node256: + return getFirstChildExists(static_cast(self)); + default: // GCOVR_EXCL_LINE + __builtin_unreachable(); // GCOVR_EXCL_LINE + } +} + // Caller is responsible for assigning a non-null pointer to the returned // reference if null Node *&getOrCreateChild(Node *&self, uint8_t index, WriteContext *tls) { @@ -1900,14 +1937,9 @@ bool checkPointRead(Node *n, const std::span key, } } downLeftSpine: - for (;;) { - if (n->entryPresent) { - return n->entry.rangeVersion <= readVersion; - } - int c = getChildGeq(n, 0); - assert(c >= 0); - n = getChildExists(n, c); + for (; !n->entryPresent; n = getFirstChildExists(n)) { } + return n->entry.rangeVersion <= readVersion; } // Logically this is the same as performing firstGeq and then checking against @@ -1980,14 +2012,9 @@ bool checkPrefixRead(Node *n, const std::span key, } } downLeftSpine: - for (;;) { - if (n->entryPresent) { - return n->entry.rangeVersion <= readVersion; - } - int c = getChildGeq(n, 0); - assert(c >= 0); - n = getChildExists(n, c); + for (; !n->entryPresent; n = getFirstChildExists(n)) { } + return n->entry.rangeVersion <= readVersion; } #ifdef HAS_AVX