HADOOP-17323. S3A getFileStatus("/") to skip IO (#2479)

Contributed by Mukund Thakur.
This commit is contained in:
Mukund Thakur 2020-11-24 16:36:56 +05:30 committed by GitHub
parent c4ba0ab7df
commit 5fee95076b
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 0 deletions

View File

@ -3144,6 +3144,10 @@ public class S3AFileSystem extends FileSystem implements StreamCapabilities,
"s3GetFileStatus(%s) wants to know if a directory is empty but" "s3GetFileStatus(%s) wants to know if a directory is empty but"
+ " does not request a list probe", path); + " does not request a list probe", path);
if (key.isEmpty() && !needEmptyDirectoryFlag) {
return new S3AFileStatus(Tristate.UNKNOWN, path, username);
}
if (!key.isEmpty() && !key.endsWith("/") if (!key.isEmpty() && !key.endsWith("/")
&& probes.contains(StatusProbeEnum.Head)) { && probes.contains(StatusProbeEnum.Head)) {
try { try {

View File

@ -29,6 +29,7 @@ import org.apache.hadoop.fs.s3a.performance.AbstractS3ACostTest;
import org.junit.Test; import org.junit.Test;
import org.junit.runner.RunWith; import org.junit.runner.RunWith;
import org.junit.runners.Parameterized; import org.junit.runners.Parameterized;
import org.assertj.core.api.Assertions;
import org.slf4j.Logger; import org.slf4j.Logger;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
@ -258,6 +259,36 @@ public class ITestS3AFileOperationCost extends AbstractS3ACostTest {
GET_FILE_STATUS_FNFE); GET_FILE_STATUS_FNFE);
} }
@Test
public void testCostOfRootFileStatus() throws Throwable {
Path root = path("/");
S3AFileStatus rootStatus = verifyRawInnerGetFileStatus(
root,
false,
StatusProbeEnum.ALL,
ROOT_FILE_STATUS_PROBE);
String rootStatusContent = rootStatus.toString();
Assertions.assertThat(rootStatus.isDirectory())
.describedAs("Status returned should be a directory "
+ rootStatusContent)
.isEqualTo(true);
Assertions.assertThat(rootStatus.isEmptyDirectory())
.isEqualTo(Tristate.UNKNOWN);
rootStatus = verifyRawInnerGetFileStatus(
root,
true,
StatusProbeEnum.ALL,
FILE_STATUS_DIR_PROBE);
Assertions.assertThat(rootStatus.isDirectory())
.describedAs("Status returned should be a directory "
+ rootStatusContent)
.isEqualTo(true);
Assertions.assertThat(rootStatus.isEmptyDirectory())
.isNotEqualByComparingTo(Tristate.UNKNOWN);
}
@Test @Test
public void testIsDirIsFileMissingPath() throws Throwable { public void testIsDirIsFileMissingPath() throws Throwable {
describe("performing isDir and isFile on a missing file"); describe("performing isDir and isFile on a missing file");

View File

@ -76,6 +76,11 @@ public final class OperationCost {
*/ */
public static final OperationCost FILE_STATUS_FILE_PROBE = HEAD_OPERATION; public static final OperationCost FILE_STATUS_FILE_PROBE = HEAD_OPERATION;
/**
* Cost of getFileStatus on root directory.
*/
public static final OperationCost ROOT_FILE_STATUS_PROBE = NO_IO;
/** /**
* Cost of {@link org.apache.hadoop.fs.s3a.impl.StatusProbeEnum#ALL}. * Cost of {@link org.apache.hadoop.fs.s3a.impl.StatusProbeEnum#ALL}.
*/ */