charlesconnell commented on code in PR #7418:
URL: https://github.com/apache/hbase/pull/7418#discussion_r2466872773
##########
hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java:
##########
@@ -88,349 +81,150 @@ abstract int findCommonPrefix(ByteBuffer left, int
leftOffset, int leftLength, B
int rightOffset, int rightLength);
}
+ /**
+ * <a href=
+ *
"https://github.com/google/guava/blob/v21.0/guava/src/com/google/common/primitives/UnsignedBytes.java#L362">Adapted
+ * from Guava</a>
+ */
static class ComparerHolder {
- static final String UNSAFE_COMPARER_NAME = ComparerHolder.class.getName()
+ "$UnsafeComparer";
-
static final Comparer BEST_COMPARER = getBestComparer();
static Comparer getBestComparer() {
- try {
- Class<? extends Comparer> theClass =
- Class.forName(UNSAFE_COMPARER_NAME).asSubclass(Comparer.class);
-
- return theClass.getConstructor().newInstance();
- } catch (Throwable t) { // ensure we really catch *everything*
- return PureJavaComparer.INSTANCE;
- }
+ return VarHandleComparer.INSTANCE;
}
- static final class PureJavaComparer extends Comparer {
- static final PureJavaComparer INSTANCE = new PureJavaComparer();
+ static final class VarHandleComparer extends Comparer {
- private PureJavaComparer() {
- }
+ static final VarHandleComparer INSTANCE = new VarHandleComparer();
+ private static final int STRIDE = Long.BYTES;
@Override
- public int compareTo(byte[] buf1, int o1, int l1, ByteBuffer buf2, int
o2, int l2) {
- int end1 = o1 + l1;
- int end2 = o2 + l2;
- for (int i = o1, j = o2; i < end1 && j < end2; i++, j++) {
- int a = buf1[i] & 0xFF;
- int b = buf2.get(j) & 0xFF;
- if (a != b) {
- return a - b;
+ int compareTo(byte[] buf1, int o1, int l1, ByteBuffer buf2, int o2, int
l2) {
+ final int minLength = Math.min(l1, l2);
+ int strideLimit = minLength & ~(STRIDE - 1);
+ int i;
+
+ for (i = 0; i < strideLimit; i += STRIDE) {
+ // big-endian fetches are faster than little-endian because the
bytes don't need to get
+ // reversed
+ long lw = (long)
BYTE_ARRAY_LONG_VIEW_BIG_ENDIAN_VAR_HANDLE.get(buf1, o1 + i);
+ long rw = (long)
BYTE_BUFFER_LONG_VIEW_BIG_ENDIAN_VAR_HANDLE.get(buf2, o2 + i);
+ if (lw != rw) {
+ return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
}
}
- return l1 - l2;
- }
- @Override
- public int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2,
int o2, int l2) {
- int end1 = o1 + l1;
- int end2 = o2 + l2;
- for (int i = o1, j = o2; i < end1 && j < end2; i++, j++) {
- int a = buf1.get(i) & 0xFF;
- int b = buf2.get(j) & 0xFF;
- if (a != b) {
- return a - b;
+ // The epilogue to cover the last (minLength % stride) elements.
+ for (; i < minLength; i++) {
+ int il = buf1[o1 + i] & 0xFF;
+ int ir = buf2.get(o2 + i) & 0xFF;
+ if (il != ir) {
+ return il - ir;
}
}
return l1 - l2;
}
- }
-
- static final class UnsafeComparer extends Comparer {
-
- public UnsafeComparer() {
- }
-
- static {
- if (!UNSAFE_UNALIGNED) {
- throw new Error();
- }
- }
-
- @Override
- public int compareTo(byte[] buf1, int o1, int l1, ByteBuffer buf2, int
o2, int l2) {
- long offset2Adj;
- Object refObj2 = null;
- if (buf2.isDirect()) {
- offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
- } else {
- offset2Adj = o2 + buf2.arrayOffset() +
UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
- refObj2 = buf2.array();
- }
- return compareToUnsafe(buf1, o1 + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET,
l1, refObj2,
- offset2Adj, l2);
- }
@Override
public int compareTo(ByteBuffer buf1, int o1, int l1, ByteBuffer buf2,
int o2, int l2) {
- long offset1Adj, offset2Adj;
- Object refObj1 = null, refObj2 = null;
- if (buf1.isDirect()) {
- offset1Adj = o1 + UnsafeAccess.directBufferAddress(buf1);
- } else {
- offset1Adj = o1 + buf1.arrayOffset() +
UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
- refObj1 = buf1.array();
- }
- if (buf2.isDirect()) {
- offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
- } else {
- offset2Adj = o2 + buf2.arrayOffset() +
UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
- refObj2 = buf2.array();
+ final int minLength = Math.min(l1, l2);
+ int strideLimit = minLength & ~(STRIDE - 1);
+ int i;
+
+ for (i = 0; i < strideLimit; i += STRIDE) {
+ // big-endian fetches are faster than little-endian because the
bytes don't need to get
+ // reversed
+ long lw = (long)
BYTE_BUFFER_LONG_VIEW_BIG_ENDIAN_VAR_HANDLE.get(buf1, o1 + i);
+ long rw = (long)
BYTE_BUFFER_LONG_VIEW_BIG_ENDIAN_VAR_HANDLE.get(buf2, o2 + i);
+ if (lw != rw) {
+ return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
+ }
}
- return compareToUnsafe(refObj1, offset1Adj, l1, refObj2, offset2Adj,
l2);
- }
- }
- }
-
- static class ConverterHolder {
- static final String UNSAFE_CONVERTER_NAME =
- ConverterHolder.class.getName() + "$UnsafeConverter";
- static final Converter BEST_CONVERTER = getBestConverter();
-
- static Converter getBestConverter() {
- try {
- Class<? extends Converter> theClass =
- Class.forName(UNSAFE_CONVERTER_NAME).asSubclass(Converter.class);
-
- // yes, UnsafeComparer does implement Comparer<byte[]>
- return theClass.getConstructor().newInstance();
- } catch (Throwable t) { // ensure we really catch *everything*
- return PureJavaConverter.INSTANCE;
- }
- }
-
- static final class PureJavaConverter extends Converter {
- static final PureJavaConverter INSTANCE = new PureJavaConverter();
-
- private PureJavaConverter() {
- }
-
- @Override
- short toShort(ByteBuffer buffer, int offset) {
- return buffer.getShort(offset);
- }
-
- @Override
- int toInt(ByteBuffer buffer) {
- return buffer.getInt();
- }
-
- @Override
- int toInt(ByteBuffer buffer, int offset) {
- return buffer.getInt(offset);
- }
-
- @Override
- long toLong(ByteBuffer buffer, int offset) {
- return buffer.getLong(offset);
- }
-
- @Override
- void putInt(ByteBuffer buffer, int val) {
- buffer.putInt(val);
- }
-
- @Override
- int putInt(ByteBuffer buffer, int index, int val) {
- buffer.putInt(index, val);
- return index + Bytes.SIZEOF_INT;
- }
- @Override
- void putShort(ByteBuffer buffer, short val) {
- buffer.putShort(val);
- }
-
- @Override
- int putShort(ByteBuffer buffer, int index, short val) {
- buffer.putShort(index, val);
- return index + Bytes.SIZEOF_SHORT;
- }
-
- @Override
- void putLong(ByteBuffer buffer, long val) {
- buffer.putLong(val);
- }
-
- @Override
- int putLong(ByteBuffer buffer, int index, long val) {
- buffer.putLong(index, val);
- return index + Bytes.SIZEOF_LONG;
- }
- }
-
- static final class UnsafeConverter extends Converter {
-
- public UnsafeConverter() {
- }
-
- static {
- if (!UNSAFE_UNALIGNED) {
- throw new Error();
+ // The epilogue to cover the last (minLength % stride) elements.
+ for (; i < minLength; i++) {
+ int il = buf1.get(o1 + i) & 0xFF;
+ int ir = buf2.get(o2 + i) & 0xFF;
+ if (il != ir) {
+ return il - ir;
+ }
}
- }
-
- @Override
- short toShort(ByteBuffer buffer, int offset) {
- return UnsafeAccess.toShort(buffer, offset);
- }
-
- @Override
- int toInt(ByteBuffer buffer) {
- int i = UnsafeAccess.toInt(buffer, buffer.position());
- buffer.position(buffer.position() + Bytes.SIZEOF_INT);
- return i;
- }
-
- @Override
- int toInt(ByteBuffer buffer, int offset) {
- return UnsafeAccess.toInt(buffer, offset);
- }
-
- @Override
- long toLong(ByteBuffer buffer, int offset) {
- return UnsafeAccess.toLong(buffer, offset);
- }
-
- @Override
- void putInt(ByteBuffer buffer, int val) {
- int newPos = UnsafeAccess.putInt(buffer, buffer.position(), val);
- buffer.position(newPos);
- }
-
- @Override
- int putInt(ByteBuffer buffer, int index, int val) {
- return UnsafeAccess.putInt(buffer, index, val);
- }
-
- @Override
- void putShort(ByteBuffer buffer, short val) {
- int newPos = UnsafeAccess.putShort(buffer, buffer.position(), val);
- buffer.position(newPos);
- }
-
- @Override
- int putShort(ByteBuffer buffer, int index, short val) {
- return UnsafeAccess.putShort(buffer, index, val);
- }
-
- @Override
- void putLong(ByteBuffer buffer, long val) {
- int newPos = UnsafeAccess.putLong(buffer, buffer.position(), val);
- buffer.position(newPos);
- }
-
- @Override
- int putLong(ByteBuffer buffer, int index, long val) {
- return UnsafeAccess.putLong(buffer, index, val);
+ return l1 - l2;
}
}
}
static class CommonPrefixerHolder {
- static final String UNSAFE_COMMON_PREFIXER_NAME =
- CommonPrefixerHolder.class.getName() + "$UnsafeCommonPrefixer";
-
static final CommonPrefixer BEST_COMMON_PREFIXER = getBestCommonPrefixer();
static CommonPrefixer getBestCommonPrefixer() {
Review Comment:
I am keeping the CommonPrefixer interface, because when the Vector API
(hopefully) gets standardized, we can try to load a Vector-based CommonPrefixer
at runtime
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]