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 3bc5b74..0158680 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 @@ -93,7 +93,7 @@ public class FuzzyRowFilter extends FilterBase { } private void preprocessSearchKey(Pair p) { - if (UnsafeAccess.isAvailable() == false) { + if (UnsafeAccess.unaligned() == false) { return; } byte[] key = p.getFirst(); @@ -111,7 +111,7 @@ public class FuzzyRowFilter extends FilterBase { * @return mask array */ private byte[] preprocessMask(byte[] mask) { - if (UnsafeAccess.isAvailable() == false) { + if (UnsafeAccess.unaligned() == false) { return mask; } if (isPreprocessedMask(mask)) return mask; @@ -320,7 +320,7 @@ public class FuzzyRowFilter extends FilterBase { static SatisfiesCode satisfies(boolean reverse, byte[] row, int offset, int length, byte[] fuzzyKeyBytes, byte[] fuzzyKeyMeta) { - if (UnsafeAccess.isAvailable() == false) { + if (UnsafeAccess.unaligned() == false) { return satisfiesNoUnsafe(reverse, row, offset, length, fuzzyKeyBytes, fuzzyKeyMeta); } 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 a5a6cca..9348145 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 @@ -604,7 +604,7 @@ public class Bytes { if (length != SIZEOF_LONG || offset + length > bytes.length) { throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_LONG); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return toLongUnsafe(bytes, offset); } else { long l = 0; @@ -645,7 +645,7 @@ public class Bytes { throw new IllegalArgumentException("Not enough room to put a long at" + " offset " + offset + " in a " + bytes.length + " byte array"); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return putLongUnsafe(bytes, offset, val); } else { for(int i = offset + 7; i > offset; i--) { @@ -800,7 +800,7 @@ public class Bytes { if (length != SIZEOF_INT || offset + length > bytes.length) { throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_INT); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return toIntUnsafe(bytes, offset); } else { int n = 0; @@ -896,7 +896,7 @@ public class Bytes { throw new IllegalArgumentException("Not enough room to put an int at" + " offset " + offset + " in a " + bytes.length + " byte array"); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return putIntUnsafe(bytes, offset, val); } else { for(int i= offset + 3; i > offset; i--) { @@ -970,7 +970,7 @@ public class Bytes { if (length != SIZEOF_SHORT || offset + length > bytes.length) { throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return toShortUnsafe(bytes, offset); } else { short n = 0; @@ -1008,7 +1008,7 @@ public class Bytes { throw new IllegalArgumentException("Not enough room to put a short at" + " offset " + offset + " in a " + bytes.length + " byte array"); } - if (UnsafeComparer.isAvailable()) { + if (UnsafeComparer.unaligned()) { return putShortUnsafe(bytes, offset, val); } else { bytes[offset+1] = (byte) val; @@ -1315,6 +1315,7 @@ public class Bytes { INSTANCE; static final Unsafe theUnsafe; + private static boolean unaligned = false; /** The offset to the first element in a byte array. */ static final int BYTE_ARRAY_BASE_OFFSET; @@ -1344,6 +1345,10 @@ public class Bytes { if (theUnsafe.arrayIndexScale(byte[].class) != 1) { throw new AssertionError(); } + String arch = AccessController + .doPrivileged(new sun.security.action.GetPropertyAction("os.arch")); + unaligned = arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") + || arch.equals("x86_64"); } static final boolean littleEndian = @@ -1404,6 +1409,14 @@ public class Bytes { } /** + * @return true when running JVM is having sun's Unsafe package available in it and underlying + * system having unaligned-access capability. + */ + public static boolean unaligned() { + return unaligned; + } + + /** * Lexicographically compare two arrays. * * @param buffer1 left operand diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java index 680bee4..73f1fb0 100644 --- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java +++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java @@ -39,6 +39,7 @@ public final class UnsafeAccess { /** The offset to the first element in a byte array. */ public static final int BYTE_ARRAY_BASE_OFFSET; + private static boolean unaligned = false; static { theUnsafe = (Unsafe) AccessController.doPrivileged(new PrivilegedAction() { @@ -57,6 +58,10 @@ public final class UnsafeAccess { if(theUnsafe != null){ BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class); + String arch = AccessController + .doPrivileged(new sun.security.action.GetPropertyAction("os.arch")); + unaligned = arch.equals("i386") || arch.equals("x86") || arch.equals("amd64") + || arch.equals("x86_64"); } else{ BYTE_ARRAY_BASE_OFFSET = -1; } @@ -68,6 +73,14 @@ public final class UnsafeAccess { return theUnsafe != null; } + /** + * @return true when running JVM is having sun's Unsafe package available in it and underlying + * system having unaligned-access capability. + */ + public static boolean unaligned() { + return unaligned; + } + public static final boolean littleEndian = ByteOrder.nativeOrder() .equals(ByteOrder.LITTLE_ENDIAN); }