@@ -42,20 +42,22 @@ private fun Array<Any?>.replaceEntryWithNode(keyIndex: Int, nodeIndex: Int, newN
4242 return newBuffer
4343}
4444
45+ private fun <K , V > Array<Any?>.replaceNodeWithEntry (nodeIndex : Int , keyIndex : Int , key : K , value : V ): Array <Any ?> {
46+ val newBuffer = this .copyOf(this .size + 1 )
47+ newBuffer.copyInto(newBuffer, nodeIndex + 2 , nodeIndex + 1 , this .size)
48+ newBuffer.copyInto(newBuffer, keyIndex + 2 , keyIndex , nodeIndex)
49+ newBuffer[keyIndex] = key
50+ newBuffer[keyIndex + 1 ] = value
51+ return newBuffer
52+ }
53+
4554private fun Array<Any?>.removeEntryAtIndex (keyIndex : Int ): Array <Any ?> {
4655 val newBuffer = arrayOfNulls<Any ?>(this .size - ENTRY_SIZE )
4756 this .copyInto(newBuffer, endIndex = keyIndex)
4857 this .copyInto(newBuffer, keyIndex, startIndex = keyIndex + ENTRY_SIZE , endIndex = this .size)
4958 return newBuffer
5059}
5160
52- private fun Array<Any?>.removeNodeAtIndex (nodeIndex : Int ): Array <Any ?> {
53- val newBuffer = arrayOfNulls<Any ?>(this .size - 1 )
54- this .copyInto(newBuffer, endIndex = nodeIndex)
55- this .copyInto(newBuffer, nodeIndex, startIndex = nodeIndex + 1 , endIndex = this .size)
56- return newBuffer
57- }
58-
5961
6062
6163internal class TrieNode <K , V >(
@@ -170,17 +172,38 @@ internal class TrieNode<K, V>(
170172 return TrieNode (dataMap, nodeMap, newBuffer, mutator.ownership)
171173 }
172174
173- private fun updateNodeAtIndex (nodeIndex : Int , newNode : TrieNode <K , V >): TrieNode <K , V > {
175+ private fun updateNodeAtIndex (nodeIndex : Int , positionMask : Int , newNode : TrieNode <K , V >): TrieNode <K , V > {
174176// assert(buffer[nodeIndex] !== newNode)
177+ val newNodeBuffer = newNode.buffer
178+ if (newNodeBuffer.size == 2 && newNode.nodeMap == 0 ) {
179+ val keyIndex = entryKeyIndex(positionMask)
180+ val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0 ], newNodeBuffer[1 ])
181+ return TrieNode (dataMap xor positionMask, nodeMap xor positionMask, newBuffer)
182+ }
175183
176- val newBuffer = buffer.copyOf()
184+ val newBuffer = buffer.copyOf(buffer.size )
177185 newBuffer[nodeIndex] = newNode
178186 return TrieNode (dataMap, nodeMap, newBuffer)
179187 }
180188
181- private fun mutableUpdateNodeAtIndex (nodeIndex : Int , newNode : TrieNode <K , V >, owner : MutabilityOwnership ): TrieNode <K , V > {
189+ private fun mutableUpdateNodeAtIndex (nodeIndex : Int , positionMask : Int , newNode : TrieNode <K , V >, owner : MutabilityOwnership ): TrieNode <K , V > {
182190// assert(buffer[nodeIndex] !== newNode)
183191
192+ val newNodeBuffer = newNode.buffer
193+ if (newNodeBuffer.size == 2 && newNode.nodeMap == 0 ) {
194+ val keyIndex = entryKeyIndex(positionMask)
195+ val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0 ], newNodeBuffer[1 ])
196+
197+ if (ownedBy == = owner) {
198+ buffer = newBuffer
199+ dataMap = dataMap xor positionMask
200+ nodeMap = nodeMap xor positionMask
201+ return this
202+ }
203+
204+ return TrieNode (dataMap xor positionMask, nodeMap xor positionMask, newBuffer)
205+ }
206+
184207 if (ownedBy == = owner) {
185208 buffer[nodeIndex] = newNode
186209 return this
@@ -255,6 +278,7 @@ internal class TrieNode<K, V>(
255278
256279 private fun removeEntryAtIndex (keyIndex : Int , positionMask : Int ): TrieNode <K , V >? {
257280// assert(hasEntryAt(positionMask))
281+ // It is possible only when this node is the root node
258282 if (buffer.size == ENTRY_SIZE ) return null
259283
260284 val newBuffer = buffer.removeEntryAtIndex(keyIndex)
@@ -296,27 +320,6 @@ internal class TrieNode<K, V>(
296320 return TrieNode (0 , 0 , newBuffer, mutator.ownership)
297321 }
298322
299- private fun removeNodeAtIndex (nodeIndex : Int , positionMask : Int ): TrieNode <K , V >? {
300- // assert(hasNodeAt(positionMask))
301- if (buffer.size == 1 ) return null
302-
303- val newBuffer = buffer.removeNodeAtIndex(nodeIndex)
304- return TrieNode (dataMap, nodeMap xor positionMask, newBuffer)
305- }
306-
307- private fun mutableRemoveNodeAtIndex (nodeIndex : Int , positionMask : Int , owner : MutabilityOwnership ): TrieNode <K , V >? {
308- // assert(hasNodeAt(positionMask))
309- if (buffer.size == 1 ) return null
310-
311- if (ownedBy == = owner) {
312- buffer = buffer.removeNodeAtIndex(nodeIndex)
313- nodeMap = nodeMap xor positionMask
314- return this
315- }
316- val newBuffer = buffer.removeNodeAtIndex(nodeIndex)
317- return TrieNode (dataMap, nodeMap xor positionMask, newBuffer, owner)
318- }
319-
320323 private fun collisionContainsKey (key : K ): Boolean {
321324 for (i in 0 until buffer.size step ENTRY_SIZE ) {
322325 if (key == buffer[i]) return true
@@ -473,7 +476,7 @@ internal class TrieNode<K, V>(
473476 } else {
474477 targetNode.put(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR ) ? : return null
475478 }
476- return putResult.replaceNode { node -> updateNodeAtIndex(nodeIndex, node) }
479+ return putResult.replaceNode { node -> updateNodeAtIndex(nodeIndex, keyPositionMask, node) }
477480 }
478481
479482 // no entry at this key hash segment
@@ -509,7 +512,7 @@ internal class TrieNode<K, V>(
509512 if (targetNode == = newNode) {
510513 return this
511514 }
512- return mutableUpdateNodeAtIndex(nodeIndex, newNode, mutator.ownership)
515+ return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
513516 }
514517
515518 // key is absent
@@ -537,11 +540,9 @@ internal class TrieNode<K, V>(
537540 } else {
538541 targetNode.remove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR )
539542 }
540- return when {
541- targetNode == = newNode -> this
542- newNode == null -> removeNodeAtIndex(nodeIndex, keyPositionMask)
543- else -> updateNodeAtIndex(nodeIndex, newNode)
544- }
543+ checkNotNull(newNode)
544+ if (targetNode == = newNode) return this
545+ return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
545546 }
546547
547548 // key is absent
@@ -568,11 +569,11 @@ internal class TrieNode<K, V>(
568569 } else {
569570 targetNode.mutableRemove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR , mutator)
570571 }
571- return when {
572- targetNode == = newNode -> this
573- newNode == null -> mutableRemoveNodeAtIndex(nodeIndex, keyPositionMask, mutator.ownership)
574- else -> mutableUpdateNodeAtIndex(nodeIndex, newNode, mutator.ownership)
572+ checkNotNull(newNode)
573+ if (ownedBy == = mutator.ownership || targetNode != = newNode) {
574+ return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
575575 }
576+ return this
576577 }
577578
578579 // key is absent
@@ -599,11 +600,9 @@ internal class TrieNode<K, V>(
599600 } else {
600601 targetNode.remove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR )
601602 }
602- return when {
603- targetNode == = newNode -> this
604- newNode == null -> removeNodeAtIndex(nodeIndex, keyPositionMask)
605- else -> updateNodeAtIndex(nodeIndex, newNode)
606- }
603+ checkNotNull(newNode)
604+ if (targetNode == = newNode) return this
605+ return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
607606 }
608607
609608 // key is absent
@@ -630,11 +629,11 @@ internal class TrieNode<K, V>(
630629 } else {
631630 targetNode.mutableRemove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR , mutator)
632631 }
633- return when {
634- targetNode == = newNode -> this
635- newNode == null -> mutableRemoveNodeAtIndex(nodeIndex, keyPositionMask, mutator.ownership)
636- else -> mutableUpdateNodeAtIndex(nodeIndex, newNode, mutator.ownership)
632+ checkNotNull(newNode)
633+ if (ownedBy == = mutator.ownership || targetNode != = newNode) {
634+ return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
637635 }
636+ return this
638637 }
639638
640639 // key is absent
0 commit comments