You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by dc...@apache.org on 2021/08/19 22:18:24 UTC

svn commit: r49567 [2/14] - in /dev/datasketches/memory/2.0.0-RC1: ./ apache-datasketches-memory-2.0.0-src/ apache-datasketches-memory-2.0.0-src/datasketches-memory-java11/ apache-datasketches-memory-2.0.0-src/datasketches-memory-java11/src/ apache-dat...

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/AllocateDirectWritableMapMemoryTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,273 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/*
+ * Note: Lincoln's Gettysburg Address is in the public domain. See LICENSE.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.datasketches.memory.internal.Util.getResourceFile;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.BaseState;
+import org.apache.datasketches.memory.MapHandle;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableMapHandle;
+import org.apache.datasketches.memory.WritableMemory;
+import org.apache.datasketches.memory.internal.Util;
+import org.testng.annotations.AfterClass;
+import org.testng.annotations.BeforeClass;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class AllocateDirectWritableMapMemoryTest {
+  private static final String LS = System.getProperty("line.separator");
+
+  static final Method IS_FILE_READ_ONLY;
+
+  static {
+    IS_FILE_READ_ONLY =
+        ReflectUtil.getMethod(ReflectUtil.ALLOCATE_DIRECT_MAP, "isFileReadOnly", File.class);
+  }
+
+  private static boolean isFileReadOnly(final File file) {
+    try {
+      return (boolean) IS_FILE_READ_ONLY.invoke(null, file);
+    } catch (final IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @BeforeClass
+  public void setReadOnly() {
+    UtilTest.setGettysburgAddressFileToReadOnly();
+  }
+
+  @Test
+  public void simpleMap() throws Exception {
+    File file = getResourceFile("GettysburgAddress.txt");
+    try (MapHandle h = Memory.map(file); WritableMapHandle wh = (WritableMapHandle) h) {
+      Memory mem = h.get();
+      byte[] bytes = new byte[(int)mem.getCapacity()];
+      mem.getByteArray(0, bytes, 0, bytes.length);
+      String text = new String(bytes, UTF_8);
+      println(text);
+      try {
+        wh.force();
+        fail();
+      } catch (ReadOnlyException e) {
+        //OK
+      }
+    }
+  }
+
+  @Test
+  public void copyOffHeapToMemoryMappedFile() throws Exception {
+    long bytes = 1L << 10; //small for unit tests.  Make it larger than 2GB if you like.
+    long longs = bytes >>> 3;
+
+    File file = new File("TestFile.bin");
+    if (file.exists()) {
+      try {
+        java.nio.file.Files.delete(file.toPath());
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    assertTrue(file.createNewFile());
+    assertTrue (file.setWritable(true, false)); //writable=true, ownerOnly=false
+    assertTrue (file.isFile());
+    file.deleteOnExit();  //comment out if you want to examine the file.
+
+    try (
+        WritableMapHandle dstHandle
+          = WritableMemory.writableMap(file, 0, bytes, ByteOrder.nativeOrder());
+        WritableHandle srcHandle = WritableMemory.allocateDirect(bytes)) {
+
+      WritableMemory dstMem = dstHandle.getWritable();
+      WritableMemory srcMem = srcHandle.getWritable();
+
+      for (long i = 0; i < longs; i++) {
+        srcMem.putLong(i << 3, i); //load source with consecutive longs
+      }
+
+      srcMem.copyTo(0, dstMem, 0, srcMem.getCapacity()); //off-heap to off-heap copy
+
+      dstHandle.force(); //push any remaining to the file
+
+      //check end value
+      assertEquals(dstMem.getLong(longs - 1L << 3), longs - 1L);
+    }
+  }
+
+  @Test
+  public void checkNonNativeFile() throws Exception {
+    File file = new File("TestFile2.bin");
+    if (file.exists()) {
+      try {
+        java.nio.file.Files.delete(file.toPath());
+      } catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+    assertTrue(file.createNewFile());
+    assertTrue(file.setWritable(true, false)); //writable=true, ownerOnly=false
+    assertTrue(file.isFile());
+    file.deleteOnExit();  //comment out if you want to examine the file.
+
+    final long bytes = 8;
+    try (WritableMapHandle h = WritableMemory.writableMap(file, 0L, bytes, Util.NON_NATIVE_BYTE_ORDER)) {
+      WritableMemory wmem = h.getWritable();
+      wmem.putChar(0, (char) 1);
+      assertEquals(wmem.getByte(1), (byte) 1);
+    }
+  }
+
+  @SuppressWarnings("resource")
+  @Test(expectedExceptions = RuntimeException.class)
+  public void testMapException() throws IOException {
+    File dummy = createFile("dummy.txt", ""); //zero length
+    //throws java.lang.reflect.InvocationTargetException
+    Memory.map(dummy, 0, dummy.length(), ByteOrder.nativeOrder());
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void simpleMap2() throws Exception {
+    File file = getResourceFile("GettysburgAddress.txt");
+    assertTrue(isFileReadOnly(file));
+    try (WritableMapHandle rh =
+        WritableMemory.writableMap(file)) { //throws
+      //
+    }
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void checkOverLength() throws Exception  {
+    File file = getResourceFile("GettysburgAddress.txt");
+    try (WritableMapHandle rh =
+        WritableMemory.writableMap(file, 0, 1 << 20, ByteOrder.nativeOrder())) {
+      //
+    } catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Test
+  public void testForce() throws Exception {
+    String origStr = "Corectng spellng mistks";
+    File origFile = createFile("force_original.txt", origStr); //23
+    assertTrue(origFile.setWritable(true, false));
+    long origBytes = origFile.length();
+    String correctStr = "Correcting spelling mistakes"; //28
+    byte[] correctByteArr = correctStr.getBytes(UTF_8);
+    long corrBytes = correctByteArr.length;
+
+    try (MapHandle rh = Memory.map(origFile, 0, origBytes, ByteOrder.nativeOrder())) {
+      Memory map = rh.get();
+      rh.load();
+      assertTrue(rh.isLoaded());
+      //confirm orig string
+      byte[] buf = new byte[(int)origBytes];
+      map.getByteArray(0, buf, 0, (int)origBytes);
+      String bufStr = new String(buf, UTF_8);
+      assertEquals(bufStr, origStr);
+    }
+
+    try (WritableMapHandle wrh = WritableMemory.writableMap(origFile, 0, corrBytes,
+        ByteOrder.nativeOrder())) {
+      WritableMemory wMap = wrh.getWritable();
+      wrh.load();
+      assertTrue(wrh.isLoaded());
+      // over write content
+      wMap.putByteArray(0, correctByteArr, 0, (int)corrBytes);
+      wrh.force();
+      //confirm correct string
+      byte[] buf = new byte[(int)corrBytes];
+      wMap.getByteArray(0, buf, 0, (int)corrBytes);
+      String bufStr = new String(buf, UTF_8);
+      assertEquals(bufStr, correctStr);
+    }
+  }
+
+  private static File createFile(String fileName, String text) throws FileNotFoundException {
+    File file = new File(fileName);
+    file.deleteOnExit();
+    PrintWriter writer;
+    try {
+      writer = new PrintWriter(file, UTF_8.name());
+      writer.print(text);
+      writer.close();
+    } catch (UnsupportedEncodingException e) {
+      e.printStackTrace();
+    }
+    return file;
+  }
+
+  @Test
+  public void checkExplicitClose() throws Exception {
+    File file = getResourceFile("GettysburgAddress.txt");
+    try (MapHandle wmh = Memory.map(file)) {
+      wmh.close(); //explicit close.
+    } //end of scope call to Cleaner/Deallocator also will be redundant
+  }
+
+  @AfterClass
+  public void checkDirectCounter() {
+    long count =  BaseState.getCurrentDirectMemoryMapAllocations();
+      if (count != 0) {
+        println(""+count);
+        fail();
+      }
+    }
+
+  @Test
+  public void printlnTest() {
+    println("PRINTING: "+this.getClass().getName());
+  }
+
+  static void println(final Object o) {
+    if (o == null) { print(LS); }
+    else { print(o.toString() + LS); }
+  }
+
+  /**
+   * @param o value to print
+   */
+  static void print(final Object o) {
+    if (o != null) {
+      //System.out.print(o.toString()); //disable here
+    }
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseBufferTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.testng.Assert.fail;
+
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("javadoc")
+public class BaseBufferTest {
+
+  @Test
+  public void checkLimits() {
+    Buffer buf = Memory.wrap(new byte[100]).asBuffer();
+    buf.setStartPositionEnd(40, 45, 50);
+    buf.setStartPositionEnd(0, 0, 100);
+    try {
+      buf.setStartPositionEnd(0, 0, 101);
+      fail();
+    } catch (AssertionError e) {
+      //ok
+    }
+  }
+
+  @Test
+  public void checkLimitsAndCheck() {
+    Buffer buf = Memory.wrap(new byte[100]).asBuffer();
+    buf.setAndCheckStartPositionEnd(40, 45, 50);
+    buf.setAndCheckStartPositionEnd(0, 0, 100);
+    try {
+      buf.setAndCheckStartPositionEnd(0, 0, 101);
+      fail();
+    } catch (IllegalArgumentException e) {
+      //ok
+    }
+    buf.setAndCheckPosition(100);
+    try {
+      buf.setAndCheckPosition(101);
+      fail();
+    } catch (IllegalArgumentException e) {
+      //ok
+    }
+    buf.setPosition(99);
+    buf.incrementAndCheckPosition(1L);
+    try {
+      buf.incrementAndCheckPosition(1L);
+      fail();
+    } catch (IllegalArgumentException e) {
+      //ok
+    }
+  }
+
+  @Test
+  public void checkCheckValid() throws Exception {
+    WritableMemory wmem;
+    Buffer buf;
+    try (WritableHandle hand = WritableMemory.allocateDirect(100)) {
+      wmem = hand.getWritable();
+      buf = wmem.asBuffer();
+    }
+    try {
+      @SuppressWarnings("unused")
+      Memory mem = buf.asMemory();
+    } catch (AssertionError ae) { }
+  }
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseStateTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseStateTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BaseStateTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_DOUBLE_INDEX_SCALE;
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertTrue;
+import static org.testng.Assert.fail;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.apache.datasketches.memory.internal.BaseStateImpl;
+import org.apache.datasketches.memory.internal.Prim;
+import org.apache.datasketches.memory.internal.StepBoolean;
+import org.apache.datasketches.memory.internal.Util;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class BaseStateTest {
+
+  @Test
+  public void checkPrimOffset() {
+    int off = (int)Prim.BYTE.off();
+    assertTrue(off > 0);
+  }
+
+  @Test
+  public void checkIsSameResource() {
+    WritableMemory wmem = WritableMemory.allocate(16);
+    Memory mem = wmem;
+    assertFalse(wmem.isSameResource(null));
+    assertTrue(wmem.isSameResource(mem));
+
+    WritableBuffer wbuf = wmem.asWritableBuffer();
+    Buffer buf = wbuf;
+    assertFalse(wbuf.isSameResource(null));
+    assertTrue(wbuf.isSameResource(buf));
+  }
+
+  @Test
+  public void checkNotEqualTo() {
+    byte[] arr = new byte[8];
+    Memory mem = Memory.wrap(arr);
+    assertFalse(mem.equalTo(0, arr, 0, 8));
+  }
+
+  //StepBoolean checks
+  @Test
+  public void checkStepBoolean() {
+    checkStepBoolean(true);
+    checkStepBoolean(false);
+  }
+
+  private static void checkStepBoolean(boolean initialState) {
+    StepBoolean step = new StepBoolean(initialState);
+    assertTrue(step.get() == initialState); //confirm initialState
+    step.change();
+    assertTrue(step.hasChanged());      //1st change was successful
+    assertTrue(step.get() != initialState); //confirm it is different from initialState
+    step.change();
+    assertTrue(step.get() != initialState); //Still different from initialState
+    assertTrue(step.hasChanged());  //confirm it was changed from initialState value
+  }
+
+  @Test
+  public void checkPrim() {
+    assertEquals(Prim.DOUBLE.scale(), ARRAY_DOUBLE_INDEX_SCALE);
+  }
+
+  @Test
+  public void checkGetNativeBaseOffset_Heap() throws Exception {
+    WritableMemory wmem = WritableMemory.allocate(8); //heap
+    final long offset = ReflectUtil.getNativeBaseOffset(wmem);
+    assertEquals(offset, 0L);
+  }
+
+  @Test
+  public void checkIsByteOrderCompatible() {
+    WritableMemory wmem = WritableMemory.allocate(8);
+    assertTrue(wmem.isByteOrderCompatible(ByteOrder.nativeOrder()));
+  }
+
+  @Test(expectedExceptions = IllegalArgumentException.class)
+  public void checkByteOrderNull() {
+    Util.isNativeByteOrder(null);
+    fail();
+  }
+
+  @Test
+  public void checkIsNativeByteOrder() {
+    assertTrue(BaseStateImpl.isNativeByteOrder(ByteOrder.nativeOrder()));
+    try {
+      BaseStateImpl.isNativeByteOrder(null);
+      fail();
+    } catch (final IllegalArgumentException e) {}
+  }
+
+  @Test
+  public void checkXxHash64() {
+    WritableMemory mem = WritableMemory.allocate(8);
+    long out = mem.xxHash64(mem.getLong(0), 1L);
+    assertTrue(out != 0);
+  }
+
+  @Test
+  public void checkTypeDecode() {
+    for (int i = 0; i < 128; i++) {
+      BaseStateImpl.typeDecode(i);
+    }
+  }
+
+  /********************/
+  @Test
+  public void printlnTest() {
+    println("PRINTING: "+this.getClass().getName());
+  }
+
+  /**
+   * @param s value to print
+   */
+  static void println(String s) {
+    //System.out.println(s); //disable here
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/Buffer2Test.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,463 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.assertFalse;
+import static org.testng.Assert.assertNotNull;
+import static org.testng.Assert.assertTrue;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class Buffer2Test {
+
+  @Test
+  public void testWrapByteBuf() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(0);
+
+    Buffer buffer = Buffer.wrap(bb.asReadOnlyBuffer().order(ByteOrder.nativeOrder()));
+    while (buffer.hasRemaining()) {
+      assertEquals(bb.get(), buffer.getByte());
+    }
+
+    assertEquals(true, buffer.hasArray());
+    assertEquals(true, buffer.hasByteBuffer());
+  }
+
+  @Test
+  public void testWrapDirectBB() {
+    ByteBuffer bb = ByteBuffer.allocateDirect(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(0);
+
+    Buffer buffer = Buffer.wrap(bb);
+    while (buffer.hasRemaining()) {
+      assertEquals(bb.get(), buffer.getByte());
+    }
+
+    assertEquals(false, buffer.hasArray());
+    assertEquals(true, buffer.hasByteBuffer());
+  }
+
+  @Test
+  public void testWrapByteArray() {
+    byte[] byteArray = new byte[64];
+
+    for (byte i = 0; i < 64; i++) {
+      byteArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(byteArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(byteArray[i++], buffer.getByte());
+    }
+
+    buffer.setPosition(0);
+    byte[] copyByteArray = new byte[64];
+    buffer.getByteArray(copyByteArray, 0, 64);
+    assertEquals(byteArray, copyByteArray);
+
+    assertEquals(true, buffer.hasArray());
+    assertEquals(false, buffer.hasByteBuffer());
+  }
+
+  @Test
+  public void testWrapCharArray() {
+    char[] charArray = new char[64];
+
+    for (char i = 0; i < 64; i++) {
+      charArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(charArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(charArray[i++], buffer.getChar());
+    }
+
+    buffer.setPosition(0);
+    char[] copyCharArray = new char[64];
+    buffer.getCharArray(copyCharArray, 0, 64);
+    assertEquals(charArray, copyCharArray);
+  }
+
+  @Test
+  public void testWrapShortArray() {
+    short[] shortArray = new short[64];
+
+    for (short i = 0; i < 64; i++) {
+      shortArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(shortArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(shortArray[i++], buffer.getShort());
+    }
+
+    buffer.setPosition(0);
+    short[] copyShortArray = new short[64];
+    buffer.getShortArray(copyShortArray, 0, 64);
+    assertEquals(shortArray, copyShortArray);
+  }
+
+  @Test
+  public void testWrapIntArray() {
+    int[] intArray = new int[64];
+
+    for (int i = 0; i < 64; i++) {
+      intArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(intArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(intArray[i++], buffer.getInt());
+    }
+
+    buffer.setPosition(0);
+    int[] copyIntArray = new int[64];
+    buffer.getIntArray(copyIntArray, 0, 64);
+    assertEquals(intArray, copyIntArray);
+  }
+
+  @Test
+  public void testWrapLongArray() {
+    long[] longArray = new long[64];
+
+    for (int i = 0; i < 64; i++) {
+      longArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(longArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(longArray[i++], buffer.getLong());
+    }
+
+    buffer.setPosition(0);
+    long[] copyLongArray = new long[64];
+    buffer.getLongArray(copyLongArray, 0, 64);
+    assertEquals(longArray, copyLongArray);
+  }
+
+  @Test
+  public void testWrapFloatArray() {
+    float[] floatArray = new float[64];
+
+    for (int i = 0; i < 64; i++) {
+      floatArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(floatArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(floatArray[i++], buffer.getFloat());
+    }
+
+    buffer.setPosition(0);
+    float[] copyFloatArray = new float[64];
+    buffer.getFloatArray(copyFloatArray, 0, 64);
+    assertEquals(floatArray, copyFloatArray);
+  }
+
+  @Test
+  public void testWrapDoubleArray() {
+    double[] doubleArray = new double[64];
+
+    for (int i = 0; i < 64; i++) {
+      doubleArray[i] = i;
+    }
+
+    Buffer buffer = Memory.wrap(doubleArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(doubleArray[i++], buffer.getDouble());
+    }
+
+    buffer.setPosition(0);
+    double[] copyDoubleArray = new double[64];
+    buffer.getDoubleArray(copyDoubleArray, 0, 64);
+    assertEquals(doubleArray, copyDoubleArray);
+  }
+
+  @Test
+  public void testWrapBooleanArray() {
+    boolean[] booleanArray = new boolean[64];
+
+    for (int i = 0; i < 64; i++) {
+      if ((i % 3) == 0) {
+        booleanArray[i] = true;
+      }
+    }
+
+    Buffer buffer = Memory.wrap(booleanArray).asBuffer();
+    int i = 0;
+    while (buffer.hasRemaining()) {
+      assertEquals(booleanArray[i++], buffer.getBoolean());
+    }
+
+    buffer.setPosition(0);
+    boolean[] copyBooleanArray = new boolean[64];
+    buffer.getBooleanArray(copyBooleanArray, 0, 64);
+    for (int j = 0; j < copyBooleanArray.length; j++) {
+      assertEquals(booleanArray[j], copyBooleanArray[j]);
+    }
+  }
+
+  @Test
+  public void testByteBufferPositionPreservation() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb);
+    while (buffer.hasRemaining()) {
+      assertEquals(bb.get(), buffer.getByte());
+    }
+  }
+
+  @Test
+  public void testGetAndHasRemaining() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb);
+    assertEquals(bb.hasRemaining(), buffer.hasRemaining());
+    assertEquals(bb.remaining(), buffer.getRemaining());
+  }
+
+  @Test
+  public void testGetSetIncResetPosition() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb);
+    assertEquals(bb.position(), buffer.getPosition());
+    assertEquals(30, buffer.setPosition(30).getPosition());
+    assertEquals(40, buffer.incrementPosition(10).getPosition());
+    assertEquals(0, buffer.resetPosition().getPosition());
+  }
+
+  @Test
+  public void testByteBufferSlice() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb.slice().order(ByteOrder.nativeOrder()));
+    while (buffer.hasRemaining()) {
+      assertEquals(bb.get(), buffer.getByte());
+    }
+
+    assertEquals(bb.position(), buffer.getPosition() + 10);
+    assertEquals(30, buffer.setPosition(30).getPosition());
+    assertEquals(40, buffer.incrementPosition(10).getPosition());
+    assertEquals(0, buffer.resetPosition().getPosition());
+  }
+
+  @Test
+  public void testDuplicateAndRegion() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb.slice().order(ByteOrder.nativeOrder())); //slice = 54
+    buffer.setPosition(30);//remaining = 24
+    Buffer dupBuffer = buffer.duplicate(); //all 54
+    Buffer regionBuffer = buffer.region(); //24
+
+    assertEquals(dupBuffer.getStart(), buffer.getStart());
+    assertEquals(regionBuffer.getStart(), buffer.getStart());
+    assertEquals(dupBuffer.getEnd(), buffer.getEnd());
+    assertEquals(regionBuffer.getEnd(), buffer.getRemaining());
+    assertEquals(dupBuffer.getPosition(), buffer.getPosition());
+    assertEquals(regionBuffer.getPosition(), 0);
+    assertEquals(dupBuffer.getCapacity(), buffer.getCapacity());
+    assertEquals(regionBuffer.getCapacity(), buffer.getCapacity() - 30);
+  }
+
+  @Test
+  public void checkRORegions() {
+    int n = 16;
+    int n2 = n / 2;
+    long[] arr = new long[n];
+    for (int i = 0; i < n; i++) { arr[i] = i; }
+    Memory mem = Memory.wrap(arr);
+    Buffer buf = mem.asBuffer();
+    Buffer reg = buf.region(n2 * 8, n2 * 8, buf.getTypeByteOrder()); //top half
+    for (int i = 0; i < n2; i++) {
+      long v = reg.getLong(i * 8);
+      long e = i + n2;
+      assertEquals(v, e);
+    }
+  }
+
+  @Test
+  public void testAsMemory() {
+    ByteBuffer bb = ByteBuffer.allocate(64).order(ByteOrder.nativeOrder());
+
+    Byte b = 0;
+    while (bb.hasRemaining()) {
+      bb.put(b);
+      b++;
+    }
+    bb.position(10);
+
+    Buffer buffer = Buffer.wrap(bb);
+    Memory memory = buffer.asMemory();
+
+    assertEquals(buffer.getCapacity(), memory.getCapacity());
+
+    while(buffer.hasRemaining()){
+      assertEquals(memory.getByte(buffer.getPosition()), buffer.getByte());
+    }
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testROByteBuffer() {
+    byte[] arr = new byte[64];
+    ByteBuffer roBB = ByteBuffer.wrap(arr).asReadOnlyBuffer();
+    Buffer buf = Buffer.wrap(roBB);
+    WritableBuffer wbuf = (WritableBuffer) buf;
+    wbuf.putByte(0, (byte) 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testROByteBuffer2() {
+    byte[] arr = new byte[64];
+    ByteBuffer roBB = ByteBuffer.wrap(arr).asReadOnlyBuffer();
+    Buffer buf = Buffer.wrap(roBB);
+    WritableBuffer wbuf = (WritableBuffer) buf;
+    wbuf.putByteArray(arr, 0, 64);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testIllegalFill() {
+    byte[] arr = new byte[64];
+    ByteBuffer roBB = ByteBuffer.wrap(arr).asReadOnlyBuffer();
+    Buffer buf = Buffer.wrap(roBB);
+    WritableBuffer wbuf = (WritableBuffer) buf;
+    wbuf.fill((byte)0);
+  }
+
+  @Test
+  public void checkWritableWrap() {
+    ByteBuffer bb = ByteBuffer.allocate(16);
+    WritableBuffer buf = WritableBuffer.writableWrap(bb, ByteOrder.nativeOrder(), null);
+    assertNotNull(buf);
+    buf = WritableBuffer.writableWrap(bb, ByteOrder.nativeOrder(), new DefaultMemoryRequestServer());
+    assertNotNull(buf);
+  }
+
+  @Test
+  public void testWritableDuplicate() {
+    WritableMemory wmem = WritableMemory.writableWrap(new byte[1]);
+    WritableBuffer wbuf = wmem.asWritableBuffer();
+    WritableBuffer wbuf2 = wbuf.writableDuplicate();
+    assertEquals(wbuf2.getCapacity(), 1);
+    Buffer buf = wmem.asBuffer();
+    assertEquals(buf.getCapacity(), 1);
+  }
+
+  @Test
+  public void checkIndependence() {
+    int cap = 64;
+    WritableMemory wmem = WritableMemory.allocate(cap);
+    WritableBuffer wbuf1 = wmem.asWritableBuffer();
+    WritableBuffer wbuf2 = wmem.asWritableBuffer();
+    assertFalse(wbuf1 == wbuf2);
+    assertTrue(wbuf1.isSameResource(wbuf2));
+
+    WritableMemory reg1 = wmem.writableRegion(0, cap);
+    WritableMemory reg2 = wmem.writableRegion(0, cap);
+    assertFalse(reg1 == reg2);
+    assertTrue(reg1.isSameResource(reg2));
+
+
+    WritableBuffer wbuf3 = wbuf1.writableRegion();
+    WritableBuffer wbuf4 = wbuf1.writableRegion();
+    assertFalse(wbuf3 == wbuf4);
+    assertTrue(wbuf3.isSameResource(wbuf4));
+  }
+
+  @Test
+  public void printlnTest() {
+    println("PRINTING: "+this.getClass().getName());
+  }
+
+  /**
+   * @param s value to print
+   */
+  static void println(String s) {
+    //System.out.println(s); //disable here
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferBoundaryCheckTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferBoundaryCheckTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferBoundaryCheckTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,238 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class BufferBoundaryCheckTest {
+
+  private final WritableMemory writableMemory = WritableMemory.allocate(8);
+
+  @Test
+  public void testGetBoolean() {
+    writableMemory.getBoolean(7);
+    try {
+      writableMemory.getBoolean(8);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutBoolean() {
+    writableMemory.putBoolean(7, true);
+    try {
+      writableMemory.putBoolean(8, true);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetByte() {
+    writableMemory.getByte(7);
+    try {
+      writableMemory.getByte(8);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutByte() {
+    writableMemory.putByte(7, (byte) 1);
+    try {
+      writableMemory.putByte(8, (byte) 1);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetChar() {
+    writableMemory.getChar(6);
+    try {
+      writableMemory.getChar(7);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutChar() {
+    writableMemory.putChar(6, 'a');
+    try {
+      writableMemory.putChar(7, 'a');
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetShort() {
+    writableMemory.getShort(6);
+    try {
+      writableMemory.getShort(7);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutShort() {
+    writableMemory.putShort(6, (short) 1);
+    try {
+      writableMemory.putShort(7, (short) 1);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetInt() {
+    writableMemory.getInt(4);
+    try {
+      writableMemory.getInt(5);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutInt() {
+    writableMemory.putInt(4, 1);
+    try {
+      writableMemory.putInt(5, 1);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetFloat() {
+    writableMemory.getFloat(4);
+    try {
+      writableMemory.getFloat(5);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutFloat() {
+    writableMemory.putFloat(4, 1f);
+    try {
+      writableMemory.putFloat(5, 1f);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetLong() {
+    writableMemory.getLong(0);
+    try {
+      writableMemory.getLong(1);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutLong() {
+    writableMemory.putLong(0, 1L);
+    try {
+      writableMemory.putLong(1, 1L);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetDouble() {
+    writableMemory.getDouble(0);
+    try {
+      writableMemory.getDouble(1);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testPutDouble() {
+    writableMemory.putDouble(0, 1d);
+    try {
+      writableMemory.putDouble(1, 1d);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetAndAddLong() {
+    writableMemory.getAndAddLong(0, 1L);
+    try {
+      writableMemory.getAndAddLong(1, 1L);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testGetAndSetLong() {
+    writableMemory.getAndSetLong(0, 1L);
+    try {
+      writableMemory.getAndSetLong(1, 1L);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+
+  @Test
+  public void testCompareAndSwapLong() {
+    writableMemory.compareAndSwapLong(0, 0L, 1L);
+    try {
+      writableMemory.compareAndSwapLong(1, 0L, 1L);
+      throw new RuntimeException("Expected AssertionError");
+    } catch (final AssertionError expected) {
+      // ignore
+    }
+  }
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferInvariantsTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferInvariantsTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferInvariantsTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,342 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.testng.Assert.assertEquals;
+import static org.testng.Assert.fail;
+
+import java.nio.ByteBuffer;
+
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("javadoc")
+public class BufferInvariantsTest {
+
+  @Test
+  public void testRegion() {
+    ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+    byteBuffer.limit(7);
+    Buffer buff = Buffer.wrap(byteBuffer); //assuming buff has cap of 8
+    assertEquals(buff.getCapacity(), 10); //wrong should be 8
+    buff.getByte(); //pos moves to 1
+    Buffer copyBuff = buff.region(); //pos: 0, start: 0, end: 6: cap: 7
+    assertEquals(copyBuff.getEnd(), 6);
+    assertEquals(copyBuff.getCapacity(), 6);
+    assertEquals(copyBuff.getStart(), 0);
+    assertEquals(copyBuff.getPosition(), 0);
+
+    buff.setStartPositionEnd(1, 1, 5);
+    buff.getByte();
+    Buffer copyBuff2 = buff.region();
+    assertEquals(copyBuff2.getEnd(), 3);
+    assertEquals(copyBuff2.getCapacity(), 3);
+    assertEquals(copyBuff2.getStart(), 0);
+    assertEquals(copyBuff2.getPosition(), 0);
+  }
+
+  @Test
+  public void testBB() {
+    int n = 25;
+    ByteBuffer bb = ByteBuffer.allocate(n);
+    for (byte i = 0; i < n; i++) { bb.put(i, i); }
+    assertEquals(bb.position(), 0);
+    assertEquals(bb.limit(), n);
+    assertEquals(bb.get(0), 0);
+//    print("Orig : ");
+//    printbb(bb);
+
+    bb.limit(20);
+    bb.position(5);
+    assertEquals(bb.remaining(), 15);
+//    print("Set  : ");
+//    printbb(bb);
+
+    ByteBuffer dup = bb.duplicate();
+    assertEquals(dup.position(), 5);
+    assertEquals(dup.limit(), 20);
+    assertEquals(dup.capacity(), 25);
+//    print("Dup  : ");
+//    printbb(dup);
+
+    ByteBuffer sl = bb.slice();
+    assertEquals(sl.position(), 0);
+    assertEquals(sl.limit(), 15);
+    assertEquals(sl.capacity(), 15);
+//    print("Slice: ");
+//    printbb(sl);
+  }
+
+  @Test
+  public void testBuf() {
+    int n = 25;
+    WritableBuffer buf = WritableMemory.allocate(n).asWritableBuffer();
+    for (byte i = 0; i < n; i++) { buf.putByte(i); }
+    buf.setPosition(0);
+    assertEquals(buf.getPosition(), 0);
+    assertEquals(buf.getEnd(), 25);
+    assertEquals(buf.getCapacity(), 25);
+//    print("Orig  : ");
+//    printbuf(buf);
+
+    buf.setStartPositionEnd(0, 5, 20);
+    assertEquals(buf.getRemaining(), 15);
+    assertEquals(buf.getCapacity(), 25);
+    assertEquals(buf.getByte(), 5);
+    buf.setPosition(5);
+//    print("Set   : ");
+//    printbuf(buf);
+
+    Buffer dup = buf.duplicate();
+    assertEquals(dup.getRemaining(), 15);
+    assertEquals(dup.getCapacity(), 25);
+    assertEquals(dup.getByte(), 5);
+    dup.setPosition(5);
+//    print("Dup   : ");
+//    printbuf(dup);
+
+
+    Buffer reg = buf.region();
+    assertEquals(reg.getPosition(), 0);
+    assertEquals(reg.getEnd(), 15);
+    assertEquals(reg.getRemaining(), 15);
+    assertEquals(reg.getCapacity(), 15);
+    assertEquals(reg.getByte(), 5);
+    reg.setPosition(0);
+//    print("Region: ");
+//    printbuf(reg);
+  }
+
+  @Test
+  public void testBufWrap() {
+    int n = 25;
+    ByteBuffer bb = ByteBuffer.allocate(n);
+    for (byte i = 0; i < n; i++) { bb.put(i, i); }
+
+    bb.position(5);
+    bb.limit(20);
+
+    Buffer buf = Buffer.wrap(bb);
+    assertEquals(buf.getPosition(), 5);
+    assertEquals(buf.getEnd(), 20);
+    assertEquals(buf.getRemaining(), 15);
+    assertEquals(buf.getCapacity(), 25);
+    assertEquals(buf.getByte(), 5);
+    buf.setPosition(5);
+//    print("Buf.wrap: ");
+//    printbuf(buf);
+
+    Buffer reg = buf.region();
+    assertEquals(reg.getPosition(), 0);
+    assertEquals(reg.getEnd(), 15);
+    assertEquals(reg.getRemaining(), 15);
+    assertEquals(reg.getCapacity(), 15);
+    assertEquals(reg.getByte(), 5);
+    reg.setPosition(0);
+//    print("Buf.region: ");
+//    printbuf(reg);
+  }
+
+  @Test
+  public void checkLimitsDirect() throws Exception {
+    try (WritableHandle hand = WritableMemory.allocateDirect(100)) {
+      WritableMemory wmem = hand.getWritable();
+      Buffer buf = wmem.asBuffer();
+      buf.setStartPositionEnd(40, 45, 50);
+      buf.setStartPositionEnd(0, 0, 100);
+      try {
+        buf.setStartPositionEnd(0, 0, 101);
+        fail();
+      } catch (AssertionError e) {
+        //ok
+      }
+    }
+  }
+
+  @Test
+  public void testRegionDirect() {
+    ByteBuffer byteBuffer = ByteBuffer.allocate(10);
+    byteBuffer.limit(7);
+    Buffer buff = Buffer.wrap(byteBuffer); //assuming buff has cap of 8
+    assertEquals(buff.getCapacity(), 10); //wrong should be 8
+    buff.getByte(); //pos moves to 1
+    Buffer copyBuff = buff.region(); //pos: 0, start: 0, end: 6: cap: 7
+    assertEquals(copyBuff.getEnd(), 6);
+    assertEquals(copyBuff.getCapacity(), 6);
+    assertEquals(copyBuff.getStart(), 0);
+    assertEquals(copyBuff.getPosition(), 0);
+
+    buff.setStartPositionEnd(1, 1, 5);
+    buff.getByte();
+    Buffer copyBuff2 = buff.region();
+    assertEquals(copyBuff2.getEnd(), 3);
+    assertEquals(copyBuff2.getCapacity(), 3);
+    assertEquals(copyBuff2.getStart(), 0);
+    assertEquals(copyBuff2.getPosition(), 0);
+  }
+
+  @Test
+  public void testBBDirect() {
+    int n = 25;
+    ByteBuffer bb = ByteBuffer.allocateDirect(n);
+    for (byte i = 0; i < n; i++) { bb.put(i, i); }
+    assertEquals(bb.position(), 0);
+    assertEquals(bb.limit(), n);
+    assertEquals(bb.get(0), 0);
+//    print("Orig : ");
+//    printbb(bb);
+
+    bb.limit(20);
+    bb.position(5);
+    assertEquals(bb.remaining(), 15);
+//    print("Set  : ");
+//    printbb(bb);
+
+    ByteBuffer dup = bb.duplicate();
+    assertEquals(dup.position(), 5);
+    assertEquals(dup.limit(), 20);
+    assertEquals(dup.capacity(), 25);
+//    print("Dup  : ");
+//    printbb(dup);
+
+    ByteBuffer sl = bb.slice();
+    assertEquals(sl.position(), 0);
+    assertEquals(sl.limit(), 15);
+    assertEquals(sl.capacity(), 15);
+//    print("Slice: ");
+//    printbb(sl);
+  }
+
+  @Test
+  public void testBufDirect() throws Exception {
+    int n = 25;
+    try (WritableHandle whand = WritableMemory.allocateDirect(n)) {
+    WritableMemory wmem = whand.getWritable();
+    WritableBuffer buf = wmem.asWritableBuffer();
+    for (byte i = 0; i < n; i++) { buf.putByte(i); }
+    buf.setPosition(0);
+    assertEquals(buf.getPosition(), 0);
+    assertEquals(buf.getEnd(), 25);
+    assertEquals(buf.getCapacity(), 25);
+//    print("Orig  : ");
+//    printbuf(buf);
+
+    buf.setStartPositionEnd(0, 5, 20);
+    assertEquals(buf.getRemaining(), 15);
+    assertEquals(buf.getCapacity(), 25);
+    assertEquals(buf.getByte(), 5);
+    buf.setPosition(5);
+//    print("Set   : ");
+//    printbuf(buf);
+
+    Buffer dup = buf.duplicate();
+    assertEquals(dup.getRemaining(), 15);
+    assertEquals(dup.getCapacity(), 25);
+    assertEquals(dup.getByte(), 5);
+    dup.setPosition(5);
+//    print("Dup   : ");
+//    printbuf(dup);
+
+
+    Buffer reg = buf.region();
+    assertEquals(reg.getPosition(), 0);
+    assertEquals(reg.getEnd(), 15);
+    assertEquals(reg.getRemaining(), 15);
+    assertEquals(reg.getCapacity(), 15);
+    assertEquals(reg.getByte(), 5);
+    reg.setPosition(0);
+//    print("Region: ");
+//    printbuf(reg);
+    }
+  }
+
+  @Test
+  public void testBufWrapDirect() {
+    int n = 25;
+    ByteBuffer bb = ByteBuffer.allocateDirect(n);
+    for (byte i = 0; i < n; i++) { bb.put(i, i); }
+
+    bb.position(5);
+    bb.limit(20);
+
+    Buffer buf = Buffer.wrap(bb);
+    assertEquals(buf.getPosition(), 5);
+    assertEquals(buf.getEnd(), 20);
+    assertEquals(buf.getRemaining(), 15);
+    assertEquals(buf.getCapacity(), 25);
+    assertEquals(buf.getByte(), 5);
+    buf.setPosition(5);
+//    print("Buf.wrap: ");
+//    printbuf(buf);
+
+    Buffer reg = buf.region();
+    assertEquals(reg.getPosition(), 0);
+    assertEquals(reg.getEnd(), 15);
+    assertEquals(reg.getRemaining(), 15);
+    assertEquals(reg.getCapacity(), 15);
+    assertEquals(reg.getByte(), 5);
+    reg.setPosition(0);
+//    print("Buf.region: ");
+//    printbuf(reg);
+  }
+
+
+  static void printbb(ByteBuffer bb) {
+    println("pos: " + bb.position() + ", lim: " + bb.limit() + ", cap: " + bb.capacity());
+    int rem = bb.remaining();
+    int pos = bb.position();
+    int i;
+    for (i = 0; i < (rem-1); i++) {
+      print(bb.get(i+ pos) + ", ");
+    }
+    println(bb.get(i + pos) + "\n");
+  }
+
+  static void printbuf(Buffer buf) {
+    println("pos: " + buf.getPosition() + ", end: " + buf.getEnd() + ", cap: " + buf.getCapacity());
+    long rem = buf.getRemaining();
+    long pos = buf.getPosition();
+    int i;
+    for (i = 0; i < (rem-1); i++) {
+      print(buf.getByte(i+ pos) + ", ");
+    }
+    println(buf.getByte(i + pos) + "\n");
+  }
+
+  /**
+   * @param s value to print
+   */
+  static void println(String s) {
+    //System.out.println(s); //disable here
+  }
+
+  /**
+   * @param s value to print
+   */
+  static void print(String s) {
+    //System.out.print(s); //disable here
+  }
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferReadWriteSafetyTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,176 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import java.nio.ByteBuffer;
+
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class BufferReadWriteSafetyTest {
+
+  // Test various operations with read-only Buffer
+
+  private final WritableBuffer buf = (WritableBuffer) Buffer.wrap(ByteBuffer.allocate(8));
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutByte() {
+    buf.putByte(0, (byte) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutBytePositional() {
+    buf.putByte((byte) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutBoolean() {
+    buf.putBoolean(0, true);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutBooleanPositional() {
+    buf.putBoolean(true);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutShort() {
+    buf.putShort(0, (short) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutShortPositional() {
+    buf.putShort((short) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutChar() {
+    buf.putChar(0, (char) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutCharPositional() {
+    buf.putChar((char) 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutInt() {
+    buf.putInt(0, 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutIntPositional() {
+    buf.putInt(1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutLong() {
+    buf.putLong(0, 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutLongPositional() {
+    buf.putLong(1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutFloat() {
+    buf.putFloat(0, 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutFloatPositional() {
+    buf.putFloat(1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutDouble() {
+    buf.putDouble(0, 1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testPutDoublePositional() {
+    buf.putDouble(1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutByteArray() {
+    buf.putByteArray(new byte[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutBooleanArray() {
+    buf.putBooleanArray(new boolean[] {true}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutShortArray() {
+    buf.putShortArray(new short[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutCharArray() {
+    buf.putCharArray(new char[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutIntArray() {
+    buf.putIntArray(new int[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutLongArray() {
+    buf.putLongArray(new long[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testPutFloatArray() {
+    buf.putFloatArray(new float[] {1}, 0, 1);
+  }
+
+  @Test(expectedExceptions = ReadOnlyException.class)
+  public void testDoubleByteArray() {
+    buf.putDoubleArray(new double[] {1}, 0, 1);
+  }
+
+  // Now, test that various ways to obtain a read-only buffer produce a read-only buffer indeed
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testWritableMemoryAsBuffer() {
+    WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asBuffer();
+    buf1.putInt(1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testWritableBufferRegion() {
+    WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asWritableBuffer().region();
+    buf1.putInt(1);
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void testWritableBufferDuplicate() {
+    WritableBuffer buf1 = (WritableBuffer) WritableMemory.allocate(8).asWritableBuffer().duplicate();
+    buf1.putInt(1);
+  }
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/BufferTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,329 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.testng.Assert.assertEquals;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.List;
+
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.Buffer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+import org.testng.collections.Lists;
+
+@SuppressWarnings("javadoc")
+public class BufferTest {
+
+  @Test
+  public void checkDirectRoundTrip() throws Exception {
+    int n = 1024; //longs
+    try (WritableHandle wh = WritableMemory.allocateDirect(n * 8)) {
+      WritableMemory wmem = wh.getWritable();
+      WritableBuffer wbuf = wmem.asWritableBuffer();
+      for (int i = 0; i < n; i++) {
+        wbuf.putLong(i);
+      }
+      wbuf.resetPosition();
+      for (int i = 0; i < n; i++) {
+        long v = wbuf.getLong();
+        assertEquals(v, i);
+      }
+    }
+  }
+
+  @Test
+  public void checkAutoHeapRoundTrip() {
+    int n = 1024; //longs
+    WritableBuffer wbuf = WritableMemory.allocate(n * 8).asWritableBuffer();
+    for (int i = 0; i < n; i++) {
+      wbuf.putLong(i);
+    }
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      long v = wbuf.getLong();
+      assertEquals(v, i);
+    }
+  }
+
+  @Test
+  public void checkArrayWrap() {
+    int n = 1024; //longs
+    byte[] arr = new byte[n * 8];
+    WritableBuffer wbuf = WritableMemory.writableWrap(arr).asWritableBuffer();
+    for (int i = 0; i < n; i++) {
+      wbuf.putLong(i);
+    }
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      long v = wbuf.getLong();
+      assertEquals(v, i);
+    }
+    Buffer buf = Memory.wrap(arr).asBuffer();
+    buf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      long v = buf.getLong();
+      assertEquals(v, i);
+    }
+    // Check Zero length array wraps
+    Memory mem = Memory.wrap(new byte[0]);
+    Buffer buffZeroLengthArrayWrap = mem.asBuffer();
+    assertEquals(buffZeroLengthArrayWrap.getCapacity(), 0);
+    // check 0 length array wraps
+    List<Buffer> buffersToCheck = Lists.newArrayList();
+    buffersToCheck.add(WritableMemory.allocate(0).asBuffer());
+    buffersToCheck.add(WritableBuffer.writableWrap(ByteBuffer.allocate(0)));
+    buffersToCheck.add(Buffer.wrap(ByteBuffer.allocate(0)));
+    buffersToCheck.add(Memory.wrap(new boolean[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new byte[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new char[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new short[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new int[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new long[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new float[0]).asBuffer());
+    buffersToCheck.add(Memory.wrap(new double[0]).asBuffer());
+    //Check the buffer lengths
+    for (Buffer buffer : buffersToCheck) {
+      assertEquals(buffer.getCapacity(), 0);
+    }
+  }
+
+  @Test
+  public void simpleBBTest() {
+    int n = 1024; //longs
+    byte[] arr = new byte[n * 8];
+    ByteBuffer bb = ByteBuffer.wrap(arr);
+    bb.order(ByteOrder.nativeOrder());
+
+    WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
+    for (int i = 0; i < n; i++) { //write to wbuf
+      wbuf.putLong(i);
+    }
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) { //read from wbuf
+      long v = wbuf.getLong();
+      assertEquals(v, i);
+    }
+    for (int i = 0; i < n; i++) { //read from BB
+      long v = bb.getLong();
+      assertEquals(v, i);
+    }
+  }
+
+  @Test
+  public void checkByteBufHeap() {
+    int n = 1024; //longs
+    byte[] arr = new byte[n * 8];
+    ByteBuffer bb = ByteBuffer.wrap(arr);
+    bb.order(ByteOrder.nativeOrder());
+
+    WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
+    for (int i = 0; i < n; i++) { //write to wbuf
+      wbuf.putLong(i);
+    }
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) { //read from wbuf
+      long v = wbuf.getLong();
+      assertEquals(v, i);
+    }
+    for (int i = 0; i < n; i++) { //read from BB
+      long v = bb.getLong(i * 8);
+      assertEquals(v, i);
+    }
+    Buffer buf1 = Memory.wrap(arr).asBuffer();
+    for (int i = 0; i < n; i++) { //read from wrapped arr
+      long v = buf1.getLong();
+      assertEquals(v, i);
+    }
+    //convert to wbuf to RO
+    Buffer buf = wbuf;
+    buf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      long v = buf.getLong();
+      assertEquals(v, i);
+    }
+  }
+
+  @Test
+  public void checkByteBufDirect() {
+    int n = 1024; //longs
+    ByteBuffer bb = ByteBuffer.allocateDirect(n * 8);
+    bb.order(ByteOrder.nativeOrder());
+
+    WritableBuffer wbuf = WritableBuffer.writableWrap(bb);
+    for (int i = 0; i < n; i++) { //write to wmem
+      wbuf.putLong(i);
+    }
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) { //read from wmem
+      long v = wbuf.getLong();
+      assertEquals(v, i);
+    }
+    for (int i = 0; i < n; i++) { //read from BB
+      long v = bb.getLong(i * 8);
+      assertEquals(v, i);
+    }
+    Buffer buf1 = Buffer.wrap(bb);
+    for (int i = 0; i < n; i++) { //read from wrapped bb RO
+      long v = buf1.getLong();
+      assertEquals(v, i);
+    }
+    //convert to RO
+    Buffer buf = wbuf;
+    buf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      long v = buf.getLong();
+      assertEquals(v, i);
+    }
+  }
+
+  @Test
+  public void checkByteBufBigEndianOrder() {
+    int n = 1024; //longs
+    ByteBuffer bb = ByteBuffer.allocate(n * 8);
+    bb.order(ByteOrder.BIG_ENDIAN);
+    Buffer buf = Buffer.wrap(bb);
+    assertEquals(buf.getTypeByteOrder(), ByteOrder.BIG_ENDIAN);
+  }
+
+  @Test
+  public void checkReadOnlyHeapByteBuffer() {
+    ByteBuffer bb = ByteBuffer.allocate(128);
+    bb.order(ByteOrder.nativeOrder());
+    for (int i = 0; i < 128; i++) { bb.put(i, (byte)i); }
+
+    bb.position(64);
+    ByteBuffer slice = bb.slice().asReadOnlyBuffer();
+    slice.order(ByteOrder.nativeOrder());
+
+    Buffer buf = Buffer.wrap(slice);
+    for (int i = 0; i < 64; i++) {
+      assertEquals(buf.getByte(), 64 + i);
+    }
+    buf.toHexString("slice", 0, slice.capacity());
+    //println(s);
+  }
+
+  @Test
+  public void checkPutGetArraysHeap() {
+    int n = 1024; //longs
+    long[] arr = new long[n];
+    for (int i = 0; i < n; i++) { arr[i] = i; }
+
+    WritableBuffer wbuf = WritableMemory.allocate(n * 8).asWritableBuffer();
+    wbuf.putLongArray(arr, 0, n);
+    long[] arr2 = new long[n];
+    wbuf.resetPosition();
+    wbuf.getLongArray(arr2, 0, n);
+    for (int i = 0; i < n; i++) {
+      assertEquals(arr2[i], i);
+    }
+  }
+
+  @Test
+  public void checkRORegions() {
+    int n = 16;
+    int n2 = n / 2;
+    long[] arr = new long[n];
+    for (int i = 0; i < n; i++) { arr[i] = i; }
+
+    Buffer buf = Memory.wrap(arr).asBuffer();
+    buf.setPosition(n2 * 8);
+    Buffer reg = buf.region();
+    for (int i = 0; i < n2; i++) {
+      long v = reg.getLong();
+      assertEquals(v, i + n2);
+      //println("" + v);
+    }
+  }
+
+  @Test
+  public void checkWRegions() {
+    int n = 16;
+    int n2 = n / 2;
+    long[] arr = new long[n];
+    for (int i = 0; i < n; i++) { arr[i] = i; }
+    WritableBuffer wbuf = WritableMemory.writableWrap(arr).asWritableBuffer();
+    for (int i = 0; i < n; i++) {
+      assertEquals(wbuf.getLong(), i); //write all
+      //println("" + wmem.getLong(i * 8));
+    }
+    //println("");
+    wbuf.setPosition(n2 * 8);
+    WritableBuffer reg = wbuf.writableRegion();
+    for (int i = 0; i < n2; i++) { reg.putLong(i); } //rewrite top half
+    wbuf.resetPosition();
+    for (int i = 0; i < n; i++) {
+      assertEquals(wbuf.getLong(), i % 8);
+      //println("" + wmem.getLong(i * 8));
+    }
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void checkParentUseAfterFree() throws Exception {
+    int bytes = 64 * 8;
+    @SuppressWarnings("resource") //intentionally not using try-with-resources here
+    WritableHandle wh = WritableMemory.allocateDirect(bytes);
+    WritableMemory wmem = wh.getWritable();
+    WritableBuffer wbuf = wmem.asWritableBuffer();
+    wh.close();
+    //with -ea assert: Memory not valid.
+    //with -da sometimes segfaults, sometimes passes!
+    wbuf.getLong();
+  }
+
+  @SuppressWarnings("resource")
+  @Test(expectedExceptions = AssertionError.class)
+  public void checkRegionUseAfterFree() throws Exception {
+    int bytes = 64;
+    WritableHandle wh = WritableMemory.allocateDirect(bytes);
+    Memory wmem = wh.get();
+
+    Buffer reg = wmem.asBuffer().region();
+    wh.close();
+    //with -ea assert: Memory not valid.
+    //with -da sometimes segfaults, sometimes passes!
+    reg.getByte();
+  }
+
+  @Test(expectedExceptions = AssertionError.class)
+  public void checkBaseBufferInvariants() {
+    WritableBuffer wbuf = WritableMemory.allocate(64).asWritableBuffer();
+    wbuf.setStartPositionEnd(1, 0, 2); //out of order
+  }
+
+
+  @Test
+  public void printlnTest() {
+    println("PRINTING: "+this.getClass().getName());
+  }
+
+  /**
+   * @param s String to print
+   */
+  static void println(final String s) {
+    //System.out.println(s);
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/CommonBufferTest.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/CommonBufferTest.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8-tests/src/test/java/org/apache/datasketches/memory/test/CommonBufferTest.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,449 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.datasketches.memory.test;
+
+import static org.testng.Assert.assertEquals;
+
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableMemory;
+import org.testng.annotations.Test;
+
+@SuppressWarnings("javadoc")
+public class CommonBufferTest {
+
+  @Test
+  public void checkSetGet() throws Exception {
+    int memCapacity = 60; //must be at least 60
+    try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
+      WritableMemory mem = wrh.getWritable();
+      WritableBuffer buf = mem.asWritableBuffer();
+      assertEquals(buf.getCapacity(), memCapacity);
+      setGetTests(buf);
+      setGetTests2(buf);
+    }
+  }
+
+  public static void setGetTests(WritableBuffer buf) {
+    buf.putBoolean(true);
+    buf.putBoolean(false);
+    buf.putByte((byte) -1);
+    buf.putByte((byte) 0);
+    buf.putChar('A');
+    buf.putChar('Z');
+    buf.putShort(Short.MAX_VALUE);
+    buf.putShort(Short.MIN_VALUE);
+    buf.putInt(Integer.MAX_VALUE);
+    buf.putInt(Integer.MIN_VALUE);
+    buf.putFloat(Float.MAX_VALUE);
+    buf.putFloat(Float.MIN_VALUE);
+    buf.putLong(Long.MAX_VALUE);
+    buf.putLong(Long.MIN_VALUE);
+    buf.putDouble(Double.MAX_VALUE);
+    buf.putDouble(Double.MIN_VALUE);
+
+    buf.resetPosition();
+
+    assertEquals(buf.getBoolean(buf.getPosition()), true);
+    assertEquals(buf.getBoolean(), true);
+    assertEquals(buf.getBoolean(buf.getPosition()), false);
+    assertEquals(buf.getBoolean(), false);
+    assertEquals(buf.getByte(buf.getPosition()), (byte) -1);
+    assertEquals(buf.getByte(), (byte) -1);
+    assertEquals(buf.getByte(buf.getPosition()), (byte)0);
+    assertEquals(buf.getByte(), (byte)0);
+    assertEquals(buf.getChar(buf.getPosition()), 'A');
+    assertEquals(buf.getChar(), 'A');
+    assertEquals(buf.getChar(buf.getPosition()), 'Z');
+    assertEquals(buf.getChar(), 'Z');
+    assertEquals(buf.getShort(buf.getPosition()), Short.MAX_VALUE);
+    assertEquals(buf.getShort(), Short.MAX_VALUE);
+    assertEquals(buf.getShort(buf.getPosition()), Short.MIN_VALUE);
+    assertEquals(buf.getShort(), Short.MIN_VALUE);
+    assertEquals(buf.getInt(buf.getPosition()), Integer.MAX_VALUE);
+    assertEquals(buf.getInt(), Integer.MAX_VALUE);
+    assertEquals(buf.getInt(buf.getPosition()), Integer.MIN_VALUE);
+    assertEquals(buf.getInt(), Integer.MIN_VALUE);
+    assertEquals(buf.getFloat(buf.getPosition()), Float.MAX_VALUE);
+    assertEquals(buf.getFloat(), Float.MAX_VALUE);
+    assertEquals(buf.getFloat(buf.getPosition()), Float.MIN_VALUE);
+    assertEquals(buf.getFloat(), Float.MIN_VALUE);
+    assertEquals(buf.getLong(buf.getPosition()), Long.MAX_VALUE);
+    assertEquals(buf.getLong(), Long.MAX_VALUE);
+    assertEquals(buf.getLong(buf.getPosition()), Long.MIN_VALUE);
+    assertEquals(buf.getLong(), Long.MIN_VALUE);
+    assertEquals(buf.getDouble(buf.getPosition()), Double.MAX_VALUE);
+    assertEquals(buf.getDouble(), Double.MAX_VALUE);
+    assertEquals(buf.getDouble(buf.getPosition()), Double.MIN_VALUE);
+    assertEquals(buf.getDouble(), Double.MIN_VALUE);
+  }
+
+  public static void setGetTests2(WritableBuffer buf) {
+    buf.putBoolean(0, true);
+    buf.putBoolean(1, false);
+    buf.putByte(2, (byte) -1);
+    buf.putByte(3, (byte) 0);
+    buf.putChar(4,'A');
+    buf.putChar(6,'Z');
+    buf.putShort(8, Short.MAX_VALUE);
+    buf.putShort(10, Short.MIN_VALUE);
+    buf.putInt(12, Integer.MAX_VALUE);
+    buf.putInt(16, Integer.MIN_VALUE);
+    buf.putFloat(20, Float.MAX_VALUE);
+    buf.putFloat(24, Float.MIN_VALUE);
+    buf.putLong(28, Long.MAX_VALUE);
+    buf.putLong(36, Long.MIN_VALUE);
+    buf.putDouble(44, Double.MAX_VALUE);
+    buf.putDouble(52, Double.MIN_VALUE);
+
+    assertEquals(buf.getBoolean(0), true);
+    assertEquals(buf.getBoolean(1), false);
+    assertEquals(buf.getByte(2), (byte) -1);
+    assertEquals(buf.getByte(3), (byte)0);
+    assertEquals(buf.getChar(4), 'A');
+    assertEquals(buf.getChar(6), 'Z');
+    assertEquals(buf.getShort(8), Short.MAX_VALUE);
+    assertEquals(buf.getShort(10), Short.MIN_VALUE);
+    assertEquals(buf.getInt(12), Integer.MAX_VALUE);
+    assertEquals(buf.getInt(16), Integer.MIN_VALUE);
+    assertEquals(buf.getFloat(20), Float.MAX_VALUE);
+    assertEquals(buf.getFloat(24), Float.MIN_VALUE);
+    assertEquals(buf.getLong(28), Long.MAX_VALUE);
+    assertEquals(buf.getLong(36), Long.MIN_VALUE);
+    assertEquals(buf.getDouble(44), Double.MAX_VALUE);
+    assertEquals(buf.getDouble(52), Double.MIN_VALUE);
+  }
+
+  @Test
+  public void checkSetGetArrays() throws Exception {
+    int memCapacity = 32;
+    try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
+      WritableMemory mem = wrh.getWritable();
+      WritableBuffer buf = mem.asWritableBuffer();
+      assertEquals(buf.getCapacity(), memCapacity);
+      setGetArraysTests(buf);
+    }
+  }
+
+  public static void setGetArraysTests(WritableBuffer buf) {
+    int words = 4;
+
+    boolean[] srcArray1 = {true, false, true, false};
+    boolean[] dstArray1 = new boolean[words];
+    buf.resetPosition();
+    buf.fill((byte)127);
+    buf.resetPosition();
+    buf.putBooleanArray(srcArray1, 0, words);
+    buf.resetPosition();
+    buf.getBooleanArray(dstArray1, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray1[i], srcArray1[i]);
+    }
+
+    byte[] srcArray2 = { 1, -2, 3, -4 };
+    byte[] dstArray2 = new byte[4];
+    buf.resetPosition();
+    buf.putByteArray(srcArray2, 0, words);
+    buf.resetPosition();
+    buf.getByteArray(dstArray2, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray2[i], srcArray2[i]);
+    }
+
+    char[] srcArray3 = { 'A', 'B', 'C', 'D' };
+    char[] dstArray3 = new char[words];
+    buf.resetPosition();
+    buf.putCharArray(srcArray3, 0, words);
+    buf.resetPosition();
+    buf.getCharArray(dstArray3, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray3[i], srcArray3[i]);
+    }
+
+    double[] srcArray4 = { 1.0, -2.0, 3.0, -4.0 };
+    double[] dstArray4 = new double[words];
+    buf.resetPosition();
+    buf.putDoubleArray(srcArray4, 0, words);
+    buf.resetPosition();
+    buf.getDoubleArray(dstArray4, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray4[i], srcArray4[i], 0.0);
+    }
+
+    float[] srcArray5 = { (float)1.0, (float)-2.0, (float)3.0, (float)-4.0 };
+    float[] dstArray5 = new float[words];
+    buf.resetPosition();
+    buf.putFloatArray(srcArray5, 0, words);
+    buf.resetPosition();
+    buf.getFloatArray(dstArray5, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray5[i], srcArray5[i], 0.0);
+    }
+
+    int[] srcArray6 = { 1, -2, 3, -4 };
+    int[] dstArray6 = new int[words];
+    buf.resetPosition();
+    buf.putIntArray(srcArray6, 0, words);
+    buf.resetPosition();
+    buf.getIntArray(dstArray6, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray6[i], srcArray6[i]);
+    }
+
+    long[] srcArray7 = { 1, -2, 3, -4 };
+    long[] dstArray7 = new long[words];
+    buf.resetPosition();
+    buf.putLongArray(srcArray7, 0, words);
+    buf.resetPosition();
+    buf.getLongArray(dstArray7, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray7[i], srcArray7[i]);
+    }
+
+    short[] srcArray8 = { 1, -2, 3, -4 };
+    short[] dstArray8 = new short[words];
+    buf.resetPosition();
+    buf.putShortArray(srcArray8, 0, words);
+    buf.resetPosition();
+    buf.getShortArray(dstArray8, 0, words);
+    for (int i=0; i<words; i++) {
+      assertEquals(dstArray8[i], srcArray8[i]);
+    }
+  }
+
+  @Test
+  public void checkSetGetPartialArraysWithOffset() throws Exception {
+    int memCapacity = 32;
+    try (WritableHandle wrh = WritableMemory.allocateDirect(memCapacity)) {
+      WritableMemory mem = wrh.getWritable();
+      WritableBuffer buf = mem.asWritableBuffer();
+      assertEquals(buf.getCapacity(), memCapacity);
+      setGetPartialArraysWithOffsetTests(buf);
+    }
+  }
+
+  public static void setGetPartialArraysWithOffsetTests(WritableBuffer buf) {
+    int items= 4;
+    boolean[] srcArray1 = {true, false, true, false};
+    boolean[] dstArray1 = new boolean[items];
+    buf.resetPosition();
+    buf.putBooleanArray(srcArray1, 2, items/2);
+    buf.resetPosition();
+    buf.getBooleanArray(dstArray1, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray1[i], srcArray1[i]);
+    }
+
+    byte[] srcArray2 = { 1, -2, 3, -4 };
+    byte[] dstArray2 = new byte[items];
+    buf.resetPosition();
+    buf.putByteArray(srcArray2, 2, items/2);
+    buf.resetPosition();
+    buf.getByteArray(dstArray2, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray2[i], srcArray2[i]);
+    }
+
+    char[] srcArray3 = { 'A', 'B', 'C', 'D' };
+    char[] dstArray3 = new char[items];
+    buf.resetPosition();
+    buf.putCharArray(srcArray3, 2, items/2);
+    buf.resetPosition();
+    buf.getCharArray(dstArray3, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray3[i], srcArray3[i]);
+    }
+
+    double[] srcArray4 = { 1.0, -2.0, 3.0, -4.0 };
+    double[] dstArray4 = new double[items];
+    buf.resetPosition();
+    buf.putDoubleArray(srcArray4, 2, items/2);
+    buf.resetPosition();
+    buf.getDoubleArray(dstArray4, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray4[i], srcArray4[i], 0.0);
+    }
+
+    float[] srcArray5 = { (float)1.0, (float)-2.0, (float)3.0, (float)-4.0 };
+    float[] dstArray5 = new float[items];
+    buf.resetPosition();
+    buf.putFloatArray(srcArray5, 2, items/2);
+    buf.resetPosition();
+    buf.getFloatArray(dstArray5, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray5[i], srcArray5[i], 0.0);
+    }
+
+    int[] srcArray6 = { 1, -2, 3, -4 };
+    int[] dstArray6 = new int[items];
+    buf.resetPosition();
+    buf.putIntArray(srcArray6, 2, items/2);
+    buf.resetPosition();
+    buf.getIntArray(dstArray6, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray6[i], srcArray6[i]);
+    }
+
+    long[] srcArray7 = { 1, -2, 3, -4 };
+    long[] dstArray7 = new long[items];
+    buf.resetPosition();
+    buf.putLongArray(srcArray7, 2, items/2);
+    buf.resetPosition();
+    buf.getLongArray(dstArray7, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray7[i], srcArray7[i]);
+    }
+
+    short[] srcArray8 = { 1, -2, 3, -4 };
+    short[] dstArray8 = new short[items];
+    buf.resetPosition();
+    buf.putShortArray(srcArray8, 2, items/2);
+    buf.resetPosition();
+    buf.getShortArray(dstArray8, 2, items/2);
+    for (int i=2; i<items; i++) {
+      assertEquals(dstArray8[i], srcArray8[i]);
+    }
+  }
+
+  @Test
+  public void checkSetClearMemoryRegions() throws Exception {
+    int memCapacity = 64; //must be 64
+    try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
+      WritableMemory mem = wrh1.getWritable();
+      WritableBuffer buf = mem.asWritableBuffer();
+      assertEquals(buf.getCapacity(), memCapacity);
+
+      setClearMemoryRegionsTests(buf); //requires println enabled to visually check
+      buf.resetPosition();
+      for (int i = 0; i < memCapacity; i++) {
+        assertEquals(mem.getByte(i), 0);
+      }
+    }
+  }
+
+  //enable println statements to visually check
+  public static void setClearMemoryRegionsTests(WritableBuffer buf) {
+    int accessCapacity = (int)buf.getCapacity();
+
+  //define regions
+    int reg1Start = 0;
+    int reg1Len = 28;
+    int reg2Start = 28;
+    int reg2Len = 32;
+
+    //set region 1
+    byte b1 = 5;
+    buf.setStartPositionEnd(reg1Start, reg1Start, reg1Len);
+    buf.fill(b1);
+    buf.resetPosition();
+    for (int i=reg1Start; i<(reg1Len+reg1Start); i++) {
+      assertEquals(buf.getByte(), b1);
+    }
+    //println(buf.toHexString("Region1 to 5", reg1Start, reg1Len));
+
+    //set region 2
+    byte b2 = 7;
+    buf.setStartPositionEnd(reg2Start, reg2Start, reg2Start + reg2Len);
+    buf.fill(b2);
+    //println(mem.toHexString("Fill", 0, (int)mem.getCapacity()));
+    buf.resetPosition();
+    for (int i=reg2Start; i<(reg2Start+reg2Len); i++) {
+      assertEquals(buf.getByte(), b2);
+    }
+    //println(buf.toHexString("Region2 to 7", reg2Start, reg2Len));
+
+    //clear region 1
+    byte zeroByte = 0;
+    buf.setStartPositionEnd(reg1Start, reg1Start, reg2Len);
+    buf.resetPosition();
+    buf.clear();
+    buf.resetPosition();
+    for (int i=reg1Start; i<(reg1Start+reg1Len); i++) {
+      assertEquals(buf.getByte(), zeroByte);
+    }
+    //println(buf.toHexString("Region1 cleared", reg1Start, reg1Len));
+
+    //clear region 2
+    buf.setStartPositionEnd(reg2Start, reg2Start, reg2Start + reg2Len);
+    buf.resetPosition();
+    buf.clear();
+    buf.resetPosition();
+    for (int i=reg2Start; i<(reg2Len+reg2Start); i++) {
+      assertEquals(buf.getByte(), zeroByte);
+    }
+    //println(buf.toHexString("Region2 cleared", reg2Start, reg2Len));
+
+    //set all to ones
+    buf.setStartPositionEnd(reg1Start, reg1Start, accessCapacity);
+    byte b4 = 127;
+    buf.resetPosition();
+    buf.fill(b4);
+    buf.resetPosition();
+    for (int i=0; i<accessCapacity; i++) {
+      assertEquals(buf.getByte(), b4);
+    }
+    //println(buf.toHexString("Region1 + Region2 all ones", 0, accessCapacity));
+
+    //clear all
+    buf.resetPosition();
+    buf.clear();
+    buf.resetPosition();
+    for (int i=0; i<accessCapacity; i++) {
+      assertEquals(buf.getByte(), zeroByte);
+    }
+    //println(buf.toHexString("Region1 + Region2 cleared", 0, accessCapacity));
+  }
+
+  @Test
+  public void checkToHexStringAllMem() throws Exception {
+    int memCapacity = 48; //must be 48
+    try (WritableHandle wrh1 = WritableMemory.allocateDirect(memCapacity)) {
+      WritableMemory mem = wrh1.getWritable();
+      WritableBuffer buf = mem.asWritableBuffer();
+      assertEquals(buf.getCapacity(), memCapacity);
+      toHexStringAllMemTests(buf); //requires println enabled to visually check
+    }
+  }
+
+  //enable println to visually check
+  public static void toHexStringAllMemTests(WritableBuffer buf) {
+    int memCapacity = (int)buf.getCapacity();
+
+    for (int i=0; i<memCapacity; i++) {
+      buf.putByte((byte)i);
+    }
+
+    //println(buf.toHexString("Check toHexString(0, 48) to integers", 0, memCapacity));
+    //println(buf.toHexString("Check toHexString(8, 40)", 8, 40));
+  }
+
+  @Test
+  public void printlnTest() {
+    println("PRINTING: "+this.getClass().getName());
+  }
+
+  /**
+   * @param s value to print
+   */
+  static void println(String s) {
+    //System.out.println(s); //disable here
+  }
+
+}



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org