1- /** Taken from the original implementation of WeakHashSet in scala-reflect
1+ /** Adapted from the original implementation of WeakHashSet in scala-reflect
22 */
33package dotty .tools .dotc .util
44
55import java .lang .ref .{ReferenceQueue , WeakReference }
66
7- import scala .annotation .tailrec
7+ import scala .annotation .{ constructorOnly , tailrec }
88import scala .collection .mutable
99
1010/**
@@ -17,7 +17,7 @@ import scala.collection.mutable
1717 * This set implementation is not in general thread safe without external concurrency control. However it behaves
1818 * properly when GC concurrently collects elements in this set.
1919 */
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 ] {
2121
2222 import WeakHashSet ._
2323
@@ -61,8 +61,6 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
6161
6262 private def computeThreshold : Int = (table.size * loadFactor).ceil.toInt
6363
64- def get (elem : A ): Option [A ] = Option (findEntry(elem))
65-
6664 /**
6765 * find the bucket associated with an element's hash code
6866 */
@@ -86,6 +84,7 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
8684 * remove a single entry from a linked list in a given bucket
8785 */
8886 private def remove (bucket : Int , prevEntry : Entry [A ], entry : Entry [A ]): Unit = {
87+ Stats .record(statsItem(" remove" ))
8988 prevEntry match {
9089 case null => table(bucket) = entry.tail
9190 case _ => prevEntry.tail = entry.tail
@@ -122,6 +121,7 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
122121 * Double the size of the internal table
123122 */
124123 private def resize (): Unit = {
124+ Stats .record(statsItem(" resize" ))
125125 val oldTable = table
126126 table = new Array [Entry [A ]](oldTable.size * 2 )
127127 threshold = computeThreshold
@@ -145,12 +145,10 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
145145 tableLoop(0 )
146146 }
147147
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 {
148+ def lookup (elem : A ): A | Null = elem match {
152149 case null => throw new NullPointerException (" WeakHashSet cannot hold nulls" )
153150 case _ =>
151+ Stats .record(statsItem(" lookup" ))
154152 removeStaleEntries()
155153 val hash = elem.hashCode
156154 val bucket = bucketFor(hash)
@@ -166,10 +164,11 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
166164
167165 linkedListLoop(table(bucket))
168166 }
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 {
167+
168+ def put (elem : A ): A = elem match {
171169 case null => throw new NullPointerException (" WeakHashSet cannot hold nulls" )
172170 case _ =>
171+ Stats .record(statsItem(" put" ))
173172 removeStaleEntries()
174173 val hash = elem.hashCode
175174 val bucket = bucketFor(hash)
@@ -194,36 +193,12 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
194193 linkedListLoop(oldHead)
195194 }
196195
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- }
196+ def += (elem : A ): Unit = put(elem)
218197
219- linkedListLoop(oldHead)
220- this
221- }
222-
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
198+ def -= (elem : A ): Unit = elem match {
199+ case null =>
226200 case _ =>
201+ Stats .record(statsItem(" -=" ))
227202 removeStaleEntries()
228203 val bucket = bucketFor(elem.hashCode)
229204
@@ -237,11 +212,9 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
237212 }
238213
239214 linkedListLoop(null , table(bucket))
240- this
241215 }
242216
243- // empty this set
244- override def clear (): Unit = {
217+ def clear (): Unit = {
245218 table = new Array [Entry [A ]](table.size)
246219 threshold = computeThreshold
247220 count = 0
@@ -251,21 +224,11 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
251224 queueLoop()
252225 }
253226
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 = {
227+ def size : Int = {
259228 removeStaleEntries()
260229 count
261230 }
262231
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-
269232 // Iterator over all the elements in this set in no particular order
270233 override def iterator : Iterator [A ] = {
271234 removeStaleEntries()
@@ -318,6 +281,12 @@ final class WeakHashSet[A <: AnyRef](initialCapacity: Int, loadFactor: Double) e
318281 }
319282 }
320283
284+ protected def statsItem (op : String ): String = {
285+ val prefix = " WeakHashSet."
286+ val suffix = getClass.getSimpleName
287+ s " $prefix$op $suffix"
288+ }
289+
321290 /**
322291 * Diagnostic information about the internals of this set. Not normally
323292 * needed by ordinary code, but may be useful for diagnosing performance problems
@@ -386,7 +355,7 @@ object WeakHashSet {
386355 * A single entry in a WeakHashSet. It's a WeakReference plus a cached hash code and
387356 * a link to the next Entry in the same bucket
388357 */
389- private class Entry [A ](element : A , val hash : Int , var tail : Entry [A ], queue : ReferenceQueue [A ]) extends WeakReference [A ](element, queue)
358+ private class Entry [A ](@ constructorOnly element : A , val hash : Int , var tail : Entry [A ], @ constructorOnly queue : ReferenceQueue [A ]) extends WeakReference [A ](element, queue)
390359
391360 private final val defaultInitialCapacity = 16
392361 private final val defaultLoadFactor = .75
0 commit comments