18
18
*/
19
19
package org .eclipse .aether .util .graph .manager ;
20
20
21
+ import java .util .ArrayList ;
22
+ import java .util .Collection ;
21
23
import java .util .HashMap ;
24
+ import java .util .Map ;
25
+ import java .util .Objects ;
22
26
23
27
/**
24
28
* 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) {
47
51
return new MMap <>(new HashMap <>(orig .delegate ));
48
52
}
49
53
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
+
50
66
protected final HashMap <K , V > delegate ;
51
67
52
68
private MMap (HashMap <K , V > delegate ) {
@@ -69,6 +85,10 @@ public MMap<K, V> done() {
69
85
return new DoneMMap <>(delegate );
70
86
}
71
87
88
+ public MMap <K , V > append () {
89
+ return new AppendMMap <>(this );
90
+ }
91
+
72
92
@ Override
73
93
public int hashCode () {
74
94
throw new IllegalStateException ("MMap is not done yet" );
@@ -79,12 +99,20 @@ public boolean equals(Object o) {
79
99
throw new IllegalStateException ("MMap is not done yet" );
80
100
}
81
101
102
+ public int size () {
103
+ return delegate .size ();
104
+ }
105
+
82
106
private static class DoneMMap <K , V > extends MMap <K , V > {
83
- private final int hashCode ;
107
+ volatile long hashCode = Long . MAX_VALUE ;
84
108
85
109
private DoneMMap (HashMap <K , V > delegate ) {
86
110
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 ;
88
116
}
89
117
90
118
@ Override
@@ -99,7 +127,12 @@ public MMap<K, V> done() {
99
127
100
128
@ Override
101
129
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 ;
103
136
}
104
137
105
138
@ Override
@@ -111,4 +144,35 @@ public boolean equals(Object o) {
111
144
return delegate .equals (other .delegate );
112
145
}
113
146
}
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
+ }
114
178
}
0 commit comments