Fix empty directory handling (#10319)

Co-authored-by: Atul Mohan <atulmohan@yahoo-inc.com>
This commit is contained in:
Atul Mohan 2020-12-02 12:37:08 -06:00 committed by GitHub
parent 2e02eebd9d
commit f965464f36
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 74 additions and 12 deletions

View File

@ -29,6 +29,8 @@ import java.util.Iterator;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
/** /**
* An iterator that walks through the file tree for a given {@link Path} and returns {@link FileStatus} for every
* file encountered within the hierarchy.
*/ */
public class FSSpideringIterator implements Iterator<FileStatus> public class FSSpideringIterator implements Iterator<FileStatus>
{ {
@ -60,8 +62,9 @@ public class FSSpideringIterator implements Iterator<FileStatus>
private final FileSystem fs; private final FileSystem fs;
private final FileStatus[] statii; private final FileStatus[] statii;
private FileStatus nextStatus = null;
FSSpideringIterator statuses = null; private FSSpideringIterator statuses = null;
int index = 0; int index = 0;
public FSSpideringIterator( public FSSpideringIterator(
@ -76,29 +79,43 @@ public class FSSpideringIterator implements Iterator<FileStatus>
@Override @Override
public boolean hasNext() public boolean hasNext()
{ {
if (statuses != null && !statuses.hasNext()) { fetchNextIfNeeded();
statuses = null; return nextStatus != null;
index++;
}
return index < statii.length;
} }
@Override @Override
public FileStatus next() public FileStatus next()
{ {
while (hasNext()) { fetchNextIfNeeded();
if (statii[index].isDir()) { if (nextStatus == null) {
throw new NoSuchElementException();
}
FileStatus result = nextStatus;
nextStatus = null;
return result;
}
private void fetchNextIfNeeded()
{
while (nextStatus == null && index < statii.length) {
if (statii[index].isDirectory()) {
if (statuses == null) { if (statuses == null) {
statuses = spiderPathPropagateExceptions(fs, statii[index].getPath()); statuses = spiderPathPropagateExceptions(fs, statii[index].getPath());
} else if (statuses.hasNext()) { } else if (statuses.hasNext()) {
return statuses.next(); nextStatus = statuses.next();
} else {
if (index == statii.length - 1) {
return;
}
statuses = null;
index++;
} }
} else { } else {
++index; ++index;
return statii[index - 1]; nextStatus = statii[index - 1];
} }
} }
throw new NoSuchElementException();
} }
@Override @Override

View File

@ -40,7 +40,7 @@ import java.util.List;
public class FSSpideringIteratorTest public class FSSpideringIteratorTest
{ {
@Test @Test
public void testIterator() public void testNonEmptyDirs()
{ {
String[] testFiles = {"file1", "file2", "file3", "file4", "file5"}; String[] testFiles = {"file1", "file2", "file3", "file4", "file5"};
@ -92,4 +92,49 @@ public class FSSpideringIteratorTest
} }
} }
} }
@Test
public void testEmptyDirs()
{
File baseDir = FileUtils.createTempDir();
try {
new File(baseDir, "dir1").mkdir();
new File(baseDir, "dir2/subDir1").mkdirs();
new File(baseDir, "dir2/subDir2").mkdirs();
new File(baseDir, "dir3/subDir1").mkdirs();
List<String> files = Lists.newArrayList(
Iterables.transform(
FSSpideringIterator.spiderIterable(
FileSystem.getLocal(new Configuration()),
new Path(baseDir.toString())
),
new Function<FileStatus, String>()
{
@Override
public String apply(@Nullable FileStatus input)
{
return input.getPath().getName();
}
}
)
);
Assert.assertTrue(files.isEmpty());
}
catch (IOException e) {
throw new RuntimeException(e);
}
finally {
try {
FileUtils.deleteDirectory(baseDir);
}
catch (IOException e) {
throw new RuntimeException(e);
}
}
}
} }