gnodet opened a new pull request, #1941: URL: https://github.com/apache/maven-resolver/pull/1941
## Summary `ScopeDependencySelector` and `OptionalDependencySelector` (in `impl.scope` package) always create new instances in `deriveChildSelector()`, incrementing `depth` at every level. Since `depth` is part of `equals()`/`hashCode()`, every tree depth produces a unique selector, which makes the `DataPool`/`GraphKey` cache in the DF dependency collector miss on every lookup across depths. This causes **exponential node growth** in the DF collector for large dependency trees. In a benchmark with a large multi-module project: | Configuration | Node count | |---|---| | Resolver 1.9.27 (Maven 3.9.16), DF collector | 1,054,704 | | Resolver 2.0.x (Maven 3.10.x), BF collector | 1,915,842 | | Resolver 2.0.x (Maven 3.10.x), DF collector | 9,893,981 | The DF collector's 9.4x node increase is caused by cache misses cascading exponentially — each miss triggers full recursion, discovering more nodes that also miss the cache. ## Root cause The old selectors (resolver 1.x, in `util.graph.selector` package) returned `this` from `deriveChildSelector()` once their behavior stabilized: - `ScopeDependencySelector`: returned `this` once `transitive=true` (after depth 1) - `OptionalDependencySelector`: returned `this` once `depth >= 2` The `AndDependencySelector` already optimizes for this pattern (line 119): when all child selectors return `this` (reference equality), the `AndDependencySelector` also returns `this`. This meant the entire composite selector was the **same instance** at all depths 2+, enabling cache hits in the `GraphKey`. The new `impl.scope` selectors never return `this` — they always create new instances with `depth + 1`, breaking this optimization chain. ## Fix Both selectors now return `this` from `deriveChildSelector()` once `depth >= applyFrom` (the point after which their `selectDependency()` behavior no longer changes with depth). For `ScopeDependencySelector`, the only exception is `depth == applyTo` where behavior transitions from "filter by scope" to "accept all". For the default Maven 3.10.x configuration (`ScopeDependencySelector.legacy(null, ["test", "provided"])`), this means the selector stabilizes at depth 2, matching the old resolver 1.x behavior. _Claude Code on behalf of Guillaume Nodet_ -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
