@@ -333,15 +333,8 @@ object Map extends MapFactory[Map] {
333
333
}
334
334
}
335
335
336
- final class Map4 [K , + V ](
337
- private [collection] val key1 : K ,
338
- private [collection] val value1 : V ,
339
- private [collection] val key2 : K ,
340
- private [collection] val value2 : V ,
341
- private [collection] val key3 : K ,
342
- private [collection] val value3 : V ,
343
- private [collection] val key4 : K ,
344
- private [collection] val value4 : V ) extends AbstractMap [K , V ] with StrictOptimizedIterableOps [(K , V ), Iterable , Map [K , V ]] {
336
+ final class Map4 [K , + V ](key1 : K , value1 : V , key2 : K , value2 : V , key3 : K , value3 : V , key4 : K , value4 : V )
337
+ extends AbstractMap [K , V ] with StrictOptimizedIterableOps [(K , V ), Iterable , Map [K , V ]] {
345
338
346
339
override def size : Int = 4
347
340
override def knownSize : Int = 4
@@ -406,6 +399,13 @@ object Map extends MapFactory[Map] {
406
399
override def foreach [U ](f : ((K , V )) => U ): Unit = {
407
400
f((key1, value1)); f((key2, value2)); f((key3, value3)); f((key4, value4))
408
401
}
402
+
403
+ private [immutable] def buildTo [V1 >: V ](builder : HashMapBuilder [K , V1 ]): Unit = {
404
+ builder.addOne(key1, value1)
405
+ builder.addOne(key2, value2)
406
+ builder.addOne(key3, value3)
407
+ builder.addOne(key4, value4)
408
+ }
409
409
}
410
410
411
411
// scalac generates a `readReplace` method to discard the deserialized state (see https://github.com/scala/bug/issues/10412).
@@ -418,46 +418,49 @@ object Map extends MapFactory[Map] {
418
418
@ SerialVersionUID (3L )
419
419
abstract class AbstractMap [K , + V ] extends scala.collection.AbstractMap [K , V ] with Map [K , V ]
420
420
421
- private [collection ] final class MapBuilderImpl [K , V ] extends Builder [(K , V ), Map [K , V ]] {
421
+ private [immutable ] final class MapBuilderImpl [K , V ] extends Builder [(K , V ), Map [K , V ]] {
422
422
private [this ] var elems : Map [K , V ] = Map .empty
423
+ private [this ] var switchedToHashMapBuilder : Boolean = false
423
424
private [this ] var hashMapBuilder : HashMapBuilder [K , V ] = _
424
425
425
426
override def clear (): Unit = {
426
427
elems = Map .empty
427
428
if (hashMapBuilder != null ) {
428
429
hashMapBuilder.clear()
429
430
}
431
+ switchedToHashMapBuilder = false
430
432
}
431
433
432
- override def result (): Map [K , V ] = {
433
- if (hashMapBuilder == null || hashMapBuilder.size == 0 ) {
434
- elems
435
- } else if (elems.size == 4 ) {
436
- val map4 = elems.asInstanceOf [Map4 [K , V ]]
434
+ override def result (): Map [K , V ] =
435
+ if (switchedToHashMapBuilder) hashMapBuilder.result() else elems
437
436
438
- hashMapBuilder.addOneIfNotExists(map4.key1, map4.value1)
439
- hashMapBuilder.addOneIfNotExists(map4.key2, map4.value2)
440
- hashMapBuilder.addOneIfNotExists(map4.key3, map4.value3)
441
- hashMapBuilder.addOneIfNotExists(map4.key4, map4.value4)
442
-
443
- hashMapBuilder.result()
444
- } else {
445
- // should never happen...
446
- elems.foreach { case (k, v) => hashMapBuilder.addOneIfNotExists(k, v) }
447
- hashMapBuilder.result()
448
- }
449
- }
450
- override def addOne (elem : (K , V )) = {
451
- if (elems.size < 4 ) {
437
+ def addOne (elem : (K , V )) = {
438
+ if (switchedToHashMapBuilder) {
439
+ hashMapBuilder.addOne(elem)
440
+ } else if (elems.size < 4 ) {
452
441
elems = elems + elem
453
442
} else {
454
- if (hashMapBuilder == null ) {
455
- hashMapBuilder = new HashMapBuilder
443
+ // assert(elems.size == 4)
444
+ if (elems.contains(elem._1)) {
445
+ elems = elems + elem
446
+ } else {
447
+ switchedToHashMapBuilder = true
448
+ if (hashMapBuilder == null ) {
449
+ hashMapBuilder = new HashMapBuilder
450
+ }
451
+ elems.asInstanceOf [Map4 [K , V ]].buildTo(hashMapBuilder)
452
+ hashMapBuilder.addOne(elem)
456
453
}
457
-
458
- hashMapBuilder.addOne(elem)
459
454
}
460
455
461
456
this
462
457
}
458
+
459
+ override def addAll (xs : IterableOnce [(K , V )]): this .type =
460
+ if (switchedToHashMapBuilder) {
461
+ hashMapBuilder.addAll(xs)
462
+ this
463
+ } else {
464
+ super .addAll(xs)
465
+ }
463
466
}
0 commit comments