Skip to content

Commit

Permalink
feat(graph-sequencer): topological ordering will look for the longest…
Browse files Browse the repository at this point in the history
… circle (pnpm#8052)
  • Loading branch information
ahaoboy authored May 6, 2024
1 parent 7a0536e commit db1d6ff
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 4 deletions.
5 changes: 5 additions & 0 deletions .changeset/kind-carrots-fry.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@pnpm/deps.graph-sequencer": patch
---

Topological ordering will look for the longest circle
13 changes: 11 additions & 2 deletions deps/graph-sequencer/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,15 @@ export function graphSequencer<T> (graph: Graph<T>, includedNodes: T[] = [...gra
function findCycle (startNode: T): T[] {
const queue: Array<[T, T[]]> = [[startNode, [startNode]]]
const cycleVisited = new Set<T>()
const cycles: T[][] = []

while (queue.length) {
const [id, cycle] = queue.shift()!
for (const to of graph.get(id)!) {
if (to === startNode) {
return cycle
cycleVisited.add(to)
cycles.push([...cycle])
continue
}
if (visited.has(to) || cycleVisited.has(to)) {
continue
Expand All @@ -111,6 +115,11 @@ export function graphSequencer<T> (graph: Graph<T>, includedNodes: T[] = [...gra
queue.push([to, [...cycle, to]])
}
}
return []

if (!cycles.length) {
return []
}
cycles.sort((a, b) => b.length - a.length)
return cycles[0]
}
}
20 changes: 18 additions & 2 deletions deps/graph-sequencer/test/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -350,8 +350,7 @@ test('graph with many nodes. Sequencing a subgraph', () => {
)
})

// TODO: fix this test
test.skip('graph with big cycle', () => {
test('graph with big cycle', () => {
expect(graphSequencer(new Map([
['a', ['b']],
['b', ['a', 'c']],
Expand All @@ -364,3 +363,20 @@ test.skip('graph with big cycle', () => {
}
)
})

test('graph with three cycles', () => {
expect(graphSequencer(new Map([
['a', ['b']],
['b', ['a', 'c']],
['c', ['a', 'b']],
['e', ['f']],
['f', ['e']],
['g', ['g']],
]))).toStrictEqual(
{
safe: false,
chunks: [['a', 'b', 'c', 'e', 'f', 'g']],
cycles: [['a', 'b', 'c'], ['e', 'f'], ['g']],
}
)
})

0 comments on commit db1d6ff

Please sign in to comment.