Browse Source

Merge "Lazily open ReadableChannel in BlockBasedFile.getOrLoadBlock"

stable-5.3
Terry Parker 6 years ago committed by Gerrit Code Review @ Eclipse.org
parent
commit
01f8e53b26
  1. 41
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java
  2. 2
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java
  3. 2
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java
  4. 4
      org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java

41
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java

@ -129,8 +129,8 @@ abstract class BlockBasedFile {
} }
DfsBlock getOrLoadBlock(long pos, DfsReader ctx) throws IOException { DfsBlock getOrLoadBlock(long pos, DfsReader ctx) throws IOException {
try (ReadableChannel rc = ctx.db.openFile(desc, ext)) { try (LazyChannel c = new LazyChannel(ctx, desc, ext)) {
return cache.getOrLoad(this, pos, ctx, () -> rc); return cache.getOrLoad(this, pos, ctx, c);
} }
} }
@ -203,4 +203,41 @@ abstract class BlockBasedFile {
static long elapsedMicros(long start) { static long elapsedMicros(long start) {
return (System.nanoTime() - start) / 1000L; return (System.nanoTime() - start) / 1000L;
} }
/**
* A supplier of readable channel that opens the channel lazily.
*/
private static class LazyChannel
implements AutoCloseable, DfsBlockCache.ReadableChannelSupplier {
private final DfsReader ctx;
private final DfsPackDescription desc;
private final PackExt ext;
private ReadableChannel rc = null;
LazyChannel(DfsReader ctx, DfsPackDescription desc, PackExt ext) {
this.ctx = ctx;
this.desc = desc;
this.ext = ext;
}
@Override
public ReadableChannel get() throws IOException {
if (rc == null) {
synchronized (this) {
if (rc == null) {
rc = ctx.db.openFile(desc, ext);
}
}
}
return rc;
}
@Override
public void close() throws IOException {
if (rc != null) {
rc.close();
}
}
}
} }

2
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java

@ -754,7 +754,7 @@ public final class DfsBlockCache {
* Supplier for readable channel * Supplier for readable channel
*/ */
@FunctionalInterface @FunctionalInterface
public interface ReadableChannelSupplier { interface ReadableChannelSupplier {
/** /**
* @return ReadableChannel * @return ReadableChannel
* @throws IOException * @throws IOException

2
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java

@ -212,7 +212,7 @@ public class DfsBlockCacheConfig {
* consumer of wait time in milliseconds. * consumer of wait time in milliseconds.
* @return {@code this} * @return {@code this}
*/ */
public DfsBlockCacheConfig setReflockWaitTimeConsumer(Consumer<Long> c) { public DfsBlockCacheConfig setRefLockWaitTimeConsumer(Consumer<Long> c) {
refLock = c; refLock = c;
return this; return this;
} }

4
org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java

@ -128,9 +128,7 @@ public class DfsReftable extends BlockBasedFile {
open().setReadAheadBytes(readAhead); open().setReadAheadBytes(readAhead);
} }
DfsBlock block = cache.getOrLoad(file, pos, ctx, () -> { DfsBlock block = cache.getOrLoad(file, pos, ctx, () -> open());
return open();
});
if (block.start == pos && block.size() >= cnt) { if (block.start == pos && block.size() >= cnt) {
return block.zeroCopyByteBuffer(cnt); return block.zeroCopyByteBuffer(cnt);
} }

Loading…
Cancel
Save