private AddressSet deleteSets(AddressSetView addrSet) {
		AddressSet newSet = new AddressSet();

		AddressRangeIterator rangeIt = getAddressRanges();
		AddressRangeIterator deleteRangeIt = addrSet.getAddressRanges();

		AddressRange range = rangeIt.hasNext() ? rangeIt.next() : null;
		AddressRange deleteRange = deleteRangeIt.hasNext() ? deleteRangeIt.next() : null;

		while (range != null && deleteRange != null) {
			switch (compareRange(deleteRange, range)) {
				case RANGE1_COMPLETELY_BEFORE_RANGE2:
					// delete range is complete before range so not relevant, get next delete range
					deleteRange = deleteRangeIt.hasNext() ? deleteRangeIt.next() : null;
					break;
				case RANGE1_COMPLETELY_AFTER_RANGE2:
					// delete range completely after current range, so save currentRange and get next range.
					newSet.add(range);
					range = rangeIt.hasNext() ? rangeIt.next() : null;
					break;
				case RANGE1_EQUALS_RANGE2:
				case RANGE1_STARTS_AT_RANGE2_ENDS_AFTER_RANGE2:
				case RANGE1_STARTS_BEFORE_RANGE2_ENDS_AFTER_RANGE2:
				case RANGE1_STARTS_BEFORE_RANGE2_ENDS_AT_RANGE2_END:
					// delete range covers range, don't save range, get next range
					range = rangeIt.hasNext() ? rangeIt.next() : null;
					break;
				case RANGE1_STARTS_AT_RANGE2_ENDS_BEFORE_RANGE2:
				case RANGE1_STARTS_BEFORE_RANGE2_ENDS_INSIDE_RANGE2:
					// delete range overlaps first part, adjust range and get next delete range
					range = new AddressRangeImpl(deleteRange.getMaxAddress().next(),
						range.getMaxAddress());
					deleteRange = deleteRangeIt.hasNext() ? deleteRangeIt.next() : null;
					break;
				case RANGE1_STARTS_INSIDE_RANGE2_ENDS_AFTER_RANGE2:
				case RANGE1_STARTS_INSIDE_RANGE2_ENDS_AT_RANGE2:
					// delete range truncates back of range, put in first part of range and get next range
					Address nextEnd = deleteRange.getMinAddress().previous();
					newSet.addRange(range.getMinAddress(), nextEnd);
					range = rangeIt.hasNext() ? rangeIt.next() : null;
					break;
				case RANGE1_STARTS_INSIDE_RANGE2_ENDS_INSIDE_RANGE2:
					// delete range is interior, save first part of range, adjust range and get
					// next delete range
					newSet.addRange(range.getMinAddress(), deleteRange.getMinAddress().previous());
					range = new AddressRangeImpl(deleteRange.getMaxAddress().next(),
						range.getMaxAddress());
					deleteRange = deleteRangeIt.hasNext() ? deleteRangeIt.next() : null;
					break;

			}
		}
		while (range != null) {
			newSet.add(range);
			range = rangeIt.hasNext() ? rangeIt.next() : null;
		}
		return newSet;
	}
Determines if the optimal algorithm for an operation.  Generally set operations can be done
either by applying each range of the given address set to this set OR by linearly visiting
each range in both this set and the other set.  The first approach involves doing a
binary search in this set for each range in the given set costing Nlog(M) operations where
N is the size of this set and M is the size of the other set.  The second approach involves
visiting every range in both sets in order so the cost is N + M.  Therefor, if N+M is less
than Nlog(M), we should use a linear algorithm.

@param set the other address set to operate against.
@return true if a linear algorithm will likely be faster that a series of binary searches.
Ghidra/Framework/SoftwareModeling/src/main/java/ghidra/program/model/address/AddressSet.java