1
- /** Taken from the original implementation of WeakHashSet in scala-reflect
1
+ /** Adapted from the original implementation of WeakHashSet in scala-reflect
2
2
*/
3
3
package dotty .tools .dotc .util
4
4
5
5
import java .lang .ref .{ReferenceQueue , WeakReference }
6
6
7
- import scala .annotation .tailrec
7
+ import scala .annotation .{ constructorOnly , tailrec }
8
8
import scala .collection .mutable
9
9
10
10
/**
@@ -17,7 +17,7 @@ import scala.collection.mutable
17
17
* This set implementation is not in general thread safe without external concurrency control. However it behaves
18
18
* properly when GC concurrently collects elements in this set.
19
19
*/
20
- final class WeakHashSet [A <: AnyRef ](initialCapacity : Int , loadFactor : Double ) extends mutable. Set [A ] {
20
+ final class WeakHashSet [A <: AnyRef ](initialCapacity : Int , loadFactor : Double ) extends MutableSet [A ] {
21
21
22
22
import WeakHashSet ._
23
23
@@ -61,8 +61,6 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
61
61
62
62
private def computeThreshold : Int = (table.size * loadFactor).ceil.toInt
63
63
64
- def get (elem : A ): Option [A ] = Option (findEntry(elem))
65
-
66
64
/**
67
65
* find the bucket associated with an element's hash code
68
66
*/
@@ -145,10 +143,7 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
145
143
tableLoop(0 )
146
144
}
147
145
148
- def contains (elem : A ): Boolean = findEntry(elem) ne null
149
-
150
- // from scala.reflect.internal.Set, find an element or null if it isn't contained
151
- def findEntry (elem : A ): A = elem match {
146
+ def lookup (elem : A ): A | Null = elem match {
152
147
case null => throw new NullPointerException (" WeakHashSet cannot hold nulls" )
153
148
case _ =>
154
149
removeStaleEntries()
@@ -160,14 +155,14 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
160
155
case null => null .asInstanceOf [A ]
161
156
case _ =>
162
157
val entryElem = entry.get
163
- if (elem.equals( entryElem)) entryElem
158
+ if (isEqual(elem, entryElem)) entryElem
164
159
else linkedListLoop(entry.tail)
165
160
}
166
161
167
162
linkedListLoop(table(bucket))
168
163
}
169
- // add an element to this set unless it's already in there and return the element
170
- def findEntryOrUpdate (elem : A ): A = elem match {
164
+
165
+ def put (elem : A ): A = elem match {
171
166
case null => throw new NullPointerException (" WeakHashSet cannot hold nulls" )
172
167
case _ =>
173
168
removeStaleEntries()
@@ -187,42 +182,17 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
187
182
case null => add()
188
183
case _ =>
189
184
val entryElem = entry.get
190
- if (elem.equals( entryElem)) entryElem
185
+ if (isEqual(elem, entryElem)) entryElem
191
186
else linkedListLoop(entry.tail)
192
187
}
193
188
194
189
linkedListLoop(oldHead)
195
190
}
196
191
197
- // add an element to this set unless it's already in there and return this set
198
- override def addOne (elem : A ): this .type = elem match {
199
- case null => throw new NullPointerException (" WeakHashSet cannot hold nulls" )
200
- case _ =>
201
- removeStaleEntries()
202
- val hash = elem.hashCode
203
- val bucket = bucketFor(hash)
204
- val oldHead = table(bucket)
205
-
206
- def add (): Unit = {
207
- table(bucket) = new Entry (elem, hash, oldHead, queue)
208
- count += 1
209
- if (count > threshold) resize()
210
- }
211
-
212
- @ tailrec
213
- def linkedListLoop (entry : Entry [A ]): Unit = entry match {
214
- case null => add()
215
- case _ if elem.equals(entry.get) => ()
216
- case _ => linkedListLoop(entry.tail)
217
- }
218
-
219
- linkedListLoop(oldHead)
220
- this
221
- }
192
+ def += (elem : A ): Unit = put(elem)
222
193
223
- // remove an element from this set and return this set
224
- override def subtractOne (elem : A ): this .type = elem match {
225
- case null => this
194
+ def -= (elem : A ): Unit = elem match {
195
+ case null =>
226
196
case _ =>
227
197
removeStaleEntries()
228
198
val bucket = bucketFor(elem.hashCode)
@@ -232,16 +202,14 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
232
202
@ tailrec
233
203
def linkedListLoop (prevEntry : Entry [A ], entry : Entry [A ]): Unit = entry match {
234
204
case null => ()
235
- case _ if elem.equals( entry.get) => remove(bucket, prevEntry, entry)
205
+ case _ if isEqual(elem, entry.get) => remove(bucket, prevEntry, entry)
236
206
case _ => linkedListLoop(entry, entry.tail)
237
207
}
238
208
239
209
linkedListLoop(null , table(bucket))
240
- this
241
210
}
242
211
243
- // empty this set
244
- override def clear (): Unit = {
212
+ def clear (): Unit = {
245
213
table = new Array [Entry [A ]](table.size)
246
214
threshold = computeThreshold
247
215
count = 0
@@ -251,21 +219,11 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
251
219
queueLoop()
252
220
}
253
221
254
- // true if this set is empty
255
- override def empty : This = new WeakHashSet [A ](initialCapacity, loadFactor)
256
-
257
- // the number of elements in this set
258
- override def size : Int = {
222
+ def size : Int = {
259
223
removeStaleEntries()
260
224
count
261
225
}
262
226
263
- override def isEmpty : Boolean = size == 0
264
- override def foreach [U ](f : A => U ): Unit = iterator foreach f
265
-
266
- // It has the `()` because iterator runs `removeStaleEntries()`
267
- override def toList (): List [A ] = iterator.toList
268
-
269
227
// Iterator over all the elements in this set in no particular order
270
228
override def iterator : Iterator [A ] = {
271
229
removeStaleEntries()
@@ -386,7 +344,7 @@ object WeakHashSet {
386
344
* A single entry in a WeakHashSet. It's a WeakReference plus a cached hash code and
387
345
* a link to the next Entry in the same bucket
388
346
*/
389
- private class Entry [A ](element : A , val hash : Int , var tail : Entry [A ], queue : ReferenceQueue [A ]) extends WeakReference [A ](element, queue)
347
+ private class Entry [A ](@ constructorOnly element : A , val hash : Int , var tail : Entry [A ], @ constructorOnly queue : ReferenceQueue [A ]) extends WeakReference [A ](element, queue)
390
348
391
349
private final val defaultInitialCapacity = 16
392
350
private final val defaultLoadFactor = .75
0 commit comments