You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by le...@apache.org on 2021/05/18 19:57:12 UTC
[datasketches-memory] 05/08: Interim. Completed refactoring of
Memory Hierarch.
This is an automated email from the ASF dual-hosted git repository.
leerho pushed a commit to branch CreateInternal2
in repository https://gitbox.apache.org/repos/asf/datasketches-memory.git
commit 16511d00e97cbf60301c642787330a51f63d7b05
Author: Lee Rhodes <le...@users.noreply.github.com>
AuthorDate: Mon May 17 16:47:22 2021 -0700
Interim. Completed refactoring of Memory Hierarch.
Buffer hierarchy is not done. Many Errors in Test. Main compiles clean,
no warnings.
---
.../internal/{Memory.java => MemoryImpl.java} | 0
...moryImpl.java => NativeWritableMemoryImpl.java} | 0
.../memory/internal/WritableMemory.java | 666 ----------------
.../memory/internal/WritableMemoryImpl.java | 855 ++++++++++++++-------
4 files changed, 596 insertions(+), 925 deletions(-)
diff --git a/src/main/java/org/apache/datasketches/memory/internal/Memory.java b/src/main/java/org/apache/datasketches/memory/internal/MemoryImpl.java
similarity index 100%
rename from src/main/java/org/apache/datasketches/memory/internal/Memory.java
rename to src/main/java/org/apache/datasketches/memory/internal/MemoryImpl.java
diff --git a/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java b/src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
similarity index 100%
copy from src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
copy to src/main/java/org/apache/datasketches/memory/internal/NativeWritableMemoryImpl.java
diff --git a/src/main/java/org/apache/datasketches/memory/internal/WritableMemory.java b/src/main/java/org/apache/datasketches/memory/internal/WritableMemory.java
deleted file mode 100644
index 85b8875..0000000
--- a/src/main/java/org/apache/datasketches/memory/internal/WritableMemory.java
+++ /dev/null
@@ -1,666 +0,0 @@
-/*
- * 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.Util.negativeCheck;
-import static org.apache.datasketches.memory.internal.Util.nullCheck;
-import static org.apache.datasketches.memory.internal.Util.zeroCheck;
-
-import java.io.File;
-import java.io.IOException;
-import java.nio.ByteBuffer;
-import java.nio.ByteOrder;
-
-import org.apache.datasketches.memory.DefaultMemoryRequestServer;
-import org.apache.datasketches.memory.Handle;
-import org.apache.datasketches.memory.MemoryRequestServer;
-import org.apache.datasketches.memory.WritableHandle;
-import org.apache.datasketches.memory.WritableMapHandle;
-import org.apache.datasketches.memory.WritableDirectHandle;
-
-
-/**
- * Provides read and write primitive and primitive array access to any of the four resources
- * mentioned at the package level.
- *
- * @author Roman Leventov
- * @author Lee Rhodes
- */
-public abstract class WritableMemory extends Memory {
-
- //Pass-through ctor
- WritableMemory(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
- final long capacityBytes) {
- super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
- }
-
- //BYTE BUFFER
- /**
- * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
- * the same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is
- * zero, then byte order of the returned WritableMemory object, as well as backing storage and
- * read-only status are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param byteBuf the given ByteBuffer
- * @return a new WritableMemory for write operations on the given ByteBuffer.
- */
- public static WritableMemory writableWrap(final ByteBuffer byteBuf) {
- return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteBuf.order());
- }
-
- /**
- * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
- * the given byte order, ignoring the byte order of the given ByteBuffer. If the capacity of
- * the given ByteBuffer is zero the byte order of the returned WritableMemory object
- * (as well as backing storage) is unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param byteBuf the given ByteBuffer, must not be null
- * @param byteOrder the byte order to be used, which may be independent of the byte order
- * state of the given ByteBuffer
- * @return a new WritableMemory for write operations on the given ByteBuffer.
- */
- public static WritableMemory writableWrap(final ByteBuffer byteBuf, final ByteOrder byteOrder) {
- return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteOrder);
- }
-
- //MAP
- /**
- * Maps the entire given file into native-ordered WritableMemory for write operations
- * (including those > 2GB). Calling this method is equivalent to calling
- * {@link #writableMap(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.map(...)</i>.
- * @param file the given file to map
- * @return WritableMapHandle for managing the mapped Memory.
- * Please read Javadocs for {@link Handle}.
- * @throws IOException file not found or a RuntimeException.
- */
- public static WritableMapHandle writableMap(final File file) throws IOException {
- return WritableMemory.writableMap(file, 0, file.length(), Util.nativeByteOrder);
- }
-
- /**
- * Maps the specified portion of the given file into Memory for write operations
- * (including those > 2GB).
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.map(...)</i>.
- * @param file the given file to map. It may not be null.
- * @param fileOffsetBytes the position in the given file in bytes. It may not be negative.
- * @param capacityBytes the size of the mapped Memory. It may not be negative or zero.
- * @param byteOrder the byte order to be used for the given file. It may not be null.
- * @return WritableMapHandleImpl for managing the mapped Memory.
- * Please read Javadocs for {@link Handle}.
- * @throws IOException file not found or RuntimeException, etc.
- */
- public static WritableMapHandle writableMap(final File file, final long fileOffsetBytes,
- final long capacityBytes, final ByteOrder byteOrder) throws IOException {
- zeroCheck(capacityBytes, "Capacity");
- nullCheck(file, "file is null");
- negativeCheck(fileOffsetBytes, "File offset is negative");
- return BaseWritableMemoryImpl
- .wrapMap(file, fileOffsetBytes, capacityBytes, false, byteOrder);
- }
-
- //ALLOCATE DIRECT
- /**
- * Allocates and provides access to capacityBytes directly in native (off-heap) memory
- * leveraging the WritableMemory API. Native byte order is assumed.
- * The allocated memory will be 8-byte aligned, but may not be page aligned.
- * If capacityBytes is zero, byte order, backing storage and read-only status
- * of the WritableMemory object, returned from {@link WritableHandle#get()} are unspecified.
- *
- * <p>The default MemoryRequestServer, which allocates any request for memory onto the heap,
- * will be used.</p>
- *
- * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
- * It is the responsibility of the using class to clear this memory, if required,
- * and to call <i>close()</i> when done.</p>
- *
- * @param capacityBytes the size of the desired memory in bytes.
- * @return WritableDirectHandleImpl for this off-heap resource.
- * Please read Javadocs for {@link Handle}.
- */
- public static WritableDirectHandle allocateDirect(final long capacityBytes) {
- return allocateDirect(capacityBytes, null);
- }
-
- /**
- * Allocates and provides access to capacityBytes directly in native (off-heap) memory
- * leveraging the WritableMemory API. The allocated memory will be 8-byte aligned, but may not
- * be page aligned. If capacityBytes is zero, byte order, backing storage and read-only status
- * of the WritableMemory object, returned from {@link WritableHandle#get()} are unspecified.
- *
- * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
- * It is the responsibility of the using class to clear this memory, if required,
- * and to call <i>close()</i> when done.</p>
- *
- * @param capacityBytes the size of the desired memory in bytes.
- * @param memReqSvr A user-specified MemoryRequestServer.
- * This is a callback mechanism for a user client of direct memory to request more memory.
- * @return WritableHandle for this off-heap resource.
- * Please read Javadocs for {@link Handle}.
- */
- public static WritableDirectHandle allocateDirect(final long capacityBytes,
- final MemoryRequestServer memReqSvr) {
- return BaseWritableMemoryImpl.wrapDirect(capacityBytes, Util.nativeByteOrder, memReqSvr);
- }
-
- //REGIONS
- /**
- * A writable region is a writable view of this object.
- * This returns a new <i>WritableMemory</i> representing the defined writable region with the
- * given offsetBytes and capacityBytes.
- * <ul>
- * <li>Returned object's origin = this objects' origin + <i>offsetBytes</i></li>
- * <li>Returned object's capacity = <i>capacityBytes</i></li>
- * </ul>
- * If the given capacityBytes is zero, the returned object is effectively immutable and
- * the backing storage and byte order are unspecified.
- *
- * @param offsetBytes the starting offset with respect to this object.
- * @param capacityBytes the capacity of the returned object in bytes.
- * @return a new <i>WritableMemory</i> representing the defined writable region.
- */
- public abstract WritableMemory writableRegion(long offsetBytes, long capacityBytes);
-
- /**
- * A writable region is a writable view of this object.
- * This returns a new <i>WritableMemory</i> representing the defined writable region with the
- * given offsetBytes, capacityBytes and byte order.
- * <ul>
- * <li>Returned object's origin = this objects' 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>
- * If the given capacityBytes is zero, the returned object is effectively immutable and
- * the backing storage and byte order are unspecified.
- *
- * @param offsetBytes the starting offset with respect to this object.
- * @param capacityBytes the capacity of the returned object in bytes.
- * @param byteOrder the given byte order
- * @return a new <i>WritableMemory</i> representing the defined writable region.
- */
- public abstract WritableMemory writableRegion(long offsetBytes, long capacityBytes,
- ByteOrder byteOrder);
-
- //AS BUFFER
- /**
- * Returns a new <i>WritableBuffer</i> with a writable 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>
- * If this object's capacity is zero, the returned object is effectively immutable and
- * the backing storage and byte order are unspecified.
- * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
- */
- public abstract WritableBuffer asWritableBuffer();
-
- /**
- * Returns a new <i>WritableBuffer</i> with a writable 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>
- * 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 given byte order
- * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
- */
- public abstract WritableBuffer asWritableBuffer(ByteOrder byteOrder);
-
- //ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
- /**
- * Creates on-heap WritableMemory with the given capacity and the native byte order. If the given
- * capacityBytes is zero, backing storage, byte order and read-only status of the returned
- * WritableMemory object are unspecified.
- * @param capacityBytes the given capacity in bytes.
- * @return a new WritableMemory for write operations on a new byte array.
- */
- public static WritableMemory allocate(final int capacityBytes) {
- final byte[] arr = new byte[capacityBytes];
- return writableWrap(arr, Util.nativeByteOrder);
- }
-
- /**
- * Creates on-heap WritableMemory with the given capacity and the given byte order. If the given
- * capacityBytes is zero, backing storage, byte order and read-only status of the returned
- * WritableMemory object are unspecified.
- * @param capacityBytes the given capacity in bytes.
- * @param byteOrder the given byte order to allocate new Memory object with.
- * @return a new WritableMemory for write operations on a new byte array.
- */
- public static WritableMemory allocate(final int capacityBytes, final ByteOrder byteOrder) {
- final byte[] arr = new byte[capacityBytes];
- return writableWrap(arr, byteOrder);
- }
-
- //ACCESS PRIMITIVE HEAP ARRAYS for write
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final boolean[] arr) {
- final long lengthBytes = arr.length << Prim.BOOLEAN.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final byte[] arr) {
- return WritableMemory.writableWrap(arr, 0, arr.length, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations with the given byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @param byteOrder the byte order to be used
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final byte[] arr, final ByteOrder byteOrder) {
- return WritableMemory.writableWrap(arr, 0, arr.length, byteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations with the given byte order. If the given
- * lengthBytes is zero, backing storage, byte order and read-only status of the returned
- * WritableMemory object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr 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 WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final byte[] arr, final int offsetBytes, final int lengthBytes,
- final ByteOrder byteOrder) {
- UnsafeUtil.checkBounds(offsetBytes, lengthBytes, arr.length);
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, byteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final char[] arr) {
- final long lengthBytes = arr.length << Prim.CHAR.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final short[] arr) {
- final long lengthBytes = arr.length << Prim.SHORT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final int[] arr) {
- final long lengthBytes = arr.length << Prim.INT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final long[] arr) {
- final long lengthBytes = arr.length << Prim.LONG.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final float[] arr) {
- final long lengthBytes = arr.length << Prim.FLOAT.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
-
- /**
- * Wraps the given primitive array for write operations assuming native byte order. If the array
- * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
- * object are unspecified.
- *
- * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
- * <i>WritableMemory.wrap(...)</i>.
- * @param arr the given primitive array.
- * @return a new WritableMemory for write operations on the given primitive array.
- */
- public static WritableMemory writableWrap(final double[] arr) {
- final long lengthBytes = arr.length << Prim.DOUBLE.shift();
- return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
- }
- //END OF CONSTRUCTOR-TYPE METHODS
-
- //PRIMITIVE putX() and putXArray()
- /**
- * Puts the boolean value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putBoolean(long offsetBytes, boolean value);
-
- /**
- * Puts the boolean array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetBooleans offset in array units
- * @param lengthBooleans number of array units to transfer
- */
- public abstract void putBooleanArray(long offsetBytes, boolean[] srcArray, int srcOffsetBooleans,
- int lengthBooleans);
-
- /**
- * Puts the byte value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putByte(long offsetBytes, byte value);
-
- /**
- * Puts the byte array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetBytes offset in array units
- * @param lengthBytes number of array units to transfer
- */
- public abstract void putByteArray(long offsetBytes, byte[] srcArray, int srcOffsetBytes,
- int lengthBytes);
-
- /**
- * Puts the char value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putChar(long offsetBytes, char value);
-
- /**
- * Puts the char array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetChars offset in array units
- * @param lengthChars number of array units to transfer
- */
- public abstract void putCharArray(long offsetBytes, char[] srcArray, int srcOffsetChars,
- int lengthChars);
-
- /**
- * Encodes characters from the given CharSequence into UTF-8 bytes and puts them into this
- * <i>WritableMemory</i> begining at the given offsetBytes.
- * 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 this <i>WritableMemory</i> start
- * @param src The source CharSequence to be encoded and put into this WritableMemory. It is
- * the responsibility of the caller to provide sufficient capacity in this
- * <i>WritableMemory</i> for the encoded Utf8 bytes. Characters outside the ASCII range can
- * require 2, 3 or 4 bytes per character to encode.
- * @return the number of bytes encoded
- */
- public abstract long putCharsToUtf8(long offsetBytes, CharSequence src);
-
- /**
- * Puts the double value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putDouble(long offsetBytes, double value);
-
- /**
- * Puts the double array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetDoubles offset in array units
- * @param lengthDoubles number of array units to transfer
- */
- public abstract void putDoubleArray(long offsetBytes, double[] srcArray,
- final int srcOffsetDoubles, final int lengthDoubles);
-
- /**
- * Puts the float value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putFloat(long offsetBytes, float value);
-
- /**
- * Puts the float array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetFloats offset in array units
- * @param lengthFloats number of array units to transfer
- */
- public abstract void putFloatArray(long offsetBytes, float[] srcArray,
- final int srcOffsetFloats, final int lengthFloats);
-
- /**
- * Puts the int value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putInt(long offsetBytes, int value);
-
- /**
- * Puts the int array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetInts offset in array units
- * @param lengthInts number of array units to transfer
- */
- public abstract void putIntArray(long offsetBytes, int[] srcArray,
- final int srcOffsetInts, final int lengthInts);
-
- /**
- * Puts the long value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putLong(long offsetBytes, long value);
-
- /**
- * Puts the long array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetLongs offset in array units
- * @param lengthLongs number of array units to transfer
- */
- public abstract void putLongArray(long offsetBytes, long[] srcArray,
- final int srcOffsetLongs, final int lengthLongs);
-
- /**
- * Puts the short value at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param value the value to put
- */
- public abstract void putShort(long offsetBytes, short value);
-
- /**
- * Puts the short array at the given offset
- * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
- * @param srcArray The source array.
- * @param srcOffsetShorts offset in array units
- * @param lengthShorts number of array units to transfer
- */
- public abstract void putShortArray(long offsetBytes, short[] srcArray,
- final int srcOffsetShorts, final int lengthShorts);
-
- //Atomic Methods
- /**
- * Atomically adds the given value to the long located at offsetBytes.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param delta the amount to add
- * @return the the previous value
- */
- public abstract long getAndAddLong(long offsetBytes, long delta);
-
- /**
- * Atomically sets the current value at the memory location to the given updated value
- * if and only if the current value {@code ==} the expected value.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param expect the expected value
- * @param update the new value
- * @return {@code true} if successful. False return indicates that
- * the current value at the memory location was not equal to the expected value.
- */
- public abstract boolean compareAndSwapLong(long offsetBytes, long expect, long update);
-
- /**
- * Atomically exchanges the given value with the current value located at offsetBytes.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param newValue new value
- * @return the previous value
- */
- public abstract long getAndSetLong(long offsetBytes, long newValue);
-
- //OTHER WRITE METHODS
- /**
- * Returns the primitive backing array, otherwise null.
- * @return the primitive backing array, otherwise null.
- */
- public abstract Object getArray();
-
- /**
- * Clears all bytes of this Memory to zero
- */
- public abstract void clear();
-
- /**
- * Clears a portion of this Memory to zero.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param lengthBytes the length in bytes
- */
- public abstract void clear(long offsetBytes, long lengthBytes);
-
- /**
- * Clears the bits defined by the bitMask
- * @param offsetBytes offset bytes relative to this Memory start.
- * @param bitMask the bits set to one will be cleared
- */
- public abstract void clearBits(long offsetBytes, byte bitMask);
-
- /**
- * Fills all bytes of this Memory region to the given byte value.
- * @param value the given byte value
- */
- public abstract void fill(byte value);
-
- /**
- * Fills a portion of this Memory region to the given byte value.
- * @param offsetBytes offset bytes relative to this Memory start
- * @param lengthBytes the length in bytes
- * @param value the given byte value
- */
- public abstract void fill(long offsetBytes, long lengthBytes, byte value);
-
- /**
- * Sets the bits defined by the bitMask
- * @param offsetBytes offset bytes relative to this Memory start
- * @param bitMask the bits set to one will be set
- */
- public abstract void setBits(long offsetBytes, byte bitMask);
-
-
- //OTHER WRITABLE API METHODS
- /**
- * For Direct Memory only. Other types of backing resources will return null.
- * Gets the MemoryRequestServer object used by dynamic off-heap (Direct) memory objects
- * to request additional memory.
- * Set using {@link WritableMemory#allocateDirect(long, MemoryRequestServer)}.
- * If not explicity set, this returns the {@link DefaultMemoryRequestServer}.
- * @return the MemoryRequestServer object (if direct memory) or null.
- */
- @Override
- public MemoryRequestServer getMemoryRequestServer() {
- return null;
- }
-
-}
diff --git a/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java b/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
index 7c416b0..85b8875 100644
--- a/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
+++ b/src/main/java/org/apache/datasketches/memory/internal/WritableMemoryImpl.java
@@ -19,311 +19,648 @@
package org.apache.datasketches.memory.internal;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_CHAR_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_DOUBLE_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_DOUBLE_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_FLOAT_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_FLOAT_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_INT_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_BASE_OFFSET;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
-import static org.apache.datasketches.memory.internal.UnsafeUtil.ARRAY_SHORT_BASE_OFFSET;
-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.negativeCheck;
+import static org.apache.datasketches.memory.internal.Util.nullCheck;
+import static org.apache.datasketches.memory.internal.Util.zeroCheck;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.nio.ByteOrder;
+
+import org.apache.datasketches.memory.DefaultMemoryRequestServer;
+import org.apache.datasketches.memory.Handle;
+import org.apache.datasketches.memory.MemoryRequestServer;
+import org.apache.datasketches.memory.WritableHandle;
+import org.apache.datasketches.memory.WritableMapHandle;
+import org.apache.datasketches.memory.WritableDirectHandle;
-/*
- * 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.
- */
/**
- * Implementation of {@link WritableMemory} for native endian byte order. Non-native variant is
- * {@link NonNativeWritableMemoryImpl}.
+ * Provides read and write primitive and primitive array access to any of the four resources
+ * mentioned at the package level.
+ *
* @author Roman Leventov
* @author Lee Rhodes
*/
-@SuppressWarnings({"restriction"})
-abstract class WritableMemoryImpl extends BaseWritableMemoryImpl {
+public abstract class WritableMemory extends Memory {
//Pass-through ctor
- WritableMemoryImpl(final Object unsafeObj, final long nativeBaseOffset,
- final long regionOffset, final long capacityBytes) {
+ WritableMemory(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
+ final long capacityBytes) {
super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
}
- ///PRIMITIVE getX() and getXArray()
- @Override
- public char getChar(final long offsetBytes) {
- return getNativeOrderedChar(offsetBytes);
- }
-
- @Override
- public void getCharArray(final long offsetBytes, final char[] dstArray, final int dstOffsetChars,
- final int lengthChars) {
- final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetChars, lengthChars, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_CHAR_BASE_OFFSET + (((long) dstOffsetChars) << CHAR_SHIFT),
- copyBytes);
- }
-
- @Override
- public double getDouble(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
- return unsafe.getDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes));
- }
-
- @Override
- public void getDoubleArray(final long offsetBytes, final double[] dstArray,
- final int dstOffsetDoubles, final int lengthDoubles) {
- final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetDoubles, lengthDoubles, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_DOUBLE_BASE_OFFSET + (((long) dstOffsetDoubles) << DOUBLE_SHIFT),
- copyBytes);
- }
-
- @Override
- public float getFloat(final long offsetBytes) {
- assertValidAndBoundsForRead(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
- return unsafe.getFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes));
- }
-
- @Override
- public void getFloatArray(final long offsetBytes, final float[] dstArray,
- final int dstOffsetFloats, final int lengthFloats) {
- final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetFloats, lengthFloats, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_FLOAT_BASE_OFFSET + (((long) dstOffsetFloats) << FLOAT_SHIFT),
- copyBytes);
- }
-
- @Override
- public int getInt(final long offsetBytes) {
- return getNativeOrderedInt(offsetBytes);
- }
-
- @Override
- public void getIntArray(final long offsetBytes, final int[] dstArray, final int dstOffsetInts,
- final int lengthInts) {
- final long copyBytes = ((long) lengthInts) << INT_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetInts, lengthInts, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_INT_BASE_OFFSET + (((long) dstOffsetInts) << INT_SHIFT),
- copyBytes);
+ //BYTE BUFFER
+ /**
+ * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
+ * the same byte order, as the given ByteBuffer, unless the capacity of the given ByteBuffer is
+ * zero, then byte order of the returned WritableMemory object, as well as backing storage and
+ * read-only status are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param byteBuf the given ByteBuffer
+ * @return a new WritableMemory for write operations on the given ByteBuffer.
+ */
+ public static WritableMemory writableWrap(final ByteBuffer byteBuf) {
+ return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteBuf.order());
}
- @Override
- public long getLong(final long offsetBytes) {
- return getNativeOrderedLong(offsetBytes);
+ /**
+ * Accesses the given ByteBuffer for write operations. The returned WritableMemory object has
+ * the given byte order, ignoring the byte order of the given ByteBuffer. If the capacity of
+ * the given ByteBuffer is zero the byte order of the returned WritableMemory object
+ * (as well as backing storage) is unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param byteBuf the given ByteBuffer, must not be null
+ * @param byteOrder the byte order to be used, which may be independent of the byte order
+ * state of the given ByteBuffer
+ * @return a new WritableMemory for write operations on the given ByteBuffer.
+ */
+ public static WritableMemory writableWrap(final ByteBuffer byteBuf, final ByteOrder byteOrder) {
+ return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, false, byteOrder);
}
- @Override
- public void getLongArray(final long offsetBytes, final long[] dstArray,
- final int dstOffsetLongs, final int lengthLongs) {
- final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetLongs, lengthLongs, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_LONG_BASE_OFFSET + (((long) dstOffsetLongs) << LONG_SHIFT),
- copyBytes);
+ //MAP
+ /**
+ * Maps the entire given file into native-ordered WritableMemory for write operations
+ * (including those > 2GB). Calling this method is equivalent to calling
+ * {@link #writableMap(File, long, long, ByteOrder) map(file, 0, file.length(), ByteOrder.nativeOrder())}.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.map(...)</i>.
+ * @param file the given file to map
+ * @return WritableMapHandle for managing the mapped Memory.
+ * Please read Javadocs for {@link Handle}.
+ * @throws IOException file not found or a RuntimeException.
+ */
+ public static WritableMapHandle writableMap(final File file) throws IOException {
+ return WritableMemory.writableMap(file, 0, file.length(), Util.nativeByteOrder);
}
- @Override
- public short getShort(final long offsetBytes) {
- return getNativeOrderedShort(offsetBytes);
+ /**
+ * Maps the specified portion of the given file into Memory for write operations
+ * (including those > 2GB).
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.map(...)</i>.
+ * @param file the given file to map. It may not be null.
+ * @param fileOffsetBytes the position in the given file in bytes. It may not be negative.
+ * @param capacityBytes the size of the mapped Memory. It may not be negative or zero.
+ * @param byteOrder the byte order to be used for the given file. It may not be null.
+ * @return WritableMapHandleImpl for managing the mapped Memory.
+ * Please read Javadocs for {@link Handle}.
+ * @throws IOException file not found or RuntimeException, etc.
+ */
+ public static WritableMapHandle writableMap(final File file, final long fileOffsetBytes,
+ final long capacityBytes, final ByteOrder byteOrder) throws IOException {
+ zeroCheck(capacityBytes, "Capacity");
+ nullCheck(file, "file is null");
+ negativeCheck(fileOffsetBytes, "File offset is negative");
+ return BaseWritableMemoryImpl
+ .wrapMap(file, fileOffsetBytes, capacityBytes, false, byteOrder);
}
- @Override
- public void getShortArray(final long offsetBytes, final short[] dstArray,
- final int dstOffsetShorts, final int lengthShorts) {
- final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
- checkValidAndBounds(offsetBytes, copyBytes);
- checkBounds(dstOffsetShorts, lengthShorts, dstArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- dstArray,
- ARRAY_SHORT_BASE_OFFSET + (((long) dstOffsetShorts) << SHORT_SHIFT),
- copyBytes);
+ //ALLOCATE DIRECT
+ /**
+ * Allocates and provides access to capacityBytes directly in native (off-heap) memory
+ * leveraging the WritableMemory API. Native byte order is assumed.
+ * The allocated memory will be 8-byte aligned, but may not be page aligned.
+ * If capacityBytes is zero, byte order, backing storage and read-only status
+ * of the WritableMemory object, returned from {@link WritableHandle#get()} are unspecified.
+ *
+ * <p>The default MemoryRequestServer, which allocates any request for memory onto the heap,
+ * will be used.</p>
+ *
+ * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
+ * It is the responsibility of the using class to clear this memory, if required,
+ * and to call <i>close()</i> when done.</p>
+ *
+ * @param capacityBytes the size of the desired memory in bytes.
+ * @return WritableDirectHandleImpl for this off-heap resource.
+ * Please read Javadocs for {@link Handle}.
+ */
+ public static WritableDirectHandle allocateDirect(final long capacityBytes) {
+ return allocateDirect(capacityBytes, null);
}
- //PRIMITIVE putX() and putXArray() implementations
- @Override
- public void putChar(final long offsetBytes, final char value) {
- putNativeOrderedChar(offsetBytes, value);
+ /**
+ * Allocates and provides access to capacityBytes directly in native (off-heap) memory
+ * leveraging the WritableMemory API. The allocated memory will be 8-byte aligned, but may not
+ * be page aligned. If capacityBytes is zero, byte order, backing storage and read-only status
+ * of the WritableMemory object, returned from {@link WritableHandle#get()} are unspecified.
+ *
+ * <p><b>NOTE:</b> Native/Direct memory acquired using Unsafe may have garbage in it.
+ * It is the responsibility of the using class to clear this memory, if required,
+ * and to call <i>close()</i> when done.</p>
+ *
+ * @param capacityBytes the size of the desired memory in bytes.
+ * @param memReqSvr A user-specified MemoryRequestServer.
+ * This is a callback mechanism for a user client of direct memory to request more memory.
+ * @return WritableHandle for this off-heap resource.
+ * Please read Javadocs for {@link Handle}.
+ */
+ public static WritableDirectHandle allocateDirect(final long capacityBytes,
+ final MemoryRequestServer memReqSvr) {
+ return BaseWritableMemoryImpl.wrapDirect(capacityBytes, Util.nativeByteOrder, memReqSvr);
}
- @Override
- public void putCharArray(final long offsetBytes, final char[] srcArray,
- final int srcOffsetChars, final int lengthChars) {
- final long copyBytes = ((long) lengthChars) << CHAR_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetChars, lengthChars, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_CHAR_BASE_OFFSET + (((long) srcOffsetChars) << CHAR_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ //REGIONS
+ /**
+ * A writable region is a writable view of this object.
+ * This returns a new <i>WritableMemory</i> representing the defined writable region with the
+ * given offsetBytes and capacityBytes.
+ * <ul>
+ * <li>Returned object's origin = this objects' origin + <i>offsetBytes</i></li>
+ * <li>Returned object's capacity = <i>capacityBytes</i></li>
+ * </ul>
+ * If the given capacityBytes is zero, the returned object is effectively immutable and
+ * the backing storage and byte order are unspecified.
+ *
+ * @param offsetBytes the starting offset with respect to this object.
+ * @param capacityBytes the capacity of the returned object in bytes.
+ * @return a new <i>WritableMemory</i> representing the defined writable region.
+ */
+ public abstract WritableMemory writableRegion(long offsetBytes, long capacityBytes);
+
+ /**
+ * A writable region is a writable view of this object.
+ * This returns a new <i>WritableMemory</i> representing the defined writable region with the
+ * given offsetBytes, capacityBytes and byte order.
+ * <ul>
+ * <li>Returned object's origin = this objects' 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>
+ * If the given capacityBytes is zero, the returned object is effectively immutable and
+ * the backing storage and byte order are unspecified.
+ *
+ * @param offsetBytes the starting offset with respect to this object.
+ * @param capacityBytes the capacity of the returned object in bytes.
+ * @param byteOrder the given byte order
+ * @return a new <i>WritableMemory</i> representing the defined writable region.
+ */
+ public abstract WritableMemory writableRegion(long offsetBytes, long capacityBytes,
+ ByteOrder byteOrder);
+
+ //AS BUFFER
+ /**
+ * Returns a new <i>WritableBuffer</i> with a writable 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>
+ * If this object's capacity is zero, the returned object is effectively immutable and
+ * the backing storage and byte order are unspecified.
+ * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
+ */
+ public abstract WritableBuffer asWritableBuffer();
+
+ /**
+ * Returns a new <i>WritableBuffer</i> with a writable 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>
+ * 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 given byte order
+ * @return a new <i>WritableBuffer</i> with a view of this WritableMemory
+ */
+ public abstract WritableBuffer asWritableBuffer(ByteOrder byteOrder);
+
+ //ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
+ /**
+ * Creates on-heap WritableMemory with the given capacity and the native byte order. If the given
+ * capacityBytes is zero, backing storage, byte order and read-only status of the returned
+ * WritableMemory object are unspecified.
+ * @param capacityBytes the given capacity in bytes.
+ * @return a new WritableMemory for write operations on a new byte array.
+ */
+ public static WritableMemory allocate(final int capacityBytes) {
+ final byte[] arr = new byte[capacityBytes];
+ return writableWrap(arr, Util.nativeByteOrder);
}
- @Override
- public void putDouble(final long offsetBytes, final double value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE);
- unsafe.putDouble(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+ /**
+ * Creates on-heap WritableMemory with the given capacity and the given byte order. If the given
+ * capacityBytes is zero, backing storage, byte order and read-only status of the returned
+ * WritableMemory object are unspecified.
+ * @param capacityBytes the given capacity in bytes.
+ * @param byteOrder the given byte order to allocate new Memory object with.
+ * @return a new WritableMemory for write operations on a new byte array.
+ */
+ public static WritableMemory allocate(final int capacityBytes, final ByteOrder byteOrder) {
+ final byte[] arr = new byte[capacityBytes];
+ return writableWrap(arr, byteOrder);
}
- @Override
- public void putDoubleArray(final long offsetBytes, final double[] srcArray,
- final int srcOffsetDoubles, final int lengthDoubles) {
- final long copyBytes = ((long) lengthDoubles) << DOUBLE_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetDoubles, lengthDoubles, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_DOUBLE_BASE_OFFSET + (((long) srcOffsetDoubles) << DOUBLE_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ //ACCESS PRIMITIVE HEAP ARRAYS for write
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final boolean[] arr) {
+ final long lengthBytes = arr.length << Prim.BOOLEAN.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- @Override
- public void putFloat(final long offsetBytes, final float value) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_FLOAT_INDEX_SCALE);
- unsafe.putFloat(getUnsafeObject(), getCumulativeOffset(offsetBytes), value);
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final byte[] arr) {
+ return WritableMemory.writableWrap(arr, 0, arr.length, Util.nativeByteOrder);
}
- @Override
- public void putFloatArray(final long offsetBytes, final float[] srcArray,
- final int srcOffsetFloats, final int lengthFloats) {
- final long copyBytes = ((long) lengthFloats) << FLOAT_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetFloats, lengthFloats, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_FLOAT_BASE_OFFSET + (((long) srcOffsetFloats) << FLOAT_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ /**
+ * Wraps the given primitive array for write operations with the given byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @param byteOrder the byte order to be used
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final byte[] arr, final ByteOrder byteOrder) {
+ return WritableMemory.writableWrap(arr, 0, arr.length, byteOrder);
}
- @Override
- public void putInt(final long offsetBytes, final int value) {
- putNativeOrderedInt(offsetBytes, value);
- }
-
- @Override
- public void putIntArray(final long offsetBytes, final int[] srcArray, final int srcOffsetInts,
- final int lengthInts) {
- final long copyBytes = ((long) lengthInts) << INT_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetInts, lengthInts, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_INT_BASE_OFFSET + (((long) srcOffsetInts) << INT_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ /**
+ * Wraps the given primitive array for write operations with the given byte order. If the given
+ * lengthBytes is zero, backing storage, byte order and read-only status of the returned
+ * WritableMemory object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr 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 WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final byte[] arr, final int offsetBytes, final int lengthBytes,
+ final ByteOrder byteOrder) {
+ UnsafeUtil.checkBounds(offsetBytes, lengthBytes, arr.length);
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, byteOrder);
}
- @Override
- public void putLong(final long offsetBytes, final long value) {
- putNativeOrderedLong(offsetBytes, value);
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final char[] arr) {
+ final long lengthBytes = arr.length << Prim.CHAR.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- @Override
- public void putLongArray(final long offsetBytes, final long[] srcArray, final int srcOffsetLongs,
- final int lengthLongs) {
- final long copyBytes = ((long) lengthLongs) << LONG_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetLongs, lengthLongs, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_LONG_BASE_OFFSET + (((long) srcOffsetLongs) << LONG_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final short[] arr) {
+ final long lengthBytes = arr.length << Prim.SHORT.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- @Override
- public void putShort(final long offsetBytes, final short value) {
- putNativeOrderedShort(offsetBytes, value);
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final int[] arr) {
+ final long lengthBytes = arr.length << Prim.INT.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- @Override
- public void putShortArray(final long offsetBytes, final short[] srcArray,
- final int srcOffsetShorts, final int lengthShorts) {
- final long copyBytes = ((long) lengthShorts) << SHORT_SHIFT;
- checkValidAndBoundsForWrite(offsetBytes, copyBytes);
- checkBounds(srcOffsetShorts, lengthShorts, srcArray.length);
- CompareAndCopy.copyMemoryCheckingDifferentObject(
- srcArray,
- ARRAY_SHORT_BASE_OFFSET + (((long) srcOffsetShorts) << SHORT_SHIFT),
- getUnsafeObject(),
- getCumulativeOffset(offsetBytes),
- copyBytes
- );
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final long[] arr) {
+ final long lengthBytes = arr.length << Prim.LONG.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- //Atomic Write Methods
- @Override
- public long getAndAddLong(final long offsetBytes, final long delta) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- return unsafe.getAndAddLong(getUnsafeObject(), addr, delta);
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final float[] arr) {
+ final long lengthBytes = arr.length << Prim.FLOAT.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
- @Override
- public long getAndSetLong(final long offsetBytes, final long newValue) { //JDK 8+
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- final long addr = getCumulativeOffset(offsetBytes);
- return unsafe.getAndSetLong(getUnsafeObject(), addr, newValue);
+ /**
+ * Wraps the given primitive array for write operations assuming native byte order. If the array
+ * size is zero, backing storage, byte order and read-only status of the returned WritableMemory
+ * object are unspecified.
+ *
+ * <p><b>Note:</b> Always qualify this method with the class name, e.g.,
+ * <i>WritableMemory.wrap(...)</i>.
+ * @param arr the given primitive array.
+ * @return a new WritableMemory for write operations on the given primitive array.
+ */
+ public static WritableMemory writableWrap(final double[] arr) {
+ final long lengthBytes = arr.length << Prim.DOUBLE.shift();
+ return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, false, Util.nativeByteOrder);
}
-
+ //END OF CONSTRUCTOR-TYPE METHODS
+
+ //PRIMITIVE putX() and putXArray()
+ /**
+ * Puts the boolean value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putBoolean(long offsetBytes, boolean value);
+
+ /**
+ * Puts the boolean array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetBooleans offset in array units
+ * @param lengthBooleans number of array units to transfer
+ */
+ public abstract void putBooleanArray(long offsetBytes, boolean[] srcArray, int srcOffsetBooleans,
+ int lengthBooleans);
+
+ /**
+ * Puts the byte value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putByte(long offsetBytes, byte value);
+
+ /**
+ * Puts the byte array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetBytes offset in array units
+ * @param lengthBytes number of array units to transfer
+ */
+ public abstract void putByteArray(long offsetBytes, byte[] srcArray, int srcOffsetBytes,
+ int lengthBytes);
+
+ /**
+ * Puts the char value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putChar(long offsetBytes, char value);
+
+ /**
+ * Puts the char array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetChars offset in array units
+ * @param lengthChars number of array units to transfer
+ */
+ public abstract void putCharArray(long offsetBytes, char[] srcArray, int srcOffsetChars,
+ int lengthChars);
+
+ /**
+ * Encodes characters from the given CharSequence into UTF-8 bytes and puts them into this
+ * <i>WritableMemory</i> begining at the given offsetBytes.
+ * 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 this <i>WritableMemory</i> start
+ * @param src The source CharSequence to be encoded and put into this WritableMemory. It is
+ * the responsibility of the caller to provide sufficient capacity in this
+ * <i>WritableMemory</i> for the encoded Utf8 bytes. Characters outside the ASCII range can
+ * require 2, 3 or 4 bytes per character to encode.
+ * @return the number of bytes encoded
+ */
+ public abstract long putCharsToUtf8(long offsetBytes, CharSequence src);
+
+ /**
+ * Puts the double value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putDouble(long offsetBytes, double value);
+
+ /**
+ * Puts the double array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetDoubles offset in array units
+ * @param lengthDoubles number of array units to transfer
+ */
+ public abstract void putDoubleArray(long offsetBytes, double[] srcArray,
+ final int srcOffsetDoubles, final int lengthDoubles);
+
+ /**
+ * Puts the float value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putFloat(long offsetBytes, float value);
+
+ /**
+ * Puts the float array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetFloats offset in array units
+ * @param lengthFloats number of array units to transfer
+ */
+ public abstract void putFloatArray(long offsetBytes, float[] srcArray,
+ final int srcOffsetFloats, final int lengthFloats);
+
+ /**
+ * Puts the int value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putInt(long offsetBytes, int value);
+
+ /**
+ * Puts the int array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetInts offset in array units
+ * @param lengthInts number of array units to transfer
+ */
+ public abstract void putIntArray(long offsetBytes, int[] srcArray,
+ final int srcOffsetInts, final int lengthInts);
+
+ /**
+ * Puts the long value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putLong(long offsetBytes, long value);
+
+ /**
+ * Puts the long array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetLongs offset in array units
+ * @param lengthLongs number of array units to transfer
+ */
+ public abstract void putLongArray(long offsetBytes, long[] srcArray,
+ final int srcOffsetLongs, final int lengthLongs);
+
+ /**
+ * Puts the short value at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param value the value to put
+ */
+ public abstract void putShort(long offsetBytes, short value);
+
+ /**
+ * Puts the short array at the given offset
+ * @param offsetBytes offset bytes relative to this <i>WritableMemory</i> start
+ * @param srcArray The source array.
+ * @param srcOffsetShorts offset in array units
+ * @param lengthShorts number of array units to transfer
+ */
+ public abstract void putShortArray(long offsetBytes, short[] srcArray,
+ final int srcOffsetShorts, final int lengthShorts);
+
+ //Atomic Methods
+ /**
+ * Atomically adds the given value to the long located at offsetBytes.
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param delta the amount to add
+ * @return the the previous value
+ */
+ public abstract long getAndAddLong(long offsetBytes, long delta);
+
+ /**
+ * Atomically sets the current value at the memory location to the given updated value
+ * if and only if the current value {@code ==} the expected value.
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param expect the expected value
+ * @param update the new value
+ * @return {@code true} if successful. False return indicates that
+ * the current value at the memory location was not equal to the expected value.
+ */
+ public abstract boolean compareAndSwapLong(long offsetBytes, long expect, long update);
+
+ /**
+ * Atomically exchanges the given value with the current value located at offsetBytes.
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param newValue new value
+ * @return the previous value
+ */
+ public abstract long getAndSetLong(long offsetBytes, long newValue);
+
+ //OTHER WRITE METHODS
+ /**
+ * Returns the primitive backing array, otherwise null.
+ * @return the primitive backing array, otherwise null.
+ */
+ public abstract Object getArray();
+
+ /**
+ * Clears all bytes of this Memory to zero
+ */
+ public abstract void clear();
+
+ /**
+ * Clears a portion of this Memory to zero.
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param lengthBytes the length in bytes
+ */
+ public abstract void clear(long offsetBytes, long lengthBytes);
+
+ /**
+ * Clears the bits defined by the bitMask
+ * @param offsetBytes offset bytes relative to this Memory start.
+ * @param bitMask the bits set to one will be cleared
+ */
+ public abstract void clearBits(long offsetBytes, byte bitMask);
+
+ /**
+ * Fills all bytes of this Memory region to the given byte value.
+ * @param value the given byte value
+ */
+ public abstract void fill(byte value);
+
+ /**
+ * Fills a portion of this Memory region to the given byte value.
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param lengthBytes the length in bytes
+ * @param value the given byte value
+ */
+ public abstract void fill(long offsetBytes, long lengthBytes, byte value);
+
+ /**
+ * Sets the bits defined by the bitMask
+ * @param offsetBytes offset bytes relative to this Memory start
+ * @param bitMask the bits set to one will be set
+ */
+ public abstract void setBits(long offsetBytes, byte bitMask);
+
+
+ //OTHER WRITABLE API METHODS
+ /**
+ * For Direct Memory only. Other types of backing resources will return null.
+ * Gets the MemoryRequestServer object used by dynamic off-heap (Direct) memory objects
+ * to request additional memory.
+ * Set using {@link WritableMemory#allocateDirect(long, MemoryRequestServer)}.
+ * If not explicity set, this returns the {@link DefaultMemoryRequestServer}.
+ * @return the MemoryRequestServer object (if direct memory) or null.
+ */
@Override
- public boolean compareAndSwapLong(final long offsetBytes, final long expect, final long update) {
- assertValidAndBoundsForWrite(offsetBytes, ARRAY_LONG_INDEX_SCALE);
- return unsafe.compareAndSwapLong(
- getUnsafeObject(), getCumulativeOffset(offsetBytes), expect, update);
+ public MemoryRequestServer getMemoryRequestServer() {
+ return null;
}
-
+
}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org