Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -46,11 +46,11 @@ static ReaderSupplier createSupplier(FileHandle fileHandle)
@Override
public void readFully(float[] dest) throws IOException
{
BufferHolder bh = bufferHolder;
BufferHolder bh = getBufferHolder();
Comment thread
netudima marked this conversation as resolved.
long position = getPosition();

FloatBuffer floatBuffer;
if (bh.offset() == 0 && position % Float.BYTES == 0)
if (getBufferHolderOffset() == 0 && position % Float.BYTES == 0)
{
// this is a separate code path because buffer() and asFloatBuffer() both allocate
// new and relatively expensive xBuffer objects, so we want to avoid doing that
Expand All @@ -63,7 +63,7 @@ public void readFully(float[] dest) throws IOException
// offset is non-zero, and probably not aligned to Float.BYTES, so
// set the position before converting to FloatBuffer.
ByteBuffer bb = bh.buffer();
bb.position(Ints.checkedCast(position - bh.offset()));
bb.position(Ints.checkedCast(position - getBufferHolderOffset()));
floatBuffer = bb.asFloatBuffer();
}

Expand Down Expand Up @@ -94,11 +94,11 @@ public void read(int[] dest, int offset, int count) throws IOException
if (count == 0)
return;

BufferHolder bh = bufferHolder;
BufferHolder bh = getBufferHolder();
long position = getPosition();

IntBuffer intBuffer;
if (bh.offset() == 0 && position % Integer.BYTES == 0)
if (getBufferHolderOffset() == 0 && position % Integer.BYTES == 0)
{
// this is a separate code path because buffer() and asIntBuffer() both allocate
// new and relatively expensive xBuffer objects, so we want to avoid doing that
Expand All @@ -111,7 +111,7 @@ public void read(int[] dest, int offset, int count) throws IOException
// offset is non-zero, and probably not aligned to Integer.BYTES, so
// set the position before converting to IntBuffer.
ByteBuffer bb = bh.buffer();
bb.position(Ints.checkedCast(position - bh.offset()));
bb.position(Ints.checkedCast(position - getBufferHolderOffset()));
intBuffer = bb.asIntBuffer();
}

Expand Down
39 changes: 33 additions & 6 deletions src/java/org/apache/cassandra/io/util/RandomAccessReader.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import javax.annotation.concurrent.NotThreadSafe;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Ints;

Expand All @@ -38,7 +39,18 @@ public class RandomAccessReader extends RebufferingInputStream implements FileDa
private long markedPointer;

final Rebufferer rebufferer;
protected BufferHolder bufferHolder = Rebufferer.EMPTY;

// It is made private to prevent subclasses from modifying the value
// without also updating the corresponding bufferHolderOffset
private BufferHolder bufferHolder = Rebufferer.EMPTY;
Comment thread
netudima marked this conversation as resolved.

// The value is cached to avoid megamorphic calls of bufferHolder.
// It must be updated in sync with bufferHolder value
private long bufferHolderOffset = 0;

// The value is cached to avoid megamorphic calls of bufferHolder
// it is immutable, the SSTable early-open mechanism does not mutate existing readers
private final long fileLength;

/**
* Only created through Builder
Expand All @@ -49,6 +61,7 @@ protected RandomAccessReader(Rebufferer rebufferer)
{
super(Rebufferer.EMPTY.buffer());
this.rebufferer = rebufferer;
this.fileLength = rebufferer.fileLength();
}

/**
Expand All @@ -67,7 +80,9 @@ private void reBufferAt(long position)
bufferHolder.release();
bufferHolder = rebufferer.rebuffer(position);
buffer = bufferHolder.buffer();
buffer.position(Ints.checkedCast(position - bufferHolder.offset()));
long newOffset = bufferHolder.offset();
bufferHolderOffset = newOffset;
buffer.position(Ints.checkedCast(position - newOffset));

assert buffer.order() == ByteOrder.BIG_ENDIAN : "Buffer must have BIG ENDIAN byte ordering";
}
Expand All @@ -76,13 +91,23 @@ private void reBufferAt(long position)
public long getFilePointer()
{
if (buffer == null) // closed already
return rebufferer.fileLength();
return fileLength;
return current();
}

protected BufferHolder getBufferHolder()
{
return bufferHolder;
}

protected long getBufferHolderOffset()
{
return bufferHolderOffset;
}

protected long current()
{
return bufferHolder.offset() + buffer.position();
return bufferHolderOffset + buffer.position();
}

public String getPath()
Expand Down Expand Up @@ -164,6 +189,7 @@ public void close()
rebufferer.closeReader();
buffer = null;
bufferHolder = null;
bufferHolderOffset = 0;

//For performance reasons we don't keep a reference to the file
//channel so we don't close it
Expand Down Expand Up @@ -197,7 +223,7 @@ public void seek(long newPosition)
if (buffer == null)
throw new IllegalStateException("Attempted to seek in a closed RAR");

long bufferOffset = bufferHolder.offset();
long bufferOffset = bufferHolderOffset;
if (newPosition >= bufferOffset && newPosition < bufferOffset + buffer.limit())
{
buffer.position((int) (newPosition - bufferOffset));
Expand Down Expand Up @@ -274,14 +300,15 @@ public final String readLine() throws IOException

public long length()
{
return rebufferer.fileLength();
return fileLength;
}

public long getPosition()
{
return current();
}

@VisibleForTesting
public double getCrcCheckChance()
{
return rebufferer.getCrcCheckChance();
Expand Down