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

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

There is a newer version: 0.12.2
Show newest version
/*
 * 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.UnsafeUtil.ARRAY_BOOLEAN_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_BOOLEAN_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_BYTE_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_BYTE_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_CHAR_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_CHAR_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_DOUBLE_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_DOUBLE_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_FLOAT_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_FLOAT_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_INT_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_INT_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_LONG_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_LONG_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.ARRAY_SHORT_BASE_OFFSET;
import static com.yahoo.memory.UnsafeUtil.ARRAY_SHORT_INDEX_SCALE;
import static com.yahoo.memory.UnsafeUtil.BOOLEAN_SHIFT;
import static com.yahoo.memory.UnsafeUtil.BYTE_SHIFT;
import static com.yahoo.memory.UnsafeUtil.CHAR_SHIFT;
import static com.yahoo.memory.UnsafeUtil.DOUBLE_SHIFT;
import static com.yahoo.memory.UnsafeUtil.FLOAT_SHIFT;
import static com.yahoo.memory.UnsafeUtil.INT_SHIFT;
import static com.yahoo.memory.UnsafeUtil.LONG_SHIFT;
import static com.yahoo.memory.UnsafeUtil.LS;
import static com.yahoo.memory.UnsafeUtil.SHORT_SHIFT;
import static com.yahoo.memory.UnsafeUtil.assertBounds;
import static com.yahoo.memory.UnsafeUtil.unsafe;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;

/**
 * Implementation of WritableBuffer
 * @author Roman Leventov
 * @author Lee Rhodes
 */
class WritableBufferImpl extends WritableBuffer {
  final ResourceState state;
  final Object unsafeObj; //Array objects are held here.
  final long unsafeObjHeader; //Heap ByteBuffer includes the slice() offset here.
  final long capacity;
  final long cumBaseOffset; //Holds the cumulative offset to the start of data.
  //Static variable for cases where byteBuf/array sizes are zero
  final static WritableBufferImpl ZERO_SIZE_BUFFER;

  static {
    ZERO_SIZE_BUFFER = new WritableBufferImpl(
        new ResourceState(new byte[0], Prim.BYTE, 0)
    );
  }

  WritableBufferImpl(final ResourceState state) {
    super(state);
    this.state = state;
    unsafeObj = state.getUnsafeObject();
    unsafeObjHeader = state.getUnsafeObjectHeader();
    capacity = state.getCapacity();
    cumBaseOffset = state.getCumBaseOffset();
  }

  //REGIONS/DUPLICATES XXX
  @Override
  public Buffer duplicate() {
    return doDuplicate(0, capacity);
  }

  @Override
  public WritableBuffer writableDuplicate() {
    return doDuplicate(0, capacity);
  }

  @Override
  public Buffer region() {
    return doRegion(getPosition(), getEnd() - getPosition());
  }

  @Override
  public WritableBuffer writableRegion() {
    return doRegion(getPosition(), getEnd() - getPosition());
  }

  @Override
  public WritableBuffer writableRegion(final long offsetBytes, final long capacityBytes) {
    return doRegion(offsetBytes, capacityBytes);
  }

  private WritableBuffer doRegion(final long offsetBytes, final long capacityBytes) {
    checkValid();
    assert (offsetBytes + capacityBytes) <= capacity
            : "newOff + newCap: " + (offsetBytes + capacityBytes) + ", origCap: " + capacity;
    final ResourceState newState = state.copy(); //creates new BaseBuffer(newState)
    newState.putRegionOffset(newState.getRegionOffset() + offsetBytes);
    newState.putCapacity(capacityBytes);
    final WritableBufferImpl wBufImpl = new WritableBufferImpl(newState);
    wBufImpl.setStartPositionEnd(0L, 0L, capacityBytes);
    return wBufImpl;
  }

  private WritableBuffer doDuplicate(final long offsetBytes, final long capacityBytes) {
    checkValid();
    assert (offsetBytes + capacityBytes) <= capacity
            : "newOff + newCap: " + (offsetBytes + capacityBytes) + ", origCap: " + capacity;
    final ResourceState newState = state.copy(); //creates new BaseBuffer(newState)
    newState.putRegionOffset(newState.getRegionOffset() + offsetBytes);
    newState.putCapacity(capacityBytes);
    final WritableBufferImpl wBufImpl = new WritableBufferImpl(newState);
    wBufImpl.setStartPositionEnd(getStart(), getPosition(), getEnd());
    return wBufImpl;
  }

  //MEMORY XXX
  @Override
  public Memory asMemory() {
    checkValid();
    return new WritableMemoryImpl(state.copy());
  }

  @Override
  public WritableMemory asWritableMemory() {
    checkValid();
    return new WritableMemoryImpl(state.copy());
  }

  //PRIMITIVE getXXX() and getXXXArray() XXX
  @Override
  public boolean getBoolean() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    final boolean ret = unsafe.getBoolean(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_BOOLEAN_INDEX_SCALE);
    return ret;
  }

  @Override
  public boolean getBoolean(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getBoolean(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getBooleanArray(final boolean[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << BOOLEAN_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_BOOLEAN_BASE_OFFSET + (dstOffset << BOOLEAN_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public byte getByte() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_BYTE_INDEX_SCALE, capacity);
    final byte ret = unsafe.getByte(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_BYTE_INDEX_SCALE);
    return ret;
  }

  @Override
  public byte getByte(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getByte(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getByteArray(final byte[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << BYTE_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_BYTE_BASE_OFFSET + (dstOffset << BYTE_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public char getChar() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_CHAR_INDEX_SCALE, capacity);
    final char ret = unsafe.getChar(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_CHAR_INDEX_SCALE);
    return ret;
  }

  @Override
  public char getChar(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getChar(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getCharArray(final char[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << CHAR_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_CHAR_BASE_OFFSET + (dstOffset << CHAR_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public double getDouble() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_DOUBLE_INDEX_SCALE, capacity);
    final double ret = unsafe.getDouble(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_DOUBLE_INDEX_SCALE);
    return ret;
  }

  @Override
  public double getDouble(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getDouble(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getDoubleArray(final double[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << DOUBLE_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_DOUBLE_BASE_OFFSET + (dstOffset << DOUBLE_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public float getFloat() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_FLOAT_INDEX_SCALE, capacity);
    final float ret = unsafe.getFloat(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_FLOAT_INDEX_SCALE);
    return ret;
  }

  @Override
  public float getFloat(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getFloat(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getFloatArray(final float[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << FLOAT_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_FLOAT_BASE_OFFSET + (dstOffset << FLOAT_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public int getInt() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_INT_INDEX_SCALE, capacity);
    final int ret = unsafe.getInt(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_INT_INDEX_SCALE);
    return ret;
  }

  @Override
  public int getInt(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getInt(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getIntArray(final int[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << INT_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_INT_BASE_OFFSET + (dstOffset << INT_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public long getLong() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_LONG_INDEX_SCALE, capacity);
    final long ret = unsafe.getLong(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_LONG_INDEX_SCALE);
    return ret;
  }

  @Override
  public long getLong(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getLong(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getLongArray(final long[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << LONG_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_LONG_BASE_OFFSET + (dstOffset << LONG_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  @Override
  public short getShort() {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_SHORT_INDEX_SCALE, capacity);
    final short ret = unsafe.getShort(unsafeObj, cumBaseOffset + pos);
    incrementPosition(ARRAY_SHORT_INDEX_SCALE);
    return ret;
  }

  @Override
  public short getShort(final long offsetBytes) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    return unsafe.getShort(unsafeObj, cumBaseOffset + offsetBytes);
  }

  @Override
  public void getShortArray(final short[] dstArray, final int dstOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << SHORT_SHIFT;
    assertBounds(pos, copyBytes, capacity);
    assertBounds(dstOffset, length, dstArray.length);
    unsafe.copyMemory(
            unsafeObj,
            cumBaseOffset + pos,
            dstArray,
            ARRAY_SHORT_BASE_OFFSET + (dstOffset << SHORT_SHIFT),
            copyBytes);
    incrementPosition(copyBytes);
  }

  //OTHER PRIMITIVE READ METHODS: copyTo, compareTo XXX
  @Override
  public int compareTo(final long thisOffsetBytes, final long thisLengthBytes, final Buffer that,
          final long thatOffsetBytes, final long thatLengthBytes) {
    checkValid();
    ((WritableBufferImpl)that).checkValid();
    assertBounds(thisOffsetBytes, thisLengthBytes, capacity);
    assertBounds(thatOffsetBytes, thatLengthBytes, that.getCapacity());
    final long thisAdd = getCumulativeOffset() + thisOffsetBytes;
    final long thatAdd = that.getCumulativeOffset() + thatOffsetBytes;
    final Object thisObj = (isDirect()) ? null : unsafeObj;
    final Object thatObj = (that.isDirect()) ? null : ((WritableBuffer)that).getArray();
    final long lenBytes = Math.min(thisLengthBytes, thatLengthBytes);
    for (long i = 0; i < lenBytes; i++) {
      final int thisByte = unsafe.getByte(thisObj, thisAdd + i);
      final int thatByte = unsafe.getByte(thatObj, thatAdd + i);
      if (thisByte < thatByte) { return -1; }
      if (thisByte > thatByte) { return  1; }
    }
    if (thisLengthBytes < thatLengthBytes) { return -1; }
    if (thisLengthBytes > thatLengthBytes) { return  1; }
    return 0;
  }

  //OTHER READ METHODS XXX

  @Override
  public long getCapacity() {
    checkValid();
    return capacity;
  }

  @Override
  public long getCumulativeOffset() {
    checkValid();
    return cumBaseOffset;
  }

  @Override
  public long getRegionOffset() {
    checkValid();
    return state.getRegionOffset();
  }

  @Override
  public ByteOrder getResourceOrder() {
    checkValid();
    return state.order();
  }

  @Override
  public boolean hasArray() {
    checkValid();
    return (unsafeObj != null);
  }

  @Override
  public boolean hasByteBuffer() {
    checkValid();
    return state.getByteBuffer() != null;
  }

  @Override
  public boolean isDirect() {
    checkValid();
    return state.isDirect();
  }

  @Override
  public boolean isResourceReadOnly() {
    checkValid();
    return state.isResourceReadOnly();
  }

  @Override
  public boolean isSameResource(final Buffer that) {
    return state.isSameResource(that.getResourceState());
  }

  @Override
  public boolean isValid() {
    return state.isValid();
  }

  @Override
  public boolean swapBytes() {
    return state.isSwapBytes();
  }

  @Override
  public String toHexString(final String header, final long offsetBytes, final int lengthBytes) {
    checkValid();
    final String klass = this.getClass().getSimpleName();
    final String s1 = String.format("(..., %d, %d)", offsetBytes, lengthBytes);
    final long hcode = hashCode() & 0XFFFFFFFFL;
    final String call = ".toHexString" + s1 + ", hashCode: " + hcode;
    final StringBuilder sb = new StringBuilder();
    sb.append("### ").append(klass).append(" SUMMARY ###").append(LS);
    sb.append("Header Comment      : ").append(header).append(LS);
    sb.append("Call Parameters     : ").append(call);
    return Memory.toHex(sb.toString(), offsetBytes, lengthBytes, state);
  }

  //PRIMITIVE putXXX() and putXXXArray() XXX
  @Override
  public void putBoolean(final boolean value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    unsafe.putBoolean(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_BOOLEAN_INDEX_SCALE);
  }

  @Override
  public void putBoolean(final long offsetBytes, final boolean value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BOOLEAN_INDEX_SCALE, capacity);
    unsafe.putBoolean(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putBooleanArray(final boolean[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << BOOLEAN_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_BOOLEAN_BASE_OFFSET + (srcOffset << BOOLEAN_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putByte(final byte value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_BYTE_INDEX_SCALE, capacity);
    unsafe.putByte(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_BYTE_INDEX_SCALE);
  }

  @Override
  public void putByte(final long offsetBytes, final byte value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_BYTE_INDEX_SCALE, capacity);
    unsafe.putByte(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putByteArray(final byte[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << BYTE_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_BYTE_BASE_OFFSET + (srcOffset << BYTE_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putChar(final char value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_CHAR_INDEX_SCALE, capacity);
    unsafe.putChar(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_CHAR_INDEX_SCALE);
  }

  @Override
  public void putChar(final long offsetBytes, final char value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_CHAR_INDEX_SCALE, capacity);
    unsafe.putChar(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putCharArray(final char[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << CHAR_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_CHAR_BASE_OFFSET + (srcOffset << CHAR_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putDouble(final double value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_DOUBLE_INDEX_SCALE, capacity);
    unsafe.putDouble(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_DOUBLE_INDEX_SCALE);
  }

  @Override
  public void putDouble(final long offsetBytes, final double value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_DOUBLE_INDEX_SCALE, capacity);
    unsafe.putDouble(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putDoubleArray(final double[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << DOUBLE_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_DOUBLE_BASE_OFFSET + (srcOffset << DOUBLE_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putFloat(final float value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_FLOAT_INDEX_SCALE, capacity);
    unsafe.putFloat(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_FLOAT_INDEX_SCALE);
  }

  @Override
  public void putFloat(final long offsetBytes, final float value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_FLOAT_INDEX_SCALE, capacity);
    unsafe.putFloat(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putFloatArray(final float[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << FLOAT_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_FLOAT_BASE_OFFSET + (srcOffset << FLOAT_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putInt(final int value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_INT_INDEX_SCALE, capacity);
    unsafe.putInt(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_INT_INDEX_SCALE);
  }

  @Override
  public void putInt(final long offsetBytes, final int value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_INT_INDEX_SCALE, capacity);
    unsafe.putInt(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putIntArray(final int[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << INT_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_INT_BASE_OFFSET + (srcOffset << INT_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putLong(final long value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_LONG_INDEX_SCALE, capacity);
    unsafe.putLong(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_LONG_INDEX_SCALE);
  }

  @Override
  public void putLong(final long offsetBytes, final long value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_LONG_INDEX_SCALE, capacity);
    unsafe.putLong(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putLongArray(final long[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << LONG_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_LONG_BASE_OFFSET + (srcOffset << LONG_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  @Override
  public void putShort(final short value) {
    checkValid();
    final long pos = getPosition();
    assertBounds(pos, ARRAY_SHORT_INDEX_SCALE, capacity);
    unsafe.putShort(unsafeObj, cumBaseOffset + pos, value);
    incrementPosition(ARRAY_SHORT_INDEX_SCALE);
  }

  @Override
  public void putShort(final long offsetBytes, final short value) {
    checkValid();
    assertBounds(offsetBytes, ARRAY_SHORT_INDEX_SCALE, capacity);
    unsafe.putShort(unsafeObj, cumBaseOffset + offsetBytes, value);
  }

  @Override
  public void putShortArray(final short[] srcArray, final int srcOffset, final int length) {
    checkValid();
    final long pos = getPosition();
    final long copyBytes = length << SHORT_SHIFT;
    assertBounds(srcOffset, length, srcArray.length);
    assertBounds(pos, copyBytes, capacity);
    unsafe.copyMemory(
            srcArray,
            ARRAY_SHORT_BASE_OFFSET + (srcOffset << SHORT_SHIFT),
            unsafeObj,
            cumBaseOffset + pos,
            copyBytes
            );
    incrementPosition(copyBytes);
  }

  //Atomic Write Methods XXX
  //Use WritableMemory for atomic methods

  //OTHER WRITE METHODS XXX
  @Override
  public Object getArray() {
    checkValid();
    return unsafeObj;
  }

  @Override
  public ByteBuffer getByteBuffer() {
    checkValid();
    return state.getByteBuffer();
  }

  @Override
  public void clear() {
    fill((byte)0);
  }

  @Override
  public void fill(final byte value) {
    checkValid();
    final long pos = getPosition();
    final long len = getEnd() - pos;
    assertBounds(pos, len, capacity);
    unsafe.setMemory(unsafeObj, cumBaseOffset + pos, len, value);
  }

  //RESTRICTED READ AND WRITE XXX
  private final void checkValid() { //applies to both readable and writable
    assert state.isValid() : "Memory not valid.";
  }

  @Override
  ResourceState getResourceState() {
    return state;
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy