Skip to content

Commit

Permalink
Ensure topo sort works with partial graphs
Browse files Browse the repository at this point in the history
  • Loading branch information
julienvincent committed Sep 4, 2024
1 parent 8e099ba commit 4d77a9d
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 17 deletions.
36 changes: 21 additions & 15 deletions packages/kmono-core/src/k16/kmono/core/graph.clj
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,27 @@
(defn parallel-topo-sort
{:malli/schema [:=> [:cat core.schema/?PackageMap] [:maybe ?ExecOrder]]}
[packages]
(when (seq packages)
(when-let [ks (->> packages
(keep
(fn [[fqn package]]
(when (empty? (:depends-on package))
fqn)))
seq
sort)]
(into [(vec ks)]
(parallel-topo-sort
(into {}
(map (fn [[fqn package]]
[fqn (assoc package
:depends-on (apply disj (:depends-on package) ks))]))
(apply dissoc packages ks)))))))
(let [stage
(into #{}
(comp
(filter (fn [[_ pkg]]
(empty? (:depends-on pkg))))
(map first))
packages)

remaining
(reduce
(fn [packages [pkg-name pkg]]
(if-not (contains? stage pkg-name)
(let [deps (apply disj (:depends-on pkg) stage)
pkg (assoc pkg :depends-on deps)]
(assoc packages pkg-name pkg))
packages))
{}
packages)]

(when (seq stage)
(into [(-> stage sort vec)] (parallel-topo-sort remaining)))))

(defn query-dependents
{:malli/schema [:=> [:cat core.schema/?PackageMap :symbol] [:set :symbol]]}
Expand Down
6 changes: 4 additions & 2 deletions packages/kmono-core/test/k16/kmono/core/graph_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,9 @@
packages (core.packages/resolve-packages *repo* config)]

(is (= [['com.kepler16/b]]
(core.graph/parallel-topo-sort (dissoc packages 'com.kepler16/a))))))
(core.graph/parallel-topo-sort
(core.graph/filter-by #(= 'com.kepler16/b (:fqn %))
packages))))))

(deftest query-dependents-test
(fs/create-dirs (fs/file *repo* "packages/c"))
Expand All @@ -73,7 +75,7 @@
(is (match? {'com.kepler16/a {:dependents #{}}}
(core.graph/filter-by #(= 'com.kepler16/a (:fqn %)) packages)))

(is (match? {'com.kepler16/b {:depends-on #{}}}
(is (match? {'com.kepler16/b {:depends-on #{}}}
(core.graph/filter-by #(= 'com.kepler16/b (:fqn %)) packages)))

(is (= ['com.kepler16/b 'com.kepler16/a]
Expand Down

0 comments on commit 4d77a9d

Please sign in to comment.