/* __ *\ ** ________ ___ / / ___ Scala API ** ** / __/ __// _ | / / / _ | (c) 2003-2013, LAMP/EPFL ** ** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ ** ** /____/\___/_/ |_/____/_/ | | ** ** |/ ** \* */ package scala package collection.parallel.mutable import scala.collection.generic.Growable import scala.collection.generic.Sizing import scala.collection.mutable.ArrayBuffer import scala.collection.parallel.Combiner /** Implements combining contents of two combiners * by postponing the operation until `result` method is called. It chains * the leaf results together instead of evaluating the actual collection. * * @tparam Elem the type of the elements in the combiner * @tparam To the type of the collection the combiner produces * @tparam Buff the type of the buffers that contain leaf results and this combiner chains together */ trait LazyCombiner[Elem, +To, Buff <: Growable[Elem] with Sizing] extends Combiner[Elem, To] { //self: scala.collection.parallel.EnvironmentPassingCombiner[Elem, To] => val chain: ArrayBuffer[Buff] val lastbuff = chain.last def +=(elem: Elem) = { lastbuff += elem; this } def result: To = allocateAndCopy def clear() = { chain.clear() } def combine[N <: Elem, NewTo >: To](other: Combiner[N, NewTo]): Combiner[N, NewTo] = if (this ne other) { import language.existentials // FIXME: See SI-7750 if (other.isInstanceOf[LazyCombiner[_, _, _]]) { val that = other.asInstanceOf[LazyCombiner[Elem, To, Buff]] newLazyCombiner(chain ++= that.chain) } else throw new UnsupportedOperationException("Cannot combine with combiner of different type.") } else this def size = chain.foldLeft(0)(_ + _.size) /** Method that allocates the data structure and copies elements into it using * `size` and `chain` members. */ def allocateAndCopy: To def newLazyCombiner(buffchain: ArrayBuffer[Buff]): LazyCombiner[Elem, To, Buff] }