diff options
author | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-06-03 13:17:13 +0200 |
---|---|---|
committer | Adriaan Moors <adriaan.moors@typesafe.com> | 2014-06-03 13:17:13 +0200 |
commit | 1b280b32199dec573b9c1a7f3bd8f354c01e86c5 (patch) | |
tree | c376437e2d1681058f1703445748b30561ea380e | |
parent | d17c098f35a8612496a732876663435a7f3184da (diff) | |
parent | d4f664c98364858c319b599caa1cdbb68030440a (diff) | |
download | scala-1b280b32199dec573b9c1a7f3bd8f354c01e86c5.tar.gz scala-1b280b32199dec573b9c1a7f3bd8f354c01e86c5.tar.bz2 scala-1b280b32199dec573b9c1a7f3bd8f354c01e86c5.zip |
Merge pull request #3795 from som-snytt/issue/8475
SI-8475 GroupedIterator is also lazy when padded
-rw-r--r-- | src/library/scala/collection/Iterator.scala | 13 | ||||
-rw-r--r-- | test/junit/scala/collection/IteratorTest.scala | 8 |
2 files changed, 15 insertions, 6 deletions
diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index e321a6adba..f6f46e158f 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -922,6 +922,9 @@ trait Iterator[+A] extends TraversableOnce[A] { /** For reasons which remain to be determined, calling * self.take(n).toSeq cause an infinite loop, so we have * a slight variation on take for local usage. + * NB: self.take.toSeq is slice.toStream, lazily built on self, + * so a subsequent self.hasNext would not test self after the + * group was consumed. */ private def takeDestructively(size: Int): Seq[A] = { val buf = new ArrayBuffer[A] @@ -945,12 +948,10 @@ trait Iterator[+A] extends TraversableOnce[A] { // so the rest of the code can be oblivious val xs: Seq[B] = { val res = takeDestructively(count) - // extra checks so we don't calculate length unless there's reason - if (pad.isDefined && !self.hasNext) { - val shortBy = count - res.length - if (shortBy > 0) res ++ padding(shortBy) else res - } - else res + // was: extra checks so we don't calculate length unless there's reason + // but since we took the group eagerly, just use the fast length + val shortBy = count - res.length + if (shortBy > 0 && pad.isDefined) res ++ padding(shortBy) else res } lazy val len = xs.length lazy val incomplete = len < count diff --git a/test/junit/scala/collection/IteratorTest.scala b/test/junit/scala/collection/IteratorTest.scala index cb7cbb40bc..b7a9805c9f 100644 --- a/test/junit/scala/collection/IteratorTest.scala +++ b/test/junit/scala/collection/IteratorTest.scala @@ -17,4 +17,12 @@ class IteratorTest { slidingIt.next assertEquals("Counter should be one, that means we didn't look further than needed", 1, counter) } + + @Test def groupedIteratorIsLazyWhenPadded(): Unit = { + var counter = 0 + def it = new Iterator[Int] { var i = 0 ; def hasNext = { counter = i; true } ; def next = { i += 1; i } } + val slidingIt = it sliding 2 withPadding -1 + slidingIt.next + assertEquals("Counter should be one, that means we didn't look further than needed", 1, counter) + } } |