HBASE-14940 Make our unsafe based ops more safe.
This commit is contained in:
parent
fdeca854ec
commit
4a7565af9c
|
@ -93,7 +93,7 @@ public class FuzzyRowFilter extends FilterBase {
|
|||
}
|
||||
|
||||
private void preprocessSearchKey(Pair<byte[], byte[]> 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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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,28 +1315,19 @@ 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;
|
||||
|
||||
static {
|
||||
theUnsafe = (Unsafe) AccessController.doPrivileged(
|
||||
new PrivilegedAction<Object>() {
|
||||
@Override
|
||||
public Object run() {
|
||||
try {
|
||||
Field f = Unsafe.class.getDeclaredField("theUnsafe");
|
||||
f.setAccessible(true);
|
||||
return f.get(null);
|
||||
} catch (NoSuchFieldException e) {
|
||||
// It doesn't matter what we throw;
|
||||
// it's swallowed in getBestComparer().
|
||||
throw new Error();
|
||||
} catch (IllegalAccessException e) {
|
||||
throw new Error();
|
||||
}
|
||||
}
|
||||
});
|
||||
if (UnsafeAccess.unaligned()) {
|
||||
theUnsafe = UnsafeAccess.theUnsafe;
|
||||
} else {
|
||||
// It doesn't matter what we throw;
|
||||
// it's swallowed in getBestComparer().
|
||||
throw new Error();
|
||||
}
|
||||
|
||||
BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
|
||||
|
||||
|
@ -1344,6 +1335,7 @@ public class Bytes {
|
|||
if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
|
||||
throw new AssertionError();
|
||||
}
|
||||
unaligned = UnsafeAccess.unaligned();
|
||||
}
|
||||
|
||||
static final boolean littleEndian =
|
||||
|
@ -1403,6 +1395,14 @@ public class Bytes {
|
|||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Lexicographically compare two arrays.
|
||||
*
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
package org.apache.hadoop.hbase.util;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.lang.reflect.Method;
|
||||
import java.nio.ByteOrder;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
|
@ -39,6 +40,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<Object>() {
|
||||
|
@ -57,6 +59,15 @@ public final class UnsafeAccess {
|
|||
|
||||
if(theUnsafe != null){
|
||||
BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
|
||||
try {
|
||||
// Using java.nio.Bits#unaligned() to check for unaligned-access capability
|
||||
Class<?> clazz = Class.forName("java.nio.Bits");
|
||||
Method m = clazz.getDeclaredMethod("unaligned");
|
||||
m.setAccessible(true);
|
||||
unaligned = (boolean) m.invoke(null);
|
||||
} catch (Exception e) {
|
||||
unaligned = false;
|
||||
}
|
||||
} else{
|
||||
BYTE_ARRAY_BASE_OFFSET = -1;
|
||||
}
|
||||
|
@ -68,6 +79,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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue