| 807 | } |
| 808 | |
| 809 | uint SetRepositoryAlgorithms::set_subtract(uint firstNode, uint secondNode, const SetNodeData* first, |
| 810 | const SetNodeData* second, uchar splitBit) |
| 811 | { |
| 812 | if (firstNode == secondNode) |
| 813 | return 0; |
| 814 | |
| 815 | if (first->start() >= second->end() || second->start() >= first->end()) |
| 816 | return firstNode; |
| 817 | |
| 818 | //The ranges of first and second do intersect |
| 819 | uint firstStart = first->start(), firstEnd = first->end(), secondStart = second->start(), secondEnd = second->end(); |
| 820 | |
| 821 | uint newStart = firstStart < secondStart ? firstStart : secondStart; |
| 822 | uint newEnd = firstEnd > secondEnd ? firstEnd : secondEnd; |
| 823 | |
| 824 | //Compute the split-position for the resulting merged node |
| 825 | uint splitPosition = splitPositionForRange(newStart, newEnd, splitBit); |
| 826 | |
| 827 | //Since the ranges overlap, we can be sure that either first or second contain splitPosition. |
| 828 | //The node that contains it, will also be split by it. |
| 829 | |
| 830 | if (splitPosition > firstStart && splitPosition < firstEnd && splitPosition > secondStart && |
| 831 | splitPosition < secondEnd) { |
| 832 | //The split-position intersect with both first and second. Continue the subtract on both sides of the split-position, and merge it. |
| 833 | |
| 834 | uint firstLeftNode = first->leftNode(); |
| 835 | uint firstRightNode = first->rightNode(); |
| 836 | |
| 837 | uint secondLeftNode = second->leftNode(); |
| 838 | uint secondRightNode = second->rightNode(); |
| 839 | |
| 840 | const SetNodeData* firstLeft = repository.itemFromIndex(firstLeftNode); |
| 841 | const SetNodeData* firstRight = repository.itemFromIndex(firstRightNode); |
| 842 | const SetNodeData* secondLeft = repository.itemFromIndex(secondLeftNode); |
| 843 | const SetNodeData* secondRight = repository.itemFromIndex(secondRightNode); |
| 844 | |
| 845 | Q_ASSERT(splitPosition >= firstLeft->end() && splitPosition <= firstRight->start()); |
| 846 | Q_ASSERT(splitPosition >= secondLeft->end() && splitPosition <= secondRight->start()); |
| 847 | |
| 848 | uint newLeftNode = set_subtract(firstLeftNode, secondLeftNode, firstLeft, secondLeft, splitBit); |
| 849 | uint newRightNode = set_subtract(firstRightNode, secondRightNode, firstRight, secondRight, splitBit); |
| 850 | |
| 851 | if (newLeftNode && newRightNode) |
| 852 | return createSetFromNodes(newLeftNode, newRightNode); |
| 853 | else if (newLeftNode) |
| 854 | return newLeftNode; |
| 855 | else |
| 856 | return newRightNode; |
| 857 | } else if (splitPosition > firstStart && splitPosition < firstEnd) { |
| 858 | // Q_ASSERT(splitPosition >= firstLeft->end() && splitPosition <= firstRight->start()); |
| 859 | |
| 860 | uint firstLeftNode = first->leftNode(); |
| 861 | uint firstRightNode = first->rightNode(); |
| 862 | |
| 863 | const SetNodeData* firstLeft = repository.itemFromIndex(firstLeftNode); |
| 864 | const SetNodeData* firstRight = repository.itemFromIndex(firstRightNode); |
| 865 | |
| 866 | //splitPosition does not intersect second. That means that second is completely on one side of it. |
no test coverage detected