All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scala.collection.parallel.immutable.ParNumericRange.scala.disabled Maven / Gradle / Ivy

There is a newer version: 2.11.2
Show newest version
/*                     __                                               *\
**     ________ ___   / /  ___     Scala API                            **
**    / __/ __// _ | / /  / _ |    (c) 2003-2013, LAMP/EPFL             **
**  __\ \/ /__/ __ |/ /__/ __ |    http://scala-lang.org/               **
** /____/\___/_/ |_/____/_/ | |                                         **
**                          |/                                          **
\*                                                                      */


package scala.collection.parallel.immutable



import scala.collection.immutable.NumericRange
import scala.collection.parallel.Combiner
import scala.collection.generic.CanCombineFrom
import scala.collection.parallel.ParIterableIterator



/** Parallel ranges for numeric types.
 *  
 *  $paralleliterableinfo
 *  
 *  $sideeffects
 *  
 *  @param range    the sequential range this parallel range was obtained from
 *  
 *  @author Aleksandar Prokopec
 *  @since 2.9
 *  
 *  @define Coll `immutable.ParRange`
 *  @define coll immutable parallel range
 */
@SerialVersionUID(1L)
class ParNumericRange[T](val range: NumericRange[T])(implicit num: Integral[T])
extends ParSeq[T]
   with Serializable
{
self =>
  
  def seq = range
  
  @inline final def length = range.length
  
  @inline final def apply(idx: Int) = range.apply(idx);
  
  def parallelIterator = new ParNumericRangeIterator with SCPI
  
  type SCPI = SignalContextPassingIterator[ParNumericRangeIterator]
  
  class ParNumericRangeIterator(range: NumericRange[T] = self.range, num: Integral[T] = self.num)
  extends ParIterator {
  me: SignalContextPassingIterator[ParNumericRangeIterator] =>
    override def toString = "ParNumericRangeIterator(over: " + range + ")"
    private var ind = 0
    private val len = range.length
    
    final def remaining = len - ind
    
    final def hasNext = ind < len
    
    final def next = if (hasNext) {
      val r = range.apply(ind)
      ind += 1
      r
    } else Iterator.empty.next
    
    private def rangeleft: NumericRange[T] = range.drop(ind)
    
    def dup = new ParNumericRangeIterator(rangeleft) with SCPI
    
    def split = {
      val rleft = rangeleft
      val elemleft = rleft.length
      if (elemleft < 2) Seq(new ParNumericRangeIterator(rleft) with SCPI)
      else Seq(
        new ParNumericRangeIterator(rleft.take(elemleft / 2)) with SCPI,
        new ParNumericRangeIterator(rleft.drop(elemleft / 2)) with SCPI
      )
    }
    
    def psplit(sizes: Int*) = {
      var rleft = rangeleft
      for (sz <- sizes) yield {
        val fronttaken = rleft.take(sz)
        rleft = rleft.drop(sz)
        new ParNumericRangeIterator(fronttaken) with SCPI
      }
    }
    
    /* accessors */
    
    override def foreach[U](f: T => U): Unit = {
      rangeleft.foreach(f)
      ind = len
    }
    
    override def reduce[U >: T](op: (U, U) => U): U = {
      val r = rangeleft.reduceLeft(op)
      ind = len
      r
    }
    
    /* transformers */
    
    override def map2combiner[S, That](f: T => S, cb: Combiner[S, That]): Combiner[S, That] = {
      while (hasNext) {
        cb += f(next)
      }
      cb
    }
  }
  
}


object ParNumericRange {
  def apply[T](start: T, end: T, step: T, inclusive: Boolean)(implicit num: Integral[T]) = new ParNumericRange[T](
    if (inclusive) NumericRange.inclusive(start, end, step)(num)
    else NumericRange.apply(start, end, step)(num)
  )
}









© 2015 - 2024 Weber Informatics LLC | Privacy Policy