Skip to content

Commit 15a292b

Browse files
committed
Synchronize WeakHashSet with scalac
Mostly cosmetic changes except for 5d071229baf7294b03d6d50c7685c934ef54a191 by Jason Zaugg: Avoid BoxesRuntime.equals in Type.unique Like using AnyRefMap, we can optimize this datastructure with the knowledge that is only holds AnyRef-s, and we can bypass BoxesRuntime for equality/hashing.
1 parent aee7a4f commit 15a292b

File tree

1 file changed

+26
-28
lines changed

1 file changed

+26
-28
lines changed

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

Lines changed: 26 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,16 @@ package dotty.tools.dotc.util
66

77
import java.lang.ref.{WeakReference, ReferenceQueue}
88
import scala.annotation.tailrec
9-
import scala.collection.generic.Clearable
109
import scala.collection.mutable.{Set => MSet}
1110

1211
/**
13-
* A HashSet where the elements are stored weakly. Elements in this set are elligible for GC if no other
12+
* A HashSet where the elements are stored weakly. Elements in this set are eligible for GC if no other
1413
* hard references are associated with them. Its primary use case is as a canonical reference
1514
* identity holder (aka "hash-consing") via findEntryOrUpdate
1615
*
1716
* This Set implementation cannot hold null. Any attempt to put a null in it will result in a NullPointerException
1817
*
19-
* This set implmeentation is not in general thread safe without external concurrency control. However it behaves
18+
* This set implementation is not in general thread safe without external concurrency control. However it behaves
2019
* properly when GC concurrently collects elements in this set.
2120
*/
2221
final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadFactor: Double) extends Set[A] with Function1[A, Boolean] with MSet[A] {
@@ -29,7 +28,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
2928

3029
/**
3130
* queue of Entries that hold elements scheduled for GC
32-
* the removeStaleEntries() method works through the queue to remeove
31+
* the removeStaleEntries() method works through the queue to remove
3332
* stale entries from the table
3433
*/
3534
private[this] val queue = new ReferenceQueue[A]
@@ -44,7 +43,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
4443
* power of two equal to or greater than the specified initial capacity
4544
*/
4645
private def computeCapacity = {
47-
if (initialCapacity < 0) throw new IllegalArgumentException("initial capacity cannot be less than 0");
46+
if (initialCapacity < 0) throw new IllegalArgumentException("initial capacity cannot be less than 0")
4847
var candidate = 1
4948
while (candidate < initialCapacity) {
5049
candidate *= 2
@@ -60,12 +59,12 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
6059
/**
6160
* the limit at which we'll increase the size of the hash table
6261
*/
63-
var threshhold = computeThreshHold
62+
private[this] var threshold = computeThreshold
6463

65-
private[this] def computeThreshHold: Int = (table.size * loadFactor).ceil.toInt
64+
private[this] def computeThreshold: Int = (table.size * loadFactor).ceil.toInt
6665

6766
/**
68-
* find the bucket associated with an elements's hash code
67+
* find the bucket associated with an element's hash code
6968
*/
7069
private[this] def bucketFor(hash: Int): Int = {
7170
// spread the bits around to try to avoid accidental collisions using the
@@ -86,7 +85,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
8685
/**
8786
* remove a single entry from a linked list in a given bucket
8887
*/
89-
private[this] def remove(bucket: Int, prevEntry: Entry[A], entry: Entry[A]): Unit = {
88+
private[this] def remove(bucket: Int, prevEntry: Entry[A], entry: Entry[A]) {
9089
prevEntry match {
9190
case null => table(bucket) = entry.tail
9291
case _ => prevEntry.tail = entry.tail
@@ -97,7 +96,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
9796
/**
9897
* remove entries associated with elements that have been gc'ed
9998
*/
100-
private[this] def removeStaleEntries(): Unit = {
99+
private[this] def removeStaleEntries() {
101100
def poll(): Entry[A] = queue.poll().asInstanceOf[Entry[A]]
102101

103102
@tailrec
@@ -122,10 +121,10 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
122121
/**
123122
* Double the size of the internal table
124123
*/
125-
private[this] def resize(): Unit = {
124+
private[this] def resize() {
126125
val oldTable = table
127126
table = new Array[Entry[A]](oldTable.size * 2)
128-
threshhold = computeThreshHold
127+
threshold = computeThreshold
129128

130129
@tailrec
131130
def tableLoop(oldBucket: Int): Unit = if (oldBucket < oldTable.size) {
@@ -160,7 +159,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
160159
case null => null.asInstanceOf[A]
161160
case _ => {
162161
val entryElem = entry.get
163-
if (elem == entryElem) entryElem
162+
if (elem.equals(entryElem)) entryElem
164163
else linkedListLoop(entry.tail)
165164
}
166165
}
@@ -180,7 +179,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
180179
def add() = {
181180
table(bucket) = new Entry(elem, hash, oldHead, queue)
182181
count += 1
183-
if (count > threshhold) resize()
182+
if (count > threshold) resize()
184183
elem
185184
}
186185

@@ -189,7 +188,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
189188
case null => add()
190189
case _ => {
191190
val entryElem = entry.get
192-
if (elem == entryElem) entryElem
191+
if (elem.equals(entryElem)) entryElem
193192
else linkedListLoop(entry.tail)
194193
}
195194
}
@@ -207,17 +206,17 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
207206
val bucket = bucketFor(hash)
208207
val oldHead = table(bucket)
209208

210-
def add() = {
209+
def add() {
211210
table(bucket) = new Entry(elem, hash, oldHead, queue)
212211
count += 1
213-
if (count > threshhold) resize()
212+
if (count > threshold) resize()
214213
}
215214

216215
@tailrec
217216
def linkedListLoop(entry: Entry[A]): Unit = entry match {
218-
case null => add()
219-
case _ if (elem == entry.get) => ()
220-
case _ => linkedListLoop(entry.tail)
217+
case null => add()
218+
case _ if elem.equals(entry.get) => ()
219+
case _ => linkedListLoop(entry.tail)
221220
}
222221

223222
linkedListLoop(oldHead)
@@ -227,8 +226,8 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
227226

228227
def +=(elem: A) = this + elem
229228

230-
// from scala.reflect.interanl.Set
231-
override def addEntry(x: A) = { this += x }
229+
// from scala.reflect.internal.Set
230+
override def addEntry(x: A) { this += x }
232231

233232
// remove an element from this set and return this set
234233
override def -(elem: A): this.type = elem match {
@@ -242,7 +241,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
242241
@tailrec
243242
def linkedListLoop(prevEntry: Entry[A], entry: Entry[A]): Unit = entry match {
244243
case null => ()
245-
case _ if (elem == entry.get) => remove(bucket, prevEntry, entry)
244+
case _ if elem.equals(entry.get) => remove(bucket, prevEntry, entry)
246245
case _ => linkedListLoop(entry, entry.tail)
247246
}
248247

@@ -256,7 +255,7 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
256255
// empty this set
257256
override def clear(): Unit = {
258257
table = new Array[Entry[A]](table.size)
259-
threshhold = computeThreshHold
258+
threshold = computeThreshold
260259
count = 0
261260

262261
// drain the queue - doesn't do anything because we're throwing away all the values anyway
@@ -375,13 +374,13 @@ final class WeakHashSet[A >: Null <: AnyRef](val initialCapacity: Int, val loadF
375374
* Number of buckets that hold collisions. Useful for diagnosing performance issues.
376375
*/
377376
def collisionBucketsCount: Int =
378-
(table filter (entry => entry != null && entry.tail != null)).size
377+
(table count (entry => entry != null && entry.tail != null))
379378

380379
/**
381380
* Number of buckets that are occupied in this hash table.
382381
*/
383382
def fullBucketsCount: Int =
384-
(table filter (entry => entry != null)).size
383+
(table count (entry => entry != null))
385384

386385
/**
387386
* Number of buckets in the table
@@ -405,6 +404,5 @@ object WeakHashSet {
405404
val defaultInitialCapacity = 16
406405
val defaultLoadFactor = .75
407406

408-
def apply[A >: Null <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) =
409-
new WeakHashSet[A](initialCapacity, defaultLoadFactor)
407+
def apply[A <: AnyRef](initialCapacity: Int = WeakHashSet.defaultInitialCapacity, loadFactor: Double = WeakHashSet.defaultLoadFactor) = new WeakHashSet[A](initialCapacity, defaultLoadFactor)
410408
}

0 commit comments

Comments
 (0)