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 [7/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/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/DefaultMemoryRequestServer.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,92 @@
+/*
+ * 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;
+
+/**
+ * This is a simple implementation of the MemoryRequestServer that creates space on the Java heap
+ * for the requesting application. This capability is only available for direct, off-heap
+ * allocated memory.
+ *
+ * <p>Using this default implementation could be something like the following:
+ *
+ * <blockquote><pre>
+ * class OffHeap {
+ *   WritableMemory mem;
+ *   MemoryRequestServer memReqSvr = null;
+ *
+ *   void add(Object something) {
+ *
+ *     if (outOfSpace) { // determine if out-of-space
+ *       long spaceNeeded = ...
+ *
+ *       //Acquire the MemoryRequestServer from the direct Memory the first time.
+ *       //Once acquired, this can be reused if more memory is needed later.
+ *       //This is required for the default implementation because it returns memory on heap
+ *       // and on-heap memory does not carry a reference to the MemoryRequestServer.
+ *       memReqSvr = (memReqSvr == null) ? mem.getMemoryRequestServer() : memReqSvr;
+ *
+ *       //Request bigger memory
+ *       WritableMemory newMem = memReqSvr.request(mem, spaceNeeded);
+ *
+ *       //Copy your data from the current memory to the new one and resize
+ *       moveAndResize(mem, newMem);
+ *
+ *       //You are done with the old memory, so request close.
+ *       //Note that it is up to the owner of the WritableHandle whether or not to
+ *       // actually close the resource.
+ *       memReqSvr.requestClose(mem, newMem);
+ *
+ *       mem = newMem; //update your reference to memory
+ *     }
+ *
+ *     //continue with the add process
+ *   }
+ * }
+ * </pre></blockquote>
+ *
+ *
+ * @author Lee Rhodes
+ */
+public final class DefaultMemoryRequestServer implements MemoryRequestServer {
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>By default this allocates new memory requests on the Java heap.
+   */
+  @Override
+  public WritableMemory request(final WritableMemory currentWritableMemory, final long capacityBytes) {
+    final WritableMemory wmem = WritableMemory.allocate((int)capacityBytes, currentWritableMemory.getTypeByteOrder());
+    return wmem;
+  }
+
+  /**
+   * {@inheritDoc}
+   *
+   * <p>This method does nothing in this default implementation because it is application specific.
+   * This method must be overridden to explicitly close if desired.
+   * Otherwise, the AutoCloseable will eventually close the resource.
+   */
+  @Override
+  public void requestClose(final WritableMemory memToRelease, final WritableMemory newMemory) {
+    //do nothing
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Handle.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,59 @@
+/*
+ * 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;
+
+/**
+ * A handle for read-only Memory resource.
+ *
+ * <p>The purpose of a Handle is to
+ * <ul><li>Provide a <i>strong reference</i> to an external <i>resource</i>.</li>
+ * <li>Extend <i>AutoCloseable</i>, which provides a means to close the resource.</li>
+ * <li>Provide other capabilites unique to a particular resource.</li>
+ * </ul>
+ *
+ * <p>Maintaining strong references to external resources is critical to avoid accidental
+ * <i>use-after-free</i> scenarios, where the Garbage Collector will automatically close an external
+ * resource if there are no remaining strong references to it. One very common mistake, is to allow
+ * a newly created Handle to fall out-of-scope from the block where it was created, such as from a
+ * try-with-resources statement. The Garbage Collector will eventually close the Handle referent
+ * resource.</p>
+ *
+ * <p>Another <i>use-after-free</i> scenario is where a thread or agent, with access to the
+ * Handle, prematurely closes a resource, when another part of the program is still using that
+ * same resource. Avoiding this scenario requires careful planning and design.</p>
+ *
+ * <p>The design philosophy here is that whatever process created the external resource has the
+ * responsibility to <i>close()</i> that resource when it is no longer needed.  This responsibility
+ * can be delegated, by passing the appropriate Handle to the delegatee. In principle, however, at
+ * any one time there should be only one agent holding the Handle and responsible for closing the
+ * resource.</p>
+ *
+ * @author Lee Rhodes
+ * @author Roman Leventov
+ */
+public interface Handle extends AutoCloseable {
+
+  /**
+   * Gets a Memory
+   * @return a Memory
+   */
+  Memory get();
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Map.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * Read only interface for a memory mapped file
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ * @author Praveenkumar Venkatesan
+ */
+public interface Map extends AutoCloseable {
+
+  /**
+   * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#load--">
+   * java/nio/MappedByteBuffer.load</a>
+   */
+  void load();
+
+  /**
+   * @return true if loaded
+   *
+   * @see <a href=
+   * "https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#isLoaded--"> java
+   * /nio/MappedByteBuffer.isLoaded</a>
+   */
+  boolean isLoaded();
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MapHandle.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * A Handle for a memory-mapped, read-only file resource. This
+ * joins a Read-only Handle with an AutoCloseable Map resource.
+ * Please read Javadocs for {@link Handle}.
+ *
+ * @author Lee Rhodes
+ * @author Roman Leventov
+ */
+public interface MapHandle extends Map, Handle { }

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Memory.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,489 @@
+/*
+ * 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;
+
+import static org.apache.datasketches.memory.internal.Util.negativeCheck;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.nio.channels.WritableByteChannel;
+import java.util.Objects;
+
+import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
+import org.apache.datasketches.memory.internal.Prim;
+import org.apache.datasketches.memory.internal.UnsafeUtil;
+
+/**
+ * Defines the read-only API for offset access to a resource.
+ *
+ * @author Lee Rhodes
+ */
+public interface Memory extends BaseState {
+
+  //BYTE BUFFER
+
+  /**
+   * Accesses the given <i>ByteBuffer</i> for read-only operations. The returned <i>Memory</i> object has
+   * the same byte order, as the given <i>ByteBuffer</i>.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null and with capacity &ge; 0.
+   * @return a new <i>Memory</i> for read-only operations on the given <i>ByteBuffer</i>.
+   */
+  static Memory wrap(ByteBuffer byteBuffer) {
+    return wrap(byteBuffer, byteBuffer.order());
+  }
+
+  /**
+   * Accesses the given <i>ByteBuffer</i> for read-only operations. The returned <i>Memory</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future reads and writes.
+   * @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null and with capacity &ge; 0.
+   * @param byteOrder the byte order to be used.  It must be non-null.
+   * @return a new <i>Memory</i> for read-only operations on the given <i>ByteBuffer</i>.
+   */
+  static Memory wrap(ByteBuffer byteBuffer, ByteOrder byteOrder) {
+    Objects.requireNonNull(byteBuffer, "byteBuffer must not be null");
+    Objects.requireNonNull(byteOrder, "byteOrder must not be null");
+    negativeCheck(byteBuffer.capacity(), "byteBuffer");
+    return BaseWritableMemoryImpl.wrapByteBuffer(byteBuffer, true, byteOrder, null);
+  }
+
+  //MAP
+  /**
+   * Maps the entire given file into native-ordered <i>Memory</i> for read operations
+   * Calling this method is equivalent to calling
+   * {@link #map(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
+   * @param file the given file to map. It must be non-null, length &ge; 0, and readable.
+   * @return <i>MapHandle</i> for managing the mapped memory.
+   * Please read Javadocs for {@link Handle}.
+   */
+  static MapHandle map(File file) {
+    return map(file, 0, file.length(), ByteOrder.nativeOrder());
+  }
+
+  /**
+   * Maps the specified portion of the given file into <i>Memory</i> for read operations.
+   * @param file the given file to map. It must be non-null and readable.
+   * @param fileOffsetBytes the position in the given file in bytes. It must not be negative.
+   * @param capacityBytes the size of the mapped memory. It must not be negative.
+   * @param byteOrder the byte order to be used for the mapped memory. It must be non-null.
+   * @return <i>MapHandle</i> for managing the mapped memory.
+   * Please read Javadocs for {@link Handle}.
+   */
+  static MapHandle map(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
+    Objects.requireNonNull(file, "file must be non-null.");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
+    if (!file.canRead()) { throw new IllegalArgumentException("file must be readable."); }
+    negativeCheck(fileOffsetBytes, "fileOffsetBytes");
+    negativeCheck(capacityBytes, "capacityBytes");
+    return (MapHandle) BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, true, byteOrder);
+  }
+
+  //REGIONS
+  /**
+   * A region is a read-only view of this object.
+   * <ul>
+   * <li>Returned object's origin = this object's origin + offsetBytes</li>
+   * <li>Returned object's capacity = capacityBytes</li>
+   * </ul>
+   * @param offsetBytes the starting offset with respect to the origin of this <i>Memory</i>. It must be &ge; 0.
+   * @param capacityBytes the capacity of the region in bytes. It must be &ge; 0.
+   * @return a new <i>Memory</i> representing the defined region based on the given
+   * offsetBytes and capacityBytes.
+   */
+  default Memory region(long offsetBytes, long capacityBytes) {
+    return region(offsetBytes, capacityBytes, ByteOrder.nativeOrder());
+  }
+
+  /**
+   * A region is a read-only view of this object.
+   * <ul>
+   * <li>Returned object's origin = this object's origin + <i>offsetBytes</i></li>
+   * <li>Returned object's capacity = <i>capacityBytes</i></li>
+   * <li>Returned object's byte order = <i>byteOrder</i></li>
+   * </ul>
+   * @param offsetBytes the starting offset with respect to the origin of this Memory. It must be &ge; 0.
+   * @param capacityBytes the capacity of the region in bytes. It must be &ge; 0.
+   * @param byteOrder the given byte order. It must be non-null.
+   * @return a new <i>Memory</i> representing the defined region based on the given
+   * offsetBytes, capacityBytes and byteOrder.
+   */
+  Memory region(long offsetBytes, long capacityBytes, ByteOrder byteOrder);
+
+  //AS BUFFER
+  /**
+   * Returns a new <i>Buffer</i> view of this object.
+   * <ul>
+   * <li>Returned object's origin = this object's origin</li>
+   * <li>Returned object's <i>start</i> = 0</li>
+   * <li>Returned object's <i>position</i> = 0</li>
+   * <li>Returned object's <i>end</i> = this object's capacity</li>
+   * <li>Returned object's <i>capacity</i> = this object's capacity</li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
+   * </ul>
+   * @return a new <i>Buffer</i>
+   */
+  default Buffer asBuffer() {
+    return asBuffer(ByteOrder.nativeOrder());
+  }
+
+  /**
+   * Returns a new <i>Buffer</i> view of this object, with the given
+   * byte order.
+   * <ul>
+   * <li>Returned object's origin = this object's origin</li>
+   * <li>Returned object's <i>start</i> = 0</li>
+   * <li>Returned object's <i>position</i> = 0</li>
+   * <li>Returned object's <i>end</i> = this object's capacity</li>
+   * <li>Returned object's <i>capacity</i> = this object's capacity</li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable</li>
+   * </ul>
+   * @param byteOrder the given byte order
+   * @return a new <i>Buffer</i> with the given byteOrder.
+   */
+  Buffer asBuffer(ByteOrder byteOrder);
+
+  //ACCESS PRIMITIVE HEAP ARRAYS for readOnly
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(byte[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    return wrap(array, 0, array.length, ByteOrder.nativeOrder());
+  }
+
+  /**
+   * Wraps the given primitive array for read operations with the given byte order.
+   * @param array the given primitive array.
+   * @param byteOrder the byte order to be used
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(byte[] array, ByteOrder byteOrder) {
+    return wrap(array, 0, array.length, byteOrder);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations with the given byte order.
+   * @param array the given primitive array.
+   * @param offsetBytes the byte offset into the given array
+   * @param lengthBytes the number of bytes to include from the given array
+   * @param byteOrder the byte order to be used
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder) {
+    Objects.requireNonNull(array, "array must be non-null");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    negativeCheck(offsetBytes, "offsetBytes");
+    negativeCheck(lengthBytes, "lengthBytes");
+    UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(boolean[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.BOOLEAN.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(char[] array) {
+    Objects.requireNonNull(array, "array must be non-null");
+    final long lengthBytes = array.length << Prim.CHAR.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(short[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.SHORT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(int[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.INT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(long[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.LONG.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(float[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.FLOAT.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  /**
+   * Wraps the given primitive array for read operations assuming native byte order.
+   * @param array the given primitive array.
+   * @return a new <i>Memory</i> for read operations
+   */
+  static Memory wrap(double[] array) {
+    Objects.requireNonNull(array, "arr must be non-null");
+    final long lengthBytes = array.length << Prim.DOUBLE.shift();
+    return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, true, ByteOrder.nativeOrder(), null);
+  }
+
+  //PRIMITIVE getX() and getXArray()
+  /**
+   * Gets the boolean value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the boolean at the given offset
+   */
+  boolean getBoolean(long offsetBytes);
+
+  /**
+   * Gets the boolean array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetBooleans offset in array units
+   * @param lengthBooleans number of array units to transfer
+   */
+  void getBooleanArray(long offsetBytes, boolean[] dstArray, int dstOffsetBooleans, int lengthBooleans);
+
+  /**
+   * Gets the byte value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the byte at the given offset
+   */
+  byte getByte(long offsetBytes);
+
+  /**
+   * Gets the byte array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetBytes offset in array units
+   * @param lengthBytes number of array units to transfer
+   */
+  void getByteArray(long offsetBytes, byte[] dstArray, int dstOffsetBytes, int lengthBytes);
+
+  /**
+   * Gets the char value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the char at the given offset
+   */
+  char getChar(long offsetBytes);
+
+  /**
+   * Gets the char array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetChars offset in array units
+   * @param lengthChars number of array units to transfer
+   */
+  void getCharArray(long offsetBytes, char[] dstArray, int dstOffsetChars, int lengthChars);
+
+  /**
+   * Gets UTF-8 encoded bytes from this Memory, starting at offsetBytes to a length of
+   * utf8LengthBytes, decodes them into characters and appends them to the given Appendable.
+   * This is specifically designed to reduce the production of intermediate objects (garbage),
+   * thus significantly reducing pressure on the JVM Garbage Collector.
+   * @param offsetBytes offset bytes relative to the Memory start
+   * @param utf8LengthBytes the number of encoded UTF-8 bytes to decode. It is assumed that the
+   * caller has the correct number of utf8 bytes required to decode the number of characters
+   * to be appended to dst. Characters outside the ASCII range can require 2, 3 or 4 bytes per
+   * character to decode.
+   * @param dst the destination Appendable to append the decoded characters to.
+   * @return the number of characters decoded
+   * @throws IOException if dst.append() throws IOException
+   * @throws Utf8CodingException in case of malformed or illegal UTF-8 input
+   */
+  int getCharsFromUtf8(long offsetBytes, int utf8LengthBytes, Appendable dst)
+      throws IOException, Utf8CodingException;
+
+  /**
+   * Gets UTF-8 encoded bytes from this Memory, starting at offsetBytes to a length of
+   * utf8LengthBytes, decodes them into characters and appends them to the given StringBuilder.
+   * This method does *not* reset the length of the destination StringBuilder before appending
+   * characters to it.
+   * This is specifically designed to reduce the production of intermediate objects (garbage),
+   * thus significantly reducing pressure on the JVM Garbage Collector.
+   * @param offsetBytes offset bytes relative to the Memory start
+   * @param utf8LengthBytes the number of encoded UTF-8 bytes to decode. It is assumed that the
+   * caller has the correct number of utf8 bytes required to decode the number of characters
+   * to be appended to dst. Characters outside the ASCII range can require 2, 3 or 4 bytes per
+   * character to decode.
+   * @param dst the destination StringBuilder to append decoded characters to.
+   * @return the number of characters decoded.
+   * @throws Utf8CodingException in case of malformed or illegal UTF-8 input
+   */
+  int getCharsFromUtf8(long offsetBytes, int utf8LengthBytes, StringBuilder dst)
+      throws Utf8CodingException;
+
+  /**
+   * Gets the double value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the double at the given offset
+   */
+  double getDouble(long offsetBytes);
+
+  /**
+   * Gets the double array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetDoubles offset in array units
+   * @param lengthDoubles number of array units to transfer
+   */
+  void getDoubleArray(long offsetBytes, double[] dstArray, int dstOffsetDoubles, int lengthDoubles);
+
+  /**
+   * Gets the float value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the float at the given offset
+   */
+  float getFloat(long offsetBytes);
+
+  /**
+   * Gets the float array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetFloats offset in array units
+   * @param lengthFloats number of array units to transfer
+   */
+  void getFloatArray(long offsetBytes, float[] dstArray, int dstOffsetFloats, int lengthFloats);
+
+  /**
+   * Gets the int value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the int at the given offset
+   */
+  int getInt(long offsetBytes);
+
+  /**
+   * Gets the int array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetInts offset in array units
+   * @param lengthInts number of array units to transfer
+   */
+  void getIntArray(long offsetBytes, int[] dstArray, int dstOffsetInts, int lengthInts);
+
+  /**
+   * Gets the long value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the long at the given offset
+   */
+  long getLong(long offsetBytes);
+
+  /**
+   * Gets the long array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetLongs offset in array units
+   * @param lengthLongs number of array units to transfer
+   */
+  void getLongArray(long offsetBytes, long[] dstArray, int dstOffsetLongs, int lengthLongs);
+
+  /**
+   * Gets the short value at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @return the short at the given offset
+   */
+  short getShort(long offsetBytes);
+
+  /**
+   * Gets the short array at the given offset
+   * @param offsetBytes offset bytes relative to this Memory start
+   * @param dstArray The preallocated destination array.
+   * @param dstOffsetShorts offset in array units
+   * @param lengthShorts number of array units to transfer
+   */
+  void getShortArray(long offsetBytes, short[] dstArray, int dstOffsetShorts, int lengthShorts);
+
+  //SPECIAL PRIMITIVE READ METHODS: compareTo, copyTo, writeTo
+  /**
+   * Compares the bytes of this Memory to <i>that</i> Memory.
+   * Returns <i>(this &lt; that) ? (some negative value) : (this &gt; that) ? (some positive value)
+   * : 0;</i>.
+   * If all bytes are equal up to the shorter of the two lengths, the shorter length is considered
+   * to be less than the other.
+   * @param thisOffsetBytes the starting offset for <i>this Memory</i>
+   * @param thisLengthBytes the length of the region to compare from <i>this Memory</i>
+   * @param that the other Memory to compare with
+   * @param thatOffsetBytes the starting offset for <i>that Memory</i>
+   * @param thatLengthBytes the length of the region to compare from <i>that Memory</i>
+   * @return <i>(this &lt; that) ? (some negative value) : (this &gt; that) ? (some positive value)
+   * : 0;</i>
+   */
+  int compareTo(long thisOffsetBytes, long thisLengthBytes, Memory that,
+      long thatOffsetBytes, long thatLengthBytes);
+
+  /**
+   * Copies bytes from a source range of this Memory to a destination range of the given Memory
+   * with the same semantics when copying between overlapping ranges of bytes as method
+   * {@link java.lang.System#arraycopy(Object, int, Object, int, int)} has. However, if the source
+   * and the destination ranges are exactly the same, this method throws {@link
+   * IllegalArgumentException}, because it should never be needed in real-world scenarios and
+   * therefore indicates a bug.
+   * @param srcOffsetBytes the source offset for this Memory
+   * @param destination the destination Memory, which may not be Read-Only.
+   * @param dstOffsetBytes the destination offset
+   * @param lengthBytes the number of bytes to copy
+   */
+  void copyTo(long srcOffsetBytes, WritableMemory destination, long dstOffsetBytes, long lengthBytes);
+
+  /**
+   * Writes bytes from a source range of this Memory to the given {@code WritableByteChannel}.
+   * @param offsetBytes the source offset for this Memory
+   * @param lengthBytes the number of bytes to copy
+   * @param out the destination WritableByteChannel
+   * @throws IOException may occur while writing to the WritableByteChannel
+   */
+  void writeTo(long offsetBytes, long lengthBytes, WritableByteChannel out)
+      throws IOException;
+
+}
+
+

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryCloseException.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,49 @@
+/*
+ * 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;
+
+/**
+ * Specific RuntimeException for the AutoCloseable.close() method.
+ *
+ * @author Lee Rhodes
+ *
+ */
+public class MemoryCloseException extends MemoryException {
+  private static final long serialVersionUID = 2L;
+
+  /**
+   * The associated resource failed to close.
+   */
+  public MemoryCloseException() {
+    super("The associated resource failed to close.");
+  }
+
+  /**
+   * The associated resource failed to close, with comment
+   *
+   * @param resource the named resource that failed to close, plus other comments.
+   */
+  public MemoryCloseException(final String resource) {
+    super("The associated resource, " + resource + ", failed to close");
+  }
+
+}
+
+

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryException.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryException.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryException.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,42 @@
+/*
+ * 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;
+
+/**
+ * Specific RuntimeExceptions for the datasketches-memory component.
+ *
+ * @author Lee Rhodes
+ *
+ */
+public class MemoryException extends RuntimeException {
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * Constructs a new runtime exception with the specified detail message. The cause is not
+   * initialized, and may subsequently be initialized by a call to
+   * Throwable.initCause(java.lang.Throwable).
+   *
+   * @param message the detail message. The detail message is saved for later retrieval by the
+   * Throwable.getMessage() method.
+   */
+  public MemoryException(final String message) {
+    super(message);
+  }
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MemoryRequestServer.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,50 @@
+/*
+ * 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;
+
+/**
+ * The MemoryRequestServer is a callback interface to provide a means for direct (off-heap), heap and ByteBuffer
+ * backed resources to request more memory.
+ *
+ * @author Lee Rhodes
+ */
+public interface MemoryRequestServer {
+
+  /**
+   * Request new WritableMemory with the given capacity. The current Writable Memory will be used to
+   * determine the byte order of the returned WritableMemory and other checks.
+   * @param currentWritableMemory the current writableMemory of the client. It must be non-null.
+   * @param capacityBytes The capacity being requested. It must be &ge; 0.
+   *
+   * @return new WritableMemory with the given capacity.
+   */
+  WritableMemory request(WritableMemory currentWritableMemory, long capacityBytes);
+
+  /**
+   * Request close the AutoCloseable resource. This only applies to resources allocated using
+   * WritableMemory.allocateDirect(...).
+   * This may be ignored depending on the application implementation.
+   * @param memToClose the relevant WritbleMemory to be considered for closing. It must be non-null.
+   * @param newMemory the newly allocated WritableMemory. It must be non-null.
+   * This is returned from the client to facilitate tracking for the convenience of the resource owner.
+   */
+  void requestClose(final WritableMemory memToClose, WritableMemory newMemory);
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/MurmurHash3v2.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,360 @@
+/*
+ * 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;
+
+import static java.nio.charset.StandardCharsets.UTF_8;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
+
+/**
+ * <p>The MurmurHash3 is a fast, non-cryptographic, 128-bit hash function that has
+ * excellent avalanche and 2-way bit independence properties.</p>
+ *
+ * <p>Austin Appleby's C++
+ * <a href="https://github.com/aappleby/smhasher/blob/master/src/MurmurHash3.cpp">
+ * MurmurHash3_x64_128(...), final revision 150</a>,
+ * which is in the Public Domain, was the inspiration for this implementation in Java.</p>
+ *
+ * <p>This implementation of the MurmurHash3 allows hashing of a block of on-heap Memory defined by an offset
+ * and length. The calling API also allows the user to supply the small output array of two longs,
+ * so that the entire hash function is static and free of object allocations.</p>
+ *
+ * <p>This implementation produces exactly the same hash result as the
+ * MurmurHash3 function in datasketches-java given compatible inputs.</p>
+ *
+ * @author Lee Rhodes
+ */
+public final class MurmurHash3v2 {
+  private static final long C1 = 0x87c37b91114253d5L;
+  private static final long C2 = 0x4cf5ad432745937fL;
+
+  //Provided for backward compatibility
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Provided for compatibility with older version of MurmurHash3,
+   * but empty or null input now throws IllegalArgumentException.
+   * @param in long array
+   * @param seed A long valued seed.
+   * @return the hash
+   */
+  public static long[] hash(final long[] in, final long seed) {
+    if ((in == null) || (in.length == 0)) {
+      throw new IllegalArgumentException("Input in is empty or null.");
+    }
+    return hash(Memory.wrap(in), 0L, in.length << 3, seed, new long[2]);
+  }
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Provided for compatibility with older version of MurmurHash3,
+   * but empty or null input now throws IllegalArgumentException.
+   * @param in int array
+   * @param seed A long valued seed.
+   * @return the hash
+   */
+  public static long[] hash(final int[] in, final long seed) {
+    if ((in == null) || (in.length == 0)) {
+      throw new IllegalArgumentException("Input in is empty or null.");
+    }
+    return hash(Memory.wrap(in), 0L, in.length << 2, seed, new long[2]);
+  }
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Provided for compatibility with older version of MurmurHash3,
+   * but empty or null input now throws IllegalArgumentException.
+   * @param in char array
+   * @param seed A long valued seed.
+   * @return the hash
+   */
+  public static long[] hash(final char[] in, final long seed) {
+    if ((in == null) || (in.length == 0)) {
+      throw new IllegalArgumentException("Input in is empty or null.");
+    }
+    return hash(Memory.wrap(in), 0L, in.length << 1, seed, new long[2]);
+  }
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Provided for compatibility with older version of MurmurHash3,
+   * but empty or null input now throws IllegalArgumentException.
+   * @param in byte array
+   * @param seed A long valued seed.
+   * @return the hash
+   */
+  public static long[] hash(final byte[] in, final long seed) {
+    if ((in == null) || (in.length == 0)) {
+      throw new IllegalArgumentException("Input in is empty or null.");
+    }
+    return hash(Memory.wrap(in), 0L, in.length, seed, new long[2]);
+  }
+
+  //Single primitive inputs
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Note the entropy of the resulting hash cannot be more than 64 bits.
+   * @param in a long
+   * @param seed A long valued seed.
+   * @param hashOut A long array of size 2
+   * @return the hash
+   */
+  public static long[] hash(final long in, final long seed, final long[] hashOut) {
+    final long h1 = seed ^ mixK1(in);
+    final long h2 = seed;
+    return finalMix128(h1, h2, 8, hashOut);
+  }
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * Note the entropy of the resulting hash cannot be more than 64 bits.
+   * @param in a double
+   * @param seed A long valued seed.
+   * @param hashOut A long array of size 2
+   * @return the hash
+   */
+  public static long[] hash(final double in, final long seed, final long[] hashOut) {
+    final double d = (in == 0.0) ? 0.0 : in;    // canonicalize -0.0, 0.0
+    final long k1 = Double.doubleToLongBits(d); // canonicalize all NaN forms
+    final long h1 = seed ^ mixK1(k1);
+    final long h2 = seed;
+    return finalMix128(h1, h2, 8, hashOut);
+  }
+
+  /**
+   * Returns a 128-bit hash of the input.
+   * An empty or null input throws IllegalArgumentException.
+   * @param in a String
+   * @param seed A long valued seed.
+   * @param hashOut A long array of size 2
+   * @return the hash
+   */
+  public static long[] hash(final String in, final long seed, final long[] hashOut) {
+    if ((in == null) || (in.length() == 0)) {
+      throw new IllegalArgumentException("Input in is empty or null.");
+    }
+    final byte[] byteArr = in.getBytes(UTF_8);
+    return hash(Memory.wrap(byteArr), 0L, byteArr.length, seed, hashOut);
+  }
+
+  //The main API call
+
+  /**
+   * Returns a 128-bit hash of the input as a long array of size 2.
+   *
+   * @param mem The input on-heap Memory. Must be non-null and non-empty,
+   * otherwise throws IllegalArgumentException.
+   * @param offsetBytes the starting point within Memory.
+   * @param lengthBytes the total number of bytes to be hashed.
+   * @param seed A long valued seed.
+   * @param hashOut the size 2 long array for the resulting 128-bit hash
+   * @return the hash.
+   */
+  @SuppressWarnings("restriction")
+  public static long[] hash(final Memory mem, final long offsetBytes, final long lengthBytes,
+      final long seed, final long[] hashOut) {
+    if ((mem == null) || (mem.getCapacity() == 0L)) {
+      throw new IllegalArgumentException("Input mem is empty or null.");
+    }
+    final Object uObj = ((WritableMemory) mem).getArray();
+    if (uObj == null) {
+      throw new IllegalArgumentException("The backing resource of input mem is not on-heap.");
+    }
+    long cumOff = mem.getCumulativeOffset() + offsetBytes;
+
+    long h1 = seed;
+    long h2 = seed;
+    long rem = lengthBytes;
+
+    // Process the 128-bit blocks (the body) into the hash
+    while (rem >= 16L) {
+      final long k1 = unsafe.getLong(uObj, cumOff);     //0, 16, 32, ...
+      final long k2 = unsafe.getLong(uObj, cumOff + 8); //8, 24, 40, ...
+      cumOff += 16L;
+      rem -= 16L;
+
+      h1 ^= mixK1(k1);
+      h1 = Long.rotateLeft(h1, 27);
+      h1 += h2;
+      h1 = (h1 * 5) + 0x52dce729L;
+
+      h2 ^= mixK2(k2);
+      h2 = Long.rotateLeft(h2, 31);
+      h2 += h1;
+      h2 = (h2 * 5) + 0x38495ab5L;
+    }
+
+    // Get the tail (if any): 1 to 15 bytes
+    if (rem > 0L) {
+      long k1 = 0;
+      long k2 = 0;
+      switch ((int) rem) {
+        case 15: {
+          k2 ^= (unsafe.getByte(uObj, cumOff + 14) & 0xFFL) << 48;
+        }
+        //$FALL-THROUGH$
+        case 14: {
+          k2 ^= (unsafe.getShort(uObj, cumOff + 12) & 0xFFFFL) << 32;
+          k2 ^= (unsafe.getInt(uObj, cumOff + 8) & 0xFFFFFFFFL);
+          k1 = unsafe.getLong(uObj, cumOff);
+          break;
+        }
+
+        case 13: {
+          k2 ^= (unsafe.getByte(uObj, cumOff + 12) & 0xFFL) << 32;
+        }
+        //$FALL-THROUGH$
+        case 12: {
+          k2 ^= (unsafe.getInt(uObj, cumOff + 8) & 0xFFFFFFFFL);
+          k1 = unsafe.getLong(uObj, cumOff);
+          break;
+        }
+
+        case 11: {
+          k2 ^= (unsafe.getByte(uObj, cumOff + 10) & 0xFFL) << 16;
+        }
+        //$FALL-THROUGH$
+        case 10: {
+          k2 ^= (unsafe.getShort(uObj, cumOff +  8) & 0xFFFFL);
+          k1 = unsafe.getLong(uObj, cumOff);
+          break;
+        }
+
+        case  9: {
+          k2 ^= (unsafe.getByte(uObj, cumOff +  8) & 0xFFL);
+        }
+        //$FALL-THROUGH$
+        case  8: {
+          k1 = unsafe.getLong(uObj, cumOff);
+          break;
+        }
+
+        case  7: {
+          k1 ^= (unsafe.getByte(uObj, cumOff +  6) & 0xFFL) << 48;
+        }
+        //$FALL-THROUGH$
+        case  6: {
+          k1 ^= (unsafe.getShort(uObj, cumOff +  4) & 0xFFFFL) << 32;
+          k1 ^= (unsafe.getInt(uObj, cumOff) & 0xFFFFFFFFL);
+          break;
+        }
+
+        case  5: {
+          k1 ^= (unsafe.getByte(uObj, cumOff +  4) & 0xFFL) << 32;
+        }
+        //$FALL-THROUGH$
+        case  4: {
+          k1 ^= (unsafe.getInt(uObj, cumOff) & 0xFFFFFFFFL);
+          break;
+        }
+
+        case  3: {
+          k1 ^= (unsafe.getByte(uObj, cumOff +  2) & 0xFFL) << 16;
+        }
+        //$FALL-THROUGH$
+        case  2: {
+          k1 ^= (unsafe.getShort(uObj, cumOff) & 0xFFFFL);
+          break;
+        }
+
+        case  1: {
+          k1 ^= (unsafe.getByte(uObj, cumOff) & 0xFFL);
+          break;
+        }
+        //default: break; //can't happen
+      }
+
+      h1 ^= mixK1(k1);
+      h2 ^= mixK2(k2);
+    }
+    return finalMix128(h1, h2, lengthBytes, hashOut);
+  }
+
+  //--Helper methods----------------------------------------------------
+
+  /**
+   * Self mix of k1
+   *
+   * @param k1 input argument
+   * @return mix
+   */
+  private static long mixK1(long k1) {
+    k1 *= C1;
+    k1 = Long.rotateLeft(k1, 31);
+    k1 *= C2;
+    return k1;
+  }
+
+  /**
+   * Self mix of k2
+   *
+   * @param k2 input argument
+   * @return mix
+   */
+  private static long mixK2(long k2) {
+    k2 *= C2;
+    k2 = Long.rotateLeft(k2, 33);
+    k2 *= C1;
+    return k2;
+  }
+
+
+  /**
+   * Final self mix of h*.
+   *
+   * @param h input to final mix
+   * @return mix
+   */
+  private static long finalMix64(long h) {
+    h ^= h >>> 33;
+    h *= 0xff51afd7ed558ccdL;
+    h ^= h >>> 33;
+    h *= 0xc4ceb9fe1a85ec53L;
+    h ^= h >>> 33;
+    return h;
+  }
+
+  /**
+   * Finalization: Add the length into the hash and mix
+   * @param h1 intermediate hash
+   * @param h2 intermediate hash
+   * @param lengthBytes the length in bytes
+   * @param hashOut the output array of 2 longs
+   * @return hashOut
+   */
+  private static long[] finalMix128(long h1, long h2, final long lengthBytes, final long[] hashOut) {
+    h1 ^= lengthBytes;
+    h2 ^= lengthBytes;
+
+    h1 += h2;
+    h2 += h1;
+
+    h1 = finalMix64(h1);
+    h2 = finalMix64(h2);
+
+    h1 += h2;
+    h2 += h1;
+
+    hashOut[0] = h1;
+    hashOut[1] = h2;
+    return hashOut;
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/ReadOnlyException.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,38 @@
+/*
+ * 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;
+
+/**
+ * The exception thrown when attempting to write into a read-only Resource.
+ *
+ * @author Praveenkumar Venkatesan
+ */
+public class ReadOnlyException extends MemoryException {
+    private static final long serialVersionUID = 1L;
+
+    /**
+     * Read Only Exception
+     * @param message the error message
+     */
+    public ReadOnlyException(final String message) {
+      super(message);
+    }
+}
+

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Utf8CodingException.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Utf8CodingException.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/Utf8CodingException.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,129 @@
+/*
+ * 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;
+
+/**
+ * This exception will be thrown for errors encountered during either the encoding of characters
+ * to Utf8 bytes, or the decoding of Utf8 bytes to characters.
+ *
+ * @author Lee Rhodes
+ */
+public final class Utf8CodingException extends RuntimeException {
+
+  private static final long serialVersionUID = 1L;
+
+  /**
+   * A coding exception occured processing UTF_8
+   * @param message the error message
+   */
+  public Utf8CodingException(final String message) {
+    super(message);
+  }
+
+  //DECODE
+  /**
+   * Exception for a short UTF_8 Decode Byte Sequence
+   * @param leadByte the given lead byte
+   * @param address the given address
+   * @param limit the given limit
+   * @param required what is required
+   * @return the exception
+   */
+  public static Utf8CodingException shortUtf8DecodeByteSequence(final byte leadByte, final long address,
+      final long limit, final int required) {
+    final String s = "Too few Utf8 decode bytes remaining given the leading byte. "
+        + shortSeq(leadByte, address, limit, required);
+    return new Utf8CodingException(s);
+  }
+
+  /**
+   * Exception for an illegal UTF_8 Decode Byte Sequence
+   * @param bytes the illegal byte sequence
+   * @return the exception.
+   */
+  public static Utf8CodingException illegalUtf8DecodeByteSequence(final byte[] bytes) {
+    final String s = "Invalid UTF-8 decode byte sequence: " + badBytes(bytes);
+    return new Utf8CodingException(s);
+  }
+
+  //ENCODE
+  /**
+   * Exception for out-of-memory
+   * @return the exception
+   */
+  public static Utf8CodingException outOfMemory() {
+    final String s = "Out-of-memory with characters remaining to be encoded";
+    return new Utf8CodingException(s);
+  }
+
+  /**
+   * Exception for an unpaired surrogate
+   * @param c The last char to encode is an unpaired surrogate
+   * @return the exception plus the unpaired surrogate character
+   */
+  public static Utf8CodingException unpairedSurrogate(final char c) {
+    final String s = "Last char to encode is an unpaired surrogate: 0X"
+        + Integer.toHexString(c & 0XFFFF);
+    return new Utf8CodingException(s);
+  }
+
+  /**
+   * Exception for a short UTF_8 encode byte length
+   * @param remaining The surrogate pair that is short
+   * @return the exception plus the surrogate pair that is short
+   */
+  public static Utf8CodingException shortUtf8EncodeByteLength(final int remaining) {
+    final String s = "Too few MemoryImpl bytes to encode a surrogate pair: " + remaining;
+    return new Utf8CodingException(s);
+  }
+
+  /**
+   * Exception for an illegal surrogate pair
+   * @param c1 the first character of the pair
+   * @param c2 the second character of the pair
+   * @return the exception plus the illegal pair
+   */
+  public static Utf8CodingException illegalSurrogatePair(final char c1, final char c2) {
+    final String s = "Illegal Surrogate Pair: Char 1: " + Integer.toHexString(c1 & 0XFFFF)
+      + ", Char 2: " + Integer.toHexString(c2 & 0XFFFF);
+    return new Utf8CodingException(s);
+  }
+
+  private static String shortSeq(final byte leadByte, final long address, final long limit,
+      final int required) {
+    final String s = "Lead byte: " + Integer.toHexString(leadByte & 0xFF)
+      + ", offset: 0X" + Long.toHexString(address)
+      + ", limit: 0X" + Long.toHexString(limit)
+      + ", required: " + required;
+    return s;
+  }
+
+  private static String badBytes(final byte[] bytes) {
+    final StringBuilder sb = new StringBuilder();
+    final int len = bytes.length;
+    int i = 0;
+    for (; i < (len - 1); i++) {
+      sb.append("0X" + Integer.toHexString(bytes[i] & 0XFF)).append(", ");
+    }
+    sb.append("0X" + Integer.toHexString(bytes[i] & 0XFF));
+    return sb.toString();
+  }
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableBuffer.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,411 @@
+/*
+ * 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;
+
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+import java.util.Objects;
+
+import org.apache.datasketches.memory.internal.BaseWritableBufferImpl;
+import org.apache.datasketches.memory.internal.Util;
+
+/**
+ * Defines the writable API for relative positional access to a resource
+ *
+ * @author Lee Rhodes
+ */
+public interface WritableBuffer extends Buffer {
+
+  //BYTE BUFFER
+  /**
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableBuffer</i> object has
+   * the same byte order, as the given <i>ByteBuffer</i>.
+   * @param byteBuf the given ByteBuffer. It must be non-null and with capacity &ge; 0.
+   * @return a new <i>WritableBuffer</i> for write operations on the given <i>ByteBuffer</i>.
+   */
+  static WritableBuffer writableWrap(ByteBuffer byteBuf) {
+    return writableWrap(byteBuf, byteBuf.order(), defaultMemReqSvr);
+  }
+
+  /**
+   * Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableBuffer</i> object has
+   * the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future writes and following reads.
+   * However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
+   * @param byteBuf the given ByteBuffer. It must be non-null and with capacity &ge; 0.
+   * @param byteOrder the byte order to be used.
+   * @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which must not be null.
+   * This is a callback mechanism for a user client to request a larger <i>WritableBuffer</i>.
+   * @return a new <i>WritableBuffer</i> for write operations on the given <i>ByteBuffer</i>.
+   */
+  static WritableBuffer writableWrap(ByteBuffer byteBuf, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
+    Objects.requireNonNull(byteBuf, "ByteBuffer 'byteBuf' must not be null");
+    Objects.requireNonNull(byteOrder, "ByteOrder 'byteOrder' must not be null");
+    Util.negativeCheck(byteBuf.capacity(), "byteBuf.capacity");
+    if (byteBuf.isReadOnly()) {
+      throw new ReadOnlyException("Cannot create a WritableBuffer from a ReadOnly ByteBuffer.");
+    }
+    return BaseWritableBufferImpl.wrapByteBuffer(byteBuf, false, byteOrder, memReqSvr);
+  }
+
+  // NO MAP
+  // NO ALLOCATE DIRECT
+
+  //DUPLICATES
+  /**
+   * Returns a duplicate writable view of this Buffer with the same but independent values of
+   * <i>start</i>, <i>position</i> and <i>end</i>.
+   * <ul>
+   * <li>Returned object's origin = this object's origin</li>
+   * <li>Returned object's <i>start</i> = this object's <i>start</i></li>
+   * <li>Returned object's <i>position</i> = this object's <i>position</i></li>
+   * <li>Returned object's <i>end</i> = this object's <i>end</i></li>
+   * <li>Returned object's <i>capacity</i> = this object' <i>capacityBytes</i></li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
+   * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
+   * </ul>
+   * @return a duplicate writable view of this Buffer with the same but independent values of
+   * <i>start</i>, <i>position</i> and <i>end</i>.
+   */
+  WritableBuffer writableDuplicate();
+
+  /**
+   * Returns a duplicate writable view of this Buffer with the same but independent values of
+   * <i>start</i>, <i>position</i> and <i>end</i>, but with the specified byteOrder.
+   * <ul>
+   * <li>Returned object's origin = this object's origin</li>
+   * <li>Returned object's <i>start</i> = this object's <i>start</i></li>
+   * <li>Returned object's <i>position</i> = this object's <i>position</i></li>
+   * <li>Returned object's <i>end</i> = this object's <i>end</i></li>
+   * <li>Returned object's <i>capacity</i> = this object' <i>capacityBytes</i></li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
+   * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
+   * </ul>
+   * @param byteOrder the given <i>ByteOrder</i>.
+   * @return a duplicate writable view of this Buffer with the same but independent values of
+   * <i>start</i>, <i>position</i> and <i>end</i>.
+   */
+  WritableBuffer writableDuplicate(ByteOrder byteOrder);
+
+  //REGIONS
+  /**
+   * A writable region is a writable view of this object.
+   * <ul>
+   * <li>Returned object's origin = this object's <i>position</i></li>
+   * <li>Returned object's <i>start</i> = 0</li>
+   * <li>Returned object's <i>position</i> = 0</li>
+   * <li>Returned object's <i>end</i> = this object's (<i>end</i> - <i>position</i>)</li>
+   * <li>Returned object's <i>capacity</i> = this object's (<i>end</i> - <i>position</i>)</li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
+   * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
+   * </ul>
+   * @return a new <i>WritableBuffer</i> representing the defined writable region.
+   */
+  WritableBuffer writableRegion();
+
+  /**
+   * A writable region is a writable view of this object.
+   * <ul>
+   * <li>Returned object's origin = this objects' origin + <i>offsetBytes</i></li>
+   * <li>Returned object's <i>start</i> = 0</li>
+   * <li>Returned object's <i>position</i> = 0</li>
+   * <li>Returned object's <i>end</i> = <i>capacityBytes</i></li>
+   * <li>Returned object's <i>capacity</i> = <i>capacityBytes</i></li>
+   * <li>Returned object's <i>start</i>, <i>position</i> and <i>end</i> are mutable and
+   * independent of this object's <i>start</i>, <i>position</i> and <i>end</i></li>
+   * <li>Returned object's byte order = <i>byteOrder</i></li>
+   * </ul>
+   *
+   * <p><b>Note: </b><i>asWritableMemory()</i> and <i>asMemory()</i>
+   * will return the originating <i>Memory</i> byte order.</p>
+   * @param offsetBytes the starting offset with respect to the origin of this <i>WritableBuffer</i>
+   * @param capacityBytes the <i>capacity</i> of the returned region in bytes
+   * @param byteOrder the given byte order
+   * @return a new <i>WritableBuffer</i> representing the defined writable region
+   * with the given offsetBytes, capacityBytes and byte order.
+   */
+  WritableBuffer writableRegion(long offsetBytes, long capacityBytes,
+      ByteOrder byteOrder);
+
+  //AS WRITABLE MEMORY
+  /**
+   * Convert this WritableBuffer to a WritableMemory.
+   * If this object's capacity is zero, the returned object is effectively immutable and
+   * the backing storage and byte order are unspecified.
+   * @return WritableMemory
+   */
+  default WritableMemory asWritableMemory() {
+    return asWritableMemory(ByteOrder.nativeOrder());
+  }
+
+  /**
+   * Convert this WritableBuffer to a WritableMemory with the given byte order.
+   * If this object's capacity is zero, the returned object is effectively immutable and
+   * the backing storage and byte order are unspecified.
+   * @param byteOrder the byte order to be used.
+   * @return WritableMemory
+   */
+  WritableMemory asWritableMemory(ByteOrder byteOrder);
+
+  //NO ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
+
+  //NO ACCESS PRIMITIVE HEAP ARRAYS for WRITE
+
+  //PRIMITIVE putX() and putXArray()
+  /**
+   * Puts the boolean value at the current position.
+   * Increments the position by 1.
+   * @param value the value to put
+   */
+  void putBoolean(boolean value);
+
+  /**
+   * Puts the boolean value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start.
+   * @param value the value to put
+   */
+  void putBoolean(long offsetBytes, boolean value);
+
+  /**
+   * Puts the boolean array at the current position.
+   * Increments the position by <i>lengthBooleans - srcOffsetBooleans</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetBooleans offset in array units
+   * @param lengthBooleans number of array units to transfer
+   */
+  void putBooleanArray(boolean[] srcArray, int srcOffsetBooleans,
+      int lengthBooleans);
+
+  /**
+   * Puts the byte value at the current position.
+   * Increments the position by <i>Byte.BYTES</i>.
+   * @param value the value to put
+   */
+  void putByte(byte value);
+
+  /**
+   * Puts the byte value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putByte(long offsetBytes, byte value);
+
+  /**
+   * Puts the byte array at the current position.
+   * Increments the position by <i>Byte.BYTES * (lengthBytes - srcOffsetBytes)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetBytes offset in array units
+   * @param lengthBytes number of array units to transfer
+   */
+  void putByteArray(byte[] srcArray, int srcOffsetBytes, int lengthBytes);
+
+  /**
+   * Puts the char value at the current position.
+   * Increments the position by <i>Character.BYTES</i>.
+   * @param value the value to put
+   */
+  void putChar(char value);
+
+  /**
+   * Puts the char value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putChar(long offsetBytes, char value);
+
+  /**
+   * Puts the char array at the current position.
+   * Increments the position by <i>Character.BYTES * (lengthChars - srcOffsetChars)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetChars offset in array units
+   * @param lengthChars number of array units to transfer
+   */
+  void putCharArray(char[] srcArray, int srcOffsetChars, int lengthChars);
+
+  /**
+   * Puts the double value at the current position.
+   * Increments the position by <i>Double.BYTES</i>.
+   * @param value the value to put
+   */
+  void putDouble(double value);
+
+  /**
+   * Puts the double value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putDouble(long offsetBytes, double value);
+
+  /**
+   * Puts the double array at the current position.
+   * Increments the position by <i>Double.BYTES * (lengthDoubles - srcOffsetDoubles)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetDoubles offset in array units
+   * @param lengthDoubles number of array units to transfer
+   */
+  void putDoubleArray(double[] srcArray, int srcOffsetDoubles, int lengthDoubles);
+
+  /**
+   * Puts the float value at the current position.
+   * Increments the position by <i>Float.BYTES</i>.
+   * @param value the value to put
+   */
+  void putFloat(float value);
+
+  /**
+   * Puts the float value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putFloat(long offsetBytes, float value);
+
+  /**
+   * Puts the float array at the current position.
+   * Increments the position by <i>Float.BYTES * (lengthFloats - srcOffsetFloats)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetFloats offset in array units
+   * @param lengthFloats number of array units to transfer
+   */
+  void putFloatArray(float[] srcArray, int srcOffsetFloats, int lengthFloats);
+
+  /**
+   * Puts the int value at the current position.
+   * Increments the position by <i>Integer.BYTES</i>.
+   * @param value the value to put
+   */
+  void putInt(int value);
+
+  /**
+   * Puts the int value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putInt(long offsetBytes, int value);
+
+  /**
+   * Puts the int array at the current position.
+   * Increments the position by <i>Integer.BYTES * (lengthInts - srcOffsetInts)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetInts offset in array units
+   * @param lengthInts number of array units to transfer
+   */
+  void putIntArray(int[] srcArray, int srcOffsetInts, int lengthInts);
+
+  /**
+   * Puts the long value at the current position.
+   * Increments the position by <i>Long.BYTES</i>.
+   * @param value the value to put
+   */
+  void putLong(long value);
+
+  /**
+   * Puts the long value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putLong(long offsetBytes, long value);
+
+  /**
+   * Puts the long array at the current position.
+   * Increments the position by <i>Long.BYTES * (lengthLongs - srcOffsetLongs)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetLongs offset in array units
+   * @param lengthLongs number of array units to transfer
+   */
+  void putLongArray(long[] srcArray, int srcOffsetLongs, int lengthLongs);
+
+  /**
+   * Puts the short value at the current position.
+   * Increments the position by <i>Short.BYTES</i>.
+   * @param value the value to put
+   */
+  void putShort(short value);
+
+  /**
+   * Puts the short value at the given offset.
+   * This does not change the position.
+   * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+   * @param value the value to put
+   */
+  void putShort(long offsetBytes, short value);
+
+  /**
+   * Puts the short array at the current position.
+   * Increments the position by <i>Short.BYTES * (lengthShorts - srcOffsetShorts)</i>.
+   * @param srcArray The source array.
+   * @param srcOffsetShorts offset in array units
+   * @param lengthShorts number of array units to transfer
+   */
+  void putShortArray(short[] srcArray, int srcOffsetShorts, int lengthShorts);
+
+  // NO ATOMIC METHODS
+
+  //OTHER WRITE METHODS
+  /**
+   * Returns the primitive backing array, otherwise null.
+   * @return the primitive backing array, otherwise null.
+   */
+  Object getArray();
+
+  /**
+   * Clears all bytes of this Buffer from position to end to zero. The position will be set to end.
+   */
+  void clear();
+
+  //NO clearBits(...)
+
+  /**
+   * Fills this Buffer from position to end with the given byte value.
+   * The position will be set to <i>end</i>.
+   * @param value the given byte value
+   */
+  void fill(byte value);
+
+  //NO fill(offsetBytes, lengthBytes, value)
+
+  //NO setBits(...)
+
+  //OTHER WRITABLE API METHODS
+  /**
+   * WritableBuffer enables this for ByteBuffer backed resources. However, the object returned is in the form of
+   * a WritableMemory. To convert to WritableBuffer use asWritableBuffer(). To enable for Heap and Direct Memory
+   * resources, use the WritableMemory to configure and then call asWritableBuffer().
+   * Map backed resources will always return null.
+   * Gets the MemoryRequestServer object, if set, for the above resources to request additional memory.
+   * The user must customize the actions of the MemoryRequestServer by
+   * implementing the MemoryRequestServer interface and set using the following method:
+   * <ul>
+   * <li>{@link WritableBuffer#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
+   * </ul>
+   * Simple implementation examples include the DefaultMemoryRequestServer in the main tree, as well as
+   * the ExampleMemoryRequestServerTest and the use with ByteBuffer documented in the DruidIssue11544Test
+   * in the test tree.
+   * @return the MemoryRequestServer object or null.
+   */
+  public MemoryRequestServer getMemoryRequestServer();
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableHandle.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,36 @@
+/*
+ * 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;
+
+/**
+ * A Handle for writable direct memory or a memory-mapped, writable file resource.
+ * Please read Javadocs for {@link Handle}.
+ *
+ * @author Lee Rhodes
+ * @author Roman Leventov
+ */
+public interface WritableHandle extends Handle {
+
+  /**
+   * Gets a WritableMemory
+   * @return a WritableMemory
+   */
+  WritableMemory getWritable();
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMap.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,37 @@
+/*
+ * 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;
+
+/**
+ * Writable interface for a memory mapped file
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ * @author Praveenkumar Venkatesan
+ */
+public interface WritableMap extends Map {
+
+  /**
+   * @see <a href="https://docs.oracle.com/javase/8/docs/api/java/nio/MappedByteBuffer.html#force--">
+   * java/nio/MappedByteBuffer.force</a>
+   */
+  void force();
+
+}

Added: dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java
==============================================================================
--- dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java (added)
+++ dev/datasketches/memory/2.0.0-RC1/apache-datasketches-memory-2.0.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/WritableMapHandle.java Thu Aug 19 22:18:24 2021
@@ -0,0 +1,30 @@
+/*
+ * 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;
+
+/**
+ * A Handle for a memory-mapped, writable file resource.
+ * Joins a WritableHandle with an AutoCloseable WritableMap resource
+ * Please read Javadocs for {@link Handle}.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+public interface WritableMapHandle extends WritableMap, WritableHandle { }



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