diff --git a/ConflictSet.cpp b/ConflictSet.cpp index 6b04956..76e9503 100644 --- a/ConflictSet.cpp +++ b/ConflictSet.cpp @@ -4094,13 +4094,34 @@ namespace interleaved_insert { typedef PRESERVE_NONE void (*Continuation)(struct Job *, struct Context *); +struct Result { + Result() = default; + Result(Node *insertionPoint, TrivialSpan remaining) + : insertionPoint(insertionPoint), remaining(remaining), + endInsertionPoint(nullptr) {} + Result(Node *insertionPoint, TrivialSpan remaining, Node *endInsertionPoint, + TrivialSpan endRemaining) + : insertionPoint(insertionPoint), remaining(remaining), + endInsertionPoint(endInsertionPoint), endRemaining(endRemaining) {} + + Node *insertionPoint; + TrivialSpan remaining; + + Node *endInsertionPoint; // Range write only + TrivialSpan endRemaining; // Range write only + + Result *nextRangeWrite; // Linked list to skip over point writes in phase 3. + // Populated in phase 2 +}; +static_assert(std::is_trivial_v); + // State relevant to an individual insertion struct Job { TrivialSpan remaining; Node *n; TaggedNodePointer child; int childIndex; - int index; + Result *result; TrivialSpan begin; // Range write only TrivialSpan end; // Range write only Node *endNode; // Range write only @@ -4165,30 +4186,6 @@ struct Job { } }; -// Result of an insertion. The search path of insertionPoint + remaining == the -// original key, and there is existing node in the tree further along the search -// path of the original key -struct Result { - Result() = default; - Result(Node *insertionPoint, TrivialSpan remaining) - : insertionPoint(insertionPoint), remaining(remaining), - endInsertionPoint(nullptr) {} - Result(Node *insertionPoint, TrivialSpan remaining, Node *endInsertionPoint, - TrivialSpan endRemaining) - : insertionPoint(insertionPoint), remaining(remaining), - endInsertionPoint(endInsertionPoint), endRemaining(endRemaining) {} - - Node *insertionPoint; - TrivialSpan remaining; - - Node *endInsertionPoint; // Range write only - TrivialSpan endRemaining; // Range write only - - Result *nextRangeWrite; // Linked list to skip over point writes in phase 3. - // Populated in phase 2 -}; -static_assert(std::is_trivial_v); - // State relevant to every insertion struct Context { int count; @@ -4250,7 +4247,7 @@ void pointIter(Job *job, Context *context) { int partialKeyIndex = longestCommonPrefix(child->partialKey(), key.data(), commonLen); if (partialKeyIndex < child->partialKeyLen) { - context->results[job->index] = {job->n, job->remaining}; + *job->result = {job->n, job->remaining}; MUSTTAIL return complete(job, context); } } @@ -4271,12 +4268,12 @@ void pointIter(Job *job, Context *context) { } if (job->remaining.size() == 0) [[unlikely]] { - context->results[job->index] = {job->n, job->remaining}; + *job->result = {job->n, job->remaining}; MUSTTAIL return complete(job, context); } if (!job->getChildAndIndex(child, job->remaining.front())) [[unlikely]] { - context->results[job->index] = {job->n, job->remaining}; + *job->result = {job->n, job->remaining}; MUSTTAIL return complete(job, context); } @@ -4312,7 +4309,7 @@ template void commonPrefixIter(Job *job, Context *context) { int prefixLen = job->commonPrefixLen - job->remaining.size(); assert(prefixLen >= 0); assert(job->n != nullptr); - context->results[job->index] = { + *job->result = { job->n, job->begin.subspan(prefixLen, job->begin.size() - prefixLen), job->n, @@ -4366,13 +4363,13 @@ template void endIter(Job *job, Context *context) { TaggedNodePointer *child = getChildUpdatingMaxVersion(endNode, job->end, context->writeVersion); if (child == nullptr) [[unlikely]] { - context->results[job->index] = {job->n, job->begin, job->endNode, job->end}; + *job->result = {job->n, job->begin, job->endNode, job->end}; assert(job->endNode != nullptr); MUSTTAIL return complete(job, context); } job->endNode = *child; if (job->remaining.size() == 0) [[unlikely]] { - context->results[job->index] = {job->n, job->begin, job->endNode, job->end}; + *job->result = {job->n, job->begin, job->endNode, job->end}; assert(job->endNode != nullptr); MUSTTAIL return complete(job, context); } @@ -4383,7 +4380,7 @@ template void endIter(Job *job, Context *context) { } void Job::init(Context *context, int index) { - this->index = index; + result = context->results + index; n = context->root; if (context->writes[index].end.len == 0) { @@ -4962,9 +4959,7 @@ struct __attribute__((visibility("hidden"))) ConflictSet::Impl { // Phase 1: Search for insertion points concurrently, without modifying the // structure of the tree. - if (count == 0) { - return; - } + assert(count > 1); constexpr int kStackResultMax = 100; interleaved_insert::Result stackResults[kStackResultMax];