@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 ); } }
private void putLong( long p, long value ) { if ( UnsafeUtil.allowUnalignedMemoryAccess ) { UnsafeUtil.putLong( p, value ); } else { UnsafeUtil.putLongByteWiseLittleEndian( p, value ); } }
private void putInt( long p, int value ) { if ( UnsafeUtil.allowUnalignedMemoryAccess ) { UnsafeUtil.putInt( p, value ); } else { UnsafeUtil.putIntByteWiseLittleEndian( p, value ); } }
protected static long alignmentSafeGetLongAsTwoInts( long address ) { if ( UnsafeUtil.allowUnalignedMemoryAccess ) { return UnsafeUtil.getLong( address ); } // See javadoc in constructor as to why we do this long lsb = UnsafeUtil.getInt( address ) & 0xFFFFFFFFL; long msb = UnsafeUtil.getInt( address + Integer.BYTES ) & 0xFFFFFFFFL; return lsb | (msb << Integer.SIZE); } }
long address = allocateMemory( sizeInBytes ); try putByte( address, (byte) 1 ); assertThat( getByte( address ), is( (byte) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getByte( address ), is( (byte) 0 ) ); putByteVolatile( address, (byte) 1 ); assertThat( getByteVolatile( address ), is( (byte) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getByteVolatile( address ), is( (byte) 0 ) ); putShort( address, (short) 1 ); assertThat( getShort( address ), is( (short) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getShort( address ), is( (short) 0 ) ); putShortVolatile( address, (short) 1 ); assertThat( getShortVolatile( address ), is( (short) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getShortVolatile( address ), is( (short) 0 ) ); putFloat( address, 1 ); assertThat( getFloat( address ), is( (float) 1 ) ); setMemory( address, sizeInBytes, (byte) 0 ); assertThat( getFloat( address ), is( (float) 0 ) ); putFloatVolatile( address, 1 );
protected OffHeapNumberArray( long length, int itemSize, long base, MemoryAllocationTracker allocationTracker ) { super( itemSize, base ); UnsafeUtil.assertHasUnsafe(); this.length = length; this.allocationTracker = allocationTracker; long dataSize = length * itemSize; boolean itemSizeIsPowerOfTwo = Integer.bitCount( itemSize ) == 1; if ( UnsafeUtil.allowUnalignedMemoryAccess || !itemSizeIsPowerOfTwo ) { // we can end up here even if we require aligned memory access. Reason is that item size // isn't power of two anyway and so we have to fallback to safer means of accessing the memory, // i.e. byte for byte. allocatedBytes = dataSize; this.allocatedAddress = this.address = UnsafeUtil.allocateMemory( allocatedBytes, allocationTracker ); } else { // the item size is a power of two and we're required to access memory aligned // so we can allocate a bit more to ensure we can get an aligned memory address to start from. allocatedBytes = dataSize + itemSize - 1; this.allocatedAddress = UnsafeUtil.allocateMemory( allocatedBytes, allocationTracker ); this.address = UnsafeUtil.alignedMemory( allocatedAddress, itemSize ); } }
long address = allocateMemory( sizeInBytes ); try setMemory( address, sizeInBytes, (byte) 0 ); ByteBuffer a = newDirectByteBuffer( address, sizeInBytes ); assertThat( a, is( not( sameInstance( newDirectByteBuffer( address, sizeInBytes ) ) ) ) ); assertThat( a.hasArray(), is( false ) ); assertThat( a.isDirect(), is( true ) ); assertThat( a.position(), is( 0 ) ); assertThat( a.remaining(), is( sizeInBytes ) ); assertThat( getByte( address ), is( (byte) 0 ) ); a.put( (byte) -1 ); assertThat( getByte( address ), is( (byte) -1 ) ); long address2 = allocateMemory( sizeInBytes2 ); try setMemory( address2, sizeInBytes2, (byte) 0 ); initDirectByteBuffer( a, address2, sizeInBytes2 ); assertThat( a.hasArray(), is( false ) ); assertThat( a.isDirect(), is( true ) ); assertThat( a.position(), is( 0 ) ); assertThat( a.remaining(), is( sizeInBytes2 ) ); assertThat( getByte( address2 ), is( (byte) 0 ) ); a.put( (byte) -1 ); assertThat( getByte( address2 ), is( (byte) -1 ) );
@Override public void close() { UnsafeUtil.free( allocatedAddress, allocatedBytes, allocationTracker ); }
protected VALUE internalRemove( long keyAddress ) { UnsafeUtil.setMemory( keyAddress, bytesPerKey, (byte) -1 ); return valueMarker; }
@Override public void writeLong( long offset, long value ) { putLong( block.addr + offset, value ); }
protected static void alignmentSafePutLongAsTwoInts( long address, long value ) { if ( UnsafeUtil.allowUnalignedMemoryAccess ) { UnsafeUtil.putLong( address, value ); } else { // See javadoc in constructor as to why we do this UnsafeUtil.putInt( address, (int) value ); UnsafeUtil.putInt( address + Integer.BYTES, (int) (value >>> Integer.SIZE) ); } }
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 ); }
@Override public long readLong( long offset ) { return getLong( block.addr + offset ); }
Grab( Grab next, long size, MemoryAllocationTracker memoryTracker ) { this.next = next; this.address = UnsafeUtil.allocateMemory( size, memoryTracker ); this.limit = address + size; this.memoryTracker = memoryTracker; nextPointer = address; }
@VisibleForTesting MemoryBlock allocateNew( long size, MemoryAllocationTracker tracker ) { final long unalignedSize = requirePositive( size ) + Long.BYTES - 1; final long unalignedAddr = UnsafeUtil.allocateMemory( unalignedSize, tracker ); final long addr = UnsafeUtil.alignedMemory( unalignedAddr, Long.BYTES ); return new MemoryBlock( addr, size, unalignedAddr, unalignedSize ); }