Skip to content

Commit 26e5a3b

Browse files
committed
update comments
1 parent 55fd837 commit 26e5a3b

File tree

1 file changed

+16
-39
lines changed

1 file changed

+16
-39
lines changed

src/client/testing/testController/common/resultResolver.ts

Lines changed: 16 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ export class PythonResultResolver implements ITestResultResolver {
9999
// if any tests exist, they should be populated in the test tree, regardless of whether there were errors or not.
100100
// parse and insert test data.
101101

102-
// CLEANUP: Clear existing maps to remove stale references before rebuilding
102+
// Clear existing mappings before rebuilding test tree
103103
this.runIdToTestItem.clear();
104104
this.runIdToVSid.clear();
105105
this.vsIdToRunId.clear();
@@ -179,18 +179,13 @@ export class PythonResultResolver implements ITestResultResolver {
179179
}
180180

181181
/**
182-
* PERFORMANCE CRITICAL: This method rebuilds the entire test case array
183-
* Currently called for EVERY test result, causing O(n*m*k) complexity
184-
* TODO: Replace with cached lookup or direct item access
182+
* Collect all test case items from the test controller tree.
183+
* Note: This performs full tree traversal - use cached lookups when possible.
185184
*/
186185
private collectAllTestCases(): TestItem[] {
187186
const testCases: TestItem[] = [];
188187

189-
// PERFORMANCE PROBLEM: This rebuilds the ENTIRE test case array
190-
// MIDDLE OPERATION: O(m) where m = number of top-level test items in controller
191188
this.testController.items.forEach((i) => {
192-
// RECURSIVE TREE TRAVERSAL: getTestCaseNodes(i) is O(depth * children)
193-
// For parameterized tests with subtests, this can be very deep
194189
const tempArr: TestItem[] = getTestCaseNodes(i);
195190
testCases.push(...tempArr);
196191
});
@@ -199,15 +194,14 @@ export class PythonResultResolver implements ITestResultResolver {
199194
}
200195

201196
/**
202-
* Find a test item efficiently using the pre-built maps, with fallback to tree search only if needed.
203-
* This avoids the O(k) search for 99% of cases while still handling edge cases.
197+
* Find a test item efficiently using cached maps with fallback strategies.
198+
* Uses a three-tier approach: direct lookup, ID mapping, then tree search.
204199
*/
205200
private findTestItemByIdEfficient(keyTemp: string): TestItem | undefined {
206-
// FAST PATH: Try the O(1) lookup first
201+
// Try direct O(1) lookup first
207202
const directItem = this.runIdToTestItem.get(keyTemp);
208203
if (directItem) {
209-
// VALIDATION: Check if the TestItem is still valid (hasn't been deleted from controller)
210-
// This prevents using stale references
204+
// Validate the item is still in the test tree
211205
if (this.isTestItemValid(directItem)) {
212206
return directItem;
213207
} else {
@@ -216,18 +210,16 @@ export class PythonResultResolver implements ITestResultResolver {
216210
}
217211
}
218212

219-
// FALLBACK: Try vsId mapping
213+
// Try vsId mapping as fallback
220214
const vsId = this.runIdToVSid.get(keyTemp);
221215
if (vsId) {
222-
// Try to find by VS Code ID directly in the controller
223-
// This is still much faster than full tree traversal
216+
// Search by VS Code ID in the controller
224217
let foundItem: TestItem | undefined;
225218
this.testController.items.forEach((item) => {
226219
if (item.id === vsId) {
227220
foundItem = item;
228221
return;
229222
}
230-
// Check children only if not found at top level
231223
if (!foundItem) {
232224
item.children.forEach((child) => {
233225
if (child.id === vsId) {
@@ -238,19 +230,18 @@ export class PythonResultResolver implements ITestResultResolver {
238230
});
239231

240232
if (foundItem) {
241-
// Cache for next time to avoid this lookup
233+
// Cache for future lookups
242234
this.runIdToTestItem.set(keyTemp, foundItem);
243235
return foundItem;
244236
} else {
245-
// Clean up stale vsId mapping
237+
// Clean up stale mapping
246238
this.runIdToVSid.delete(keyTemp);
247239
this.vsIdToRunId.delete(vsId);
248240
}
249241
}
250242

251-
// LAST RESORT: Only do expensive tree traversal if really needed
252-
// This should rarely happen with proper discovery
253-
console.warn(`Falling back to expensive tree search for test: ${keyTemp}`);
243+
// Last resort: full tree search
244+
console.warn(`Falling back to tree search for test: ${keyTemp}`);
254245
const testCases = this.collectAllTestCases();
255246
return testCases.find((item) => item.id === vsId);
256247
}
@@ -278,11 +269,8 @@ export class PythonResultResolver implements ITestResultResolver {
278269
}
279270

280271
/**
281-
* Clean up stale references from maps (optional method for external cleanup)
282-
*
283-
* Time Complexity: O(n * depth) where n is the number of cached test items and depth
284-
* is the average tree depth. This is much more efficient than the original O(n*m*k)
285-
* tree rebuilding approach, since it only validates existing cache entries.
272+
* Clean up stale test item references from the cache maps.
273+
* Validates cached items and removes any that are no longer in the test tree.
286274
*/
287275
public cleanupStaleReferences(): void {
288276
const staleRunIds: string[] = [];
@@ -454,22 +442,11 @@ export class PythonResultResolver implements ITestResultResolver {
454442

455443
/**
456444
* Process test execution results and update VS Code's Test Explorer with outcomes.
457-
*
458-
* CURRENT PERFORMANCE ISSUE: For each test result, this method rebuilds the entire test tree
459-
* (O(m) traversal) and then searches through all test items (O(k) search). With parameterized
460-
* tests producing many results, this becomes O(n*m*k) complexity, eventually causing stack overflow.
445+
* Uses efficient lookup methods to handle large numbers of test results.
461446
*/
462447
public _resolveExecution(payload: ExecutionTestPayload, runInstance: TestRun): void {
463-
// PERFORMANCE ISSUE: This method has O(n*m*k) complexity that causes stack overflow:
464-
// - For each test result (n), we rebuild the entire test tree (m items)
465-
// - Then search through all leaf nodes (k nodes) to find the matching test
466-
// - With parameterized tests, n can be large, making this exponentially slow
467448
const rawTestExecData = payload as ExecutionTestPayload;
468449
if (rawTestExecData !== undefined && rawTestExecData.result !== undefined) {
469-
// Map which holds the subtest information for each test item.
470-
471-
// PERFORMANCE FIX: No longer need to rebuild test tree for every result!
472-
// Use efficient lookup methods instead
473450
for (const keyTemp of Object.keys(rawTestExecData.result)) {
474451
const testItem = rawTestExecData.result[keyTemp];
475452

0 commit comments

Comments
 (0)