fix(cbm): replace O(N²) ts_node_child loop with O(N) TSTreeCursor in parse_generic_imports#107
fix(cbm): replace O(N²) ts_node_child loop with O(N) TSTreeCursor in parse_generic_imports#107halindrome wants to merge 1 commit intoDeusData:mainfrom
Conversation
…c_imports ts_node_child(root, i) and ts_node_next_sibling() both call ts_node_child_with_descendant() internally, making sibling iteration O(N²) total on roots with many children (e.g. generated TypeScript .d.ts files or large Perl files with 5,000–50,000 top-level nodes). Replace with TSTreeCursor: ts_tree_cursor_goto_next_sibling() maintains traversal state across calls and is O(1) per step, reducing total complexity from O(N²) to O(N). Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
QA Round 1Reviewer: claude-opus-4-6 Findings[PASS] Cursor traversal correctness [PASS] Resource management [PASS] Thread safety [PASS] Cursor root vs. child semantics [MINOR] Pre-existing fallback logic (not a regression) SummaryThe cursor conversion is correct and complete. The pre-existing fallback logic issue is out of scope for this fix. No changes needed for Round 1. |
QA Round 2Reviewer: claude-opus-4-6 Findings[PASS] All call sites accounted for [PASS] Edge cases correct
[PASS] Test coverage [INFO] Other O(N²) extractors (out of scope) SummaryNo issues found. The cursor conversion is correct on all edge cases and all call sites are accounted for. The seven remaining O(N²) extractors are noted for a follow-up issue. |
QA CompleteBoth rounds returned PASS with no confirmed critical or major findings. The PR is ready for review. Summary of QA rounds:
No fix commits were needed. The implementation is correct as submitted. |
Fixes #106.
Problem
parse_generic_importsiterated top-level AST nodes with indexedts_node_child(root, i). This is O(i) per call internally (walks the child linked list from 0 to i viats_node_child_with_descendant), making the loop O(N²) total.ts_node_next_sibling()has the same problem — it also callsts_node_child_with_descendantinternally.On repos with generated TypeScript
.d.tsfiles or large Perl files with 5,000–50,000 top-level AST nodes, this causes the indexer to spin at 100% CPU indefinitely.Fix
Replace with
TSTreeCursor.ts_tree_cursor_goto_next_sibling()maintains traversal state and is O(1) per step. Only the iteration mechanism changes — the loop body logic is identical.Test Results