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