diff options
Diffstat (limited to 'src')
39 files changed, 170 insertions, 177 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 } |