summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/parallel/immutable/ParRange.scala
blob: 53f6bd33e6956acd50c1a9f5728576b2f94d9ab6 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
package scala.collection.parallel.immutable



import scala.collection.immutable.Range
import scala.collection.immutable.RangeUtils
import scala.collection.parallel.ParSeq
import scala.collection.parallel.Combiner
import scala.collection.generic.CanCombineFrom



class ParRange(val start: Int, val end: Int, val step: Int, val inclusive: Boolean)
extends ParSeq[Int]
   with RangeUtils[ParRange] {
  self =>

  def seq = new Range(start, end, step)

  def length = _length

  def apply(idx: Int) = _apply(idx)

  def create(_start: Int, _end: Int, _step: Int, _inclusive: Boolean) = new ParRange(_start, _end, _step, _inclusive)

  def parallelIterator = new ParRangeIterator with SCPI

  override def toString = seq.toString // TODO

  type SCPI = SignalContextPassingIterator[ParRangeIterator]

  class ParRangeIterator
  (var start: Int = self.start, val end: Int = self.end, val step: Int = self.step, val inclusive: Boolean = self.inclusive)
  extends ParIterator with RangeUtils[ParRangeIterator] {
    me: SignalContextPassingIterator[ParRangeIterator] =>
    def remaining = _length
    def next = { val r = start; start += step; r }
    def hasNext = remaining > 0
    def split: Seq[ParIterator] = psplit(remaining / 2, remaining - remaining / 2)
    def psplit(sizes: Int*): Seq[ParIterator] = {
      val incr = sizes.scanLeft(0)(_ + _)
      for ((from, until) <- incr.init zip incr.tail) yield _slice(from, until)
    }
    def create(_start: Int, _end: Int, _step: Int, _inclusive: Boolean) = {
      new ParRangeIterator(_start, _end, _step, _inclusive) with SCPI
    }

    override def toString = "ParRangeIterator(" + start + ", " + end + ", " + step + ", incl: " + inclusive + ")"

    /* accessors */

    override def foreach[U](f: Int => U): Unit = {
      _foreach(f)
      start = end + step
    }

    override def reduce[U >: Int](op: (U, U) => U): U = {
      var sum = next
      for (elem <- this) sum += elem
      sum
    }

    /* transformers */

    override def map2combiner[S, That](f: Int => S, cb: Combiner[S, That]): Combiner[S, That] = {
      //val cb = pbf(self.repr)
      val sz = remaining
      cb.sizeHint(sz)
      if (sz > 0) {
        val last = _last
        while (start != last) {
          f(start)
          start += step
        }
      }
      cb
    }

  }

}


object ParRange {
  def apply(start: Int, end: Int, step: Int, inclusive: Boolean) =
    new ParRange(start, end, step, inclusive)
}