From c9336bcff64b727773e7b17bc07f1e1a64a793ee Mon Sep 17 00:00:00 2001
From: Brad King <brad.king@kitware.com>
Date: Thu, 9 Jul 2015 15:47:19 -0400
Subject: [PATCH] SystemTools: Optimize GetActualCaseForPath memoization

Use a case-insensitive map key since paths of all case combinations
should map to the same actual case.  This may reduce the number
of copies of each path differing only by case in the map.

Change-Id: Ic5460fcf14fa263d45ef1909bf80a81c6f4791a4
---
 SystemTools.cxx    | 42 ++++++++++++++++++++++++++++++++++--------
 SystemTools.hxx.in |  6 +++++-
 2 files changed, 39 insertions(+), 9 deletions(-)

diff --git a/SystemTools.cxx b/SystemTools.cxx
index c171727..3452259 100644
--- a/SystemTools.cxx
+++ b/SystemTools.cxx
@@ -385,6 +385,26 @@ class SystemToolsTranslationMap :
 {
 };
 
+#ifdef _WIN32
+struct SystemToolsPathCaseCmp
+{
+  bool operator()(kwsys_stl::string const& l, kwsys_stl::string const& r) const
+    {
+# ifdef _MSC_VER
+    return _stricmp(l.c_str(), r.c_str()) < 0;
+# elif defined(__GNUC__)
+    return strcasecmp(l.c_str(), r.c_str()) < 0;
+# else
+    return SystemTools::Strucmp(l.c_str(), r.c_str()) < 0;
+# endif
+    }
+};
+
+class SystemToolsPathCaseMap:
+  public kwsys_stl::map<kwsys_stl::string, kwsys_stl::string,
+                        SystemToolsPathCaseCmp> {};
+#endif
+
 // adds the elements of the env variable path to the arg passed in
 void SystemTools::GetPath(kwsys_stl::vector<kwsys_stl::string>& path, const char* env)
 {
@@ -3751,10 +3771,10 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p)
   return p;
 #else
   // Check to see if actual case has already been called
-  // for this path, and the result is stored in the LongPathMap
-  SystemToolsTranslationMap::iterator i =
-    SystemTools::LongPathMap->find(p);
-  if(i != SystemTools::LongPathMap->end())
+  // for this path, and the result is stored in the PathCaseMap
+  SystemToolsPathCaseMap::iterator i =
+    SystemTools::PathCaseMap->find(p);
+  if(i != SystemTools::PathCaseMap->end())
     {
     return i->second;
     }
@@ -3764,7 +3784,7 @@ kwsys_stl::string SystemTools::GetActualCaseForPath(const kwsys_stl::string& p)
     {
     return p;
     }
-  (*SystemTools::LongPathMap)[p] = casePath;
+  (*SystemTools::PathCaseMap)[p] = casePath;
   return casePath;
 #endif
 }
@@ -5138,7 +5158,9 @@ bool SystemTools::ParseURL( const kwsys_stl::string& URL,
 // necessary.
 static unsigned int SystemToolsManagerCount;
 SystemToolsTranslationMap *SystemTools::TranslationMap;
-SystemToolsTranslationMap *SystemTools::LongPathMap;
+#ifdef _WIN32
+SystemToolsPathCaseMap *SystemTools::PathCaseMap;
+#endif
 #ifdef __CYGWIN__
 SystemToolsTranslationMap *SystemTools::Cyg2Win32Map;
 #endif
@@ -5186,7 +5208,9 @@ void SystemTools::ClassInitialize()
 #endif
   // Allocate the translation map first.
   SystemTools::TranslationMap = new SystemToolsTranslationMap;
-  SystemTools::LongPathMap = new SystemToolsTranslationMap;
+#ifdef _WIN32
+  SystemTools::PathCaseMap = new SystemToolsPathCaseMap;
+#endif
 #ifdef __CYGWIN__
   SystemTools::Cyg2Win32Map = new SystemToolsTranslationMap;
 #endif
@@ -5243,7 +5267,9 @@ void SystemTools::ClassInitialize()
 void SystemTools::ClassFinalize()
 {
   delete SystemTools::TranslationMap;
-  delete SystemTools::LongPathMap;
+#ifdef _WIN32
+  delete SystemTools::PathCaseMap;
+#endif
 #ifdef __CYGWIN__
   delete SystemTools::Cyg2Win32Map;
 #endif
diff --git a/SystemTools.hxx.in b/SystemTools.hxx.in
index 93cde02..7899141 100644
--- a/SystemTools.hxx.in
+++ b/SystemTools.hxx.in
@@ -54,6 +54,8 @@ namespace @KWSYS_NAMESPACE@
 {
 
 class SystemToolsTranslationMap;
+class SystemToolsPathCaseMap;
+
 /** \class SystemToolsManager
  * \brief Use to make sure SystemTools is initialized before it is used
  * and is the last static object destroyed
@@ -944,7 +946,9 @@ private:
    * Each time 'dir' will be found it will be replace by 'refdir'
    */
   static SystemToolsTranslationMap *TranslationMap;
-  static SystemToolsTranslationMap *LongPathMap;
+#ifdef _WIN32
+  static SystemToolsPathCaseMap *PathCaseMap;
+#endif
 #ifdef __CYGWIN__
   static SystemToolsTranslationMap *Cyg2Win32Map;
 #endif
-- 
GitLab