summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-03-18 19:07:38 +0000
committerAleksandar Pokopec <aleksandar.prokopec@epfl.ch>2011-03-18 19:07:38 +0000
commit86e8f5ae1dccc9f628b6a3f1bdab7e4e81ae9cbb (patch)
tree2e8a5cc7b5ef666c31a2c99dca990f269b850eb5
parent0554c378653c47aefaabe48b0ef568f952d1695b (diff)
downloadscala-86e8f5ae1dccc9f628b6a3f1bdab7e4e81ae9cbb.tar.gz
scala-86e8f5ae1dccc9f628b6a3f1bdab7e4e81ae9cbb.tar.bz2
scala-86e8f5ae1dccc9f628b6a3f1bdab7e4e81ae9cbb.zip
Removing toPar* methods, since we've agreed the...
Removing toPar* methods, since we've agreed they're difficult to: - underestand - maintain Also, changed the docs and some tests appropriately. Description: 1) Every collection is now parallelizable - switch to the parallel version of the collection is done via `par`. - Traversable collections and iterators have `par` return a parallel - collection of type `ParIterable[A]` with the implementation being the - representative of `ParIterable`s (currently, `ParArray`). Iterable - collections do the same thing. Sequences refine `par`'s returns type - to `ParSeq[A]`. Maps and sets do a similar thing. The above means that the contract for `par` changed - it is no longer guaranteed to be O(1), nor reflect the same underlying data, as was the case for mutable collections before. Method `par` is now at worst linear. Furthermore, specific collection implementations override `par` to a more efficient alternative - instead of copying the dataset, the dataset is shared between the old and the new version. Implementation complexity may be sublinear or constant in these cases, and the underlying data structure may be shared. Currently, these data structures include parallel arrays, maps and sets, vectors, hash trie maps and sets, and ranges. Finally, parallel collections implement `par` trivially. 2) Methods `toMap`, `toSet`, `toSeq` and `toIterable` have been refined for parallel collections to switch between collection types, however, they never switch an implementation from parallel to sequential. They may or may not copy the elements, as is the case with sequential variants of these methods. 3) The preferred way to switch between different collection types, whether maps, sets and seqs, or parallel and sequential, is now via use of methods `toIterable`, `toSeq`, `toSet` and `toMap` in combination with `par` and `seq`. Review by odersky.
-rw-r--r--src/library/scala/collection/Iterator.scala5
-rw-r--r--src/library/scala/collection/MapLike.scala6
-rw-r--r--src/library/scala/collection/Parallelizable.scala49
-rw-r--r--src/library/scala/collection/SeqLike.scala5
-rw-r--r--src/library/scala/collection/SetLike.scala6
-rw-r--r--src/library/scala/collection/TraversableLike.scala6
-rw-r--r--src/library/scala/collection/TraversableOnce.scala60
-rw-r--r--src/library/scala/collection/immutable/HashMap.scala8
-rw-r--r--src/library/scala/collection/immutable/HashSet.scala9
-rw-r--r--src/library/scala/collection/immutable/Iterable.scala5
-rw-r--r--src/library/scala/collection/immutable/MapLike.scala4
-rw-r--r--src/library/scala/collection/immutable/Range.scala10
-rw-r--r--src/library/scala/collection/immutable/Seq.scala5
-rw-r--r--src/library/scala/collection/immutable/Set.scala5
-rw-r--r--src/library/scala/collection/immutable/Vector.scala4
-rw-r--r--src/library/scala/collection/interfaces/TraversableOnceMethods.scala4
-rw-r--r--src/library/scala/collection/mutable/ArrayBuffer.scala8
-rw-r--r--src/library/scala/collection/mutable/ArrayOps.scala4
-rw-r--r--src/library/scala/collection/mutable/ArraySeq.scala8
-rw-r--r--src/library/scala/collection/mutable/HashMap.scala9
-rw-r--r--src/library/scala/collection/mutable/HashSet.scala8
-rw-r--r--src/library/scala/collection/mutable/Iterable.scala5
-rw-r--r--src/library/scala/collection/mutable/MapLike.scala4
-rw-r--r--src/library/scala/collection/mutable/SeqLike.scala6
-rw-r--r--src/library/scala/collection/mutable/SetLike.scala4
-rw-r--r--src/library/scala/collection/mutable/WrappedArray.scala8
-rw-r--r--src/library/scala/collection/parallel/ParIterableLike.scala43
-rw-r--r--src/library/scala/collection/parallel/ParMapLike.scala4
-rw-r--r--src/library/scala/collection/parallel/ParSeqLike.scala4
-rw-r--r--src/library/scala/collection/parallel/ParSetLike.scala3
-rw-r--r--src/library/scala/collection/parallel/immutable/ParIterable.scala10
-rw-r--r--src/library/scala/collection/parallel/immutable/ParMap.scala2
-rw-r--r--src/library/scala/collection/parallel/immutable/ParNumericRange.scala.disabled4
-rw-r--r--src/library/scala/collection/parallel/immutable/ParRange.scala4
-rw-r--r--src/library/scala/collection/parallel/immutable/ParSet.scala4
-rw-r--r--src/library/scala/collection/parallel/mutable/ParIterable.scala5
-rw-r--r--src/library/scala/collection/parallel/mutable/ParMapLike.scala6
-rw-r--r--src/library/scala/collection/parallel/mutable/ParSeq.scala2
-rw-r--r--src/library/scala/collection/parallel/mutable/ParSetLike.scala1
-rw-r--r--test/files/run/coder/Coder.scala2
-rw-r--r--test/files/run/coder2/Coder2.scala58
-rw-r--r--test/files/run/pc-conversions.scala47
42 files changed, 234 insertions, 220 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala
index 4e349cb423..d8a3514954 100644
--- a/src/library/scala/collection/Iterator.scala
+++ b/src/library/scala/collection/Iterator.scala
@@ -12,6 +12,7 @@ package scala.collection
import mutable.ArrayBuffer
import annotation.{ tailrec, migration }
+import parallel.ParIterable
/** The `Iterator` object provides various functions for
* creating specialized iterators.
@@ -250,7 +251,7 @@ import Iterator.empty
* @define mayNotTerminateInf
* Note: may not terminate for infinite iterators.
*/
-trait Iterator[+A] extends TraversableOnce[A] {
+trait Iterator[+A] extends TraversableOnce[A] with Parallelizable[A, ParIterable[A]] {
self =>
/** Tests whether this iterator can provide another element.
@@ -275,6 +276,8 @@ trait Iterator[+A] extends TraversableOnce[A] {
*/
def isTraversableAgain = false
+ protected[this] def parCombiner = ParIterable.newCombiner[A]
+
/** Tests whether this Iterator has a known size.
*
* @return `true` for empty Iterators, `false` otherwise.
diff --git a/src/library/scala/collection/MapLike.scala b/src/library/scala/collection/MapLike.scala
index 6fb971d128..fd58540086 100644
--- a/src/library/scala/collection/MapLike.scala
+++ b/src/library/scala/collection/MapLike.scala
@@ -12,6 +12,7 @@ package scala.collection
import generic._
import mutable.{ Builder, MapBuilder }
import annotation.migration
+import parallel.ParMap
/** A template trait for maps, which associate keys with values.
*
@@ -56,7 +57,8 @@ import annotation.migration
trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]]
extends PartialFunction[A, B]
with IterableLike[(A, B), This]
- with Subtractable[A, This] {
+ with Subtractable[A, This]
+ with Parallelizable[(A, B), ParMap[A, B]] {
self =>
/** The empty map of the same type as this map
@@ -311,6 +313,8 @@ self =>
result
}
+ protected[this] override def parCombiner = ParMap.newCombiner[A, B]
+
/** Appends all bindings of this map to a string builder using start, end, and separator strings.
* The written text begins with the string `start` and ends with the string
* `end`. Inside, the string representations of all bindings of this map
diff --git a/src/library/scala/collection/Parallelizable.scala b/src/library/scala/collection/Parallelizable.scala
index 999849fbab..207bb25cb6 100644
--- a/src/library/scala/collection/Parallelizable.scala
+++ b/src/library/scala/collection/Parallelizable.scala
@@ -1,8 +1,18 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+
package scala.collection
import parallel.ParIterableLike
+import parallel.Combiner
@@ -10,19 +20,50 @@ import parallel.ParIterableLike
* by invoking the method `par`. Parallelizable collections may be parametrized with
* a target type different than their own.
*
+ * @tparam A the type of the elements in the collection
* @tparam ParRepr the actual type of the collection, which has to be parallel
*/
-trait Parallelizable[+ParRepr <: Parallel] {
-
- /** Returns a parallel implementation of a collection.
+trait Parallelizable[+A, +ParRepr <: Parallel] {
+self: TraversableOnce[A] =>
+
+ /** Returns a parallel implementation of this collection.
+ *
+ * For most collection types, this method creates a new parallel collection by copying
+ * all the elements. For these collection, `par` takes linear time. Mutable collections
+ * in this category do not produce a mutable parallel collection that has the same
+ * underlying dataset, so changes in one collection will not be reflected in the other one.
+ *
+ * Specific collections (e.g. `ParArray` or `mutable.ParHashMap`) override this default
+ * behaviour by creating a parallel collection which shares the same underlying dataset.
+ * For these collections, `par` takes constant or sublinear time.
+ *
+ * All parallel collections return a reference to themselves.
+ *
+ * @return a parallel implementation of this collection
*/
- def par: ParRepr
+ def par: ParRepr = {
+ val cb = parCombiner
+ for (x <- this) cb += x
+ cb.result
+ }
+
+ /** The default `par` implementation uses the combiner provided by this method
+ * to create a new parallel collection.
+ *
+ * @return a combiner for the parallel collection of type `ParRepr`
+ */
+ protected[this] def parCombiner: Combiner[A, ParRepr]
}
+trait CustomParallelizable[+A, +ParRepr <: Parallel] extends Parallelizable[A, ParRepr] {
+self: TraversableOnce[A] =>
+ override def par: ParRepr
+ protected override def parCombiner = throw new UnsupportedOperationException("")
+}
diff --git a/src/library/scala/collection/SeqLike.scala b/src/library/scala/collection/SeqLike.scala
index 12e4c45c75..4936e652b2 100644
--- a/src/library/scala/collection/SeqLike.scala
+++ b/src/library/scala/collection/SeqLike.scala
@@ -13,6 +13,7 @@ package scala.collection
import mutable.{ListBuffer, HashMap, ArraySeq}
import immutable.{List, Range}
import generic._
+import parallel.ParSeq
/** The companion object for trait `SeqLike`.
*/
@@ -168,7 +169,7 @@ object SeqLike {
*
* Note: will not terminate for infinite-sized collections.
*/
-trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self =>
+trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] with Parallelizable[A, ParSeq[A]] { self =>
override protected[this] def thisCollection: Seq[A] = this.asInstanceOf[Seq[A]]
override protected[this] def toCollection(repr: Repr): Seq[A] = repr.asInstanceOf[Seq[A]]
@@ -191,6 +192,8 @@ trait SeqLike[+A, +Repr] extends IterableLike[A, Repr] { self =>
*/
def apply(idx: Int): A
+ protected[this] override def parCombiner = ParSeq.newCombiner[A]
+
/** Compares the length of this $coll to a test value.
*
* @param len the test value that gets compared with the length.
diff --git a/src/library/scala/collection/SetLike.scala b/src/library/scala/collection/SetLike.scala
index 73f0b9c839..7cbb8ee2ef 100644
--- a/src/library/scala/collection/SetLike.scala
+++ b/src/library/scala/collection/SetLike.scala
@@ -12,6 +12,7 @@ package scala.collection
import generic._
import mutable.{ Builder, SetBuilder }
import scala.annotation.migration
+import parallel.ParSet
/** A template trait for sets.
*
@@ -57,7 +58,8 @@ import scala.annotation.migration
*/
trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
extends IterableLike[A, This]
- with Subtractable[A, This] {
+ with Subtractable[A, This]
+ with Parallelizable[A, ParSet[A]] {
self =>
/** The empty set of the same type as this set
@@ -72,6 +74,8 @@ self =>
*/
override protected[this] def newBuilder: Builder[A, This] = new SetBuilder[A, This](empty)
+ protected[this] override def parCombiner = ParSet.newCombiner[A]
+
/** Overridden for efficiency. */
override def toSeq: Seq[A] = toBuffer[A]
override def toBuffer[A1 >: A]: mutable.Buffer[A1] = {
diff --git a/src/library/scala/collection/TraversableLike.scala b/src/library/scala/collection/TraversableLike.scala
index 9cf73142e6..70d5c37837 100644
--- a/src/library/scala/collection/TraversableLike.scala
+++ b/src/library/scala/collection/TraversableLike.scala
@@ -15,6 +15,7 @@ import mutable.{ Builder, ListBuffer }
import annotation.tailrec
import annotation.migration
import annotation.unchecked.{ uncheckedVariance => uV }
+import parallel.ParIterable
/** A template trait for traversable collections of type `Traversable[A]`.
@@ -90,7 +91,8 @@ import annotation.unchecked.{ uncheckedVariance => uV }
*/
trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
with FilterMonadic[A, Repr]
- with TraversableOnce[A] {
+ with TraversableOnce[A]
+ with Parallelizable[A, ParIterable[A]] {
self =>
import Traversable.breaks._
@@ -119,6 +121,8 @@ trait TraversableLike[+A, +Repr] extends HasNewBuilder[A, Repr]
*/
protected[this] def newBuilder: Builder[A, Repr]
+ protected[this] def parCombiner = ParIterable.newCombiner[A]
+
/** Applies a function `f` to all elements of this $coll.
*
* Note: this method underlies the implementation of most other bulk operations.
diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala
index 5b8abb3e5e..de3b4770f3 100644
--- a/src/library/scala/collection/TraversableOnce.scala
+++ b/src/library/scala/collection/TraversableOnce.scala
@@ -501,66 +501,6 @@ trait TraversableOnce[+A] {
b.result
}
- /* The following 4 methods are implemented in a generic way here,
- * but are specialized further down the hierarchy where possible.
- * In particular:
- *
- * - all concrete sequential collection classes that can be
- * parallelized have their corresponding `toPar*` methods
- * overridden (e.g. ArrayBuffer overrides `toParIterable`
- * and `toParSeq`)
- * - ParIterableLike overrides all 4 methods
- * - ParSeqLike again overrides `toParSeq`
- * - ParSetLike again overrides `toParSet`
- * - ParMapLike again overrides `toParMap`
- * - immutable.ParIterable overrides all 4 methods to have immutable return types
- * - immutable.ParSet overrides `toParSet` to `this`
- * - immutable.ParSeq overrides nothing yet TODO vector
- * - immutable.ParMap overrides `toParMap` to `this`
- */
-
- /** Converts this $coll to a parallel iterable.
- * $willNotTerminateInf
- * @return a parallel iterable containing all elements of this $coll.
- */
- def toParIterable: parallel.ParIterable[A] = toParSeq
-
- /** Converts this $coll to a parallel sequence.
- * $willNotTerminateInf
- * @return a parallel sequence containing all elements of this $coll.
- */
- def toParSeq: parallel.ParSeq[A] = {
- val cb = parallel.mutable.ParArray.newCombiner[A]
- for (elem <- this) cb += elem
- cb.result
- }
-
- /** Converts this $coll to a parallel set.
- * $willNotTerminateInf
- * @return a parallel set containing all elements of this $coll.
- */
- def toParSet[B >: A]: parallel.ParSet[B] = {
- val cb = parallel.mutable.ParHashSet.newCombiner[B]
- for (elem <- this) cb += elem
- cb.result
- }
-
- /** Converts this $coll to a parallel map.
- * $willNotTerminateInf
- *
- * This operation is only available on collections containing pairs of elements.
- *
- * @return a parallel map containing all elements of this $coll.
- * @usecase def toParMap[T, U]: ParMap[T, U]
- * @return a parallel map of type `parallel.ParMap[T, U]`
- * containing all key/value pairs of type `(T, U)` of this $coll.
- */
- def toParMap[T, U](implicit ev: A <:< (T, U)): parallel.ParMap[T, U] = {
- val cb = parallel.mutable.ParHashMap.newCombiner[T, U]
- for (elem <- this) cb += elem
- cb.result
- }
-
/** Displays all elements of this $coll in a string using start, end, and
* separator strings.
*
diff --git a/src/library/scala/collection/immutable/HashMap.scala b/src/library/scala/collection/immutable/HashMap.scala
index d44791c2eb..cf7b0d423a 100644
--- a/src/library/scala/collection/immutable/HashMap.scala
+++ b/src/library/scala/collection/immutable/HashMap.scala
@@ -33,7 +33,7 @@ import parallel.immutable.ParHashMap
* @define willNotTerminateInf
*/
@SerialVersionUID(2L)
-class HashMap[A, +B] extends Map[A,B] with MapLike[A, B, HashMap[A, B]] with Parallelizable[ParHashMap[A, B]] with Serializable {
+class HashMap[A, +B] extends Map[A,B] with MapLike[A, B, HashMap[A, B]] with CustomParallelizable[(A, B), ParHashMap[A, B]] with Serializable {
override def size: Int = 0
@@ -87,12 +87,8 @@ class HashMap[A, +B] extends Map[A,B] with MapLike[A, B, HashMap[A, B]] with Par
protected def merge0[B1 >: B](that: HashMap[A, B1], level: Int, merger: Merger[B1]): HashMap[A, B1] = that
- def par = ParHashMap.fromTrie(this)
+ override def par = ParHashMap.fromTrie(this)
- override def toParIterable = par
-
- private type C = (A, B)
- override def toParMap[D, E](implicit ev: C <:< (D, E)) = par.asInstanceOf[ParHashMap[D, E]]
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/HashSet.scala b/src/library/scala/collection/immutable/HashSet.scala
index 7d31f20e14..951f6d235e 100644
--- a/src/library/scala/collection/immutable/HashSet.scala
+++ b/src/library/scala/collection/immutable/HashSet.scala
@@ -32,13 +32,15 @@ import collection.parallel.immutable.ParHashSet
class HashSet[A] extends Set[A]
with GenericSetTemplate[A, HashSet]
with SetLike[A, HashSet[A]]
- with Parallelizable[ParHashSet[A]]
+ with CustomParallelizable[A, ParHashSet[A]]
with Serializable
{
override def companion: GenericCompanion[HashSet] = HashSet
//class HashSet[A] extends Set[A] with SetLike[A, HashSet[A]] {
+ override def par = ParHashSet.fromTrie(this)
+
override def size: Int = 0
override def empty = HashSet.empty[A]
@@ -58,8 +60,6 @@ class HashSet[A] extends Set[A]
def - (e: A): HashSet[A] =
removed0(e, computeHash(e), 0)
- def par = ParHashSet.fromTrie(this)
-
protected def elemHashCode(key: A) = key.##
protected final def improve(hcode: Int) = {
@@ -79,8 +79,7 @@ class HashSet[A] extends Set[A]
protected def removed0(key: A, hash: Int, level: Int): HashSet[A] = this
protected def writeReplace(): AnyRef = new HashSet.SerializationProxy(this)
- override def toParIterable = par
- override def toParSet[B >: A] = par.asInstanceOf[ParHashSet[B]]
+
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/Iterable.scala b/src/library/scala/collection/immutable/Iterable.scala
index 51227556ad..7f5cb055f4 100644
--- a/src/library/scala/collection/immutable/Iterable.scala
+++ b/src/library/scala/collection/immutable/Iterable.scala
@@ -13,6 +13,7 @@ package immutable
import generic._
import mutable.Builder
+import parallel.immutable.ParIterable
/** A base trait for iterable collections that are guaranteed immutable.
* $iterableInfo
@@ -23,8 +24,10 @@ import mutable.Builder
trait Iterable[+A] extends Traversable[A]
with scala.collection.Iterable[A]
with GenericTraversableTemplate[A, Iterable]
- with IterableLike[A, Iterable[A]] {
+ with IterableLike[A, Iterable[A]]
+ with Parallelizable[A, ParIterable[A]] {
override def companion: GenericCompanion[Iterable] = Iterable
+ protected[this] override def parCombiner = ParIterable.newCombiner[A] // if `immutable.IterableLike` gets introduced, please move this there!
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/MapLike.scala b/src/library/scala/collection/immutable/MapLike.scala
index a0f1632d1e..13054b9f83 100644
--- a/src/library/scala/collection/immutable/MapLike.scala
+++ b/src/library/scala/collection/immutable/MapLike.scala
@@ -10,6 +10,7 @@ package scala.collection
package immutable
import generic._
+import parallel.immutable.ParMap
/**
* A generic template for immutable maps from keys of type `A`
@@ -46,8 +47,11 @@ import generic._
*/
trait MapLike[A, +B, +This <: MapLike[A, B, This] with Map[A, B]]
extends scala.collection.MapLike[A, B, This]
+ with Parallelizable[(A, B), ParMap[A, B]]
{ self =>
+ protected[this] override def parCombiner = ParMap.newCombiner[A, B]
+
/** A new immutable map containing updating this map with a given key/value mapping.
* @param key the key
* @param value the value
diff --git a/src/library/scala/collection/immutable/Range.scala b/src/library/scala/collection/immutable/Range.scala
index f8b3dfa54f..90a1383353 100644
--- a/src/library/scala/collection/immutable/Range.scala
+++ b/src/library/scala/collection/immutable/Range.scala
@@ -41,10 +41,10 @@ import scala.collection.parallel.immutable.ParRange
@SerialVersionUID(7618862778670199309L)
class Range(val start: Int, val end: Int, val step: Int)
extends IndexedSeq[Int]
- with collection.Parallelizable[ParRange]
+ with collection.CustomParallelizable[Int, ParRange]
with Serializable
{
- def par = new ParRange(this)
+ override def par = new ParRange(this)
// Note that this value is calculated eagerly intentionally: it also
// serves to enforce conditions (step != 0) && (length <= Int.MaxValue)
@@ -205,11 +205,9 @@ extends IndexedSeq[Int]
final def contains(x: Int) = isWithinBoundaries(x) && ((x - start) % step == 0)
- override def toParIterable = par
+ override def toIterable = this
- override def toParSeq = par
-
- override def toParSet[U >: Int] = par.toParSet[U]
+ override def toSeq = this
override def equals(other: Any) = other match {
case x: Range =>
diff --git a/src/library/scala/collection/immutable/Seq.scala b/src/library/scala/collection/immutable/Seq.scala
index c3c34d3f89..4f061983de 100644
--- a/src/library/scala/collection/immutable/Seq.scala
+++ b/src/library/scala/collection/immutable/Seq.scala
@@ -13,6 +13,7 @@ package immutable
import generic._
import mutable.Builder
+import parallel.immutable.ParSeq
/** A subtrait of `collection.Seq` which represents sequences
* that are guaranteed immutable.
@@ -24,9 +25,11 @@ import mutable.Builder
trait Seq[+A] extends Iterable[A]
with scala.collection.Seq[A]
with GenericTraversableTemplate[A, Seq]
- with SeqLike[A, Seq[A]] {
+ with SeqLike[A, Seq[A]]
+ with Parallelizable[A, ParSeq[A]] {
override def companion: GenericCompanion[Seq] = Seq
override def toSeq: Seq[A] = this
+ protected[this] override def parCombiner = ParSeq.newCombiner[A] // if `immutable.SeqLike` gets introduced, please move this there!
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/Set.scala b/src/library/scala/collection/immutable/Set.scala
index e2bad2f052..1b61c6f565 100644
--- a/src/library/scala/collection/immutable/Set.scala
+++ b/src/library/scala/collection/immutable/Set.scala
@@ -12,6 +12,7 @@ package scala.collection
package immutable
import generic._
+import parallel.immutable.ParSet
/** A generic trait for immutable sets.
*
@@ -27,9 +28,11 @@ import generic._
trait Set[A] extends Iterable[A]
with scala.collection.Set[A]
with GenericSetTemplate[A, Set]
- with SetLike[A, Set[A]] {
+ with SetLike[A, Set[A]]
+ with Parallelizable[A, ParSet[A]] {
override def companion: GenericCompanion[Set] = Set
override def toSet[B >: A]: Set[B] = this.asInstanceOf[Set[B]]
+ protected override def parCombiner = ParSet.newCombiner[A] // if `immutable.SetLike` gets introduced, please move this there!
}
/** $factoryInfo
diff --git a/src/library/scala/collection/immutable/Vector.scala b/src/library/scala/collection/immutable/Vector.scala
index 92a6160213..3078a26411 100644
--- a/src/library/scala/collection/immutable/Vector.scala
+++ b/src/library/scala/collection/immutable/Vector.scala
@@ -39,7 +39,7 @@ extends IndexedSeq[A]
with IndexedSeqLike[A, Vector[A]]
with VectorPointer[A @uncheckedVariance]
with Serializable
- with Parallelizable[ParVector[A]]
+ with CustomParallelizable[A, ParVector[A]]
{ self =>
override def companion: GenericCompanion[Vector] = Vector
@@ -53,7 +53,7 @@ override def companion: GenericCompanion[Vector] = Vector
def length = endIndex - startIndex
- def par = new ParVector(this)
+ override def par = new ParVector(this)
override def lengthCompare(len: Int): Int = length - len
diff --git a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
index 8967e15a34..5e1325fef6 100644
--- a/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
+++ b/src/library/scala/collection/interfaces/TraversableOnceMethods.scala
@@ -53,10 +53,6 @@ trait TraversableOnceMethods[+A] {
def toIterator: Iterator[A]
def toList: List[A]
def toMap[T, U](implicit ev: A <:< (T, U)): immutable.Map[T, U]
- def toParIterable: parallel.ParIterable[A]
- def toParMap[T, U](implicit ev: A <:< (T, U)): parallel.ParMap[T, U]
- def toParSeq: parallel.ParSeq[A]
- def toParSet[B >: A]: parallel.ParSet[B]
def toSeq: Seq[A]
def toSet[B >: A]: immutable.Set[B]
def toStream: Stream[A]
diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala
index 9d07294f51..daa3c48578 100644
--- a/src/library/scala/collection/mutable/ArrayBuffer.scala
+++ b/src/library/scala/collection/mutable/ArrayBuffer.scala
@@ -48,7 +48,7 @@ class ArrayBuffer[A](override protected val initialSize: Int)
with IndexedSeqOptimized[A, ArrayBuffer[A]]
with Builder[A, ArrayBuffer[A]]
with ResizableArray[A]
- with Parallelizable[ParArray[A]]
+ with CustomParallelizable[A, ParArray[A]]
with Serializable {
override def companion: GenericCompanion[ArrayBuffer] = ArrayBuffer
@@ -67,7 +67,7 @@ class ArrayBuffer[A](override protected val initialSize: Int)
}
}
- def par = ParArray.handoff[A](array.asInstanceOf[Array[A]], size)
+ override def par = ParArray.handoff[A](array.asInstanceOf[Array[A]], size)
/** Appends a single element to this buffer and returns
* the identity of the buffer. It takes constant amortized time.
@@ -177,10 +177,6 @@ class ArrayBuffer[A](override protected val initialSize: Int)
*/
override def stringPrefix: String = "ArrayBuffer"
- override def toParIterable = par
-
- override def toParSeq = par
-
}
/** Factory object for the `ArrayBuffer` class.
diff --git a/src/library/scala/collection/mutable/ArrayOps.scala b/src/library/scala/collection/mutable/ArrayOps.scala
index 3cf1795e80..b72206e6f3 100644
--- a/src/library/scala/collection/mutable/ArrayOps.scala
+++ b/src/library/scala/collection/mutable/ArrayOps.scala
@@ -35,7 +35,7 @@ import parallel.mutable.ParArray
* @define mayNotTerminateInf
* @define willNotTerminateInf
*/
-abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with Parallelizable[ParArray[T]] {
+abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with CustomParallelizable[T, ParArray[T]] {
private def rowBuilder[U]: Builder[U, Array[U]] =
Array.newBuilder(
@@ -55,7 +55,7 @@ abstract class ArrayOps[T] extends ArrayLike[T, Array[T]] with Parallelizable[Pa
else
super.toArray[U]
- def par = ParArray.handoff(repr)
+ override def par = ParArray.handoff(repr)
/** Flattens a two-dimensional array by concatenating all its rows
* into a single array.
diff --git a/src/library/scala/collection/mutable/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala
index cd53a24680..0b3f0ebc5b 100644
--- a/src/library/scala/collection/mutable/ArraySeq.scala
+++ b/src/library/scala/collection/mutable/ArraySeq.scala
@@ -44,7 +44,7 @@ class ArraySeq[A](override val length: Int)
extends IndexedSeq[A]
with GenericTraversableTemplate[A, ArraySeq]
with IndexedSeqOptimized[A, ArraySeq[A]]
- with Parallelizable[ParArray[A]]
+ with CustomParallelizable[A, ParArray[A]]
with Serializable
{
@@ -52,7 +52,7 @@ extends IndexedSeq[A]
val array: Array[AnyRef] = new Array[AnyRef](length)
- def par = ParArray.handoff(array.asInstanceOf[Array[A]])
+ override def par = ParArray.handoff(array.asInstanceOf[Array[A]])
def apply(idx: Int): A = {
if (idx >= length) throw new IndexOutOfBoundsException(idx.toString)
@@ -86,10 +86,6 @@ extends IndexedSeq[A]
Array.copy(array, 0, xs, start, len1)
}
- override def toParIterable = par
-
- override def toParSeq = par
-
}
/** $factoryInfo
diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala
index 890a6cbf24..e78e9a1296 100644
--- a/src/library/scala/collection/mutable/HashMap.scala
+++ b/src/library/scala/collection/mutable/HashMap.scala
@@ -44,7 +44,7 @@ class HashMap[A, B] private[collection] (contents: HashTable.Contents[A, Default
extends Map[A, B]
with MapLike[A, B, HashMap[A, B]]
with HashTable[A, DefaultEntry[A, B]]
- with Parallelizable[ParHashMap[A, B]]
+ with CustomParallelizable[(A, B), ParHashMap[A, B]]
with Serializable
{
initWithContents(contents)
@@ -57,7 +57,7 @@ extends Map[A, B]
def this() = this(null)
- def par = new ParHashMap[A, B](hashTableContents)
+ override def par = new ParHashMap[A, B](hashTableContents)
def get(key: A): Option[B] = {
val e = findEntry(key)
@@ -130,11 +130,6 @@ extends Map[A, B]
init[B](in, new Entry(_, _))
}
- override def toParIterable = par
-
- private type C = (A, B)
- override def toParMap[D, E](implicit ev: C <:< (D, E)) = par.asInstanceOf[ParHashMap[D, E]]
-
}
/** $factoryInfo
diff --git a/src/library/scala/collection/mutable/HashSet.scala b/src/library/scala/collection/mutable/HashSet.scala
index a1b85fa16e..2ba5065964 100644
--- a/src/library/scala/collection/mutable/HashSet.scala
+++ b/src/library/scala/collection/mutable/HashSet.scala
@@ -44,7 +44,7 @@ extends Set[A]
with GenericSetTemplate[A, HashSet]
with SetLike[A, HashSet[A]]
with FlatHashTable[A]
- with Parallelizable[ParHashSet[A]]
+ with CustomParallelizable[A, ParHashSet[A]]
with Serializable
{
initWithContents(contents)
@@ -60,7 +60,7 @@ extends Set[A]
def += (elem: A): this.type = { addEntry(elem); this }
def -= (elem: A): this.type = { removeEntry(elem); this }
- def par = new ParHashSet(hashTableContents)
+ override def par = new ParHashSet(hashTableContents)
override def add(elem: A): Boolean = addEntry(elem)
override def remove(elem: A): Boolean = removeEntry(elem).isDefined
@@ -93,10 +93,6 @@ extends Set[A]
if (!isSizeMapDefined) sizeMapInitAndRebuild
} else sizeMapDisable
- override def toParIterable = par
-
- override def toParSet[B >: A] = par.asInstanceOf[ParHashSet[B]]
-
}
/** $factoryInfo
diff --git a/src/library/scala/collection/mutable/Iterable.scala b/src/library/scala/collection/mutable/Iterable.scala
index ddf917ba82..8e244d980d 100644
--- a/src/library/scala/collection/mutable/Iterable.scala
+++ b/src/library/scala/collection/mutable/Iterable.scala
@@ -9,6 +9,7 @@ package scala.collection
package mutable
import generic._
+import parallel.mutable.ParIterable
/** A base trait for iterable collections that can be mutated.
* $iterableInfo
@@ -16,8 +17,10 @@ import generic._
trait Iterable[A] extends Traversable[A]
with scala.collection.Iterable[A]
with GenericTraversableTemplate[A, Iterable]
- with IterableLike[A, Iterable[A]] {
+ with IterableLike[A, Iterable[A]]
+ with Parallelizable[A, ParIterable[A]] {
override def companion: GenericCompanion[Iterable] = Iterable
+ protected[this] override def parCombiner = ParIterable.newCombiner[A] // if `mutable.IterableLike` gets introduced, please move this there!
}
/** $factoryInfo
diff --git a/src/library/scala/collection/mutable/MapLike.scala b/src/library/scala/collection/mutable/MapLike.scala
index 1708d25234..04ba8608b9 100644
--- a/src/library/scala/collection/mutable/MapLike.scala
+++ b/src/library/scala/collection/mutable/MapLike.scala
@@ -13,6 +13,7 @@ package mutable
import generic._
import annotation.migration
+import parallel.mutable.ParMap
/** A template trait for mutable maps.
* $mapNote
@@ -25,6 +26,7 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
with Growable[(A, B)]
with Shrinkable[A]
with Cloneable[This]
+ with Parallelizable[(A, B), ParMap[A, B]]
{ self =>
import scala.collection.Traversable
@@ -36,6 +38,8 @@ trait MapLike[A, B, +This <: MapLike[A, B, This] with Map[A, B]]
*/
override protected[this] def newBuilder: Builder[(A, B), This] = empty
+ protected[this] override def parCombiner = ParMap.newCombiner[A, B]
+
/** Adds a new key/value pair to this map and optionally returns previously bound value.
* If the map already contains a
* mapping for the key, it will be overridden by the new value.
diff --git a/src/library/scala/collection/mutable/SeqLike.scala b/src/library/scala/collection/mutable/SeqLike.scala
index 910dd1aab9..4d315b8256 100644
--- a/src/library/scala/collection/mutable/SeqLike.scala
+++ b/src/library/scala/collection/mutable/SeqLike.scala
@@ -10,6 +10,7 @@ package scala.collection
package mutable
import generic._
+import parallel.mutable.ParSeq
/** A template trait for mutable sequences of type `mutable.Seq[A]`.
* @tparam A the type of the elements of the set
@@ -18,9 +19,12 @@ import generic._
*/
trait SeqLike[A, +This <: SeqLike[A, This] with Seq[A]]
extends scala.collection.SeqLike[A, This]
- with Cloneable[This] {
+ with Cloneable[This]
+ with Parallelizable[A, ParSeq[A]] {
self =>
+ protected[this] override def parCombiner = ParSeq.newCombiner[A]
+
/** Replaces element at given index with a new value.
*
* @param n the index of the element to replace.
diff --git a/src/library/scala/collection/mutable/SetLike.scala b/src/library/scala/collection/mutable/SetLike.scala
index c85349fc1a..985e7a3b47 100644
--- a/src/library/scala/collection/mutable/SetLike.scala
+++ b/src/library/scala/collection/mutable/SetLike.scala
@@ -14,6 +14,7 @@ package mutable
import generic._
import script._
import scala.annotation.migration
+import parallel.mutable.ParSet
/** A template trait for mutable sets of type `mutable.Set[A]`.
* @tparam A the type of the elements of the set
@@ -60,6 +61,7 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
with Growable[A]
with Shrinkable[A]
with Cloneable[mutable.Set[A]]
+ with Parallelizable[A, ParSet[A]]
{ self =>
/** A common implementation of `newBuilder` for all mutable sets
@@ -68,6 +70,8 @@ trait SetLike[A, +This <: SetLike[A, This] with Set[A]]
*/
override protected[this] def newBuilder: Builder[A, This] = empty
+ protected[this] override def parCombiner = ParSet.newCombiner[A]
+
/** Adds an element to this $coll.
*
* @param elem the element to be added
diff --git a/src/library/scala/collection/mutable/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala
index 319053d488..21e62306e7 100644
--- a/src/library/scala/collection/mutable/WrappedArray.scala
+++ b/src/library/scala/collection/mutable/WrappedArray.scala
@@ -33,7 +33,7 @@ import scala.collection.parallel.mutable.ParArray
abstract class WrappedArray[T]
extends IndexedSeq[T]
with ArrayLike[T, WrappedArray[T]]
- with Parallelizable[ParArray[T]]
+ with CustomParallelizable[T, ParArray[T]]
{
override protected[this] def thisCollection: WrappedArray[T] = this
@@ -54,7 +54,7 @@ extends IndexedSeq[T]
/** The underlying array */
def array: Array[T]
- def par = ParArray.handoff(array)
+ override def par = ParArray.handoff(array)
override def toArray[U >: T : ClassManifest]: Array[U] =
if (implicitly[ClassManifest[U]].erasure eq array.getClass.getComponentType)
@@ -72,10 +72,6 @@ extends IndexedSeq[T]
override protected[this] def newBuilder: Builder[T, WrappedArray[T]] =
new WrappedArrayBuilder[T](elemManifest)
- override def toParIterable = par
-
- override def toParSeq = par
-
}
/** A companion object used to create instances of `WrappedArray`.
diff --git a/src/library/scala/collection/parallel/ParIterableLike.scala b/src/library/scala/collection/parallel/ParIterableLike.scala
index a92c4f15fb..6b7f244867 100644
--- a/src/library/scala/collection/parallel/ParIterableLike.scala
+++ b/src/library/scala/collection/parallel/ParIterableLike.scala
@@ -16,7 +16,7 @@ import scala.collection.mutable.Builder
import scala.collection.mutable.ArrayBuffer
import scala.collection.IterableLike
import scala.collection.Parallel
-import scala.collection.Parallelizable
+import scala.collection.CustomParallelizable
import scala.collection.Sequentializable
import scala.collection.generic._
import immutable.HashMapCombiner
@@ -82,10 +82,15 @@ import annotation.unchecked.uncheckedVariance
* def par: Repr
* }}}
*
- * produce a view of the collection that has sequential or parallel operations, respectively.
- * These methods are efficient - they will not copy the elements, but have fixed target
- * types. The combination of methods `toParMap`, `toParSeq` or `toParSet` is more flexible,
- * but may copy the elements in some cases.
+ * produce the sequential or parallel implementation of the collection, respectively.
+ * Method `par` just returns a reference to this parallel collection.
+ * Method `seq` is efficient - it will not copy the elements. Instead,
+ * it will create a sequential version of the collection using the same underlying data structure.
+ * Note that this is not the case for sequential collections in general - they may copy the elements
+ * and produce a different underlying data structure.
+ *
+ * The combination of methods `toMap`, `toSeq` or `toSet` along with `par` and `seq` is a flexible
+ * way to change between different collection types.
*
* The method:
*
@@ -152,9 +157,9 @@ import annotation.unchecked.uncheckedVariance
* that splitters may set and read the `indexFlag` state.
*
*/
-trait ParIterableLike[+T, +Repr <: Parallel, +Sequential <: Iterable[T] with IterableLike[T, Sequential]]
+trait ParIterableLike[+T, +Repr <: ParIterable[T], +Sequential <: Iterable[T] with IterableLike[T, Sequential]]
extends IterableLike[T, Repr]
- with Parallelizable[Repr]
+ with CustomParallelizable[T, Repr]
with Sequentializable[T, Sequential]
with Parallel
with HasNewCombiner[T, Repr]
@@ -215,7 +220,7 @@ self =>
*/
def iterator: Splitter[T] = parallelIterator
- def par = repr
+ override def par = repr
/** Denotes whether this parallel collection has strict splitters.
*
@@ -730,8 +735,6 @@ self =>
def parallelIterator = self.parallelIterator
}
- override def toIterable: Iterable[T] = seq.drop(0).asInstanceOf[Iterable[T]]
-
override def toArray[U >: T: ClassManifest]: Array[U] = {
val arr = new Array[U](size)
copyToArray(arr)
@@ -744,25 +747,21 @@ self =>
override def toStream: Stream[T] = seq.toStream
- override def toSet[U >: T]: collection.immutable.Set[U] = seq.toSet
-
- override def toSeq: Seq[T] = seq.toSeq
-
- override def toIterator: Iterator[T] = seq.toIterator
+ override def toIterator: Iterator[T] = parallelIterator
- override def toTraversable: Traversable[T] = seq.toTraversable
+ // the methods below are overridden
- override def toBuffer[U >: T]: collection.mutable.Buffer[U] = seq.toBuffer
+ override def toBuffer[U >: T]: collection.mutable.Buffer[U] = seq.toBuffer // have additional, parallel buffers?
- override def toMap[K, V](implicit ev: T <:< (K, V)): collection.immutable.Map[K, V] = seq.toMap
+ override def toTraversable: Traversable[T] = this.asInstanceOf[Traversable[T]] // TODO add ParTraversable[T]
- override def toParIterable: ParIterable[T] = this.asInstanceOf[ParIterable[T]]
+ override def toIterable: ParIterable[T] = this.asInstanceOf[ParIterable[T]]
- override def toParSeq: ParSeq[T] = toParCollection[T, ParSeq[T]](() => mutable.ParArrayCombiner[T]())
+ override def toSeq: ParSeq[T] = toParCollection[T, ParSeq[T]](() => ParSeq.newCombiner[T])
- override def toParSet[U >: T]: ParSet[U] = toParCollection[U, ParSet[U]](() => mutable.ParHashSetCombiner[U])
+ override def toSet[U >: T]: immutable.ParSet[U] = toParCollection[U, immutable.ParSet[U]](() => immutable.ParSet.newCombiner[U])
- override def toParMap[K, V](implicit ev: T <:< (K, V)): ParMap[K, V] = toParMap[K, V, mutable.ParHashMap[K, V]](() => mutable.ParHashMapCombiner[K, V])
+ override def toMap[K, V](implicit ev: T <:< (K, V)): immutable.ParMap[K, V] = toParMap[K, V, immutable.ParMap[K, V]](() => immutable.ParMap.newCombiner[K, V])
/* tasks */
diff --git a/src/library/scala/collection/parallel/ParMapLike.scala b/src/library/scala/collection/parallel/ParMapLike.scala
index e8f076dc4f..1cd5ad02d7 100644
--- a/src/library/scala/collection/parallel/ParMapLike.scala
+++ b/src/library/scala/collection/parallel/ParMapLike.scala
@@ -48,9 +48,7 @@ extends MapLike[K, V, Repr]
override def empty: Repr
- private type T = (K, V)
- override def toParMap[K, V](implicit ev: T <:< (K, V)) = this.asInstanceOf[ParMap[K, V]]
-
+ // note - should not override toMap (could be mutable)
}
diff --git a/src/library/scala/collection/parallel/ParSeqLike.scala b/src/library/scala/collection/parallel/ParSeqLike.scala
index d40ced0cd8..1e49f69753 100644
--- a/src/library/scala/collection/parallel/ParSeqLike.scala
+++ b/src/library/scala/collection/parallel/ParSeqLike.scala
@@ -45,7 +45,7 @@ import scala.collection.generic.VolatileAbort
* @author Aleksandar Prokopec
* @since 2.9
*/
-trait ParSeqLike[+T, +Repr <: Parallel, +Sequential <: Seq[T] with SeqLike[T, Sequential]]
+trait ParSeqLike[+T, +Repr <: ParSeq[T], +Sequential <: Seq[T] with SeqLike[T, Sequential]]
extends scala.collection.SeqLike[T, Repr]
with ParIterableLike[T, Repr, Sequential] {
self =>
@@ -314,7 +314,7 @@ self =>
override def toString = seq.mkString(stringPrefix + "(", ", ", ")")
- override def toParSeq = this.asInstanceOf[ParSeq[T]] // TODO add a type bound for `Repr`
+ override def toSeq = this.asInstanceOf[ParSeq[T]]
override def view = new ParSeqView[T, Repr, Sequential] {
protected lazy val underlying = self.repr
diff --git a/src/library/scala/collection/parallel/ParSetLike.scala b/src/library/scala/collection/parallel/ParSetLike.scala
index d888d5865f..9e769f425b 100644
--- a/src/library/scala/collection/parallel/ParSetLike.scala
+++ b/src/library/scala/collection/parallel/ParSetLike.scala
@@ -45,8 +45,7 @@ extends SetLike[T, Repr]
override def empty: Repr
- override def toParSet[U >: T] = this.asInstanceOf[ParSet[U]]
-
+ // note: should not override toSet (could be mutable)
}
diff --git a/src/library/scala/collection/parallel/immutable/ParIterable.scala b/src/library/scala/collection/parallel/immutable/ParIterable.scala
index 0118452cb8..c4da1ced8e 100644
--- a/src/library/scala/collection/parallel/immutable/ParIterable.scala
+++ b/src/library/scala/collection/parallel/immutable/ParIterable.scala
@@ -36,16 +36,14 @@ extends collection.immutable.Iterable[T]
{
override def companion: GenericCompanion[ParIterable] with GenericParCompanion[ParIterable] = ParIterable
- override def toParIterable: ParIterable[T] = this
+ // if `immutable.ParIterableLike` is introduced, please move these 4 methods there
+ override def toIterable: ParIterable[T] = this
- // override def toParSeq: ParSeq TODO vector
-
- override def toParSet[U >: T]: ParSet[U] = toParCollection[U, ParHashSet[U]](() => HashSetCombiner[U])
-
- override def toParMap[K, V](implicit ev: T <:< (K, V)): ParMap[K, V] = toParMap(() => HashMapCombiner[K, V])
+ override def toSeq: ParSeq[T] = toParCollection[T, ParSeq[T]](() => ParSeq.newCombiner[T])
}
+
/** $factoryinfo
*/
object ParIterable extends ParFactory[ParIterable] {
diff --git a/src/library/scala/collection/parallel/immutable/ParMap.scala b/src/library/scala/collection/parallel/immutable/ParMap.scala
index d99091c57c..5db07a6a3b 100644
--- a/src/library/scala/collection/parallel/immutable/ParMap.scala
+++ b/src/library/scala/collection/parallel/immutable/ParMap.scala
@@ -50,7 +50,7 @@ self =>
override def stringPrefix = "ParMap"
- override def toParMap[P, Q](implicit ev: (K, V) <:< (P, Q)): ParMap[P, Q] = this.asInstanceOf[ParMap[P, Q]]
+ override def toMap[P, Q](implicit ev: (K, V) <:< (P, Q)): ParMap[P, Q] = this.asInstanceOf[ParMap[P, Q]]
}
diff --git a/src/library/scala/collection/parallel/immutable/ParNumericRange.scala.disabled b/src/library/scala/collection/parallel/immutable/ParNumericRange.scala.disabled
index a32d7bb086..fb411ec0ac 100644
--- a/src/library/scala/collection/parallel/immutable/ParNumericRange.scala.disabled
+++ b/src/library/scala/collection/parallel/immutable/ParNumericRange.scala.disabled
@@ -49,10 +49,6 @@ self =>
type SCPI = SignalContextPassingIterator[ParNumericRangeIterator]
- override def toParSeq = this
-
- override def toParSet[U >: T] = toParCollection[U, ParSet[U]](() => HashSetCombiner[U])
-
class ParNumericRangeIterator(range: NumericRange[T] = self.range, num: Integral[T] = self.num)
extends ParIterator {
me: SignalContextPassingIterator[ParNumericRangeIterator] =>
diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala
index 19d2a6d3b8..f68c7c9062 100644
--- a/src/library/scala/collection/parallel/immutable/ParRange.scala
+++ b/src/library/scala/collection/parallel/immutable/ParRange.scala
@@ -49,10 +49,6 @@ self =>
type SCPI = SignalContextPassingIterator[ParRangeIterator]
- override def toParSeq = this
-
- override def toParSet[U >: Int] = toParCollection[U, ParSet[U]](() => HashSetCombiner[U])
-
class ParRangeIterator(range: Range = self.range)
extends ParIterator {
me: SignalContextPassingIterator[ParRangeIterator] =>
diff --git a/src/library/scala/collection/parallel/immutable/ParSet.scala b/src/library/scala/collection/parallel/immutable/ParSet.scala
index 2002d6432d..73d27df994 100644
--- a/src/library/scala/collection/parallel/immutable/ParSet.scala
+++ b/src/library/scala/collection/parallel/immutable/ParSet.scala
@@ -42,8 +42,8 @@ self =>
override def stringPrefix = "ParSet"
- override def toParSet[U >: T] = this.asInstanceOf[ParSet[U]]
-
+ // ok, because this could only violate `apply` and we can live with that
+ override def toSet[U >: T]: ParSet[U] = this.asInstanceOf[ParSet[U]]
}
diff --git a/src/library/scala/collection/parallel/mutable/ParIterable.scala b/src/library/scala/collection/parallel/mutable/ParIterable.scala
index eba4ff2e72..fcba75452f 100644
--- a/src/library/scala/collection/parallel/mutable/ParIterable.scala
+++ b/src/library/scala/collection/parallel/mutable/ParIterable.scala
@@ -32,6 +32,11 @@ trait ParIterable[T] extends collection.mutable.Iterable[T]
with GenericParTemplate[T, ParIterable]
with ParIterableLike[T, ParIterable[T], Iterable[T]] {
override def companion: GenericCompanion[ParIterable] with GenericParCompanion[ParIterable] = ParIterable
+
+ // if `mutable.ParIterableLike` is introduced, please move these 4 methods there
+ override def toIterable: ParIterable[T] = this
+
+ override def toSeq: ParSeq[T] = toParCollection[T, ParSeq[T]](() => ParSeq.newCombiner[T])
}
/** $factoryinfo
diff --git a/src/library/scala/collection/parallel/mutable/ParMapLike.scala b/src/library/scala/collection/parallel/mutable/ParMapLike.scala
index cd2bea1419..46352829aa 100644
--- a/src/library/scala/collection/parallel/mutable/ParMapLike.scala
+++ b/src/library/scala/collection/parallel/mutable/ParMapLike.scala
@@ -33,5 +33,9 @@ trait ParMapLike[K,
+Repr <: ParMapLike[K, V, Repr, Sequential] with ParMap[K, V],
+Sequential <: collection.mutable.Map[K, V] with collection.mutable.MapLike[K, V, Sequential]]
extends collection.mutable.MapLike[K, V, Repr]
- with collection.parallel.ParMapLike[K, V, Repr, Sequential]
+ with collection.parallel.ParMapLike[K, V, Repr, Sequential] {
+
+ // note: should not override toMap
+
+}
diff --git a/src/library/scala/collection/parallel/mutable/ParSeq.scala b/src/library/scala/collection/parallel/mutable/ParSeq.scala
index 10d3033701..1b2b9f9854 100644
--- a/src/library/scala/collection/parallel/mutable/ParSeq.scala
+++ b/src/library/scala/collection/parallel/mutable/ParSeq.scala
@@ -39,6 +39,8 @@ trait ParSeq[T] extends collection.mutable.Seq[T]
def update(i: Int, elem: T): Unit
+ override def toSeq: ParSeq[T] = this
+
}
diff --git a/src/library/scala/collection/parallel/mutable/ParSetLike.scala b/src/library/scala/collection/parallel/mutable/ParSetLike.scala
index df87eff42c..68f142cda7 100644
--- a/src/library/scala/collection/parallel/mutable/ParSetLike.scala
+++ b/src/library/scala/collection/parallel/mutable/ParSetLike.scala
@@ -46,6 +46,7 @@ extends mutable.SetLike[T, Repr]
override def empty: Repr
+ // note: should not override toSet
}
diff --git a/test/files/run/coder/Coder.scala b/test/files/run/coder/Coder.scala
index 5c81efc9c0..06dd4b6355 100644
--- a/test/files/run/coder/Coder.scala
+++ b/test/files/run/coder/Coder.scala
@@ -85,7 +85,7 @@ class ParCoder(words: List[String]) {
def encode(number: String): ParSet[List[String]] =
if (number.isEmpty) ParSet(List())
else {
- val splits = (1 to number.length).toParSet
+ val splits = (1 to number.length).toSet.par
// for {
// split <- splits
// word <- wordsForNum(number take split)
diff --git a/test/files/run/coder2/Coder2.scala b/test/files/run/coder2/Coder2.scala
index 7ecc5e67d1..abe284a398 100644
--- a/test/files/run/coder2/Coder2.scala
+++ b/test/files/run/coder2/Coder2.scala
@@ -77,7 +77,7 @@ class ParCoder(words: List[String]) {
* them e.g. `5282` -> List(`Java`, `Kata`, `Lava`, ...)
*/
val wordsForNum: Map[String, ParSeq[String]] =
- (words groupBy wordCode).map(t => (t._1, t._2.toParSeq)) withDefaultValue ParSeq()
+ (words groupBy wordCode).map(t => (t._1, t._2.toSeq.par)) withDefaultValue ParSeq()
val comparison = new SeqCoder(words)
@@ -85,7 +85,7 @@ class ParCoder(words: List[String]) {
def encode(number: String): ParSet[ParSeq[String]] =
if (number.isEmpty) ParSet(ParSeq())
else {
- val splits = (1 to number.length).toParSet
+ val splits = (1 to number.length).toSet.par
// for {
// split <- splits
// word <- wordsForNum(number take split)
@@ -118,7 +118,7 @@ class ParCoder(words: List[String]) {
def assertWfn(num: String, split: String, dropped: String, r: ParSeq[ParSeq[String]]) {
val m = comparison.wfnmemo((num, split))
- val rs = r.toParSet
+ val rs = r.toSet.par
val words: ParSeq[String] = wordsForNum(split)
if (rs != m) {
println("flatmap for number with split: " + num + ", " + split)
@@ -168,32 +168,32 @@ object Test {
/* */
def main(args : Array[String]) {
- // for (i <- 0 until 10) {
- // val seqcoder = new SeqCoder(Dictionary.wordlist)
- // val st = seqcoder.translate(code)
- // //println("Translation check: " + st.size)
-
- // val parcoder = new ParCoder(Dictionary.wordlist)
- // val pt = parcoder.translate(code)
- // //println("Translation check: " + pt.size)
-
- // // val st = sts.toList.sorted
- // // val pt = pts.toList.sorted
- // if (st.size != pt.size) {
- // // val zipped = st.zip(pt)
- // // val ind = zipped.indexWhere { case (a, b) => a != b }
- // // val sliced = zipped.slice(ind - 10, ind + 10)
- // // println(sliced.map(t => t._1 + "\n" + t._2 + "\n--------").mkString("\n"))
- // println(i + ") seq vs par: " + st.size + " vs " + pt.size)
- // }
- // if (st != pt) {
- // val zipped = (st.toList.sorted zip pt.toList.sorted);
- // val diffp = zipped indexWhere { case (x, y) => x != y }
- // println(zipped/*.slice(diffp - 10, diffp + 10)*/ mkString ("\n"))
- // println((st.toList.sorted zip pt.toList.sorted) map { case (x, y) => (x == y) } reduceLeft(_ && _))
- // }
- // assert(st == pt)
- // }
+ for (i <- 0 until 10) {
+ val seqcoder = new SeqCoder(Dictionary.wordlist)
+ val sts = seqcoder.translate(code)
+ //println("Translation check: " + st.size)
+
+ val parcoder = new ParCoder(Dictionary.wordlist)
+ val pts = parcoder.translate(code)
+ //println("Translation check: " + pt.size)
+
+ val st = sts.toList.sorted
+ val pt = pts.toList.sorted
+ if (st.size != pt.size) {
+ val zipped = st.zip(pt)
+ val ind = zipped.indexWhere { case (a, b) => a != b }
+ val sliced = zipped.slice(ind - 10, ind + 10)
+ //println(sliced.map(t => t._1 + "\n" + t._2 + "\n--------").mkString("\n"))
+ //println(i + ") seq vs par: " + st.size + " vs " + pt.size)
+ }
+ if (st != pt) {
+ val zipped = (st.toList.sorted zip pt.toList.sorted);
+ val diffp = zipped indexWhere { case (x, y) => x != y }
+ //println(zipped/*.slice(diffp - 10, diffp + 10)*/ mkString ("\n"))
+ //println((st.toList.sorted zip pt.toList.sorted) map { case (x, y) => (x == y) } reduceLeft(_ && _))
+ }
+ assert(st == pt)
+ }
}
}
diff --git a/test/files/run/pc-conversions.scala b/test/files/run/pc-conversions.scala
index 7e894f70f3..23fcb9fa59 100644
--- a/test/files/run/pc-conversions.scala
+++ b/test/files/run/pc-conversions.scala
@@ -30,7 +30,7 @@ object Test {
assertPar(immutable.HashMap(1 -> 1, 2 -> 2))
assertPar(immutable.HashSet(1, 2, 3))
- // toPar*
+ // par.to* and to*.par tests
assertToPar(List(1 -> 1, 2 -> 2, 3 -> 3))
assertToPar(Stream(1 -> 1, 2 -> 2))
assertToPar(Array(1 -> 1, 2 -> 2))
@@ -55,28 +55,49 @@ object Test {
def assertSeq[T](pc: parallel.ParIterable[T]) = assert(pc.seq == pc)
- def assertPar[T, P <: Parallel](xs: Iterable[T] with Parallelizable[P]) = assert(xs == xs.par)
+ def assertPar[T, P <: Parallel](xs: Iterable[T]) = assert(xs == xs.par)
def assertToPar[K, V](xs: Traversable[(K, V)]) {
xs match {
- case _: Seq[_] => assert(xs.toParIterable == xs)
+ case _: Seq[_] =>
+ assert(xs.toIterable.par == xs)
+ assert(xs.par.toIterable == xs)
case _ =>
}
- assert(xs.toParSeq == xs.toSeq)
- assert(xs.toParSet == xs.toSet)
- assert(xs.toParMap == xs.toMap)
+
+ assert(xs.toSeq.par == xs.toSeq)
+ assert(xs.par.toSeq == xs.toSeq)
+
+ assert(xs.toSet.par == xs.toSet)
+ assert(xs.par.toSet == xs.toSet)
+
+ assert(xs.toMap.par == xs.toMap)
+ assert(xs.par.toMap == xs.toMap)
}
- def assertToParWoMap[T](xs: Traversable[T]) {
- assert(xs.toParIterable == xs)
- assert(xs.toParSeq == xs.toSeq)
- assert(xs.toParSet == xs.toSet)
+ def assertToParWoMap[T](xs: Seq[T]) {
+ assert(xs.toIterable.par == xs.toIterable)
+ assert(xs.par.toIterable == xs.toIterable)
+
+ assert(xs.toSeq.par == xs.toSeq)
+ assert(xs.par.toSeq == xs.toSeq)
+
+ assert(xs.toSet.par == xs.toSet)
+ assert(xs.par.toSet == xs.toSet)
}
def assertToParIt[K, V](xs: =>Iterator[(K, V)]) {
- assert(xs.toParSeq == xs.toSeq)
- assert(xs.toParSet == xs.toSet)
- assert(xs.toParMap == xs.toMap)
+ assert(xs.toIterable.par == xs.toIterable)
+ assert(xs.par.toIterable == xs.toIterable)
+
+ assert(xs.toSeq.par == xs.toSeq)
+ assert(xs.par.toSeq == xs.toSeq)
+
+ assert(xs.toSet.par == xs.toSet)
+ assert(xs.par.toSet == xs.toSet)
+
+ assert(xs.toMap.par == xs.toMap)
+ assert(xs.par.toMap == xs.toMap)
}
}