me
/
guix
Archived
1
0
Fork 0

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
Ludovic Courtès 2017-06-16 12:07:26 +02:00 committed by Ludovic Courtès
parent fa73c19373
commit d27cc3bfaa
No known key found for this signature in database
GPG Key ID: 090B11993D9AEBB5
1 changed files with 29 additions and 21 deletions

View File

@ -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 #\/))))