diff options
author | Paul Phillips <paulp@improving.org> | 2011-04-14 04:15:50 +0000 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-04-14 04:15:50 +0000 |
commit | 8198c1193ccc539ce58b12505c31e399139b45e6 (patch) | |
tree | 280c7896e4ef294c675a5aef9caf12ad95f63bd8 /src/library/scala/collection/parallel/mutable/ResizableParArrayCombiner.scala | |
parent | 20d0a7dd224dfbcaa8e484628704b810a5ba7bdd (diff) | |
download | scala-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.scala | 111 |
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]) +} + + + + + + + + + + + + |