Skip to content

Commit 65fe089

Browse files
zhangyue19921010yuezhang
authored andcommitted
[HUDI-3281][Performance]Tuning performance of getAllPartitionPaths API in FileSystemBackedTableMetadata (apache#4643)
Co-authored-by: yuezhang <yuezhang@freewheel.tv>
1 parent 636445e commit 65fe089

1 file changed

Lines changed: 21 additions & 26 deletions

File tree

hudi-common/src/main/java/org/apache/hudi/metadata/FileSystemBackedTableMetadata.java

Lines changed: 21 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,11 @@
3131
import org.apache.hadoop.fs.Path;
3232

3333
import java.io.IOException;
34-
import java.util.ArrayList;
3534
import java.util.Arrays;
3635
import java.util.Collections;
37-
import java.util.LinkedList;
3836
import java.util.List;
3937
import java.util.Map;
38+
import java.util.concurrent.CopyOnWriteArrayList;
4039
import java.util.stream.Collectors;
4140

4241
public class FileSystemBackedTableMetadata implements HoodieTableMetadata {
@@ -64,45 +63,41 @@ public FileStatus[] getAllFilesInPartition(Path partitionPath) throws IOExceptio
6463

6564
@Override
6665
public List<String> getAllPartitionPaths() throws IOException {
66+
FileSystem fs = new Path(datasetBasePath).getFileSystem(hadoopConf.get());
6767
if (assumeDatePartitioning) {
68-
FileSystem fs = new Path(datasetBasePath).getFileSystem(hadoopConf.get());
6968
return FSUtils.getAllPartitionFoldersThreeLevelsDown(fs, datasetBasePath);
7069
}
7170

72-
List<Path> pathsToList = new LinkedList<>();
71+
List<Path> pathsToList = new CopyOnWriteArrayList<>();
7372
pathsToList.add(new Path(datasetBasePath));
74-
List<String> partitionPaths = new ArrayList<>();
73+
List<String> partitionPaths = new CopyOnWriteArrayList<>();
7574

7675
while (!pathsToList.isEmpty()) {
7776
// TODO: Get the parallelism from HoodieWriteConfig
7877
int listingParallelism = Math.min(DEFAULT_LISTING_PARALLELISM, pathsToList.size());
7978

8079
// List all directories in parallel
81-
List<Pair<Path, FileStatus[]>> dirToFileListing = engineContext.map(pathsToList, path -> {
80+
List<FileStatus[]> dirToFileListing = engineContext.map(pathsToList, path -> {
8281
FileSystem fileSystem = path.getFileSystem(hadoopConf.get());
83-
return Pair.of(path, fileSystem.listStatus(path));
82+
return fileSystem.listStatus(path);
8483
}, listingParallelism);
8584
pathsToList.clear();
8685

87-
// If the listing reveals a directory, add it to queue. If the listing reveals a hoodie partition, add it to
88-
// the results.
89-
dirToFileListing.forEach(p -> {
90-
Option<FileStatus> partitionMetaFile = Option.fromJavaOptional(Arrays.stream(p.getRight()).parallel()
91-
.filter(fs -> fs.getPath().getName().equals(HoodiePartitionMetadata.HOODIE_PARTITION_METAFILE))
92-
.findFirst());
93-
94-
if (partitionMetaFile.isPresent()) {
95-
// Is a partition.
96-
String partitionName = FSUtils.getRelativePartitionPath(new Path(datasetBasePath), p.getLeft());
97-
partitionPaths.add(partitionName);
98-
} else {
99-
// Add sub-dirs to the queue
100-
pathsToList.addAll(Arrays.stream(p.getRight())
101-
.filter(fs -> fs.isDirectory() && !fs.getPath().getName().equals(HoodieTableMetaClient.METAFOLDER_NAME))
102-
.map(fs -> fs.getPath())
103-
.collect(Collectors.toList()));
104-
}
105-
});
86+
// if current dictionary contains PartitionMetadata, add it to result
87+
// if current dictionary does not contain PartitionMetadata, add it to queue
88+
dirToFileListing.stream().flatMap(Arrays::stream).parallel()
89+
.forEach(fileStatus -> {
90+
if (fileStatus.isDirectory()) {
91+
if (HoodiePartitionMetadata.hasPartitionMetadata(fs, fileStatus.getPath())) {
92+
partitionPaths.add(FSUtils.getRelativePartitionPath(new Path(datasetBasePath), fileStatus.getPath()));
93+
} else if (!fileStatus.getPath().getName().equals(HoodieTableMetaClient.METAFOLDER_NAME)) {
94+
pathsToList.add(fileStatus.getPath());
95+
}
96+
} else if (fileStatus.getPath().getName().equals(HoodiePartitionMetadata.HOODIE_PARTITION_METAFILE)) {
97+
String partitionName = FSUtils.getRelativePartitionPath(new Path(datasetBasePath), fileStatus.getPath().getParent());
98+
partitionPaths.add(partitionName);
99+
}
100+
});
106101
}
107102
return partitionPaths;
108103
}

0 commit comments

Comments
 (0)