Avoid branching on type twice in erase
All checks were successful
Tests / Clang total: 2500, passed: 2500
Clang |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Debug total: 2498, passed: 2498
Tests / SIMD fallback total: 2500, passed: 2500
Tests / Release [gcc] total: 2500, passed: 2500
GNU C Compiler (gcc) |Total|New|Outstanding|Fixed|Trend |:-:|:-:|:-:|:-:|:-: |0|0|0|0|:clap:
Tests / Release [gcc,aarch64] total: 1867, passed: 1867
Tests / Coverage total: 1877, passed: 1877
Code Coverage #### Project Overview No changes detected, that affect the code coverage. * Line Coverage: 99.29% (1829/1842) * Branch Coverage: 67.35% (1479/2196) * Complexity Density: 0.00 * Lines of Code: 1842 #### Quality Gates Summary Output truncated.
weaselab/conflict-set/pipeline/head This commit looks good

This commit is contained in:
2024-08-16 09:29:22 -07:00
parent 55a230c75e
commit b009de1c2b

View File

@@ -1675,53 +1675,67 @@ void mergeWithChild(Node *&self, WriteContext *tls, ConflictSet::Impl *impl,
tls->release(self3); tls->release(self3);
} }
void maybeDownsize(Node *self, WriteContext *tls, ConflictSet::Impl *impl, bool needsDownsize(Node *n) {
static int minTable[] = {0, kMinChildrenNode3, kMinChildrenNode16,
kMinChildrenNode48, kMinChildrenNode256};
return n->numChildren + n->entryPresent < minTable[n->getType()];
}
void downsize(Node3 *self, WriteContext *tls, ConflictSet::Impl *impl,
Node *&dontInvalidate) { Node *&dontInvalidate) {
#if DEBUG_VERBOSE && !defined(NDEBUG)
fprintf(stderr, "maybeDownsize: %s\n", getSearchPathPrintable(self).c_str());
#endif
switch (self->getType()) {
case Type_Node0: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
case Type_Node3: {
auto *self3 = (Node3 *)self;
if (self->numChildren == 0) { if (self->numChildren == 0) {
auto *newSelf = tls->allocate<Node0>(self->partialKeyLen); auto *newSelf = tls->allocate<Node0>(self->partialKeyLen);
newSelf->copyChildrenAndKeyFrom(*self3); newSelf->copyChildrenAndKeyFrom(*self);
getInTree(self, impl) = newSelf; getInTree(self, impl) = newSelf;
tls->release(self3); tls->release(self);
} else if (self->numChildren == 1 && !self->entryPresent) { } else {
mergeWithChild(getInTree(self, impl), tls, impl, dontInvalidate, self3); assert(self->numChildren == 1 && !self->entryPresent);
mergeWithChild(getInTree(self, impl), tls, impl, dontInvalidate, self);
} }
} break; }
case Type_Node16:
if (self->numChildren + int(self->entryPresent) < kMinChildrenNode16) { void downsize(Node16 *self, WriteContext *tls, ConflictSet::Impl *impl) {
auto *self16 = (Node16 *)self; assert(self->numChildren + int(self->entryPresent) < kMinChildrenNode16);
auto *newSelf = tls->allocate<Node3>(self->partialKeyLen); auto *newSelf = tls->allocate<Node3>(self->partialKeyLen);
newSelf->copyChildrenAndKeyFrom(*self16); newSelf->copyChildrenAndKeyFrom(*self);
getInTree(self, impl) = newSelf; getInTree(self, impl) = newSelf;
tls->release(self16); tls->release(self);
} }
break;
case Type_Node48: void downsize(Node48 *self, WriteContext *tls, ConflictSet::Impl *impl) {
if (self->numChildren + int(self->entryPresent) < kMinChildrenNode48) { assert(self->numChildren + int(self->entryPresent) < kMinChildrenNode48);
auto *self48 = (Node48 *)self;
auto *newSelf = tls->allocate<Node16>(self->partialKeyLen); auto *newSelf = tls->allocate<Node16>(self->partialKeyLen);
newSelf->copyChildrenAndKeyFrom(*self48); newSelf->copyChildrenAndKeyFrom(*self);
getInTree(self, impl) = newSelf; getInTree(self, impl) = newSelf;
tls->release(self48); tls->release(self);
} }
break;
case Type_Node256: void downsize(Node256 *self, WriteContext *tls, ConflictSet::Impl *impl) {
if (self->numChildren + int(self->entryPresent) < kMinChildrenNode256) { assert(self->numChildren + int(self->entryPresent) < kMinChildrenNode256);
auto *self256 = (Node256 *)self; auto *self256 = (Node256 *)self;
auto *newSelf = tls->allocate<Node48>(self->partialKeyLen); auto *newSelf = tls->allocate<Node48>(self->partialKeyLen);
newSelf->copyChildrenAndKeyFrom(*self256); newSelf->copyChildrenAndKeyFrom(*self256);
getInTree(self, impl) = newSelf; getInTree(self, impl) = newSelf;
tls->release(self256); tls->release(self256);
} }
void downsize(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
Node *&dontInvalidate) {
switch (self->getType()) {
case Type_Node0: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE
case Type_Node3:
downsize(static_cast<Node3 *>(self), tls, impl, dontInvalidate);
break;
case Type_Node16:
downsize(static_cast<Node16 *>(self), tls, impl);
break;
case Type_Node48:
downsize(static_cast<Node48 *>(self), tls, impl);
break;
case Type_Node256:
downsize(static_cast<Node256 *>(self), tls, impl);
break; break;
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
@@ -1751,7 +1765,9 @@ Node *erase(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
self->entryPresent = false; self->entryPresent = false;
if (self->numChildren != 0) { if (self->numChildren != 0) {
maybeDownsize(self, tls, impl, result); if (needsDownsize(self)) {
downsize(self, tls, impl, result);
}
return result; return result;
} }
@@ -1771,7 +1787,10 @@ Node *erase(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
parent3->children[i] = parent3->children[i + 1]; parent3->children[i] = parent3->children[i + 1];
parent3->childMaxVersion[i] = parent3->childMaxVersion[i + 1]; parent3->childMaxVersion[i] = parent3->childMaxVersion[i + 1];
} }
assert(parent->numChildren > 0 || parent->entryPresent);
if (needsDownsize(parent3)) {
downsize(parent3, tls, impl, result);
}
} break; } break;
case Type_Node16: { case Type_Node16: {
auto *parent16 = static_cast<Node16 *>(parent); auto *parent16 = static_cast<Node16 *>(parent);
@@ -1784,8 +1803,9 @@ Node *erase(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
parent16->childMaxVersion[i] = parent16->childMaxVersion[i + 1]; parent16->childMaxVersion[i] = parent16->childMaxVersion[i + 1];
} }
// By kMinChildrenNode16 if (needsDownsize(parent16)) {
assert(parent->numChildren > 0); downsize(parent16, tls, impl, result);
}
} break; } break;
case Type_Node48: { case Type_Node48: {
auto *parent48 = static_cast<Node48 *>(parent); auto *parent48 = static_cast<Node48 *>(parent);
@@ -1813,8 +1833,9 @@ Node *erase(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
--parent->numChildren; --parent->numChildren;
// By kMinChildrenNode48 if (needsDownsize(parent48)) {
assert(parent->numChildren > 0); downsize(parent48, tls, impl, result);
}
} break; } break;
case Type_Node256: { case Type_Node256: {
auto *parent256 = static_cast<Node256 *>(parent); auto *parent256 = static_cast<Node256 *>(parent);
@@ -1823,16 +1844,14 @@ Node *erase(Node *self, WriteContext *tls, ConflictSet::Impl *impl,
--parent->numChildren; --parent->numChildren;
// By kMinChildrenNode256 if (needsDownsize(parent256)) {
assert(parent->numChildren > 0); downsize(parent256, tls, impl, result);
}
} break; } break;
default: // GCOVR_EXCL_LINE default: // GCOVR_EXCL_LINE
__builtin_unreachable(); // GCOVR_EXCL_LINE __builtin_unreachable(); // GCOVR_EXCL_LINE
} }
maybeDownsize(parent, tls, impl, result);
return result; return result;
} }