Skip to content

Commit b654c6f

Browse files
author
Abduqodiri Qurbonzoda
committed
Do note create node containing a single other node
1 parent 25d9e54 commit b654c6f

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
@@ -172,12 +172,19 @@ internal class TrieNode<K, V>(
172172
return TrieNode(dataMap, nodeMap, newBuffer, mutator.ownership)
173173
}
174174

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

179180
val newNodeBuffer = newNode.buffer
180181
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
182+
if (buffer.size == 1) {
183+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
184+
newNode.dataMap = nodeMap
185+
return newNode
186+
}
187+
181188
val keyIndex = entryKeyIndex(positionMask)
182189
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
183190
return TrieNode(dataMap xor positionMask, nodeMap xor positionMask, newBuffer)
@@ -188,11 +195,18 @@ internal class TrieNode<K, V>(
188195
return TrieNode(dataMap, nodeMap, newBuffer)
189196
}
190197

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

194202
val newNodeBuffer = newNode.buffer
195203
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
204+
if (buffer.size == 1) {
205+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
206+
newNode.dataMap = nodeMap
207+
return newNode
208+
}
209+
196210
val keyIndex = entryKeyIndex(positionMask)
197211
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
198212

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

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

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

95-
val newBuffer = buffer.copyOf()
97+
val cell: Any?
9698

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

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

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

112119
val cell: Any?
120+
113121
val newNodeBuffer = newNode.buffer
114122
if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) {
123+
if (buffer.size == 1) {
124+
newNode.bitmap = bitmap
125+
return newNode
126+
}
115127
cell = newNodeBuffer[0]
116128
} else {
117129
cell = newNode

0 commit comments

Comments
 (0)