summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBrad King <brad.king@kitware.com>2024-06-05 13:21:12 (GMT)
committerKitware Robot <kwrobot@kitware.com>2024-06-05 13:21:31 (GMT)
commit311cc37e767a28465438fa789d26e8e44d486e60 (patch)
tree49af539888f8001602fc46441555cb229137e5ab
parentc3878be97ffbabd48e5b43ca417f13d24c3dfc7e (diff)
parentc598a4609c103aa94b08fc2537265caf77a96e81 (diff)
downloadCMake-311cc37e767a28465438fa789d26e8e44d486e60.zip
CMake-311cc37e767a28465438fa789d26e8e44d486e60.tar.gz
CMake-311cc37e767a28465438fa789d26e8e44d486e60.tar.bz2
Merge topic 'cmFileSet-FixWindowsPerformance'
c598a4609c cmFileSet: Fix poor performance of large file sets with export() on Windows Acked-by: Kitware Robot <kwrobot@kitware.com> Acked-by: buildbot <buildbot@kitware.com> Merge-request: !9572
-rw-r--r--Source/cmFileSet.cxx36
1 files changed, 31 insertions, 5 deletions
diff --git a/Source/cmFileSet.cxx b/Source/cmFileSet.cxx
index b74855f..a00c10e 100644
--- a/Source/cmFileSet.cxx
+++ b/Source/cmFileSet.cxx
@@ -4,9 +4,11 @@
#include <sstream>
#include <string>
+#include <unordered_map>
#include <utility>
#include <vector>
+#include <cm/optional>
#include <cmext/algorithm>
#include <cmext/string_view>
@@ -158,6 +160,13 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
const cmGeneratorTarget* target,
cmGeneratorExpressionDAGChecker* dagChecker) const
{
+ struct DirCacheEntry
+ {
+ std::string collapsedDir;
+ cm::optional<cmSystemTools::FileId> fileId;
+ };
+
+ std::unordered_map<std::string, DirCacheEntry> dirCache;
std::vector<std::string> result;
for (auto const& cge : cges) {
auto entry = cge->Evaluate(lg, config, target, dagChecker);
@@ -166,12 +175,29 @@ std::vector<std::string> cmFileSet::EvaluateDirectoryEntries(
if (!cmSystemTools::FileIsFullPath(dir)) {
dir = cmStrCat(lg->GetCurrentSourceDirectory(), '/', dir);
}
- auto collapsedDir = cmSystemTools::CollapseFullPath(dir);
+
+ auto dirCacheResult = dirCache.emplace(dir, DirCacheEntry());
+ auto& dirCacheEntry = dirCacheResult.first->second;
+ const auto isNewCacheEntry = dirCacheResult.second;
+
+ if (isNewCacheEntry) {
+ cmSystemTools::FileId fileId;
+ auto isFileIdValid = cmSystemTools::GetFileId(dir, fileId);
+ dirCacheEntry.collapsedDir = cmSystemTools::CollapseFullPath(dir);
+ dirCacheEntry.fileId =
+ isFileIdValid ? cm::optional<decltype(fileId)>(fileId) : cm::nullopt;
+ }
+
for (auto const& priorDir : result) {
- auto collapsedPriorDir = cmSystemTools::CollapseFullPath(priorDir);
- if (!cmSystemTools::SameFile(collapsedDir, collapsedPriorDir) &&
- (cmSystemTools::IsSubDirectory(collapsedDir, collapsedPriorDir) ||
- cmSystemTools::IsSubDirectory(collapsedPriorDir, collapsedDir))) {
+ auto priorDirCacheEntry = dirCache.at(priorDir);
+ bool sameFile = dirCacheEntry.fileId.has_value() &&
+ priorDirCacheEntry.fileId.has_value() &&
+ (*dirCacheEntry.fileId == *priorDirCacheEntry.fileId);
+ if (!sameFile &&
+ (cmSystemTools::IsSubDirectory(dirCacheEntry.collapsedDir,
+ priorDirCacheEntry.collapsedDir) ||
+ cmSystemTools::IsSubDirectory(priorDirCacheEntry.collapsedDir,
+ dirCacheEntry.collapsedDir))) {
lg->GetCMakeInstance()->IssueMessage(
MessageType::FATAL_ERROR,
cmStrCat(