From e9bf15c1ab15ddebf4695356bc858b6c37e2b20c Mon Sep 17 00:00:00 2001 From: Sahil Aggarwal Date: Thu, 28 Jun 2018 21:28:45 +0530 Subject: [PATCH] HBASE-20716: [INCOMPLETE] Adds ConverterHolder in Bytes to hold the best converter(safe vs unsafe) --- .../apache/hadoop/hbase/filter/FuzzyRowFilter.java | 6 +- .../java/org/apache/hadoop/hbase/util/Bytes.java | 79 ++++++++++++++++------ 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java index 714c550ddd..51d243c1be 100644 --- a/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java +++ b/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java @@ -351,9 +351,9 @@ public class FuzzyRowFilter extends FilterBase { int j = numWords << 3; // numWords * SIZEOF_LONG; for (int i = 0; i < j; i += Bytes.SIZEOF_LONG) { - long fuzzyBytes = UnsafeAccess.toLong(fuzzyKeyBytes, i); - long fuzzyMeta = UnsafeAccess.toLong(fuzzyKeyMeta, i); - long rowValue = UnsafeAccess.toLong(row, offset + i); + long fuzzyBytes = Bytes.toLong(fuzzyKeyBytes, i); + long fuzzyMeta = Bytes.toLong(fuzzyKeyMeta, i); + long rowValue = Bytes.toLong(row, offset + i); if ((rowValue & fuzzyMeta) != (fuzzyBytes)) { // We always return NEXT_EXISTS return SatisfiesCode.NEXT_EXISTS; diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java index 15facea307..dd59483a67 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java @@ -811,16 +811,7 @@ public class Bytes implements Comparable { if (length != SIZEOF_LONG || offset + length > bytes.length) { throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_LONG); } - if (UNSAFE_UNALIGNED) { - return UnsafeAccess.toLong(bytes, offset); - } else { - long l = 0; - for(int i = offset; i < offset + length; i++) { - l <<= 8; - l ^= bytes[i] & 0xFF; - } - return l; - } + return ConverterHolder.BEST_CONVERTER.toLong(bytes, offset, length); } private static IllegalArgumentException @@ -852,16 +843,7 @@ public class Bytes implements Comparable { throw new IllegalArgumentException("Not enough room to put a long at" + " offset " + offset + " in a " + bytes.length + " byte array"); } - if (UNSAFE_UNALIGNED) { - return UnsafeAccess.putLong(bytes, offset, val); - } else { - for(int i = offset + 7; i > offset; i--) { - bytes[i] = (byte) val; - val >>>= 8; - } - bytes[offset] = (byte) val; - return offset + SIZEOF_LONG; - } + return ConverterHolder.BEST_CONVERTER.putLong(bytes, offset, val); } /** @@ -1431,11 +1413,68 @@ public class Bytes implements Comparable { ); } + interface Converter { + long toLong(byte[] bytes, int offset, int length); + int putLong(byte[] bytes, int offset, long val); + } + @VisibleForTesting static Comparer lexicographicalComparerJavaImpl() { return LexicographicalComparerHolder.PureJavaComparer.INSTANCE; } + static class ConverterHolder { + static final Converter BEST_CONVERTER = getBestConverter(); + + static Converter getBestConverter() { + if(UNSAFE_UNALIGNED) { + return UnsafeConverter.INSTANCE; + } else { + return PureJavaConverter.INSTANCE; + } + } + + enum PureJavaConverter implements Converter { + INSTANCE; + + @Override + public long toLong(byte[] bytes, int offset, int length) { + long l = 0; + for(int i = offset; i < offset + length; i++) { + l <<= 8; + l ^= bytes[i] & 0xFF; + } + return l; + } + + @Override + public int putLong(byte[] bytes, int offset, long val) { + for(int i = offset + 7; i > offset; i--) { + bytes[i] = (byte) val; + val >>>= 8; + } + bytes[offset] = (byte) val; + return offset + SIZEOF_LONG; + } + } + + enum UnsafeConverter implements Converter { + INSTANCE; + + static final Unsafe theUnsafe = UnsafeAccess.theUnsafe; + + @Override + public long toLong(byte[] bytes, int offset, int length) { + return UnsafeAccess.toLong(bytes, offset); + } + + @Override + public int putLong(byte[] bytes, int offset, long val) { + return UnsafeAccess.putLong(bytes, offset, val); + } + } + } + /** * Provides a lexicographical comparer implementation; either a Java * implementation or a faster implementation based on {@link Unsafe}. -- 2.16.2