Skip to content

Commit b9e2ba7

Browse files
authored
fix: Use an actual queue for BFS traversal (#308)
`Array.shift()` is an O(N) operation, it moves the tail to the front of the array. For BFS traversal in verbose which does not prune except on cycles, these queues can get quite wide (>600K for a relatively simple repo) This makes the BFS traversal actually efficient
1 parent 061c346 commit b9e2ba7

File tree

2 files changed

+11
-5
lines changed

2 files changed

+11
-5
lines changed

lib/graph.ts

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { DepGraphBuilder, PkgInfo, PkgManager } from '@snyk/dep-graph';
2+
import Queue from '@common.js/yocto-queue';
23

34
import type { Sha1Map } from './types';
45
import { parseCoordinate } from './coordinate';
@@ -37,12 +38,14 @@ export async function buildGraph(
3738
}
3839

3940
const visitedMap: Record<string, PkgInfo> = {};
40-
const queue: QueueItem[] = [];
41-
queue.push(...findChildren('root-node', [], gradleGraph)); // queue direct dependencies
41+
const queue = new Queue<QueueItem>();
42+
findChildren('root-node', [], gradleGraph).forEach((item) =>
43+
queue.enqueue(item),
44+
);
4245

4346
// breadth first search
44-
while (queue.length > 0) {
45-
const item = queue.shift();
47+
while (queue.size > 0) {
48+
const item = queue.dequeue();
4649
if (!item) continue;
4750
let { id, parentId } = item;
4851
const { ancestry } = item;
@@ -107,7 +110,9 @@ export async function buildGraph(
107110
visitedMap[id] = { name, version };
108111
}
109112
// Remember to push updated ancestry here
110-
queue.push(...findChildren(gradleGraphId, [...ancestry, id], gradleGraph)); // queue children
113+
findChildren(gradleGraphId, [...ancestry, id], gradleGraph).forEach(
114+
(item) => queue.enqueue(item),
115+
);
111116
}
112117

113118
return depGraphBuilder.build();

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
"typescript": "^4.2.0"
4141
},
4242
"dependencies": {
43+
"@common.js/yocto-queue": "^1.1.1",
4344
"@snyk/cli-interface": "2.11.3",
4445
"@snyk/dep-graph": "^1.28.0",
4546
"@types/debug": "^4.1.4",

0 commit comments

Comments
 (0)