in src/java/org/apache/cassandra/dht/NormalizedRanges.java [137:202]
public NormalizedRanges<T> subtract(NormalizedRanges<T> b)
{
if (b.isEmpty())
return this;
if (b.size() == 1 && b.get(0).isFull())
return NormalizedRanges.empty();
if (this.size() == 1 && this.get(0).isFull())
return b.invert();
List<Range<T>> remaining = new ArrayList<>();
Iterator<Range<T>> aIter = this.iterator();
Iterator<Range<T>> bIter = b.iterator();
Range<T> aRange = aIter.hasNext() ? aIter.next() : null;
Range<T> bRange = bIter.hasNext() ? bIter.next() : null;
while (aRange != null && bRange != null)
{
boolean aRMin = aRange.right.isMinimum();
boolean bRMin = bRange.right.isMinimum();
if (aRMin && bRMin)
{
if (aRange.left.compareTo(bRange.left) < 0)
remaining.add(new Range<>(aRange.left, bRange.left));
checkState(!aIter.hasNext() && !bIter.hasNext());
aRange = null;
break;
}
if (!aRMin && aRange.right.compareTo(bRange.left) <= 0)
{
remaining.add(aRange);
aRange = aIter.hasNext() ? aIter.next() : null;
}
else if (!bRMin && aRange.left.compareTo(bRange.right) >= 0)
{
bRange = bIter.hasNext() ? bIter.next() : null;
}
else
{
// Handle what remains to the left of the intersection
if (aRange.left.compareTo(bRange.left) < 0)
{
remaining.add(new Range(aRange.left, bRange.left));
}
// Handle what remains to the right of the intersection
if (!aRMin && (aRange.right.compareTo(bRange.right) <= 0 | bRMin))
aRange = aIter.hasNext() ? aIter.next() : null;
else
aRange = new Range(bRange.right, aRange.right);
}
}
while (aRange != null)
{
remaining.add(aRange);
aRange = aIter.hasNext() ? aIter.next() : null;
}
NormalizedRanges<T> result = normalizedRanges(remaining);
if (Range.EXPENSIVE_CHECKS)
checkState(result.equals(Range.normalize(Range.subtract(this, b))));
return result;
}