From ecee7b75328ae1f856b5fa832ebad7fc9e42f64a Mon Sep 17 00:00:00 2001 From: Stefan Zeiger Date: Fri, 29 Jan 2016 17:28:16 +0100 Subject: SI-9623 Avoid unnecessary hasNext calls in JoinIterator & ConcatIterator MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- src/library/scala/collection/Iterator.scala | 51 +++++++++++++++++++++++++---- 1 file changed, 45 insertions(+), 6 deletions(-) (limited to 'src') diff --git a/src/library/scala/collection/Iterator.scala b/src/library/scala/collection/Iterator.scala index ed536f10a8..8d88b1c6b1 100644 --- a/src/library/scala/collection/Iterator.scala +++ b/src/library/scala/collection/Iterator.scala @@ -10,7 +10,7 @@ package scala package collection import mutable.ArrayBuffer -import scala.annotation.migration +import scala.annotation.{tailrec, migration} import immutable.Stream import scala.collection.generic.CanBuildFrom import scala.annotation.unchecked.{ uncheckedVariance => uV } @@ -168,8 +168,10 @@ object Iterator { private[scala] final class ConcatIterator[+A](private[this] var current: Iterator[A], initial: Vector[() => Iterator[A]]) extends Iterator[A] { @deprecated def this(initial: Vector[() => Iterator[A]]) = this(Iterator.empty, initial) // for binary compatibility private[this] var queue: Vector[() => Iterator[A]] = initial + private[this] var currentHasNextChecked = false // Advance current to the next non-empty iterator // current is set to null when all iterators are exhausted + @tailrec private[this] def advance(): Boolean = { if (queue.isEmpty) { current = null @@ -178,20 +180,57 @@ object Iterator { else { current = queue.head() queue = queue.tail - current.hasNext || advance() + if (current.hasNext) { + currentHasNextChecked = true + true + } else advance() } } - def hasNext = (current ne null) && (current.hasNext || advance()) - def next() = if (hasNext) current.next else Iterator.empty.next + def hasNext = + if (currentHasNextChecked) true + else if (current eq null) false + else if (current.hasNext) { + currentHasNextChecked = true + true + } else advance() + def next() = + if (hasNext) { + currentHasNextChecked = false + current.next() + } else Iterator.empty.next() override def ++[B >: A](that: => GenTraversableOnce[B]): Iterator[B] = new ConcatIterator(current, queue :+ (() => that.toIterator)) } private[scala] final class JoinIterator[+A](lhs: Iterator[A], that: => GenTraversableOnce[A]) extends Iterator[A] { + private[this] var state = 0 // 0: lhs not checked, 1: lhs has next, 2: switched to rhs private[this] lazy val rhs: Iterator[A] = that.toIterator - def hasNext = lhs.hasNext || rhs.hasNext - def next = if (lhs.hasNext) lhs.next else rhs.next + def hasNext = state match { + case 0 => + if (lhs.hasNext) { + state = 1 + true + } else { + state = 2 + rhs.hasNext + } + case 1 => true + case _ => rhs.hasNext + } + def next() = state match { + case 0 => + if (lhs.hasNext) lhs.next() + else { + state = 2 + rhs.next() + } + case 1 => + state = 0 + lhs.next() + case _ => + rhs.next() + } override def ++[B >: A](that: => GenTraversableOnce[B]) = new ConcatIterator(this, Vector(() => that.toIterator)) -- cgit v1.2.3 From 310f4d0537a47cfd177cf290479fadc54d7a27a6 Mon Sep 17 00:00:00 2001 From: Seth Tisue Date: Wed, 3 Feb 2016 14:20:02 -0500 Subject: bump copyright year to 2016 --- build.xml | 2 +- doc/LICENSE.md | 4 ++-- doc/License.rtf | 4 ++-- project/VersionUtil.scala | 2 +- src/library/scala/util/Properties.scala | 2 +- src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala | 2 +- src/scalap/decoder.properties | 2 +- 7 files changed, 9 insertions(+), 9 deletions(-) (limited to 'src') diff --git a/build.xml b/build.xml index 129d5982d9..8cf68b668c 100644 --- a/build.xml +++ b/build.xml @@ -184,7 +184,7 @@ TODO: - + diff --git a/doc/LICENSE.md b/doc/LICENSE.md index 55e82f64ba..b16711896c 100644 --- a/doc/LICENSE.md +++ b/doc/LICENSE.md @@ -2,9 +2,9 @@ Scala is licensed under the [BSD 3-Clause License](http://opensource.org/license ## Scala License -Copyright (c) 2002-2015 EPFL +Copyright (c) 2002-2016 EPFL -Copyright (c) 2011-2015 Typesafe, Inc. +Copyright (c) 2011-2016 Typesafe, Inc. All rights reserved. diff --git a/doc/License.rtf b/doc/License.rtf index c475bda3ef..21beba0e9f 100644 --- a/doc/License.rtf +++ b/doc/License.rtf @@ -10,8 +10,8 @@ \fs48 Scala License \fs40 \ -\fs26 Copyright (c) 2002-2015 EPFL\ -Copyright (c) 2011-2015 Typesafe, Inc.\ +\fs26 Copyright (c) 2002-2016 EPFL\ +Copyright (c) 2011-2016 Typesafe, Inc.\ All rights reserved.\ \ Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\ diff --git a/project/VersionUtil.scala b/project/VersionUtil.scala index f237c35c68..fab22e66d4 100644 --- a/project/VersionUtil.scala +++ b/project/VersionUtil.scala @@ -19,7 +19,7 @@ object VersionUtil { ) lazy val generatePropertiesFileSettings = Seq[Setting[_]]( - copyrightString := "Copyright 2002-2015, LAMP/EPFL", + copyrightString := "Copyright 2002-2016, LAMP/EPFL", resourceGenerators in Compile += generateVersionPropertiesFile.map(file => Seq(file)).taskValue, generateVersionPropertiesFile := generateVersionPropertiesFileImpl.value ) diff --git a/src/library/scala/util/Properties.scala b/src/library/scala/util/Properties.scala index d4a5e2f0e8..7ea597eac9 100644 --- a/src/library/scala/util/Properties.scala +++ b/src/library/scala/util/Properties.scala @@ -105,7 +105,7 @@ private[scala] trait PropertiesTrait { * or "version (unknown)" if it cannot be determined. */ val versionString = "version " + scalaPropOrElse("version.number", "(unknown)") - val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2015, LAMP/EPFL") + val copyrightString = scalaPropOrElse("copyright.string", "Copyright 2002-2016, LAMP/EPFL") /** This is the encoding to use reading in source files, overridden with -encoding. * Note that it uses "prop" i.e. looks in the scala jar, not the system properties. diff --git a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala index 1b3cfa236f..9daca10e63 100644 --- a/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala +++ b/src/scaladoc/scala/tools/nsc/doc/html/page/Template.scala @@ -280,7 +280,7 @@ class Template(universe: doc.Universe, generator: DiagramGenerator, tpl: DocTemp { if (Set("epfl", "EPFL").contains(tpl.universe.settings.docfooter.value)) - + else } diff --git a/src/scalap/decoder.properties b/src/scalap/decoder.properties index 333f6ce715..9bb8d130ea 100644 --- a/src/scalap/decoder.properties +++ b/src/scalap/decoder.properties @@ -1,2 +1,2 @@ version.number=2.0.1 -copyright.string=(c) 2002-2015 LAMP/EPFL +copyright.string=(c) 2002-2016 LAMP/EPFL -- cgit v1.2.3 From 504ac0d635d36e94dc6241a43cfba88b36c9a889 Mon Sep 17 00:00:00 2001 From: Jason Zaugg Date: Sun, 7 Feb 2016 22:27:29 +1000 Subject: Enable IntellIJ smarts while editing the build Even though our build can't be imported into IntelliJ automatically, we don't need to live in the dark ages of red squigglies when editing build.sbt. This commit hand-crafts the module defintion for the project, which has SBT and its dependendencies on the classpath. A screenshot of the code assist is worth the thousand expletives I uttered while writing the pictured code without this facility: https://www.dropbox.com/s/6mxv0iwxkhvnor7/Screenshot%202016-02-07%2022.09.12.png?dl=0 To download the sources for the SBT JARs that are referenced herein, run sbt> reload plugins sbt> updateClassifiers --- src/intellij/scala-build.iml.SAMPLE | 109 ++++++++++++++++++++++++++++++++++++ src/intellij/scala.ipr.SAMPLE | 3 +- 2 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 src/intellij/scala-build.iml.SAMPLE (limited to 'src') diff --git a/src/intellij/scala-build.iml.SAMPLE b/src/intellij/scala-build.iml.SAMPLE new file mode 100644 index 0000000000..bf722e464f --- /dev/null +++ b/src/intellij/scala-build.iml.SAMPLE @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/intellij/scala.ipr.SAMPLE b/src/intellij/scala.ipr.SAMPLE index 47ac2be188..420f559097 100644 --- a/src/intellij/scala.ipr.SAMPLE +++ b/src/intellij/scala.ipr.SAMPLE @@ -46,6 +46,7 @@ + @@ -125,4 +126,4 @@ - \ No newline at end of file + -- cgit v1.2.3