diff --git a/core/commonMain/src/implementations/immutableMap/TrieNode.kt b/core/commonMain/src/implementations/immutableMap/TrieNode.kt index c3fd19c3..8a7cbe58 100644 --- a/core/commonMain/src/implementations/immutableMap/TrieNode.kt +++ b/core/commonMain/src/implementations/immutableMap/TrieNode.kt @@ -172,10 +172,17 @@ internal class TrieNode( return TrieNode(dataMap, nodeMap, newBuffer, mutator.ownership) } + /** The given [newNode] must not be a part of any persistent map instance. */ private fun updateNodeAtIndex(nodeIndex: Int, positionMask: Int, newNode: TrieNode): TrieNode { // assert(buffer[nodeIndex] !== newNode) val newNodeBuffer = newNode.buffer if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) { + if (buffer.size == 1) { +// assert(dataMap == 0 && nodeMap xor positionMask == 0) + newNode.dataMap = nodeMap + return newNode + } + val keyIndex = entryKeyIndex(positionMask) val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1]) return TrieNode(dataMap xor positionMask, nodeMap xor positionMask, newBuffer) @@ -186,11 +193,18 @@ internal class TrieNode( return TrieNode(dataMap, nodeMap, newBuffer) } + /** The given [newNode] must not be a part of any persistent map instance. */ private fun mutableUpdateNodeAtIndex(nodeIndex: Int, positionMask: Int, newNode: TrieNode, owner: MutabilityOwnership): TrieNode { // assert(buffer[nodeIndex] !== newNode) val newNodeBuffer = newNode.buffer if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) { + if (buffer.size == 1) { +// assert(dataMap == 0 && nodeMap xor positionMask == 0) + newNode.dataMap = nodeMap + return newNode + } + val keyIndex = entryKeyIndex(positionMask) val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1]) diff --git a/core/commonMain/src/implementations/immutableSet/TrieNode.kt b/core/commonMain/src/implementations/immutableSet/TrieNode.kt index c1207505..2725ac8f 100644 --- a/core/commonMain/src/implementations/immutableSet/TrieNode.kt +++ b/core/commonMain/src/implementations/immutableSet/TrieNode.kt @@ -89,29 +89,39 @@ internal class TrieNode( return TrieNode(bitmap or positionMask, newBuffer, owner) } + /** The given [newNode] must not be a part of any persistent set instance. */ private fun updateNodeAtIndex(nodeIndex: Int, newNode: TrieNode): TrieNode { // assert(buffer[nodeIndex] !== newNode) + val cell: Any? - val newBuffer = buffer.copyOf() - - // TODO: check how this changes affect `add` operation performance. - // Try to not create this newNode, but pass here the remained element. val newNodeBuffer = newNode.buffer if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) { - newBuffer[nodeIndex] = newNodeBuffer[0] + if (buffer.size == 1) { + newNode.bitmap = bitmap + return newNode + } + cell = newNodeBuffer[0] } else { - newBuffer[nodeIndex] = newNode + cell = newNode } + val newBuffer = buffer.copyOf() + newBuffer[nodeIndex] = cell return TrieNode(bitmap, newBuffer) } + /** The given [newNode] must not be a part of any persistent set instance. */ private fun mutableUpdateNodeAtIndex(nodeIndex: Int, newNode: TrieNode, owner: MutabilityOwnership): TrieNode { // assert(buffer[nodeIndex] !== newNode) val cell: Any? + val newNodeBuffer = newNode.buffer if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) { + if (buffer.size == 1) { + newNode.bitmap = bitmap + return newNode + } cell = newNodeBuffer[0] } else { cell = newNode