Add readAheadBuffer hint to ReadableChannel
This hint allows an underlying implementation to read more bytes when possible and buffer them locally for future read calls to consume. Change-Id: Ia986a1bb8640eecb91cfbd515c61fa1ff1574a6f
This commit is contained in:
parent
3fa520b653
commit
1553a6ff55
|
@ -516,7 +516,9 @@ private long copyPackThroughCache(PackOutputStream out, DfsReader ctx,
|
|||
private long copyPackBypassCache(PackOutputStream out, DfsReader ctx,
|
||||
MessageDigest md) throws IOException {
|
||||
try (ReadableChannel rc = ctx.db.openFile(packDesc, PACK)) {
|
||||
ByteBuffer buf = newCopyBuffer(out, rc, ctx);
|
||||
ByteBuffer buf = newCopyBuffer(out, rc);
|
||||
if (ctx.getOptions().getStreamPackBufferSize() > 0)
|
||||
rc.setReadAheadBytes(ctx.getOptions().getStreamPackBufferSize());
|
||||
long position = 12;
|
||||
long remaining = length - (12 + 20);
|
||||
while (0 < remaining) {
|
||||
|
@ -547,13 +549,8 @@ else if (n > remaining)
|
|||
}
|
||||
}
|
||||
|
||||
private ByteBuffer newCopyBuffer(PackOutputStream out, ReadableChannel rc,
|
||||
DfsReader ctx) {
|
||||
private ByteBuffer newCopyBuffer(PackOutputStream out, ReadableChannel rc) {
|
||||
int bs = blockSize(rc);
|
||||
int bufferSize = ctx.getOptions().getStreamPackBufferSize();
|
||||
if (bufferSize > bs)
|
||||
bs = (bufferSize / bs) * bs;
|
||||
|
||||
byte[] copyBuf = out.getCopyBuffer();
|
||||
if (bs > copyBuf.length)
|
||||
copyBuf = new byte[bs];
|
||||
|
|
|
@ -227,6 +227,10 @@ public long size() {
|
|||
public int blockSize() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void setReadAheadBytes(int b) {
|
||||
// Unnecessary on a byte array.
|
||||
}
|
||||
}
|
||||
|
||||
private class MemRefDatabase extends DfsRefDatabase {
|
||||
|
|
|
@ -100,4 +100,33 @@ public interface ReadableChannel extends ReadableByteChannel {
|
|||
* not need to be a power of 2.
|
||||
*/
|
||||
public int blockSize();
|
||||
|
||||
/**
|
||||
* Recommend the channel maintain a read-ahead buffer.
|
||||
* <p>
|
||||
* A read-ahead buffer of approximately {@code bufferSize} in bytes may be
|
||||
* allocated and used by the channel to smooth out latency for read.
|
||||
* <p>
|
||||
* Callers can continue to read in smaller than {@code bufferSize} chunks.
|
||||
* With read-ahead buffering enabled read latency may fluctuate in a pattern
|
||||
* of one slower read followed by {@code (bufferSize / readSize) - 1} fast
|
||||
* reads satisfied by the read-ahead buffer. When summed up overall time to
|
||||
* read the same contiguous range should be lower than if read-ahead was not
|
||||
* enabled, as the implementation can combine reads to increase throughput.
|
||||
* <p>
|
||||
* To avoid unnecessary IO callers should only enable read-ahead if the
|
||||
* majority of the channel will be accessed in order.
|
||||
* <p>
|
||||
* Implementations may chose to read-ahead using asynchronous APIs or
|
||||
* background threads, or may simply aggregate reads using a buffer.
|
||||
* <p>
|
||||
* This read ahead stays in effect until the channel is closed or the buffer
|
||||
* size is set to 0.
|
||||
*
|
||||
* @param bufferSize
|
||||
* requested size of the read ahead buffer, in bytes.
|
||||
* @throws IOException
|
||||
* if the read ahead cannot be adjusted.
|
||||
*/
|
||||
public void setReadAheadBytes(int bufferSize) throws IOException;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue