# Timeline — java-topology ## 2026-03-23 **Session opened.** Sparse shallow clone of `jdk.compiler` confirmed present. Branch: `master`. **Investigation started.** Searched all `.java` files for `Graph`, `Topology`, `graph`, `topology` hits. **Primary targets identified:** - `util/GraphUtils.java` — core graph algorithm library - `util/Dependencies.java` — symbol completion dependency graph - `comp/Infer.java` — type inference graph solver (uses Tarjan) - `comp/DeferredAttr.java` — stuck expression resolution (uses Tarjan) - `comp/Modules.java` — module graph, transitive closure **Defect confirmed:** `GraphUtils.java:186` — Tarjan's SCC algorithm uses `stack.contains(n)` (O(n) linear scan on `ListBuffer`) instead of `n.active` (O(1) boolean field that exists on `TarjanNode` for exactly this purpose). Makes Tarjan O(V²) instead of O(V+E). **Ticket opened:** [0001-tarjan-ov2-stack-contains](tickets/0001-tarjan-ov2-stack-contains.md) **Tests created:** `tests/unit/`, `tests/integration/`, `tests/functional/` — 74 tests all passing. `make -C tests all`. **Before/after timing confirmed:** - Algorithm level: 23x speedup at V=800, ~4x growth ratio BEFORE vs ~2x AFTER. - End-to-end compilation: no measurable difference at typical inference var counts (V=4–6). ## 2026-03-23 (continued) **Stack-wide defect survey.** Fox pointed out the algorithm propagates up the full stack. Extracted all JDK module classes from jimage and scanned bytecode for `Deque/List/Stack.contains()` in graph/topology/dependency code. **Additional defect sites confirmed:** | Ticket | Location | Defect | Module | |--------|----------|--------|--------| | 0002 | `Infer$GraphSolver$InferenceGraph.findNode()` | O(N) ArrayList scan, called O(N³) total via `buildStuckGraph()` → `canInfluence()` | jdk.compiler | | 0003 | `ModuleHashesBuilder$TopoSorter.visit()` | `Deque.contains()` for on-stack check — same pattern as 0001, different module | **java.base** | | 0004 | `Dependencies$GraphDependencies$Node.addDependency()` | `List.contains()` dedup on every add | jdk.compiler | **Pattern confirmed:** The same O(n) membership check on a linear collection, used where O(1) is possible and a dedicated flag/set already exists or trivially could. Not one bug — a systemic pattern replicated across at least 4 locations in 2 modules. **Cascade analysis:** - `buildStuckGraph()` is O(N³) due to N² calls to `canInfluence()`, each doing O(N) `findNode()` + uncached O(V+E) `closure()` — independent of 0001. - `ModuleHashesBuilder` is in `java.base` — affects every `jlink` build. - Fix 0001 alone: algorithm is correct but callers are still slow. - Fix 0001+0002+0003: full stack improvement. **Next:** Tickets for 0002–0004. Additional dot diagrams. Tests for 0002 (closure caching, findNode indexing).