Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit a10823d

Browse files
authored
Merge pull request #10248 from som-snytt/tweak/12316
Minor refactor in ListSet to foreground guards and add test
2 parents 0bd21e6 + e7f9194 commit a10823d

File tree

3 files changed

+26
-17
lines changed

3 files changed

+26
-17
lines changed

build.sbt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -691,7 +691,7 @@ lazy val junit = project.in(file("test") / "junit")
691691
(Test / forkOptions) := (Test / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value),
692692
(Test / testOnly / forkOptions) := (Test / testOnly / forkOptions).value.withWorkingDirectory((ThisBuild / baseDirectory).value),
693693
libraryDependencies ++= Seq(junitDep, junitInterfaceDep, jolDep),
694-
testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v"),
694+
testOptions += Tests.Argument(TestFrameworks.JUnit, "-a", "-v", "-s"),
695695
(Compile / unmanagedSourceDirectories) := Nil,
696696
(Test / unmanagedSourceDirectories) := List(baseDirectory.value),
697697
Test / headerSources := Nil,

src/library/scala/collection/immutable/ListSet.scala

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -82,18 +82,15 @@ sealed class ListSet[A] extends AbstractSet[A]
8282

8383
override def ++(xs: GenTraversableOnce[A]): ListSet[A] =
8484
xs match {
85-
// we want to avoid to use of iterator as it causes allocations
86-
// during reverseList
87-
case ls: ListSet[A] =>
88-
if (ls eq this) this
89-
else {
90-
val lsSize = ls.size
91-
if (lsSize == 0) this
92-
else if (isEmpty) ls
85+
case _: this.type => this
86+
case _ if xs.isEmpty => this
87+
// we want to avoid using iterator as it causes allocations during reverseList
88+
case ls: ListSet[A] =>
89+
if (isEmpty) ls
9390
else {
94-
@tailrec def skip(ls: ListSet[A], count: Int): ListSet[A] = {
91+
// optimize add non-empty ListSet
92+
@tailrec def skip(ls: ListSet[A], count: Int): ListSet[A] =
9593
if (count == 0) ls else skip(ls.next, count - 1)
96-
}
9794

9895
@tailrec def containsLimited(n: ListSet[A], e: A, end: ListSet[A]): Boolean =
9996
(n ne end) && (e == n.elem || containsLimited(n.next, e, end))
@@ -104,6 +101,7 @@ sealed class ListSet[A] extends AbstractSet[A]
104101
// We hope to get some structural sharing so find the tail of the
105102
// ListSet that are `eq` (or if there are not any then the ends of the lists),
106103
// and we optimise the add to only iterate until we reach the common end
104+
val lsSize = ls.size
107105
val thisSize = this.size
108106
val remaining = Math.min(thisSize, lsSize)
109107
var thisTail = skip(this, thisSize - remaining)
@@ -151,16 +149,13 @@ sealed class ListSet[A] extends AbstractSet[A]
151149
case 4 => pending3
152150
case _ => pending(pendingCount - 5)
153151
}
154-
val r = result
152+
val r = result
155153
result = new r.Node(elem)
156154
pendingCount -= 1
157155
}
158156
result
159157
}
160-
}
161-
case _ =>
162-
if (xs.isEmpty) this
163-
else (repr /: xs) (_ + _)
158+
case _ => xs.foldLeft(repr)(_ + _)
164159
}
165160

166161
def iterator: Iterator[A] = {

test/junit/scala/collection/immutable/ListSetTest.scala

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package scala.collection.immutable
22

3-
import org.junit.Assert._
3+
import org.junit.Assert.{fail => _, _}
44
import org.junit.Test
55
import org.junit.runner.RunWith
66
import org.junit.runners.JUnit4
77

8+
import scala.tools.testing.AssertUtil._
9+
810
@RunWith(classOf[JUnit4])
911
class ListSetTest {
1012

@@ -56,6 +58,11 @@ class ListSetTest {
5658
@Test
5759
def hasCorrectOrderAfterPlusPlus(): Unit = {
5860
val foo = ListSet(1)
61+
62+
assertSame(foo, foo ++ foo)
63+
assertSame(foo, foo ++ ListSet.empty)
64+
assertSame(foo, foo ++ Nil)
65+
5966
var bar = foo ++ ListSet()
6067
assertEquals(List(1), bar.iterator.toList)
6168

@@ -79,6 +86,13 @@ class ListSetTest {
7986

8087
bar = foo ++ ListSet(1, 2, 3, 4, 5, 6)
8188
assertEquals(List(1, 2, 3, 4, 5, 6), bar.iterator.toList)
89+
assertSameElements(List(1, 2, 3, 4, 5, 6), bar.iterator)
90+
}
91+
@Test
92+
def `t12316 ++ is correctly ordered`(): Unit = {
93+
// was: ListSet(1, 2, 3, 42, 43, 44, 29, 28, 27, 12, 11, 10)
94+
assertEquals(ListSet(1,2,3,42,43,44,10,11,12,27,28,29), ListSet(1,2,3,42,43,44) ++ ListSet(10,11,12,42,43,44,27,28,29))
95+
assertSameElements(List(1,2,3,42,43,44,10,11,12,27,28,29), ListSet(1,2,3,42,43,44) ++ ListSet(10,11,12,42,43,44,27,28,29))
8296
}
8397

8498
@Test

0 commit comments

Comments
 (0)