From 9d72ff22218b11d2301aaae6bbf43b1ebe45da91 Mon Sep 17 00:00:00 2001 From: Martin Bednar Date: Mon, 22 Oct 2018 10:38:10 +0200 Subject: [PATCH] #63 Fix LObjectArrayLarge allocation --- .../src/main/scala/xerial/larray/LArray.scala | 16 ++++---- .../java/xerial/larray/japi/JLArrayTest.java | 40 ++++++++++++++++++- 2 files changed, 46 insertions(+), 10 deletions(-) diff --git a/larray/src/main/scala/xerial/larray/LArray.scala b/larray/src/main/scala/xerial/larray/LArray.scala index bc4d1e7..5dccb51 100644 --- a/larray/src/main/scala/xerial/larray/LArray.scala +++ b/larray/src/main/scala/xerial/larray/LArray.scala @@ -22,17 +22,17 @@ package xerial.larray -import scala.reflect.ClassTag +import java.io.{File, FileInputStream, FileOutputStream} +import java.nio.channels.WritableByteChannel import java.nio.{ByteBuffer, ByteOrder} -import java.nio.channels.{FileChannel, WritableByteChannel} import sun.nio.ch.DirectBuffer -import java.io.{File, FileInputStream, FileOutputStream} - import wvlet.log.LogSupport import xerial.larray.buffer.{Memory, MemoryAllocator} import xerial.larray.mmap.MMapMode +import scala.reflect.ClassTag + /** * Read-only interface of [[xerial.larray.LArray]] @@ -1096,15 +1096,15 @@ class LObjectArrayLarge[A: ClassTag](val size: Long) extends LArray[A] { /** * block size in pow(2, B) */ + private val RESERVED = 3 // Due to JVM limitations private val B = 31 - private val mask = (1L << B) - 1L + private val BLOCK_SIZE = ((1L << B) - RESERVED).toInt - @inline private def index(i: Long): Int = (i >>> B).toInt + @inline private def index(i: Long): Int = ((i + RESERVED) >>> B).toInt - @inline private def offset(i: Long): Int = (i & mask).toInt + @inline private def offset(i: Long): Int = (i - (index(i)) * BLOCK_SIZE).toInt private var array: Array[Array[A]] = { - val BLOCK_SIZE = (1L << B).toInt val NUM_BLOCKS = index(size - 1) + 1 // initialize the array val a = new Array[Array[A]](NUM_BLOCKS) diff --git a/larray/src/test/java/xerial/larray/japi/JLArrayTest.java b/larray/src/test/java/xerial/larray/japi/JLArrayTest.java index c3ab01b..ee03e61 100644 --- a/larray/src/test/java/xerial/larray/japi/JLArrayTest.java +++ b/larray/src/test/java/xerial/larray/japi/JLArrayTest.java @@ -15,11 +15,15 @@ *--------------------------------------------------------------------------*/ package xerial.larray.japi; -import junit.framework.Assert; import org.junit.Test; +import scala.reflect.ClassTag; +import xerial.larray.LArray; import xerial.larray.LIntArray; +import xerial.larray.LObjectArray; import xerial.larray.util.Logger; +import static org.junit.Assert.assertEquals; + /** * @author Taro L. Saito */ @@ -36,8 +40,40 @@ public void constructor() { for (long i = 0; i < l.size(); ++i) l.update(i, (int) (i * i)); _logger.debug(l.mkString(", ")); - Assert.assertEquals(5L, l.size()); + assertEquals(5L, l.size()); l.free(); } + + @Test + public void testLObjectArray32() { + + ClassTag classTag = scala.reflect.ClassTag$.MODULE$.apply(String.class); + LArray lObjectArray = LObjectArray.ofDim(10, classTag); + + lObjectArray.update(0, "FOO"); + lObjectArray.update(9, "BAR"); + + assertEquals(lObjectArray.apply(0), "FOO"); + assertEquals(lObjectArray.apply(9), "BAR"); + assertEquals(lObjectArray.size(), 10); + + } + + @Test + public void testLObjectArrayLarge() { + + ClassTag classTag = scala.reflect.ClassTag$.MODULE$.apply(String.class); + long oneMoreThanInt = (1L << 31) + 1; //2147483649L + LArray lObjectArray = LObjectArray.ofDim(oneMoreThanInt, classTag); + + lObjectArray.update(oneMoreThanInt - 2, "0,2147483644"); + lObjectArray.update(oneMoreThanInt - 1, "0,0"); + + assertEquals("0,2147483644", lObjectArray.apply(oneMoreThanInt - 2)); + assertEquals("0,0", lObjectArray.apply(oneMoreThanInt - 1)); + + assertEquals(oneMoreThanInt, lObjectArray.size()); + + } }