/** * Creates and returns a direct ByteBuffer that contains the contents of this Chunk. * Note that the returned ByteBuffer has a reference to this chunk's * off-heap address so it can only be used while this Chunk is retained. * @return the created direct byte buffer or null if it could not be created. */ @Unretained public ByteBuffer createDirectByteBuffer() { return basicCreateDirectByteBuffer(getBaseDataAddress(), getDataSize()); } @Override
protected byte[] getRawBytes() { byte[] result = getCompressedBytes(); // TODO OFFHEAP: change the following to assert !isCompressed(); if (isCompressed()) { throw new UnsupportedOperationException(); } return result; }
/** * Returns an address that can be used with unsafe apis to access this chunks memory. * @param offset the offset from this chunk's first byte of the byte the returned address should point to. Must be >= 0. * @param size the number of bytes that will be read using the returned address. Assertion will use this to verify that all the memory accessed belongs to this chunk. Must be > 0. * @return a memory address that can be used with unsafe apis */ public long getUnsafeAddress(int offset, int size) { assert offset >= 0 && offset + size <= getDataSize(): "Offset=" + offset + ",size=" + size + ",dataSize=" + getDataSize() + ", chunkSize=" + getSize() + ", but offset + size must be <= " + getDataSize(); assert size > 0; long result = getBaseDataAddress() + offset; // validateAddressAndSizeWithinSlab(result, size); return result; }
@Override public StoredObject allocateAndInitialize(byte[] v, boolean isSerialized, boolean isCompressed, ChunkType chunkType) { long addr = OffHeapRegionEntryHelper.encodeDataAsAddress(v, isSerialized, isCompressed); if (addr != 0L) { return new DataAsAddress(addr); } if (chunkType == null) { chunkType = GemFireChunk.TYPE; } Chunk result = this.freeList.allocate(v.length, chunkType); //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()), true); //debugLog("allocated off heap object of size " + v.length + " @" + Long.toHexString(result.getMemoryAddress()) + "chunkSize=" + result.getSize() + " isSerialized=" + isSerialized + " v=" + Arrays.toString(v), true); if (ReferenceCountHelper.trackReferenceCounts()) { ReferenceCountHelper.refCountChanged(result.getMemoryAddress(), false, 1); } assert result.getChunkType() == chunkType: "chunkType=" + chunkType + " getChunkType()=" + result.getChunkType(); result.setSerializedValue(v); result.setSerialized(isSerialized); result.setCompressed(isCompressed); return result; }
} else if (this.part instanceof Chunk) { Chunk c = (Chunk) this.part; ByteBuffer bb = c.createDirectByteBuffer(); if (bb != null) { buf.put(bb); } else { int bytesToSend = c.getDataSize(); long addr = c.getAddressForReading(0, bytesToSend); while (bytesToSend > 0) { buf.put(UnsafeMemoryChunk.readAbsoluteByte(addr));
if (decompress && chunk.isCompressed()) { try { byte[] decompressedBytes = chunk.getDecompressedBytes(context); if (chunk.isSerialized()) { chunk.release();
@Override public byte readByte(int offset) { assert offset < getDataSize(); return UnsafeMemoryChunk.readAbsoluteByte(getBaseDataAddress() + offset); }
protected String toStringForOffHeapByteSource() { return super.toString() + ":<dataSize=" + getDataSize() + " refCount=" + getRefCount() + " addr=" + Long.toHexString(getMemoryAddress()) + ">"; }
@Override public void sendTo(DataOutput out) throws IOException { if (!this.isCompressed() && out instanceof HeapDataOutputStream) { ByteBuffer bb = createDirectByteBuffer(); if (bb != null) { HeapDataOutputStream hdos = (HeapDataOutputStream) out; if (this.isSerialized()) { hdos.write(bb); } else { hdos.writeByte(DSCODE.BYTE_ARRAY); InternalDataSerializer.writeArrayLength(bb.remaining(), hdos); hdos.write(bb); } return; } } super.sendTo(out); }
ByteBuffer chunkbb = this.chunk.createDirectByteBuffer(); if (chunkbb != null) { flushable.flush(bb, chunkbb); final long bbAddress = Chunk.getDirectByteBufferAddress(bb); if (bbAddress != 0L) { int bytesRemaining = maxOffset; int availableSpace = bb.remaining(); long addrToWrite = bbAddress + bb.position(); long addrToRead = this.chunk.getAddressForReading(0, maxOffset); if (bytesRemaining > availableSpace) { do { bb.position(bb.position()+bytesRemaining); } else { long addr = this.chunk.getAddressForReading(0, maxOffset); final long endAddr = addr + maxOffset; while (addr != endAddr) {
@Override public void sendAsByteArray(DataOutput out) throws IOException { if (!isCompressed() && out instanceof HeapDataOutputStream) { ByteBuffer bb = createDirectByteBuffer(); if (bb != null) { HeapDataOutputStream hdos = (HeapDataOutputStream) out; InternalDataSerializer.writeArrayLength(bb.remaining(), hdos); hdos.write(bb); return; } } super.sendAsByteArray(out); }
/** * Returns the raw possibly compressed bytes of this chunk */ public byte[] getCompressedBytes() { byte[] result = new byte[getDataSize()]; readBytes(0, result); //debugLog("reading", true); SimpleMemoryAllocatorImpl.getAllocator().getStats().incReads(); return result; } protected byte[] getRawBytes() {
public String getDataType() { if (this.block.getDataType() != null) { return this.block.getDataType(); } if (!isSerialized()) { // byte array if (isCompressed()) { return "compressed byte[" + ((Chunk)this.block).getDataSize() + "]"; } else { return "byte[" + ((Chunk)this.block).getDataSize() + "]"; } } else if (isCompressed()) { return "compressed object of size " + ((Chunk)this.block).getDataSize(); } //Object obj = EntryEventImpl.deserialize(((Chunk)this.block).getRawBytes()); byte[] bytes = ((Chunk)this.block).getRawBytes(); return DataType.getDataType(bytes); } public boolean isSerialized() {
@Override public Object getDataValue() { String dataType = getDataType(); if (dataType == null || dataType.equals("N/A")) { return null; } else if (isCompressed()) { return ((Chunk)this.block).getCompressedBytes(); } else if (!isSerialized()) { // byte array //return "byte[" + ((Chunk)this.block).getDataSize() + "]"; return ((Chunk)this.block).getRawBytes(); } else { try { byte[] bytes = ((Chunk)this.block).getRawBytes(); return DataSerializer.readObject(DataType.getDataInput(bytes)); } catch (IOException e) { e.printStackTrace(); return "IOException:" + e.getMessage(); } catch (ClassNotFoundException e) { e.printStackTrace(); return "ClassNotFoundException:" + e.getMessage(); } catch (CacheClosedException e) { e.printStackTrace(); return "CacheClosedException:" + e.getMessage(); } } } @Override
@Override public int getLength() { return this.chunk.getDataSize(); } @Override
private Object getTargetObjectForUpdate(RegionEntry entry) { if (this.indexOnValues) { Object o = entry.getValueOffHeapOrDiskWithoutFaultIn((LocalRegion) getRegion()); try { if (o instanceof Chunk) { Chunk ohval = (Chunk) o; try { o = ohval.getDeserializedForReading(); } finally { ohval.release(); } } else if (o instanceof CachedDeserializable) { o = ((CachedDeserializable)o).getDeserializedForReading(); } } catch (EntryDestroyedException ede) { return Token.INVALID; } return o; } else if (this.indexOnRegionKeys) { return entry.getKey(); } return ((LocalRegion) getRegion()).new NonTXEntry(entry); }
private char basicGetChar(int pos) { long addr = this.chunk.getAddressForReading(pos, 2); if (unaligned) { char result = UnsafeMemoryChunk.readAbsoluteChar(addr); if (ByteOrder.nativeOrder() == ByteOrder.LITTLE_ENDIAN) { result = Character.reverseBytes(result); } return result; } else { int ch1 = UnsafeMemoryChunk.readAbsoluteByte(addr++); int ch2 = UnsafeMemoryChunk.readAbsoluteByte(addr); return (char)((ch1 << 8) + (ch2 << 0)); } }
public static ByteSource create(Chunk chunk) { // Since I found a way to create a DirectByteBuffer (using reflection) from a Chunk // we might not even need the ByteSource abstraction any more. // But it is possible that createByteBuffer will not work on a different jdk so keep it for now. ByteBuffer bb = chunk.createDirectByteBuffer(); if (bb != null) { return create(bb); } else { return new OffHeapByteSource(chunk); } } }
public byte[] getDecompressedBytes(RegionEntryContext context) { byte[] result = getCompressedBytes(); long time = context.getCachePerfStats().startDecompression(); result = context.getCompressor().decompress(result); context.getCachePerfStats().endDecompression(time); return result; }