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);
}