Skip to content

Commit 8111d6a

Browse files
author
Abduqodiri Qurbonzoda
committed
Do note create node containing a single other node
1 parent 507cb73 commit 8111d6a

File tree

2 files changed

+31
-5
lines changed
  • kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations

2 files changed

+31
-5
lines changed

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/immutableMap/TrieNode.kt

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

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

190191
val newNodeBuffer = newNode.buffer
191192
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
193+
if (buffer.size == 1) {
194+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
195+
newNode.dataMap = nodeMap
196+
return newNode
197+
}
198+
192199
val keyIndex = entryKeyIndex(positionMask)
193200
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
194201
return TrieNode(dataMap xor positionMask, nodeMap xor positionMask, newBuffer)
@@ -199,11 +206,18 @@ internal class TrieNode<K, V>(
199206
return TrieNode(dataMap, nodeMap, newBuffer)
200207
}
201208

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

205213
val newNodeBuffer = newNode.buffer
206214
if (newNodeBuffer.size == 2 && newNode.nodeMap == 0) {
215+
if (buffer.size == 1) {
216+
// assert(dataMap == 0 && nodeMap xor positionMask == 0)
217+
newNode.dataMap = nodeMap
218+
return newNode
219+
}
220+
207221
val keyIndex = entryKeyIndex(positionMask)
208222
val newBuffer = buffer.replaceNodeWithEntry(nodeIndex, keyIndex, newNodeBuffer[0], newNodeBuffer[1])
209223

kotlinx-collections-immutable/src/main/kotlin/kotlinx/collections/immutable/implementations/immutableSet/TrieNode.kt

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

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

104-
val newBuffer = buffer.copyOf()
106+
val cell: Any?
105107

106-
// TODO: check how this changes affect `add` operation performance.
107-
// Try to not create this newNode, but pass here the remained element.
108108
val newNodeBuffer = newNode.buffer
109109
if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) {
110-
newBuffer[nodeIndex] = newNodeBuffer[0]
110+
if (buffer.size == 1) {
111+
newNode.bitmap = bitmap
112+
return newNode
113+
}
114+
cell = newNodeBuffer[0]
111115
} else {
112-
newBuffer[nodeIndex] = newNode
116+
cell = newNode
113117
}
114118

119+
val newBuffer = buffer.copyOf()
120+
newBuffer[nodeIndex] = cell
115121
return TrieNode(bitmap, newBuffer)
116122
}
117123

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

121128
val cell: Any?
129+
122130
val newNodeBuffer = newNode.buffer
123131
if (newNodeBuffer.size == 1 && newNodeBuffer[0] !is TrieNode<*>) {
132+
if (buffer.size == 1) {
133+
newNode.bitmap = bitmap
134+
return newNode
135+
}
124136
cell = newNodeBuffer[0]
125137
} else {
126138
cell = newNode

0 commit comments

Comments
 (0)