diff --git a/gcsio/src/main/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManager.java b/gcsio/src/main/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManager.java index 04771e201..659f43dd6 100644 --- a/gcsio/src/main/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManager.java +++ b/gcsio/src/main/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManager.java @@ -65,12 +65,10 @@ public void updateAccessPattern(long currentPosition) { return; } if (readOptions.getFadvise() == Fadvise.AUTO_RANDOM) { - if (randomAccess) { + if (isBackwardOrForwardSeekNotRequested()) { if (isSequentialAccessPattern(currentPosition)) { unsetRandomAccess(); - } - } else { - if (isRandomAccessPattern(currentPosition)) { + } else if (isRandomAccessPattern(currentPosition)) { setRandomAccess(); } } @@ -151,18 +149,21 @@ private boolean isRandomAccessPattern(long currentPosition) { return false; } + private boolean isBackwardOrForwardSeekNotRequested() { + return !isBackwardSeekRequested && !isForwardSeekRequested; + } + private boolean shouldDetectSequentialAccess() { return randomAccess - && !isBackwardSeekRequested - && !isForwardSeekRequested + && isBackwardOrForwardSeekNotRequested() && consecutiveSequentialCount >= readOptions.getFadviseRequestTrackCount() && readOptions.getFadvise() == Fadvise.AUTO_RANDOM; } private boolean shouldDetectRandomAccess() { - return !randomAccess - && (readOptions.getFadvise() == Fadvise.AUTO - || readOptions.getFadvise() == Fadvise.AUTO_RANDOM); + return (!randomAccess && readOptions.getFadvise() == Fadvise.AUTO) + || (isBackwardOrForwardSeekNotRequested() + && readOptions.getFadvise() == Fadvise.AUTO_RANDOM); } private void setRandomAccess() { diff --git a/gcsio/src/test/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManagerTest.java b/gcsio/src/test/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManagerTest.java index 030a3f4f8..3cc3bc97f 100644 --- a/gcsio/src/test/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManagerTest.java +++ b/gcsio/src/test/java/com/google/cloud/hadoop/gcsio/FileAccessPatternManagerTest.java @@ -169,5 +169,28 @@ public void testAutoRandomMode() { assertThat(fileAccessPattern.isRandomAccessPattern()).isEqualTo(expectedRandomAccess[i]); fileAccessPattern.updateLastServedIndex(currentPosition); } + + // R --> R backward seek + // a backward seek should lock the random pattern + readIndexes = new long[] {4, 1, 2, 3, 4, 5, 0, 1, 2, 3, 4}; + expectedRandomAccess = + new boolean[] {true, true, true, true, true, true, true, true, true, true, true}; + for (int i = 0; i < readIndexes.length; i++) { + long currentPosition = readIndexes[i]; + fileAccessPattern.updateAccessPattern(currentPosition); + assertThat(fileAccessPattern.isRandomAccessPattern()).isEqualTo(expectedRandomAccess[i]); + fileAccessPattern.updateLastServedIndex(currentPosition); + } + + // R --> R forward seek + // a forward seek should lock the random pattern + readIndexes = new long[] {0, 11, 12, 13, 14, 15}; + expectedRandomAccess = new boolean[] {true, true, true, true, true, true}; + for (int i = 0; i < readIndexes.length; i++) { + long currentPosition = readIndexes[i]; + fileAccessPattern.updateAccessPattern(currentPosition); + assertThat(fileAccessPattern.isRandomAccessPattern()).isEqualTo(expectedRandomAccess[i]); + fileAccessPattern.updateLastServedIndex(currentPosition); + } } }