fix: reduce memory usage by using numbers for Node IDs (#8135)

This commit is contained in:
Zoltan Kochan
2024-05-27 00:54:34 +02:00
committed by GitHub
parent 006f4c8a81
commit 81d90c9dd2
5 changed files with 16 additions and 11 deletions

View File

@@ -0,0 +1,5 @@
---
"@pnpm/resolve-dependencies": patch
---
Reduce memory usage during peer dependency resolution by using numbers for Node IDs.

View File

@@ -170,7 +170,7 @@ export async function resolveDependencies (
const target = !opts.excludeLinksFromLockfile || isSubdir(opts.lockfileDir, linkedDependency.resolution.directory)
? linkedDependency.resolution.directory
: path.join(project.modulesDir, linkedDependency.alias)
const linkedDir = createNodeIdForLinkedLocalPkg(opts.lockfileDir, target)
const linkedDir = createNodeIdForLinkedLocalPkg(opts.lockfileDir, target) as string
topParents.push({
name: linkedDependency.alias,
version: linkedDependency.version,

View File

@@ -2,8 +2,8 @@ let nodeIdCounter = 0
type Brand<K, T> = K & { __brand: T }
export type NodeId = Brand<string, 'nodeId'>
export type NodeId = Brand<string | number, 'nodeId'>
export function nextNodeId (): NodeId {
return (++nodeIdCounter).toString() as NodeId
return ++nodeIdCounter as NodeId
}

View File

@@ -341,7 +341,7 @@ interface ResolvePeersContext {
depPathsByPkgId?: Map<PkgIdWithPatchHash, Set<DepPath>>
}
type CalculateDepPath = (cycles: string[][]) => Promise<void>
type CalculateDepPath = (cycles: NodeId[][]) => Promise<void>
type FinishingResolutionPromise = Promise<void>
interface ParentPkgInfo {
@@ -493,7 +493,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
const peerIds: PeerId[] = []
const pendingPeerNodeIds: NodeId[] = []
for (const [alias, peerNodeId] of allResolvedPeers.entries()) {
if (peerNodeId.startsWith('link:')) {
if (typeof peerNodeId === 'string' && peerNodeId.startsWith('link:')) {
const linkedDir = peerNodeId.slice(5)
peerIds.push({
name: alias,
@@ -526,7 +526,7 @@ async function resolvePeersOfNode<T extends PartialResolvedPackage> (
async function calculateDepPath (
peerIds: PeerId[],
pendingPeerNodeIds: NodeId[],
cycles: string[][]
cycles: NodeId[][]
): Promise<void> {
const cyclicPeerNodeIds = new Set()
for (const cycle of cycles) {
@@ -618,7 +618,7 @@ function findHit<T extends PartialResolvedPackage> (ctx: {
ctx.pathsByNodeId.has(cachedNodeId) &&
ctx.pathsByNodeId.get(cachedNodeId) === ctx.pathsByNodeId.get(parentPkgNodeId)
) continue
if (!ctx.dependenciesTree.has(parentPkgNodeId) && parentPkgNodeId.startsWith('link:')) {
if (!ctx.dependenciesTree.has(parentPkgNodeId) && typeof parentPkgNodeId === 'string' && parentPkgNodeId.startsWith('link:')) {
return false
}
const parentPkgId = (ctx.dependenciesTree.get(parentPkgNodeId)!.resolvedPackage as T).pkgIdWithPatchHash
@@ -756,7 +756,7 @@ async function resolvePeersOfChildren<T extends PartialResolvedPackage> (
const parentDepPaths: Record<string, ParentPkgInfo> = {}
for (const [name, parentPkg] of Object.entries(parentPkgs)) {
if (!ctx.allPeerDepNames.has(name)) continue
if (parentPkg.nodeId && !parentPkg.nodeId.startsWith('link:')) {
if (parentPkg.nodeId && (typeof parentPkg.nodeId === 'number' || !parentPkg.nodeId.startsWith('link:'))) {
parentDepPaths[name] = {
pkgIdWithPatchHash: (ctx.dependenciesTree.get(parentPkg.nodeId)!.resolvedPackage as T).pkgIdWithPatchHash,
depth: parentPkg.depth,
@@ -793,7 +793,7 @@ async function resolvePeersOfChildren<T extends PartialResolvedPackage> (
}
}
if (calculateDepPaths.length) {
const { cycles } = analyzeGraph(graph as unknown as Graph)
const { cycles } = analyzeGraph(graph as unknown as Graph) as unknown as { cycles: NodeId[][] }
finishingList.push(...calculateDepPaths.map((calculateDepPath) => calculateDepPath(cycles)))
}
const finishing = Promise.all(finishingList).then(() => {})
@@ -812,7 +812,7 @@ function _resolvePeers<T extends PartialResolvedPackage> (
ctx: {
currentDepth: number
lockfileDir: string
nodeId: string
nodeId: NodeId
parentPkgs: ParentRefs
parentNodeIds: NodeId[]
resolvedPackage: T

View File

@@ -91,7 +91,7 @@ test('packages are not deduplicated when versions do not match', async () => {
['>project4>bar/2.0.0>' as NodeId, peers.bar_2_0_0],
['>project4>baz/2.0.0>' as NodeId, peers.baz_2_0_0],
] satisfies Array<[string, PartialResolvedPackage]>).map(([path, resolvedPackage]) => [path, {
] satisfies Array<[NodeId, PartialResolvedPackage]>).map(([path, resolvedPackage]) => [path, {
children: {},
installable: {},
resolvedPackage,