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 <mthai@google.com>
This commit is contained in:
parent
23c30c6310
commit
513d80db10
|
@ -129,8 +129,8 @@ else if (size < cache.getBlockSize())
|
|||
}
|
||||
|
||||
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 @@ static int read(ReadableChannel rc, ByteBuffer buf) throws IOException {
|
|||
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();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -754,7 +754,7 @@ interface RefLoader<T> {
|
|||
* Supplier for readable channel
|
||||
*/
|
||||
@FunctionalInterface
|
||||
public interface ReadableChannelSupplier {
|
||||
interface ReadableChannelSupplier {
|
||||
/**
|
||||
* @return ReadableChannel
|
||||
* @throws IOException
|
||||
|
|
|
@ -212,7 +212,7 @@ public Consumer<Long> getRefLockWaitTimeConsumer() {
|
|||
* consumer of wait time in milliseconds.
|
||||
* @return {@code this}
|
||||
*/
|
||||
public DfsBlockCacheConfig setReflockWaitTimeConsumer(Consumer<Long> c) {
|
||||
public DfsBlockCacheConfig setRefLockWaitTimeConsumer(Consumer<Long> c) {
|
||||
refLock = c;
|
||||
return this;
|
||||
}
|
||||
|
|
|
@ -128,9 +128,7 @@ public ByteBuffer read(long pos, int cnt) throws IOException {
|
|||
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);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue