Skip to content

Instantly share code, notes, and snippets.

@amir343
Created October 18, 2011 09:37
Show Gist options
  • Save amir343/1295051 to your computer and use it in GitHub Desktop.
Save amir343/1295051 to your computer and use it in GitHub Desktop.
Parallel Experiment part two
protected[this] override def newCombiner: Combiner[Char, ParallelString] = new ParallelStringCombiner
class ParallelStringCombiner extends Combiner[Char, ParallelString] {
var sz = 0
val chunks = new ArrayBuffer[StringBuilder] += new StringBuilder
var lastChunk = chunks.last
def size: Int = sz
def +=(elem: Char): this.type = {
lastChunk += elem
sz += 1
this
}
def clear = {
chunks.clear
chunks += new StringBuilder
lastChunk = chunks.last
sz = 0
}
def result: ParallelString = {
val rsb = new StringBuilder
for (sb <- chunks) rsb.append(sb)
new ParallelString(rsb.toString)
}
def combine[U <: Char, NewTo >: ParallelString](other: Combiner[U, NewTo]) =
if (other eq this) this
else {
val that = other.asInstanceOf[ParallelStringCombiner]
sz += that.sz
chunks ++= that.chunks
lastChunk = chunks.last
this
}
}
class ParallelStringSplitter(private val str:String, private var from:Int, private val to:Int)
extends Splitter[Char] with ParIterator {
self:SignalContextPassingIterator[ParallelStringSplitter] =>
final def hasNext = from < to
final def next = {
val c = str.charAt(from)
from += 1
c
}
def remaining = to - from
def dup = new ParallelStringSplitter(str, from, to) with SignalContextPassingIterator[ParallelStringSplitter]
def split = {
val rem = remaining
if (rem >= 2) psplit(rem / 2, rem - rem / 2)
else Seq(this)
}
def psplit(sizes: Int*): Seq[ParIterator] = {
val splitted = new ArrayBuffer[ParallelStringSplitter]
for (size <- sizes) {
val next = (from + size) min to
splitted += new ParallelStringSplitter(str, from, next) with SignalContextPassingIterator[ParallelStringSplitter]
from = next
}
splitted
}
}
class ParallelString(val str:String) extends immutable.ParSeq[Char] {
def apply(i:Int) = str.charAt(i)
def length = str.length
def seq = new collection.immutable.WrappedString(str)
def splitter = new ParallelStringSplitter(str, 0, str.length) with SignalContextPassingIterator[ParallelStringSplitter]
}
class ParallelString(val str:String) extends immutable.ParSeq[Char]
with ParSeqLike[Char, ParallelString, collection.immutable.WrappedString]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment