@@ -19,7 +19,8 @@ import java.io.IOException
19
19
import generic ._
20
20
import immutable .{NewRedBlackTree => RB }
21
21
import mutable .Builder
22
- import scala .runtime .AbstractFunction2
22
+ import scala .annotation .tailrec
23
+ import scala .runtime .{AbstractFunction1 , AbstractFunction2 }
23
24
import scala .util .hashing .MurmurHash3
24
25
25
26
/** $factoryInfo
@@ -268,18 +269,36 @@ final class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering:
268
269
xs match {
269
270
case tm : TreeMap [A , B ] if ordering == tm.ordering =>
270
271
newMapOrSelf(RB .union(tree, tm.tree0))
272
+ case ls : LinearSeq [(A ,B1 )] =>
273
+ if (ls.isEmpty) this // to avoid the creation of the adder
274
+ else {
275
+ val adder = new Adder [B1 ]
276
+ adder addAll ls
277
+ newMapOrSelf(adder.finalTree)
278
+ }
271
279
case _ =>
272
- // probably should be something like
273
- // val builder = TreeMap.newBuilder[A, B1]
274
- // builder ++= this
275
- // builder ++= xs
276
- // builder.result()
277
- // but for compat and simplicity
278
-
279
- ((repr : TreeMap [A , B1 ]) /: xs.seq) (_ + _)
280
+ val adder = new Adder [B1 ]
281
+ xs foreach adder
282
+ newMapOrSelf(adder.finalTree)
283
+ }
284
+ }
285
+ private final class Adder [B1 >: B ]
286
+ extends RB .MapHelper [A , B1 ] with Function1 [(A , B1 ), Unit ] {
287
+ private var currentMutableTree : RB .Tree [A ,B1 ] = tree0
288
+ def finalTree = beforePublish(currentMutableTree)
289
+ override def apply (kv : (A , B1 )): Unit = {
290
+ currentMutableTree= mutableUpd(currentMutableTree, kv._1, kv._2)
291
+ }
292
+ @ tailrec def addAll (ls : LinearSeq [(A , B1 )]): Unit = {
293
+ if (! ls.isEmpty) {
294
+ val kv = ls.head
295
+ currentMutableTree = mutableUpd(currentMutableTree, kv._1, kv._2)
296
+ addAll(ls.tail)
297
+ }
280
298
}
281
299
}
282
300
301
+
283
302
/** A new TreeMap with the entry added is returned,
284
303
* assuming that key is <em>not</em> in the TreeMap.
285
304
*
@@ -296,11 +315,23 @@ final class TreeMap[A, +B] private (tree: RB.Tree[A, B])(implicit val ordering:
296
315
def - (key: A ): TreeMap [A , B ] =
297
316
newMapOrSelf(RB .delete(tree, key))
298
317
299
- private [collection] def removeAllImpl (ts : TreeSet [A ]): TreeMap [A , B ] = {
300
- assert(ordering == ts.ordering)
301
- newMapOrSelf(RB .difference(tree, ts.tree))
318
+ private [collection] def removeAllImpl (xs : GenTraversableOnce [A ]): TreeMap [A , B ] = xs match {
319
+ case ts : TreeSet [A ] if ordering == ts.ordering =>
320
+ newMapOrSelf(RB .difference(tree, ts.tree))
321
+ case _ =>
322
+ // TODO add an implementation of a mutable subtractor similar to ++
323
+ // but at least this doesnt create a TreeMap for each iteration
324
+ object sub extends AbstractFunction1 [A , Unit ] {
325
+ var currentTree = tree0
326
+ override def apply (k : A ): Unit = {
327
+ currentTree= RB .delete(currentTree, k)
328
+ }
329
+ }
330
+ xs.foreach(sub)
331
+ newMapOrSelf(sub.currentTree)
302
332
}
303
333
334
+
304
335
/** Check if this map maps `key` to a value and return the
305
336
* value if it exists.
306
337
*
0 commit comments