You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hbase.apache.org by an...@apache.org on 2016/03/11 05:07:25 UTC
hbase git commit: HBASE-15322 Operations using Unsafe path broken for
platforms not having sun.misc.Unsafe.
Repository: hbase
Updated Branches:
refs/heads/master bb5bfe82f -> 6628d2df1
HBASE-15322 Operations using Unsafe path broken for platforms not having sun.misc.Unsafe.
Project: http://git-wip-us.apache.org/repos/asf/hbase/repo
Commit: http://git-wip-us.apache.org/repos/asf/hbase/commit/6628d2df
Tree: http://git-wip-us.apache.org/repos/asf/hbase/tree/6628d2df
Diff: http://git-wip-us.apache.org/repos/asf/hbase/diff/6628d2df
Branch: refs/heads/master
Commit: 6628d2df1183974a4e7d1ac72d73ce0810f5183e
Parents: bb5bfe8
Author: anoopsjohn <an...@gmail.com>
Authored: Fri Mar 11 09:37:00 2016 +0530
Committer: anoopsjohn <an...@gmail.com>
Committed: Fri Mar 11 09:37:00 2016 +0530
----------------------------------------------------------------------
.../hadoop/hbase/filter/FuzzyRowFilter.java | 8 +-
.../apache/hadoop/hbase/nio/SingleByteBuff.java | 5 +-
.../hadoop/hbase/util/ByteBufferUtils.java | 10 +--
.../org/apache/hadoop/hbase/util/Bytes.java | 15 ++--
.../apache/hadoop/hbase/util/UnsafeAccess.java | 29 -------
.../hadoop/hbase/util/UnsafeAvailChecker.java | 86 ++++++++++++++++++++
6 files changed, 107 insertions(+), 46 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-client/src/main/java/org/apache/hadoop/hbase/filter/FuzzyRowFilter.java
----------------------------------------------------------------------
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 0f01fb7..500d01d 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
@@ -35,6 +35,7 @@ import org.apache.hadoop.hbase.util.ByteStringer;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
import org.apache.hadoop.hbase.util.UnsafeAccess;
+import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
import com.google.common.annotations.VisibleForTesting;
import com.google.protobuf.InvalidProtocolBufferException;
@@ -60,6 +61,7 @@ import com.google.protobuf.InvalidProtocolBufferException;
@InterfaceAudience.Public
@InterfaceStability.Evolving
public class FuzzyRowFilter extends FilterBase {
+ private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
private List<Pair<byte[], byte[]>> fuzzyKeysData;
private boolean done = false;
@@ -94,7 +96,7 @@ public class FuzzyRowFilter extends FilterBase {
}
private void preprocessSearchKey(Pair<byte[], byte[]> p) {
- if (UnsafeAccess.unaligned() == false) {
+ if (!UNSAFE_UNALIGNED) {
// do nothing
return;
}
@@ -113,7 +115,7 @@ public class FuzzyRowFilter extends FilterBase {
* @return mask array
*/
private byte[] preprocessMask(byte[] mask) {
- if (UnsafeAccess.unaligned() == false) {
+ if (!UNSAFE_UNALIGNED) {
// do nothing
return mask;
}
@@ -318,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.unaligned() == false) {
+ if (!UNSAFE_UNALIGNED) {
return satisfiesNoUnsafe(reverse, row, offset, length, fuzzyKeyBytes, fuzzyKeyMeta);
}
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
index 227216a..946962b 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/nio/SingleByteBuff.java
@@ -23,6 +23,7 @@ import org.apache.hadoop.hbase.classification.InterfaceAudience;
import org.apache.hadoop.hbase.util.ByteBufferUtils;
import org.apache.hadoop.hbase.util.ObjectIntPair;
import org.apache.hadoop.hbase.util.UnsafeAccess;
+import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
import sun.nio.ch.DirectBuffer;
@@ -33,8 +34,8 @@ import sun.nio.ch.DirectBuffer;
@InterfaceAudience.Private
public class SingleByteBuff extends ByteBuff {
- private static final boolean UNSAFE_AVAIL = UnsafeAccess.isAvailable();
- private static final boolean UNSAFE_UNALIGNED = UnsafeAccess.unaligned();
+ private static final boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
+ private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
// Underlying BB
private final ByteBuffer buf;
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
index 7f3d777..6ca97da 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java
@@ -47,8 +47,8 @@ public final class ByteBufferUtils {
public final static int VALUE_MASK = 0x7f;
public final static int NEXT_BIT_SHIFT = 7;
public final static int NEXT_BIT_MASK = 1 << 7;
- private static final boolean UNSAFE_AVAIL = UnsafeAccess.isAvailable();
- private static final boolean UNSAFE_UNALIGNED = UnsafeAccess.unaligned();
+ private static final boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
+ private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
private ByteBufferUtils() {
}
@@ -150,7 +150,7 @@ public final class ByteBufferUtils {
}
public static byte toByte(ByteBuffer buffer, int offset) {
- if (UnsafeAccess.isAvailable()) {
+ if (UNSAFE_AVAIL) {
return UnsafeAccess.toByte(buffer, offset);
} else {
return buffer.get(offset);
@@ -202,7 +202,7 @@ public final class ByteBufferUtils {
}
public static int putByte(ByteBuffer buffer, int offset, byte b) {
- if (UnsafeAccess.isAvailable()) {
+ if (UNSAFE_AVAIL) {
return UnsafeAccess.putByte(buffer, offset, b);
} else {
buffer.put(offset, b);
@@ -369,7 +369,7 @@ public final class ByteBufferUtils {
* @param out destination buffer
*/
public static void copyFromBufferToBuffer(ByteBuffer in, ByteBuffer out) {
- if (UnsafeAccess.isAvailable()) {
+ if (UNSAFE_AVAIL) {
int length = in.remaining();
UnsafeAccess.copy(in, in.position(), out, out.position(), length);
out.position(out.position() + length);
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-common/src/main/java/org/apache/hadoop/hbase/util/Bytes.java
----------------------------------------------------------------------
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 987f1e2..aae6c4c 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
@@ -132,6 +132,7 @@ public class Bytes implements Comparable<Bytes> {
// SizeOf which uses java.lang.instrument says 24 bytes. (3 longs?)
public static final int ESTIMATED_HEAP_TAX = 16;
+ private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
/**
* Returns length of the byte array, returning 0 if the array is null.
@@ -789,7 +790,7 @@ public class Bytes implements Comparable<Bytes> {
if (length != SIZEOF_LONG || offset + length > bytes.length) {
throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_LONG);
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.toLong(bytes, offset);
} else {
long l = 0;
@@ -830,7 +831,7 @@ public class Bytes implements Comparable<Bytes> {
throw new IllegalArgumentException("Not enough room to put a long at"
+ " offset " + offset + " in a " + bytes.length + " byte array");
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.putLong(bytes, offset, val);
} else {
for(int i = offset + 7; i > offset; i--) {
@@ -981,7 +982,7 @@ public class Bytes implements Comparable<Bytes> {
if (length != SIZEOF_INT || offset + length > bytes.length) {
throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_INT);
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.toInt(bytes, offset);
} else {
int n = 0;
@@ -1065,7 +1066,7 @@ public class Bytes implements Comparable<Bytes> {
throw new IllegalArgumentException("Not enough room to put an int at"
+ " offset " + offset + " in a " + bytes.length + " byte array");
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.putInt(bytes, offset, val);
} else {
for(int i= offset + 3; i > offset; i--) {
@@ -1135,7 +1136,7 @@ public class Bytes implements Comparable<Bytes> {
if (length != SIZEOF_SHORT || offset + length > bytes.length) {
throw explainWrongLengthOrOffset(bytes, offset, length, SIZEOF_SHORT);
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.toShort(bytes, offset);
} else {
short n = 0;
@@ -1173,7 +1174,7 @@ public class Bytes implements Comparable<Bytes> {
throw new IllegalArgumentException("Not enough room to put a short at"
+ " offset " + offset + " in a " + bytes.length + " byte array");
}
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
return UnsafeAccess.putShort(bytes, offset, val);
} else {
bytes[offset+1] = (byte) val;
@@ -1477,7 +1478,7 @@ public class Bytes implements Comparable<Bytes> {
static final Unsafe theUnsafe;
static {
- if (UnsafeAccess.unaligned()) {
+ if (UNSAFE_UNALIGNED) {
theUnsafe = UnsafeAccess.theUnsafe;
} else {
// It doesn't matter what we throw;
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAccess.java
----------------------------------------------------------------------
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 af2632b..9078def 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
@@ -18,7 +18,6 @@
package org.apache.hadoop.hbase.util;
import java.lang.reflect.Field;
-import java.lang.reflect.Method;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.security.AccessController;
@@ -34,14 +33,11 @@ import sun.nio.ch.DirectBuffer;
@InterfaceAudience.Private
@InterfaceStability.Evolving
-@edu.umd.cs.findbugs.annotations.SuppressWarnings(value="REC_CATCH_EXCEPTION",
- justification="If exception, presume unaligned")
public final class UnsafeAccess {
private static final Log LOG = LogFactory.getLog(UnsafeAccess.class);
static final Unsafe theUnsafe;
- private static boolean unaligned;
/** The offset to the first element in a byte array. */
public static final long BYTE_ARRAY_BASE_OFFSET;
@@ -70,38 +66,13 @@ 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; // FindBugs: Causes REC_CATCH_EXCEPTION. Suppressed.
- }
} else{
BYTE_ARRAY_BASE_OFFSET = -1;
- unaligned = false;
}
}
private UnsafeAccess(){}
- /**
- * @return true when running JVM is having sun's Unsafe package available in it.
- */
- public static boolean isAvailable() {
- 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;
- }
-
// APIs to read primitive data from a byte[] using Unsafe way
/**
* Converts a byte array to a short value considering it was written in big-endian format.
http://git-wip-us.apache.org/repos/asf/hbase/blob/6628d2df/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java
----------------------------------------------------------------------
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java
new file mode 100644
index 0000000..2e140c4
--- /dev/null
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/UnsafeAvailChecker.java
@@ -0,0 +1,86 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.hadoop.hbase.util;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.hbase.classification.InterfaceAudience;
+
+@InterfaceAudience.Private
+public class UnsafeAvailChecker {
+
+ private static final String CLASS_NAME = "sun.misc.Unsafe";
+ private static final Log LOG = LogFactory.getLog(UnsafeAvailChecker.class);
+ private static boolean avail = false;
+ private static boolean unaligned = false;
+
+ static {
+ avail = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+ @Override
+ public Boolean run() {
+ try {
+ Class<?> clazz = Class.forName(CLASS_NAME);
+ Field f = clazz.getDeclaredField("theUnsafe");
+ f.setAccessible(true);
+ return f.get(null) != null;
+ } catch (Throwable e) {
+ LOG.warn("sun.misc.Unsafe is not available/accessible", e);
+ }
+ return false;
+ }
+ });
+ // When Unsafe itself is not available/accessible consider unaligned as false.
+ if (avail) {
+ 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) {
+ LOG.warn("java.nio.Bits#unaligned() check failed."
+ + "Unsafe based read/write of primitive types won't be used", e);
+ }
+ }
+ }
+
+ /**
+ * @return true when running JVM is having sun's Unsafe package available in it and it is
+ * accessible.
+ */
+ public static boolean isAvailable() {
+ return avail;
+ }
+
+ /**
+ * @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;
+ }
+
+ private UnsafeAvailChecker() {
+ // private constructor to avoid instantiation
+ }
+}
\ No newline at end of file