Skip to content

Commit 6e2455b

Browse files
committed
faster equals for HashSet
1 parent 8a63f12 commit 6e2455b

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
@@ -258,12 +260,21 @@ object HashSet extends ImmutableSetFactory[HashSet] {
258260
override protected def get0(key: A, hash: Int, level: Int): Boolean =
259261
(hash == this.hash && key == this.key)
260262

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

269280
override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
@@ -328,12 +339,21 @@ object HashSet extends ImmutableSetFactory[HashSet] {
328339
override protected def get0(key: A, hash: Int, level: Int): Boolean =
329340
if (hash == this.hash) ks.contains(key) else false
330341

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

339359
override private[collection] def updated0(key: A, hash: Int, level: Int): HashSet[A] =
@@ -878,7 +898,17 @@ object HashSet extends ImmutableSetFactory[HashSet] {
878898
}
879899
}
880900

881-
override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = if (that eq this) true else that match {
901+
override def equals(other: Any): Boolean = {
902+
other match {
903+
case that: HashTrieSet[A] =>
904+
(this eq that) || (this.bitmap == that.bitmap && this.size0 == that.size0 &&
905+
util.Arrays.equals(this.elems.asInstanceOf[Array[AnyRef]], that.elems.asInstanceOf[Array[AnyRef]]))
906+
case _ : HashSet[_] => false
907+
case _ => super.equals(other)
908+
}
909+
}
910+
911+
override protected def subsetOf0(that: HashSet[A], level: Int): Boolean = (that eq this) || (that match {
882912
case that: HashTrieSet[A] if this.size0 <= that.size0 =>
883913
// create local mutable copies of members
884914
var abm = this.bitmap
@@ -919,7 +949,7 @@ object HashSet extends ImmutableSetFactory[HashSet] {
919949
// 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
920950
// if the other set is the empty set, we are not a subset of it because we are not empty
921951
false
922-
}
952+
})
923953

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

0 commit comments

Comments
 (0)