store: Add 'topologically-sorted'.
* guix/store.scm (topologically-sorted): New procedure. * tests/store.scm ("topologically-sorted, one item", "topologically-sorted, several items", "topologically-sorted, more difficult"): New tests.
This commit is contained in:
parent
cd4027fa47
commit
50add47748
|
@ -76,6 +76,7 @@
|
||||||
references
|
references
|
||||||
requisites
|
requisites
|
||||||
referrers
|
referrers
|
||||||
|
topologically-sorted
|
||||||
valid-derivers
|
valid-derivers
|
||||||
query-derivation-outputs
|
query-derivation-outputs
|
||||||
live-paths
|
live-paths
|
||||||
|
@ -589,6 +590,40 @@ SEED."
|
||||||
references, recursively)."
|
references, recursively)."
|
||||||
(fold-path store cons '() path))
|
(fold-path store cons '() path))
|
||||||
|
|
||||||
|
(define (topologically-sorted store paths)
|
||||||
|
"Return a list containing PATHS and all their references sorted in
|
||||||
|
topological order."
|
||||||
|
(define (traverse)
|
||||||
|
;; Do a simple depth-first traversal of all of PATHS.
|
||||||
|
(let loop ((paths paths)
|
||||||
|
(visited vlist-null)
|
||||||
|
(result '()))
|
||||||
|
(define (visit n)
|
||||||
|
(vhash-cons n #t visited))
|
||||||
|
|
||||||
|
(define (visited? n)
|
||||||
|
(vhash-assoc n visited))
|
||||||
|
|
||||||
|
(match paths
|
||||||
|
((head tail ...)
|
||||||
|
(if (visited? head)
|
||||||
|
(loop tail visited result)
|
||||||
|
(call-with-values
|
||||||
|
(lambda ()
|
||||||
|
(loop (references store head)
|
||||||
|
(visit head)
|
||||||
|
result))
|
||||||
|
(lambda (visited result)
|
||||||
|
(loop tail
|
||||||
|
visited
|
||||||
|
(cons head result))))))
|
||||||
|
(()
|
||||||
|
(values visited result)))))
|
||||||
|
|
||||||
|
(call-with-values traverse
|
||||||
|
(lambda (_ result)
|
||||||
|
(reverse result))))
|
||||||
|
|
||||||
(define referrers
|
(define referrers
|
||||||
(operation (query-referrers (store-path path))
|
(operation (query-referrers (store-path path))
|
||||||
"Return the list of path that refer to PATH."
|
"Return the list of path that refer to PATH."
|
||||||
|
|
|
@ -162,6 +162,38 @@
|
||||||
(equal? (valid-derivers %store o)
|
(equal? (valid-derivers %store o)
|
||||||
(list (derivation-file-name d))))))
|
(list (derivation-file-name d))))))
|
||||||
|
|
||||||
|
(test-assert "topologically-sorted, one item"
|
||||||
|
(let* ((a (add-text-to-store %store "a" "a"))
|
||||||
|
(b (add-text-to-store %store "b" "b" (list a)))
|
||||||
|
(c (add-text-to-store %store "c" "c" (list b)))
|
||||||
|
(d (add-text-to-store %store "d" "d" (list c)))
|
||||||
|
(s (topologically-sorted %store (list d))))
|
||||||
|
(equal? s (list a b c d))))
|
||||||
|
|
||||||
|
(test-assert "topologically-sorted, several items"
|
||||||
|
(let* ((a (add-text-to-store %store "a" "a"))
|
||||||
|
(b (add-text-to-store %store "b" "b" (list a)))
|
||||||
|
(c (add-text-to-store %store "c" "c" (list b)))
|
||||||
|
(d (add-text-to-store %store "d" "d" (list c)))
|
||||||
|
(s1 (topologically-sorted %store (list d a c b)))
|
||||||
|
(s2 (topologically-sorted %store (list b d c a b d))))
|
||||||
|
(equal? s1 s2 (list a b c d))))
|
||||||
|
|
||||||
|
(test-assert "topologically-sorted, more difficult"
|
||||||
|
(let* ((a (add-text-to-store %store "a" "a"))
|
||||||
|
(b (add-text-to-store %store "b" "b" (list a)))
|
||||||
|
(c (add-text-to-store %store "c" "c" (list b)))
|
||||||
|
(d (add-text-to-store %store "d" "d" (list c)))
|
||||||
|
(w (add-text-to-store %store "w" "w"))
|
||||||
|
(x (add-text-to-store %store "x" "x" (list w)))
|
||||||
|
(y (add-text-to-store %store "y" "y" (list x d)))
|
||||||
|
(s1 (topologically-sorted %store (list y)))
|
||||||
|
(s2 (topologically-sorted %store (list c y)))
|
||||||
|
(s3 (topologically-sorted %store (cons y (references %store y)))))
|
||||||
|
(and (equal? s1 (list w x a b c d y))
|
||||||
|
(equal? s2 (list a b c w x d y))
|
||||||
|
(lset= string=? s1 s3))))
|
||||||
|
|
||||||
(test-assert "log-file, derivation"
|
(test-assert "log-file, derivation"
|
||||||
(let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
|
(let* ((b (add-text-to-store %store "build" "echo $foo > $out" '()))
|
||||||
(s (add-to-store %store "bash" #t "sha256"
|
(s (add-to-store %store "bash" #t "sha256"
|
||||||
|
|
Loading…
Reference in New Issue