@SuppressWarnings("CompareToUsesNonFinalVariable")
  @Override
  public int compareTo(IntSet o)
  {
    // empty set cases
    if (this.isEmpty() && o.isEmpty()) {
      return 0;
    }
    if (this.isEmpty()) {
      return -1;
    }
    if (o.isEmpty()) {
      return 1;
    }

    final ConciseSet other = convert(o);

    // the word at the end must be the same
    int res = Integer.compare(this.last, other.last);
    if (res != 0) {
      return res;
    }

    // scan words from MSB to LSB
    int thisIndex = this.lastWordIndex;
    int otherIndex = other.lastWordIndex;
    int thisWord = this.words[thisIndex];
    int otherWord = other.words[otherIndex];
    while (thisIndex >= 0 && otherIndex >= 0) {
      if (!isLiteral(thisWord)) {
        if (!isLiteral(otherWord)) {
          // compare two sequences
          // note that they are made up of at least two blocks, and we
          // start comparing from the end, that is at blocks with no
          // (un)set bits
          if (isZeroSequence(thisWord)) {
            if (isOneSequence(otherWord)) {
              // zeros < ones
              return -1;
            }
            // compare two sequences of zeros
            res = Integer.compare(getSequenceCount(otherWord), getSequenceCount(thisWord));
            if (res != 0) {
              return res;
            }
          } else {
            if (isZeroSequence(otherWord)) {
              // ones > zeros
              return 1;
            }
            // compare two sequences of ones
            res = Integer.compare(getSequenceCount(thisWord), getSequenceCount(otherWord));
            if (res != 0) {
              return res;
            }
          }
          // if the sequences are the same (both zeros or both ones)
          // and have the same length, compare the first blocks in the
          // next loop since such blocks might contain (un)set bits
          thisWord = getLiteral(thisWord);
          otherWord = getLiteral(otherWord);
        } else {
          // zeros < literal --> -1
          // ones > literal --> +1
          // note that the sequence is made up of at least two blocks,
          // and we start comparing from the end, that is at a block
          // with no (un)set bits
          if (isZeroSequence(thisWord)) {
            if (otherWord != ConciseSetUtils.ALL_ZEROS_LITERAL) {
              return -1;
            }
          } else {
            if (otherWord != ConciseSetUtils.ALL_ONES_LITERAL) {
              return 1;
            }
          }
          if (getSequenceCount(thisWord) == 1) {
            thisWord = getLiteral(thisWord);
          } else {
            thisWord--;
          }
          if (--otherIndex >= 0) {
            otherWord = other.words[otherIndex];
          }
        }
      } else if (!isLiteral(otherWord)) {
        // literal > zeros --> +1
        // literal < ones --> -1
        // note that the sequence is made up of at least two blocks,
        // and we start comparing from the end, that is at a block
        // with no (un)set bits
        if (isZeroSequence(otherWord)) {
          if (thisWord != ConciseSetUtils.ALL_ZEROS_LITERAL) {
            return 1;
          }
        } else {
          if (thisWord != ConciseSetUtils.ALL_ONES_LITERAL) {
            return -1;
          }
        }
        if (--thisIndex >= 0) {
          thisWord = this.words[thisIndex];
        }
        if (getSequenceCount(otherWord) == 1) {
          otherWord = getLiteral(otherWord);
        } else {
          otherWord--;
        }
      } else {
        // equals compare(getLiteralBits(thisWord), getLiteralBits(otherWord))
        res = Integer.compare(thisWord, otherWord);
        if (res != 0) {
          return res;
        }
        if (--thisIndex >= 0) {
          thisWord = this.words[thisIndex];
        }
        if (--otherIndex >= 0) {
          otherWord = other.words[otherIndex];
        }
      }
    }
    return thisIndex >= 0 ? 1 : (otherIndex >= 0 ? -1 : 0);
  }
@ SuppressWarnings ( "CompareToUsesNonFinalVariable" ) @ Override public int compareTo ( IntSet o ) { if ( this . isEmpty ( ) && o . isEmpty ( ) ) { return 0 ; } if ( this . isEmpty ( ) ) { return - 1 ; } if ( o . isEmpty ( ) ) { return 1 ; } final ConciseSet other = convert ( o ) ; int res = Integer . compare ( this . last , other . last ) ; if ( res != 0 ) { return res ; } int thisIndex = this . lastWordIndex ; int otherIndex = other . lastWordIndex ; int thisWord = this . words [ thisIndex ] ; int otherWord = other . words [ otherIndex ] ; while ( thisIndex >= 0 && otherIndex >= 0 ) { if ( ! isLiteral ( thisWord ) ) { if ( ! isLiteral ( otherWord ) ) { if ( isZeroSequence ( thisWord ) ) { if ( isOneSequence ( otherWord ) ) { return - 1 ; } res = Integer . compare ( getSequenceCount ( otherWord ) , getSequenceCount ( thisWord ) ) ; if ( res != 0 ) { return res ; } } else { if ( isZeroSequence ( otherWord ) ) { return 1 ; } res = Integer . compare ( getSequenceCount ( thisWord ) , getSequenceCount ( otherWord ) ) ; if ( res != 0 ) { return res ; } } thisWord = getLiteral ( thisWord ) ; otherWord = getLiteral ( otherWord ) ; } else { if ( isZeroSequence ( thisWord ) ) { if ( otherWord != ConciseSetUtils . ALL_ZEROS_LITERAL ) { return - 1 ; } } else { if ( otherWord != ConciseSetUtils . ALL_ONES_LITERAL ) { return 1 ; } } if ( getSequenceCount ( thisWord ) == 1 ) { thisWord = getLiteral ( thisWord ) ; } else { thisWord -- ; } if ( -- otherIndex >= 0 ) { otherWord = other . words [ otherIndex ] ; } } } else if ( ! isLiteral ( otherWord ) ) { if ( isZeroSequence ( otherWord ) ) { if ( thisWord != ConciseSetUtils . ALL_ZEROS_LITERAL ) { return 1 ; } } else { if ( thisWord != ConciseSetUtils . ALL_ONES_LITERAL ) { return - 1 ; } } if ( -- thisIndex >= 0 ) { thisWord = this . words [ thisIndex ] ; } if ( getSequenceCount ( otherWord ) == 1 ) { otherWord = getLiteral ( otherWord ) ; } else { otherWord -- ; } } else { res = Integer . compare ( thisWord , otherWord ) ; if ( res != 0 ) { return res ; } if ( -- thisIndex >= 0 ) { thisWord = this . words [ thisIndex ] ; } if ( -- otherIndex >= 0 ) { otherWord = other . words [ otherIndex ] ; } } } return thisIndex >= 0 ? 1 : ( otherIndex >= 0 ? - 1 : 0 ) ; }
{@inheritDoc}