Skip to content

Commit 950f436

Browse files
committed
Added comments to topological_sort
1 parent 315f103 commit 950f436

File tree

1 file changed

+17
-6
lines changed

1 file changed

+17
-6
lines changed

lib/spack/spack/graph.py

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)