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 5151d79023d..5abcee2a9fd 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
@@ -23,19 +23,20 @@ import java.util.Comparator;
import java.util.List;
import java.util.Objects;
import java.util.PriorityQueue;
-
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.PrivateCellUtil;
-import org.apache.yetus.audience.InterfaceAudience;
import org.apache.hadoop.hbase.exceptions.DeserializationException;
-import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
-import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;
-import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.BytesBytesPair;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
import org.apache.hadoop.hbase.util.Bytes;
import org.apache.hadoop.hbase.util.Pair;
-import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
+import org.apache.yetus.audience.InterfaceAudience;
+
+import org.apache.hbase.thirdparty.com.google.protobuf.InvalidProtocolBufferException;
+import org.apache.hbase.thirdparty.com.google.protobuf.UnsafeByteOperations;
+
+import org.apache.hadoop.hbase.shaded.protobuf.generated.FilterProtos;
+import org.apache.hadoop.hbase.shaded.protobuf.generated.HBaseProtos.BytesBytesPair;
/**
* This is optimized version of a standard FuzzyRowFilter Filters data based on fuzzy row key.
@@ -57,7 +58,8 @@ import org.apache.hadoop.hbase.util.UnsafeAvailChecker;
*/
@InterfaceAudience.Public
public class FuzzyRowFilter extends FilterBase {
- private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+
+ private static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
// the wildcard byte is 1 on the user side. but the filter converts it internally
// in preprocessMask. This was changed in HBASE-15676 due to a bug with using 0.
diff --git a/hbase-common/pom.xml b/hbase-common/pom.xml
index ce242286f4a..eb48680a707 100644
--- a/hbase-common/pom.xml
+++ b/hbase-common/pom.xml
@@ -167,6 +167,10 @@
org.apache.hbase.thirdpartyhbase-shaded-netty
+
+ org.apache.hbase.thirdparty
+ hbase-unsafe
+ org.slf4jslf4j-api
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
index 00964e2057f..2fc3380e662 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/io/ByteBuffAllocator.java
@@ -30,10 +30,10 @@ import org.apache.hadoop.hbase.HConstants;
import org.apache.hadoop.hbase.nio.ByteBuff;
import org.apache.hadoop.hbase.nio.SingleByteBuff;
import org.apache.hadoop.hbase.util.ReflectionUtils;
+import org.apache.hadoop.hbase.util.UnsafeAccess;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sun.nio.ch.DirectBuffer;
import org.apache.hbase.thirdparty.com.google.common.collect.Sets;
@@ -339,11 +339,8 @@ public class ByteBuffAllocator {
public void clean() {
while (!buffers.isEmpty()) {
ByteBuffer b = buffers.poll();
- if (b instanceof DirectBuffer) {
- DirectBuffer db = (DirectBuffer) b;
- if (db.cleaner() != null) {
- db.cleaner().clean();
- }
+ if (b.isDirect()) {
+ UnsafeAccess.freeDirectBuffer(b);
}
}
this.usedBufCount.set(0);
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 797bfdc1fff..46c86a3f20b 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,16 +23,13 @@ import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.channels.ReadableByteChannel;
-
import org.apache.hadoop.hbase.io.ByteBuffAllocator.Recycler;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
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 org.apache.yetus.audience.InterfaceAudience;
-import sun.nio.ch.DirectBuffer;
-
/**
* An implementation of ByteBuff where a single BB backs the BBI. This just acts as a wrapper over a
* normal BB - offheap or onheap
@@ -40,8 +37,8 @@ import sun.nio.ch.DirectBuffer;
@InterfaceAudience.Private
public class SingleByteBuff extends ByteBuff {
- private static final boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
- private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+ private static final boolean UNSAFE_AVAIL = HBasePlatformDependent.isUnsafeAvailable();
+ private static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
// Underlying BB
private final ByteBuffer buf;
@@ -65,7 +62,7 @@ public class SingleByteBuff extends ByteBuff {
this.unsafeOffset = UnsafeAccess.BYTE_ARRAY_BASE_OFFSET + buf.arrayOffset();
this.unsafeRef = buf.array();
} else {
- this.unsafeOffset = ((DirectBuffer) buf).address();
+ this.unsafeOffset = UnsafeAccess.directBufferAddress(buf);
}
}
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 d913d3c7aeb..5fb3e8f77b3 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
@@ -31,18 +31,16 @@ import java.util.Arrays;
import org.apache.hadoop.hbase.io.ByteBufferWriter;
import org.apache.hadoop.hbase.io.util.StreamUtils;
import org.apache.hadoop.hbase.nio.ByteBuff;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
import org.apache.hadoop.io.IOUtils;
import org.apache.hadoop.io.WritableUtils;
import org.apache.yetus.audience.InterfaceAudience;
-import sun.nio.ch.DirectBuffer;
-
/**
* Utility functions for working with byte buffers, such as reading/writing
* variable-length long numbers.
* @deprecated This class will become IA.Private in HBase 3.0. Downstream folks shouldn't use it.
*/
-@SuppressWarnings("restriction")
@Deprecated
@InterfaceAudience.Public
public final class ByteBufferUtils {
@@ -51,8 +49,8 @@ public final class ByteBufferUtils {
public final static int NEXT_BIT_SHIFT = 7;
public final static int NEXT_BIT_MASK = 1 << 7;
@InterfaceAudience.Private
- final static boolean UNSAFE_AVAIL = UnsafeAvailChecker.isAvailable();
- public final static boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+ final static boolean UNSAFE_AVAIL = HBasePlatformDependent.isUnsafeAvailable();
+ public final static boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
private ByteBufferUtils() {
}
@@ -83,11 +81,10 @@ public final class ByteBufferUtils {
static Comparer getBestComparer() {
try {
- Class> theClass = Class.forName(UNSAFE_COMPARER_NAME);
+ Class extends Comparer> theClass =
+ Class.forName(UNSAFE_COMPARER_NAME).asSubclass(Comparer.class);
- @SuppressWarnings("unchecked")
- Comparer comparer = (Comparer) theClass.getConstructor().newInstance();
- return comparer;
+ return theClass.getConstructor().newInstance();
} catch (Throwable t) { // ensure we really catch *everything*
return PureJavaComparer.INSTANCE;
}
@@ -142,7 +139,7 @@ public final class ByteBufferUtils {
long offset2Adj;
Object refObj2 = null;
if (buf2.isDirect()) {
- offset2Adj = o2 + ((DirectBuffer)buf2).address();
+ offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
} else {
offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
refObj2 = buf2.array();
@@ -156,13 +153,13 @@ public final class ByteBufferUtils {
long offset1Adj, offset2Adj;
Object refObj1 = null, refObj2 = null;
if (buf1.isDirect()) {
- offset1Adj = o1 + ((DirectBuffer) buf1).address();
+ offset1Adj = o1 + UnsafeAccess.directBufferAddress(buf1);
} else {
offset1Adj = o1 + buf1.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
refObj1 = buf1.array();
}
if (buf2.isDirect()) {
- offset2Adj = o2 + ((DirectBuffer) buf2).address();
+ offset2Adj = o2 + UnsafeAccess.directBufferAddress(buf2);
} else {
offset2Adj = o2 + buf2.arrayOffset() + UnsafeAccess.BYTE_ARRAY_BASE_OFFSET;
refObj2 = buf2.array();
@@ -180,12 +177,11 @@ public final class ByteBufferUtils {
static Converter getBestConverter() {
try {
- Class> theClass = Class.forName(UNSAFE_CONVERTER_NAME);
+ Class extends Converter> theClass =
+ Class.forName(UNSAFE_CONVERTER_NAME).asSubclass(Converter.class);
// yes, UnsafeComparer does implement Comparer
- @SuppressWarnings("unchecked")
- Converter converter = (Converter) theClass.getConstructor().newInstance();
- return converter;
+ return theClass.getConstructor().newInstance();
} catch (Throwable t) { // ensure we really catch *everything*
return PureJavaConverter.INSTANCE;
}
@@ -949,8 +945,8 @@ public final class ByteBufferUtils {
* 64-bit.
*/
for (i = 0; i < strideLimit; i += stride) {
- long lw = UnsafeAccess.theUnsafe.getLong(obj1, o1 + (long) i);
- long rw = UnsafeAccess.theUnsafe.getLong(obj2, o2 + (long) i);
+ long lw = HBasePlatformDependent.getLong(obj1, o1 + (long) i);
+ long rw = HBasePlatformDependent.getLong(obj2, o2 + (long) i);
if (lw != rw) {
if (!UnsafeAccess.LITTLE_ENDIAN) {
return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
@@ -971,8 +967,8 @@ public final class ByteBufferUtils {
// The epilogue to cover the last (minLength % stride) elements.
for (; i < minLength; i++) {
- int il = (UnsafeAccess.theUnsafe.getByte(obj1, o1 + i) & 0xFF);
- int ir = (UnsafeAccess.theUnsafe.getByte(obj2, o2 + i) & 0xFF);
+ int il = (HBasePlatformDependent.getByte(obj1, o1 + i) & 0xFF);
+ int ir = (HBasePlatformDependent.getByte(obj2, o2 + i) & 0xFF);
if (il != ir) {
return il - ir;
}
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 96742f03289..7afd8723715 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
@@ -43,13 +43,13 @@ import java.util.Random;
import org.apache.hadoop.hbase.Cell;
import org.apache.hadoop.hbase.CellComparator;
import org.apache.hadoop.hbase.KeyValue;
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
import org.apache.hadoop.io.RawComparator;
import org.apache.hadoop.io.WritableComparator;
import org.apache.hadoop.io.WritableUtils;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
-import sun.misc.Unsafe;
import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUtils;
@@ -58,7 +58,6 @@ import org.apache.hbase.thirdparty.org.apache.commons.collections4.CollectionUti
* comparisons, hash code generation, manufacturing keys for HashMaps or
* HashSets, and can be used as key in maps or trees.
*/
-@SuppressWarnings("restriction")
@InterfaceAudience.Public
@edu.umd.cs.findbugs.annotations.SuppressWarnings(
value="EQ_CHECK_FOR_OPERAND_NOT_COMPATIBLE_WITH_THIS",
@@ -129,7 +128,7 @@ public class Bytes implements Comparable {
public static final int ESTIMATED_HEAP_TAX = 16;
@InterfaceAudience.Private
- static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
+ static final boolean UNSAFE_UNALIGNED = HBasePlatformDependent.unaligned();
/**
* Returns length of the byte array, returning 0 if the array is null.
@@ -1487,21 +1486,17 @@ public class Bytes implements Comparable {
protected static final class UnsafeConverter extends Converter {
- static final Unsafe theUnsafe;
-
public UnsafeConverter() {}
static {
- if (UNSAFE_UNALIGNED) {
- theUnsafe = UnsafeAccess.theUnsafe;
- } else {
+ if (!UNSAFE_UNALIGNED) {
// It doesn't matter what we throw;
// it's swallowed in getBestComparer().
throw new Error();
}
// sanity check - this should never fail
- if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
+ if (HBasePlatformDependent.arrayIndexScale(byte[].class) != 1) {
throw new AssertionError();
}
}
@@ -1540,7 +1535,7 @@ public class Bytes implements Comparable {
/**
* Provides a lexicographical comparer implementation; either a Java
- * implementation or a faster implementation based on {@link Unsafe}.
+ * implementation or a faster implementation based on {@code Unsafe}.
*
*
Uses reflection to gracefully fall back to the Java implementation if
* {@code Unsafe} isn't available.
@@ -1599,18 +1594,15 @@ public class Bytes implements Comparable {
enum UnsafeComparer implements Comparer {
INSTANCE;
- static final Unsafe theUnsafe;
static {
- if (UNSAFE_UNALIGNED) {
- theUnsafe = UnsafeAccess.theUnsafe;
- } else {
+ if (!UNSAFE_UNALIGNED) {
// It doesn't matter what we throw;
// it's swallowed in getBestComparer().
throw new Error();
}
// sanity check - this should never fail
- if (theUnsafe.arrayIndexScale(byte[].class) != 1) {
+ if (HBasePlatformDependent.arrayIndexScale(byte[].class) != 1) {
throw new AssertionError();
}
}
@@ -1648,8 +1640,8 @@ public class Bytes implements Comparable {
* than 4 bytes even on 32-bit. On the other hand, it is substantially faster on 64-bit.
*/
for (i = 0; i < strideLimit; i += stride) {
- long lw = theUnsafe.getLong(buffer1, offset1Adj + i);
- long rw = theUnsafe.getLong(buffer2, offset2Adj + i);
+ long lw = HBasePlatformDependent.getLong(buffer1, offset1Adj + i);
+ long rw = HBasePlatformDependent.getLong(buffer2, offset2Adj + i);
if (lw != rw) {
if(!UnsafeAccess.LITTLE_ENDIAN) {
return ((lw + Long.MIN_VALUE) < (rw + Long.MIN_VALUE)) ? -1 : 1;
diff --git a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
index 0161fa7563a..1cb44959310 100644
--- a/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
+++ b/hbase-common/src/main/java/org/apache/hadoop/hbase/util/ClassSize.java
@@ -24,7 +24,7 @@ import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentSkipListMap;
-
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
import org.apache.yetus.audience.InterfaceAudience;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -185,13 +185,19 @@ public class ClassSize {
private byte a;
}
+ private static final int ARRAY_OBJECT_INDEX_SCALE =
+ HBasePlatformDependent.arrayIndexScale(Object[].class);
+
+ private static final int ARRAY_BYTE_INDEX_SCALE =
+ HBasePlatformDependent.arrayIndexScale(byte[].class);
+
public UnsafeLayout() {
}
@Override
int headerSize() {
try {
- return (int) UnsafeAccess.theUnsafe.objectFieldOffset(
+ return (int) HBasePlatformDependent.objectFieldOffset(
HeaderSize.class.getDeclaredField("a"));
} catch (NoSuchFieldException | SecurityException e) {
LOG.error(e.toString(), e);
@@ -201,21 +207,19 @@ public class ClassSize {
@Override
int arrayHeaderSize() {
- return UnsafeAccess.theUnsafe.arrayBaseOffset(byte[].class);
+ return HBasePlatformDependent.arrayBaseOffset(byte[].class);
}
@Override
- @SuppressWarnings("static-access")
int oopSize() {
// Unsafe.addressSize() returns 8, even with CompressedOops. This is how many bytes each
// element is allocated in an Object[].
- return UnsafeAccess.theUnsafe.ARRAY_OBJECT_INDEX_SCALE;
+ return ARRAY_OBJECT_INDEX_SCALE;
}
@Override
- @SuppressWarnings("static-access")
long sizeOfByteArray(int len) {
- return align(ARRAY + len * UnsafeAccess.theUnsafe.ARRAY_BYTE_INDEX_SCALE);
+ return align(ARRAY + len * ARRAY_BYTE_INDEX_SCALE);
}
}
@@ -223,7 +227,8 @@ public class ClassSize {
// Have a safeguard in case Unsafe estimate is wrong. This is static context, there is
// no configuration, so we look at System property.
String enabled = System.getProperty("hbase.memorylayout.use.unsafe");
- if (UnsafeAvailChecker.isAvailable() && (enabled == null || Boolean.parseBoolean(enabled))) {
+ if (HBasePlatformDependent.isUnsafeAvailable() &&
+ (enabled == null || Boolean.parseBoolean(enabled))) {
LOG.debug("Using Unsafe to estimate memory layout");
return new UnsafeLayout();
}
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 9c4b1ec37f8..ed40106c9e7 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
@@ -17,61 +17,37 @@
*/
package org.apache.hadoop.hbase.util;
-import java.lang.reflect.Field;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
-import java.security.AccessController;
-import java.security.PrivilegedAction;
-
+import org.apache.hadoop.hbase.unsafe.HBasePlatformDependent;
import org.apache.yetus.audience.InterfaceAudience;
import org.apache.yetus.audience.InterfaceStability;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sun.misc.Unsafe;
-import sun.nio.ch.DirectBuffer;
+import org.apache.hbase.thirdparty.io.netty.util.internal.PlatformDependent;
@InterfaceAudience.Private
@InterfaceStability.Evolving
public final class UnsafeAccess {
- private static final Logger LOG = LoggerFactory.getLogger(UnsafeAccess.class);
-
- public static final Unsafe theUnsafe;
-
/** The offset to the first element in a byte array. */
public static final long BYTE_ARRAY_BASE_OFFSET;
- public static final boolean LITTLE_ENDIAN = ByteOrder.nativeOrder()
- .equals(ByteOrder.LITTLE_ENDIAN);
+ public static final boolean LITTLE_ENDIAN =
+ ByteOrder.nativeOrder().equals(ByteOrder.LITTLE_ENDIAN);
// This number limits the number of bytes to copy per call to Unsafe's
// copyMemory method. A limit is imposed to allow for safepoint polling
// during a large copy
static final long UNSAFE_COPY_THRESHOLD = 1024L * 1024L;
static {
- theUnsafe = (Unsafe) AccessController.doPrivileged(new PrivilegedAction