Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .bumpy/faster-large-schema-resolve.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"varlock": patch
---

Resolving a large schema no longer slows down quadratically with the number of items (3,000 items: about 245 ms to 50 ms)
9 changes: 7 additions & 2 deletions packages/varlock/src/env-graph/lib/env-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -933,18 +933,23 @@ export class EnvGraph {
// - false = not yet started
// - items are removed when completed
const itemsToResolveStatus = _.fromPairs(keysToResolve.map((key) => [key, false]));
// kept as a counter, because counting the object's keys after every item is O(n^2)
let itemsRemaining = Object.keys(itemsToResolveStatus).length;

// code is a bit awkward here because we are resolving items in parallel
// and need to continue resolving dependent items as each finishes

const deferred = new Promise<void>((resolve, reject) => {
const markItemCompleted = (itemKey: string) => {
delete itemsToResolveStatus[itemKey];
if (itemKey in itemsToResolveStatus) {
delete itemsToResolveStatus[itemKey];
itemsRemaining--;
}
if (reverseAdjList[itemKey]) {
// eslint-disable-next-line no-use-before-define
reverseAdjList[itemKey].forEach((depKey) => startResolveItem(depKey));
}
if (_.keys(itemsToResolveStatus).length === 0) resolve();
if (itemsRemaining === 0) resolve();
};

const resolveItem = async (itemKey: string) => {
Expand Down
Loading