This is an automated email from the ASF dual-hosted git repository.

zhangduo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/hbase-thirdparty.git


The following commit(s) were added to refs/heads/master by this push:
     new 9f5c6e2  HBASE-26773 [hbase-thirdparty] Introduce a hbase-unsafe 
module in hbase-thirdparty to remove the direct references of Unsafe in our 
main code base (#78)
9f5c6e2 is described below

commit 9f5c6e27c0519c0afb23e3dfcac5ddd19bffcfa9
Author: Duo Zhang <[email protected]>
AuthorDate: Tue Mar 1 20:58:22 2022 +0800

    HBASE-26773 [hbase-thirdparty] Introduce a hbase-unsafe module in 
hbase-thirdparty to remove the direct references of Unsafe in our main code 
base (#78)
    
    Signed-off-by: Andrew Purtell <[email protected]>
---
 hbase-unsafe/pom.xml                               |  92 ++++
 .../apache/hadoop/hbase/unsafe/HBaseUnsafe.java    | 562 +++++++++++++++++++++
 .../hadoop/hbase/unsafe/HBaseUnsafeInternal.java   | 414 +++++++++++++++
 .../hadoop/hbase/unsafe/TestHBaseUnsafe.java       |  35 ++
 pom.xml                                            |   5 +
 5 files changed, 1108 insertions(+)

diff --git a/hbase-unsafe/pom.xml b/hbase-unsafe/pom.xml
new file mode 100644
index 0000000..555b54f
--- /dev/null
+++ b/hbase-unsafe/pom.xml
@@ -0,0 +1,92 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<project xmlns="http://maven.apache.org/POM/4.0.0"; 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"; 
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 
http://maven.apache.org/maven-v4_0_0.xsd";>
+  <!--
+/**
+ * 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.
+ */
+
+-->
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.hbase.thirdparty</groupId>
+    <artifactId>hbase-thirdparty</artifactId>
+    <version>4.0.2-SNAPSHOT</version>
+    <relativePath>..</relativePath>
+  </parent>
+  <artifactId>hbase-unsafe</artifactId>
+  <name>Apache HBase Unsafe Wrapper</name>
+  <description>
+    Wrap sun.misc.Unsafe to avoid referencing it in the main code base
+  </description>
+  <properties>
+    
<maven.test.redirectTestOutputToFile>true</maven.test.redirectTestOutputToFile>
+    <!-- This library is meant to work with whatever HBase and Hadoop combos 
we still list
+         as recommended. The version here is what we'll test out of the box if 
you run mvn test
+      -->
+    <hbase.stable.version>2.4.8</hbase.stable.version>
+    <!-- should match the slf4j-api version used in the above hbase -->
+    <slf4j.version>1.7.30</slf4j.version>
+    <!-- These maybe need to match the main repo -->
+    <maven.checkstyle.version>3.1.0</maven.checkstyle.version>
+    <checkstyle.version>8.28</checkstyle.version>
+  </properties>
+  <dependencies>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-api</artifactId>
+      <version>${slf4j.version}</version>
+    </dependency>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.13.2</version>
+      <scope>test</scope>
+    </dependency>
+    <dependency>
+      <groupId>org.slf4j</groupId>
+      <artifactId>slf4j-simple</artifactId>
+      <version>${slf4j.version}</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+  <build>
+    <plugins>
+      <plugin>
+        <groupId>org.apache.maven.plugins</groupId>
+        <artifactId>maven-checkstyle-plugin</artifactId>
+        <version>${maven.checkstyle.version}</version>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.hbase</groupId>
+            <artifactId>hbase-checkstyle</artifactId>
+            <version>${hbase.stable.version}</version>
+          </dependency>
+          <dependency>
+            <groupId>com.puppycrawl.tools</groupId>
+            <artifactId>checkstyle</artifactId>
+            <version>${checkstyle.version}</version>
+          </dependency>
+        </dependencies>
+        <configuration>
+          <configLocation>hbase/checkstyle.xml</configLocation>
+          
<suppressionsLocation>hbase/checkstyle-suppressions.xml</suppressionsLocation>
+          <includeTestSourceDirectory>true</includeTestSourceDirectory>
+        </configuration>
+      </plugin>
+    </plugins>
+  </build>
+</project>
diff --git 
a/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafe.java 
b/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafe.java
new file mode 100644
index 0000000..aa142b9
--- /dev/null
+++ b/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafe.java
@@ -0,0 +1,562 @@
+/**
+ * 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.unsafe;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Delegate all methods of {@link HBaseUnsafeInternal}, so we will not touch 
the actual
+ * {@code sun.misc.Unsafe} class until we actually call the methods.
+ */
+public final class HBaseUnsafe {
+
+  private static final String CLASS_NAME = "sun.misc.Unsafe";
+  private static final Logger LOG = LoggerFactory.getLogger(HBaseUnsafe.class);
+  private static final boolean AVAIL;
+  private static final boolean UNALIGNED;
+
+  static {
+    AVAIL = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {
+
+      @Override
+      public Boolean run() {
+        return checkAvailable();
+      }
+    });
+    UNALIGNED = checkUnaligned();
+  }
+
+  private static boolean checkAvailable() {
+    try {
+      Class<?> clazz = Class.forName(CLASS_NAME);
+      Field f = clazz.getDeclaredField("theUnsafe");
+      f.setAccessible(true);
+      Object theUnsafe = f.get(null);
+      if (theUnsafe == null) {
+        LOG.warn("Could not get static instance from sun.misc.Unsafe");
+        return false;
+      }
+      // Check for availability of all methods used by UnsafeAccess
+      Method m;
+      try {
+        m = clazz.getDeclaredMethod("arrayBaseOffset", Class.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing arrayBaseOffset(Class)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("copyMemory", Object.class, long.class, 
Object.class,
+          long.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing 
copyMemory(Object,long,Object,long,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getByte", Object.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getByte(Object,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getShort", long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getShort(long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getShort", Object.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getShort(Object,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getInt", long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getInt(long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getInt", Object.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getInt(Object,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getLong", long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getLong(long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("getLong", Object.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing getLong(Object,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putByte", long.class, byte.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putByte(long,byte)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putByte", Object.class, long.class, 
byte.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putByte(Object,long,byte)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putShort", long.class, short.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putShort(long,short)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putShort", Object.class, long.class, 
short.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putShort(Object,long,short)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putInt", long.class, int.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putInt(long,int)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putInt", Object.class, long.class, 
int.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putInt(Object,long,int)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putLong", long.class, long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putLong(long,long)");
+          return false;
+        }
+        m = clazz.getDeclaredMethod("putLong", Object.class, long.class, 
long.class);
+        if (m == null) {
+          LOG.warn("sun.misc.Unsafe is missing putLong(Object,long,long)");
+          return false;
+        }
+        // theUnsafe is accessible and all methods are available
+        return true;
+      } catch (Throwable e) {
+        LOG.warn("sun.misc.Unsafe is missing one or more required methods", e);
+      }
+    } catch (Throwable e) {
+      LOG.warn("sun.misc.Unsafe is not available/accessible", e);
+    }
+    return false;
+  }
+
+  private static boolean checkUnaligned() {
+    // When Unsafe itself is not available/accessible consider unaligned as 
false.
+    if (!AVAIL) {
+      return false;
+    }
+    String arch = System.getProperty("os.arch");
+    if ("ppc64".equals(arch) || "ppc64le".equals(arch) || 
"aarch64".equals(arch)) {
+      // java.nio.Bits.unaligned() wrongly returns false on ppc (JDK-8165231),
+      return true;
+    }
+    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);
+      return (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 false;
+  }
+
+  /**
+   * @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 HBaseUnsafe() {
+    // private constructor to avoid instantiation
+  }
+
+  public static int getInt(Object o, long offset) {
+    return HBaseUnsafeInternal.getInt(o, offset);
+  }
+
+  public static void putInt(Object o, long offset, int x) {
+    HBaseUnsafeInternal.putInt(o, offset, x);
+  }
+
+  public static Object getObject(Object o, long offset) {
+    return HBaseUnsafeInternal.getObject(o, offset);
+  }
+
+  public static void putObject(Object o, long offset, Object x) {
+    HBaseUnsafeInternal.putObject(o, offset, x);
+  }
+
+  public static boolean getBoolean(Object o, long offset) {
+    return HBaseUnsafeInternal.getBoolean(o, offset);
+  }
+
+  public static void putBoolean(Object o, long offset, boolean x) {
+    HBaseUnsafeInternal.putBoolean(o, offset, x);
+  }
+
+  public static byte getByte(Object o, long offset) {
+    return HBaseUnsafeInternal.getByte(o, offset);
+  }
+
+  public static void putByte(Object o, long offset, byte x) {
+    HBaseUnsafeInternal.putByte(o, offset, x);
+  }
+
+  public static short getShort(Object o, long offset) {
+    return HBaseUnsafeInternal.getShort(o, offset);
+  }
+
+  public static void putShort(Object o, long offset, short x) {
+    HBaseUnsafeInternal.putShort(o, offset, x);
+  }
+
+  public static char getChar(Object o, long offset) {
+    return HBaseUnsafeInternal.getChar(o, offset);
+  }
+
+  public static void putChar(Object o, long offset, char x) {
+    HBaseUnsafeInternal.putChar(o, offset, x);
+  }
+
+  public static long getLong(Object o, long offset) {
+    return HBaseUnsafeInternal.getLong(o, offset);
+  }
+
+  public static void putLong(Object o, long offset, long x) {
+    HBaseUnsafeInternal.putLong(o, offset, x);
+  }
+
+  public static float getFloat(Object o, long offset) {
+    return HBaseUnsafeInternal.getFloat(o, offset);
+  }
+
+  public static void putFloat(Object o, long offset, float x) {
+    HBaseUnsafeInternal.putFloat(o, offset, x);
+  }
+
+  public static double getDouble(Object o, long offset) {
+    return HBaseUnsafeInternal.getDouble(o, offset);
+  }
+
+  public static void putDouble(Object o, long offset, double x) {
+    HBaseUnsafeInternal.putDouble(o, offset, x);
+  }
+
+  public static byte getByte(long address) {
+    return HBaseUnsafeInternal.getByte(address);
+  }
+
+  public static void putByte(long address, byte x) {
+    HBaseUnsafeInternal.putByte(address, x);
+  }
+
+  public static short getShort(long address) {
+    return HBaseUnsafeInternal.getShort(address);
+  }
+
+  public static void putShort(long address, short x) {
+    HBaseUnsafeInternal.putShort(address, x);
+  }
+
+  public static char getChar(long address) {
+    return HBaseUnsafeInternal.getChar(address);
+  }
+
+  public static void putChar(long address, char x) {
+    HBaseUnsafeInternal.putChar(address, x);
+  }
+
+  public static int getInt(long address) {
+    return HBaseUnsafeInternal.getInt(address);
+  }
+
+  public static void putInt(long address, int x) {
+    HBaseUnsafeInternal.putInt(address, x);
+  }
+
+  public static long getLong(long address) {
+    return HBaseUnsafeInternal.getLong(address);
+  }
+
+  public static void putLong(long address, long x) {
+    HBaseUnsafeInternal.putLong(address, x);
+  }
+
+  public static float getFloat(long address) {
+    return HBaseUnsafeInternal.getFloat(address);
+  }
+
+  public static void putFloat(long address, float x) {
+    HBaseUnsafeInternal.putFloat(address, x);
+  }
+
+  public static double getDouble(long address) {
+    return HBaseUnsafeInternal.getDouble(address);
+  }
+
+  public static void putDouble(long address, double x) {
+    HBaseUnsafeInternal.putDouble(address, x);
+  }
+
+  public static long getAddress(long address) {
+    return HBaseUnsafeInternal.getAddress(address);
+  }
+
+  public static void putAddress(long address, long x) {
+    HBaseUnsafeInternal.putAddress(address, x);
+  }
+
+  public static long allocateMemory(long bytes) {
+    return HBaseUnsafeInternal.allocateMemory(bytes);
+  }
+
+  public static long reallocateMemory(long address, long bytes) {
+    return HBaseUnsafeInternal.reallocateMemory(address, bytes);
+  }
+
+  public static void setMemory(Object o, long offset, long bytes, byte value) {
+    HBaseUnsafeInternal.setMemory(o, offset, bytes, value);
+  }
+
+  public static void setMemory(long address, long bytes, byte value) {
+    HBaseUnsafeInternal.setMemory(address, bytes, value);
+  }
+
+  public static void copyMemory(Object srcBase, long srcOffset, Object 
destBase, long destOffset,
+      long bytes) {
+    HBaseUnsafeInternal.copyMemory(srcBase, srcOffset, destBase, destOffset, 
bytes);
+  }
+
+  public static void copyMemory(long srcAddress, long destAddress, long bytes) 
{
+    HBaseUnsafeInternal.copyMemory(srcAddress, destAddress, bytes);
+  }
+
+  public static void freeMemory(long address) {
+    HBaseUnsafeInternal.freeMemory(address);
+  }
+
+  public static long staticFieldOffset(Field f) {
+    return HBaseUnsafeInternal.staticFieldOffset(f);
+  }
+
+  public static long objectFieldOffset(Field f) {
+    return HBaseUnsafeInternal.objectFieldOffset(f);
+  }
+
+  public static Object staticFieldBase(Field f) {
+    return HBaseUnsafeInternal.staticFieldBase(f);
+  }
+
+  public static boolean shouldBeInitialized(Class<?> c) {
+    return HBaseUnsafeInternal.shouldBeInitialized(c);
+  }
+
+  public static void ensureClassInitialized(Class<?> c) {
+    HBaseUnsafeInternal.ensureClassInitialized(c);
+  }
+
+  public static int arrayBaseOffset(Class<?> arrayClass) {
+    return HBaseUnsafeInternal.arrayBaseOffset(arrayClass);
+  }
+
+  public static int arrayIndexScale(Class<?> arrayClass) {
+    return HBaseUnsafeInternal.arrayIndexScale(arrayClass);
+  }
+
+  public static int addressSize() {
+    return HBaseUnsafeInternal.addressSize();
+  }
+
+  public static int pageSize() {
+    return HBaseUnsafeInternal.pageSize();
+  }
+
+  public static Class<?> defineClass(String name, byte[] b, int off, int len, 
ClassLoader loader,
+      ProtectionDomain protectionDomain) {
+    return HBaseUnsafeInternal.defineClass(name, b, off, len, loader, 
protectionDomain);
+  }
+
+  public static Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, 
Object[] cpPatches) {
+    return HBaseUnsafeInternal.defineAnonymousClass(hostClass, data, 
cpPatches);
+  }
+
+  public static Object allocateInstance(Class<?> cls) throws 
InstantiationException {
+    return HBaseUnsafeInternal.allocateInstance(cls);
+  }
+
+  public static void throwException(Throwable ee) {
+    HBaseUnsafeInternal.throwException(ee);
+  }
+
+  public static boolean compareAndSwapObject(Object o, long offset, Object 
expected, Object x) {
+    return HBaseUnsafeInternal.compareAndSwapObject(o, offset, expected, x);
+  }
+
+  public static boolean compareAndSwapInt(Object o, long offset, int expected, 
int x) {
+    return HBaseUnsafeInternal.compareAndSwapInt(o, offset, expected, x);
+  }
+
+  public static boolean compareAndSwapLong(Object o, long offset, long 
expected, long x) {
+    return HBaseUnsafeInternal.compareAndSwapLong(o, offset, expected, x);
+  }
+
+  public static Object getObjectVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getObjectVolatile(o, offset);
+  }
+
+  public static void putObjectVolatile(Object o, long offset, Object x) {
+    HBaseUnsafeInternal.putObjectVolatile(o, offset, x);
+  }
+
+  public static int getIntVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getIntVolatile(o, offset);
+  }
+
+  public static void putIntVolatile(Object o, long offset, int x) {
+    HBaseUnsafeInternal.putIntVolatile(o, offset, x);
+  }
+
+  public static boolean getBooleanVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getBooleanVolatile(o, offset);
+  }
+
+  public static void putBooleanVolatile(Object o, long offset, boolean x) {
+    HBaseUnsafeInternal.putBooleanVolatile(o, offset, x);
+  }
+
+  public static byte getByteVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getByteVolatile(o, offset);
+  }
+
+  public static void putByteVolatile(Object o, long offset, byte x) {
+    HBaseUnsafeInternal.putByteVolatile(o, offset, x);
+  }
+
+  public static short getShortVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getShortVolatile(o, offset);
+  }
+
+  public static void putShortVolatile(Object o, long offset, short x) {
+    HBaseUnsafeInternal.putShortVolatile(o, offset, x);
+  }
+
+  public static char getCharVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getCharVolatile(o, offset);
+  }
+
+  public static void putCharVolatile(Object o, long offset, char x) {
+    HBaseUnsafeInternal.putCharVolatile(o, offset, x);
+  }
+
+  public static long getLongVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getLongVolatile(o, offset);
+  }
+
+  public static void putLongVolatile(Object o, long offset, long x) {
+    HBaseUnsafeInternal.putLongVolatile(o, offset, x);
+  }
+
+  public static float getFloatVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getFloatVolatile(o, offset);
+  }
+
+  public static void putFloatVolatile(Object o, long offset, float x) {
+    HBaseUnsafeInternal.putFloatVolatile(o, offset, x);
+  }
+
+  public static double getDoubleVolatile(Object o, long offset) {
+    return HBaseUnsafeInternal.getDoubleVolatile(o, offset);
+  }
+
+  public static void putDoubleVolatile(Object o, long offset, double x) {
+    HBaseUnsafeInternal.putDoubleVolatile(o, offset, x);
+  }
+
+  public static void putOrderedObject(Object o, long offset, Object x) {
+    HBaseUnsafeInternal.putOrderedObject(o, offset, x);
+  }
+
+  public static void putOrderedInt(Object o, long offset, int x) {
+    HBaseUnsafeInternal.putOrderedInt(o, offset, x);
+  }
+
+  public static void putOrderedLong(Object o, long offset, long x) {
+    HBaseUnsafeInternal.putOrderedLong(o, offset, x);
+  }
+
+  public static void unpark(Object thread) {
+    HBaseUnsafeInternal.unpark(thread);
+  }
+
+  public static void park(boolean isAbsolute, long time) {
+    HBaseUnsafeInternal.park(isAbsolute, time);
+  }
+
+  public static int getLoadAverage(double[] loadavg, int nelems) {
+    return HBaseUnsafeInternal.getLoadAverage(loadavg, nelems);
+  }
+
+  public static int getAndAddInt(Object o, long offset, int delta) {
+    return HBaseUnsafeInternal.getAndAddInt(o, offset, delta);
+  }
+
+  public static long getAndAddLong(Object o, long offset, long delta) {
+    return HBaseUnsafeInternal.getAndAddLong(o, offset, delta);
+  }
+
+  public static int getAndSetInt(Object o, long offset, int newValue) {
+    return HBaseUnsafeInternal.getAndSetInt(o, offset, newValue);
+  }
+
+  public static long getAndSetLong(Object o, long offset, long newValue) {
+    return HBaseUnsafeInternal.getAndSetLong(o, offset, newValue);
+  }
+
+  public static Object getAndSetObject(Object o, long offset, Object newValue) 
{
+    return HBaseUnsafeInternal.getAndSetObject(o, offset, newValue);
+  }
+
+  public static void loadFence() {
+    HBaseUnsafeInternal.loadFence();
+  }
+
+  public static void storeFence() {
+    HBaseUnsafeInternal.storeFence();
+  }
+
+  public static void fullFence() {
+    HBaseUnsafeInternal.fullFence();
+  }
+
+}
diff --git 
a/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafeInternal.java
 
b/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafeInternal.java
new file mode 100644
index 0000000..fede210
--- /dev/null
+++ 
b/hbase-unsafe/src/main/java/org/apache/hadoop/hbase/unsafe/HBaseUnsafeInternal.java
@@ -0,0 +1,414 @@
+/**
+ * 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.unsafe;
+
+import java.lang.reflect.Field;
+import java.security.AccessController;
+import java.security.PrivilegedAction;
+import java.security.ProtectionDomain;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import sun.misc.Unsafe;
+
+/**
+ * Delegate all the method in sun.misc.Unsafe.
+ */
+@SuppressWarnings("restriction")
+final class HBaseUnsafeInternal {
+
+  private static final Logger LOG = 
LoggerFactory.getLogger(HBaseUnsafeInternal.class);
+
+  private static final Unsafe UNSAFE;
+  static {
+    UNSAFE = (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 (Throwable e) {
+          LOG.warn("sun.misc.Unsafe is not accessible", e);
+        }
+        return null;
+      }
+    });
+  }
+
+  private HBaseUnsafeInternal() {
+  }
+
+  public static int getInt(Object o, long offset) {
+    return UNSAFE.getInt(o, offset);
+  }
+
+  public static void putInt(Object o, long offset, int x) {
+    UNSAFE.putInt(o, offset, x);
+  }
+
+  public static Object getObject(Object o, long offset) {
+    return UNSAFE.getObject(o, offset);
+  }
+
+  public static void putObject(Object o, long offset, Object x) {
+    UNSAFE.putObject(o, offset, x);
+  }
+
+  public static boolean getBoolean(Object o, long offset) {
+    return UNSAFE.getBoolean(o, offset);
+  }
+
+  public static void putBoolean(Object o, long offset, boolean x) {
+    UNSAFE.putBoolean(o, offset, x);
+  }
+
+  public static byte getByte(Object o, long offset) {
+    return UNSAFE.getByte(o, offset);
+  }
+
+  public static void putByte(Object o, long offset, byte x) {
+    UNSAFE.putByte(o, offset, x);
+  }
+
+  public static short getShort(Object o, long offset) {
+    return UNSAFE.getShort(o, offset);
+  }
+
+  public static void putShort(Object o, long offset, short x) {
+    UNSAFE.putShort(o, offset, x);
+  }
+
+  public static char getChar(Object o, long offset) {
+    return UNSAFE.getChar(o, offset);
+  }
+
+  public static void putChar(Object o, long offset, char x) {
+    UNSAFE.putChar(o, offset, x);
+  }
+
+  public static long getLong(Object o, long offset) {
+    return UNSAFE.getLong(o, offset);
+  }
+
+  public static void putLong(Object o, long offset, long x) {
+    UNSAFE.putLong(o, offset, x);
+  }
+
+  public static float getFloat(Object o, long offset) {
+    return UNSAFE.getFloat(o, offset);
+  }
+
+  public static void putFloat(Object o, long offset, float x) {
+    UNSAFE.putFloat(o, offset, x);
+  }
+
+  public static double getDouble(Object o, long offset) {
+    return UNSAFE.getDouble(o, offset);
+  }
+
+  public static void putDouble(Object o, long offset, double x) {
+    UNSAFE.putDouble(o, offset, x);
+  }
+
+  public static byte getByte(long address) {
+    return UNSAFE.getByte(address);
+  }
+
+  public static void putByte(long address, byte x) {
+    UNSAFE.putByte(address, x);
+  }
+
+  public static short getShort(long address) {
+    return UNSAFE.getShort(address);
+  }
+
+  public static void putShort(long address, short x) {
+    UNSAFE.putShort(address, x);
+  }
+
+  public static char getChar(long address) {
+    return UNSAFE.getChar(address);
+  }
+
+  public static void putChar(long address, char x) {
+    UNSAFE.putChar(address, x);
+  }
+
+  public static int getInt(long address) {
+    return UNSAFE.getInt(address);
+  }
+
+  public static void putInt(long address, int x) {
+    UNSAFE.putInt(address, x);
+  }
+
+  public static long getLong(long address) {
+    return UNSAFE.getLong(address);
+  }
+
+  public static void putLong(long address, long x) {
+    UNSAFE.putLong(address, x);
+  }
+
+  public static float getFloat(long address) {
+    return UNSAFE.getFloat(address);
+  }
+
+  public static void putFloat(long address, float x) {
+    UNSAFE.putFloat(address, x);
+  }
+
+  public static double getDouble(long address) {
+    return UNSAFE.getDouble(address);
+  }
+
+  public static void putDouble(long address, double x) {
+    UNSAFE.putDouble(address, x);
+  }
+
+  public static long getAddress(long address) {
+    return UNSAFE.getAddress(address);
+  }
+
+  public static void putAddress(long address, long x) {
+    UNSAFE.putAddress(address, x);
+  }
+
+  public static long allocateMemory(long bytes) {
+    return UNSAFE.allocateMemory(bytes);
+  }
+
+  public static long reallocateMemory(long address, long bytes) {
+    return UNSAFE.reallocateMemory(address, bytes);
+  }
+
+  public static void setMemory(Object o, long offset, long bytes, byte value) {
+    UNSAFE.setMemory(o, offset, bytes, value);
+  }
+
+  public static void setMemory(long address, long bytes, byte value) {
+    UNSAFE.setMemory(address, bytes, value);
+  }
+
+  public static void copyMemory(Object srcBase, long srcOffset, Object 
destBase, long destOffset,
+      long bytes) {
+    UNSAFE.copyMemory(srcBase, srcOffset, destBase, destOffset, bytes);
+  }
+
+  public static void copyMemory(long srcAddress, long destAddress, long bytes) 
{
+    UNSAFE.copyMemory(srcAddress, destAddress, bytes);
+  }
+
+  public static void freeMemory(long address) {
+    UNSAFE.freeMemory(address);
+  }
+
+  public static long staticFieldOffset(Field f) {
+    return UNSAFE.staticFieldOffset(f);
+  }
+
+  public static long objectFieldOffset(Field f) {
+    return UNSAFE.objectFieldOffset(f);
+  }
+
+  public static Object staticFieldBase(Field f) {
+    return UNSAFE.staticFieldBase(f);
+  }
+
+  public static boolean shouldBeInitialized(Class<?> c) {
+    return UNSAFE.shouldBeInitialized(c);
+  }
+
+  public static void ensureClassInitialized(Class<?> c) {
+    UNSAFE.ensureClassInitialized(c);
+  }
+
+  public static int arrayBaseOffset(Class<?> arrayClass) {
+    return UNSAFE.arrayBaseOffset(arrayClass);
+  }
+
+  public static int arrayIndexScale(Class<?> arrayClass) {
+    return UNSAFE.arrayIndexScale(arrayClass);
+  }
+
+  public static int addressSize() {
+    return UNSAFE.addressSize();
+  }
+
+  public static int pageSize() {
+    return UNSAFE.pageSize();
+  }
+
+  public static Class<?> defineClass(String name, byte[] b, int off, int len, 
ClassLoader loader,
+      ProtectionDomain protectionDomain) {
+    return UNSAFE.defineClass(name, b, off, len, loader, protectionDomain);
+  }
+
+  public static Class<?> defineAnonymousClass(Class<?> hostClass, byte[] data, 
Object[] cpPatches) {
+    return UNSAFE.defineAnonymousClass(hostClass, data, cpPatches);
+  }
+
+  public static Object allocateInstance(Class<?> cls) throws 
InstantiationException {
+    return UNSAFE.allocateInstance(cls);
+  }
+
+  public static void throwException(Throwable ee) {
+    UNSAFE.throwException(ee);
+  }
+
+  public static boolean compareAndSwapObject(Object o, long offset, Object 
expected, Object x) {
+    return UNSAFE.compareAndSwapObject(o, offset, expected, x);
+  }
+
+  public static boolean compareAndSwapInt(Object o, long offset, int expected, 
int x) {
+    return UNSAFE.compareAndSwapInt(o, offset, expected, x);
+  }
+
+  public static boolean compareAndSwapLong(Object o, long offset, long 
expected, long x) {
+    return UNSAFE.compareAndSwapLong(o, offset, expected, x);
+  }
+
+  public static Object getObjectVolatile(Object o, long offset) {
+    return UNSAFE.getObjectVolatile(o, offset);
+  }
+
+  public static void putObjectVolatile(Object o, long offset, Object x) {
+    UNSAFE.putObjectVolatile(o, offset, x);
+  }
+
+  public static int getIntVolatile(Object o, long offset) {
+    return UNSAFE.getIntVolatile(o, offset);
+  }
+
+  public static void putIntVolatile(Object o, long offset, int x) {
+    UNSAFE.putIntVolatile(o, offset, x);
+  }
+
+  public static boolean getBooleanVolatile(Object o, long offset) {
+    return UNSAFE.getBooleanVolatile(o, offset);
+  }
+
+  public static void putBooleanVolatile(Object o, long offset, boolean x) {
+    UNSAFE.putBooleanVolatile(o, offset, x);
+  }
+
+  public static byte getByteVolatile(Object o, long offset) {
+    return UNSAFE.getByteVolatile(o, offset);
+  }
+
+  public static void putByteVolatile(Object o, long offset, byte x) {
+    UNSAFE.putByteVolatile(o, offset, x);
+  }
+
+  public static short getShortVolatile(Object o, long offset) {
+    return UNSAFE.getShortVolatile(o, offset);
+  }
+
+  public static void putShortVolatile(Object o, long offset, short x) {
+    UNSAFE.putShortVolatile(o, offset, x);
+  }
+
+  public static char getCharVolatile(Object o, long offset) {
+    return UNSAFE.getCharVolatile(o, offset);
+  }
+
+  public static void putCharVolatile(Object o, long offset, char x) {
+    UNSAFE.putCharVolatile(o, offset, x);
+  }
+
+  public static long getLongVolatile(Object o, long offset) {
+    return UNSAFE.getLongVolatile(o, offset);
+  }
+
+  public static void putLongVolatile(Object o, long offset, long x) {
+    UNSAFE.putLongVolatile(o, offset, x);
+  }
+
+  public static float getFloatVolatile(Object o, long offset) {
+    return UNSAFE.getFloatVolatile(o, offset);
+  }
+
+  public static void putFloatVolatile(Object o, long offset, float x) {
+    UNSAFE.putFloatVolatile(o, offset, x);
+  }
+
+  public static double getDoubleVolatile(Object o, long offset) {
+    return UNSAFE.getDoubleVolatile(o, offset);
+  }
+
+  public static void putDoubleVolatile(Object o, long offset, double x) {
+    UNSAFE.putDoubleVolatile(o, offset, x);
+  }
+
+  public static void putOrderedObject(Object o, long offset, Object x) {
+    UNSAFE.putOrderedObject(o, offset, x);
+  }
+
+  public static void putOrderedInt(Object o, long offset, int x) {
+    UNSAFE.putOrderedInt(o, offset, x);
+  }
+
+  public static void putOrderedLong(Object o, long offset, long x) {
+    UNSAFE.putOrderedLong(o, offset, x);
+  }
+
+  public static void unpark(Object thread) {
+    UNSAFE.unpark(thread);
+  }
+
+  public static void park(boolean isAbsolute, long time) {
+    UNSAFE.park(isAbsolute, time);
+  }
+
+  public static int getLoadAverage(double[] loadavg, int nelems) {
+    return UNSAFE.getLoadAverage(loadavg, nelems);
+  }
+
+  public static int getAndAddInt(Object o, long offset, int delta) {
+    return UNSAFE.getAndAddInt(o, offset, delta);
+  }
+
+  public static long getAndAddLong(Object o, long offset, long delta) {
+    return UNSAFE.getAndAddLong(o, offset, delta);
+  }
+
+  public static int getAndSetInt(Object o, long offset, int newValue) {
+    return UNSAFE.getAndSetInt(o, offset, newValue);
+  }
+
+  public static long getAndSetLong(Object o, long offset, long newValue) {
+    return UNSAFE.getAndSetLong(o, offset, newValue);
+  }
+
+  public static Object getAndSetObject(Object o, long offset, Object newValue) 
{
+    return UNSAFE.getAndSetObject(o, offset, newValue);
+  }
+
+  public static void loadFence() {
+    UNSAFE.loadFence();
+  }
+
+  public static void storeFence() {
+    UNSAFE.storeFence();
+  }
+
+  public static void fullFence() {
+    UNSAFE.fullFence();
+  }
+
+}
diff --git 
a/hbase-unsafe/src/test/java/org/apache/hadoop/hbase/unsafe/TestHBaseUnsafe.java
 
b/hbase-unsafe/src/test/java/org/apache/hadoop/hbase/unsafe/TestHBaseUnsafe.java
new file mode 100644
index 0000000..699996b
--- /dev/null
+++ 
b/hbase-unsafe/src/test/java/org/apache/hadoop/hbase/unsafe/TestHBaseUnsafe.java
@@ -0,0 +1,35 @@
+/**
+ * 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.unsafe;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assume.assumeTrue;
+
+import org.junit.Test;
+
+public class TestHBaseUnsafe {
+
+  @Test
+  public void test() {
+    assumeTrue(HBaseUnsafe.isAvailable());
+    byte[] arr = new byte[4];
+    int arrayBaseOffset = HBaseUnsafe.arrayBaseOffset(arr.getClass());
+    HBaseUnsafe.putInt(arr, arrayBaseOffset, 123456);
+    assertEquals(123456, HBaseUnsafe.getInt(arr, arrayBaseOffset));
+  }
+}
diff --git a/pom.xml b/pom.xml
index c15cd20..377c9c0 100644
--- a/pom.xml
+++ b/pom.xml
@@ -61,6 +61,7 @@
     <module>hbase-shaded-jersey</module>
     <module>hbase-shaded-jackson-jaxrs-json-provider</module>
     <module>hbase-noop-htrace</module>
+    <module>hbase-unsafe</module>
   </modules>
   <scm>
     <connection>scm:git:git://git.apache.org/hbase-thirdparty.git</connection>
@@ -239,6 +240,10 @@
           <groupId>org.apache.maven.plugins</groupId>
           <artifactId>maven-compiler-plugin</artifactId>
           <version>3.8.1</version>
+          <configuration>
+            <source>1.8</source>
+            <target>1.8</target>
+          </configuration>
         </plugin>
         <plugin>
           <groupId>org.apache.maven.plugins</groupId>

Reply via email to