Optimise -fstype NOTUSED to -false at -O2. * find/parser.c: Include mountlist.h. (insert_false): New function, inserts a -false predicate. (parse_false): Use insert_false. (is_used_fs_type): New function, determines if any mounted filesystem is of the named type. (parse_fstype): At optimisation level 2 and above, -fstpe FOO is converted to -false if no mounted filesytem is of type FOO. * find/find.1: Document this optimisation. * doc/find.texi (Optimisation Options): Likewise. * NEWS: Mention this change. --- ChangeLog | 12 ++++++++ NEWS | 7 +++++ doc/find.texi | 6 ++++ find/find.1 | 9 ++++++ find/parser.c | 82 +++++++++++++++++++++++++++++++++++++++++++++++--------- 5 files changed, 102 insertions(+), 14 deletions(-)
diff --git a/ChangeLog b/ChangeLog index e069683..eab9e91 100644 --- a/ChangeLog +++ b/ChangeLog @@ -219,6 +219,18 @@ (parse_iwholename): Remove redundant extra definition. (parse_ipath): Likewise. + Optimise -fstype NOTUSED to -false at -O2. + * find/parser.c: Include mountlist.h. + (insert_false): New function, inserts a -false predicate. + (parse_false): Use insert_false. + (is_used_fs_type): New function, determines if any mounted + filesystem is of the named type. + (parse_fstype): At optimisation level 2 and above, -fstpe FOO + is converted to -false if no mounted filesytem is of type FOO. + * find/find.1: Document this optimisation. + * doc/find.texi (Optimisation Options): Likewise. + * NEWS: Mention this change. + 2009-07-14 James Youngman <j...@gnu.org> Fix Savannah bug #27017: find -D opt / -fstype ext3 -print , -quit diff --git a/NEWS b/NEWS index 29b78f9..5088dd2 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,13 @@ GNU findutils NEWS - User visible changes. -*- outline -*- (allout) * Major changes in release 4.5.6-git, YYYY-MM-DD +** Performance changes + +If you use the -fstype FOO predicate and specify a filsystem type FOO +which is not known (e.g. present in /etc/mtab) at the time find +starts, that predicate is now equivalent to -false. This substitution +currently occurs at optimisation level 2 and above. + ** Bug Fixes #28872: Mistake in "#safer" example in "Problems with -exec and diff --git a/doc/find.texi b/doc/find.texi index c2c2c03..3b21c0a 100644 --- a/doc/find.texi +++ b/doc/find.texi @@ -3106,6 +3106,12 @@ information from the inode. On many modern versions of Unix, file types are returned by @code{readdir()} and so these predicates are faster to evaluate than predicates which need to stat the file first. +If you use the @samp{-fstype FOO} predicate and specify a filsystem +type @samp{FOO} which is not known (that is, present in +...@file{/etc/mtab}) at the time @code{find} starts, that predicate is +equivalent to @samp{-false}. + + @item 3 At this optimisation level, the full cost-based query optimiser is enabled. The order of tests is modified so that cheap (i.e., fast) diff --git a/find/find.1 b/find/find.1 index e17b21e..34daf54 100644 --- a/find/find.1 +++ b/find/find.1 @@ -253,6 +253,15 @@ modern versions of Unix, file types are returned by .B readdir() and so these predicates are faster to evaluate than predicates which need to stat the file first. +If you use the +.B \-fstype +.I FOO +predicate and specify a filsystem type +.I FOO +which is not known (that is, present in `/etc/mtab') at the time +.B find +starts, that predicate is equivalent to +.BR \-false . .IP 3 At this optimisation level, the full cost-based query optimiser is enabled. The order of tests is modified so that cheap (i.e. fast) diff --git a/find/parser.c b/find/parser.c index 5fdb949..8a15148 100644 --- a/find/parser.c +++ b/find/parser.c @@ -26,6 +26,7 @@ #include <errno.h> #include <grp.h> #include <fnmatch.h> +#include "mountlist.h" #include "modechange.h" #include "modetype.h" #include "xstrtol.h" @@ -854,20 +855,26 @@ parse_execdir (const struct parser_table* entry, char **argv, int *arg_ptr) } static boolean -parse_false (const struct parser_table* entry, char **argv, int *arg_ptr) +insert_false(void) { struct predicate *our_pred; + const struct parser_table *entry_false; - (void) argv; - (void) arg_ptr; - - our_pred = insert_primary_noarg (entry); + entry_false = find_parser("false"); + our_pred = insert_primary_noarg (entry_false); our_pred->need_stat = our_pred->need_type = false; our_pred->side_effects = our_pred->no_default_print = false; our_pred->est_success_rate = 0.0f; return true; } + +static boolean +parse_false (const struct parser_table* entry, char **argv, int *arg_ptr) +{ + return insert_false (); +} + static boolean insert_fls (const struct parser_table* entry, const char *filename) { @@ -969,22 +976,69 @@ static float estimate_fstype_success_rate(const char *fsname) } + +static boolean +is_used_fs_type(const char *name) +{ + if (0 == strcmp("afs", name)) + { + /* I guess AFS may not appear in /etc/mtab (or equivalent) but still be in use, + so assume we always need to check for AFS. */ + return true; + } + else + { + const struct mount_entry *entries = read_file_system_list(false); + if (entries) + { + const struct mount_entry *entry; + for (entry = entries; entry; entry = entry->me_next) + { + if (0 == strcmp(name, entry->me_type)) + return true; + } + } + else + { + return true; + } + } + return false; +} + + static boolean parse_fstype (const struct parser_table* entry, char **argv, int *arg_ptr) { const char *typename; if (collect_arg(argv, arg_ptr, &typename)) { - struct predicate *our_pred = insert_primary (entry, typename); - our_pred->args.str = typename; + if (options.optimisation_level < 2 || is_used_fs_type (typename)) + { + struct predicate *our_pred = insert_primary (entry, typename); + our_pred->args.str = typename; - /* This is an expensive operation, so although there are - * circumstances where it is selective, we ignore this fact - * because we probably don't want to promote this test to the - * front anyway. - */ - our_pred->est_success_rate = estimate_fstype_success_rate(typename); - return true; + /* This is an expensive operation, so although there are + * circumstances where it is selective, we ignore this fact + * because we probably don't want to promote this test to the + * front anyway. + */ + our_pred->est_success_rate = estimate_fstype_success_rate(typename); + return true; + } + else + { + /* This filesystem type is not listed in the mount table. + * Hence this predicate will always return false (with this argument). + * Substitute a predicate with the same effect as -false. + */ + if (options.debug_options & DebugTreeOpt) + { + fprintf(stderr, + "-fstype %s can never succeed, substituting -false\n", typename); + } + return insert_false (); + } } else { -- 1.5.6.5 _______________________________________________ Findutils-patches mailing list Findutils-patches@gnu.org http://lists.gnu.org/mailman/listinfo/findutils-patches