@@ -8,32 +8,37 @@ package kotlinx.collections.immutable.implementations.immutableMap
88import kotlinx.collections.immutable.internal.assert
99
1010
11- internal class TrieNodeMutableEntriesIterator <K , V >(private val builder : PersistentHashMapBuilder <K , V >)
12- : TrieNodeBaseIterator <K , V , MutableMap .MutableEntry <K , V >>() {
11+ internal class TrieNodeMutableEntriesIterator <K , V >(
12+ private val parentIterator : PersistentHashMapBuilderEntriesIterator <K , V >
13+ ) : TrieNodeBaseIterator<K, V, MutableMap.MutableEntry<K, V>>() {
1314
1415 override fun next (): MutableMap .MutableEntry <K , V > {
1516 assert (hasNextKey())
1617 index + = 2
1718 @Suppress(" UNCHECKED_CAST" )
18- return MutableMapEntry (builder , buffer[index - 2 ] as K , buffer[index - 1 ] as V )
19+ return MutableMapEntry (parentIterator , buffer[index - 2 ] as K , buffer[index - 1 ] as V )
1920 }
2021}
2122
22- private class MutableMapEntry <K , V >(private val builder : PersistentHashMapBuilder <K , V >,
23- key : K ,
24- override var value : V ) : MapEntry<K, V>(key, value), MutableMap.MutableEntry<K, V> {
23+ private class MutableMapEntry <K , V >(
24+ private val parentIterator : PersistentHashMapBuilderEntriesIterator <K , V >,
25+ key : K ,
26+ override var value : V
27+ ) : MapEntry<K, V>(key, value), MutableMap.MutableEntry<K, V> {
28+
2529 override fun setValue (newValue : V ): V {
2630 val result = value
2731 value = newValue
28- builder[ key] = newValue
32+ parentIterator.setValue( key, newValue)
2933 return result
3034 }
3135}
3236
3337
34- internal abstract class PersistentHashMapBuilderBaseIterator <K , V , T >(private val builder : PersistentHashMapBuilder <K , V >,
35- path : Array <TrieNodeBaseIterator <K , V , T >>)
36- : MutableIterator <T >, PersistentHashMapBaseIterator <K , V , T >(builder.node, path) {
38+ internal open class PersistentHashMapBuilderBaseIterator <K , V , T >(
39+ private val builder : PersistentHashMapBuilder <K , V >,
40+ path : Array <TrieNodeBaseIterator <K , V , T >>
41+ ) : MutableIterator<T>, PersistentHashMapBaseIterator<K, V, T>(builder.node, path) {
3742
3843 private var lastIteratedKey: K ? = null
3944 private var nextWasInvoked = false
@@ -62,8 +67,33 @@ internal abstract class PersistentHashMapBuilderBaseIterator<K, V, T>(private va
6267 expectedModCount = builder.modCount
6368 }
6469
70+ fun setValue (key : K , newValue : V ) {
71+ if (! builder.containsKey(key)) return
72+
73+ if (hasNext()) {
74+ val currentKey = currentKey()
75+
76+ builder[key] = newValue
77+ resetPath(currentKey.hashCode(), builder.node, currentKey, 0 )
78+ } else {
79+ builder[key] = newValue
80+ }
81+
82+ expectedModCount = builder.modCount
83+ }
84+
6585 private fun resetPath (keyHash : Int , node : TrieNode <* , * >, key : K , pathIndex : Int ) {
6686 val shift = pathIndex * LOG_MAX_BRANCHING_FACTOR
87+
88+ if (shift > MAX_SHIFT ) { // collision
89+ path[pathIndex].reset(node.buffer, node.buffer.size, 0 )
90+ while (path[pathIndex].currentKey() != key) {
91+ path[pathIndex].moveToNextKey()
92+ }
93+ pathLastIndex = pathIndex
94+ return
95+ }
96+
6797 val keyPositionMask = 1 shl indexSegment(keyHash, shift)
6898
6999 if (node.hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -72,22 +102,16 @@ internal abstract class PersistentHashMapBuilderBaseIterator<K, V, T>(private va
72102// assert(node.keyAtIndex(keyIndex) == key)
73103
74104 path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), keyIndex)
105+ pathLastIndex = pathIndex
75106 return
76107 }
77108
78- // assert(node.hasNodeAt(keyPosition )) // key is in node
109+ // assert(node.hasNodeAt(keyPositionMask )) // key is in node
79110
80111 val nodeIndex = node.nodeIndex(keyPositionMask)
81112 val targetNode = node.nodeAtIndex(nodeIndex)
82- if (shift == MAX_SHIFT ) { // collision
83- path[pathIndex].reset(node.buffer, node.buffer.size, 0 )
84- while (path[pathIndex].currentKey() != key) {
85- path[pathIndex].moveToNextKey()
86- }
87- } else {
88- path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), nodeIndex)
89- resetPath(keyHash, targetNode, key, pathIndex + 1 )
90- }
113+ path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), nodeIndex)
114+ resetPath(keyHash, targetNode, key, pathIndex + 1 )
91115 }
92116
93117 private fun checkNextWasInvoked () {
@@ -101,8 +125,20 @@ internal abstract class PersistentHashMapBuilderBaseIterator<K, V, T>(private va
101125 }
102126}
103127
104- internal class PersistentHashMapBuilderEntriesIterator <K , V >(builder : PersistentHashMapBuilder <K , V >)
105- : PersistentHashMapBuilderBaseIterator <K , V , MutableMap .MutableEntry <K , V >>(builder, Array (TRIE_MAX_HEIGHT + 1 ) { TrieNodeMutableEntriesIterator <K , V >(builder) })
128+ internal class PersistentHashMapBuilderEntriesIterator <K , V >(
129+ builder : PersistentHashMapBuilder <K , V >
130+ ) : MutableIterator<MutableMap.MutableEntry<K, V>> {
131+ private val base = PersistentHashMapBuilderBaseIterator <K , V , MutableMap .MutableEntry <K , V >>(
132+ builder,
133+ Array (TRIE_MAX_HEIGHT + 1 ) { TrieNodeMutableEntriesIterator (this ) }
134+ )
135+
136+ override fun hasNext (): Boolean = base.hasNext()
137+ override fun next (): MutableMap .MutableEntry <K , V > = base.next()
138+ override fun remove (): Unit = base.remove()
139+
140+ fun setValue (key : K , newValue : V ): Unit = base.setValue(key, newValue)
141+ }
106142
107143internal class PersistentHashMapBuilderKeysIterator <K , V >(builder : PersistentHashMapBuilder <K , V >)
108144 : PersistentHashMapBuilderBaseIterator <K , V , K >(builder, Array (TRIE_MAX_HEIGHT + 1 ) { TrieNodeKeysIterator <K , V >() })
0 commit comments