@Override
      public int compare(byte[] left, byte[] right) {
        int minLength = Math.min(left.length, right.length);
        int minWords = minLength / Longs.BYTES;

        /*
         * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a
         * time is no slower than comparing 4 bytes at a time even on 32-bit.
         * On the other hand, it is substantially faster on 64-bit.
         */
        for (int i = 0; i < minWords * Longs.BYTES; i += Longs.BYTES) {
          long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
          long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
          long diff = lw ^ rw;

          if (diff != 0) {
            if (!littleEndian) {
              return UnsignedLongs.compare(lw, rw);
            }

            // Use binary search
            int n = 0;
            int y;
            int x = (int) diff;
            if (x == 0) {
              x = (int) (diff >>> 32);
              n = 32;
            }

            y = x << 16;
            if (y == 0) {
              n += 16;
            } else {
              x = y;
            }

            y = x << 8;
            if (y == 0) {
              n += 8;
            }
            return (int) (((lw >>> n) & UNSIGNED_MASK) - ((rw >>> n) & UNSIGNED_MASK));
          }
        }

        // The epilogue to cover the last (minLength % 8) elements.
        for (int i = minWords * Longs.BYTES; i < minLength; i++) {
          int result = UnsignedBytes.compare(left[i], right[i]);
          if (result != 0) {
            return result;
          }
        }
        return left.length - right.length;
      }
Esempio n. 2
0
  private static int compare(
      @NotNull final Buffer left,
      long leftFrom,
      final long leftLength,
      @NotNull final Buffer right,
      long rightFrom,
      final long rightLength) {
    assert leftLength > 0;
    assert rightLength > 0;

    // Adapted from Guava UnsignedBytes

    long length = Math.min(leftLength, rightLength);

    for (;
        length >= Longs.BYTES;
        leftFrom += Longs.BYTES, rightFrom += Longs.BYTES, length -= Longs.BYTES) {
      final long lw = left.getLong(leftFrom);
      final long rw = right.getLong(rightFrom);
      if (lw != rw) {
        return UnsignedLongs.compare(lw, rw);
      }
    }

    if (length >= Ints.BYTES) {
      final int lw = left.getInt(leftFrom);
      final int rw = right.getInt(rightFrom);
      if (lw != rw) {
        return UnsignedInts.compare(lw, rw);
      }
      leftFrom += Ints.BYTES;
      rightFrom += Ints.BYTES;
      length -= Ints.BYTES;
    }

    for (; length > 0; leftFrom++, rightFrom++, length--) {
      final int result = UnsignedBytes.compare(left.get(leftFrom), right.get(rightFrom));

      if (result != 0) {
        return result;
      }
    }

    return (leftLength < rightLength) ? -1 : ((leftLength == rightLength) ? 0 : 1);
  }