Support: Have directory_iterator::status() return FindFirstFileEx/FindNextFile results on Windows.
This allows clients to avoid an unnecessary fs::status() call on each
directory entry. Because the information returned by FindFirstFileEx
is a subset of the information returned by a regular status() call,
I needed to extract a base class from file_status that contains only
that information.
On my machine, this reduces the time required to enumerate a ThinLTO
cache directory containing 520k files from almost 4 minutes to less
than 2 seconds.
Differential Revision: https://reviews.llvm.org/D38716
llvm-svn: 315378
diff --git a/llvm/lib/Support/CachePruning.cpp b/llvm/lib/Support/CachePruning.cpp
index 60d0964..5a9580c 100644
--- a/llvm/lib/Support/CachePruning.cpp
+++ b/llvm/lib/Support/CachePruning.cpp
@@ -182,19 +182,9 @@
bool ShouldComputeSize =
(Policy.MaxSizePercentageOfAvailableSpace > 0 || Policy.MaxSizeBytes > 0);
- // Keep track of space
+ // Keep track of space. Needs to be kept ordered by size for determinism.
std::set<std::pair<uint64_t, std::string>> FileSizes;
uint64_t TotalSize = 0;
- // Helper to add a path to the set of files to consider for size-based
- // pruning, sorted by size.
- auto AddToFileListForSizePruning =
- [&](StringRef Path) {
- if (!ShouldComputeSize)
- return;
- TotalSize += FileStatus.getSize();
- FileSizes.insert(
- std::make_pair(FileStatus.getSize(), std::string(Path)));
- };
// Walk the entire directory cache, looking for unused files.
std::error_code EC;
@@ -212,13 +202,14 @@
// Look at this file. If we can't stat it, there's nothing interesting
// there.
- if (sys::fs::status(File->path(), FileStatus)) {
+ ErrorOr<sys::fs::basic_file_status> StatusOrErr = File->status();
+ if (!StatusOrErr) {
DEBUG(dbgs() << "Ignore " << File->path() << " (can't stat)\n");
continue;
}
// If the file hasn't been used recently enough, delete it
- const auto FileAccessTime = FileStatus.getLastAccessedTime();
+ const auto FileAccessTime = StatusOrErr->getLastAccessedTime();
auto FileAge = CurrentTime - FileAccessTime;
if (FileAge > Policy.Expiration) {
DEBUG(dbgs() << "Remove " << File->path() << " ("
@@ -228,7 +219,10 @@
}
// Leave it here for now, but add it to the list of size-based pruning.
- AddToFileListForSizePruning(File->path());
+ if (!ShouldComputeSize)
+ continue;
+ TotalSize += StatusOrErr->getSize();
+ FileSizes.insert({StatusOrErr->getSize(), std::string(File->path())});
}
// Prune for size now if needed