summaryrefslogtreecommitdiff
path: root/test/junit/scala/collection/IteratorTest.scala
diff options
context:
space:
mode:
authorStefan Zeiger <szeiger@novocode.com>2016-01-29 17:28:16 +0100
committerStefan Zeiger <szeiger@novocode.com>2016-02-01 14:41:17 +0100
commitecee7b75328ae1f856b5fa832ebad7fc9e42f64a (patch)
treed49c0a1e1d2f1b546d374e8888b431f0e069bf86 /test/junit/scala/collection/IteratorTest.scala
parentea154faf467ae27c221ba0dcd7235e1e55673c51 (diff)
downloadscala-ecee7b75328ae1f856b5fa832ebad7fc9e42f64a.tar.gz
scala-ecee7b75328ae1f856b5fa832ebad7fc9e42f64a.tar.bz2
scala-ecee7b75328ae1f856b5fa832ebad7fc9e42f64a.zip
SI-9623 Avoid unnecessary hasNext calls in JoinIterator & ConcatIterator
These iterator implementations are used to concatenate two (JoinIterator) or more (ConcatIterator) other iterators with `++`. They used to perform many unnecessary calls to the child iterators’ `hasNext` methods. This improved state machine-based implementation reduces that number to the bare minimum, i.e. iterating over concatenated iterators with `foreach` calls the children's `hasNext` methods a total of (number of children) + (number of elements) times, the same as when iterating over all children separately.
Diffstat (limited to 'test/junit/scala/collection/IteratorTest.scala')
-rw-r--r--test/junit/scala/collection/IteratorTest.scala28
1 files changed, 28 insertions, 0 deletions
diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala
index 1c1e50aed9..329c85127a 100644
--- a/test/junit/scala/collection/IteratorTest.scala
+++ b/test/junit/scala/collection/IteratorTest.scala
@@ -164,4 +164,32 @@ class IteratorTest {
assertEquals(1, y.next)
assertFalse(x.hasNext) // was true, after advancing underlying iterator
}
+ // SI-9623
+ @Test def noExcessiveHasNextInJoinIterator: Unit = {
+ var counter = 0
+ val exp = List(1,2,3,1,2,3)
+ def it: Iterator[Int] = new Iterator[Int] {
+ val parent = List(1,2,3).iterator
+ def next(): Int = parent.next
+ def hasNext: Boolean = { counter += 1; parent.hasNext }
+ }
+ // Iterate separately
+ val res = new mutable.ArrayBuffer[Int]
+ it.foreach(res += _)
+ it.foreach(res += _)
+ assertSameElements(exp, res)
+ assertEquals(8, counter)
+ // JoinIterator
+ counter = 0
+ res.clear
+ (it ++ it).foreach(res += _)
+ assertSameElements(exp, res)
+ assertEquals(8, counter) // was 17
+ // ConcatIterator
+ counter = 0
+ res.clear
+ (Iterator.empty ++ it ++ it).foreach(res += _)
+ assertSameElements(exp, res)
+ assertEquals(8, counter) // was 14
+ }
}