]> source.dussan.org Git - jgit.git/commitdiff
Add readAheadBuffer hint to ReadableChannel 90/46390/4
authorShawn Pearce <spearce@spearce.org>
Fri, 24 Apr 2015 04:59:23 +0000 (21:59 -0700)
committerShawn Pearce <spearce@spearce.org>
Fri, 24 Apr 2015 18:06:56 +0000 (11:06 -0700)
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

org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsPackFile.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/InMemoryRepository.java
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/ReadableChannel.java

index 386754fc2b2ff00a45b0a7a22b3b06c0b94a47eb..88ef0dd044f73823923ff11703624bf78a6b095a 100644 (file)
@@ -516,7 +516,9 @@ public final class DfsPackFile {
        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 @@ public final class DfsPackFile {
                }
        }
 
-       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];
index ae05536de5feccb08b64489a713f22ee73d8fae7..8e7af0d2909c1efded76560305509b317e3b1b4a 100644 (file)
@@ -227,6 +227,10 @@ public class InMemoryRepository extends DfsRepository {
                public int blockSize() {
                        return 0;
                }
+
+               public void setReadAheadBytes(int b) {
+                       // Unnecessary on a byte array.
+               }
        }
 
        private class MemRefDatabase extends DfsRefDatabase {
index 5ec7079a8382c7978e0e88b040b63fc5912f6b4d..240d552aad23395af5ab1805558d5c9ff1e40cb9 100644 (file)
@@ -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;
 }