Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,503 @@
+/*
+ * 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.internal;
+
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_BOOLEAN_BASE_OFFSET;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_BOOLEAN_INDEX_SCALE;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_BYTE_BASE_OFFSET;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_BYTE_INDEX_SCALE;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_CHAR_INDEX_SCALE;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_INDEX_SCALE;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
+import static 
org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_INDEX_SCALE;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
+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.Buffer;
+import org.apache.datasketches.memory.Memory;
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.ReadOnlyException;
+import org.apache.datasketches.memory.Utf8CodingException;
+import org.apache.datasketches.memory.WritableBuffer;
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableMapHandle;
+import org.apache.datasketches.memory.WritableMemory;
+
+/*
+ * Developer notes: The heavier methods, such as put/get arrays, duplicate, 
region, clear, fill,
+ * compareTo, etc., use hard checks (checkValid*() and checkBounds()), which 
execute at runtime and
+ * throw exceptions if violated. The cost of the runtime checks are minor 
compared to the rest of
+ * the work these methods are doing.
+ *
+ * <p>The light weight methods, such as put/get primitives, use asserts 
(assertValid*()), which only
+ * execute when asserts are enabled and JIT will remove them entirely from 
production runtime code.
+ * The light weight methods will simplify to a single unsafe call, which is 
further simplified by
+ * JIT to an intrinsic that is often a single CPU instruction.
+ */
+
+/**
+ * Common base of native-ordered and non-native-ordered {@link WritableMemory} 
implementations.
+ * Contains methods which are agnostic to the byte order.
+ */
+@SuppressWarnings("restriction")
+public abstract class BaseWritableMemoryImpl extends BaseStateImpl implements 
WritableMemory {
+
+  //1KB of empty bytes for speedy clear()
+  private final static byte[] EMPTY_BYTES;
+
+  static {
+    EMPTY_BYTES = new byte[1024];
+  }
+
+  //Pass-through ctor
+  BaseWritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset,
+      final long regionOffset, final long capacityBytes) {
+    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
+  }
+
+  /**
+   * The static constructor that chooses the correct Heap leaf node based on 
the byte order.
+   * @param arr the primitive heap array being wrapped
+   * @param offsetBytes the offset bytes into the array (independent of array 
type).
+   * @param lengthBytes the length of the wrapped region.
+   * @param localReadOnly the requested read-only status
+   * @param byteOrder the requested byte order
+   * @param memReqSvr the requested MemoryRequestServer, which may be null.
+   * @return this class constructed via the leaf node.
+   */
+  public static BaseWritableMemoryImpl wrapHeapArray(final Object arr, final 
long offsetBytes, final long lengthBytes,
+      final boolean localReadOnly, final ByteOrder byteOrder, final 
MemoryRequestServer memReqSvr) {
+    final int typeId = localReadOnly ? READONLY : 0;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(arr, offsetBytes, lengthBytes, typeId, 
memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(arr, offsetBytes, lengthBytes, 
typeId, memReqSvr);
+  }
+
+  /**
+   * The static constructor that chooses the correct ByteBuffer leaf node 
based on the byte order.
+   * @param byteBuf the ByteBuffer being wrapped
+   * @param localReadOnly the requested read-only state
+   * @param byteOrder the requested byteOrder
+   * @param memReqSvr the requested MemoryRequestServer, which may be null.
+   * @return this class constructed via the leaf node.
+   */
+  public static BaseWritableMemoryImpl wrapByteBuffer(
+      final ByteBuffer byteBuf, final boolean localReadOnly, final ByteOrder 
byteOrder,
+      final MemoryRequestServer memReqSvr) {
+    final AccessByteBuffer abb = new AccessByteBuffer(byteBuf);
+    final int typeId = (abb.resourceReadOnly || localReadOnly) ? READONLY : 0;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new BBWritableMemoryImpl(abb.unsafeObj, abb.nativeBaseOffset,
+            abb.regionOffset, abb.capacityBytes, typeId, byteBuf, memReqSvr)
+        : new BBNonNativeWritableMemoryImpl(abb.unsafeObj, 
abb.nativeBaseOffset,
+            abb.regionOffset, abb.capacityBytes,  typeId, byteBuf, memReqSvr);
+  }
+
+  /**
+   * The static constructor that chooses the correct Map leaf node based on 
the byte order.
+   * @param file the file being wrapped.
+   * @param fileOffsetBytes the file offset bytes
+   * @param capacityBytes the requested capacity of the memory mapped region
+   * @param localReadOnly the requested read-only state
+   * @param byteOrder the requested byte-order
+   * @return this class constructed via the leaf node.
+   */
+  public static WritableMapHandle wrapMap(final File file, final long 
fileOffsetBytes,
+      final long capacityBytes, final boolean localReadOnly, final ByteOrder 
byteOrder) {
+    final AllocateDirectWritableMap dirWMap =
+        new AllocateDirectWritableMap(file, fileOffsetBytes, capacityBytes, 
localReadOnly);
+    final int typeId = (dirWMap.resourceReadOnly || localReadOnly) ? READONLY 
: 0;
+    final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
+        ? new MapWritableMemoryImpl(dirWMap.nativeBaseOffset, 0L, 
capacityBytes,
+            typeId, dirWMap.getValid())
+        : new MapNonNativeWritableMemoryImpl(dirWMap.nativeBaseOffset, 0L, 
capacityBytes,
+            typeId, dirWMap.getValid());
+    return new WritableMapHandleImpl(dirWMap, wmem);
+  }
+
+  /**
+   * The static constructor that chooses the correct Direct leaf node based on 
the byte order.
+   * @param capacityBytes the requested capacity for the Direct (off-heap) 
memory
+   * @param byteOrder the requested byte order
+   * @param memReqSvr the requested MemoryRequestServer, which may be null
+   * @return this class constructed via the leaf node.
+   */
+  public static WritableHandle wrapDirect(final long capacityBytes,
+      final ByteOrder byteOrder, final MemoryRequestServer memReqSvr) {
+    final AllocateDirect direct = new AllocateDirect(capacityBytes);
+    final int typeId = 0; //direct is never read-only on construction
+    final BaseWritableMemoryImpl wmem = Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(direct.getNativeBaseOffset(), 0L, 
capacityBytes,
+            typeId, direct.getValid(), memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(direct.getNativeBaseOffset(), 
0L, capacityBytes,
+            typeId, direct.getValid(), memReqSvr);
+
+    final WritableHandle handle = new WritableDirectHandleImpl(direct, wmem);
+    return handle;
+  }
+
+  //REGIONS
+  @Override
+  public Memory region(final long offsetBytes, final long capacityBytes, final 
ByteOrder byteOrder) {
+    return writableRegionImpl(offsetBytes, capacityBytes, true, byteOrder);
+  }
+
+  @Override
+  public WritableMemory writableRegion(final long offsetBytes, final long 
capacityBytes, final ByteOrder byteOrder) {
+    return writableRegionImpl(offsetBytes, capacityBytes, false, byteOrder);
+  }
+
+  WritableMemory writableRegionImpl(final long offsetBytes, final long 
capacityBytes,
+      final boolean localReadOnly, final ByteOrder byteOrder) {
+    if (isReadOnly() && !localReadOnly) {
+      throw new ReadOnlyException("Writable region of a read-only Memory is 
not allowed.");
+    }
+    negativeCheck(offsetBytes, "offsetBytes must be >= 0");
+    negativeCheck(capacityBytes, "capacityBytes must be >= 0");
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
+    checkValidAndBounds(offsetBytes, capacityBytes);
+    final boolean readOnly = isReadOnly() || localReadOnly;
+    return toWritableRegion(offsetBytes, capacityBytes, readOnly, byteOrder);
+  }
+
+  abstract BaseWritableMemoryImpl toWritableRegion(
+      long offsetBytes, long capcityBytes, boolean readOnly, ByteOrder 
byteOrder);
+
+  //AS BUFFER
+  @Override
+  public Buffer asBuffer(final ByteOrder byteOrder) {
+    return asWritableBuffer(true, byteOrder);
+  }
+
+  @Override
+  public WritableBuffer asWritableBuffer(final ByteOrder byteOrder) {
+    return asWritableBuffer(false, byteOrder);
+  }
+
+  WritableBuffer asWritableBuffer(final boolean localReadOnly, final ByteOrder 
byteOrder) {
+    Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
+    if (isReadOnly() && !localReadOnly) {
+      throw new ReadOnlyException(
+          "Converting a read-only Memory to a writable Buffer is not 
allowed.");
+    }
+    final boolean readOnly = isReadOnly() || localReadOnly;
+    final WritableBuffer wbuf = toWritableBuffer(readOnly, byteOrder);
+    wbuf.setStartPositionEnd(0, 0, getCapacity());
+    return wbuf;
+  }
+
+  abstract BaseWritableBufferImpl toWritableBuffer(boolean readOnly, ByteOrder 
byteOrder);
+
+  //PRIMITIVE getX() and getXArray()
+  @Override
+  public final boolean getBoolean(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+    return unsafe.getBoolean(getUnsafeObject(), 
getCumulativeOffset(offsetBytes));
+  }
+
+  @Override
+  public final void getBooleanArray(final long offsetBytes, final boolean[] 
dstArray,
+      final int dstOffsetBooleans, final int lengthBooleans) {
+    final long copyBytes = lengthBooleans;
+    checkValidAndBounds(offsetBytes, copyBytes);
+    checkBounds(dstOffsetBooleans, lengthBooleans, dstArray.length);
+    CompareAndCopy.copyMemoryCheckingDifferentObject(
+        getUnsafeObject(),
+        getCumulativeOffset(offsetBytes),
+        dstArray,
+        ARRAY_BOOLEAN_BASE_OFFSET + dstOffsetBooleans,
+        copyBytes);
+  }
+
+  @Override
+  public final byte getByte(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+    return unsafe.getByte(getUnsafeObject(), getCumulativeOffset(offsetBytes));
+  }
+
+  @Override
+  public final void getByteArray(final long offsetBytes, final byte[] dstArray,
+      final int dstOffsetBytes, final int lengthBytes) {
+    final long copyBytes = lengthBytes;
+    checkValidAndBounds(offsetBytes, copyBytes);
+    checkBounds(dstOffsetBytes, lengthBytes, dstArray.length);
+    CompareAndCopy.copyMemoryCheckingDifferentObject(
+        getUnsafeObject(),
+        getCumulativeOffset(offsetBytes),
+        dstArray,
+        ARRAY_BYTE_BASE_OFFSET + dstOffsetBytes,
+        copyBytes);
+  }
+
+  @Override
+  public final int getCharsFromUtf8(final long offsetBytes, final int 
utf8LengthBytes,
+      final Appendable dst) throws IOException, Utf8CodingException {
+    checkValidAndBounds(offsetBytes, utf8LengthBytes);
+    return Utf8.getCharsFromUtf8(offsetBytes, utf8LengthBytes, dst, 
getCumulativeOffset(),
+        getUnsafeObject());
+  }
+
+  @Override
+  public final int getCharsFromUtf8(final long offsetBytes, final int 
utf8LengthBytes,
+      final StringBuilder dst) throws Utf8CodingException {
+    try {
+      // Ensure that we do at most one resize of internal StringBuilder's char 
array
+      dst.ensureCapacity(dst.length() + utf8LengthBytes);
+      return getCharsFromUtf8(offsetBytes, utf8LengthBytes, (Appendable) dst);
+    } catch (final IOException e) {
+      throw new RuntimeException("Should not happen", e);
+    }
+  }
+
+  //PRIMITIVE getX() Native Endian (used by both endians)
+  final char getNativeOrderedChar(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+    return unsafe.getChar(getUnsafeObject(), getCumulativeOffset(offsetBytes));
+  }
+
+  final int getNativeOrderedInt(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_INT_INDEX_SCALE);
+    return unsafe.getInt(getUnsafeObject(), getCumulativeOffset(offsetBytes));
+  }
+
+  final long getNativeOrderedLong(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+    return unsafe.getLong(getUnsafeObject(), getCumulativeOffset(offsetBytes));
+  }
+
+  final short getNativeOrderedShort(final long offsetBytes) {
+    assertValidAndBoundsForRead(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+    return unsafe.getShort(getUnsafeObject(), 
getCumulativeOffset(offsetBytes));
+  }
+
+  //OTHER PRIMITIVE READ METHODS: compareTo, copyTo, equals
+  @Override
+  public final int compareTo(final long thisOffsetBytes, final long 
thisLengthBytes,
+      final Memory thatMem, final long thatOffsetBytes, final long 
thatLengthBytes) {
+    return CompareAndCopy.compare((BaseStateImpl)this, thisOffsetBytes, 
thisLengthBytes,
+        (BaseStateImpl)thatMem, thatOffsetBytes, thatLengthBytes);
+  }
+
+  @Override
+  public final void copyTo(final long srcOffsetBytes, final WritableMemory 
destination,
+      final long dstOffsetBytes, final long lengthBytes) {
+    CompareAndCopy.copy((BaseStateImpl)this, srcOffsetBytes, 
(BaseStateImpl)destination,
+        dstOffsetBytes, lengthBytes);
+  }
+
+  @Override
+  public final void writeTo(final long offsetBytes, final long lengthBytes,
+      final WritableByteChannel out) throws IOException {
+    checkValidAndBounds(offsetBytes, lengthBytes);
+    if (getUnsafeObject() instanceof byte[]) {
+      writeByteArrayTo((byte[]) getUnsafeObject(), offsetBytes, lengthBytes, 
out);
+    } else if (getUnsafeObject() == null) {
+      writeDirectMemoryTo(offsetBytes, lengthBytes, out);
+    } else {
+      // Memory is backed by some array that is not byte[], for example int[], 
long[], etc.
+      // We don't have the choice to do an extra intermediate copy.
+      writeToWithExtraCopy(offsetBytes, lengthBytes, out);
+    }
+  }
+
+  //PRIMITIVE putX() and putXArray() implementations
+  @Override
+  public final void putBoolean(final long offsetBytes, final boolean value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE);
+    unsafe.putBoolean(getUnsafeObject(), getCumulativeOffset(offsetBytes), 
value);
+  }
+
+  @Override
+  public final void putBooleanArray(final long offsetBytes, final boolean[] 
srcArray,
+      final int srcOffsetBooleans, final int lengthBooleans) {
+    final long copyBytes = lengthBooleans;
+    checkValidAndBoundsForWrite(offsetBytes, copyBytes);
+    checkBounds(srcOffsetBooleans, lengthBooleans, srcArray.length);
+    CompareAndCopy.copyMemoryCheckingDifferentObject(
+        srcArray,
+        ARRAY_BOOLEAN_BASE_OFFSET + srcOffsetBooleans,
+        getUnsafeObject(),
+        getCumulativeOffset(offsetBytes),
+        copyBytes
+    );
+  }
+
+  @Override
+  public final void putByte(final long offsetBytes, final byte value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+    unsafe.putByte(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+  }
+
+  @Override
+  public final void putByteArray(final long offsetBytes, final byte[] srcArray,
+      final int srcOffsetBytes, final int lengthBytes) {
+    final long copyBytes = lengthBytes;
+    checkValidAndBoundsForWrite(offsetBytes, copyBytes);
+    checkBounds(srcOffsetBytes, lengthBytes, srcArray.length);
+    CompareAndCopy.copyMemoryCheckingDifferentObject(
+        srcArray,
+        ARRAY_BYTE_BASE_OFFSET + srcOffsetBytes,
+        getUnsafeObject(),
+        getCumulativeOffset(offsetBytes),
+        copyBytes
+    );
+  }
+
+  @Override
+  public final long putCharsToUtf8(final long offsetBytes, final CharSequence 
src) {
+    checkValid();
+    return Utf8.putCharsToUtf8(offsetBytes, src, getCapacity(), 
getCumulativeOffset(),
+        getUnsafeObject());
+  }
+
+  //PRIMITIVE putX() Native Endian (used by both endians)
+  final void putNativeOrderedChar(final long offsetBytes, final char value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_CHAR_INDEX_SCALE);
+    unsafe.putChar(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+  }
+
+  final void putNativeOrderedInt(final long offsetBytes, final int value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_INT_INDEX_SCALE);
+    unsafe.putInt(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+  }
+
+  final void putNativeOrderedLong(final long offsetBytes, final long value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
+    unsafe.putLong(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+  }
+
+  final void putNativeOrderedShort(final long offsetBytes, final short value) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_SHORT_INDEX_SCALE);
+    unsafe.putShort(getUnsafeObject(), getCumulativeOffset(offsetBytes), 
value);
+  }
+
+  //OTHER WRITE METHODS
+  @Override
+  public final Object getArray() {
+    assertValid();
+    return getUnsafeObject();
+  }
+
+  @Override
+  public final void clear() {
+    clear(0, getCapacity());
+  }
+
+  @Override
+  public final void clear(final long offsetBytes, final long lengthBytes)
+  {
+    //No need to check bounds, since putByteArray calls 
checkValidAndBoundsForWrite
+
+    final long endBytes = offsetBytes + lengthBytes;
+    for (long i = offsetBytes; i < endBytes; i += EMPTY_BYTES.length) {
+      putByteArray(i, EMPTY_BYTES, 0, (int) Math.min(EMPTY_BYTES.length, 
endBytes - i));
+    }
+  }
+
+  @Override
+  public final void clearBits(final long offsetBytes, final byte bitMask) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+    final long cumBaseOff = getCumulativeOffset(offsetBytes);
+    int value = unsafe.getByte(getUnsafeObject(), cumBaseOff) & 0XFF;
+    value &= ~bitMask;
+    unsafe.putByte(getUnsafeObject(), cumBaseOff, (byte)value);
+  }
+
+  @Override
+  public final void fill(final byte value) {
+    fill(0, getCapacity(), value);
+  }
+
+  @Override
+  public final void fill(long offsetBytes, long lengthBytes, final byte value) 
{
+    checkValidAndBoundsForWrite(offsetBytes, lengthBytes);
+    while (lengthBytes > 0) {
+      final long chunk = Math.min(lengthBytes, 
Util.UNSAFE_COPY_THRESHOLD_BYTES);
+      unsafe.setMemory(getUnsafeObject(), getCumulativeOffset(offsetBytes), 
chunk, value);
+      offsetBytes += chunk;
+      lengthBytes -= chunk;
+    }
+  }
+
+  @Override
+  public final void setBits(final long offsetBytes, final byte bitMask) {
+    assertValidAndBoundsForWrite(offsetBytes, ARRAY_BYTE_INDEX_SCALE);
+    final long myOffset = getCumulativeOffset(offsetBytes);
+    final byte value = unsafe.getByte(getUnsafeObject(), myOffset);
+    unsafe.putByte(getUnsafeObject(), myOffset, (byte)(value | bitMask));
+  }
+
+  //RESTRICTED
+  private void writeByteArrayTo(final byte[] unsafeObj, final long offsetBytes,
+      final long lengthBytes, final WritableByteChannel out) throws 
IOException {
+    final int off =
+        Ints.checkedCast((getCumulativeOffset(offsetBytes)) - 
UnsafeUtil.ARRAY_BYTE_BASE_OFFSET);
+    final int len = Ints.checkedCast(lengthBytes);
+    final ByteBuffer bufToWrite = ByteBuffer.wrap(unsafeObj, off, len);
+    writeFully(bufToWrite, out);
+  }
+
+  private void writeDirectMemoryTo(final long offsetBytes, long lengthBytes,
+      final WritableByteChannel out) throws IOException {
+    long addr = getCumulativeOffset(offsetBytes);
+    // Do chunking, because it's likely that 
WritableByteChannel.write(ByteBuffer) in some network-
+    // or file-backed WritableByteChannel implementations with direct 
ByteBuffer argument could
+    // be subject of the same safepoint problems as in Unsafe.copyMemory and 
Unsafe.setMemory.
+    while (lengthBytes > 0) {
+      final int chunk = (int) Math.min(Util.UNSAFE_COPY_THRESHOLD_BYTES, 
lengthBytes);
+      final ByteBuffer bufToWrite = 
AccessByteBuffer.getDummyReadOnlyDirectByteBuffer(addr, chunk);
+      writeFully(bufToWrite, out);
+      addr += chunk;
+      lengthBytes -= chunk;
+    }
+  }
+
+  private void writeToWithExtraCopy(long offsetBytes, long lengthBytes,
+      final WritableByteChannel out) throws IOException {
+    // Keep the bufLen a multiple of 8, to maybe allow getByteArray() to go a 
faster path.
+    final int bufLen = Ints.checkedCast(Math.max(8, Math.min((getCapacity() / 
1024) & ~7L, 4096)));
+    final byte[] buf = new byte[bufLen];
+    final ByteBuffer bufToWrite = ByteBuffer.wrap(buf);
+    while (lengthBytes > 0) {
+      final int chunk = (int) Math.min(buf.length, lengthBytes);
+      getByteArray(offsetBytes, buf, 0, chunk);
+      bufToWrite.clear().limit(chunk);
+      writeFully(bufToWrite, out);
+      offsetBytes += chunk;
+      lengthBytes -= chunk;
+    }
+  }
+
+  private static void writeFully(final ByteBuffer bufToWrite, final 
WritableByteChannel out)
+      throws IOException {
+    while (bufToWrite.remaining() > 0) {
+      out.write(bufToWrite);
+    }
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/BaseWritableMemoryImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,522 @@
+/*
+ * 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.internal;
+
+import static org.apache.datasketches.memory.internal.UnsafeUtil.CHAR_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.DOUBLE_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.FLOAT_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.INT_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.LONG_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.SHORT_SHIFT;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.checkBounds;
+import static org.apache.datasketches.memory.internal.UnsafeUtil.unsafe;
+import static 
org.apache.datasketches.memory.internal.Util.UNSAFE_COPY_THRESHOLD_BYTES;
+
+/**
+ * @author Lee Rhodes
+ */
+@SuppressWarnings("restriction")
+final class CompareAndCopy {
+
+  private CompareAndCopy() { }
+
+  static int compare(
+      final BaseStateImpl state1, final long offsetBytes1, final long 
lengthBytes1,
+      final BaseStateImpl state2, final long offsetBytes2, final long 
lengthBytes2) {
+    state1.checkValid();
+    checkBounds(offsetBytes1, lengthBytes1, state1.getCapacity());
+    state2.checkValid();
+    checkBounds(offsetBytes2, lengthBytes2, state2.getCapacity());
+    final long cumOff1 = state1.getCumulativeOffset(offsetBytes1);
+    final long cumOff2 = state2.getCumulativeOffset(offsetBytes2);
+    final Object arr1 = state1.getUnsafeObject();
+    final Object arr2 = state2.getUnsafeObject();
+    if ((arr1 != arr2) || (cumOff1 != cumOff2)) {
+      final long lenBytes = Math.min(lengthBytes1, lengthBytes2);
+      for (long i = 0; i < lenBytes; i++) {
+        final int byte1 = unsafe.getByte(arr1, cumOff1 + i);
+        final int byte2 = unsafe.getByte(arr2, cumOff2 + i);
+        if (byte1 < byte2) { return -1; }
+        if (byte1 > byte2) { return  1; }
+      }
+    }
+    return Long.compare(lengthBytes1, lengthBytes2);
+  }
+
+  static boolean equals(final BaseStateImpl state1, final BaseStateImpl 
state2) {
+    final long cap1 = state1.getCapacity();
+    final long cap2 = state2.getCapacity();
+    return (cap1 == cap2) && equals(state1, 0, state2, 0, cap1);
+  }
+
+  //Developer notes: this is subtlely different from (campare == 0) in that 
this has an early
+  // stop if the arrays and offsets are the same as there is only one length.  
Also this can take
+  // advantage of chunking with longs, while compare cannot.
+  static boolean equals(
+      final BaseStateImpl state1, final long offsetBytes1,
+      final BaseStateImpl state2, final long offsetBytes2, long lengthBytes) {
+    state1.checkValid();
+    checkBounds(offsetBytes1, lengthBytes, state1.getCapacity());
+    state2.checkValid();
+    checkBounds(offsetBytes2, lengthBytes, state2.getCapacity());
+    long cumOff1 = state1.getCumulativeOffset(offsetBytes1);
+    long cumOff2 = state2.getCumulativeOffset(offsetBytes2);
+    final Object arr1 = state1.getUnsafeObject(); //could be null
+    final Object arr2 = state2.getUnsafeObject(); //could be null
+    if ((arr1 == arr2) && (cumOff1 == cumOff2)) { return true; }
+
+    while (lengthBytes >= Long.BYTES) {
+      final int chunk = (int) Math.min(lengthBytes, 
UNSAFE_COPY_THRESHOLD_BYTES);
+      // int-counted loop to avoid safepoint polls (otherwise why we chunk by
+      // UNSAFE_COPY_MEMORY_THRESHOLD)
+      int i = 0;
+      for (; i <= (chunk - Long.BYTES); i += Long.BYTES) {
+        final long v1 = unsafe.getLong(arr1, cumOff1 + i);
+        final long v2 = unsafe.getLong(arr2, cumOff2 + i);
+        if (v1 != v2) { return false; }
+      }
+      lengthBytes -= i;
+      cumOff1 += i;
+      cumOff2 += i;
+    }
+    //check the remainder bytes, if any
+    return (lengthBytes == 0) || equalsByBytes(arr1, cumOff1, arr2, cumOff2, 
(int) lengthBytes);
+  }
+
+  //use only for short runs
+  private static boolean equalsByBytes(final Object arr1, final long cumOff1, 
final Object arr2,
+      final long cumOff2, final int lenBytes) {
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lenBytes; i++) {
+      final int v1 = unsafe.getByte(arr1, cumOff1 + i);
+      final int v2 = unsafe.getByte(arr2, cumOff2 + i);
+      if (v1 != v2) { return false; }
+    }
+    return true;
+  }
+
+  static void copy(final BaseStateImpl srcState, final long srcOffsetBytes,
+      final BaseStateImpl dstState, final long dstOffsetBytes, final long 
lengthBytes) {
+    srcState.checkValid();
+    checkBounds(srcOffsetBytes, lengthBytes, srcState.getCapacity());
+    dstState.checkValid();
+    checkBounds(dstOffsetBytes, lengthBytes, dstState.getCapacity());
+    final long srcAdd = srcState.getCumulativeOffset(srcOffsetBytes);
+    final long dstAdd = dstState.getCumulativeOffset(dstOffsetBytes);
+    copyMemory(srcState.getUnsafeObject(), srcAdd, dstState.getUnsafeObject(), 
dstAdd,
+        lengthBytes);
+  }
+
+  //Used by all of the get/put array methods in BufferImpl and MemoryImpl 
classes
+  static final void copyMemoryCheckingDifferentObject(final Object 
srcUnsafeObj,
+      final long srcAdd, final Object dstUnsafeObj, final long dstAdd, final 
long lengthBytes) {
+    if (srcUnsafeObj != dstUnsafeObj) {
+      copyNonOverlappingMemoryWithChunking(srcUnsafeObj, srcAdd, dstUnsafeObj, 
dstAdd,
+          lengthBytes);
+    } else {
+      throw new IllegalArgumentException("Not expecting to copy to/from array 
which is the "
+          + "underlying object of the memory at the same time");
+    }
+  }
+
+  //only valid and bounds checks have been performed at this point
+  private static void copyMemory(final Object srcUnsafeObj, final long srcAdd,
+      final Object dstUnsafeObj, final long dstAdd, final long lengthBytes) {
+    if (srcUnsafeObj != dstUnsafeObj) {
+      //either srcArray != dstArray OR one of them is off-heap
+      copyNonOverlappingMemoryWithChunking(srcUnsafeObj, srcAdd, dstUnsafeObj, 
dstAdd,
+          lengthBytes);
+    } else { //either srcArray == dstArray OR both src and dst are off-heap
+      copyMemoryOverlapAddressCheck(srcUnsafeObj, srcAdd, dstUnsafeObj, 
dstAdd, lengthBytes);
+    }
+  }
+
+  /**
+   * At this point either srcArray == dstArray OR both src and dst are 
off-heap.
+   * Performs overlapping address check. If addresses do not overlap, proceed 
to
+   * {@link #copyNonOverlappingMemoryWithChunking(Object, long, Object, long, 
long)}; otherwise
+   * fall back on <i>Unsafe.copyMemory(...)</i> tolerating potentially long
+   * Time to Safe Point pauses.
+   * If srcAdd == dstAdd an exception will be thrown.
+   * @param srcUnsafeObj The source array object, it may be null.
+   * @param srcAdd The cumulative source offset
+   * @param dstUnsafeObj The destination array object, it may be null
+   * @param dstAdd The cumulative destination offset
+   * @param lengthBytes The length to be copied in bytes
+   */
+  private static void copyMemoryOverlapAddressCheck(final Object srcUnsafeObj, 
final long srcAdd,
+      final Object dstUnsafeObj, final long dstAdd, final long lengthBytes) {
+    if (((srcAdd + lengthBytes) <= dstAdd) || ((dstAdd + lengthBytes) <= 
srcAdd)) {
+      copyNonOverlappingMemoryWithChunking(srcUnsafeObj, srcAdd, dstUnsafeObj, 
dstAdd,
+          lengthBytes);
+      return;
+    }
+    if (srcAdd == dstAdd) {
+      throw new IllegalArgumentException(
+          "Attempt to copy a block of memory exactly in-place, should be a 
bug");
+    }
+    // If regions do overlap, fall back to unsafe.copyMemory, tolerating 
potentially long
+    // Time to Safe Point pauses.
+    unsafe.copyMemory(srcUnsafeObj, srcAdd, dstUnsafeObj, dstAdd, lengthBytes);
+  }
+
+  /**
+   * This copies only non-overlapping memory in chunks to avoid safepoint 
delays.
+   * Java 9 may not require the chunking.
+   * @param srcUnsafeObj The source array object, it may be null.
+   * @param srcAdd The cumulative source offset
+   * @param dstUnsafeObj The destination array object, it may be null
+   * @param dstAdd The cumulative destination offset
+   * @param lengthBytes The length to be copied in bytes
+   * @see #UNSAFE_COPY_THRESHOLD_BYTES
+   */
+  private static void copyNonOverlappingMemoryWithChunking(final Object 
srcUnsafeObj,
+      long srcAdd, final Object dstUnsafeObj, long dstAdd, long lengthBytes) {
+    while (lengthBytes > 0) {
+      final long chunk = Math.min(lengthBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      unsafe.copyMemory(srcUnsafeObj, srcAdd, dstUnsafeObj, dstAdd, chunk);
+      lengthBytes -= chunk;
+      srcAdd += chunk;
+      dstAdd += chunk;
+    }
+  }
+
+  static void getNonNativeChars(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final char[] dstArray, int dstOffsetChars,
+      int lengthChars) {
+    checkBounds(dstOffsetChars, lengthChars, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkChars = (int) (chunkBytes >> CHAR_SHIFT);
+      getCharArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetChars, 
chunkChars);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetChars += chunkChars;
+      copyBytes -= chunkBytes;
+      lengthChars -= chunkChars;
+    }
+    getCharArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetChars, 
lengthChars);
+  }
+
+  private static void getCharArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final char[] dstArray, final int dstOffsetChars, final int lengthChars) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthChars; i++) {
+      dstArray[dstOffsetChars + i] = Character.reverseBytes(
+          unsafe.getChar(unsafeObj, cumOffsetBytes + (((long) i) << 
CHAR_SHIFT)));
+    }
+  }
+
+  static void getNonNativeDoubles(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final double[] dstArray, int dstOffsetDoubles,
+      int lengthDoubles) {
+    checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkDoubles = (int) (chunkBytes >> DOUBLE_SHIFT);
+      getDoubleArrayChunk(unsafeObj, cumOffsetBytes,
+          dstArray, dstOffsetDoubles, chunkDoubles);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetDoubles += chunkDoubles;
+      copyBytes -= chunkBytes;
+      lengthDoubles -= chunkDoubles;
+    }
+    getDoubleArrayChunk(unsafeObj, cumOffsetBytes,
+        dstArray, dstOffsetDoubles, lengthDoubles);
+  }
+
+  private static void getDoubleArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final double[] dstArray, final int dstOffsetDoubles, final int 
lengthDoubles) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthDoubles; i++) {
+      dstArray[dstOffsetDoubles + i] = 
Double.longBitsToDouble(Long.reverseBytes(
+          unsafe.getLong(unsafeObj, cumOffsetBytes + (((long) i) << 
DOUBLE_SHIFT))));
+    }
+  }
+
+  static void getNonNativeFloats(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final float[] dstArray, int dstOffsetFloats,
+      int lengthFloats) {
+    checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkFloats = (int) (chunkBytes >> FLOAT_SHIFT);
+      getFloatArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetFloats, 
chunkFloats);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetFloats += chunkFloats;
+      copyBytes -= chunkBytes;
+      lengthFloats -= chunkFloats;
+    }
+    getFloatArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetFloats, 
lengthFloats);
+  }
+
+  private static void getFloatArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final float[] dstArray, final int dstOffsetFloats, final int 
lengthFloats) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthFloats; i++) {
+      dstArray[dstOffsetFloats + i] = 
Float.intBitsToFloat(Integer.reverseBytes(
+          unsafe.getInt(unsafeObj, cumOffsetBytes + (((long) i) << 
FLOAT_SHIFT))));
+    }
+  }
+
+  static void getNonNativeInts(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final int[] dstArray, int dstOffsetInts,
+      int lengthInts) {
+    checkBounds(dstOffsetInts, lengthInts, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkInts = (int) (chunkBytes >> INT_SHIFT);
+      getIntArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetInts, 
chunkInts);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetInts += chunkInts;
+      copyBytes -= chunkBytes;
+      lengthInts -= chunkInts;
+    }
+    getIntArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetInts, 
lengthInts);
+  }
+
+  private static void getIntArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final int[] dstArray, final int dstOffsetInts, final int lengthInts) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthInts; i++) {
+      dstArray[dstOffsetInts + i] = Integer.reverseBytes(
+          unsafe.getInt(unsafeObj, cumOffsetBytes + (((long) i) << 
INT_SHIFT)));
+    }
+  }
+
+  static void getNonNativeLongs(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final long[] dstArray, int dstOffsetLongs,
+      int lengthLongs) {
+    checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkLongs = (int) (chunkBytes >> LONG_SHIFT);
+      getLongArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetLongs, 
chunkLongs);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetLongs += chunkLongs;
+      copyBytes -= chunkBytes;
+      lengthLongs -= chunkLongs;
+    }
+    getLongArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetLongs, 
lengthLongs);
+  }
+
+  private static void getLongArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final long[] dstArray, final int dstOffsetLongs, final int lengthLongs) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthLongs; i++) {
+      dstArray[dstOffsetLongs + i] = Long.reverseBytes(
+          unsafe.getLong(unsafeObj, cumOffsetBytes + (((long) i) << 
LONG_SHIFT)));
+    }
+  }
+
+  static void getNonNativeShorts(final Object unsafeObj, long cumOffsetBytes,
+      long copyBytes, final short[] dstArray, int dstOffsetShorts,
+      int lengthShorts) {
+    checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkShorts = (int) (chunkBytes >> SHORT_SHIFT);
+      getShortArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetShorts, 
chunkShorts);
+      cumOffsetBytes += chunkBytes;
+      dstOffsetShorts += chunkShorts;
+      copyBytes -= chunkBytes;
+      lengthShorts -= chunkShorts;
+    }
+    getShortArrayChunk(unsafeObj, cumOffsetBytes, dstArray, dstOffsetShorts, 
lengthShorts);
+  }
+
+  private static void getShortArrayChunk(final Object unsafeObj, final long 
cumOffsetBytes,
+      final short[] dstArray, final int dstOffsetShorts, final int 
lengthShorts) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthShorts; i++) {
+      dstArray[dstOffsetShorts + i] = Short.reverseBytes(
+          unsafe.getShort(unsafeObj, cumOffsetBytes + (((long) i) << 
SHORT_SHIFT)));
+    }
+  }
+
+  static void putNonNativeChars(final char[] srcArray, int srcOffsetChars, int 
lengthChars,
+      long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
+    checkBounds(srcOffsetChars, lengthChars, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkChars = (int) (chunkBytes >> CHAR_SHIFT);
+      putCharArrayChunk(srcArray, srcOffsetChars, chunkChars, unsafeObj, 
cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetChars += chunkChars;
+      copyBytes -= chunkBytes;
+      lengthChars -= chunkChars;
+    }
+    putCharArrayChunk(srcArray, srcOffsetChars, lengthChars, unsafeObj, 
cumOffsetBytes);
+  }
+
+  private static void putCharArrayChunk(final char[] srcArray, final int 
srcOffsetChars,
+      final int lengthChars, final Object unsafeObj, final long 
cumOffsetBytes) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthChars; i++) {
+      unsafe.putChar(unsafeObj, cumOffsetBytes + (((long) i) << CHAR_SHIFT),
+          Character.reverseBytes(srcArray[srcOffsetChars + i]));
+    }
+  }
+
+  static void putNonNativeDoubles(final double[] srcArray, int 
srcOffsetDoubles,
+      int lengthDoubles, long copyBytes, final Object unsafeObj, long 
cumOffsetBytes) {
+    checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkDoubles = (int) (chunkBytes >> DOUBLE_SHIFT);
+      putDoubleArrayChunk(srcArray, srcOffsetDoubles, chunkDoubles,
+          unsafeObj, cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetDoubles += chunkDoubles;
+      copyBytes -= chunkBytes;
+      lengthDoubles -= chunkDoubles;
+    }
+    putDoubleArrayChunk(srcArray, srcOffsetDoubles, lengthDoubles,
+        unsafeObj, cumOffsetBytes);
+  }
+
+  private static void putDoubleArrayChunk(final double[] srcArray, final int 
srcOffsetDoubles,
+      final int lengthDoubles, final Object unsafeObj, final long 
cumOffsetBytes) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthDoubles; i++) {
+      unsafe.putLong(unsafeObj, cumOffsetBytes + (((long) i) << DOUBLE_SHIFT),
+          
Long.reverseBytes(Double.doubleToRawLongBits(srcArray[srcOffsetDoubles + i])));
+    }
+  }
+
+  static void putNonNativeFloats(final float[] srcArray, int srcOffsetFloats,
+      int lengthFloats, long copyBytes, final Object unsafeObj, long 
cumOffsetBytes) {
+    checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkFloats = (int) (chunkBytes >> FLOAT_SHIFT);
+      putFloatArrayChunk(srcArray, srcOffsetFloats, chunkFloats, unsafeObj, 
cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetFloats += chunkFloats;
+      copyBytes -= chunkBytes;
+      lengthFloats -= chunkFloats;
+    }
+    putFloatArrayChunk(srcArray, srcOffsetFloats, lengthFloats, unsafeObj, 
cumOffsetBytes);
+  }
+
+  private static void putFloatArrayChunk(final float[] srcArray, final int 
srcOffsetFloats,
+      final int lengthFloats, final Object unsafeObj, final long 
cumOffsetBytes) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthFloats; i++) {
+      unsafe.putInt(unsafeObj, cumOffsetBytes + (((long) i) << FLOAT_SHIFT),
+          
Integer.reverseBytes(Float.floatToRawIntBits(srcArray[srcOffsetFloats + i])));
+    }
+  }
+
+  static void putNonNativeInts(final int[] srcArray, int srcOffsetInts, int 
lengthInts,
+      long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
+    checkBounds(srcOffsetInts, lengthInts, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkInts = (int) (chunkBytes >> INT_SHIFT);
+      putIntArrayChunk(srcArray, srcOffsetInts, chunkInts, unsafeObj, 
cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetInts += chunkInts;
+      copyBytes -= chunkBytes;
+      lengthInts -= chunkInts;
+    }
+    putIntArrayChunk(srcArray, srcOffsetInts, lengthInts, unsafeObj, 
cumOffsetBytes);
+  }
+
+  private static void putIntArrayChunk(final int[] srcArray, final int 
srcOffsetInts,
+      final int lengthInts, final Object unsafeObj, final long cumOffsetBytes) 
{
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthInts; i++) {
+      unsafe.putInt(unsafeObj, cumOffsetBytes + (((long) i) << INT_SHIFT),
+          Integer.reverseBytes(srcArray[srcOffsetInts + i]));
+    }
+  }
+
+  static void putNonNativeLongs(final long[] srcArray, int srcOffsetLongs, int 
lengthLongs,
+      long copyBytes, final Object unsafeObj, long cumOffsetBytes) {
+    checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkLongs = (int) (chunkBytes >> LONG_SHIFT);
+      putLongArrayChunk(srcArray, srcOffsetLongs, chunkLongs, unsafeObj, 
cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetLongs += chunkLongs;
+      copyBytes -= chunkBytes;
+      lengthLongs -= chunkLongs;
+    }
+    putLongArrayChunk(srcArray, srcOffsetLongs, lengthLongs, unsafeObj, 
cumOffsetBytes);
+  }
+
+  private static void putLongArrayChunk(final long[] srcArray, final int 
srcOffsetLongs,
+      final int lengthLongs, final Object unsafeObj, final long 
cumOffsetBytes) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthLongs; i++) {
+      unsafe.putLong(unsafeObj, cumOffsetBytes + (((long) i) << LONG_SHIFT),
+          Long.reverseBytes(srcArray[srcOffsetLongs + i]));
+    }
+  }
+
+  static void putNonNativeShorts(final short[] srcArray, int srcOffsetShorts,
+      int lengthShorts, long copyBytes, final Object unsafeObj, long 
cumOffsetBytes) {
+    checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
+    while (copyBytes > UNSAFE_COPY_THRESHOLD_BYTES) {
+      final long chunkBytes = Math.min(copyBytes, UNSAFE_COPY_THRESHOLD_BYTES);
+      final int chunkShorts = (int) (chunkBytes >> SHORT_SHIFT);
+      putShortArrayChunk(srcArray, srcOffsetShorts, chunkShorts, unsafeObj, 
cumOffsetBytes);
+      cumOffsetBytes += chunkBytes;
+      srcOffsetShorts += chunkShorts;
+      copyBytes -= chunkBytes;
+      lengthShorts -= chunkShorts;
+    }
+    putShortArrayChunk(srcArray, srcOffsetShorts, lengthShorts, unsafeObj, 
cumOffsetBytes);
+  }
+
+  private static void putShortArrayChunk(final short[] srcArray, final int 
srcOffsetShorts,
+      final int lengthShorts, final Object unsafeObj, final long 
cumOffsetBytes) {
+    // JDK 9 adds native intrinsics for such bulk non-native ordered primitive 
memory copy.
+    // TODO-JDK9 use them when the library adds support for JDK 9
+    // int-counted loop to avoid safepoint polls
+    for (int i = 0; i < lengthShorts; i++) {
+      unsafe.putShort(unsafeObj, cumOffsetBytes + (((long) i) << SHORT_SHIFT),
+          Short.reverseBytes(srcArray[srcOffsetShorts + i]));
+    }
+  }
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/CompareAndCopy.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,106 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
+
+/**
+ * Implementation of {@link WritableBuffer} for direct memory, non-native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class DirectNonNativeWritableBufferImpl extends 
NonNativeWritableBufferImpl {
+  private static final int id = BUFFER | NONNATIVE | DIRECT;
+  private final long nativeBaseOffset; //used to compute cumBaseOffset
+  private final StepBoolean valid; //a reference only
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  DirectNonNativeWritableBufferImpl(
+      final long nativeBaseOffset,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final StepBoolean valid,
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
+    this.nativeBaseOffset = nativeBaseOffset;
+    this.valid = valid;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder 
byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    assertValid();
+    return memReqSvr;
+  }
+
+  @Override
+  long getNativeBaseOffset() {
+    return nativeBaseOffset;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  public boolean isValid() {
+    return valid.get();
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableBufferImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,96 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
+
+/**
+ * Implementation of {@link WritableMemory} for direct memory, non-native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class DirectNonNativeWritableMemoryImpl extends 
NonNativeWritableMemoryImpl {
+  private static final int id = MEMORY | NONNATIVE | DIRECT;
+  private final long nativeBaseOffset; //used to compute cumBaseOffset
+  private final StepBoolean valid; //a reference only
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  DirectNonNativeWritableMemoryImpl(
+      final long nativeBaseOffset,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final StepBoolean valid,
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
+    this.nativeBaseOffset = nativeBaseOffset;
+    this.valid = valid;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    assertValid();
+    return memReqSvr;
+  }
+
+  @Override
+  long getNativeBaseOffset() {
+    return nativeBaseOffset;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  public boolean isValid() {
+    return valid.get();
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectNonNativeWritableMemoryImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,106 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
+
+/**
+ * Implementation of {@link WritableBuffer} for direct memory, native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class DirectWritableBufferImpl extends NativeWritableBufferImpl {
+  private static final int id = BUFFER | NATIVE | DIRECT;
+  private final long nativeBaseOffset; //used to compute cumBaseOffset
+  private final StepBoolean valid; //a reference only
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  DirectWritableBufferImpl(
+      final long nativeBaseOffset,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final StepBoolean valid,
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
+    this.nativeBaseOffset = nativeBaseOffset;
+    this.valid = valid;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder 
byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    assertValid();
+    return memReqSvr;
+  }
+
+  @Override
+  long getNativeBaseOffset() {
+    return nativeBaseOffset;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  public boolean isValid() {
+    return valid.get();
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableBufferImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,96 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
+
+/**
+ * Implementation of {@link WritableMemory} for direct memory, native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class DirectWritableMemoryImpl extends NativeWritableMemoryImpl {
+  private static final int id = MEMORY | NATIVE | DIRECT;
+  private final long nativeBaseOffset; //used to compute cumBaseOffset
+  private final StepBoolean valid; //a reference only
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  DirectWritableMemoryImpl(
+      final long nativeBaseOffset,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final StepBoolean valid,
+      final MemoryRequestServer memReqSvr) {
+    super(null, nativeBaseOffset, regionOffset, capacityBytes);
+    this.nativeBaseOffset = nativeBaseOffset;
+    this.valid = valid;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr)
+        : new DirectNonNativeWritableMemoryImpl(
+            nativeBaseOffset, getRegionOffset(offsetBytes), capacityBytes, 
type, valid, memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new DirectWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr)
+        : new DirectNonNativeWritableBufferImpl(
+            nativeBaseOffset, getRegionOffset(), getCapacity(), type, valid, 
memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    assertValid();
+    return memReqSvr;
+  }
+
+  @Override
+  long getNativeBaseOffset() {
+    return nativeBaseOffset;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  public boolean isValid() {
+    return valid.get();
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/DirectWritableMemoryImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,97 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
+
+/**
+ * Implementation of {@link WritableBuffer} for heap-based, non-native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class HeapNonNativeWritableBufferImpl extends 
NonNativeWritableBufferImpl {
+  private static final int id = BUFFER | NONNATIVE | HEAP;
+  private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  HeapNonNativeWritableBufferImpl(
+      final Object unsafeObj,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
+    this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder 
byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    return memReqSvr;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  Object getUnsafeObject() {
+    return unsafeObj;
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableBufferImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,87 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
+
+/**
+ * Implementation of {@link WritableMemory} for heap-based, non-native byte 
order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class HeapNonNativeWritableMemoryImpl extends 
NonNativeWritableMemoryImpl {
+  private static final int id = MEMORY | NONNATIVE | HEAP;
+  private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  HeapNonNativeWritableMemoryImpl(
+      final Object unsafeObj,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
+    this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    return memReqSvr;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  Object getUnsafeObject() {
+    return unsafeObj;
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapNonNativeWritableMemoryImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,97 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableBuffer;
+
+/**
+ * Implementation of {@link WritableBuffer} for heap-based, native byte order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class HeapWritableBufferImpl extends NativeWritableBufferImpl {
+  private static final int id = BUFFER | NATIVE | HEAP;
+  private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  HeapWritableBufferImpl(
+      final Object unsafeObj,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
+    this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toDuplicate(final boolean readOnly, final ByteOrder 
byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | DUPLICATE;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableMemory(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    return memReqSvr;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  Object getUnsafeObject() {
+    return unsafeObj;
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableBufferImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,87 @@
+/*
+ * 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.internal;
+
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableMemory;
+
+/**
+ * Implementation of {@link WritableMemory} for heap-based, native byte order.
+ *
+ * @author Roman Leventov
+ * @author Lee Rhodes
+ */
+final class HeapWritableMemoryImpl extends NativeWritableMemoryImpl {
+  private static final int id = MEMORY | NATIVE | HEAP;
+  private final Object unsafeObj;
+  private final MemoryRequestServer memReqSvr;
+  private final byte typeId;
+
+  HeapWritableMemoryImpl(
+      final Object unsafeObj,
+      final long regionOffset,
+      final long capacityBytes,
+      final int typeId,
+      final MemoryRequestServer memReqSvr) {
+    super(unsafeObj, 0L, regionOffset, capacityBytes);
+    this.unsafeObj = unsafeObj;
+    this.memReqSvr = memReqSvr;
+    this.typeId = (byte) (id | (typeId & 0x7));
+  }
+
+  @Override
+  BaseWritableMemoryImpl toWritableRegion(final long offsetBytes, final long 
capacityBytes,
+      final boolean readOnly, final ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly) | REGION;
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableMemoryImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr)
+        : new HeapNonNativeWritableMemoryImpl(
+            unsafeObj, getRegionOffset(offsetBytes), capacityBytes, type, 
memReqSvr);
+  }
+
+  @Override
+  BaseWritableBufferImpl toWritableBuffer(final boolean readOnly, final 
ByteOrder byteOrder) {
+    final int type = setReadOnlyType(typeId, readOnly);
+    return Util.isNativeByteOrder(byteOrder)
+        ? new HeapWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr)
+        : new HeapNonNativeWritableBufferImpl(
+            unsafeObj, getRegionOffset(), getCapacity(), type, memReqSvr);
+  }
+
+  @Override
+  public MemoryRequestServer getMemoryRequestServer() {
+    return memReqSvr;
+  }
+
+  @Override
+  int getTypeId() {
+    return typeId & 0xff;
+  }
+
+  @Override
+  Object getUnsafeObject() {
+    return unsafeObj;
+  }
+
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/HeapWritableMemoryImpl.java
------------------------------------------------------------------------------
    svn:executable = *

Added: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Ints.java
==============================================================================
--- 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Ints.java
 (added)
+++ 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Ints.java
 Tue May 21 21:11:49 2024
@@ -0,0 +1,39 @@
+/*
+ * 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.internal;
+
+/** Equivalent of Guava's Ints. */
+public final class Ints {
+
+  private Ints() {}
+
+  /**
+   * Checks if a cast of a long to an int is within the range of an int
+   * @param v the given long
+   * @return returns the cast int, or throws an exception that the long was 
out-of-range of an int.
+   */
+  public static int checkedCast(final long v) {
+    final int result = (int) v;
+    if (result != v) {
+      throw new IllegalArgumentException("Out of range: " + v);
+    }
+    return result;
+  }
+}

Propchange: 
dev/datasketches/memory/2.2.0-RC1/apache-datasketches-memory-2.2.0-src/datasketches-memory-java8/src/main/java/org/apache/datasketches/memory/internal/Ints.java
------------------------------------------------------------------------------
    svn:executable = *



---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]


Reply via email to