static int compareToUnsafe(Object obj1, long o1, int l1, Object obj2, long o2, int l2) {
    final int stride = 8;
    final int minLength = Math.min(l1, l2);
    int strideLimit = minLength & ~(stride - 1);
    int i;

    /*
     * Compare 8 bytes at a time. Benchmarking shows comparing 8 bytes at a time is no slower than
     * comparing 4 bytes at a time even on 32-bit. On the other hand, it is substantially faster on
     * 64-bit.
     */
    for (i = 0; i < strideLimit; i += stride) {
      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;
        }

        /*
         * We want to compare only the first index where left[index] != right[index]. This
         * corresponds to the least significant nonzero byte in lw ^ rw, since lw and rw are
         * little-endian. Long.numberOfTrailingZeros(diff) tells us the least significant nonzero
         * bit, and zeroing out the first three bits of L.nTZ gives us the shift to get that least
         * significant nonzero byte. This comparison logic is based on UnsignedBytes from guava v21
         */
        int n = Long.numberOfTrailingZeros(lw ^ rw) & ~0x7;
        return ((int) ((lw >>> n) & 0xFF)) - ((int) ((rw >>> n) & 0xFF));
      }
    }

    // The epilogue to cover the last (minLength % stride) elements.
    for (; i < minLength; i++) {
      int il = (HBasePlatformDependent.getByte(obj1, o1 + i) & 0xFF);
      int ir = (HBasePlatformDependent.getByte(obj2, o2 + i) & 0xFF);
      if (il != ir) {
        return il - ir;
      }
    }
    return l1 - l2;
  }
ByteBuffer to hash offset to start from length to hash
hbase-common/src/main/java/org/apache/hadoop/hbase/util/ByteBufferUtils.java