commonMain.implementations.immutableMap.PersistentHashMapBuilderContentIterators.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of kotlinx-collections-immutable Show documentation
Show all versions of kotlinx-collections-immutable Show documentation
Kotlin Immutable Collections multiplatform library
The newest version!
/*
* Copyright 2016-2019 JetBrains s.r.o.
* Use of this source code is governed by the Apache 2.0 License that can be found in the LICENSE.txt file.
*/
package kotlinx.collections.immutable.implementations.immutableMap
import kotlinx.collections.immutable.internal.assert
internal class TrieNodeMutableEntriesIterator(
private val parentIterator: PersistentHashMapBuilderEntriesIterator
) : TrieNodeBaseIterator>() {
override fun next(): MutableMap.MutableEntry {
assert(hasNextKey())
index += 2
@Suppress("UNCHECKED_CAST")
return MutableMapEntry(parentIterator, buffer[index - 2] as K, buffer[index - 1] as V)
}
}
private class MutableMapEntry(
private val parentIterator: PersistentHashMapBuilderEntriesIterator,
key: K,
override var value: V
) : MapEntry(key, value), MutableMap.MutableEntry {
override fun setValue(newValue: V): V {
val result = value
value = newValue
parentIterator.setValue(key, newValue)
return result
}
}
internal open class PersistentHashMapBuilderBaseIterator(
private val builder: PersistentHashMapBuilder,
path: Array>
) : MutableIterator, PersistentHashMapBaseIterator(builder.node, path) {
private var lastIteratedKey: K? = null
private var nextWasInvoked = false
private var expectedModCount = builder.modCount
override fun next(): T {
checkForComodification()
lastIteratedKey = currentKey()
nextWasInvoked = true
return super.next()
}
override fun remove() {
checkNextWasInvoked()
if (hasNext()) {
val currentKey = currentKey()
builder.remove(lastIteratedKey)
resetPath(currentKey.hashCode(), builder.node, currentKey, 0)
} else {
builder.remove(lastIteratedKey)
}
lastIteratedKey = null
nextWasInvoked = false
expectedModCount = builder.modCount
}
fun setValue(key: K, newValue: V) {
if (!builder.containsKey(key)) return
if (hasNext()) {
val currentKey = currentKey()
builder[key] = newValue
resetPath(currentKey.hashCode(), builder.node, currentKey, 0)
} else {
builder[key] = newValue
}
expectedModCount = builder.modCount
}
private fun resetPath(keyHash: Int, node: TrieNode<*, *>, key: K, pathIndex: Int) {
val shift = pathIndex * LOG_MAX_BRANCHING_FACTOR
if (shift > MAX_SHIFT) { // collision
path[pathIndex].reset(node.buffer, node.buffer.size, 0)
while (path[pathIndex].currentKey() != key) {
path[pathIndex].moveToNextKey()
}
pathLastIndex = pathIndex
return
}
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
if (node.hasEntryAt(keyPositionMask)) { // key is directly in buffer
val keyIndex = node.entryKeyIndex(keyPositionMask)
// assert(node.keyAtIndex(keyIndex) == key)
path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), keyIndex)
pathLastIndex = pathIndex
return
}
// assert(node.hasNodeAt(keyPositionMask)) // key is in node
val nodeIndex = node.nodeIndex(keyPositionMask)
val targetNode = node.nodeAtIndex(nodeIndex)
path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), nodeIndex)
resetPath(keyHash, targetNode, key, pathIndex + 1)
}
private fun checkNextWasInvoked() {
if (!nextWasInvoked)
throw IllegalStateException()
}
private fun checkForComodification() {
if (builder.modCount != expectedModCount)
throw ConcurrentModificationException()
}
}
internal class PersistentHashMapBuilderEntriesIterator(
builder: PersistentHashMapBuilder
) : MutableIterator> {
private val base = PersistentHashMapBuilderBaseIterator>(
builder,
Array(TRIE_MAX_HEIGHT + 1) { TrieNodeMutableEntriesIterator(this) }
)
override fun hasNext(): Boolean = base.hasNext()
override fun next(): MutableMap.MutableEntry = base.next()
override fun remove(): Unit = base.remove()
fun setValue(key: K, newValue: V): Unit = base.setValue(key, newValue)
}
internal class PersistentHashMapBuilderKeysIterator(builder: PersistentHashMapBuilder)
: PersistentHashMapBuilderBaseIterator(builder, Array(TRIE_MAX_HEIGHT + 1) { TrieNodeKeysIterator() })
internal class PersistentHashMapBuilderValuesIterator(builder: PersistentHashMapBuilder)
: PersistentHashMapBuilderBaseIterator(builder, Array(TRIE_MAX_HEIGHT + 1) { TrieNodeValuesIterator() })
© 2015 - 2024 Weber Informatics LLC | Privacy Policy