package org.neo4j.kernel.impl.transaction.xaframework; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.FileChannel; import java.nio.channels.ReadableByteChannel; public class InMemoryLogBuffer implements LogBuffer, ReadableByteChannel { private byte[] bytes = new byte[1000]; private int writeIndex; private int readIndex; private ByteBuffer bufferForConversions = ByteBuffer.wrap( new byte[100] ); public InMemoryLogBuffer() { } private void ensureArrayCapacityPlus( int plus ) { while ( writeIndex+plus > bytes.length ) { byte[] tmp = bytes; bytes = new byte[bytes.length*2]; System.arraycopy( tmp, 0, bytes, 0, tmp.length ); } } private LogBuffer flipAndPut() { ensureArrayCapacityPlus( bufferForConversions.limit() ); System.arraycopy( bufferForConversions.flip().array(), 0, bytes, writeIndex, bufferForConversions.limit() ); writeIndex += bufferForConversions.limit(); return this; } public LogBuffer put( byte b ) throws IOException { ensureArrayCapacityPlus( 1 ); bytes[writeIndex++] = b; return this; } public LogBuffer putInt( int i ) throws IOException { ((ByteBuffer) bufferForConversions.clear()).putInt( i ); return flipAndPut(); } public LogBuffer putLong( long l ) throws IOException { ((ByteBuffer) bufferForConversions.clear()).putLong( l ); return flipAndPut(); } public LogBuffer put( byte[] bytes ) throws IOException { ensureArrayCapacityPlus( bytes.length ); System.arraycopy( bytes, 0, this.bytes, writeIndex, bytes.length ); writeIndex += bytes.length; return this; } public LogBuffer put( char[] chars ) throws IOException { ensureConversionBufferCapacity( chars.length*2 ); bufferForConversions.clear(); for ( char ch : chars ) { bufferForConversions.putChar( ch ); } return flipAndPut(); } private void ensureConversionBufferCapacity( int length ) { if ( bufferForConversions.capacity() < length ) { bufferForConversions = ByteBuffer.wrap( new byte[length*2] ); } } public void force() throws IOException { } public long getFileChannelPosition() throws IOException { return this.readIndex; } public FileChannel getFileChannel() { throw new UnsupportedOperationException(); } public boolean isOpen() { return true; } public void close() throws IOException { } public int read( ByteBuffer dst ) throws IOException { if ( readIndex >= writeIndex ) { return -1; } int actualLengthToRead = Math.min( dst.limit(), writeIndex-readIndex ); try { dst.put( bytes, readIndex, actualLengthToRead ); return actualLengthToRead; } finally { readIndex += actualLengthToRead; } } }