fts.c: adjust a new interface to be more generally useful
authorJim Meyering <meyering@redhat.com>
Wed, 1 Oct 2008 07:22:11 +0000 (09:22 +0200)
committerJim Meyering <meyering@redhat.com>
Wed, 1 Oct 2008 07:24:02 +0000 (09:24 +0200)
* lib/fts.c (dirent_inode_sort_may_be_useful): Take an FD parameter.
(fts_build): Adjust caller.

ChangeLog
lib/fts.c

index 6b9cddc..5ef986e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-10-01  Jim Meyering  <meyering@redhat.com>
+
+       fts.c: adjust a new interface to be more generally useful
+       * lib/fts.c (dirent_inode_sort_may_be_useful): Take an FD parameter.
+       (fts_build): Adjust caller.
+
 2008-09-30  Yoann Vandoorselaere  <yoann.v@prelude-ids.com>
 
        * modules/cond-tests: New file.
index 673693a..95d0c7a 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -955,18 +955,19 @@ fs_handles_readdir_ordered_dirents_efficiently (uintmax_t fs_type)
 }
 
 /* Return true if it is easy to determine the file system type of the
-   current directory, and sorting dirents on inode numbers is known to
-   improve traversal performance with that type of file system.  */
+   directory on which DIR_FD is open, and sorting dirents on inode numbers
+   is known to improve traversal performance with that type of file system.  */
 static bool
-dirent_inode_sort_may_be_useful (FTS const *sp)
+dirent_inode_sort_may_be_useful (int dir_fd)
 {
-  struct statfs fs_buf;
   /* Skip the sort only if we can determine efficiently
-     that it's the right thing to do.  */
-  bool skip = (ISSET (FTS_CWDFD)
-              && fstatfs (sp->fts_cwd_fd, &fs_buf) == 0
-              && fs_handles_readdir_ordered_dirents_efficiently
-                   (fs_buf.f_type));
+     that skipping it is the right thing to do.
+     The cost of performing an unnecessary sort is negligible,
+     while the cost of *not* performing it can be O(N^2) with
+     a very large constant.  */
+  struct statfs fs_buf;
+  bool skip = (fstatfs (dir_fd, &fs_buf) == 0
+              && fs_handles_readdir_ordered_dirents_efficiently (dir_fd));
   return !skip;
 }
 #else
@@ -1289,7 +1290,8 @@ mem1:                             saved_errno = errno;
           inode numbers.  */
        if (nitems > _FTS_INODE_SORT_DIR_ENTRIES_THRESHOLD
            && !sp->fts_compar
-           && dirent_inode_sort_may_be_useful (sp)) {
+           && ISSET (FTS_CWDFD)
+           && dirent_inode_sort_may_be_useful (sp->fts_cwd_fd)) {
                sp->fts_compar = fts_compare_ino;
                head = fts_sort (sp, head, nitems);
                sp->fts_compar = NULL;