summaryrefslogtreecommitdiff
path: root/src/library/scala/collection/immutable/Stream.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2012-10-29 17:17:43 -0700
committerPaul Phillips <paulp@improving.org>2012-11-01 05:04:53 -0700
commit8a537b7d7da03833946a6a2f4461da2080363c88 (patch)
tree50d2a05eb55cd8b7f8f56f09260ddebf55f16f8f /src/library/scala/collection/immutable/Stream.scala
parente660b58f795a9ad7825398b5831e4011b652cffb (diff)
downloadscala-8a537b7d7da03833946a6a2f4461da2080363c88.tar.gz
scala-8a537b7d7da03833946a6a2f4461da2080363c88.tar.bz2
scala-8a537b7d7da03833946a6a2f4461da2080363c88.zip
Fix SI-6584, Stream#distinct uses too much memory.
Nesting recursive calls in Stream is always a dicey business.
Diffstat (limited to 'src/library/scala/collection/immutable/Stream.scala')
-rw-r--r--src/library/scala/collection/immutable/Stream.scala13
1 files changed, 10 insertions, 3 deletions
diff --git a/src/library/scala/collection/immutable/Stream.scala b/src/library/scala/collection/immutable/Stream.scala
index 461a375317..78c4d76eda 100644
--- a/src/library/scala/collection/immutable/Stream.scala
+++ b/src/library/scala/collection/immutable/Stream.scala
@@ -841,9 +841,16 @@ self =>
* // produces: "1, 2, 3, 4, 5, 6"
* }}}
*/
- override def distinct: Stream[A] =
- if (isEmpty) this
- else cons(head, tail.filter(head != _).distinct)
+ override def distinct: Stream[A] = {
+ // This should use max memory proportional to N, whereas
+ // recursively calling distinct on the tail is N^2.
+ def loop(seen: Set[A], rest: Stream[A]): Stream[A] = {
+ if (rest.isEmpty) rest
+ else if (seen(rest.head)) loop(seen, rest.tail)
+ else cons(rest.head, loop(seen + rest.head, rest.tail))
+ }
+ loop(Set(), this)
+ }
/** Returns a new sequence of given length containing the elements of this
* sequence followed by zero or more occurrences of given elements.