Skip to content

Commit 04a7837

Browse files
authored
Merge pull request scala/scala#8583 from rorygraves/mike/2.12.x/quickHashSetEquals
faster equals for HashSet
2 parents 230d327 + 6e2455b commit 04a7837

File tree

1 file changed

+34
-4
lines changed

1 file changed

+34
-4
lines changed

library/src/scala/collection/immutable/HashSet.scala

Lines changed: 34 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ package scala
1414
package collection
1515
package immutable
1616

17+
import java.util
18+
1719
import generic._
1820
import scala.collection.parallel.immutable.ParHashSet
1921
import scala.collection.GenSet
@@ -260,12 +262,21 @@ object HashSet extends ImmutableSetFactory[HashSet] {
260262
override protected def get0(key: A, hash: Int, level: Int): Boolean =
261263
(hash == this.hash && key == this.key)
262264

265+
override def equals(other: Any): Boolean = {
266+
other match {
267+
case that: HashSet1[A] =>
268+
(this eq that) || (this.hash == that.hash && this.key == that.key)
269+
case _ : HashSet[_] => false
270+
case _ => super.equals(other)
271+
}
272+
}
273+
263274
override protected def subsetOf0(that: HashSet[A], level: Int) = {
264275
// check if that contains this.key
265276
// we use get0 with our key and hash at the correct level instead of calling contains,
266277
// which would not work since that might not be a top-level HashSet
267278
// and in any case would be inefficient because it would require recalculating the hash code
268-
that.get0(key, hash, level)
279+
(this eq that) || that.get0(key, hash, level)
269280
}
270281

271282
override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
@@ -330,12 +341,21 @@ object HashSet extends ImmutableSetFactory[HashSet] {
330341
override protected def get0(key: A, hash: Int, level: Int): Boolean =
331342
if (hash == this.hash) ks.contains(key) else false
332343

344+
override def equals(other: Any): Boolean = {
345+
other match {
346+
case that: HashSetCollision1[A] =>
347+
(this eq that) || (this.hash == that.hash && this.ks == that.ks)
348+
case miss : HashSet[_] => false
349+
case _ => super.equals(other)
350+
}
351+
}
352+
333353
override protected def subsetOf0(that: HashSet[A], level: Int) = {
334354
// we have to check each element
335355
// we use get0 with our hash at the correct level instead of calling contains,
336356
// which would not work since that might not be a top-level HashSet
337357
// and in any case would be inefficient because it would require recalculating the hash code
338-
ks.forall(key => that.get0(key, hash, level))
358+
(this eq that) || ks.forall(key => that.get0(key, hash, level))
339359
}
340360

341361
override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
@@ -880,7 +900,17 @@ object HashSet extends ImmutableSetFactory[HashSet] {
880900
}
881901
}
882902

883-
override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
903+
override def equals(other: Any): Boolean = {
904+
other match {
905+
case that: HashTrieSet[A] =>
906+
(this eq that) || (this.bitmap == that.bitmap && this.size0 == that.size0 &&
907+
util.Arrays.equals(this.elems.asInstanceOf[Array[AnyRef]], that.elems.asInstanceOf[Array[AnyRef]]))
908+
case _ : HashSet[_] => false
909+
case _ => super.equals(other)
910+
}
911+
}
912+
913+
override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = (that eq this) || (that match {
884914
case that: HashTrieSet[A] if this.size0 <= that.size0 =>
885915
// create local mutable copies of members
886916
var abm = this.bitmap
@@ -921,7 +951,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
921951
// if the other set is a HashSetCollision1, we can not be a subset of it because we are a HashTrieSet with at least two different hash codes
922952
// if the other set is the empty set, we are not a subset of it because we are not empty
923953
false
924-
}
954+
})
925955

926956
override protected def filter0(p: A => Boolean, negate: Boolean, level: Int, buffer: Array[HashSet[A]], offset0: Int): HashSet[A] = {
927957
// current offset

0 commit comments

Comments
 (0)