summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-04-14 04:15:50 +0000
committerPaul Phillips <paulp@improving.org>2011-04-14 04:15:50 +0000
commit8198c1193ccc539ce58b12505c31e399139b45e6 (patch)
tree280c7896e4ef294c675a5aef9caf12ad95f63bd8 /src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
parent20d0a7dd224dfbcaa8e484628704b810a5ba7bdd (diff)
downloadscala-8198c1193ccc539ce58b12505c31e399139b45e6.tar.gz
scala-8198c1193ccc539ce58b12505c31e399139b45e6.tar.bz2
scala-8198c1193ccc539ce58b12505c31e399139b45e6.zip
Tests which run have to be called "Test".
and renames file to avoid ant's brainlessness, no review.
Diffstat (limited to 'src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala')
-rw-r--r--src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala111
1 files changed, 111 insertions, 0 deletions
diff --git a/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala b/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
new file mode 100644
index 0000000000..8290438c10
--- /dev/null
+++ b/src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala
@@ -0,0 +1,111 @@
+/* __ *\
+** ________ ___ / / ___ Scala API **
+** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
+** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
+** /____/\___/_/ |_/____/_/ | | **
+** |/ **
+\* */
+
+package scala.collection.parallel.mutable
+
+
+
+import scala.collection.generic.Sizing
+import scala.collection.mutable.ArraySeq
+import scala.collection.mutable.ArrayBuffer
+import scala.collection.parallel.TaskSupport
+//import scala.collection.parallel.EnvironmentPassingCombiner
+import scala.collection.parallel.unsupportedop
+import scala.collection.parallel.Combiner
+
+
+
+/** An array combiner that uses a chain of arraybuffers to store elements. */
+trait ResizableParArrayCombiner[T]
+extends LazyCombiner[T, ParArray[T], ExposedArrayBuffer[T]]
+{
+//self: EnvironmentPassingCombiner[T, ParArray[T]] =>
+ import collection.parallel.tasksupport._
+
+ override def sizeHint(sz: Int) = if (chain.length == 1) chain(0).sizeHint(sz)
+
+ def newLazyCombiner(c: ArrayBuffer[ExposedArrayBuffer[T]]) = ResizableParArrayCombiner(c)
+
+ def allocateAndCopy = if (chain.size > 1) {
+ val arrayseq = new ArraySeq[T](size)
+ val array = arrayseq.array.asInstanceOf[Array[Any]]
+
+ executeAndWaitResult(new CopyChainToArray(array, 0, size))
+
+ new ParArray(arrayseq)
+ } else { // optimisation if there is only 1 array
+ val pa = new ParArray(new ExposedArraySeq[T](chain(0).internalArray, size))
+ pa
+ }
+
+ override def toString = "ResizableParArrayCombiner(" + size + "): " //+ chain
+
+ /* tasks */
+
+ class CopyChainToArray(array: Array[Any], offset: Int, howmany: Int) extends Task[Unit, CopyChainToArray] {
+ var result = ()
+ def leaf(prev: Option[Unit]) = if (howmany > 0) {
+ var totalleft = howmany
+ val (stbuff, stind) = findStart(offset)
+ var buffind = stbuff
+ var ind = stind
+ var arrayIndex = offset
+ while (totalleft > 0) {
+ val currbuff = chain(buffind)
+ val chunksize = if (totalleft < (currbuff.size - ind)) totalleft else currbuff.size - ind
+ val until = ind + chunksize
+
+ copyChunk(currbuff.internalArray, ind, array, arrayIndex, until)
+ arrayIndex += chunksize
+ ind += chunksize
+
+ totalleft -= chunksize
+ buffind += 1
+ ind = 0
+ }
+ }
+ private def copyChunk(buffarr: Array[AnyRef], buffStart: Int, ra: Array[Any], arrayStart: Int, until: Int) {
+ Array.copy(buffarr, buffStart, ra, arrayStart, until - buffStart)
+ }
+ private def findStart(pos: Int) = {
+ var left = pos
+ var buffind = 0
+ while (left >= chain(buffind).size) {
+ left -= chain(buffind).size
+ buffind += 1
+ }
+ (buffind, left)
+ }
+ def split = {
+ val fp = howmany / 2
+ List(new CopyChainToArray(array, offset, fp), new CopyChainToArray(array, offset + fp, howmany - fp))
+ }
+ def shouldSplitFurther = howmany > collection.parallel.thresholdFromSize(size, parallelismLevel)
+ }
+
+}
+
+
+object ResizableParArrayCombiner {
+ def apply[T](c: ArrayBuffer[ExposedArrayBuffer[T]]): ResizableParArrayCombiner[T] = {
+ new { val chain = c } with ResizableParArrayCombiner[T] // was: with EnvironmentPassingCombiner[T, ParArray[T]]
+ }
+ def apply[T](): ResizableParArrayCombiner[T] = apply(new ArrayBuffer[ExposedArrayBuffer[T]] += new ExposedArrayBuffer[T])
+}
+
+
+
+
+
+
+
+
+
+
+
+