コード例 #1
0
  @Override
  public MappeableContainer inot(final int firstOfRange, final int lastOfRange) {
    // TODO: this can be optimized for performance
    // determine the span of array indices to be affected
    int startIndex = BufferUtil.unsignedBinarySearch(content, 0, cardinality, (short) firstOfRange);
    if (startIndex < 0) startIndex = -startIndex - 1;
    int lastIndex =
        BufferUtil.unsignedBinarySearch(content, 0, cardinality, (short) (lastOfRange - 1));
    if (lastIndex < 0) lastIndex = -lastIndex - 1 - 1;
    final int currentValuesInRange = lastIndex - startIndex + 1;
    final int spanToBeFlipped = lastOfRange - firstOfRange;
    final int newValuesInRange = spanToBeFlipped - currentValuesInRange;
    final ShortBuffer buffer = ShortBuffer.allocate(newValuesInRange);
    final int cardinalityChange = newValuesInRange - currentValuesInRange;
    final int newCardinality = cardinality + cardinalityChange;

    if (cardinalityChange > 0) { // expansion, right shifting needed
      if (newCardinality > content.limit()) {
        // so big we need a bitmap?
        if (newCardinality > DEFAULT_MAX_SIZE)
          return toBitmapContainer().inot(firstOfRange, lastOfRange);
        final ShortBuffer co = ShortBuffer.allocate(newCardinality);
        content.rewind();
        co.put(content);
        content = co;
      }
      // slide right the contents after the range
      for (int pos = cardinality - 1; pos > lastIndex; --pos)
        content.put(pos + cardinalityChange, content.get(pos));
      negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange);
    } else { // no expansion needed
      negateRange(buffer, startIndex, lastIndex, firstOfRange, lastOfRange);
      if (cardinalityChange < 0) // contraction, left sliding.
        // Leave array oversize
        for (int i = startIndex + newValuesInRange; i < newCardinality; ++i)
          content.put(i, content.get(i - cardinalityChange));
    }
    cardinality = newCardinality;
    return this;
  }