Skip to content

Commit

Permalink
Optimize Symbol Propagation (propagateSymbolsUp) (#9337)
Browse files Browse the repository at this point in the history
Co-authored-by: Niklas Mischkulnig <[email protected]>
Co-authored-by: Celina Peralta <[email protected]>
  • Loading branch information
3 people authored Nov 27, 2023
1 parent 65f8e21 commit dc3d92b
Show file tree
Hide file tree
Showing 2 changed files with 71 additions and 13 deletions.
23 changes: 10 additions & 13 deletions packages/core/core/src/SymbolPropagation.js
Original file line number Diff line number Diff line change
Expand Up @@ -639,21 +639,18 @@ function propagateSymbolsUp(
assetGraph.rootNodeId,
'A root node is required to traverse',
);
let visited = new Set([rootNodeId]);
const walk = (nodeId: NodeId) => {

const nodeVisitor = nodeId => {
let node = nullthrows(assetGraph.getNode(nodeId));
let outgoing = assetGraph.getNodeIdsConnectedFrom(nodeId);

for (let childId of outgoing) {
if (!visited.has(childId)) {
visited.add(childId);
walk(childId);
let child = nullthrows(assetGraph.getNode(childId));
if (node.type === 'asset') {
invariant(child.type === 'dependency');
if (child.usedSymbolsUpDirtyUp) {
node.usedSymbolsUpDirty = true;
child.usedSymbolsUpDirtyUp = false;
}
let child = nullthrows(assetGraph.getNode(childId));
if (node.type === 'asset') {
invariant(child.type === 'dependency');
if (child.usedSymbolsUpDirtyUp) {
node.usedSymbolsUpDirty = true;
child.usedSymbolsUpDirtyUp = false;
}
}
}
Expand Down Expand Up @@ -698,7 +695,7 @@ function propagateSymbolsUp(
}
}
};
walk(rootNodeId);
assetGraph.postOrderDfsFast(nodeVisitor, rootNodeId);
}

let queue = dirtyDeps ?? changedDepsUsedSymbolsUpDirtyDownAssets;
Expand Down
61 changes: 61 additions & 0 deletions packages/core/graph/src/Graph.js
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,67 @@ export default class Graph<TNode, TEdgeType: number = 1> {
return null;
}

// A post-order implementation of dfsFast
postOrderDfsFast(
visit: GraphTraversalCallback<NodeId, TraversalActions>,
startNodeId: ?NodeId,
): void {
let traversalStartNode = nullthrows(
startNodeId ?? this.rootNodeId,
'A start node is required to traverse',
);
this._assertHasNodeId(traversalStartNode);

let visited;
if (!this._visited || this._visited.capacity < this.nodes.length) {
this._visited = new BitSet(this.nodes.length);
visited = this._visited;
} else {
visited = this._visited;
visited.clear();
}
this._visited = null;

let stopped = false;
let actions: TraversalActions = {
stop() {
stopped = true;
},
skipChildren() {
throw new Error(
'Calling skipChildren inside a post-order traversal is not allowed',
);
},
};

let queue = [traversalStartNode];
while (queue.length !== 0) {
let nodeId = queue[queue.length - 1];

if (!visited.has(nodeId)) {
visited.add(nodeId);

this.adjacencyList.forEachNodeIdConnectedFromReverse(nodeId, child => {
if (!visited.has(child)) {
queue.push(child);
}
return false;
});
} else {
queue.pop();
visit(nodeId, null, actions);

if (stopped) {
this._visited = visited;
return;
}
}
}

this._visited = visited;
return;
}

dfs<TContext>({
visit,
startNodeId,
Expand Down

0 comments on commit dc3d92b

Please sign in to comment.