From 1e6f8eccad0a477a63c3d7317b6cfde96d4556c6 Mon Sep 17 00:00:00 2001
From: Francois-Rene Rideau <fare@tunes.org>
Date: Fri, 10 Jun 2016 21:20:16 -0400
Subject: [PATCH] Fix directory-files to be linear not quadratic

Bug found by @axionic on github: on very large directories,
directory-files was slow, because it was using remove-duplicates
with non-hashable test function #'pathname-equal.
But this functionality was only really needed for the purpose
of dealing with logical-pathnames, and having a few duplicates
in case of wanton symlinks isn't much of an issue.
---
 uiop/filesystem.lisp | 20 +++++++++++---------
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/uiop/filesystem.lisp b/uiop/filesystem.lisp
index ba860cc34..dca670ae0 100644
--- a/uiop/filesystem.lisp
+++ b/uiop/filesystem.lisp
@@ -171,11 +171,14 @@ Try to override the defaults to not resolving symlinks, if implementation allows
                                         '(:resolve-symlinks nil))))))
 
   (defun filter-logical-directory-results (directory entries merger)
-    "Given ENTRIES in a DIRECTORY, remove if the directory is logical
-the entries which are physical yet when transformed by MERGER have a different TRUENAME.
-This function is used as a helper to DIRECTORY-FILES to avoid invalid entries when using logical-pathnames."
-    (remove-duplicates ;; on CLISP, querying ~/ will return duplicates
-     (if (logical-pathname-p directory)
+    "If DIRECTORY isn't a logical pathname, return ENTRIES. If it is,
+given ENTRIES in the DIRECTORY, remove the entries which are physical yet
+when transformed by MERGER have a different TRUENAME.
+Also remove duplicates as may appear with some translation rules.
+This function is used as a helper to DIRECTORY-FILES to avoid invalid entries
+when using logical-pathnames."
+    (if (logical-pathname-p directory)
+	(remove-duplicates ;; on CLISP, querying ~/ will return duplicates
          ;; Try hard to not resolve logical-pathname into physical pathnames;
          ;; otherwise logical-pathname users/lovers will be disappointed.
          ;; If directory* could use some implementation-dependent magic,
@@ -189,10 +192,9 @@ This function is used as a helper to DIRECTORY-FILES to avoid invalid entries wh
                               ;; At this point f should already be a truename,
                               ;; but isn't quite in CLISP, for it doesn't have :version :newest
                               (and u (equal (truename* u) (truename* f)) u)))
-               :when p :collect p)
-         entries)
-     :test 'pathname-equal))
-
+	   :when p :collect p)
+	 :test 'pathname-equal)
+	entries))
 
   (defun directory-files (directory &optional (pattern *wild-file*))
     "Return a list of the files in a directory according to the PATTERN.
-- 
GitLab