1
1
package dotty .tools .dotc .util
2
2
3
- import collection .mutable . ListBuffer
3
+ import collection .mutable
4
4
5
5
/** A simple linked set with `eq` as the comparison, optimized for small sets.
6
6
* It has linear complexity for `contains`, `+`, and `-`.
@@ -15,10 +15,13 @@ abstract class SimpleIdentitySet[+Elem <: AnyRef] {
15
15
def exists [E >: Elem <: AnyRef ](p : E => Boolean ): Boolean
16
16
def /: [A , E >: Elem <: AnyRef ](z : A )(f : (A , E ) => A ): A
17
17
def toList : List [Elem ]
18
- final def ++ [E >: Elem <: AnyRef ](that : SimpleIdentitySet [E ]): SimpleIdentitySet [E ] =
18
+ def ++ [E >: Elem <: AnyRef ](that : SimpleIdentitySet [E ]): SimpleIdentitySet [E ] = {
19
+ if (this .size == 0 ) that
20
+ else if (that.size == 0 ) this
21
+ else concat(that)
22
+ }
23
+ protected def concat [E >: Elem <: AnyRef ](that : SimpleIdentitySet [E ]): SimpleIdentitySet [E ] =
19
24
((this : SimpleIdentitySet [E ]) /: that)(_ + _)
20
- final def -- [E >: Elem <: AnyRef ](that : SimpleIdentitySet [E ]): SimpleIdentitySet [Elem ] =
21
- (this /: that)(_ - _)
22
25
override def toString : String = toList.mkString(" (" , " , " , " )" )
23
26
}
24
27
@@ -96,7 +99,7 @@ object SimpleIdentitySet {
96
99
def toList = x0.asInstanceOf [Elem ] :: x1.asInstanceOf [Elem ] :: x2.asInstanceOf [Elem ] :: Nil
97
100
}
98
101
99
- private class SetN [+ Elem <: AnyRef ](xs : Array [AnyRef ]) extends SimpleIdentitySet [Elem ] {
102
+ private class SetN [+ Elem <: AnyRef ](val xs : Array [AnyRef ]) extends SimpleIdentitySet [Elem ] {
100
103
def size = xs.length
101
104
def + [E >: Elem <: AnyRef ](x : E ): SimpleIdentitySet [E ] =
102
105
if (contains(x)) this
@@ -136,9 +139,37 @@ object SimpleIdentitySet {
136
139
def /: [A , E >: Elem <: AnyRef ](z : A )(f : (A , E ) => A ): A =
137
140
(z /: xs.asInstanceOf [Array [E ]])(f)
138
141
def toList : List [Elem ] = {
139
- val buf = new ListBuffer [Elem ]
142
+ val buf = new mutable. ListBuffer [Elem ]
140
143
foreach(buf += _)
141
144
buf.toList
142
145
}
146
+ override def concat [E >: Elem <: AnyRef ](that : SimpleIdentitySet [E ]): SimpleIdentitySet [E ] =
147
+ that match {
148
+ case that : SetN [_] =>
149
+ var toAdd : mutable.ArrayBuffer [AnyRef ] = null
150
+ var i = 0
151
+ val limit = that.xs.length
152
+ while (i < limit) {
153
+ val elem = that.xs(i)
154
+ if (! contains(elem)) {
155
+ if (toAdd == null ) toAdd = new mutable.ArrayBuffer
156
+ toAdd += elem
157
+ }
158
+ i += 1
159
+ }
160
+ if (toAdd == null ) this
161
+ else {
162
+ val numAdded = toAdd.size
163
+ val xs1 = new Array [AnyRef ](size + numAdded)
164
+ System .arraycopy(xs, 0 , xs1, 0 , size)
165
+ var i = 0
166
+ while (i < numAdded) {
167
+ xs1(i + size) = toAdd(i)
168
+ i += 1
169
+ }
170
+ new SetN [E ](xs1)
171
+ }
172
+ case _ => super .concat(that)
173
+ }
143
174
}
144
175
}
0 commit comments