New defects (all PASS): - exim-0001: same_hosts() MX-segment O(H²) → AVL set O(H log H), 10.5x at H=20 - minecraft-0001: DependencySorter.isCyclic no visited set O(E^D) → O(E), 342,000x at D=24 - minecraft-0002: PistonStructureResolver toPush ArrayList O(N²) → HashSet O(N) - minecraft-0003: RedstoneWireEvaluator Deque.contains O(N²) → HashSet O(N) - minecraft-0004: MoveThroughVillageGoal visited List O(N²) → HashSet O(N) - mpich-0001: group_lpid_to_rank O(N²) → HashMap O(N), 313x at N=1000 - ompi-0001: group_overlap process-name scan O(N×M) → HashMap O(N+M), 2048x - pcl-0001: RegionGrowing::getSegmentFromPoint O(C×S) → point_labels[] O(1), 50000x CLEAN confirmed: esbuild, express, koa, ktor, lucene, mpich-recvq, ompi-startup, prosody, roda, rust/rustc-wave2, signal-server, solana, wiredtiger, wireguard-tools, linux-kernel (pointer to linux/)
20 lines
1.3 KiB
Diff
20 lines
1.3 KiB
Diff
--- a/src/main/java/net/minecraft/util/DependencySorter.java
|
|
+++ b/src/main/java/net/minecraft/util/DependencySorter.java
|
|
@@ -20,11 +20,12 @@ public class DependencySorter<K, V extends DependencySorter.Entry<K>> {
|
|
* Check whether adding an edge from→to would create a cycle.
|
|
* BEFORE: no visited set — exponential revisiting of shared ancestors.
|
|
+ * AFTER: visited set prevents O(E^D) blowup on diamond dependency graphs.
|
|
*/
|
|
- private static <K> boolean isCyclic(Multimap<K, K> directDependencies, K from, K to) {
|
|
+ private static <K> boolean isCyclic(Multimap<K, K> directDependencies, K from, K to, Set<K> visited) {
|
|
+ if (!visited.add(to)) return false;
|
|
Collection<K> dependencies = directDependencies.get(to);
|
|
if (dependencies.contains(from)) return true;
|
|
- return dependencies.stream().anyMatch(dep -> isCyclic(directDependencies, from, dep));
|
|
+ return dependencies.stream().anyMatch(dep -> isCyclic(directDependencies, from, dep, visited));
|
|
}
|
|
|
|
private static <K> void addDependencyIfNotCyclic(Multimap<K, K> directDependencies, K from, K to) {
|
|
- if (!isCyclic(directDependencies, from, to)) directDependencies.put(from, to);
|
|
+ if (!isCyclic(directDependencies, from, to, new HashSet<>())) directDependencies.put(from, to);
|
|
}
|