diff libinterp/corefcn/load-path.cc @ 29300:8b65dc1fd34d stable

load-path.cc: Reduce number of times "canonicalize_file_name" is called (bug #59711). * libinterp/corefcn/load-path.cc (load_path::dir_info::update, load_path::dir_info::initialize): Canonicalize paths for members "abs_dir_name" and "abs_dir_cache". (load_path::find_file, load_path::find_dir, load_path::find_matching_dirs, load_path::find_first_of, load_path::find_all_first_of, load_path::package_info::move, load_path::package_info::add_to_fcn_map,): Use (canonicalized) "abs_dir_name" instead of "dir_name". (load_path::package_info::remove, load_path::package_info::add_to_private_fcn_map, load_path::package_info::add_to_method_map, load_path::package_info::remove_private_fcn_map): Do not call "canonicalize_file_name" on (modified) absolute path again.
author Markus Mützel <markus.muetzel@gmx.de>
date Sat, 16 Jan 2021 13:32:57 +0100
parents 37584021e209
children 1ece396fe3df 0a5b15007766
line wrap: on
line diff
--- a/libinterp/corefcn/load-path.cc	Tue Jan 12 08:46:46 2021 -0800
+++ b/libinterp/corefcn/load-path.cc	Sat Jan 16 13:32:57 2021 +0100
@@ -56,9 +56,9 @@
   static std::string
   maybe_canonicalize (const std::string& dir_arg)
   {
-    bool is_absolute_path = octave::sys::env::absolute_pathname (dir_arg);
-
-    std::string canonical_dir = octave::sys::canonicalize_file_name (dir_arg);
+    bool is_absolute_path = sys::env::absolute_pathname (dir_arg);
+
+    std::string canonical_dir = sys::canonicalize_file_name (dir_arg);
     std::string dir;
     if (canonical_dir.empty ())
       dir = dir_arg;
@@ -70,7 +70,7 @@
           {
             // Remove current path from absolute path generated by
             // canonicalize_file_name.
-            std::string cwd = octave::sys::canonicalize_file_name (".");
+            std::string cwd = sys::canonicalize_file_name (".");
             if (dir.compare (0, cwd.length (), cwd) == 0)
               dir.erase (0, cwd.length ()+1);
             if (dir.empty ())
@@ -561,7 +561,7 @@
         // element of the load path in turn.
         for (const auto& di : dir_info_list)
           {
-            std::string tfile = sys::file_ops::concat (di.dir_name, file);
+            std::string tfile = sys::file_ops::concat (di.abs_dir_name, file);
 
             sys::file_stat fs (tfile);
 
@@ -581,7 +581,7 @@
             for (octave_idx_type i = 0; i < len; i++)
               {
                 if (all_files[i] == file)
-                  return sys::file_ops::concat (di.dir_name, file);
+                  return sys::file_ops::concat (di.abs_dir_name, file);
               }
           }
       }
@@ -608,7 +608,7 @@
         std::string canon_dir = maybe_canonicalize (dir);
         for (const auto& di : dir_info_list)
           {
-            std::string dname = sys::env::make_absolute (di.dir_name);
+            std::string dname = di.abs_dir_name;
 
             size_t dname_len = dname.length ();
 
@@ -628,7 +628,7 @@
                 sys::file_stat fs (di.dir_name);
 
                 if (fs.exists () && fs.is_dir ())
-                  return di.dir_name;
+                  return di.abs_dir_name;
               }
           }
       }
@@ -655,7 +655,7 @@
         std::string canon_dir = maybe_canonicalize (dir);
         for (const auto& di : dir_info_list)
           {
-            std::string dname = sys::env::make_absolute (di.dir_name);
+            std::string dname = di.abs_dir_name;
 
             size_t dname_len = dname.length ();
 
@@ -675,7 +675,7 @@
                 sys::file_stat fs (di.dir_name);
 
                 if (fs.exists () && fs.is_dir ())
-                  retlist.push_back (di.dir_name);
+                  retlist.push_back (di.abs_dir_name);
               }
           }
       }
@@ -716,7 +716,7 @@
                 for (const auto& di : dir_info_list)
                   {
                     std::string tfile;
-                    tfile = sys::file_ops::concat (di.dir_name, file);
+                    tfile = sys::file_ops::concat (di.abs_dir_name, file);
 
                     sys::file_stat fs (tfile);
 
@@ -743,7 +743,7 @@
               {
                 if (all_files[i] == rel_flist[j])
                   {
-                    dir_name = di.dir_name;
+                    dir_name = di.abs_dir_name;
                     file_name = rel_flist[j];
 
                     goto done;
@@ -793,7 +793,7 @@
                 for (const auto& di : dir_info_list)
                   {
                     std::string tfile;
-                    tfile = sys::file_ops::concat (di.dir_name, file);
+                    tfile = sys::file_ops::concat (di.abs_dir_name, file);
 
                     sys::file_stat fs (tfile);
 
@@ -819,7 +819,7 @@
             for (octave_idx_type j = 0; j < rel_flen; j++)
               {
                 if (all_files[i] == rel_flist[j])
-                  retlist.push_back (sys::file_ops::concat (di.dir_name,
+                  retlist.push_back (sys::file_ops::concat (di.abs_dir_name,
                                                             rel_flist[j]));
               }
           }
@@ -1270,7 +1270,7 @@
       {
         try
           {
-            std::string abs_name = sys::env::make_absolute (dir_name);
+            std::string abs_name = sys::canonicalize_file_name (dir_name);
 
             const_abs_dir_cache_iterator p = abs_dir_cache.find (abs_name);
 
@@ -1372,13 +1372,13 @@
 
         try
           {
-            std::string abs_name = sys::env::make_absolute (dir_name);
+            abs_dir_name = sys::canonicalize_file_name (dir_name);
 
             // FIXME: nothing is ever removed from this cache of
             // directory information, so there could be some resource
             // problems.  Perhaps it should be pruned from time to time.
 
-            abs_dir_cache[abs_name] = *this;
+            abs_dir_cache[abs_dir_name] = *this;
           }
         catch (const execution_exception&)
           {
@@ -1493,7 +1493,7 @@
   void
   load_path::package_info::move (const dir_info& di, bool at_end)
   {
-    std::string dir_name = di.dir_name;
+    std::string dir_name = di.abs_dir_name;
 
     auto s = std::find (dir_list.begin (), dir_list.end (), dir_name);
 
@@ -1517,7 +1517,7 @@
   void
   load_path::package_info::remove (const dir_info& di)
   {
-    std::string dir = di.dir_name;
+    std::string dir = di.abs_dir_name;
 
     string_vector fcn_files = di.fcn_files;
 
@@ -1525,7 +1525,7 @@
 
     remove_fcn_map (dir, fcn_files);
 
-    remove_private_fcn_map (sys::canonicalize_file_name (dir));
+    remove_private_fcn_map (dir);
 
     remove_method_map (dir);
   }
@@ -1784,7 +1784,7 @@
   load_path::package_info::add_to_fcn_map (const dir_info& di,
                                            bool at_end, bool updating)
   {
-    std::string dir_name = di.dir_name;
+    std::string dir_name = di.abs_dir_name;
 
     string_vector fcn_files = di.fcn_files;
 
@@ -1892,14 +1892,13 @@
     dir_info::fcn_file_map_type private_file_map = di.private_file_map;
 
     if (! private_file_map.empty ())
-      private_fcn_map[sys::canonicalize_file_name (di.dir_name)]
-        = private_file_map;
+      private_fcn_map[di.abs_dir_name] = private_file_map;
   }
 
   void
   load_path::package_info::add_to_method_map (const dir_info& di, bool at_end)
   {
-    std::string dir_name = di.dir_name;
+    std::string dir_name = di.abs_dir_name;
 
     // <CLASS_NAME, CLASS_INFO>
     dir_info::method_file_map_type method_file_map = di.method_file_map;
@@ -1956,8 +1955,7 @@
         dir_info::fcn_file_map_type private_file_map = ci.private_file_map;
 
         if (! private_file_map.empty ())
-          private_fcn_map[sys::canonicalize_file_name (full_dir_name)]
-            = private_file_map;
+          private_fcn_map[full_dir_name] = private_file_map;
       }
   }
 
@@ -2096,7 +2094,7 @@
   void
   load_path::package_info::remove_private_fcn_map (const std::string& dir)
   {
-    auto p = private_fcn_map.find (sys::canonicalize_file_name (dir));
+    auto p = private_fcn_map.find (dir);
 
     if (p != private_fcn_map.end ())
       private_fcn_map.erase (p);