HBASE-21208 Bytes#toShort doesn't work without unsafe
Signed-off-by: Ted Yu <yuzhihong@gmail.com> Signed-off-by: anoopsamjohn <anoopsamjohn@gmail.com> Signed-off-by: Reid Chan <reidchan@apache.org>
This commit is contained in:
parent
7ab77518a2
commit
c686b535c2
|
@ -130,7 +130,8 @@ public class Bytes implements Comparable<Bytes> {
|
||||||
// SizeOf which uses java.lang.instrument says 24 bytes. (3 longs?)
|
// SizeOf which uses java.lang.instrument says 24 bytes. (3 longs?)
|
||||||
public static final int ESTIMATED_HEAP_TAX = 16;
|
public static final int ESTIMATED_HEAP_TAX = 16;
|
||||||
|
|
||||||
private static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
|
@VisibleForTesting
|
||||||
|
static final boolean UNSAFE_UNALIGNED = UnsafeAvailChecker.unaligned();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns length of the byte array, returning 0 if the array is null.
|
* Returns length of the byte array, returning 0 if the array is null.
|
||||||
|
@ -1161,9 +1162,9 @@ public class Bytes implements Comparable<Bytes> {
|
||||||
return UnsafeAccess.toShort(bytes, offset);
|
return UnsafeAccess.toShort(bytes, offset);
|
||||||
} else {
|
} else {
|
||||||
short n = 0;
|
short n = 0;
|
||||||
n = (short) ((n ^ bytes[offset]) & 0xFF);
|
n = (short) (n ^ (bytes[offset] & 0xFF));
|
||||||
n = (short) (n << 8);
|
n = (short) (n << 8);
|
||||||
n = (short) ((n ^ bytes[offset+1]) & 0xFF);
|
n = (short) (n ^ (bytes[offset + 1] & 0xFF));
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,6 +22,8 @@ import java.io.ByteArrayOutputStream;
|
||||||
import java.io.DataInputStream;
|
import java.io.DataInputStream;
|
||||||
import java.io.DataOutputStream;
|
import java.io.DataOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.math.BigDecimal;
|
import java.math.BigDecimal;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -44,6 +46,48 @@ public class TestBytes extends TestCase {
|
||||||
public static final HBaseClassTestRule CLASS_RULE =
|
public static final HBaseClassTestRule CLASS_RULE =
|
||||||
HBaseClassTestRule.forClass(TestBytes.class);
|
HBaseClassTestRule.forClass(TestBytes.class);
|
||||||
|
|
||||||
|
private static void setUnsafe(boolean value) throws Exception {
|
||||||
|
Field field = Bytes.class.getDeclaredField("UNSAFE_UNALIGNED");
|
||||||
|
field.setAccessible(true);
|
||||||
|
Field modifiersField = Field.class.getDeclaredField("modifiers");
|
||||||
|
modifiersField.setAccessible(true);
|
||||||
|
int oldModifiers = field.getModifiers();
|
||||||
|
modifiersField.setInt(field, oldModifiers & ~Modifier.FINAL);
|
||||||
|
try {
|
||||||
|
field.set(null, value);
|
||||||
|
} finally {
|
||||||
|
modifiersField.setInt(field, oldModifiers);
|
||||||
|
}
|
||||||
|
assertEquals(Bytes.UNSAFE_UNALIGNED, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testShort() throws Exception {
|
||||||
|
testShort(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testShortUnsafe() throws Exception {
|
||||||
|
testShort(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testShort(boolean unsafe) throws Exception {
|
||||||
|
setUnsafe(unsafe);
|
||||||
|
try {
|
||||||
|
for (short n : Arrays.asList(
|
||||||
|
Short.MIN_VALUE,
|
||||||
|
(short) -100,
|
||||||
|
(short) -1,
|
||||||
|
(short) 0,
|
||||||
|
(short) 1,
|
||||||
|
(short) 300,
|
||||||
|
Short.MAX_VALUE)) {
|
||||||
|
byte[] bytes = Bytes.toBytes(n);
|
||||||
|
assertEquals(Bytes.toShort(bytes, 0, bytes.length), n);
|
||||||
|
}
|
||||||
|
} finally {
|
||||||
|
setUnsafe(UnsafeAvailChecker.unaligned());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public void testNullHashCode() {
|
public void testNullHashCode() {
|
||||||
byte [] b = null;
|
byte [] b = null;
|
||||||
Exception ee = null;
|
Exception ee = null;
|
||||||
|
|
Loading…
Reference in New Issue