Mercurial > octave
changeset 24367:1909f2d7a36e
Backed out changeset 4e746afab617
The fix for this problem is not as simple as it would appear...
author | John W. Eaton <jwe@octave.org> |
---|---|
date | Wed, 06 Dec 2017 13:55:23 -0500 |
parents | 8bf013efffa3 |
children | 77d976a84d0a |
files | NEWS libinterp/corefcn/load-path.cc libinterp/corefcn/load-path.h |
diffstat | 3 files changed, 76 insertions(+), 18 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Wed Dec 06 09:05:32 2017 -0800 +++ b/NEWS Wed Dec 06 13:55:23 2017 -0500 @@ -66,10 +66,6 @@ ** An initial implementation of alpha transparency has been made for patch and surface objects. Printing to svg and pdf is supported. - ** All directories are now converted to absolute names when they are - added to the load path. This change was made for compatibility with - Matlab, which was changed similarly in release 2016b. - ** The following statistical functions have been moved from core Octave to the statistics package available from Octave Forge.
--- a/libinterp/corefcn/load-path.cc Wed Dec 06 09:05:32 2017 -0800 +++ b/libinterp/corefcn/load-path.cc Wed Dec 06 13:55:23 2017 -0500 @@ -497,7 +497,7 @@ { for (const auto& di : dir_info_list) { - std::string dname = di.dir_name; + std::string dname = sys::env::make_absolute (di.dir_name); size_t dname_len = dname.length (); @@ -543,7 +543,7 @@ { for (const auto& di : dir_info_list) { - std::string dname = di.dir_name; + std::string dname = sys::env::make_absolute (di.dir_name); size_t dname_len = dname.length (); @@ -1123,8 +1123,59 @@ std::string msg = fs.error (); warning ("load_path: %s: %s", dir_name.c_str (), msg.c_str ()); } - else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked) - initialize (); + else + { + if (is_relative) + { + try + { + std::string abs_name = sys::env::make_absolute (dir_name); + + const_abs_dir_cache_iterator p = abs_dir_cache.find (abs_name); + + if (p != abs_dir_cache.end ()) + { + // The directory is in the cache of all directories we have + // visited (indexed by absolute name). If it is out of date, + // initialize it. Otherwise, copy the info from the cache. + // By doing that, we avoid unnecessary calls to stat that can + // slow things down tremendously for large directories. + const dir_info& di = p->second; + + if (fs.mtime () + fs.time_resolution () + > di.dir_time_last_checked) + initialize (); + else + { + // Copy over info from cache, but leave dir_name and + // is_relative unmodified. + this->abs_dir_name = di.abs_dir_name; + this->dir_mtime = di.dir_mtime; + this->dir_time_last_checked = di.dir_time_last_checked; + this->all_files = di.all_files; + this->fcn_files = di.fcn_files; + this->private_file_map = di.private_file_map; + this->method_file_map = di.method_file_map; + this->package_dir_map = di.package_dir_map; + } + } + else + { + // We haven't seen this directory before. + initialize (); + } + } + catch (const execution_exception&) + { + // Skip updating if we don't know where we are, + // but don't treat it as an error. + interpreter::recover_from_exception (); + } + } + // Absolute path, check timestamp to see whether it requires re-caching + else if (fs.mtime () + fs.time_resolution () > dir_time_last_checked) + initialize (); + } } bool @@ -1151,9 +1202,7 @@ void load_path::dir_info::initialize (void) { - // We only handle absolute directory names. - - dir_name = sys::env::make_absolute (dir_name); + is_relative = ! sys::env::absolute_pathname (dir_name); dir_time_last_checked = sys::time (static_cast<time_t> (0)); @@ -1169,11 +1218,23 @@ get_file_list (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[dir_name] = *this; + try + { + std::string abs_name = sys::env::make_absolute (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; + } + catch (const execution_exception&) + { + // Skip updating if we don't know where we are but don't treat + // it as an error. + + interpreter::recover_from_exception (); + } } else {
--- a/libinterp/corefcn/load-path.h Wed Dec 06 09:05:32 2017 -0800 +++ b/libinterp/corefcn/load-path.h Wed Dec 06 13:55:23 2017 -0500 @@ -252,8 +252,8 @@ dir_info (void) = default; dir_info (const std::string& d) - : dir_name (d), abs_dir_name (), dir_mtime (), - dir_time_last_checked (), all_files (), fcn_files (), + : dir_name (d), abs_dir_name (), is_relative (false), + dir_mtime (), dir_time_last_checked (), all_files (), fcn_files (), private_file_map (), method_file_map (), package_dir_map () { initialize (); @@ -269,6 +269,7 @@ std::string dir_name; std::string abs_dir_name; + bool is_relative; sys::time dir_mtime; sys::time dir_time_last_checked; string_vector all_files;