package org.apache.cassandra.io.util;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
public class SafeMemoryWriter extends DataOutputBuffer
{
private SafeMemory memory;
@SuppressWarnings("resource")
public SafeMemoryWriter(long initialCapacity)
{
this(new SafeMemory(initialCapacity));
}
private SafeMemoryWriter(SafeMemory memory)
{
super(tailBuffer(memory).order(ByteOrder.BIG_ENDIAN));
this.memory = memory;
}
public SafeMemory currentBuffer()
{
return memory;
}
@Override
protected void expandToFit(long count)
{
resizeTo(calculateNewSize(count));
}
private void resizeTo(long newCapacity)
{
if (newCapacity != capacity())
{
long position = length();
ByteOrder order = buffer.order();
SafeMemory oldBuffer = memory;
memory = this.memory.copy(newCapacity);
buffer = tailBuffer(memory);
int newPosition = (int) (position - tailOffset(memory));
buffer.position(newPosition);
buffer.order(order);
oldBuffer.free();
}
}
public void trim()
{
resizeTo(length());
}
public void close()
{
memory.close();
}
public Throwable close(Throwable accumulate)
{
return memory.close(accumulate);
}
public long length()
{
return tailOffset(memory) + buffer.position();
}
public long capacity()
{
return memory.size();
}
@Override
public SafeMemoryWriter order(ByteOrder order)
{
super.order(order);
return this;
}
@Override
public long validateReallocation(long newSize)
{
return Math.min(newSize, length() + Integer.MAX_VALUE);
}
private static long tailOffset(Memory memory)
{
return Math.max(0, memory.size - Integer.MAX_VALUE);
}
private static ByteBuffer tailBuffer(Memory memory)
{
return memory.asByteBuffer(tailOffset(memory), (int) Math.min(memory.size, Integer.MAX_VALUE));
}
}