]> git.ipfire.org Git - thirdparty/coreutils.git/commitdiff
(fts_sort): Optimize the common case where all pointers smell the same.
authorPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 May 2005 23:54:26 +0000 (23:54 +0000)
committerPaul Eggert <eggert@cs.ucla.edu>
Mon, 9 May 2005 23:54:26 +0000 (23:54 +0000)
lib/ChangeLog
lib/fts.c

index 36f4034970d6f4a6dddc171b7c3eb01a3d70f28f..97b0c47022eac9cb05f9978dd2c0c6422a9e8e5d 100644 (file)
@@ -7,7 +7,8 @@
        * fts.c (__P): Remove.  All uses rewritten to assume C89 or better.
        (fts_open): Don't cast a function value in a possibly-unsafe way.
        (fts_compar): New function.
-       (fts_sort): Use it.
+       (fts_sort): Use it.  But optimize the common case where all
+       pointers smell the same.
 
 2005-05-08  Paul Eggert  <eggert@cs.ucla.edu>
 
index 281ed37abadfb1448320f7bbb55b30b4df3339f3..f82ef0fe3624096fc4b313182e9897bfba88ee2b 100644 (file)
--- a/lib/fts.c
+++ b/lib/fts.c
@@ -1240,6 +1240,20 @@ fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
 {
        register FTSENT **ap, *p;
 
+       /* On most modern hosts, void * and FTSENT ** have the same
+          run-time representation, and one can convert sp->fts_compar to
+          the type qsort expects without problem.  Use the heuristic that
+          this is OK if the two pointer types are the same size, and if
+          converting FTSENT ** to long int is the same as converting
+          FTSENT ** to void * and then to long int.  This heuristic isn't
+          valid in general but we don't know of any counterexamples.  */
+       FTSENT *dummy;
+       int (*compare) (void const *, void const *) =
+         ((sizeof &dummy == sizeof (void *)
+           && (long int) &dummy == (long int) (void *) &dummy)
+          ? (int (*) (void const *, void const *)) sp->fts_compar
+          : fts_compar);
+
        /*
         * Construct an array of pointers to the structures and call qsort(3).
         * Reassemble the array in the order returned by qsort.  If unable to
@@ -1263,7 +1277,7 @@ fts_sort (FTS *sp, FTSENT *head, register size_t nitems)
        }
        for (ap = sp->fts_array, p = head; p; p = p->fts_link)
                *ap++ = p;
-       qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), fts_compar);
+       qsort((void *)sp->fts_array, nitems, sizeof(FTSENT *), compare);
        for (head = *(ap = sp->fts_array); --nitems; ++ap)
                ap[0]->fts_link = ap[1];
        ap[0]->fts_link = NULL;