Skip to content

Commit 2530f6a

Browse files
committed
#1933 remove use of sun.misc.Unsafe
1 parent 128627c commit 2530f6a

File tree

1 file changed

+15
-88
lines changed

1 file changed

+15
-88
lines changed
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,7 @@
1-
/*
2-
* Copyright © 2021-present Arcade Data Ltd ([email protected])
3-
*
4-
* Licensed under the Apache License, Version 2.0 (the "License");
5-
* you may not use this file except in compliance with the License.
6-
* You may obtain a copy of the License at
7-
*
8-
* http://www.apache.org/licenses/LICENSE-2.0
9-
*
10-
* Unless required by applicable law or agreed to in writing, software
11-
* distributed under the License is distributed on an "AS IS" BASIS,
12-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13-
* See the License for the specific language governing permissions and
14-
* limitations under the License.
15-
*
16-
* SPDX-FileCopyrightText: 2021-present Arcade Data Ltd ([email protected])
17-
* SPDX-License-Identifier: Apache-2.0
18-
*/
191
package com.arcadedb.serializer;
202

21-
import com.arcadedb.exception.ArcadeDBException;
22-
import sun.misc.Unsafe;
23-
24-
import java.lang.reflect.*;
25-
import java.nio.*;
26-
import java.security.*;
3+
import java.nio.ByteBuffer;
4+
import java.nio.ByteOrder;
275

286
/**
297
* This class was inspired by Guava's UnsignedBytes, under Apache 2 license.
@@ -35,29 +13,13 @@
3513
*/
3614
public final class UnsignedBytesComparator {
3715
private static final int UNSIGNED_MASK = 0xFF;
38-
private static final Unsafe theUnsafe;
39-
private static final int BYTE_ARRAY_BASE_OFFSET;
4016
public static final PureJavaComparator PURE_JAVA_COMPARATOR = new PureJavaComparator();
41-
public static final ByteArrayComparator BEST_COMPARATOR;
42-
43-
static {
44-
theUnsafe = getUnsafe();
45-
BYTE_ARRAY_BASE_OFFSET = theUnsafe.arrayBaseOffset(byte[].class);
46-
// fall back to the safer pure java implementation unless we're in
47-
// a 64-bit JVM with an 8-byte aligned field offset.
48-
if (!("64".equals(System.getProperty("sun.arch.data.model")) && (BYTE_ARRAY_BASE_OFFSET % 8) == 0
49-
// sanity check - this should never fail
50-
&& theUnsafe.arrayIndexScale(byte[].class) == 1)) {
51-
BEST_COMPARATOR = PURE_JAVA_COMPARATOR; // force fallback to PureJavaComparator
52-
} else {
53-
BEST_COMPARATOR = new UnsafeComparator();
54-
}
55-
}
17+
public static final ByteArrayComparator BEST_COMPARATOR = new ByteBufferComparator();
5618

5719
private UnsignedBytesComparator() {
5820
}
5921

60-
public static class UnsafeComparator implements ByteArrayComparator {
22+
public static class ByteBufferComparator implements ByteArrayComparator {
6123
static final boolean BIG_ENDIAN = ByteOrder.nativeOrder().equals(ByteOrder.BIG_ENDIAN);
6224

6325
@Override
@@ -67,13 +29,12 @@ public int compare(final byte[] left, final byte[] right) {
6729
final int strideLimit = minLength & -stride;
6830
int i;
6931

70-
/*
71-
* Compare 8 bytes at a time. Benchmarking on x86 shows a stride of 8 bytes is no slower
72-
* than 4 bytes even on 32-bit. On the other hand, it is substantially faster on 64-bit.
73-
*/
32+
ByteBuffer leftBuffer = ByteBuffer.wrap(left).order(ByteOrder.nativeOrder());
33+
ByteBuffer rightBuffer = ByteBuffer.wrap(right).order(ByteOrder.nativeOrder());
34+
7435
for (i = 0; i < strideLimit; i += stride) {
75-
final long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
76-
final long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
36+
final long lw = leftBuffer.getLong(i);
37+
final long rw = rightBuffer.getLong(i);
7738
if (lw != rw) {
7839
if (BIG_ENDIAN) {
7940
return unsignedLongsCompare(lw, rw);
@@ -83,7 +44,6 @@ public int compare(final byte[] left, final byte[] right) {
8344
}
8445
}
8546

86-
// The epilogue to cover the last (minLength % stride) elements.
8747
for (; i < minLength; i++) {
8848
final int result = UnsignedBytesComparator.compare(left[i], right[i]);
8949
if (result != 0)
@@ -99,18 +59,16 @@ public boolean equals(final byte[] left, final byte[] right, final int length) {
9959
final int strideLimit = length & -stride;
10060
int i;
10161

102-
/*
103-
* Compare 8 bytes at a time. Benchmarking on x86 shows a stride of 8 bytes is no slower
104-
* than 4 bytes even on 32-bit. On the other hand, it is substantially faster on 64-bit.
105-
*/
62+
ByteBuffer leftBuffer = ByteBuffer.wrap(left).order(ByteOrder.nativeOrder());
63+
ByteBuffer rightBuffer = ByteBuffer.wrap(right).order(ByteOrder.nativeOrder());
64+
10665
for (i = 0; i < strideLimit; i += stride) {
107-
final long lw = theUnsafe.getLong(left, BYTE_ARRAY_BASE_OFFSET + (long) i);
108-
final long rw = theUnsafe.getLong(right, BYTE_ARRAY_BASE_OFFSET + (long) i);
66+
final long lw = leftBuffer.getLong(i);
67+
final long rw = rightBuffer.getLong(i);
10968
if (lw != rw)
11069
return false;
11170
}
11271

113-
// The epilogue to cover the last (minLength % stride) elements.
11472
for (; i < length; i++) {
11573
final int result = UnsignedBytesComparator.compare(left[i], right[i]);
11674
if (result != 0)
@@ -122,7 +80,7 @@ public boolean equals(final byte[] left, final byte[] right, final int length) {
12280

12381
@Override
12482
public String toString() {
125-
return "UnsignedBytes.lexicographicalComparator() (sun.misc.Unsafe version)";
83+
return "UnsignedBytes.lexicographicalComparator() (ByteBuffer version)";
12684
}
12785
}
12886

@@ -141,7 +99,6 @@ public int compare(final byte[] left, final byte[] right) {
14199

142100
@Override
143101
public boolean equals(final byte[] left, final byte[] right, final int length) {
144-
// OPTIMIZATION: TEST LAST BYTE FIRST
145102
int result = UnsignedBytesComparator.compare(left[length - 1], right[length - 1]);
146103
if (result != 0)
147104
return false;
@@ -169,34 +126,4 @@ public static int unsignedLongsCompare(final long a, final long b) {
169126
final long b2 = b ^ Long.MIN_VALUE;
170127
return Long.compare(a2, b2);
171128
}
172-
173-
/**
174-
* Returns a sun.misc.Unsafe. Suitable for use in a 3rd party package. Replace with a simple
175-
* call to Unsafe.getUnsafe when integrating into a jdk.
176-
*
177-
* @return a sun.misc.Unsafe
178-
*/
179-
private static Unsafe getUnsafe() {
180-
try {
181-
return Unsafe.getUnsafe();
182-
} catch (final SecurityException e) {
183-
// that's okay; try reflection instead
184-
}
185-
try {
186-
return AccessController.doPrivileged((PrivilegedExceptionAction<Unsafe>) () -> {
187-
final Class<Unsafe> k = Unsafe.class;
188-
for (final Field f : k.getDeclaredFields()) {
189-
f.setAccessible(true);
190-
final Object x = f.get(null);
191-
if (k.isInstance(x)) {
192-
return k.cast(x);
193-
}
194-
}
195-
throw new NoSuchFieldError("the Unsafe");
196-
});
197-
} catch (final PrivilegedActionException e) {
198-
throw new ArcadeDBException("Could not initialize intrinsics", e.getCause());
199-
}
200-
}
201-
202129
}

0 commit comments

Comments
 (0)