private static RS unionInternal()

in accord-core/src/main/java/accord/primitives/AbstractRanges.java [572:621]


    private static <P1, P2, RS> RS unionInternal(Range[] as, Range[] bs, int ai, int bi, int cmp, P1 p1, P2 p2, UnionConstructor<P1, P2, RS> constructor)
    {
        Range[] result = cachedRanges().get(as.length + bs.length - bi);
        int resultCount = 0;
        if (ai > 0)
        {
            if (ai >= as.length)
                --ai;
            System.arraycopy(as, 0, result, 0, resultCount = ai);
        }
        Range prev = as[ai].start().compareTo(bs[bi].start()) <= 0 ? as[ai++] : bs[bi++];
        while (ai < as.length || bi < bs.length)
        {
            Range next;
            if (ai == as.length) next = bs[bi++];
            else if (bi == bs.length) next = as[ai++];
            else
            {
                int c = as[ai].start().compareTo(bs[bi].start());
                if (c < 0) next = as[ai++];
                else if (c > 0) next = bs[bi++];
                else if (as[ai].end().compareTo(bs[bi].end()) >= 0) next = as[ai++];
                else next = bs[bi++];
            }

            if (prev.end().compareTo(next.start()) <= cmp)
            {
                result[resultCount++] = prev;
                prev = next;
            }
            else if (next.end().compareTo(prev.end()) > 0)
            {
                prev = prev.newRange(prev.start(), next.end());
            }
        }
        result[resultCount++] = prev;

        if (resultCount == as.length && Arrays.equals(as, 0, as.length, result, 0, resultCount))
        {
            cachedRanges().forceDiscard(result, resultCount);
            return constructor.construct(p1, p2, as);
        }
        if (resultCount == bs.length && Arrays.equals(bs, 0, bs.length, result, 0, resultCount))
        {
            cachedRanges().forceDiscard(result, resultCount);
            return constructor.construct(p1, p2, bs);
        }
        result = cachedRanges().completeAndDiscard(result, resultCount);
        return constructor.construct(p1, p2, result);
    }