bug-findutils
[Top][All Lists]
Advanced

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

[PATCH 3/4] Fix Savannah bug #19593, -execdir .... {} + has suboptimal p


From: James Youngman
Subject: [PATCH 3/4] Fix Savannah bug #19593, -execdir .... {} + has suboptimal performance
Date: Sat, 10 Apr 2010 21:33:05 +0100

* find/ftsfind.c (consider_visiting): Don't call
complete_pending_execdirs for every file we visit.
(find): Instead, call complete_pending_execdirs every time we
see a file which isn't at the same nesting level as the previous
file we saw.  This is an improvement but not optimal (since
descending into a subdirectory will cause us to issue an exec
before we've finished with the current directory).
* NEWS: Mention this change.

Signed-off-by: James Youngman <address@hidden>
---
 ChangeLog      |   10 ++++++++++
 NEWS           |   13 +++++++++++++
 find/ftsfind.c |   37 +++++++++++++++++++------------------
 3 files changed, 42 insertions(+), 18 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index e167e7a..f2c1e5d 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,15 @@
 2010-04-10  James Youngman  <address@hidden>
 
+       Fix Savannah bug #19593, -execdir .... {} + has suboptimal performance
+       * find/ftsfind.c (consider_visiting): Don't call
+       complete_pending_execdirs for every file we visit.
+       (find): Instead, call complete_pending_execdirs every time we
+       see a file which isn't at the same nesting level as the previous
+       file we saw.  This is an improvement but not optimal (since
+       descending into a subdirectory will cause us to issue an exec
+       before we've finished with the current directory).
+       * NEWS: Mention this change.
+
         Exec predicates now store which directory they want to run in.
         * lib/dircallback.c (run_in_dirfd): New name for old run_in_dir
         function.
diff --git a/NEWS b/NEWS
index 85a474c..2670ad7 100644
--- a/NEWS
+++ b/NEWS
@@ -2,6 +2,19 @@ GNU findutils NEWS - User visible changes.      -*- outline 
-*- (allout)
 
 * Major changes in release 4.5.9-git, YYYY-MM-DD
 
+** Bug Fixes
+
+#19593, -execdir .... {} + has suboptimal performance (see below)
+
+** Performance changes
+
+The find program will once again build argument lists longer than 1
+with "-execdir ...+".  The upper limit of 1 argument for execdir was
+introduced as a workaround in findutils-4.3.4.   The limit is now
+removed, but find still does not issue the maximum possible number of
+arguments, since an exec will occur each time find encounters a
+subdirectory (if at least one argument is pending).
+
 * Major changes in release 4.5.8, 2010-04-07
 
 ** Bug Fixes
diff --git a/find/ftsfind.c b/find/ftsfind.c
index 49aef9b..9fdb8ef 100644
--- a/find/ftsfind.c
+++ b/find/ftsfind.c
@@ -513,24 +513,6 @@ consider_visiting (FTS *p, FTSENT *ent)
       visit (p, ent, &statbuf);
     }
 
-  /* XXX: if we allow a build-up of pending arguments for "-execdir foo {} +"
-   * we need to execute them in the same directory as we found the item.
-   * If we are trying to do "find a -execdir echo {} +", we will need to
-   * echo
-   *      a while in the original working directory
-   *      b while in a
-   *      c while in b (just before leaving b)
-   *
-   * These restrictions are hard to satisfy while using fts().   The reason is
-   * that it doesn't tell us just before we leave a directory.  For the moment,
-   * we punt and don't allow the arguments to build up.
-   */
-  if (state.execdirs_outstanding)
-    {
-      show_outstanding_execdirs (stderr);
-      complete_pending_execdirs ();
-    }
-
   if (ent->fts_info == FTS_DP)
     {
       /* we're leaving a directory. */
@@ -580,8 +562,27 @@ find (char *arg)
     }
   else
     {
+      int level = INT_MIN;
+
       while ( (ent=fts_read (p)) != NULL )
        {
+         if (state.execdirs_outstanding)
+           {
+             /* If we changed level, perform any outstanding
+              * execdirs.  If we see a sequence of directory entries
+              * like this: fffdfffdfff, we could build a command line
+              * of 9 files, but this simple-minded implementation
+              * builds a command line for only 3 files at a time
+              * (since fts descends into the directories).
+              */
+             if ((int)ent->fts_level != level)
+               {
+                 show_outstanding_execdirs (stderr);
+                 complete_pending_execdirs ();
+               }
+           }
+         level = (int)ent->fts_level;
+
          state.already_issued_stat_error_msg = false;
          state.have_stat = false;
          state.have_type = !!ent->fts_statp->st_mode;
-- 
1.7.0





reply via email to

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