@@ -72,41 +72,52 @@ def topological_sort(spec, deptype='all'):
7272 """
7373 deptype = spack .dependency .canonical_deptype (deptype )
7474
75- # Work on a copy so this is nondestructive.
75+ # Work on a copy so this is nondestructive
7676 spec = spec .copy (deps = True )
7777 nodes = spec .index (deptype = deptype )
7878
7979 def dependencies (specs ):
80+ """Return all the dependencies (including transitive) for a spec."""
8081 return list (set (itertools .chain .from_iterable (
8182 s .dependencies (deptype = deptype ) for s in specs
8283 )))
8384
8485 def dependents (specs ):
86+ """Return all the dependents (including those of transitive dependencies)
87+ for a spec.
88+ """
8589 candidates = list (set (itertools .chain .from_iterable (
8690 s .dependents (deptype = deptype ) for s in specs
8791 )))
8892 return [x for x in candidates if x .name in nodes ]
8993
9094 topological_order , children = [], {}
95+
96+ # Map a spec encoded as (id, name) to a list of its transitive dependencies
9197 for spec in itertools .chain .from_iterable (nodes .values ()):
9298 children [(id (spec ), spec .name )] = [
9399 x for x in dependencies ([spec ]) if x .name in nodes
94100 ]
95101
96- remaining = [
102+ # To return a result that is topologically ordered we need to add nodes
103+ # only after their dependencies. The first nodes we can add are leaf nodes,
104+ # i.e. nodes that have no dependencies.
105+ ready = [
97106 spec for spec in itertools .chain .from_iterable (nodes .values ())
98107 if not dependencies ([spec ])
99108 ]
100- heapq .heapify (remaining )
109+ heapq .heapify (ready )
101110
102- while remaining :
103- s = heapq .heappop (remaining )
111+ while ready :
112+ # Pop a "ready" node and add it to the topologically ordered list
113+ s = heapq .heappop (ready )
104114 topological_order .append (s )
105115
116+ # Check if adding the last node made other nodes "ready"
106117 for dep in dependents ([s ]):
107118 children [(id (dep ), dep .name )].remove (s )
108119 if not children [(id (dep ), dep .name )]:
109- heapq .heappush (remaining , dep )
120+ heapq .heappush (ready , dep )
110121
111122 return topological_order
112123
0 commit comments