blob: 1641a397a5f9378ad98b806f529a5dc5be87e7ab [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.datasketches.memory;
import static org.apache.datasketches.memory.internal.Util.negativeCheck;
import static org.apache.datasketches.memory.internal.Util.zeroCheck;
import java.io.File;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.util.Objects;
import org.apache.datasketches.memory.internal.BaseWritableMemoryImpl;
import org.apache.datasketches.memory.internal.Prim;
import org.apache.datasketches.memory.internal.UnsafeUtil;
/**
* Defines the writable API for offset access to a resource.
*
* @author Lee Rhodes
*/
public interface WritableMemory extends Memory {
//BYTE BUFFER
/**
* Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
* the same byte order, as the given <i>ByteBuffer</i>.
* @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity &ge; 0, and writable.
* @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
*/
static WritableMemory writableWrap(ByteBuffer byteBuffer) {
return writableWrap(byteBuffer, byteBuffer.order(), defaultMemReqSvr);
}
/**
* Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
* the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future writes and following reads.
* However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
* @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity &ge; 0, and writable.
* @param byteOrder the byte order to be used. It must be non-null.
* @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
*/
static WritableMemory writableWrap(ByteBuffer byteBuffer, ByteOrder byteOrder) {
return writableWrap(byteBuffer, byteOrder, defaultMemReqSvr);
}
/**
* Accesses the given <i>ByteBuffer</i> for write operations. The returned <i>WritableMemory</i> object has
* the given byte order, ignoring the byte order of the given <i>ByteBuffer</i> for future reads and writes.
* However, this does not change the byte order of data already in the <i>ByteBuffer</i>.
* @param byteBuffer the given <i>ByteBuffer</i>. It must be non-null, with capacity &ge; 0, and writable.
* @param byteOrder the byte order to be used. It must be non-null.
* @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
* This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
* @return a new <i>WritableMemory</i> for write operations on the given <i>ByteBuffer</i>.
*/
static WritableMemory writableWrap(ByteBuffer byteBuffer, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
Objects.requireNonNull(byteBuffer, "byteBuffer must be non-null");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
negativeCheck(byteBuffer.capacity(), "byteBuffer.capacity()");
if (byteBuffer.isReadOnly()) { throw new ReadOnlyException("byteBuffer must be writable."); }
return BaseWritableMemoryImpl.wrapByteBuffer(byteBuffer, false, byteOrder, memReqSvr);
}
//MAP
/**
* Maps the entire given file into native-ordered WritableMemory for write operations
* Calling this method is equivalent to calling
* {@link #writableMap(File, long, long, ByteOrder) writableMap(file, 0, file.length(), ByteOrder.nativeOrder())}.
* @param file the given file to map. It must be non-null, with length &ge; 0, and writable.
* @return WritableMapHandle for managing the mapped Memory.
* Please read Javadocs for {@link Handle}.
*/
static WritableMapHandle writableMap(File file) {
return writableMap(file, 0, file.length(), ByteOrder.nativeOrder());
}
/**
* Maps the specified portion of the given file into Memory for write operations.
*
* <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 must be non-null, writable and length &ge; 0.
* @param fileOffsetBytes the position in the given file in bytes. It must not be negative.
* @param capacityBytes the size of the mapped Memory. It must be &ge; 0.
* @param byteOrder the byte order to be used for the given file. It must be non-null.
* @return WritableMapHandle for managing the mapped Memory.
* Please read Javadocs for {@link Handle}.
*/
static WritableMapHandle writableMap(File file, long fileOffsetBytes, long capacityBytes, ByteOrder byteOrder) {
Objects.requireNonNull(file, "file must be non-null.");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null.");
if (!file.canWrite()) { throw new ReadOnlyException("file must be writable."); }
negativeCheck(file.length(), "file.length()");
negativeCheck(fileOffsetBytes, "fileOffsetBytes");
negativeCheck(capacityBytes, "capacityBytes");
return BaseWritableMemoryImpl.wrapMap(file, fileOffsetBytes, capacityBytes, false, byteOrder);
}
//ALLOCATE DIRECT
/**
* Allocates and provides access to capacityBytes directly in native (off-heap) memory.
* Native byte order is assumed.
* The allocated memory will be 8-byte aligned, but may not be page aligned.
*
* <p><b>NOTE:</b> Native/Direct memory acquired may have garbage in it.
* It is the responsibility of the using application 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. It must be &gt; 0.
* @return WritableHandle for this off-heap resource.
* Please read Javadocs for {@link Handle}.
*/
static WritableHandle allocateDirect(long capacityBytes) {
return allocateDirect(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
}
/**
* Allocates and provides access to capacityBytes directly in native (off-heap) memory.
* The allocated memory will be 8-byte aligned, but may not be page aligned.
*
* <p><b>NOTE:</b> Native/Direct memory acquired may have garbage in it.
* It is the responsibility of the using application 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. It must be &gt; 0.
* @param byteOrder the given byte order. It must be non-null.
* @param memReqSvr A user-specified MemoryRequestServer, which may be null.
* 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}.
*/
static WritableHandle allocateDirect(long capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
zeroCheck(capacityBytes, "capacityBytes");
return BaseWritableMemoryImpl.wrapDirect(capacityBytes, byteOrder, 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>
*
* @param offsetBytes the starting offset with respect to this object. It must be &ge; 0.
* @param capacityBytes the capacity of the returned object in bytes. It must be &gt; 0.
* @return a new <i>WritableMemory</i> representing the defined writable region.
*/
default WritableMemory writableRegion(long offsetBytes, long capacityBytes) {
return writableRegion(offsetBytes, capacityBytes, getTypeByteOrder());
}
/**
* 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>
*
* @param offsetBytes the starting offset with respect to this object. It must be &ge; 0.
* @param capacityBytes the capacity of the returned object in bytes. It must be &gt; 0.
* @param byteOrder the given byte order. It must be non-null.
* @return a new <i>WritableMemory</i> representing the defined writable region.
*/
WritableMemory writableRegion(long offsetBytes, long capacityBytes, ByteOrder byteOrder);
//AS WRITABLE 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>
* @return a new <i>WritableBuffer</i> with a view of this WritableMemory
*/
default WritableBuffer asWritableBuffer() {
return asWritableBuffer(getTypeByteOrder());
}
/**
* 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>
* @param byteOrder the given byte order
* @return a new <i>WritableBuffer</i> with a view of this WritableMemory
*/
WritableBuffer asWritableBuffer(ByteOrder byteOrder);
//ALLOCATE HEAP VIA AUTOMATIC BYTE ARRAY
/**
* Creates on-heap WritableMemory with the given capacity and the native byte order.
* @param capacityBytes the given capacity in bytes. It must be &ge; 0.
* @return a new WritableMemory for write operations on a new byte array.
*/
static WritableMemory allocate(int capacityBytes) {
return allocate(capacityBytes, ByteOrder.nativeOrder(), defaultMemReqSvr);
}
/**
* Creates on-heap WritableMemory with the given capacity and the given byte order.
* @param capacityBytes the given capacity in bytes. It must be &ge; 0.
* @param byteOrder the given byte order to allocate new Memory object with. It must be non-null.
* @return a new WritableMemory for write operations on a new byte array.
*/
static WritableMemory allocate(int capacityBytes, ByteOrder byteOrder) {
return allocate(capacityBytes, byteOrder, defaultMemReqSvr);
}
/**
* Creates on-heap WritableMemory with the given capacity and the given byte order.
* @param capacityBytes the given capacity in bytes. It must be &ge; 0.
* @param byteOrder the given byte order to allocate new Memory object with. It must be non-null.
* @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
* This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
* @return a new WritableMemory for write operations on a new byte array.
*/
static WritableMemory allocate(int capacityBytes, ByteOrder byteOrder, MemoryRequestServer memReqSvr) {
final byte[] arr = new byte[capacityBytes];
negativeCheck(capacityBytes, "capacityBytes");
return writableWrap(arr, 0, capacityBytes, byteOrder, memReqSvr);
}
//ACCESS PRIMITIVE HEAP ARRAYS for WRITE
/**
* Wraps the given primitive array for write operations assuming native byte order.
*
* <p><b>Note:</b> Always qualify this method with the class name, e.g.,
* <i>WritableMemory.wrap(...)</i>.
* @param array the given primitive array. It must be non-null, with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(byte[] array) {
return writableWrap(array, 0, array.length, ByteOrder.nativeOrder(), defaultMemReqSvr);
}
/**
* Wraps the given primitive array for write operations with the given byte order.
*
* <p><b>Note:</b> Always qualify this method with the class name, e.g.,
* <i>WritableMemory.wrap(...)</i>.
* @param array the given primitive array. It must be non-null, with length &ge; 0
* @param byteOrder the byte order to be used. It must be non-null.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(byte[] array, ByteOrder byteOrder) {
return writableWrap(array, 0, array.length, byteOrder, defaultMemReqSvr);
}
/**
* Wraps the given primitive array for write operations with the given byte order.
*
* <p><b>Note:</b> Always qualify this method with the class name, e.g.,
* <i>WritableMemory.wrap(...)</i>.
* @param array the given primitive array. It must be non-null.
* @param offsetBytes the byte offset into the given array. It must be &ge; 0.
* @param lengthBytes the number of bytes to include from the given array. It must be &ge; 0.
* @param byteOrder the byte order to be used. It must be non-null.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder) {
return writableWrap(array, offsetBytes, lengthBytes, byteOrder, defaultMemReqSvr);
}
/**
* 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 array the given primitive array. It must be non-null.
* @param offsetBytes the byte offset into the given array. It must be &ge; 0.
* @param lengthBytes the number of bytes to include from the given array. It must be &ge; 0.
* @param byteOrder the byte order to be used. It must be non-null.
* @param memReqSvr A user-specified <i>MemoryRequestServer</i>, which may be null.
* This is a callback mechanism for a user client to request a larger <i>WritableMemory</i>.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(byte[] array, int offsetBytes, int lengthBytes, ByteOrder byteOrder,
MemoryRequestServer memReqSvr) {
Objects.requireNonNull(array, "array must be non-null");
Objects.requireNonNull(byteOrder, "byteOrder must be non-null");
negativeCheck(offsetBytes, "offsetBytes");
negativeCheck(lengthBytes, "lengthBytes");
UnsafeUtil.checkBounds(offsetBytes, lengthBytes, array.length);
return BaseWritableMemoryImpl.wrapHeapArray(array, offsetBytes, lengthBytes, false, byteOrder, memReqSvr);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(boolean[] array) {
Objects.requireNonNull(array, "array must be non-null");
final long lengthBytes = array.length << Prim.BOOLEAN.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(char[] array) {
Objects.requireNonNull(array, "array must be non-null");
final long lengthBytes = array.length << Prim.CHAR.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(short[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.SHORT.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(int[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.INT.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(long[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.LONG.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(float[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.FLOAT.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
/**
* Wraps the given primitive array for write operations assuming native byte order.
* @param array the given primitive array. It must be non-null with length &ge; 0.
* @return a new WritableMemory for write operations on the given primitive array.
*/
static WritableMemory writableWrap(double[] array) {
Objects.requireNonNull(array, "arr must be non-null");
final long lengthBytes = array.length << Prim.DOUBLE.shift();
return BaseWritableMemoryImpl.wrapHeapArray(array, 0L, lengthBytes, false, ByteOrder.nativeOrder(), null);
}
//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
*/
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
*/
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
*/
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
*/
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
*/
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
*/
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> beginning 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
*/
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
*/
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
*/
void putDoubleArray(long offsetBytes, double[] srcArray, int srcOffsetDoubles, 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
*/
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
*/
void putFloatArray(long offsetBytes, float[] srcArray, int srcOffsetFloats, 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
*/
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
*/
void putIntArray(long offsetBytes, int[] srcArray, int srcOffsetInts, 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
*/
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
*/
void putLongArray(long offsetBytes, long[] srcArray, int srcOffsetLongs, 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
*/
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
*/
void putShortArray(long offsetBytes, short[] srcArray, int srcOffsetShorts, 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
*/
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.
*/
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
*/
long getAndSetLong(long offsetBytes, long newValue);
//OTHER WRITE METHODS
/**
* Returns the primitive backing array, otherwise null.
* @return the primitive backing array, otherwise null.
*/
Object getArray();
/**
* Clears all bytes of this Memory to zero
*/
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
*/
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
*/
void clearBits(long offsetBytes, byte bitMask);
/**
* Fills all bytes of this Memory region to the given byte value.
* @param value the given byte value
*/
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
*/
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
*/
void setBits(long offsetBytes, byte bitMask);
//OTHER WRITABLE API METHODS
/**
* WritableMemory enables this for ByteBuffer, Heap and Direct Memory backed resources.
* Map backed resources will always return null.
* Gets the MemoryRequestServer object, if set, for the above resources to request additional memory.
* The user must customize the actions of the MemoryRequestServer by
* implementing the MemoryRequestServer interface and set using one of these methods:
* <ul><li>{@link WritableMemory#allocateDirect(long, ByteOrder, MemoryRequestServer)}</li>
* <li>{@link WritableMemory#allocate(int, ByteOrder, MemoryRequestServer)}</li>
* <li>{@link WritableMemory#writableWrap(ByteBuffer, ByteOrder, MemoryRequestServer)}</li>
* </ul>
* Simple implementation examples include the DefaultMemoryRequestServer in the main tree, as well as
* the ExampleMemoryRequestServerTest and the use with ByteBuffer documented in the DruidIssue11544Test
* in the test tree.
* @return the MemoryRequestServer object or null.
*/
MemoryRequestServer getMemoryRequestServer();
}