Skip to content

Commit f295e15

Browse files
committed
bugfix for MMap with List value usage.(also performance related)
fix the bug about using MMap when value be collection, but the old codes didn't copy the collection, thus may cause appending to a list value in a DoneMMap, thus makes infinity long value, thus makes the run slow in super multi module project.
1 parent d0a0269 commit f295e15

File tree

2 files changed

+72
-8
lines changed

2 files changed

+72
-8
lines changed

maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/AbstractDependencyManager.java

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -151,23 +151,23 @@ public DependencyManager deriveChildManager(DependencyCollectionContext context)
151151
String version = artifact.getVersion();
152152
if (!version.isEmpty() && !managedVersions.containsKey(key)) {
153153
if (managedVersions == this.managedVersions) {
154-
managedVersions = MMap.copy(this.managedVersions);
154+
managedVersions = MMap.append(this.managedVersions);
155155
}
156156
managedVersions.put(key, new Holder<>(depth, version));
157157
}
158158

159159
String scope = managedDependency.getScope();
160160
if (!scope.isEmpty() && !managedScopes.containsKey(key)) {
161161
if (managedScopes == this.managedScopes) {
162-
managedScopes = MMap.copy(this.managedScopes);
162+
managedScopes = MMap.append(this.managedScopes);
163163
}
164164
managedScopes.put(key, new Holder<>(depth, scope));
165165
}
166166

167167
Boolean optional = managedDependency.getOptional();
168168
if (optional != null && !managedOptionals.containsKey(key)) {
169169
if (managedOptionals == this.managedOptionals) {
170-
managedOptionals = MMap.copy(this.managedOptionals);
170+
managedOptionals = MMap.append(this.managedOptionals);
171171
}
172172
managedOptionals.put(key, new Holder<>(depth, optional));
173173
}
@@ -177,15 +177,15 @@ public DependencyManager deriveChildManager(DependencyCollectionContext context)
177177
: systemDependencyScope.getSystemPath(managedDependency.getArtifact());
178178
if (localPath != null && !managedLocalPaths.containsKey(key)) {
179179
if (managedLocalPaths == this.managedLocalPaths) {
180-
managedLocalPaths = MMap.copy(this.managedLocalPaths);
180+
managedLocalPaths = MMap.append(this.managedLocalPaths);
181181
}
182182
managedLocalPaths.put(key, new Holder<>(depth, localPath));
183183
}
184184

185185
Collection<Exclusion> exclusions = managedDependency.getExclusions();
186186
if (!exclusions.isEmpty()) {
187187
if (managedExclusions == this.managedExclusions) {
188-
managedExclusions = MMap.copy(this.managedExclusions);
188+
managedExclusions = MMap.copyWithListValue(this.managedExclusions);
189189
}
190190
Collection<Holder<Collection<Exclusion>>> managed = managedExclusions.get(key);
191191
if (managed == null) {

maven-resolver-util/src/main/java/org/eclipse/aether/util/graph/manager/MMap.java

Lines changed: 67 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,11 @@
1818
*/
1919
package org.eclipse.aether.util.graph.manager;
2020

21+
import java.util.ArrayList;
22+
import java.util.Collection;
2123
import java.util.HashMap;
24+
import java.util.Map;
25+
import java.util.Objects;
2226

2327
/**
2428
* Warning: this is a special map-like construct that suits only and should be used only in this package!
@@ -47,6 +51,18 @@ public static <K, V> MMap<K, V> copy(MMap<K, V> orig) {
4751
return new MMap<>(new HashMap<>(orig.delegate));
4852
}
4953

54+
public static <K, V> MMap<K, Collection<V>> copyWithListValue(MMap<K, Collection<V>> orig) {
55+
HashMap<K, Collection<V>> newMap = new HashMap<>((int) Math.ceil(orig.size() / 0.75D));
56+
for (Map.Entry<K, Collection<V>> entry : orig.delegate.entrySet()) {
57+
newMap.put(entry.getKey(), entry.getValue() == null ? null : new ArrayList<>(entry.getValue()));
58+
}
59+
return new MMap<>(newMap);
60+
}
61+
62+
public static <K, V> MMap<K, V> append(MMap<K, V> orig) {
63+
return new AppendMMap<>(orig);
64+
}
65+
5066
protected final HashMap<K, V> delegate;
5167

5268
private MMap(HashMap<K, V> delegate) {
@@ -69,6 +85,10 @@ public MMap<K, V> done() {
6985
return new DoneMMap<>(delegate);
7086
}
7187

88+
public MMap<K, V> append() {
89+
return new AppendMMap<>(this);
90+
}
91+
7292
@Override
7393
public int hashCode() {
7494
throw new IllegalStateException("MMap is not done yet");
@@ -79,12 +99,20 @@ public boolean equals(Object o) {
7999
throw new IllegalStateException("MMap is not done yet");
80100
}
81101

102+
public int size() {
103+
return delegate.size();
104+
}
105+
82106
private static class DoneMMap<K, V> extends MMap<K, V> {
83-
private final int hashCode;
107+
volatile long hashCode = Long.MAX_VALUE;
84108

85109
private DoneMMap(HashMap<K, V> delegate) {
86110
super(delegate);
87-
this.hashCode = delegate.hashCode();
111+
}
112+
113+
private DoneMMap(HashMap<K, V> delegate, long hashCode) {
114+
super(delegate);
115+
this.hashCode = hashCode;
88116
}
89117

90118
@Override
@@ -99,7 +127,12 @@ public MMap<K, V> done() {
99127

100128
@Override
101129
public int hashCode() {
102-
return hashCode;
130+
if (this.hashCode != Long.MAX_VALUE) {
131+
return (int) hashCode;
132+
}
133+
int result = delegate.hashCode();
134+
this.hashCode = result;
135+
return result;
103136
}
104137

105138
@Override
@@ -111,4 +144,35 @@ public boolean equals(Object o) {
111144
return delegate.equals(other.delegate);
112145
}
113146
}
147+
148+
private static class AppendMMap<K, V> extends DoneMMap<K, V> {
149+
150+
AppendMMap(MMap<K, V> orig) {
151+
super(new HashMap<>(orig.delegate));
152+
if (orig instanceof DoneMMap) {
153+
this.hashCode = ((DoneMMap<K, V>) orig).hashCode;
154+
} else {
155+
this.hashCode = Long.MAX_VALUE;
156+
}
157+
}
158+
159+
@Override
160+
public V put(K key, V value) {
161+
boolean ifPresent = delegate.containsKey(key);
162+
V originalValue = delegate.put(key, value);
163+
if (hashCode != Long.MAX_VALUE) {
164+
int keyHash = Objects.hashCode(key);
165+
if (ifPresent) {
166+
hashCode -= keyHash ^ Objects.hashCode(originalValue);
167+
}
168+
hashCode += keyHash ^ Objects.hashCode(value);
169+
}
170+
return originalValue;
171+
}
172+
173+
@Override
174+
public MMap<K, V> done() {
175+
return new DoneMMap<>(delegate, hashCode);
176+
}
177+
}
114178
}

0 commit comments

Comments
 (0)