diff options
4 files changed, 37 insertions, 29 deletions
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala index 55ce8fa822..9cde20f1df 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -111,7 +111,7 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { // TODO: add HashMap2, HashMap3, ... - class HashMap1[A,+B](private[HashMap] var key: A, private[HashMap] var hash: Int, private[collection] var value: (B @uV), private[collection] var kv: (A,B @uV)) extends HashMap[A,B] { + class HashMap1[A,+B](private[collection] val key: A, private[collection] val hash: Int, private[collection] val value: (B @uV), private[collection] var kv: (A,B @uV)) extends HashMap[A,B] { override def size = 1 private[collection] def getKey = key @@ -176,13 +176,14 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { override def iterator: Iterator[(A,B)] = Iterator(ensurePair) override def foreach[U](f: ((A, B)) => U): Unit = f(ensurePair) + // this method may be called multiple times in a multithreaded environment, but that's ok private[HashMap] def ensurePair: (A,B) = if (kv ne null) kv else { kv = (key, value); kv } protected override def merge0[B1 >: B](that: HashMap[A, B1], level: Int, merger: Merger[B1]): HashMap[A, B1] = { that.updated0(key, hash, level, value, kv, merger) } } - private[collection] class HashMapCollision1[A, +B](private[HashMap] var hash: Int, var kvs: ListMap[A, B @uV]) + private[collection] class HashMapCollision1[A, +B](private[collection] val hash: Int, val kvs: ListMap[A, B @uV]) extends HashMap[A, B @uV] { override def size = kvs.size @@ -227,9 +228,9 @@ object HashMap extends ImmutableMapFactory[HashMap] with BitOperations.Int { } class HashTrieMap[A, +B]( - private[HashMap] var bitmap: Int, - private[collection] var elems: Array[HashMap[A, B @uV]], - private[HashMap] var size0: Int + private[collection] val bitmap: Int, + private[collection] val elems: Array[HashMap[A, B @uV]], + private[collection] val size0: Int ) extends HashMap[A, B @uV] { /* diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala index 8cb19d4f31..79d2fb71cc 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -105,7 +105,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { // TODO: add HashSet2, HashSet3, ... - class HashSet1[A](private[HashSet] var key: A, private[HashSet] var hash: Int) extends HashSet[A] { + class HashSet1[A](private[HashSet] val key: A, private[HashSet] val hash: Int) extends HashSet[A] { override def size = 1 override def get0(key: A, hash: Int, level: Int): Boolean = @@ -131,7 +131,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { override def foreach[U](f: A => U): Unit = f(key) } - private[immutable] class HashSetCollision1[A](private[HashSet] var hash: Int, var ks: ListSet[A]) + private[immutable] class HashSetCollision1[A](private[HashSet] val hash: Int, val ks: ListSet[A]) extends HashSet[A] { override def size = ks.size @@ -178,7 +178,7 @@ object HashSet extends ImmutableSetFactory[HashSet] { } - class HashTrieSet[A](private var bitmap: Int, private[collection] var elems: Array[HashSet[A]], private var size0: Int) + class HashTrieSet[A](private val bitmap: Int, private[collection] val elems: Array[HashSet[A]], private val size0: Int) extends HashSet[A] { override def size = size0 diff --git a/src/library/scala/collection/parallel/immutable/ParHashMap.scala b/src/library/scala/collection/parallel/immutable/ParHashMap.scala index 1fec522a93..e785932933 100644 --- a/src/library/scala/collection/parallel/immutable/ParHashMap.scala +++ b/src/library/scala/collection/parallel/immutable/ParHashMap.scala @@ -304,14 +304,21 @@ extends collection.parallel.BucketCombiner[(K, V), ParHashMap[K, V], (K, V), Has evaluateCombiners(trie) trie.asInstanceOf[HashMap[K, Repr]] } - private def evaluateCombiners(trie: HashMap[K, Combiner[V, Repr]]): Unit = trie match { + private def evaluateCombiners(trie: HashMap[K, Combiner[V, Repr]]): HashMap[K, Repr] = trie match { case hm1: HashMap.HashMap1[_, _] => - hm1.asInstanceOf[HashMap.HashMap1[K, Repr]].value = hm1.value.result - hm1.kv = null + val evaledvalue = hm1.value.result + new HashMap.HashMap1[K, Repr](hm1.key, hm1.hash, evaledvalue, null) case hmc: HashMap.HashMapCollision1[_, _] => - hmc.asInstanceOf[HashMap.HashMapCollision1[K, Repr]].kvs = hmc.kvs map { p => (p._1, p._2.result) } - case htm: HashMap.HashTrieMap[_, _] => - for (hm <- htm.elems) evaluateCombiners(hm) + val evaledkvs = hmc.kvs map { p => (p._1, p._2.result) } + new HashMap.HashMapCollision1[K, Repr](hmc.hash, evaledkvs) + case htm: HashMap.HashTrieMap[k, v] => + var i = 0 + while (i < htm.elems.length) { + htm.elems(i) = evaluateCombiners(htm.elems(i)).asInstanceOf[HashMap[k, v]] + i += 1 + } + htm.asInstanceOf[HashMap[K, Repr]] + case empty => empty.asInstanceOf[HashMap[K, Repr]] } def split = { val fp = howmany / 2 diff --git a/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala b/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala index fbacb9f45c..8273e302a2 100644 --- a/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala +++ b/test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala @@ -414,21 +414,21 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col }).reduceLeft(_ && _) } - // property("groupBy must be equal") = forAll(collectionPairs) { - // case (t, coll) => - // (for ((f, ind) <- groupByFunctions.zipWithIndex) yield { - // val tgroup = t.groupBy(f) - // val cgroup = coll.groupBy(f) - // if (tgroup != cgroup || cgroup != tgroup) { - // println("from: " + t) - // println("and: " + coll) - // println("groups are: ") - // println(tgroup) - // println(cgroup) - // } - // ("operator " + ind) |: tgroup == cgroup && cgroup == tgroup - // }).reduceLeft(_ && _) - // } + property("groupBy must be equal") = forAll(collectionPairs) { + case (t, coll) => + (for ((f, ind) <- groupByFunctions.zipWithIndex) yield { + val tgroup = t.groupBy(f) + val cgroup = coll.groupBy(f) + if (tgroup != cgroup || cgroup != tgroup) { + println("from: " + t) + println("and: " + coll) + println("groups are: ") + println(tgroup) + println(cgroup) + } + ("operator " + ind) |: tgroup == cgroup && cgroup == tgroup + }).reduceLeft(_ && _) + } } |