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
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/* __ *\
** ________ ___ / / ___ Scala API **
** / __/ __// _ | / / / _ | (c) 2003-2011, LAMP/EPFL **
** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
** /____/\___/_/ |_/____/_/ | | **
** |/ **
\* */
package scala.collection
package parallel.immutable
import scala.collection.generic.{GenericParTemplate, CanCombineFrom, ParFactory}
import scala.collection.parallel.ParSeqLike
import scala.collection.parallel.Combiner
import scala.collection.parallel.SeqSplitter
import mutable.ArrayBuffer
import immutable.Vector
import immutable.VectorBuilder
import immutable.VectorIterator
/** Immutable parallel vectors, based on vectors.
*
* $paralleliterableinfo
*
* $sideeffects
*
* @tparam T the element type of the vector
*
* @author Aleksandar Prokopec
* @since 2.9
*
* @define Coll immutable.ParVector
* @define coll immutable parallel vector
*/
class ParVector[+T](private[this] val vector: Vector[T])
extends ParSeq[T]
with GenericParTemplate[T, ParVector]
with ParSeqLike[T, ParVector[T], Vector[T]]
with Serializable
{
override def companion = ParVector
def this() = this(Vector())
type SCPI = SignalContextPassingIterator[ParVectorIterator]
def apply(idx: Int) = vector.apply(idx)
def length = vector.length
def splitter: SeqSplitter[T] = {
val pit = new ParVectorIterator(vector.startIndex, vector.endIndex) with SCPI
vector.initIterator(pit)
pit
}
override def seq: Vector[T] = vector
class ParVectorIterator(_start: Int, _end: Int) extends VectorIterator[T](_start, _end) with ParIterator {
self: SCPI =>
def remaining: Int = remainingElementCount
def dup: SeqSplitter[T] = (new ParVector(remainingVector)).splitter
def split: Seq[ParVectorIterator] = {
val rem = remaining
if (rem >= 2) psplit(rem / 2, rem - rem / 2)
else Seq(this)
}
def psplit(sizes: Int*): Seq[ParVectorIterator] = {
var remvector = remainingVector
val splitted = new ArrayBuffer[Vector[T]]
for (sz <- sizes) {
splitted += remvector.take(sz)
remvector = remvector.drop(sz)
}
splitted.map(v => new ParVector(v).splitter.asInstanceOf[ParVectorIterator])
}
}
}
/** $factoryInfo
* @define Coll immutable.ParVector
* @define coll immutable parallel vector
*/
object ParVector extends ParFactory[ParVector] {
implicit def canBuildFrom[T]: CanCombineFrom[Coll, T, ParVector[T]] =
new GenericCanCombineFrom[T]
def newBuilder[T]: Combiner[T, ParVector[T]] = newCombiner[T]
def newCombiner[T]: Combiner[T, ParVector[T]] = new LazyParVectorCombiner[T] // was: with EPC[T, ParVector[T]]
}
private[immutable] class LazyParVectorCombiner[T] extends Combiner[T, ParVector[T]] {
//self: EnvironmentPassingCombiner[T, ParVector[T]] =>
var sz = 0
val vectors = new ArrayBuffer[VectorBuilder[T]] += new VectorBuilder[T]
def size: Int = sz
def +=(elem: T): this.type = {
vectors.last += elem
sz += 1
this
}
def clear = {
vectors.clear
vectors += new VectorBuilder[T]
sz = 0
}
def result: ParVector[T] = {
val rvb = new VectorBuilder[T]
for (vb <- vectors) {
rvb ++= vb.result
}
new ParVector(rvb.result)
}
def combine[U <: T, NewTo >: ParVector[T]](other: Combiner[U, NewTo]) = if (other eq this) this else {
val that = other.asInstanceOf[LazyParVectorCombiner[T]]
sz += that.sz
vectors ++= that.vectors
this
}
}
|