From 513d80db1066beaa284c97b1515cd069049f6f05 Mon Sep 17 00:00:00 2001 From: Minh Thai Date: Wed, 9 Jan 2019 12:53:51 -0800 Subject: [PATCH] Lazily open ReadableChannel in BlockBasedFile.getOrLoadBlock To avoid opening the readable channel in case of DfsBlockCache hits. Also cleaning up typos around DfsBlockCache. Change-Id: I615e349cb4838387c1e6743cdc384d1b81b54369 Signed-off-by: Minh Thai --- .../internal/storage/dfs/BlockBasedFile.java | 41 ++++++++++++++++++- .../internal/storage/dfs/DfsBlockCache.java | 2 +- .../storage/dfs/DfsBlockCacheConfig.java | 2 +- .../internal/storage/dfs/DfsReftable.java | 4 +- 4 files changed, 42 insertions(+), 7 deletions(-) diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java index 600b1a44d..4d1474244 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/BlockBasedFile.java +++ b/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 { - try (ReadableChannel rc = ctx.db.openFile(desc, ext)) { - return cache.getOrLoad(this, pos, ctx, () -> rc); + try (LazyChannel c = new LazyChannel(ctx, desc, ext)) { + return cache.getOrLoad(this, pos, ctx, c); } } @@ -203,4 +203,41 @@ abstract class BlockBasedFile { static long elapsedMicros(long start) { 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(); + } + } + } } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java index d9e9327d3..c6e2fae42 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCache.java @@ -754,7 +754,7 @@ public final class DfsBlockCache { * Supplier for readable channel */ @FunctionalInterface - public interface ReadableChannelSupplier { + interface ReadableChannelSupplier { /** * @return ReadableChannel * @throws IOException diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java index eea9ef4e0..cd1fa5f78 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsBlockCacheConfig.java +++ b/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. * @return {@code this} */ - public DfsBlockCacheConfig setReflockWaitTimeConsumer(Consumer c) { + public DfsBlockCacheConfig setRefLockWaitTimeConsumer(Consumer c) { refLock = c; return this; } diff --git a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java index a80797730..485329801 100644 --- a/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java +++ b/org.eclipse.jgit/src/org/eclipse/jgit/internal/storage/dfs/DfsReftable.java @@ -128,9 +128,7 @@ public class DfsReftable extends BlockBasedFile { open().setReadAheadBytes(readAhead); } - DfsBlock block = cache.getOrLoad(file, pos, ctx, () -> { - return open(); - }); + DfsBlock block = cache.getOrLoad(file, pos, ctx, () -> open()); if (block.start == pos && block.size() >= cnt) { return block.zeroCopyByteBuffer(cnt); }