findutils-patches
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Findutils-patches] [PATCH] Optimise -fstype NOTUSED to -false at -O2.


From: James Youngman
Subject: [Findutils-patches] [PATCH] Optimise -fstype NOTUSED to -false at -O2.
Date: Tue, 30 Mar 2010 10:04:19 +0100

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  <address@hidden>
 
        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
address@hidden/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





reply via email to

[Prev in Thread] Current Thread [Next in Thread]