Skip to content

Commit dd791a1

Browse files
committed
Introduce setProperties function that takes nullable MutabilityOwnership
It sets bitmap and buffer properties of this node if ownedBy === owner. Otherwise, it returns a new TrieNode with the specified properties and owner.
1 parent 5ffa476 commit dd791a1

File tree

1 file changed

+27
-37
lines changed
  • core/commonMain/src/implementations/immutableSet

1 file changed

+27
-37
lines changed

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

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -99,21 +99,27 @@ internal class TrieNode<E>(
9999
// assert(hasNoCellAt(positionMask))
100100

101101
val index = indexOfCellAt(positionMask)
102+
val newBitmap = bitmap or positionMask
102103
val newBuffer = buffer.addElementAtIndex(index, element)
103-
return TrieNode(bitmap or positionMask, newBuffer)
104+
return setProperties(newBitmap, newBuffer, owner = null)
104105
}
105106

106107
private fun mutableAddElementAt(positionMask: Int, element: E, owner: MutabilityOwnership): TrieNode<E> {
107108
// assert(hasNoCellAt(positionMask))
108109

109110
val index = indexOfCellAt(positionMask)
110-
if (ownedBy === owner) {
111-
buffer = buffer.addElementAtIndex(index, element)
112-
bitmap = bitmap or positionMask
111+
val newBitmap = bitmap or positionMask
112+
val newBuffer = buffer.addElementAtIndex(index, element)
113+
return setProperties(newBitmap, newBuffer, owner)
114+
}
115+
116+
private fun setProperties(newBitmap: Int, newBuffer: Array<Any?>, owner: MutabilityOwnership?): TrieNode<E> {
117+
if (ownedBy != null && ownedBy === owner) {
118+
bitmap = newBitmap
119+
buffer = newBuffer
113120
return this
114121
}
115-
val newBuffer = buffer.addElementAtIndex(index, element)
116-
return TrieNode(bitmap or positionMask, newBuffer, owner)
122+
return TrieNode(newBitmap, newBuffer, owner)
117123
}
118124

119125
/** The given [newNode] must not be a part of any persistent set instance. */
@@ -187,35 +193,28 @@ internal class TrieNode<E>(
187193
// assert(!hasNoCellAt(positionMask))
188194
// assert(buffer.size > 1) can be false only for the root node
189195

196+
val newBitmap = bitmap xor positionMask
190197
val newBuffer = buffer.removeCellAtIndex(cellIndex)
191-
return TrieNode(bitmap xor positionMask, newBuffer)
198+
return setProperties(newBitmap, newBuffer, owner = null)
192199
}
193200

194201
private fun mutableRemoveCellAtIndex(cellIndex: Int, positionMask: Int, owner: MutabilityOwnership): TrieNode<E> {
195202
// assert(!hasNoCellAt(positionMask))
196203
// assert(buffer.size > 1)
197204

198-
if (ownedBy === owner) {
199-
buffer = buffer.removeCellAtIndex(cellIndex)
200-
bitmap = bitmap xor positionMask
201-
return this
202-
}
205+
val newBitmap = bitmap xor positionMask
203206
val newBuffer = buffer.removeCellAtIndex(cellIndex)
204-
return TrieNode(bitmap xor positionMask, newBuffer, owner)
207+
return setProperties(newBitmap, newBuffer, owner)
205208
}
206209

207210
private fun collisionRemoveElementAtIndex(i: Int): TrieNode<E> {
208211
val newBuffer = buffer.removeCellAtIndex(i)
209-
return TrieNode(0, newBuffer)
212+
return setProperties(newBitmap = 0, newBuffer, owner = null)
210213
}
211214

212215
private fun mutableCollisionRemoveElementAtIndex(i: Int, owner: MutabilityOwnership): TrieNode<E> {
213-
if (ownedBy === owner) {
214-
buffer = buffer.removeCellAtIndex(i)
215-
return this
216-
}
217216
val newBuffer = buffer.removeCellAtIndex(i)
218-
return TrieNode(0, newBuffer, owner)
217+
return setProperties(newBitmap = 0, newBuffer, owner)
219218
}
220219

221220
private fun collisionContainsElement(element: E): Boolean {
@@ -225,18 +224,14 @@ internal class TrieNode<E>(
225224
private fun collisionAdd(element: E): TrieNode<E> {
226225
if (collisionContainsElement(element)) return this
227226
val newBuffer = buffer.addElementAtIndex(0, element)
228-
return TrieNode(0, newBuffer)
227+
return setProperties(newBitmap = 0, newBuffer, owner = null)
229228
}
230229

231230
private fun mutableCollisionAdd(element: E, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
232231
if (collisionContainsElement(element)) return this
233232
mutator.size++
234-
if (ownedBy === mutator.ownership) {
235-
buffer = buffer.addElementAtIndex(0, element)
236-
return this
237-
}
238233
val newBuffer = buffer.addElementAtIndex(0, element)
239-
return TrieNode(0, newBuffer, mutator.ownership)
234+
return setProperties(newBitmap = 0, newBuffer, owner = mutator.ownership)
240235
}
241236

242237
private fun collisionRemove(element: E): TrieNode<E> {
@@ -274,12 +269,7 @@ internal class TrieNode<E>(
274269
if (totalSize == otherNode.buffer.size) return otherNode
275270

276271
val newBuffer = if (totalSize == tempBuffer.size) tempBuffer else tempBuffer.copyOf(newSize = totalSize)
277-
return if (ownedBy == owner) {
278-
this.buffer = newBuffer
279-
this
280-
} else {
281-
TrieNode(0, newBuffer, owner)
282-
}
272+
return setProperties(newBitmap = 0, newBuffer, owner)
283273
}
284274

285275
private fun mutableCollisionRetainAll(otherNode: TrieNode<E>, intersectionSizeRef: DeltaCounter,
@@ -289,7 +279,7 @@ internal class TrieNode<E>(
289279
return this
290280
}
291281
val tempBuffer =
292-
if (owner == ownedBy) buffer
282+
if (owner === ownedBy) buffer
293283
else arrayOfNulls<Any?>(minOf(buffer.size, otherNode.buffer.size))
294284
val totalWritten = buffer.filterTo(tempBuffer) {
295285
@Suppress("UNCHECKED_CAST")
@@ -301,8 +291,8 @@ internal class TrieNode<E>(
301291
1 -> tempBuffer[0]
302292
this.buffer.size -> this
303293
otherNode.buffer.size -> otherNode
304-
tempBuffer.size -> TrieNode<E>(0, tempBuffer, owner)
305-
else -> TrieNode<E>(0, tempBuffer.copyOf(newSize = totalWritten), owner)
294+
tempBuffer.size -> setProperties(newBitmap = 0, newBuffer = tempBuffer, owner)
295+
else -> setProperties(newBitmap = 0, newBuffer = tempBuffer.copyOf(newSize = totalWritten), owner)
306296
}
307297
}
308298

@@ -313,7 +303,7 @@ internal class TrieNode<E>(
313303
intersectionSizeRef += buffer.size
314304
return EMPTY
315305
}
316-
val tempBuffer = if (owner == ownedBy) buffer else arrayOfNulls<Any?>(buffer.size)
306+
val tempBuffer = if (owner === ownedBy) buffer else arrayOfNulls<Any?>(buffer.size)
317307
val totalWritten = buffer.filterTo(tempBuffer) {
318308
@Suppress("UNCHECKED_CAST")
319309
!otherNode.collisionContainsElement(it as E)
@@ -323,8 +313,8 @@ internal class TrieNode<E>(
323313
0 -> EMPTY
324314
1 -> tempBuffer[0]
325315
this.buffer.size -> this
326-
tempBuffer.size -> TrieNode<E>(0, tempBuffer, owner)
327-
else -> TrieNode<E>(0, tempBuffer.copyOf(newSize = totalWritten), owner)
316+
tempBuffer.size -> setProperties(newBitmap = 0, newBuffer = tempBuffer, owner)
317+
else -> setProperties(newBitmap = 0, newBuffer = tempBuffer.copyOf(newSize = totalWritten), owner)
328318
}
329319
}
330320

0 commit comments

Comments
 (0)