public Ranges difference()

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