in accord-core/src/main/java/accord/primitives/Ranges.java [170:235]
public Ranges difference(AbstractRanges<?> that)
{
if (that.isEmpty())
return this;
if (isEmpty() || that == this)
return EMPTY;
ObjectBuffers<Range> cachedRanges = cachedRanges();
Range[] result = null;
int count = 0;
int i = 0, j = 0;
Range iv = ranges[0];
while (true)
{
j = that.findNext(j, iv, CEIL);
if (j < 0)
{
j = -1 - j;
int nexti = j == that.size() ? size() : findNext(i + 1, that.ranges[j], CEIL);
if (nexti < 0) nexti = -1 - nexti;
if (count == 0)
result = cachedRanges.get(1 + (this.size() - i) + (that.size() - j));
else if (count == result.length)
result = cachedRanges.resize(result, count, count * 2);
result[count] = iv;
if (nexti > i + 1)
System.arraycopy(ranges, i + 1, result, count + 1, nexti - (i + 1));
count += nexti - i;
if (nexti == ranges.length)
break;
iv = ranges[i = nexti];
continue;
}
Range jv = that.ranges[j];
if (jv.start().compareTo(iv.start()) > 0)
{
if (count == 0)
result = cachedRanges.get(1 + (this.size() - i) + (that.size() - j));
else if (count == result.length)
result = cachedRanges.resize(result, count, count * 2);
result[count++] = iv.newRange(iv.start(), jv.start());
}
if (jv.end().compareTo(iv.end()) >= 0)
{
if (++i == ranges.length)
break;
iv = ranges[i];
}
else
{
iv = iv.newRange(jv.end(), iv.end());
}
}
if (count == 0)
return EMPTY;
return construct(cachedRanges.completeAndDiscard(result, count));
}