discovery: Rewrite 'scheme-files' using 'scandir*'.
On a command like: guix environment --ad-hoc coreutils -- true this reduces the number of 'stat' calls from 14.1K to 9.7K on my setup (previously each getdents(2) call would be followed by one stat(2) call per entry). * guix/discovery.scm (scheme-files): Rewrite using 'scandir*'.master
parent
fa73c19373
commit
d27cc3bfaa
|
@ -19,6 +19,7 @@
|
||||||
(define-module (guix discovery)
|
(define-module (guix discovery)
|
||||||
#:use-module (guix ui)
|
#:use-module (guix ui)
|
||||||
#:use-module (guix combinators)
|
#:use-module (guix combinators)
|
||||||
|
#:use-module (guix build syscalls)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
#:use-module (ice-9 match)
|
#:use-module (ice-9 match)
|
||||||
#:use-module (ice-9 vlist)
|
#:use-module (ice-9 vlist)
|
||||||
|
@ -38,28 +39,35 @@
|
||||||
(define* (scheme-files directory)
|
(define* (scheme-files directory)
|
||||||
"Return the list of Scheme files found under DIRECTORY, recursively. The
|
"Return the list of Scheme files found under DIRECTORY, recursively. The
|
||||||
returned list is sorted in alphabetical order."
|
returned list is sorted in alphabetical order."
|
||||||
|
(define (entry-type name properties)
|
||||||
|
(match (assoc-ref properties 'type)
|
||||||
|
('unknown
|
||||||
|
(stat:type (lstat name)))
|
||||||
|
((? symbol? type)
|
||||||
|
type)))
|
||||||
|
|
||||||
;; Sort entries so that 'fold-packages' works in a deterministic fashion
|
;; Use 'scandir*' so we can avoid an extra 'lstat' for each entry, as
|
||||||
;; regardless of details of the underlying file system.
|
;; opposed to Guile's 'scandir' or 'file-system-fold'.
|
||||||
(sort (file-system-fold (const #t) ;enter?
|
(fold-right (lambda (entry result)
|
||||||
(lambda (path stat result) ;leaf
|
(match entry
|
||||||
(if (string-suffix? ".scm" path)
|
(("." . _)
|
||||||
(cons path result)
|
result)
|
||||||
result))
|
((".." . _)
|
||||||
(lambda (path stat result) ;down
|
result)
|
||||||
result)
|
((name . properties)
|
||||||
(lambda (path stat result) ;up
|
(let ((absolute (string-append directory "/" name)))
|
||||||
result)
|
(case (entry-type absolute properties)
|
||||||
(const #f) ;skip
|
((directory)
|
||||||
(lambda (path stat errno result)
|
(append (scheme-files absolute) result))
|
||||||
(unless (= ENOENT errno)
|
((regular symlink)
|
||||||
(warning (G_ "cannot access `~a': ~a~%")
|
;; XXX: We don't recurse if we find a symlink.
|
||||||
path (strerror errno)))
|
(if (string-suffix? ".scm" name)
|
||||||
result)
|
(cons absolute result)
|
||||||
'()
|
result))
|
||||||
directory
|
(else
|
||||||
stat)
|
result))))))
|
||||||
string<?))
|
'()
|
||||||
|
(scandir* directory)))
|
||||||
|
|
||||||
(define file-name->module-name
|
(define file-name->module-name
|
||||||
(let ((not-slash (char-set-complement (char-set #\/))))
|
(let ((not-slash (char-set-complement (char-set #\/))))
|
||||||
|
|
Reference in New Issue