mirror of
https://git.savannah.gnu.org/git/guix.git
synced 2025-01-31 14:56:54 +01:00
grafts: Improve performance for derivations with many inputs.
Partly fixes <https://bugs.gnu.org/41702>. Reported by Lars-Dominik Braun <ldb@leibniz-psychology.org>. Previously we'd potentially traverse the same sub-graph of DEPS several times. With this patch, command: guix environment --ad-hoc r-learnr --search-paths goes from 11.3s to 4.6s. * guix/grafts.scm (reference-origin): Rename to... (reference-origins): ... this. Change 'item' parameter to 'items'. [lookup-derivers]: New procedure. (cumulative-grafts)[dependency-grafts]: Change 'item' to 'items' and use 'reference-origins'. Remove 'mapm' around 'dependency-grafts' call.
This commit is contained in:
parent
22fdca91a9
commit
58bb833365
1 changed files with 52 additions and 33 deletions
|
@ -20,10 +20,12 @@ (define-module (guix grafts)
|
||||||
#:use-module (guix store)
|
#:use-module (guix store)
|
||||||
#:use-module (guix monads)
|
#:use-module (guix monads)
|
||||||
#:use-module (guix records)
|
#:use-module (guix records)
|
||||||
|
#:use-module (guix combinators)
|
||||||
#:use-module (guix derivations)
|
#:use-module (guix derivations)
|
||||||
#:use-module ((guix utils) #:select (%current-system))
|
#:use-module ((guix utils) #:select (%current-system))
|
||||||
#:use-module (guix sets)
|
#:use-module (guix sets)
|
||||||
#:use-module (srfi srfi-1)
|
#:use-module (srfi srfi-1)
|
||||||
|
#:use-module (srfi srfi-11)
|
||||||
#:use-module (srfi srfi-9 gnu)
|
#:use-module (srfi srfi-9 gnu)
|
||||||
#:use-module (srfi srfi-26)
|
#:use-module (srfi srfi-26)
|
||||||
#:use-module (srfi srfi-34)
|
#:use-module (srfi srfi-34)
|
||||||
|
@ -183,32 +185,47 @@ (define-syntax-rule (with-cache key exp ...)
|
||||||
(set-current-state (vhash-cons key result cache))
|
(set-current-state (vhash-cons key result cache))
|
||||||
(return result)))))))
|
(return result)))))))
|
||||||
|
|
||||||
(define (reference-origin drv item)
|
(define (reference-origins drv items)
|
||||||
"Return the derivation/output pair among the inputs of DRV, recursively,
|
"Return the derivation/output pairs among the inputs of DRV, recursively,
|
||||||
that produces ITEM. Return #f if ITEM is not produced by a derivation (i.e.,
|
that produce ITEMS. Elements of ITEMS not produced by a derivation (i.e.,
|
||||||
it's a content-addressed \"source\"), or if it's not produced by a dependency
|
it's a content-addressed \"source\"), or not produced by a dependency of DRV,
|
||||||
of DRV."
|
have no corresponding element in the resulting list."
|
||||||
|
(define (lookup-derivers drv result items)
|
||||||
|
;; Return RESULT augmented by all the drv/output pairs producing one of
|
||||||
|
;; ITEMS, and ITEMS stripped of matching items.
|
||||||
|
(fold2 (match-lambda*
|
||||||
|
(((output . file) result items)
|
||||||
|
(if (member file items)
|
||||||
|
(values (alist-cons drv output result)
|
||||||
|
(delete file items))
|
||||||
|
(values result items))))
|
||||||
|
result items
|
||||||
|
(derivation->output-paths drv)))
|
||||||
|
|
||||||
;; Perform a breadth-first traversal of the dependency graph of DRV in
|
;; Perform a breadth-first traversal of the dependency graph of DRV in
|
||||||
;; search of the derivation that produces ITEM.
|
;; search of the derivations that produce ITEMS.
|
||||||
(let loop ((drv (list drv))
|
(let loop ((drv (list drv))
|
||||||
|
(items items)
|
||||||
|
(result '())
|
||||||
(visited (setq)))
|
(visited (setq)))
|
||||||
(match drv
|
(match drv
|
||||||
(()
|
(()
|
||||||
#f)
|
result)
|
||||||
((drv . rest)
|
((drv . rest)
|
||||||
(if (set-contains? visited drv)
|
(cond ((null? items)
|
||||||
(loop rest visited)
|
result)
|
||||||
(let ((inputs (derivation-inputs drv)))
|
((set-contains? visited drv)
|
||||||
(or (any (lambda (input)
|
(loop rest items result visited))
|
||||||
(let ((drv (derivation-input-derivation input)))
|
(else
|
||||||
(any (match-lambda
|
(let*-values (((inputs)
|
||||||
((output . file)
|
(map derivation-input-derivation
|
||||||
(and (string=? file item)
|
(derivation-inputs drv)))
|
||||||
(cons drv output))))
|
((result items)
|
||||||
(derivation->output-paths drv))))
|
(fold2 lookup-derivers
|
||||||
inputs)
|
result items inputs)))
|
||||||
(loop (append rest (map derivation-input-derivation inputs))
|
(loop (append rest inputs)
|
||||||
(set-insert drv visited)))))))))
|
items result
|
||||||
|
(set-insert drv visited)))))))))
|
||||||
|
|
||||||
(define* (cumulative-grafts store drv grafts
|
(define* (cumulative-grafts store drv grafts
|
||||||
#:key
|
#:key
|
||||||
|
@ -233,25 +250,27 @@ (define (graft-origin? drv graft)
|
||||||
(_
|
(_
|
||||||
#f)))
|
#f)))
|
||||||
|
|
||||||
(define (dependency-grafts item)
|
(define (dependency-grafts items)
|
||||||
(match (reference-origin drv item)
|
(mapm %store-monad
|
||||||
((drv . output)
|
(lambda (drv+output)
|
||||||
;; If GRAFTS already contains a graft from DRV, do not override it.
|
(match drv+output
|
||||||
(if (find (cut graft-origin? drv <>) grafts)
|
((drv . output)
|
||||||
(state-return grafts)
|
;; If GRAFTS already contains a graft from DRV, do not
|
||||||
(cumulative-grafts store drv grafts
|
;; override it.
|
||||||
#:outputs (list output)
|
(if (find (cut graft-origin? drv <>) grafts)
|
||||||
#:guile guile
|
(state-return grafts)
|
||||||
#:system system)))
|
(cumulative-grafts store drv grafts
|
||||||
(#f
|
#:outputs (list output)
|
||||||
(state-return grafts))))
|
#:guile guile
|
||||||
|
#:system system)))))
|
||||||
|
(reference-origins drv items)))
|
||||||
|
|
||||||
(with-cache (cons (derivation-file-name drv) outputs)
|
(with-cache (cons (derivation-file-name drv) outputs)
|
||||||
(match (non-self-references store drv outputs)
|
(match (non-self-references store drv outputs)
|
||||||
(() ;no dependencies
|
(() ;no dependencies
|
||||||
(return grafts))
|
(return grafts))
|
||||||
(deps ;one or more dependencies
|
(deps ;one or more dependencies
|
||||||
(mlet %state-monad ((grafts (mapm %state-monad dependency-grafts deps)))
|
(mlet %state-monad ((grafts (dependency-grafts deps)))
|
||||||
(let ((grafts (delete-duplicates (concatenate grafts) equal?)))
|
(let ((grafts (delete-duplicates (concatenate grafts) equal?)))
|
||||||
(match (filter (lambda (graft)
|
(match (filter (lambda (graft)
|
||||||
(member (graft-origin-file-name graft) deps))
|
(member (graft-origin-file-name graft) deps))
|
||||||
|
|
Loading…
Reference in a new issue