Skip to content

Commit 9246e26

Browse files
committed
feat: add memoization to when converting a graph into a tree
1 parent bda1aa5 commit 9246e26

File tree

2 files changed

+32
-4
lines changed

2 files changed

+32
-4
lines changed

src/legacy/index.ts

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import * as crypto from 'crypto';
22
import * as types from '../core/types';
3-
import { DepGraphBuilder } from '../core/builder';
3+
import { DepGraphBuilder } from '..';
44
import { EventLoopSpinner } from './event-loop-spinner';
55

66
import objectHash = require('object-hash');
@@ -286,7 +286,11 @@ async function buildSubtree(
286286
nodeId: string,
287287
eventLoopSpinner: EventLoopSpinner,
288288
maybeDeduplicationSet: Set<string> | null | false = null, // false = disabled; null = not in deduplication scope yet
289+
memoizationMap: Map<string, DepTree> = new Map(),
289290
): Promise<DepTree> {
291+
if (!maybeDeduplicationSet && memoizationMap.has(nodeId)) {
292+
return memoizationMap.get(nodeId)!;
293+
}
290294
const isRoot = nodeId === depGraph.rootNodeId;
291295
const nodePkg = depGraph.getNodePkg(nodeId);
292296
const nodeInfo = depGraph.getNode(nodeId);
@@ -302,6 +306,7 @@ async function buildSubtree(
302306

303307
const depInstanceIds = depGraph.getNodeDepsNodeIds(nodeId);
304308
if (!depInstanceIds || depInstanceIds.length === 0) {
309+
memoizationMap.set(nodeId, depTree);
305310
return depTree;
306311
}
307312

@@ -326,6 +331,7 @@ async function buildSubtree(
326331
depInstId,
327332
eventLoopSpinner,
328333
maybeDeduplicationSet,
334+
memoizationMap,
329335
);
330336
if (!subtree) {
331337
continue;
@@ -341,6 +347,7 @@ async function buildSubtree(
341347
if (eventLoopSpinner.isStarving()) {
342348
await eventLoopSpinner.spin();
343349
}
350+
memoizationMap.set(nodeId, depTree);
344351
return depTree;
345352
}
346353

test/core/stress.test.ts

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import * as depGraphLib from '../../src';
2+
import { graphToDepTree } from '../../src/legacy';
23

34
const dependencyName = 'needle';
45

@@ -10,11 +11,14 @@ async function generateLargeGraph(width: number) {
1011
const rootNodeId = 'root-node';
1112

1213
const deepDependency = { name: dependencyName, version: '1.2.3' };
14+
const deepDependency2 = { name: dependencyName + 2, version: '1.2.3' };
1315

1416
builder.addPkgNode(deepDependency, dependencyName);
17+
builder.addPkgNode(deepDependency2, deepDependency2.name);
1518
builder.connectDep(rootNodeId, dependencyName);
19+
builder.connectDep(deepDependency.name, deepDependency2.name);
1620

17-
for (let j = 0; j < width; j++) {
21+
for (let j = 0; j < width / 2; j++) {
1822
const shallowName = `id-${j}`;
1923
const shallowDependency = { name: shallowName, version: '1.2.3' };
2024

@@ -23,17 +27,34 @@ async function generateLargeGraph(width: number) {
2327
builder.connectDep(shallowName, dependencyName);
2428
}
2529

30+
for (let j = 0; j < width / 2; j++) {
31+
const shallowName = `second-${j}`;
32+
const shallowDependency = { name: shallowName, version: '1.2.3' };
33+
34+
builder.addPkgNode(shallowDependency, shallowName);
35+
builder.connectDep(deepDependency2.name, shallowName);
36+
}
37+
2638
return builder.build();
2739
}
2840

2941
describe('stress tests', () => {
42+
let graph;
43+
beforeAll(async () => {
44+
graph = await generateLargeGraph(125000);
45+
});
3046
test('pkgPathsToRoot() does not cause stack overflow for large dep-graphs', async () => {
31-
const graph = await generateLargeGraph(125000);
32-
3347
const result = graph.pkgPathsToRoot({
3448
name: dependencyName,
3549
version: '1.2.3',
3650
});
3751
expect(result).toBeDefined();
3852
});
53+
54+
test('graphToDepTree() with memoization (without deduplicateWithinTopLevelDeps) succeed for large dep-graphs', async () => {
55+
const depTree = await graphToDepTree(graph, 'gomodules', {
56+
deduplicateWithinTopLevelDeps: false,
57+
});
58+
expect(depTree).toBeDefined();
59+
});
3960
});

0 commit comments

Comments
 (0)