Skip to content

Commit 08d8f8a

Browse files
committed
Map ++ without CBF should use the same optimised path as ++ with CBF
also optimise for small map addition
1 parent 5320f0b commit 08d8f8a

File tree

1 file changed

+63
-2
lines changed
  • library/src/scala/collection/immutable

1 file changed

+63
-2
lines changed

library/src/scala/collection/immutable/Map.scala

Lines changed: 63 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ package collection
1515
package immutable
1616

1717
import generic._
18-
import scala.collection.immutable.Map.MapBuilderImpl
1918
import scala.util.hashing.MurmurHash3
2019

2120
/**
@@ -116,7 +115,7 @@ object Map extends ImmutableMapFactory[Map] {
116115
if (isMapCBF(bf))
117116
that match {
118117
case hm: HashMap[a, b] if hm.size > 4 => hm.asInstanceOf[That]
119-
case EmptyMap => this.asInstanceOf[That]
118+
case m: AnyRef if m eq EmptyMap => this.asInstanceOf[That]
120119
case m: Map1[_, _] => m.asInstanceOf[That]
121120
case m: Map2[_, _] => m.asInstanceOf[That]
122121
case m: Map3[_, _] => m.asInstanceOf[That]
@@ -151,6 +150,20 @@ object Map extends ImmutableMapFactory[Map] {
151150
if (key == key1) new Map1(key1, value)
152151
else new Map2(key1, value1, key, value)
153152
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
153+
override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): Map[K, V1] = ++[(K, V1), Map[K, V1]](xs)(Map.canBuildFrom[K, V1])
154+
override def ++[B >: (K, V), That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Map[K, V], B, That]): That = {
155+
if (isMapCBF(bf)) that match {
156+
case m: AnyRef if m eq EmptyMap => this.asInstanceOf[That]
157+
case m: Map1[K, V] => m.addTo(this).asInstanceOf[That]
158+
case m: Map2[K, V] => m.addTo(this).asInstanceOf[That]
159+
case m: Map3[K, V] => m.addTo(this).asInstanceOf[That]
160+
case m: Map4[K, V] => m.addTo(this).asInstanceOf[That]
161+
case _ => super.++(that)(bf)
162+
} else super.++(that)(bf)
163+
}
164+
private[Map] def addTo[V1 >: V](m : Map[K,V1]): Map[K, V1] = {
165+
m.updated(key1, value1)
166+
}
154167
def - (key: K): Map[K, V] =
155168
if (key == key1) Map.empty else this
156169
override def foreach[U](f: ((K, V)) => U): Unit = {
@@ -204,6 +217,21 @@ object Map extends ImmutableMapFactory[Map] {
204217
else if (key == key2) new Map2(key1, value1, key2, value)
205218
else new Map3(key1, value1, key2, value2, key, value)
206219
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
220+
override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): Map[K, V1] = ++[(K, V1), Map[K, V1]](xs)(Map.canBuildFrom[K, V1])
221+
override def ++[B >: (K, V), That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Map[K, V], B, That]): That = {
222+
if (isMapCBF(bf)) that match {
223+
case m: AnyRef if m eq EmptyMap => this.asInstanceOf[That]
224+
case m: Map1[K, V] => m.addTo(this).asInstanceOf[That]
225+
case m: Map2[K, V] => m.addTo(this).asInstanceOf[That]
226+
case m: Map3[K, V] => m.addTo(this).asInstanceOf[That]
227+
case m: Map4[K, V] => m.addTo(this).asInstanceOf[That]
228+
case _ => super.++(that)(bf)
229+
} else super.++(that)(bf)
230+
}
231+
private[Map] def addTo[V1 >: V](m : Map[K,V1]): Map[K, V1] = {
232+
m.updated(key1, value1).
233+
updated(key2, value2)
234+
}
207235
def - (key: K): Map[K, V] =
208236
if (key == key1) new Map1(key2, value2)
209237
else if (key == key2) new Map1(key1, value1)
@@ -280,6 +308,22 @@ object Map extends ImmutableMapFactory[Map] {
280308
else if (key == key3) new Map3(key1, value1, key2, value2, key3, value)
281309
else new Map4(key1, value1, key2, value2, key3, value3, key, value)
282310
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
311+
override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): Map[K, V1] = ++[(K, V1), Map[K, V1]](xs)(Map.canBuildFrom[K, V1])
312+
override def ++[B >: (K, V), That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Map[K, V], B, That]): That = {
313+
if (isMapCBF(bf)) that match {
314+
case m: AnyRef if m eq EmptyMap => this.asInstanceOf[That]
315+
case m: Map1[K, V] => m.addTo(this).asInstanceOf[That]
316+
case m: Map2[K, V] => m.addTo(this).asInstanceOf[That]
317+
case m: Map3[K, V] => m.addTo(this).asInstanceOf[That]
318+
case m: Map4[K, V] => m.addTo(this).asInstanceOf[That]
319+
case _ => super.++(that)(bf)
320+
} else super.++(that)(bf)
321+
}
322+
private[Map] def addTo[V1 >: V](m : Map[K,V1]): Map[K, V1] = {
323+
m.updated(key1, value1).
324+
updated(key2, value2).
325+
updated(key3, value3)
326+
}
283327
def - (key: K): Map[K, V] =
284328
if (key == key1) new Map2(key2, value2, key3, value3)
285329
else if (key == key2) new Map2(key1, value1, key3, value3)
@@ -369,6 +413,23 @@ object Map extends ImmutableMapFactory[Map] {
369413
else if (key == key4) new Map4(key1, value1, key2, value2, key3, value3, key4, value)
370414
else (new HashMap).updated(key1,value1).updated(key2, value2).updated(key3, value3).updated(key4, value4).updated(key, value)
371415
def + [V1 >: V](kv: (K, V1)): Map[K, V1] = updated(kv._1, kv._2)
416+
override def ++[V1 >: V](xs: GenTraversableOnce[(K, V1)]): Map[K, V1] = ++[(K, V1), Map[K, V1]](xs)(Map.canBuildFrom[K, V1])
417+
override def ++[B >: (K, V), That](that: GenTraversableOnce[B])(implicit bf: CanBuildFrom[Map[K, V], B, That]): That = {
418+
if (isMapCBF(bf)) that match {
419+
case m: AnyRef if m eq EmptyMap => this.asInstanceOf[That]
420+
case m: Map1[K, V] => m.addTo(this).asInstanceOf[That]
421+
case m: Map2[K, V] => m.addTo(this).asInstanceOf[That]
422+
case m: Map3[K, V] => m.addTo(this).asInstanceOf[That]
423+
case m: Map4[K, V] => m.addTo(this).asInstanceOf[That]
424+
case _ => super.++(that)(bf)
425+
} else super.++(that)(bf)
426+
}
427+
private[Map] def addTo[V1 >: V](m : Map[K,V1]): Map[K, V1] = {
428+
m.updated(key1, value1).
429+
updated(key2, value2).
430+
updated(key3, value3).
431+
updated(key4, value4)
432+
}
372433
def - (key: K): Map[K, V] =
373434
if (key == key1) new Map3(key2, value2, key3, value3, key4, value4)
374435
else if (key == key2) new Map3(key1, value1, key3, value3, key4, value4)

0 commit comments

Comments
 (0)