From a16bba97a013cc7cb8bb7fa8815b4683efa4324a Mon Sep 17 00:00:00 2001 From: Aleksandar Pokopec Date: Thu, 25 Nov 2010 17:16:53 +0000 Subject: Added toParIterable, toParSeq, toParSet and toP... Added toParIterable, toParSeq, toParSet and toParMap conversions. No review. --- src/library/scala/collection/TraversableOnce.scala | 34 ++++++++++++++++++++++ .../scala/collection/immutable/HashMap.scala | 5 ++++ .../scala/collection/immutable/HashSet.scala | 5 ++++ src/library/scala/collection/immutable/Range.scala | 10 ++++++- .../scala/collection/mutable/ArrayBuffer.scala | 5 ++++ .../scala/collection/mutable/ArraySeq.scala | 20 +++++++++---- src/library/scala/collection/mutable/HashMap.scala | 7 ++++- src/library/scala/collection/mutable/HashSet.scala | 4 +++ .../scala/collection/mutable/WrappedArray.scala | 14 ++++++++- .../collection/parallel/ParIterableLike.scala | 20 +++++++++++-- .../scala/collection/parallel/ParMapLike.scala | 3 ++ .../scala/collection/parallel/ParSeqLike.scala | 6 ++-- .../scala/collection/parallel/ParSetLike.scala | 2 ++ .../collection/parallel/immutable/ParRange.scala | 4 +++ .../collection/parallel/mutable/ParHashMap.scala | 2 ++ .../collection/parallel/mutable/package.scala | 3 +- 16 files changed, 129 insertions(+), 15 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/TraversableOnce.scala b/src/library/scala/collection/TraversableOnce.scala index e29ca1ed91..1011108d8e 100644 --- a/src/library/scala/collection/TraversableOnce.scala +++ b/src/library/scala/collection/TraversableOnce.scala @@ -469,6 +469,40 @@ 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` + */ + + def toParIterable: parallel.ParIterable[A] = toParSeq + + def toParSeq: parallel.ParSeq[A] = { + val cb = parallel.mutable.ParArray.newCombiner[A] + for (elem <- this) cb += elem + cb.result + } + + def toParSet[B >: A]: parallel.ParSet[B] = { + val cb = parallel.mutable.ParHashSet.newCombiner[B] + for (elem <- this) cb += elem + cb.result + } + + 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 32542b9359..977dd6d837 100644 --- a/src/library/scala/collection/immutable/HashMap.scala +++ b/src/library/scala/collection/immutable/HashMap.scala @@ -92,6 +92,11 @@ class HashMap[A, +B] extends Map[A,B] with MapLike[A, B, HashMap[A, B]] with Par 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 5a65e69d4d..e75c230eb8 100644 --- a/src/library/scala/collection/immutable/HashSet.scala +++ b/src/library/scala/collection/immutable/HashSet.scala @@ -80,6 +80,11 @@ 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/Range.scala b/src/library/scala/collection/immutable/Range.scala index b8bccc742f..26e32e08fb 100644 --- a/src/library/scala/collection/immutable/Range.scala +++ b/src/library/scala/collection/immutable/Range.scala @@ -9,6 +9,8 @@ package scala.collection.immutable +import scala.collection.parallel.immutable.ParRange + /** The `Range` class represents integer values in range * ''[start;end)'' with non-zero step value `step`. * It's a special case of an indexed sequence. @@ -37,7 +39,12 @@ package scala.collection.immutable * and its complexity is O(1). */ @serializable @SerialVersionUID(7618862778670199309L) -class Range(val start: Int, val end: Int, val step: Int) extends IndexedSeq[Int] { +class Range(val start: Int, val end: Int, val step: Int) +extends IndexedSeq[Int] + with collection.Parallelizable[ParRange] +{ + def par = ParRange(start, end, step, false) + // Note that this value is calculated eagerly intentionally: it also // serves to enforce conditions (step != 0) && (length <= Int.MaxValue) private val numRangeElements: Int = @@ -241,6 +248,7 @@ object Range { NumericRange.count[Long](start, end, step, isInclusive) class Inclusive(start: Int, end: Int, step: Int) extends Range(start, end, step) { + override def par = ParRange(start, end, step, true) override def isInclusive = true override protected def copy(start: Int, end: Int, step: Int): Range = new Inclusive(start, end, step) } diff --git a/src/library/scala/collection/mutable/ArrayBuffer.scala b/src/library/scala/collection/mutable/ArrayBuffer.scala index 2fe5f23a46..83109d0255 100644 --- a/src/library/scala/collection/mutable/ArrayBuffer.scala +++ b/src/library/scala/collection/mutable/ArrayBuffer.scala @@ -175,6 +175,11 @@ class ArrayBuffer[A](override protected val initialSize: Int) /** Defines the prefix of the string representation. */ 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/ArraySeq.scala b/src/library/scala/collection/mutable/ArraySeq.scala index 3fc45eaa5f..91bc864224 100644 --- a/src/library/scala/collection/mutable/ArraySeq.scala +++ b/src/library/scala/collection/mutable/ArraySeq.scala @@ -12,6 +12,7 @@ package scala.collection package mutable import generic._ +import parallel.mutable.ParArray /** A class for polymorphic arrays of elements that's represented * internally by an array of objects. This means that elements of @@ -42,12 +43,16 @@ import generic._ class ArraySeq[A](override val length: Int) extends IndexedSeq[A] with GenericTraversableTemplate[A, ArraySeq] - with IndexedSeqOptimized[A, ArraySeq[A]] { + with IndexedSeqOptimized[A, ArraySeq[A]] + with Parallelizable[ParArray[A]] +{ override def companion: GenericCompanion[ArraySeq] = ArraySeq val array: Array[AnyRef] = new Array[AnyRef](length) + def par = ParArray.handoff(array.asInstanceOf[Array[A]]) + def apply(idx: Int): A = { if (idx >= length) throw new IndexOutOfBoundsException(idx.toString) array(idx).asInstanceOf[A] @@ -75,10 +80,15 @@ extends IndexedSeq[A] * @param start starting index. * @param len number of elements to copy */ - override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) { - val len1 = len min (xs.length - start) min length - Array.copy(array, 0, xs, start, len1) - } + override def copyToArray[B >: A](xs: Array[B], start: Int, len: Int) { + val len1 = len min (xs.length - start) min length + 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 44461eaf74..3960af763b 100644 --- a/src/library/scala/collection/mutable/HashMap.scala +++ b/src/library/scala/collection/mutable/HashMap.scala @@ -56,7 +56,7 @@ extends Map[A, B] def this() = this(null) - def par = new ParHashMap[A, B](contents) + def par = new ParHashMap[A, B](hashTableContents) def get(key: A): Option[B] = { val e = findEntry(key) @@ -129,6 +129,11 @@ 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 a7b1fb477c..377f58e74e 100644 --- a/src/library/scala/collection/mutable/HashSet.scala +++ b/src/library/scala/collection/mutable/HashSet.scala @@ -92,6 +92,10 @@ 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/WrappedArray.scala b/src/library/scala/collection/mutable/WrappedArray.scala index 6aea49ec9d..4246a59bf8 100644 --- a/src/library/scala/collection/mutable/WrappedArray.scala +++ b/src/library/scala/collection/mutable/WrappedArray.scala @@ -13,6 +13,7 @@ package mutable import scala.reflect.ClassManifest import scala.collection.generic._ +import scala.collection.parallel.mutable.ParArray /** * A class representing `Array[T]`. @@ -29,7 +30,11 @@ import scala.collection.generic._ * @define mayNotTerminateInf * @define willNotTerminateInf */ -abstract class WrappedArray[T] extends IndexedSeq[T] with ArrayLike[T, WrappedArray[T]] { +abstract class WrappedArray[T] +extends IndexedSeq[T] + with ArrayLike[T, WrappedArray[T]] + with Parallelizable[ParArray[T]] +{ override protected[this] def thisCollection: WrappedArray[T] = this override protected[this] def toCollection(repr: WrappedArray[T]): WrappedArray[T] = repr @@ -49,6 +54,8 @@ abstract class WrappedArray[T] extends IndexedSeq[T] with ArrayLike[T, WrappedAr /** The underlying array */ def array: Array[T] + def par = ParArray.handoff(array) + override def toArray[U >: T : ClassManifest]: Array[U] = if (implicitly[ClassManifest[U]].erasure eq array.getClass.getComponentType) array.asInstanceOf[Array[U]] @@ -64,6 +71,11 @@ abstract class WrappedArray[T] extends IndexedSeq[T] with ArrayLike[T, WrappedAr */ 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 b312c953ad..b3e7ea6072 100644 --- a/src/library/scala/collection/parallel/ParIterableLike.scala +++ b/src/library/scala/collection/parallel/ParIterableLike.scala @@ -666,14 +666,30 @@ self => override def toList: List[T] = seq.toList - override def toIndexedSeq[S >: T]: collection.immutable.IndexedSeq[S] = seq.toIndexedSeq[S] + override def toIndexedSeq[U >: T]: collection.immutable.IndexedSeq[U] = seq.toIndexedSeq[U] override def toStream: Stream[T] = seq.toStream - override def toSet[S >: T]: collection.immutable.Set[S] = seq.toSet + 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 toTraversable: Traversable[T] = seq.toTraversable + + override def toBuffer[U >: T]: collection.mutable.Buffer[U] = seq.toBuffer + + override def toMap[K, V](implicit ev: T <:< (K, V)): collection.immutable.Map[K, V] = seq.toMap + + override def toParIterable = this.asInstanceOf[ParIterable[T]] // TODO add a type bound on Repr + + override def toParSeq = seq.toParSeq + + override def toParSet[U >: T] = seq.toParSet + + override def toParMap[K, V](implicit ev: T <:< (K, V)) = seq.toParMap + /* tasks */ protected trait StrictSplitterCheckTask[R, Tp] extends super.Task[R, Tp] { diff --git a/src/library/scala/collection/parallel/ParMapLike.scala b/src/library/scala/collection/parallel/ParMapLike.scala index 6eb621c76a..9be70d9957 100644 --- a/src/library/scala/collection/parallel/ParMapLike.scala +++ b/src/library/scala/collection/parallel/ParMapLike.scala @@ -28,6 +28,9 @@ 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]] + } diff --git a/src/library/scala/collection/parallel/ParSeqLike.scala b/src/library/scala/collection/parallel/ParSeqLike.scala index b3d0593ecd..5cc78e272b 100644 --- a/src/library/scala/collection/parallel/ParSeqLike.scala +++ b/src/library/scala/collection/parallel/ParSeqLike.scala @@ -72,10 +72,6 @@ self => } } - /** A convenient shorthand for the signal context passing stackable modification. - */ - //type SCPI <: SignalContextPassingIterator[ParIterator] - /** A more refined version of the iterator found in the `ParallelIterable` trait, * this iterator can be split into arbitrary subsets of iterators. * @@ -305,6 +301,8 @@ self => override def toString = seq.mkString(stringPrefix + "(", ", ", ")") + override def toParSeq = this.asInstanceOf[ParSeq[T]] // TODO add a type bound for `Repr` + override def view = new ParSeqView[T, Repr, Sequential] { protected lazy val underlying = self.repr def length = self.length diff --git a/src/library/scala/collection/parallel/ParSetLike.scala b/src/library/scala/collection/parallel/ParSetLike.scala index 444117368c..272ad0048b 100644 --- a/src/library/scala/collection/parallel/ParSetLike.scala +++ b/src/library/scala/collection/parallel/ParSetLike.scala @@ -26,6 +26,8 @@ extends SetLike[T, Repr] override def empty: Repr + override def toParSet[U >: T] = this.asInstanceOf[ParSet[U]] + } diff --git a/src/library/scala/collection/parallel/immutable/ParRange.scala b/src/library/scala/collection/parallel/immutable/ParRange.scala index df13d41d10..53f6bd33e6 100644 --- a/src/library/scala/collection/parallel/immutable/ParRange.scala +++ b/src/library/scala/collection/parallel/immutable/ParRange.scala @@ -81,6 +81,10 @@ extends ParSeq[Int] } +object ParRange { + def apply(start: Int, end: Int, step: Int, inclusive: Boolean) = + new ParRange(start, end, step, inclusive) +} diff --git a/src/library/scala/collection/parallel/mutable/ParHashMap.scala b/src/library/scala/collection/parallel/mutable/ParHashMap.scala index a737c03db1..f4b59186d5 100644 --- a/src/library/scala/collection/parallel/mutable/ParHashMap.scala +++ b/src/library/scala/collection/parallel/mutable/ParHashMap.scala @@ -65,6 +65,8 @@ self => def -=(key: K): this.type = { removeEntry(key); this } + override def stringPrefix = "ParHashMap" + type SCPI = SignalContextPassingIterator[ParHashMapIterator] class ParHashMapIterator(start: Int, untilIdx: Int, totalSize: Int, e: DefaultEntry[K, V]) diff --git a/src/library/scala/collection/parallel/mutable/package.scala b/src/library/scala/collection/parallel/mutable/package.scala index cddd09f696..89544c8bdd 100644 --- a/src/library/scala/collection/parallel/mutable/package.scala +++ b/src/library/scala/collection/parallel/mutable/package.scala @@ -52,7 +52,7 @@ package object mutable { private[mutable] class ExposedArrayBuffer[T] extends ArrayBuffer[T] with Sizing { def internalArray = array def setInternalSize(s: Int) = size0 = s - override def sizeHint(len: Int) = { // delete once we start using 2.8.RC1+ + override def sizeHint(len: Int) = { if (len > size && len >= 1) { val newarray = new Array[AnyRef](len) Array.copy(array, 0, newarray, 0, size0) @@ -64,6 +64,7 @@ package object mutable { private[mutable] class ExposedArraySeq[T](arr: Array[AnyRef], sz: Int) extends ArraySeq[T](sz) { override val array = arr override val length = sz + override def stringPrefix = "ArraySeq" } } -- cgit v1.2.3