Skip to content

Commit 59ac6e5

Browse files
author
Abduqodiri Qurbonzoda
committed
Return nonnull node from remove method
1 parent d14c192 commit 59ac6e5

File tree

6 files changed

+29
-46
lines changed

6 files changed

+29
-46
lines changed

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

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,12 @@ internal class PersistentHashMap<K, V>(internal val node: TrieNode<K, V>,
5151
override fun remove(key: K): PersistentHashMap<K, V> {
5252
val newNode = node.remove(key.hashCode(), key, 0)
5353
if (node === newNode) { return this }
54-
if (newNode == null) { return PersistentHashMap.emptyOf() }
5554
return PersistentHashMap(newNode, size - 1)
5655
}
5756

5857
override fun remove(key: K, value: @UnsafeVariance V): PersistentHashMap<K, V> {
5958
val newNode = node.remove(key.hashCode(), key, value, 0)
6059
if (node === newNode) { return this }
61-
if (newNode == null) { return PersistentHashMap.emptyOf() }
6260
return PersistentHashMap(newNode, size - 1)
6361
}
6462

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,14 +64,14 @@ internal class PersistentHashMapBuilder<K, V>(private var map: PersistentHashMap
6464
override fun remove(key: K): V? {
6565
operationResult = null
6666
@Suppress("UNCHECKED_CAST")
67-
node = node.mutableRemove(key.hashCode(), key, 0, this) ?: TrieNode.EMPTY as TrieNode<K, V>
67+
node = node.mutableRemove(key.hashCode(), key, 0, this)
6868
return operationResult
6969
}
7070

7171
fun remove(key: K, value: V): Boolean {
7272
val oldSize = size
7373
@Suppress("UNCHECKED_CAST")
74-
node = node.mutableRemove(key.hashCode(), key, value, 0, this) ?: TrieNode.EMPTY as TrieNode<K, V>
74+
node = node.mutableRemove(key.hashCode(), key, value, 0, this)
7575
return oldSize != size
7676
}
7777

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

Lines changed: 16 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -290,20 +290,18 @@ internal class TrieNode<K, V>(
290290
return TrieNode(0, 1 shl setBit1, arrayOf<Any?>(node), owner)
291291
}
292292

293-
private fun removeEntryAtIndex(keyIndex: Int, positionMask: Int): TrieNode<K, V>? {
293+
private fun removeEntryAtIndex(keyIndex: Int, positionMask: Int): TrieNode<K, V> {
294294
// assert(hasEntryAt(positionMask))
295-
// It is possible only when this node is the root node
296-
if (buffer.size == ENTRY_SIZE) return null
297-
295+
// assert(buffer.size > ENTRY_SIZE) // can be false only for the root node
298296
val newBuffer = buffer.removeEntryAtIndex(keyIndex)
299297
return TrieNode(dataMap xor positionMask, nodeMap, newBuffer)
300298
}
301299

302-
private fun mutableRemoveEntryAtIndex(keyIndex: Int, positionMask: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
300+
private fun mutableRemoveEntryAtIndex(keyIndex: Int, positionMask: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
303301
// assert(hasEntryAt(positionMask))
302+
// assert(buffer.size > ENTRY_SIZE)
304303
mutator.size--
305304
mutator.operationResult = valueAtKeyIndex(keyIndex)
306-
if (buffer.size == ENTRY_SIZE) return null
307305

308306
if (ownedBy === mutator.ownership) {
309307
buffer = buffer.removeEntryAtIndex(keyIndex)
@@ -314,17 +312,16 @@ internal class TrieNode<K, V>(
314312
return TrieNode(dataMap xor positionMask, nodeMap, newBuffer, mutator.ownership)
315313
}
316314

317-
private fun collisionRemoveEntryAtIndex(i: Int): TrieNode<K, V>? {
318-
if (buffer.size == ENTRY_SIZE) return null
319-
315+
private fun collisionRemoveEntryAtIndex(i: Int): TrieNode<K, V> {
316+
// assert(buffer.size > ENTRY_SIZE)
320317
val newBuffer = buffer.removeEntryAtIndex(i)
321318
return TrieNode(0, 0, newBuffer)
322319
}
323320

324-
private fun mutableCollisionRemoveEntryAtIndex(i: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
321+
private fun mutableCollisionRemoveEntryAtIndex(i: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
322+
// assert(buffer.size > ENTRY_SIZE)
325323
mutator.size--
326324
mutator.operationResult = valueAtKeyIndex(i)
327-
if (buffer.size == ENTRY_SIZE) return null
328325

329326
if (ownedBy === mutator.ownership) {
330327
buffer = buffer.removeEntryAtIndex(i)
@@ -391,7 +388,7 @@ internal class TrieNode<K, V>(
391388
return TrieNode(0, 0, newBuffer, mutator.ownership)
392389
}
393390

394-
private fun collisionRemove(key: K): TrieNode<K, V>? {
391+
private fun collisionRemove(key: K): TrieNode<K, V> {
395392
for (i in 0 until buffer.size step ENTRY_SIZE) {
396393
if (key == keyAtIndex(i)) {
397394
return collisionRemoveEntryAtIndex(i)
@@ -400,7 +397,7 @@ internal class TrieNode<K, V>(
400397
return this
401398
}
402399

403-
private fun mutableCollisionRemove(key: K, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
400+
private fun mutableCollisionRemove(key: K, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
404401
for (i in 0 until buffer.size step ENTRY_SIZE) {
405402
if (key == keyAtIndex(i)) {
406403
return mutableCollisionRemoveEntryAtIndex(i, mutator)
@@ -409,7 +406,7 @@ internal class TrieNode<K, V>(
409406
return this
410407
}
411408

412-
private fun collisionRemove(key: K, value: V): TrieNode<K, V>? {
409+
private fun collisionRemove(key: K, value: V): TrieNode<K, V> {
413410
for (i in 0 until buffer.size step ENTRY_SIZE) {
414411
if (key == keyAtIndex(i) && value == valueAtKeyIndex(i)) {
415412
return collisionRemoveEntryAtIndex(i)
@@ -418,7 +415,7 @@ internal class TrieNode<K, V>(
418415
return this
419416
}
420417

421-
private fun mutableCollisionRemove(key: K, value: V, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
418+
private fun mutableCollisionRemove(key: K, value: V, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
422419
for (i in 0 until buffer.size step ENTRY_SIZE) {
423420
if (key == keyAtIndex(i) && value == valueAtKeyIndex(i)) {
424421
return mutableCollisionRemoveEntryAtIndex(i, mutator)
@@ -534,7 +531,7 @@ internal class TrieNode<K, V>(
534531
return mutableInsertEntryAt(keyPositionMask, key, value, mutator.ownership)
535532
}
536533

537-
fun remove(keyHash: Int, key: K, shift: Int): TrieNode<K, V>? {
534+
fun remove(keyHash: Int, key: K, shift: Int): TrieNode<K, V> {
538535
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
539536

540537
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -554,7 +551,6 @@ internal class TrieNode<K, V>(
554551
} else {
555552
targetNode.remove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR)
556553
}
557-
checkNotNull(newNode)
558554
if (targetNode === newNode) return this
559555
return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
560556
}
@@ -563,7 +559,7 @@ internal class TrieNode<K, V>(
563559
return this
564560
}
565561

566-
fun mutableRemove(keyHash: Int, key: K, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
562+
fun mutableRemove(keyHash: Int, key: K, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
567563
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
568564

569565
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -583,7 +579,6 @@ internal class TrieNode<K, V>(
583579
} else {
584580
targetNode.mutableRemove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
585581
}
586-
checkNotNull(newNode)
587582
if (ownedBy === mutator.ownership || targetNode !== newNode) {
588583
return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
589584
}
@@ -594,7 +589,7 @@ internal class TrieNode<K, V>(
594589
return this
595590
}
596591

597-
fun remove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): TrieNode<K, V>? {
592+
fun remove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): TrieNode<K, V> {
598593
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
599594

600595
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -614,7 +609,6 @@ internal class TrieNode<K, V>(
614609
} else {
615610
targetNode.remove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR)
616611
}
617-
checkNotNull(newNode)
618612
if (targetNode === newNode) return this
619613
return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
620614
}
@@ -623,7 +617,7 @@ internal class TrieNode<K, V>(
623617
return this
624618
}
625619

626-
fun mutableRemove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
620+
fun mutableRemove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
627621
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
628622

629623
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -643,7 +637,6 @@ internal class TrieNode<K, V>(
643637
} else {
644638
targetNode.mutableRemove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
645639
}
646-
checkNotNull(newNode)
647640
if (ownedBy === mutator.ownership || targetNode !== newNode) {
648641
return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
649642
}

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

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ internal class PersistentHashSet<E>(internal val node: TrieNode<E>,
2727
override fun remove(element: E): PersistentSet<E> {
2828
val newNode = node.remove(element.hashCode(), element, 0)
2929
if (node === newNode) { return this }
30-
if (newNode == null) { return PersistentHashSet.emptyOf() }
3130
return PersistentHashSet(newNode, size - 1)
3231
}
3332

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ internal class PersistentHashSetBuilder<E>(private var set: PersistentHashSet<E>
4646
override fun remove(element: E): Boolean {
4747
val size = this.size
4848
@Suppress("UNCHECKED_CAST")
49-
node = node.mutableRemove(element.hashCode(), element, 0, this) ?: TrieNode.EMPTY as TrieNode<E>
49+
node = node.mutableRemove(element.hashCode(), element, 0, this)
5050
return size != this.size
5151
}
5252

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

Lines changed: 10 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -186,18 +186,17 @@ internal class TrieNode<E>(
186186
}
187187

188188

189-
private fun removeCellAtIndex(cellIndex: Int, positionMask: Int): TrieNode<E>? {
189+
private fun removeCellAtIndex(cellIndex: Int, positionMask: Int): TrieNode<E> {
190190
// assert(!hasNoCellAt(positionMask))
191-
// It is possible only when this node is the root node
192-
if (buffer.size == 1) return null
191+
// assert(buffer.size > 1) can be false only for the root node
193192

194193
val newBuffer = buffer.removeCellAtIndex(cellIndex)
195194
return TrieNode(bitmap xor positionMask, newBuffer)
196195
}
197196

198-
private fun mutableRemoveCellAtIndex(cellIndex: Int, positionMask: Int, owner: MutabilityOwnership): TrieNode<E>? {
197+
private fun mutableRemoveCellAtIndex(cellIndex: Int, positionMask: Int, owner: MutabilityOwnership): TrieNode<E> {
199198
// assert(!hasNoCellAt(positionMask))
200-
if (buffer.size == 1) return null
199+
// assert(buffer.size > 1)
201200

202201
if (ownedBy === owner) {
203202
buffer = buffer.removeCellAtIndex(cellIndex)
@@ -208,16 +207,12 @@ internal class TrieNode<E>(
208207
return TrieNode(bitmap xor positionMask, newBuffer, owner)
209208
}
210209

211-
private fun collisionRemoveElementAtIndex(i: Int): TrieNode<E>? {
212-
if (buffer.size == 1) return null
213-
210+
private fun collisionRemoveElementAtIndex(i: Int): TrieNode<E> {
214211
val newBuffer = buffer.removeCellAtIndex(i)
215212
return TrieNode(0, newBuffer)
216213
}
217214

218-
private fun mutableCollisionRemoveElementAtIndex(i: Int, owner: MutabilityOwnership): TrieNode<E>? {
219-
if (buffer.size == 1) return null
220-
215+
private fun mutableCollisionRemoveElementAtIndex(i: Int, owner: MutabilityOwnership): TrieNode<E> {
221216
if (ownedBy === owner) {
222217
buffer = buffer.removeCellAtIndex(i)
223218
return this
@@ -247,15 +242,15 @@ internal class TrieNode<E>(
247242
return TrieNode(0, newBuffer, mutator.ownership)
248243
}
249244

250-
private fun collisionRemove(element: E): TrieNode<E>? {
245+
private fun collisionRemove(element: E): TrieNode<E> {
251246
val index = buffer.indexOf(element)
252247
if (index != -1) {
253248
return collisionRemoveElementAtIndex(index)
254249
}
255250
return this
256251
}
257252

258-
private fun mutableCollisionRemove(element: E, mutator: PersistentHashSetBuilder<*>): TrieNode<E>? {
253+
private fun mutableCollisionRemove(element: E, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
259254
val index = buffer.indexOf(element)
260255
if (index != -1) {
261256
mutator.size--
@@ -331,7 +326,7 @@ internal class TrieNode<E>(
331326
return mutableMoveElementToNode(cellIndex, elementHash, element, shift, mutator.ownership)
332327
}
333328

334-
fun remove(elementHash: Int, element: E, shift: Int): TrieNode<E>? {
329+
fun remove(elementHash: Int, element: E, shift: Int): TrieNode<E> {
335330
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
336331

337332
if (hasNoCellAt(cellPositionMask)) { // element is absent
@@ -346,7 +341,6 @@ internal class TrieNode<E>(
346341
} else {
347342
targetNode.remove(elementHash, element, shift + LOG_MAX_BRANCHING_FACTOR)
348343
}
349-
checkNotNull(newNode)
350344
if (targetNode === newNode) return this
351345
return updateNodeAtIndex(cellIndex, newNode)
352346
}
@@ -357,7 +351,7 @@ internal class TrieNode<E>(
357351
return this
358352
}
359353

360-
fun mutableRemove(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E>? {
354+
fun mutableRemove(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
361355
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
362356

363357
if (hasNoCellAt(cellPositionMask)) { // element is absent
@@ -372,7 +366,6 @@ internal class TrieNode<E>(
372366
} else {
373367
targetNode.mutableRemove(elementHash, element, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
374368
}
375-
checkNotNull(newNode)
376369
if (ownedBy === mutator.ownership || targetNode !== newNode) {
377370
return mutableUpdateNodeAtIndex(cellIndex, newNode, mutator.ownership)
378371
}

0 commit comments

Comments
 (0)