fun mergeBranch()

in src/jvm/main/org/jetbrains/kotlinx/lincheck/strategy/managed/InterleavingSequenceTrackableSet.kt [241:289]


        fun mergeBranch(newChain: List<InterleavingHistoryNode>, startIndex: Int, executionsCountedEarlier: Int) {
            if (startIndex > newChain.lastIndex) return
            val firstNewNode = newChain[startIndex]
            var firstNewNodeExecutions = (firstNewNode.executions + firstNewNode.spinCyclePeriod) - executionsCountedEarlier
            check(firstNewNode.threadId == threadId)

            // Some execution points may be added to the history after the spin-cycle is detected early
            // even if we switched the execution using LoopDetector hint. In this case, the new branch may have
            // more executions than the InterleavingSequenceSetNode which told switching the thread at this point.
            // But these executions will be omitted in the next time, so we merge new branch taking execution count
            // from the corresponding existing node.
            if (cycleOccurred && firstNewNodeExecutions > executions) {
                firstNewNodeExecutions = executions
            }

            when {
                executions == firstNewNodeExecutions -> mergeFurtherOrAddNewBranch(newChain, startIndex + 1, 0)

                executions < firstNewNodeExecutions -> mergeFurtherOrAddNewBranch(
                    newChain = newChain,
                    startIndex = startIndex,
                    executionsCountedEarlier = executionsCountedEarlier + executions
                )

                else -> { // node.operations > first.operations
                    if (startIndex == newChain.lastIndex) return

                    val deltaExecutions = executions - firstNewNodeExecutions
                    val nextNode = InterleavingSequenceSetNode(
                        threadId = threadId,
                        executions = deltaExecutions,
                        transitions = transitions,
                        cyclePeriod = cyclePeriod,
                        cycleOccurred = cycleOccurred,
                        cycleLocationsHash = cycleLocationsHash
                    )
                    executions = firstNewNodeExecutions
                    cyclePeriod = firstNewNode.spinCyclePeriod
                    cycleOccurred = firstNewNode.cycleOccurred

                    val (newChainRoot, newChainLeaf) = wrapChain(newChain, startIndex + 1)
                    transitions = mutableMapOf(
                        threadId to nextNode,
                        newChainRoot.threadId to newChainRoot
                    )
                    cursor.setTo(newChainLeaf)
                }
            }
        }