private void putLongBigEndian( long value, long p ) { UnsafeUtil.putByte( p , (byte)( value >> 56 ) ); UnsafeUtil.putByte( p + 1, (byte)( value >> 48 ) ); UnsafeUtil.putByte( p + 2, (byte)( value >> 40 ) ); UnsafeUtil.putByte( p + 3, (byte)( value >> 32 ) ); UnsafeUtil.putByte( p + 4, (byte)( value >> 24 ) ); UnsafeUtil.putByte( p + 5, (byte)( value >> 16 ) ); UnsafeUtil.putByte( p + 6, (byte)( value >> 8 ) ); UnsafeUtil.putByte( p + 7, (byte) value ); }
try putByte( address, (byte) 1 ); assertThat( getByte( address ), is( (byte) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 );
private void putByte( long p, byte value ) { UnsafeUtil.putByte( p, value ); }
/** * Puts a {@code short} at memory address {@code p} by writing byte for byte, instead of the whole value * in one go. This can be useful, even necessary in some scenarios where {@link #allowUnalignedMemoryAccess} * is {@code false} and {@code p} isn't aligned properly. Values written with this method should be * read using {@link #getShortByteWiseLittleEndian(long)}. * * @param p address pointer to start writing at. * @param value value to write byte for byte. */ public static void putShortByteWiseLittleEndian( long p, short value ) { UnsafeUtil.putByte( p, (byte) value ); UnsafeUtil.putByte( p + 1, (byte) (value >> 8) ); }
/** * Puts a {@code int} at memory address {@code p} by writing byte for byte, instead of the whole value * in one go. This can be useful, even necessary in some scenarios where {@link #allowUnalignedMemoryAccess} * is {@code false} and {@code p} isn't aligned properly. Values written with this method should be * read using {@link #getIntByteWiseLittleEndian(long)}. * * @param p address pointer to start writing at. * @param value value to write byte for byte. */ public static void putIntByteWiseLittleEndian( long p, int value ) { UnsafeUtil.putByte( p, (byte) value ); UnsafeUtil.putByte( p + 1, (byte) (value >> 8) ); UnsafeUtil.putByte( p + 2, (byte) (value >> 16) ); UnsafeUtil.putByte( p + 3, (byte) (value >> 24) ); }
/** * Puts a {@code long} at memory address {@code p} by writing byte for byte, instead of the whole value * in one go. This can be useful, even necessary in some scenarios where {@link #allowUnalignedMemoryAccess} * is {@code false} and {@code p} isn't aligned properly. Values written with this method should be * read using {@link #getShortByteWiseLittleEndian(long)}. * * @param p address pointer to start writing at. * @param value value to write byte for byte. */ public static void putLongByteWiseLittleEndian( long p, long value ) { UnsafeUtil.putByte( p, (byte) value ); UnsafeUtil.putByte( p + 1, (byte) (value >> 8) ); UnsafeUtil.putByte( p + 2, (byte) (value >> 16) ); UnsafeUtil.putByte( p + 3, (byte) (value >> 24) ); UnsafeUtil.putByte( p + 4, (byte) (value >> 32) ); UnsafeUtil.putByte( p + 5, (byte) (value >> 40) ); UnsafeUtil.putByte( p + 6, (byte) (value >> 48) ); UnsafeUtil.putByte( p + 7, (byte) (value >> 56) ); }
@Override public void putByte( byte value ) { long p = nextBoundedPointer( SIZE_OF_BYTE ); UnsafeUtil.putByte( p, value ); offset++; }
@Override public void setByte( long index, int offset, byte value ) { UnsafeUtil.putByte( address( index, offset ), value ); }
private void putBytes( long page, byte[] data, int srcOffset, int tgtOffset, int length ) { for ( int i = 0; i < length; i++ ) { UnsafeUtil.putByte( page + srcOffset + i, data[tgtOffset + i] ); } }
@Override public void set( long index, byte[] value ) { long address = address( index, 0 ); for ( int i = 0; i < itemSize; i++, address++ ) { UnsafeUtil.putByte( address, value[i] ); } }
@Override public void putByte( int offset, byte value ) { long p = getBoundedPointer( offset, SIZE_OF_BYTE ); UnsafeUtil.putByte( p, value ); }
@Override public void putBytes( byte[] data, int arrayOffset, int length ) { long p = getBoundedPointer( offset, length ); if ( !outOfBounds ) { for ( int i = 0; i < length; i++ ) { byte b = data[arrayOffset + i]; UnsafeUtil.putByte( p + i, b ); } } offset += length; }
@Override public void set3ByteInt( long index, int offset, int value ) { long address = address( index, offset ); UnsafeUtil.putShort( address, (short) value ); UnsafeUtil.putByte( address + Short.BYTES, (byte) (value >>> Short.SIZE) ); }
@Override public void set5ByteLong( long index, int offset, long value ) { long address = address( index, offset ); putInt( address, (int) value ); UnsafeUtil.putByte( address + Integer.BYTES, (byte) (value >>> 32) ); }
protected void clear( long address ) { byte b = (byte) 0; for ( int i = 0; i < cachePageSize(); i++ ) { UnsafeUtil.putByte( address + i, b ); } }
private void unsafeShiftRight( int fromPos, int toPos, int length, int shift ) { int longSteps = length >> 3; if ( UnsafeUtil.allowUnalignedMemoryAccess && longSteps > 0 ) { for ( int i = 0; i < longSteps; i++ ) { fromPos -= Long.BYTES; long x = UnsafeUtil.getLong( pointer + fromPos ); UnsafeUtil.putLong( pointer + fromPos + shift, x ); } } while ( fromPos > toPos ) { fromPos--; byte b = UnsafeUtil.getByte( pointer + fromPos ); UnsafeUtil.putByte( pointer + fromPos + shift, b ); } }
private void unsafeShiftLeft( int fromPos, int toPos, int length, int shift ) { int longSteps = length >> 3; if ( UnsafeUtil.allowUnalignedMemoryAccess && longSteps > 0 ) { for ( int i = 0; i < longSteps; i++ ) { long x = UnsafeUtil.getLong( pointer + fromPos ); UnsafeUtil.putLong( pointer + fromPos + shift, x ); fromPos += Long.BYTES; } } while ( fromPos < toPos ) { byte b = UnsafeUtil.getByte( pointer + fromPos ); UnsafeUtil.putByte( pointer + fromPos + shift, b ); fromPos++; } }
@Override public void clear() { if ( isByteUniform( defaultValue ) ) { UnsafeUtil.setMemory( address, length * itemSize, defaultValue[0] ); } else { long intermediary = UnsafeUtil.allocateMemory( itemSize, allocationTracker ); for ( int i = 0; i < defaultValue.length; i++ ) { UnsafeUtil.putByte( intermediary + i, defaultValue[i] ); } for ( long i = 0, adr = address; i < length; i++, adr += itemSize ) { UnsafeUtil.copyMemory( intermediary, adr, itemSize ); } UnsafeUtil.free( intermediary, itemSize, allocationTracker ); } }