diff options
author | Brad King <brad.king@kitware.com> | 2024-06-05 13:21:12 (GMT) |
---|---|---|
committer | Kitware Robot <kwrobot@kitware.com> | 2024-06-05 13:21:31 (GMT) |
commit | 311cc37e767a28465438fa789d26e8e44d486e60 (patch) | |
tree | 49af539888f8001602fc46441555cb229137e5ab | |
parent | c3878be97ffbabd48e5b43ca417f13d24c3dfc7e (diff) | |
parent | c598a4609c103aa94b08fc2537265caf77a96e81 (diff) | |
download | CMake-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.cxx | 36 |
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( |