mirror of
https://github.com/pnpm/pnpm.git
synced 2026-01-09 23:48:28 -05:00
feat(graph-sequencer): topological ordering will look for the longest circle (#8052)
This commit is contained in:
5
.changeset/kind-carrots-fry.md
Normal file
5
.changeset/kind-carrots-fry.md
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
"@pnpm/deps.graph-sequencer": patch
|
||||
---
|
||||
|
||||
Topological ordering will look for the longest circle
|
||||
13
deps/graph-sequencer/src/index.ts
vendored
13
deps/graph-sequencer/src/index.ts
vendored
@@ -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
|
||||
@@ -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
deps/graph-sequencer/test/index.ts
vendored
20
deps/graph-sequencer/test/index.ts
vendored
@@ -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']],
|
||||
@@ -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']],
|
||||
}
|
||||
)
|
||||
})
|
||||
|
||||
Reference in New Issue
Block a user