-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Better paging when random reads go backwards #12357
Changes from 7 commits
3b13621
7e8f54a
1365b68
ee40aed
be2341d
8d196a0
66811c8
a6942fe
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -43,7 +43,7 @@ public abstract class BufferedIndexInput extends IndexInput implements RandomAcc | |||||
/** A buffer size for merges set to {@value #MERGE_BUFFER_SIZE}. */ | ||||||
public static final int MERGE_BUFFER_SIZE = 4096; | ||||||
|
||||||
private int bufferSize = BUFFER_SIZE; | ||||||
private final int bufferSize; | ||||||
romseygeek marked this conversation as resolved.
Show resolved
Hide resolved
|
||||||
|
||||||
private ByteBuffer buffer = EMPTY_BYTEBUFFER; | ||||||
|
||||||
|
@@ -72,7 +72,7 @@ public BufferedIndexInput(String resourceDesc, int bufferSize) { | |||||
this.bufferSize = bufferSize; | ||||||
} | ||||||
|
||||||
/** Returns buffer size. @see #setBufferSize */ | ||||||
/** Returns buffer size */ | ||||||
public final int getBufferSize() { | ||||||
return bufferSize; | ||||||
} | ||||||
|
@@ -159,55 +159,53 @@ public final long readLong() throws IOException { | |||||
} | ||||||
} | ||||||
|
||||||
@Override | ||||||
public final byte readByte(long pos) throws IOException { | ||||||
// Computes an offset into the current buffer from an absolute position to read | ||||||
// `width` bytes from. If the buffer does not contain the position, then we | ||||||
// readjust the bufferStart and refill. | ||||||
private long resolvePositionInBuffer(long pos, int width) throws IOException { | ||||||
long index = pos - bufferStart; | ||||||
if (index < 0 || index >= buffer.limit()) { | ||||||
if (index >= 0 && index < buffer.limit() - width + 1) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: let's save an addition?
Suggested change
|
||||||
return index; | ||||||
} | ||||||
if (index < 0) { | ||||||
// if we're moving backwards, then try and fill up the previous page rather than | ||||||
// starting again at the current pos, to avoid successive backwards reads reloading | ||||||
// the same data over and over again | ||||||
bufferStart = Math.min(pos, Math.max(0, bufferStart - bufferSize)); | ||||||
if (bufferStart + bufferSize - pos < width) { | ||||||
bufferStart += width - 1; // make sure we don't read over the end of the buffer | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: should we update bufferStart in that case so that
Suggested change
Maybe this could be folded directly into the min/max computations? E.g. something like (not tested) bufferStart = bufferStart - bufferSize;
bufferStart = Math.max(bufferStart, pos + width - bufferSize); // make sure we don't read over the end of the buffer
bufferStart = Math.max(bufferStart, 0);
bufferStart = Math.min(bufferStart, pos); |
||||||
} | ||||||
} else { | ||||||
// we're moving forwards, reset the buffer to start at pos | ||||||
bufferStart = pos; | ||||||
buffer.limit(0); // trigger refill() on read | ||||||
seekInternal(pos); | ||||||
refill(); | ||||||
index = 0; | ||||||
} | ||||||
buffer.limit(0); // trigger refill() on read | ||||||
seekInternal(bufferStart); | ||||||
refill(); | ||||||
return pos - bufferStart; | ||||||
} | ||||||
|
||||||
@Override | ||||||
public final byte readByte(long pos) throws IOException { | ||||||
long index = resolvePositionInBuffer(pos, Byte.BYTES); | ||||||
return buffer.get((int) index); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public final short readShort(long pos) throws IOException { | ||||||
long index = pos - bufferStart; | ||||||
if (index < 0 || index >= buffer.limit() - 1) { | ||||||
bufferStart = pos; | ||||||
buffer.limit(0); // trigger refill() on read | ||||||
seekInternal(pos); | ||||||
refill(); | ||||||
index = 0; | ||||||
} | ||||||
long index = resolvePositionInBuffer(pos, Short.BYTES); | ||||||
return buffer.getShort((int) index); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public final int readInt(long pos) throws IOException { | ||||||
long index = pos - bufferStart; | ||||||
if (index < 0 || index >= buffer.limit() - 3) { | ||||||
bufferStart = pos; | ||||||
buffer.limit(0); // trigger refill() on read | ||||||
seekInternal(pos); | ||||||
refill(); | ||||||
index = 0; | ||||||
} | ||||||
long index = resolvePositionInBuffer(pos, Integer.BYTES); | ||||||
return buffer.getInt((int) index); | ||||||
} | ||||||
|
||||||
@Override | ||||||
public final long readLong(long pos) throws IOException { | ||||||
long index = pos - bufferStart; | ||||||
if (index < 0 || index >= buffer.limit() - 7) { | ||||||
bufferStart = pos; | ||||||
buffer.limit(0); // trigger refill() on read | ||||||
seekInternal(pos); | ||||||
refill(); | ||||||
index = 0; | ||||||
} | ||||||
long index = resolvePositionInBuffer(pos, Long.BYTES); | ||||||
return buffer.getLong((int) index); | ||||||
} | ||||||
|
||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.