gnodet opened a new pull request, #1937:
URL: https://github.com/apache/maven-resolver/pull/1937

   ## Summary
   
   Fixes a severe performance regression introduced in 2.0.19 by commits 
7fa7741 and d9a1b87, which added heavyweight `synchronized` blocks on the two 
hottest paths during dependency resolution.
   
   The `synchronized(versionCache)` in `GenericVersionScheme.parseVersion()` 
and `synchronized(map)` in `WeakInternPool.intern()` create **global serial 
bottlenecks** that force all threads to serialize on a single monitor — even 
for cache hits (the common case). This effectively destroys the parallelism 
that makes Resolver 2.x twice as fast as 1.x.
   
   Reported by @cstamas: building Quarkus regressed from ~6 min (3.10-SNAPSHOT 
before the fixes) back to ~12 min (same as 3.9.16), completely erasing Resolver 
2.x's speedup.
   
   ### Changes
   
   - **`GenericVersionScheme`**: Replace `Collections.synchronizedMap(new 
WeakHashMap<>())` with `ConcurrentHashMap`. Its `computeIfAbsent` is 
lock-striped, allowing concurrent access across hash buckets. Weak-reference 
semantics are unnecessary here — version strings are small and bounded per 
build.
   
   - **`WeakInternPool`**: Replace `Collections.synchronizedMap` + 
`synchronized(map)` with a plain `WeakHashMap` guarded by a `ReadWriteLock`. 
The read lock allows concurrent cache hits (the overwhelmingly common case); 
only cache misses acquire the exclusive write lock. This preserves 
weak-reference GC semantics while eliminating the serial bottleneck.
   
   ### Background
   
   The original thread-safety issue was real: `Collections.synchronizedMap` 
does not make compound operations like `computeIfAbsent`/`compute` atomic — the 
default `Map` implementations call `get()` then `put()` as separate 
synchronized calls, leaving a race window that can corrupt `WeakHashMap`'s 
internal hash table. But `synchronized` on the entire map is the wrong remedy 
for hot paths — it trades a rare race for guaranteed serialization of every 
access.
   
   ## Test plan
   
   - [x] All 440 tests pass in `maven-resolver-util` and `maven-resolver-impl`
   - [ ] Benchmark: build Quarkus with this patch and verify wall-clock time 
returns to ~6 min range (from ~12 min with 2.0.19)
   
   🤖 Generated with [Claude Code](https://claude.com/claude-code)


-- 
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]

Reply via email to