[JS IR] Get rid of HashMap EqualityComparator

^KT-59001
This commit is contained in:
Alexander Korepanov
2023-06-19 14:24:19 +02:00
committed by Space Team
parent 402d5e63fd
commit 6a77514a83
5 changed files with 14 additions and 44 deletions
@@ -1,26 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package kotlin.collections
internal interface EqualityComparator {
/**
* Subclasses must override to return a value indicating
* whether or not two keys or values are equal.
*/
abstract fun equals(value1: Any?, value2: Any?): Boolean
/**
* Subclasses must override to return the hash code of a given key.
*/
abstract fun getHashCode(value: Any?): Int
object HashCode : EqualityComparator {
override fun equals(value1: Any?, value2: Any?): Boolean = value1 == value2
override fun getHashCode(value: Any?): Int = value?.hashCode() ?: 0
}
}
@@ -49,17 +49,14 @@ public actual open class HashMap<K, V> : AbstractMutableMap<K, V>, MutableMap<K,
*/
private val internalMap: InternalMap<K, V>
private val equality: EqualityComparator
internal constructor(internalMap: InternalMap<K, V>) : super() {
this.internalMap = internalMap
this.equality = internalMap.equality
}
/**
* Creates a new empty [HashMap].
*/
actual constructor() : this(InternalHashCodeMap(EqualityComparator.HashCode))
actual constructor() : this(InternalHashCodeMap())
/**
* Creates a new empty [HashMap] with the specified initial capacity and load factor.
@@ -110,7 +107,7 @@ public actual open class HashMap<K, V> : AbstractMutableMap<K, V>, MutableMap<K,
actual override fun containsKey(key: K): Boolean = internalMap.contains(key)
actual override fun containsValue(value: V): Boolean = internalMap.any { equality.equals(it.value, value) }
actual override fun containsValue(value: V): Boolean = internalMap.any { it.value == value }
private var _entries: MutableSet<MutableMap.MutableEntry<K, V>>? = null
actual override val entries: MutableSet<MutableMap.MutableEntry<K, V>>
@@ -138,5 +135,5 @@ public actual open class HashMap<K, V> : AbstractMutableMap<K, V>, MutableMap<K,
* JS object without hashing them.
*/
public fun <V> stringMapOf(vararg pairs: Pair<String, V>): HashMap<String, V> {
return HashMap<String, V>(InternalStringMap(EqualityComparator.HashCode)).apply { putAll(pairs) }
return HashMap<String, V>(InternalStringMap()).apply { putAll(pairs) }
}
@@ -24,14 +24,13 @@ import kotlin.collections.AbstractMutableMap.SimpleEntry
* have the same hash, each value in hashCodeMap is actually an array containing all entries whose
* keys share the same hash.
*/
internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparator) : InternalMap<K, V> {
internal class InternalHashCodeMap<K, V> : InternalMap<K, V> {
private var backingMap: dynamic = createJsMap()
override var size: Int = 0
private set
override fun put(key: K, value: V): V? {
val hashCode = equality.getHashCode(key)
val hashCode = hash(key)
val chainOrEntry = getChainOrEntryOrNull(hashCode)
if (chainOrEntry == null) {
// This is a new chain, put it to the map.
@@ -40,7 +39,7 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
if (chainOrEntry !is Array<*>) {
// It is an entry
val entry: SimpleEntry<K, V> = chainOrEntry
if (equality.equals(entry.key, key)) {
if (entry.key == key) {
return entry.setValue(value)
} else {
backingMap[hashCode] = arrayOf(entry, SimpleEntry(key, value))
@@ -63,11 +62,11 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
}
override fun remove(key: K): V? {
val hashCode = equality.getHashCode(key)
val hashCode = hash(key)
val chainOrEntry = getChainOrEntryOrNull(hashCode) ?: return null
if (chainOrEntry !is Array<*>) {
val entry: MutableEntry<K, V> = chainOrEntry
if (equality.equals(entry.key, key)) {
if (entry.key == key) {
jsDeleteProperty(backingMap, hashCode)
size--
return entry.value
@@ -78,7 +77,7 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
val chain: Array<MutableEntry<K, V>> = chainOrEntry
for (index in chain.indices) {
val entry = chain[index]
if (equality.equals(key, entry.key)) {
if (key == entry.key) {
if (chain.size == 1) {
chain.asDynamic().length = 0
// remove the whole array
@@ -106,10 +105,10 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
override fun get(key: K): V? = getEntry(key)?.value
private fun getEntry(key: K): MutableEntry<K, V>? {
val chainOrEntry = getChainOrEntryOrNull(equality.getHashCode(key)) ?: return null
val chainOrEntry = getChainOrEntryOrNull(hash(key)) ?: return null
if (chainOrEntry !is Array<*>) {
val entry: MutableEntry<K, V> = chainOrEntry
if (equality.equals(entry.key, key)) {
if (entry.key == key) {
return entry
} else {
return null
@@ -121,7 +120,7 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
}
private fun Array<MutableEntry<K, V>>.findEntryInChain(key: K): MutableEntry<K, V>? =
firstOrNull { entry -> equality.equals(entry.key, key) }
firstOrNull { entry -> entry.key == key }
override fun iterator(): MutableIterator<MutableEntry<K, V>> {
@@ -187,4 +186,5 @@ internal class InternalHashCodeMap<K, V>(override val equality: EqualityComparat
return if (chainOrEntry === undefined) null else chainOrEntry
}
private fun hash(key: K) = key?.hashCode() ?: 0
}
@@ -9,7 +9,6 @@ package kotlin.collections
* The common interface of [InternalStringMap] and [InternalHashCodeMap].
*/
internal interface InternalMap<K, V> : MutableIterable<MutableMap.MutableEntry<K, V>> {
val equality: EqualityComparator
val size: Int
operator fun contains(key: K): Boolean
operator fun get(key: K): V?
@@ -17,7 +17,7 @@ import kotlin.collections.MutableMap.MutableEntry
* because we want to have it erased to Any? in order not to generate type-safe override bridges for
* [get], [contains], [remove] etc, if they ever are generated.
*/
internal class InternalStringMap<K, V>(override val equality: EqualityComparator) : InternalMap<K, V> {
internal class InternalStringMap<K, V> : InternalMap<K, V> {
private var backingMap: dynamic = createJsMap()
override var size: Int = 0