Import StringMap from GWT
This commit is contained in:
@@ -0,0 +1,124 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2016 JetBrains s.r.o.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
/*
|
||||||
|
* Based on GWT InternalStringMap
|
||||||
|
* Copyright 2008 Google Inc.
|
||||||
|
*/
|
||||||
|
package kotlin.collections
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple wrapper around JavaScript Map for key type is string.
|
||||||
|
*/
|
||||||
|
internal class InternalStringMap<K, V>(private val host: AbstractHashMap<K, V>) : Iterable<Entry<K, V>> {
|
||||||
|
|
||||||
|
private val backingMap = InternalJsMapFactory.newJsMap()
|
||||||
|
private var size: Int = 0
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A mod count to track 'value' replacements in map to ensure that the 'value' that we have in the
|
||||||
|
* iterator entry is guaranteed to be still correct.
|
||||||
|
* This is to optimize for the common scenario where the values are not modified during
|
||||||
|
* iterations where the entries are never stale.
|
||||||
|
*/
|
||||||
|
private var valueMod: Int = 0
|
||||||
|
|
||||||
|
operator fun contains(key: String): Boolean {
|
||||||
|
return !JsUtils.isUndefined(backingMap.get(key))
|
||||||
|
}
|
||||||
|
|
||||||
|
operator fun get(key: String): V {
|
||||||
|
return backingMap.get(key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun put(key: String, value: V): V {
|
||||||
|
val oldValue = backingMap.get(key)
|
||||||
|
backingMap.set(key, toNullIfUndefined(value))
|
||||||
|
|
||||||
|
if (JsUtils.isUndefined(oldValue)) {
|
||||||
|
size++
|
||||||
|
structureChanged(host)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valueMod++
|
||||||
|
}
|
||||||
|
return oldValue
|
||||||
|
}
|
||||||
|
|
||||||
|
fun remove(key: String): V {
|
||||||
|
val value = backingMap.get(key)
|
||||||
|
if (!JsUtils.isUndefined(value)) {
|
||||||
|
backingMap.delete(key)
|
||||||
|
size--
|
||||||
|
structureChanged(host)
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
valueMod++
|
||||||
|
}
|
||||||
|
|
||||||
|
return value
|
||||||
|
}
|
||||||
|
|
||||||
|
fun size(): Int {
|
||||||
|
return size
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun iterator(): Iterator<Entry<K, V>> {
|
||||||
|
return object : Iterator<Entry<K, V>> {
|
||||||
|
internal var entries = backingMap.entries()
|
||||||
|
internal var current = entries.next()
|
||||||
|
internal var last: InternalJsMap.IteratorEntry<V>
|
||||||
|
|
||||||
|
override fun hasNext(): Boolean {
|
||||||
|
return !current.done
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun next(): Entry<K, V> {
|
||||||
|
last = current
|
||||||
|
current = entries.next()
|
||||||
|
return newMapEntry(last, valueMod)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun remove() {
|
||||||
|
this@InternalStringMap.remove(last.getKey())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun newMapEntry(entry: InternalJsMap.IteratorEntry<V>,
|
||||||
|
lastValueMod: Int): Entry<K, V> {
|
||||||
|
return object : AbstractMapEntry<K, V>() {
|
||||||
|
val key: K
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
|
get() = entry.getKey()
|
||||||
|
// Let's get a fresh copy as the value may have changed.
|
||||||
|
val value: V
|
||||||
|
get() {
|
||||||
|
if (valueMod != lastValueMod) {
|
||||||
|
return get(entry.getKey())
|
||||||
|
}
|
||||||
|
return entry.getValue()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setValue(`object`: V): V {
|
||||||
|
return put(entry.getKey(), `object`)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun <T> toNullIfUndefined(value: T): T? {
|
||||||
|
return if (JsUtils.isUndefined(value)) null else value
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user