diff --git a/src/main/java/org/apache/datasketches/memory/UnsafeUtil.java b/src/main/java/org/apache/datasketches/memory/UnsafeUtil.java index e6982dc7..7349829f 100644 --- a/src/main/java/org/apache/datasketches/memory/UnsafeUtil.java +++ b/src/main/java/org/apache/datasketches/memory/UnsafeUtil.java @@ -157,15 +157,14 @@ static long getFieldOffset(final Class c, final String fieldName) { } } + /** + * Like {@link Unsafe#arrayBaseOffset(Class)}, but caches return values for common array types. Useful because + * calling {@link Unsafe#arrayBaseOffset(Class)} directly incurs more overhead. + */ static long getArrayBaseOffset(final Class c) { + // Ordering here is roughly in order of what we expect to be most popular. if (c == byte[].class) { return ARRAY_BYTE_BASE_OFFSET; - } else if (c == boolean[].class) { - return ARRAY_BOOLEAN_BASE_OFFSET; - } else if (c == short[].class) { - return ARRAY_SHORT_BASE_OFFSET; - } else if (c == char[].class) { - return ARRAY_CHAR_BASE_OFFSET; } else if (c == int[].class) { return ARRAY_INT_BASE_OFFSET; } else if (c == long[].class) { @@ -174,6 +173,12 @@ static long getArrayBaseOffset(final Class c) { return ARRAY_FLOAT_BASE_OFFSET; } else if (c == double[].class) { return ARRAY_DOUBLE_BASE_OFFSET; + } else if (c == boolean[].class) { + return ARRAY_BOOLEAN_BASE_OFFSET; + } else if (c == short[].class) { + return ARRAY_SHORT_BASE_OFFSET; + } else if (c == char[].class) { + return ARRAY_CHAR_BASE_OFFSET; } else if (c == Object[].class) { return ARRAY_OBJECT_BASE_OFFSET; } else { diff --git a/src/test/java/org/apache/datasketches/memory/UnsafeUtilTest.java b/src/test/java/org/apache/datasketches/memory/UnsafeUtilTest.java index 2afa8e35..3c7ec09a 100644 --- a/src/test/java/org/apache/datasketches/memory/UnsafeUtilTest.java +++ b/src/test/java/org/apache/datasketches/memory/UnsafeUtilTest.java @@ -23,6 +23,9 @@ import static org.testng.Assert.assertTrue; import static org.testng.Assert.fail; +import java.util.ArrayList; +import java.util.List; + import org.testng.annotations.Test; @@ -122,6 +125,30 @@ public void checkInts() { Ints.checkedCast(1L << 32); } + @Test + public void checkArrayBaseOffset() + { + final List> classes = new ArrayList<>(); + classes.add(byte[].class); + classes.add(int[].class); + classes.add(long[].class); + classes.add(float[].class); + classes.add(double[].class); + classes.add(boolean[].class); + classes.add(short[].class); + classes.add(char[].class); + classes.add(Object[].class); + classes.add(byte[][].class); // An array type that is not cached + + for (Class clazz : classes) { + assertEquals( + UnsafeUtil.getArrayBaseOffset(clazz), + UnsafeUtil.unsafe.arrayBaseOffset(clazz), + clazz.getTypeName() + ); + } + } + @Test public void printlnTest() { println("PRINTING: "+this.getClass().getName());