Last active
August 29, 2015 14:18
-
-
Save gyulalaszlo/00e948885e5ed2aff52b to your computer and use it in GitHub Desktop.
Simple Clojure code to solve a DAG
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
; Takes a list of tasks and their dependencies, solves a DAG | |
; and returns the order in which the tasks | |
; should be run, grouping the paralellizable tasks into lists. | |
; | |
; Transforms this task list: | |
; {:sql_1 [] | |
; :sql_sum [:sql_1] | |
; :sql_3 [] | |
; :view [:sql_1 :sql_sum]} | |
; | |
; Into the following execution order | |
; ((:sql_1 :sql_3) (:sql_sum) (:view)) | |
; | |
; | |
(defn solve-dag [nodes] | |
(let | |
; let solvable = the keys of all the nodes without any dependencies. | |
[solvable (set (map first (filter (fn [t] (empty? (last t))) nodes )))] | |
; If solvable contains any items (can we solve anything?) | |
(if (seq solvable) | |
; If yes then recurse with removing all the solvable nodes from the nodes seq | |
; and removing all the solved nodes from the dependencies list of the | |
; remaining ones. | |
; Then prepend the nodes solved in the current round to the execution\ | |
; order returned from the recursion | |
(cons (seq solvable) (solve-dag (remove-solvable solvable nodes))) | |
; otherwise return an empty list | |
(list)))) | |
; Remove all solvable elements from the list of nodes and from | |
; their dependencies. | |
; solvable is a set containing the keys solved in the current round | |
; nodes is the seq of nodes passed to solve-dag | |
(defn remove-solvable [solvable nodes] | |
(map (fn [node] | |
; node is a (key dependencies) pair. | |
; remove the solved ones from the dependencies of all the elements | |
(list (first node) (remove (fn [n] (contains? solvable n)) (last node)))) | |
; n is a (key dependencies) pair | |
; Remove the solved nodes (nodes whose key is in the solvable set. | |
(remove (fn [n] (contains? solvable (first n))) nodes))) | |
; A simple test of four tasks. Output should be | |
; ((:sql_1 :sql_3) (:sql_sum) (:view)) | |
(solve-dag {:sql_1 [] | |
:sql_sum [:sql_1] | |
:sql_3 [] | |
:view [:sql_1 :sql_sum]}) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment