All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.yahoo.memory.Memory Maven / Gradle / Ivy

/*
 * Copyright 2017, Yahoo! Inc. Licensed under the terms of the
 * Apache License 2.0. See LICENSE file at the project root for terms.
 */

package com.yahoo.memory;

import static com.yahoo.memory.Util.nativeOrder;
import static com.yahoo.memory.Util.negativeCheck;
import static com.yahoo.memory.Util.nullCheck;
import static com.yahoo.memory.Util.zeroCheck;

import java.io.File;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.channels.WritableByteChannel;

/**
 * Provides read-only primitive and primitive array methods to any of the four resources
 * mentioned in the package level documentation.
 *
 * @author Roman Leventov
 * @author Lee Rhodes
 *
 * @see com.yahoo.memory
 */
public abstract class Memory extends BaseState {

  //Pass-through ctor
  Memory(final Object unsafeObj, final long nativeBaseOffset, final long regionOffset,
      final long capacityBytes) {
    super(unsafeObj, nativeBaseOffset, regionOffset, capacityBytes);
  }

  //BYTE BUFFER
  /**
   * Accesses the given ByteBuffer for read-only operations. The returned Memory 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 Memory object (as well as backing storage) is
   * unspecified.
   *
   * 

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param byteBuf the given ByteBuffer, must not be null * @return a new Memory for read-only operations on the given ByteBuffer. */ public static Memory wrap(final ByteBuffer byteBuf) { return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, true, byteBuf.order()); } /** * Accesses the given ByteBuffer for read-only operations. The returned Memory 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 Memory object (as well as backing * storage) is unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param byteBuf the given ByteBuffer, must not be null * @param byteOrder the byte order to be used, whicn may be independent of the byte order * state of the given ByteBuffer. * @return a new Memory for read-only operations on the given ByteBuffer. */ public static Memory wrap(final ByteBuffer byteBuf, final ByteOrder byteOrder) { return BaseWritableMemoryImpl.wrapByteBuffer(byteBuf, true, byteOrder); } //MAP /** * Maps the entire given file into native-ordered Memory for read operations * (including those > 2GB). * Calling this method is equivalent to calling {@link #map(File, long, long, ByteOrder) * map(file, 0, file.length(), ByteOrder.nativeOrder())}. * *

Note: Always qualify this method with the class name, e.g., * Memory.map(...). * @param file the given file to map * @return MapHandle for managing the mapped Memory * @throws IOException if file not found or a RuntimeException. */ public static MapHandle map(final File file) throws IOException { return map(file, 0, file.length(), ByteOrder.nativeOrder()); } /** * Maps the specified portion of the given file into Memory for read operations * (including those > 2GB). * *

Note: Always qualify this method with the class name, e.g., * Memory.map(...). * @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 mapped Memory. It may not be null. * @return MapHandle for managing the mapped Memory * @throws IOException if file not found or a RuntimeException. */ public static MapHandle map(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, true, byteOrder); } //REGIONS /** * A region is a read-only view of this object. *

    *
  • Returned object's origin = this object's origin + offsetBytes
  • *
  • Returned object's capacity = capacityBytes
  • *
* 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 the origin of this Memory. * @param capacityBytes the capacity of the region in bytes * @return a new Memory representing the defined region based on the given * offsetBytes and capacityBytes. */ public abstract Memory region(long offsetBytes, long capacityBytes); /** * A region is a read-only view of this object. *
    *
  • Returned object's origin = this object's origin + offsetBytes
  • *
  • Returned object's capacity = capacityBytes
  • *
  • Returned object's byte order = byteOrder
  • *
* 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 the origin of this Memory. * @param capacityBytes the capacity of the region in bytes * @param byteOrder the given byte order * @return a new Memory representing the defined region based on the given * offsetBytes, capacityBytes and byteOrder. */ public abstract Memory region(long offsetBytes, long capacityBytes, ByteOrder byteOrder); //AS BUFFER /** * Returns a new Buffer view of this object. *
    *
  • Returned object's origin = this object's origin
  • *
  • Returned object's start = 0
  • *
  • Returned object's position = 0
  • *
  • Returned object's end = this object's capacity
  • *
  • Returned object's capacity = this object's capacity
  • *
  • Returned object's start, position and end are mutable
  • *
* 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 Buffer */ public abstract Buffer asBuffer(); /** * Returns a new Buffer view of this object, with the given * byte order. *
    *
  • Returned object's origin = this object's origin
  • *
  • Returned object's start = 0
  • *
  • Returned object's position = 0
  • *
  • Returned object's end = this object's capacity
  • *
  • Returned object's capacity = this object's capacity
  • *
  • Returned object's start, position and end are mutable
  • *
* 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 Buffer with the given byteOrder. */ public abstract Buffer asBuffer(ByteOrder byteOrder); //UNSAFE BYTE BUFFER VIEW /** * Returns the specified region of this Memory object as a new read-only {@link ByteBuffer} * object. The {@link ByteOrder} of the returned {@code ByteBuffer} corresponds to the {@linkplain * #getByteOrder() byte order of this Memory}. The returned ByteBuffer's position is 0 and * the limit is equal to the capacity. * *

If this Memory object is the result of wrapping non-byte Java arrays ({@link * Memory#wrap(int[])}, {@link Memory#wrap(long[])}, etc.) this methods throws an {@link * UnsupportedOperationException}. * *

The name of this method starts with "unsafe" because if this is a native managed Memory * (e. g. obtained via {@link #map(File)} or {@link WritableMemory#allocateDirect(long)})), and * the returned {@code ByteBuffer} object is used after the Memory is freed, it may cause a JVM * crash. This is also possible for Memory objects themselves with some methods, * but Memory's use-after-free is caught as an AssertionError, if assertions are enabled. * * @param offsetBytes the starting offset with respect to the origin of this Memory * @param capacityBytes the capacity of the returned ByteBuffer * @return a new read-only {@code ByteBuffer} to access the specified region. * @throws UnsupportedOperationException if this method couldn't be viewed as ByteBuffer, because * when it wraps a non-byte Java array. */ public abstract ByteBuffer unsafeByteBufferView(long offsetBytes, int capacityBytes); //ACCESS PRIMITIVE HEAP ARRAYS for readOnly /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final boolean[] arr) { final long lengthBytes = arr.length << Prim.BOOLEAN.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final byte[] arr) { return Memory.wrap(arr, 0, arr.length, nativeOrder); } /** * Wraps the given primitive array for read operations with the given byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @param byteOrder the byte order to be used * @return a new Memory for read operations */ public static Memory wrap(final byte[] arr, final ByteOrder byteOrder) { return Memory.wrap(arr, 0, arr.length, byteOrder); } /** * Wraps the given primitive array for read operations with the given byte order. If the given * lengthBytes is zero, backing storage and byte order of the returned Memory object are * unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @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 Memory for read operations */ public static Memory wrap(final byte[] arr, final int offsetBytes, final int lengthBytes, final ByteOrder byteOrder) { UnsafeUtil.checkBounds(offsetBytes, lengthBytes, arr.length); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, byteOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final char[] arr) { final long lengthBytes = arr.length << Prim.CHAR.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final short[] arr) { final long lengthBytes = arr.length << Prim.SHORT.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final int[] arr) { final long lengthBytes = arr.length << Prim.INT.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final long[] arr) { final long lengthBytes = arr.length << Prim.LONG.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final float[] arr) { final long lengthBytes = arr.length << Prim.FLOAT.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } /** * Wraps the given primitive array for read operations assuming native byte order. If the array * size is zero, backing storage and byte order of the returned Memory object are unspecified. * *

Note: Always qualify this method with the class name, e.g., * Memory.wrap(...). * @param arr the given primitive array. * @return a new Memory for read operations */ public static Memory wrap(final double[] arr) { final long lengthBytes = arr.length << Prim.DOUBLE.shift(); return BaseWritableMemoryImpl.wrapHeapArray(arr, 0L, lengthBytes, true, nativeOrder); } //PRIMITIVE getX() and getXArray() /** * Gets the boolean value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the boolean at the given offset */ public abstract boolean getBoolean(long offsetBytes); /** * Gets the boolean array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetBooleans offset in array units * @param lengthBooleans number of array units to transfer */ public abstract void getBooleanArray(long offsetBytes, boolean[] dstArray, int dstOffsetBooleans, int lengthBooleans); /** * Gets the byte value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the byte at the given offset */ public abstract byte getByte(long offsetBytes); /** * Gets the byte array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetBytes offset in array units * @param lengthBytes number of array units to transfer */ public abstract void getByteArray(long offsetBytes, byte[] dstArray, int dstOffsetBytes, int lengthBytes); /** * Gets the char value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the char at the given offset */ public abstract char getChar(long offsetBytes); /** * Gets the char array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetChars offset in array units * @param lengthChars number of array units to transfer */ public abstract void getCharArray(long offsetBytes, char[] dstArray, int dstOffsetChars, int lengthChars); /** * Gets UTF-8 encoded bytes from this Memory, starting at offsetBytes to a length of * utf8LengthBytes, decodes them into characters and appends them to the given Appendable. * This is specifically designed to reduce the production of intermediate objects (garbage), * thus significantly reducing pressure on the JVM Garbage Collector. * @param offsetBytes offset bytes relative to the Memory start * @param utf8LengthBytes the number of encoded UTF-8 bytes to decode. It is assumed that the * caller has the correct number of utf8 bytes required to decode the number of characters * to be appended to dst. Characters outside the ASCII range can require 2, 3 or 4 bytes per * character to decode. * @param dst the destination Appendable to append the decoded characters to. * @return the number of characters decoded * @throws IOException if dst.append() throws IOException * @throws Utf8CodingException in case of malformed or illegal UTF-8 input */ public abstract int getCharsFromUtf8(long offsetBytes, int utf8LengthBytes, Appendable dst) throws IOException, Utf8CodingException; /** * Gets UTF-8 encoded bytes from this Memory, starting at offsetBytes to a length of * utf8LengthBytes, decodes them into characters and appends them to the given StringBuilder. * This method does *not* reset the length of the destination StringBuilder before appending * characters to it. * This is specifically designed to reduce the production of intermediate objects (garbage), * thus significantly reducing pressure on the JVM Garbage Collector. * @param offsetBytes offset bytes relative to the Memory start * @param utf8LengthBytes the number of encoded UTF-8 bytes to decode. It is assumed that the * caller has the correct number of utf8 bytes required to decode the number of characters * to be appended to dst. Characters outside the ASCII range can require 2, 3 or 4 bytes per * character to decode. * @param dst the destination StringBuilder to append decoded characters to. * @return the number of characters decoded. * @throws Utf8CodingException in case of malformed or illegal UTF-8 input */ public abstract int getCharsFromUtf8(final long offsetBytes, final int utf8LengthBytes, final StringBuilder dst) throws Utf8CodingException; /** * Gets the double value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the double at the given offset */ public abstract double getDouble(long offsetBytes); /** * Gets the double array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetDoubles offset in array units * @param lengthDoubles number of array units to transfer */ public abstract void getDoubleArray(long offsetBytes, double[] dstArray, int dstOffsetDoubles, int lengthDoubles); /** * Gets the float value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the float at the given offset */ public abstract float getFloat(long offsetBytes); /** * Gets the float array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetFloats offset in array units * @param lengthFloats number of array units to transfer */ public abstract void getFloatArray(long offsetBytes, float[] dstArray, int dstOffsetFloats, int lengthFloats); /** * Gets the int value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the int at the given offset */ public abstract int getInt(long offsetBytes); /** * Gets the int array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetInts offset in array units * @param lengthInts number of array units to transfer */ public abstract void getIntArray(long offsetBytes, int[] dstArray, int dstOffsetInts, int lengthInts); /** * Gets the long value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the long at the given offset */ public abstract long getLong(long offsetBytes); /** * Gets the long array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetLongs offset in array units * @param lengthLongs number of array units to transfer */ public abstract void getLongArray(long offsetBytes, long[] dstArray, int dstOffsetLongs, int lengthLongs); /** * Gets the short value at the given offset * @param offsetBytes offset bytes relative to this Memory start * @return the short at the given offset */ public abstract short getShort(long offsetBytes); /** * Gets the short array at the given offset * @param offsetBytes offset bytes relative to this Memory start * @param dstArray The preallocated destination array. * @param dstOffsetShorts offset in array units * @param lengthShorts number of array units to transfer */ public abstract void getShortArray(long offsetBytes, short[] dstArray, int dstOffsetShorts, int lengthShorts); //SPECIAL PRIMITIVE READ METHODS: compareTo, copyTo, writeTo /** * Compares the bytes of this Memory to that Memory. * Returns (this < that) ? (some negative value) : (this > that) ? (some positive value) * : 0;. * If all bytes are equal up to the shorter of the two lengths, the shorter length is considered * to be less than the other. * @param thisOffsetBytes the starting offset for this Memory * @param thisLengthBytes the length of the region to compare from this Memory * @param that the other Memory to compare with * @param thatOffsetBytes the starting offset for that Memory * @param thatLengthBytes the length of the region to compare from that Memory * @return (this < that) ? (some negative value) : (this > that) ? (some positive value) * : 0; */ public abstract int compareTo(long thisOffsetBytes, long thisLengthBytes, Memory that, long thatOffsetBytes, long thatLengthBytes); /** * Copies bytes from a source range of this Memory to a destination range of the given Memory * with the same semantics when copying between overlapping ranges of bytes as method * {@link java.lang.System#arraycopy(Object, int, Object, int, int)} has. However, if the source * and the destination ranges are exactly the same, this method throws {@link * IllegalArgumentException}, because it should never be needed in real-world scenarios and * therefore indicates a bug. * @param srcOffsetBytes the source offset for this Memory * @param destination the destination Memory, which may not be Read-Only. * @param dstOffsetBytes the destination offset * @param lengthBytes the number of bytes to copy */ public abstract void copyTo(long srcOffsetBytes, WritableMemory destination, long dstOffsetBytes, long lengthBytes); /** * Writes bytes from a source range of this Memory to the given {@code WritableByteChannel}. * @param offsetBytes the source offset for this Memory * @param lengthBytes the number of bytes to copy * @param out the destination WritableByteChannel * @throws IOException may occur while writing to the WritableByteChannel */ public abstract void writeTo(long offsetBytes, long lengthBytes, WritableByteChannel out) throws IOException; }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy