@@ -46,7 +46,7 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
46
46
with CustomParallelizable [(A , B ), ParHashMap [A , B ]]
47
47
with HasForeachEntry [A , B ]
48
48
{
49
- import HashMap .{nullToEmpty , bufferSize }
49
+ import HashMap .{bufferSize , concatMerger , nullToEmpty }
50
50
51
51
override def size : Int = 0
52
52
@@ -159,7 +159,7 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
159
159
override def values : scala.collection.Iterable [B ] = new HashMapValues
160
160
161
161
override final def transform [W , That ](f : (A , B ) => W )(implicit bf : CanBuildFrom [HashMap [A , B ], (A , W ), That ]): That =
162
- if ((bf eq Map .canBuildFrom) || (bf eq HashMap .canBuildFrom)) transformImpl(f). asInstanceOf [ That ]
162
+ if ((bf eq Map .canBuildFrom) || (bf eq HashMap .canBuildFrom)) castToThat( transformImpl(f))
163
163
else super .transform(f)(bf)
164
164
165
165
/* `transform` specialized to return a HashMap */
@@ -179,17 +179,18 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
179
179
override def ++ [C >: (A , B ), That ](that : GenTraversableOnce [C ])(implicit bf : CanBuildFrom [HashMap [A , B ], C , That ]): That = {
180
180
if (isCompatibleCBF(bf)) {
181
181
// here we know that That =:= HashMap[_, _], or compatible with it
182
- if (this eq that.asInstanceOf [AnyRef ]) that.asInstanceOf [That ]
183
- else if (that.isEmpty) this .asInstanceOf [That ]
184
- else that match {
185
- case thatHash : HashMap [A , B ] =>
186
- // default Merge prefers to keep than replace
187
- // so we merge from thatHash
188
- (thatHash.merged(this ) (null ) ).asInstanceOf [That ]
189
- case that =>
190
- var result : HashMap [Any , _] = this .asInstanceOf [HashMap [Any , _]]
191
- that foreach { case kv : (_, _) => result = result + kv }
192
- result.asInstanceOf [That ]
182
+ if (this eq that.asInstanceOf [AnyRef ]) castToThat(that)
183
+ else if (that.isEmpty) castToThat(this )
184
+ else {
185
+ val result : HashMap [A , B ] = that match {
186
+ case thatHash : HashMap [A , B ] =>
187
+ this .merge0(thatHash, 0 , concatMerger[A , B ])
188
+ case that =>
189
+ var result : HashMap [A , B ] = this
190
+ that.asInstanceOf [GenTraversableOnce [(A , B )]] foreach { case kv : (_, _) => result = result + kv }
191
+ result
192
+ }
193
+ castToThat(result)
193
194
}
194
195
} else super .++ (that)(bf)
195
196
}
@@ -203,42 +204,45 @@ sealed class HashMap[A, +B] extends AbstractMap[A, B]
203
204
if (isCompatibleCBF(bf)) addSimple(that)
204
205
else super .++: (that)
205
206
}
206
- private def addSimple [C >: (A , B ), That ](that : TraversableOnce [C ]): That = {
207
+ private def addSimple [C >: (A , B ), That ](that : TraversableOnce [C ])( implicit bf : CanBuildFrom [ HashMap [ A , B ], C , That ]) : That = {
207
208
// here we know that That =:= HashMap[_, _], or compatible with it
208
- if (this eq that.asInstanceOf [AnyRef ]) that.asInstanceOf [That ]
209
- else if (that.isEmpty) this .asInstanceOf [That ]
210
- else that match {
211
- case thatHash : HashMap [A , B ] =>
212
- val merger : Merger [A , B ] = HashMap .liftMerger[A , B ](null )
213
- // merger prefers to keep than replace
214
- // so we invert
215
- (this .merge0(thatHash, 0 , merger.invert)).asInstanceOf [That ]
216
-
217
- case that: HasForeachEntry [A , B ] =>
218
- object adder extends Function2 [A , B , Unit ] {
219
- var result : HashMap [A , B ] = this .asInstanceOf [HashMap [A , B ]]
220
- val merger = HashMap .liftMerger[A , B ](null )
221
-
222
- override def apply (key : A , value : B ): Unit = {
223
- result = result.updated0(key, computeHash(key), 0 , value, null , merger)
209
+ if (this eq that.asInstanceOf [AnyRef ]) castToThat(that)
210
+ else if (that.isEmpty) castToThat(this )
211
+ else {
212
+ val merger = HashMap .concatMerger[A , B ].invert
213
+ val result : HashMap [A , B ] = that match {
214
+ case thatHash : HashMap [A , B ] =>
215
+ this .merge0(thatHash, 0 , HashMap .concatMerger[A , B ].invert)
216
+
217
+ case that: HasForeachEntry [A , B ] =>
218
+ object adder extends Function2 [A , B , Unit ] {
219
+ var result : HashMap [A , B ] = HashMap .this
220
+ override def apply (key : A , value : B ): Unit = {
221
+ result = result.updated0(key, computeHash(key), 0 , value, null , merger)
222
+ }
224
223
}
225
- }
226
- that foreachEntry adder
227
- adder.result.asInstanceOf [That ]
228
- case that =>
229
- object adder extends Function1 [(A ,B ), Unit ] {
230
- var result : HashMap [A , B ] = this .asInstanceOf [HashMap [A , B ]]
231
- val merger = HashMap .liftMerger[A , B ](null )
232
-
233
- override def apply (kv : (A , B )): Unit = {
234
- val key = kv._1
235
- result = result.updated0(key, computeHash(key), 0 , kv._2, kv, merger)
224
+ that foreachEntry adder
225
+ adder.result
226
+ case that =>
227
+ object adder extends Function1 [(A ,B ), Unit ] {
228
+ var result : HashMap [A , B ] = HashMap .this
229
+ override def apply (kv : (A , B )): Unit = {
230
+ val key = kv._1
231
+ result = result.updated0(key, computeHash(key), 0 , kv._2, kv, merger)
232
+ }
236
233
}
237
- }
238
- that.asInstanceOf [scala.Traversable [(A ,B )]] foreach adder
239
- adder.result.asInstanceOf [That ]
234
+ that.asInstanceOf [scala.Traversable [(A ,B )]] foreach adder
235
+ adder.result
236
+ }
237
+ castToThat(result)
240
238
}
241
239
}
240
+ private [this ] def castToThat [C , That ](m : HashMap [A , B ])(implicit bf : CanBuildFrom [HashMap [A , B ], C , That ]): That = {
241
+ m.asInstanceOf [That ]
242
+ }
243
+ private [this ] def castToThat [C , That ](m : GenTraversableOnce [C ])(implicit bf : CanBuildFrom [HashMap [A , B ], C , That ]): That = {
244
+ m.asInstanceOf [That ]
245
+ }
242
246
}
243
247
244
248
/** $factoryInfo
@@ -261,9 +265,10 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
261
265
private type MergeFunction [A1 , B1 ] = ((A1 , B1 ), (A1 , B1 )) => (A1 , B1 )
262
266
263
267
private def liftMerger [A1 , B1 ](mergef : MergeFunction [A1 , B1 ]): Merger [A1 , B1 ] =
264
- if (mergef == null ) defaultMerger. asInstanceOf [ Merger [ A1 , B1 ] ] else liftMerger0(mergef)
268
+ if (mergef == null ) defaultMerger[ A1 , B1 ] else liftMerger0(mergef)
265
269
266
- private val defaultMerger : Merger [Any , Any ] = new Merger [Any , Any ] {
270
+ private def defaultMerger [A , B ]: Merger [A , B ] = _defaultMerger.asInstanceOf [Merger [A , B ]]
271
+ private [this ] val _defaultMerger : Merger [Any , Any ] = new Merger [Any , Any ] {
267
272
override def apply (a : (Any , Any ), b : (Any , Any )): (Any , Any ) = a
268
273
override def retainIdentical : Boolean = true
269
274
override val invert : Merger [Any , Any ] = new Merger [Any , Any ] {
@@ -273,6 +278,23 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
273
278
}
274
279
}
275
280
281
+ private def concatMerger [A , B ]: Merger [A , B ] = _concatMerger.asInstanceOf [Merger [A , B ]]
282
+ private [this ] val _concatMerger : Merger [Any , Any ] = new Merger [Any , Any ] {
283
+ override def apply (a : (Any , Any ), b : (Any , Any )): (Any , Any ) = {
284
+ if (a._1.asInstanceOf [AnyRef ] eq b._1.asInstanceOf [AnyRef ]) b
285
+ else (a._1, b._2)
286
+ }
287
+ override def retainIdentical : Boolean = true
288
+ override val invert : Merger [Any , Any ] = new Merger [Any , Any ] {
289
+ override def apply (a : (Any , Any ), b : (Any , Any )): (Any , Any ) = {
290
+ if (b._1.asInstanceOf [AnyRef ] eq a._1.asInstanceOf [AnyRef ]) a
291
+ else (b._1, a._2)
292
+ }
293
+ override def retainIdentical : Boolean = true
294
+ override def invert = concatMerger
295
+ }
296
+ }
297
+
276
298
private [this ] def liftMerger0 [A1 , B1 ](mergef : MergeFunction [A1 , B1 ]): Merger [A1 , B1 ] = new Merger [A1 , B1 ] {
277
299
self =>
278
300
def apply (kv1 : (A1 , B1 ), kv2 : (A1 , B1 )): (A1 , B1 ) = mergef(kv1, kv2)
@@ -1049,7 +1071,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
1049
1071
1050
1072
/** The root node of the partially build hashmap */
1051
1073
private var rootNode : HashMap [A , B ] = HashMap .empty
1052
- private def plusPlusMerger = liftMerger[ A , B ]( null ).invert
1074
+
1053
1075
private def isMutable (hs : HashMap [A , B ]) = {
1054
1076
hs.isInstanceOf [HashTrieMap [A , B ]] && hs.size == - 1
1055
1077
}
@@ -1249,11 +1271,11 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int {
1249
1271
if (toNode eq toBeAdded) toNode
1250
1272
else toBeAdded match {
1251
1273
case bLeaf : HashMap1 [A , B ] =>
1252
- if (toNodeHash == bLeaf.hash) toNode.merge0(bLeaf, level, plusPlusMerger )
1274
+ if (toNodeHash == bLeaf.hash) toNode.merge0(bLeaf, level, concatMerger[ A , B ] )
1253
1275
else makeMutableTrie(toNode, bLeaf, level)
1254
1276
1255
1277
case bLeaf : HashMapCollision1 [A , B ] =>
1256
- if (toNodeHash == bLeaf.hash) toNode.merge0(bLeaf, level, plusPlusMerger )
1278
+ if (toNodeHash == bLeaf.hash) toNode.merge0(bLeaf, level, concatMerger[ A , B ] )
1257
1279
else makeMutableTrie(toNode, bLeaf, level)
1258
1280
1259
1281
case bTrie : HashTrieMap [A , B ] =>
0 commit comments