Skip to content

Commit 0ea1710

Browse files
committed
Specialize SimpleIdentitySet with 3 elements
1 parent 868f8e1 commit 0ea1710

File tree

1 file changed

+31
-12
lines changed

1 file changed

+31
-12
lines changed

compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala

Lines changed: 31 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ object SimpleIdentitySet {
3737
private class Set1[+Elem <: AnyRef](x0: AnyRef) extends SimpleIdentitySet[Elem] {
3838
def size = 1
3939
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] =
40-
new Set2[E](x0, x)
40+
if (contains(x)) this else new Set2[E](x0, x)
4141
def - [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[Elem] =
4242
if (x `eq` x0) empty else this
4343
def contains[E >: Elem <: AnyRef](x: E): Boolean = x `eq` x0
@@ -46,13 +46,8 @@ object SimpleIdentitySet {
4646

4747
private class Set2[+Elem <: AnyRef](x0: AnyRef, x1: AnyRef) extends SimpleIdentitySet[Elem] {
4848
def size = 2
49-
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] = {
50-
val xs = new Array[AnyRef](3)
51-
xs(0) = x0
52-
xs(1) = x1
53-
xs(2) = x
54-
new SetN[E](xs)
55-
}
49+
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] =
50+
if (contains(x)) this else new Set3(x0, x1, x)
5651
def - [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[Elem] =
5752
if (x `eq` x0) new Set1(x1)
5853
else if (x `eq` x1) new Set1(x0)
@@ -61,6 +56,29 @@ object SimpleIdentitySet {
6156
def foreach(f: Elem => Unit): Unit = { f(x0.asInstanceOf[Elem]); f(x1.asInstanceOf[Elem]) }
6257
}
6358

59+
private class Set3[+Elem <: AnyRef](x0: AnyRef, x1: AnyRef, x2: AnyRef) extends SimpleIdentitySet[Elem] {
60+
def size = 3
61+
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] =
62+
if (contains(this)) this
63+
else {
64+
val xs = new Array[AnyRef](4)
65+
xs(0) = x0
66+
xs(1) = x1
67+
xs(2) = x2
68+
xs(3) = x
69+
new SetN[E](xs)
70+
}
71+
def - [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[Elem] =
72+
if (x `eq` x0) new Set2(x1, x2)
73+
else if (x `eq` x1) new Set2(x0, x2)
74+
else if (x `eq` x2) new Set2(x0, x1)
75+
else this
76+
def contains[E >: Elem <: AnyRef](x: E): Boolean = (x `eq` x0) || (x `eq` x1) || (x `eq` x2)
77+
def foreach(f: Elem => Unit): Unit = {
78+
f(x0.asInstanceOf[Elem]); f(x1.asInstanceOf[Elem]); f(x2.asInstanceOf[Elem])
79+
}
80+
}
81+
6482
private class SetN[+Elem <: AnyRef](xs: Array[AnyRef]) extends SimpleIdentitySet[Elem] {
6583
def size = xs.length
6684
def + [E >: Elem <: AnyRef](x: E): SimpleIdentitySet[E] = {
@@ -73,10 +91,11 @@ object SimpleIdentitySet {
7391
var i = 0
7492
while (i < size && (xs(i) `ne` x)) i += 1
7593
if (i == size) this
76-
else if (size == 3)
77-
if (i == 0) new Set2(xs(1), xs(2))
78-
else if (i == 1) new Set2(xs(0), xs(2))
79-
else new Set2(xs(0), xs(1))
94+
else if (size == 4)
95+
if (i == 0) new Set3(xs(1), xs(2), xs(3))
96+
else if (i == 1) new Set3(xs(0), xs(2), xs(3))
97+
else if (i == 2) new Set3(xs(0), xs(1), xs(3))
98+
else new Set3(xs(0), xs(1), xs(2))
8099
else {
81100
val xs1 = new Array[AnyRef](size - 1)
82101
Array.copy(xs, 0, xs1, 0, i)

0 commit comments

Comments
 (0)