| 593 | } |
| 594 | |
| 595 | uint SetRepositoryAlgorithms::set_union(uint firstNode, uint secondNode, const SetNodeData* first, |
| 596 | const SetNodeData* second, uchar splitBit) |
| 597 | { |
| 598 | if (firstNode == secondNode) |
| 599 | return firstNode; |
| 600 | |
| 601 | uint firstStart = first->start(), secondEnd = second->end(); |
| 602 | |
| 603 | if (firstStart >= secondEnd) |
| 604 | return computeSetFromNodes(secondNode, firstNode, second, first, splitBit); |
| 605 | |
| 606 | uint firstEnd = first->end(), secondStart = second->start(); |
| 607 | |
| 608 | if (secondStart >= firstEnd) |
| 609 | return computeSetFromNodes(firstNode, secondNode, first, second, splitBit); |
| 610 | |
| 611 | //The ranges of first and second do intersect |
| 612 | |
| 613 | uint newStart = firstStart < secondStart ? firstStart : secondStart; |
| 614 | uint newEnd = firstEnd > secondEnd ? firstEnd : secondEnd; |
| 615 | |
| 616 | //Compute the split-position for the resulting merged node |
| 617 | uint splitPosition = splitPositionForRange(newStart, newEnd, splitBit); |
| 618 | |
| 619 | //Since the ranges overlap, we can be sure that either first or second contain splitPosition. |
| 620 | //The node that contains it, will also be split by it. |
| 621 | |
| 622 | if (splitPosition > firstStart && splitPosition < firstEnd && splitPosition > secondStart && |
| 623 | splitPosition < secondEnd) { |
| 624 | //The split-position intersect with both first and second. Continue the union on both sides of the split-position, and merge it. |
| 625 | |
| 626 | uint firstLeftNode = first->leftNode(); |
| 627 | uint firstRightNode = first->rightNode(); |
| 628 | uint secondLeftNode = second->leftNode(); |
| 629 | uint secondRightNode = second->rightNode(); |
| 630 | |
| 631 | const SetNodeData* firstLeft = repository.itemFromIndex(firstLeftNode); |
| 632 | const SetNodeData* firstRight = repository.itemFromIndex(firstRightNode); |
| 633 | const SetNodeData* secondLeft = repository.itemFromIndex(secondLeftNode); |
| 634 | const SetNodeData* secondRight = repository.itemFromIndex(secondRightNode); |
| 635 | |
| 636 | Q_ASSERT(splitPosition >= firstLeft->end() && splitPosition <= firstRight->start()); |
| 637 | Q_ASSERT(splitPosition >= secondLeft->end() && splitPosition <= secondRight->start()); |
| 638 | |
| 639 | return createSetFromNodes(set_union(firstLeftNode, secondLeftNode, firstLeft, secondLeft, splitBit), |
| 640 | set_union(firstRightNode, secondRightNode, firstRight, secondRight, splitBit)); |
| 641 | } else if (splitPosition > firstStart && splitPosition < firstEnd) { |
| 642 | uint firstLeftNode = first->leftNode(); |
| 643 | uint firstRightNode = first->rightNode(); |
| 644 | |
| 645 | const SetNodeData* firstLeft = repository.itemFromIndex(firstLeftNode); |
| 646 | const SetNodeData* firstRight = repository.itemFromIndex(firstRightNode); |
| 647 | |
| 648 | Q_ASSERT(splitPosition >= firstLeft->end() && splitPosition <= firstRight->start()); |
| 649 | |
| 650 | //splitPosition does not intersect second. That means that second is completely on one side of it. |
| 651 | //So we only need to union that side of first with second. |
| 652 |
no test coverage detected