Răsfoiți Sursa

cmSystemTools: Cache ToNormalizedPathOnDisk actual-case lookups

Prior to re-implementing `ToNormalizedPathOnDisk`, its use of KWSys's
`GetActualCaseForPathCached` cached file actual-case lookups to avoid
redundant filesystem access.  Add caching to the actual-case lookups we
do for `cm::PathResolver`.
Brad King 11 luni în urmă
părinte
comite
b378781c5d
1 a modificat fișierele cu 24 adăugiri și 1 ștergeri
  1. 24 1
      Source/cmSystemTools.cxx

+ 24 - 1
Source/cmSystemTools.cxx

@@ -22,6 +22,10 @@
 
 #include <iterator>
 
+#ifdef _WIN32
+#  include <unordered_map>
+#endif
+
 #include <cm/optional>
 #include <cmext/algorithm>
 #include <cmext/string_view>
@@ -211,9 +215,28 @@ public:
   {
     return GetDosDriveWorkingDirectory(letter);
   }
+
+  struct NameOnDisk
+  {
+    cmsys::Status Status;
+    std::string Name;
+  };
+  using NameOnDiskMap = std::unordered_map<std::string, NameOnDisk>;
+  NameOnDiskMap CachedNameOnDisk;
+
   cmsys::Status ReadName(std::string const& path, std::string& name) override
   {
-    return ReadNameOnDisk(path, name);
+    // Cache results to avoid repeated filesystem access.
+    // We assume any files created by our own process keep their case.
+    // Index the cache by lower-case paths to make it case-insensitive.
+    std::string path_lower = cmSystemTools::LowerCase(path);
+    auto i = this->CachedNameOnDisk.find(path_lower);
+    if (i == this->CachedNameOnDisk.end()) {
+      i = this->CachedNameOnDisk.emplace(path_lower, NameOnDisk()).first;
+      i->second.Status = ReadNameOnDisk(path, i->second.Name);
+    }
+    name = i->second.Name;
+    return i->second.Status;
   }
 #endif
 };