blob: 88912f9ea91173c8fd0d4ab54ac6275d77c029e5 [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
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), null);
this.memory = memory;
}
public SafeMemory currentBuffer()
{
return memory;
}
@Override
protected void reallocate(long count)
{
long newCapacity = calculateNewSize(count);
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 setCapacity(long newCapacity)
{
reallocate(newCapacity);
}
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 newSize;
}
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));
}
}