Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prefetcher, to read fast. #3054

Merged
merged 4 commits into from
Apr 3, 2018

Conversation

jean-philippe-martin
Copy link

The prefetcher can load data on another thread in between calls,
and it can intelligently use its existing buffer to deal with small
seeks without having to fetch again.

The prefetcher can load data on another thread in between calls,
and it can intelligently use its existing buffer to deal with small
seeks without having to fetch again.
@googlebot googlebot added the cla: yes This human has signed the Contributor License Agreement. label Mar 16, 2018
@jean-philippe-martin
Copy link
Author

@pongad, I understand the ball is in your camp? If it isn't then please let me know what you'd like me to do before you look at this PR.

Copy link
Contributor

@pongad pongad left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@jean-philippe-martin Thank you for the PR! I made a few comments. @garrettjonesgoogle @jabubake Could you also take a look?

@@ -0,0 +1,496 @@
/*
* Copyright 2016 Google LLC

This comment was marked as spam.

This comment was marked as spam.


// statistics, for profiling
// time spent blocking the user because we're waiting on the network
public long msWaitingForData;

This comment was marked as spam.

This comment was marked as spam.

* @param bufSize buffer size in bytes
* @param chan channel to wrap in the prefetcher
*/
public SeekableByteChannelPrefetcher(SeekableByteChannel chan, int bufSize) throws IOException {

This comment was marked as spam.

This comment was marked as spam.

*/
public SeekableByteChannelPrefetcher(SeekableByteChannel chan, int bufSize) throws IOException {
if (chan instanceof SeekableByteChannelPrefetcher) {
throw new IllegalArgumentException("Cannot put two prefetchers on the same channel.");

This comment was marked as spam.

This comment was marked as spam.

// if we don't already have that block and the fetching thread is idle,
// make sure it now goes looking for that block index.
private void ensureFetching(long blockIndex) {
if (null != fetching) {

This comment was marked as spam.

This comment was marked as spam.

this.bufSize = bufSize;
}
this.open = true;
int prefetcherIndex = prefetcherCount++;

This comment was marked as spam.

This comment was marked as spam.

fetching = full.remove(0);
fetching.resetForIndex(blockIndex);
bytesRead += bufSize;
fetching.futureBuf = exec.submit(fetching);

This comment was marked as spam.

This comment was marked as spam.

@jean-philippe-martin
Copy link
Author

In case you'd like extra eyes, @jart is familiar with this code and may be willing to help review.

@jabubake
Copy link
Contributor

@frankyn FYI

@pongad
Copy link
Contributor

pongad commented Mar 28, 2018

I'm good with this. @jabubake Do you also want to take a look?

@@ -0,0 +1,494 @@
/*
* Copyright 2018 Google LLC

This comment was marked as spam.

This comment was marked as spam.

exec = Executors.newFixedThreadPool(1, threadFactory);
}

public String getStatistics() {

This comment was marked as spam.

This comment was marked as spam.

.setDaemon(true)
.build();
// Single thread to ensure no concurrent access to chan.
exec = Executors.newFixedThreadPool(1, threadFactory);

This comment was marked as spam.

This comment was marked as spam.

// Make sure the prefetching thread's name indicate what it is and
// which prefetcher it belongs to (for debugging purposes only, naturally).
String nameFormat = "nio-prefetcher-" + prefetcherIndex + "-thread-%d";
ThreadFactory threadFactory = new ThreadFactoryBuilder()

This comment was marked as spam.

*/
@Override
public SeekableByteChannel position(long newPosition) throws IOException {
if (!open) throw new ClosedChannelException();

This comment was marked as spam.

This comment was marked as spam.

* the entity to grow to accommodate the new bytes; the values of any bytes
* between the previous end-of-file and the newly-written bytes are
* unspecified.
* <p>

This comment was marked as spam.

This comment was marked as spam.

.build();
// Single thread to ensure no concurrent access to chan.
exec = Executors.newFixedThreadPool(1, threadFactory);
}

This comment was marked as spam.

This comment was marked as spam.

* (Of course this is only worthwhile if the underlying SeekableByteChannel doesn't already
* implement prefetching).
*/
public final class SeekableByteChannelPrefetcher implements SeekableByteChannel {

This comment was marked as spam.

This comment was marked as spam.

@pongad pongad merged commit 6bccbce into googleapis:master Apr 3, 2018
@jean-philippe-martin jean-philippe-martin deleted the jp_prefetcher branch April 16, 2018 18:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
cla: yes This human has signed the Contributor License Agreement.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants