# HG changeset patch # User John W. Eaton # Date 1384964767 18000 # Node ID 2ca3a2f46d93f53a1eeaf04328233b2f6818e3a8 # Parent 4a53bcc1a4aead43a341035b79821ccb2dcfa6fc improve performance of exist when searching for specific items * variables.cc (symbol_exist): Search specifically for variables first, then files and directories. If doing a specific search, exit early if nothing is found. (Fexist): Rework argument decoding for clarity. diff -r 4a53bcc1a4ae -r 2ca3a2f46d93 libinterp/corefcn/variables.cc --- a/libinterp/corefcn/variables.cc Tue Nov 19 22:19:41 2013 -0500 +++ b/libinterp/corefcn/variables.cc Wed Nov 20 11:26:07 2013 -0500 @@ -388,8 +388,6 @@ int symbol_exist (const std::string& name, const std::string& type) { - int retval = 0; - std::string struct_elts; std::string symbol_name = name; @@ -401,7 +399,70 @@ symbol_name = name.substr (0, pos); } else if (is_keyword (symbol_name)) - return retval; + return 0; + + bool search_any = type == "any"; + bool search_var = type == "var"; + bool search_dir = type == "dir"; + bool search_file = type == "file"; + bool search_builtin = type == "builtin"; + + if (search_any || search_var) + { + bool not_a_struct = struct_elts.empty (); + bool var_ok = not_a_struct; // || val.is_map_element (struct_elts) + + octave_value val = symbol_table::varval (name); + + if (var_ok && (val.is_constant () || val.is_object () + || val.is_function_handle () + || val.is_anonymous_function () + || val.is_inline_function ())) + return 1; + + if (search_var) + return 0; + } + + if (search_any || search_file || search_dir) + { + std::string file_name = lookup_autoload (name); + + if (file_name.empty ()) + file_name = load_path::find_fcn (name); + + size_t len = file_name.length (); + + if (len > 0) + { + if (search_any || search_file) + { + if (len > 4 && (file_name.substr (len-4) == ".oct" + || file_name.substr (len-4) == ".mex")) + return 3; + else + return 2; + } + } + + file_name = file_in_path (name, ""); + + if (file_name.empty ()) + file_name = name; + + file_stat fs (file_name); + + if (fs) + { + if (search_any || search_file) + return fs.is_dir () ? 7 : 2; + else if (search_dir && fs.is_dir ()) + return 7; + } + + if (search_file || search_dir) + return 0; + } // We shouldn't need to look in the global symbol table, since any // name that is visible in the current scope will be in the local @@ -409,87 +470,23 @@ octave_value val = safe_symbol_lookup (symbol_name); - if (val.is_defined ()) + if (val.is_defined () && struct_elts.empty ()) { - bool not_a_struct = struct_elts.empty (); - bool var_ok = not_a_struct /* || val.is_map_element (struct_elts) */; - - if (! retval - && var_ok - && (type == "any" || type == "var") - && (val.is_constant () || val.is_object () - || val.is_function_handle () - || val.is_anonymous_function () - || val.is_inline_function ())) - { - retval = 1; - } - - if (! retval - && (type == "any" || type == "builtin")) - { - if (not_a_struct && val.is_builtin_function ()) - { - retval = 5; - } - } - - if (! retval - && not_a_struct - && (type == "any" || type == "file") + if ((search_any || search_builtin) + && val.is_builtin_function ()) + return 5; + + if ((search_any || search_file) && (val.is_user_function () || val.is_dld_function ())) { octave_function *f = val.function_value (true); std::string s = f ? f->fcn_file_name () : std::string (); - retval = s.empty () ? 103 : (val.is_user_function () ? 2 : 3); + return s.empty () ? 103 : (val.is_user_function () ? 2 : 3); } } - if (! (type == "var" || type == "builtin")) - { - if (! retval) - { - std::string file_name = lookup_autoload (name); - - if (file_name.empty ()) - file_name = load_path::find_fcn (name); - - size_t len = file_name.length (); - - if (len > 0) - { - if (type == "any" || type == "file") - { - if (len > 4 && (file_name.substr (len-4) == ".oct" - || file_name.substr (len-4) == ".mex")) - retval = 3; - else - retval = 2; - } - } - } - - if (! retval) - { - std::string file_name = file_in_path (name, ""); - - if (file_name.empty ()) - file_name = name; - - file_stat fs (file_name); - - if (fs) - { - if (type == "any" || type == "file") - retval = fs.is_dir () ? 7 : 2; - else if (type == "dir" && fs.is_dir ()) - retval = 7; - } - } - } - - return retval; + return 0; } #define GET_IDX(LEN) \ @@ -564,13 +561,17 @@ if (! error_state) { - std::string type - = (nargin == 2) ? args(1).string_value () : std::string ("any"); - - if (! error_state) - retval = symbol_exist (name, type); + if (nargin == 2) + { + std::string type = args(1).string_value (); + + if (! error_state) + retval = symbol_exist (name, type); + else + error ("exist: TYPE must be a string"); + } else - error ("exist: TYPE must be a string"); + retval = symbol_exist (name); } else error ("exist: NAME must be a string");