Skip to content

Commit c8cb305

Browse files
author
Abduqodiri Qurbonzoda
committed
Do note create node containing a single other node
1 parent 7fed6ca commit c8cb305

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

core/commonMain/src/implementations/immutableMap/TrieNode.kt

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -175,12 +175,19 @@ internal class TrieNode<K, V>(
175175
return TrieNode(dataMap, nodeMap, newBuffer, mutator.ownership)
176176
}
177177

178+
/** The given [newNode] must not be a part of any persistent map instance. */
178179
private fun updateNodeAtIndex(nodeIndex: Int, positionMask: Int, newNode: TrieNode<K, V>): TrieNode<K, V> {
179180
// assert(buffer[nodeIndex] !== newNode)
180181
// TODO: check how this changes affect `put` and non-collision `remove` operations performance.
181182

182183
val newNodeBuffer = newNode.buffer
183184
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
185+
if (buffer.size == 1) {
186+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
187+
newNode.dataMap = nodeMap
188+
return newNode
189+
}
190+
184191
val keyIndex = entryKeyIndex(positionMask)
185192
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
186193
return TrieNode(dataMap xor positionMask, nodeMap xor positionMask, newBuffer)
@@ -191,11 +198,18 @@ internal class TrieNode<K, V>(
191198
return TrieNode(dataMap, nodeMap, newBuffer)
192199
}
193200

201+
/** The given [newNode] must not be a part of any persistent map instance. */
194202
private fun mutableUpdateNodeAtIndex(nodeIndex: Int, positionMask: Int, newNode: TrieNode<K, V>, owner: MutabilityOwnership): TrieNode<K, V> {
195203
// assert(buffer[nodeIndex] !== newNode)
196204

197205
val newNodeBuffer = newNode.buffer
198206
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
207+
if (buffer.size == 1) {
208+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
209+
newNode.dataMap = nodeMap
210+
return newNode
211+
}
212+
199213
val keyIndex = entryKeyIndex(positionMask)
200214
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
201215

core/commonMain/src/implementations/immutableSet/TrieNode.kt

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,29 +88,41 @@ internal class TrieNode<E>(
8888
return TrieNode(bitmap or positionMask, newBuffer, owner)
8989
}
9090

91+
/** The given [newNode] must not be a part of any persistent set instance. */
9192
private fun updateNodeAtIndex(nodeIndex: Int, newNode: TrieNode<E>): TrieNode<E> {
9293
// assert(buffer[nodeIndex] !== newNode)
94+
// TODO: check how this changes affect `add` and non-collision `remove` operations performance.
9395

94-
val newBuffer = buffer.copyOf()
96+
val cell: Any?
9597

96-
// TODO: check how this changes affect `add` operation performance.
97-
// Try to not create this newNode, but pass here the remained element.
9898
val newNodeBuffer = newNode.buffer
9999
if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) {
100-
newBuffer[nodeIndex] = newNodeBuffer[0]
100+
if (buffer.size == 1) {
101+
newNode.bitmap = bitmap
102+
return newNode
103+
}
104+
cell = newNodeBuffer[0]
101105
} else {
102-
newBuffer[nodeIndex] = newNode
106+
cell = newNode
103107
}
104108

109+
val newBuffer = buffer.copyOf()
110+
newBuffer[nodeIndex] = cell
105111
return TrieNode(bitmap, newBuffer)
106112
}
107113

114+
/** The given [newNode] must not be a part of any persistent set instance. */
108115
private fun mutableUpdateNodeAtIndex(nodeIndex: Int, newNode: TrieNode<E>, owner: MutabilityOwnership): TrieNode<E> {
109116
// assert(buffer[nodeIndex] !== newNode)
110117

111118
val cell: Any?
119+
112120
val newNodeBuffer = newNode.buffer
113121
if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) {
122+
if (buffer.size == 1) {
123+
newNode.bitmap = bitmap
124+
return newNode
125+
}
114126
cell = newNodeBuffer[0]
115127
} else {
116128
cell = newNode

0 commit comments

Comments
 (0)