From 83c584026d593b6806e1107d645606b9498c05d6 Mon Sep 17 00:00:00 2001 From: Aleksandar Prokopec Date: Wed, 15 Feb 2012 10:42:29 +0100 Subject: Add `dup` method to ParCtrie iterators. --- src/library/scala/collection/mutable/Ctrie.scala | 23 ++++++++++++++++++++-- .../collection/parallel/mutable/ParCtrie.scala | 7 ++++++- test/files/run/ctries/iterator.scala | 10 ++++++++++ 3 files changed, 37 insertions(+), 3 deletions(-) diff --git a/src/library/scala/collection/mutable/Ctrie.scala b/src/library/scala/collection/mutable/Ctrie.scala index 6ed3a516c4..dbd2129f0c 100644 --- a/src/library/scala/collection/mutable/Ctrie.scala +++ b/src/library/scala/collection/mutable/Ctrie.scala @@ -852,7 +852,7 @@ object Ctrie extends MutableMapFactory[Ctrie] { } -private[collection] class CtrieIterator[K, V](var level: Int, ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] { +private[collection] class CtrieIterator[K, V](var level: Int, private var ct: Ctrie[K, V], mustInit: Boolean = true) extends Iterator[(K, V)] { var stack = new Array[Array[BasicNode]](7) var stackpos = new Array[Int](7) var depth = -1 @@ -920,6 +920,25 @@ private[collection] class CtrieIterator[K, V](var level: Int, ct: Ctrie[K, V], m protected def newIterator(_lev: Int, _ct: Ctrie[K, V], _mustInit: Boolean) = new CtrieIterator[K, V](_lev, _ct, _mustInit) + protected def dupTo(it: CtrieIterator[K, V]) = { + it.level = this.level + it.ct = this.ct + it.depth = this.depth + it.current = this.current + + // these need a deep copy + Array.copy(this.stack, 0, it.stack, 0, 7) + Array.copy(this.stackpos, 0, it.stackpos, 0, 7) + + // this one needs to be evaluated + if (this.subiter == null) it.subiter = null + else { + val lst = this.subiter.toList + this.subiter = lst.iterator + it.subiter = lst.iterator + } + } + /** Returns a sequence of iterators over subsets of this iterator. * It's used to ease the implementation of splitters for a parallel version of the Ctrie. */ @@ -955,7 +974,7 @@ private[collection] class CtrieIterator[K, V](var level: Int, ct: Ctrie[K, V], m Seq(this) } - private def print { + def printDebug { println("ctrie iterator") println(stackpos.mkString(",")) println("depth: " + depth) diff --git a/src/library/scala/collection/parallel/mutable/ParCtrie.scala b/src/library/scala/collection/parallel/mutable/ParCtrie.scala index 86624500fd..37add60df9 100644 --- a/src/library/scala/collection/parallel/mutable/ParCtrie.scala +++ b/src/library/scala/collection/parallel/mutable/ParCtrie.scala @@ -92,7 +92,12 @@ extends CtrieIterator[K, V](lev, ct, mustInit) level < maxsplits } - def dup = null // TODO necessary for views + def dup = { + val it = newIterator(0, ct, false) + dupTo(it) + it.iterated = this.iterated + it + } override def next() = { iterated += 1 diff --git a/test/files/run/ctries/iterator.scala b/test/files/run/ctries/iterator.scala index 4bbf9009f0..85a6ab7623 100644 --- a/test/files/run/ctries/iterator.scala +++ b/test/files/run/ctries/iterator.scala @@ -274,6 +274,16 @@ object IteratorSpec extends Spec { while (it.hasNext) it.next() } + "be duplicated" in { + val sz = 50 + val ct = collection.parallel.mutable.ParCtrie((0 until sz) zip (0 until sz): _*) + val it = ct.splitter + for (_ <- 0 until (sz / 2)) it.next() + val dupit = it.dup + + it.toList shouldEqual dupit.toList + } + } } -- cgit v1.2.3