Skip to content

Commit 8dc8c13

Browse files
author
Abduqodiri Qurbonzoda
committed
Return nonnull node from remove method
1 parent 3525070 commit 8dc8c13

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
@@ -292,20 +292,18 @@ internal class TrieNode<K, V>(
292292
return TrieNode(0, 1 shl setBit1, arrayOf<Any?>(node), owner)
293293
}
294294

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

304-
private fun mutableRemoveEntryAtIndex(keyIndex: Int, positionMask: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
302+
private fun mutableRemoveEntryAtIndex(keyIndex: Int, positionMask: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
305303
// assert(hasEntryAt(positionMask))
304+
// assert(buffer.size > ENTRY_SIZE)
306305
mutator.size--
307306
mutator.operationResult = valueAtKeyIndex(keyIndex)
308-
if (buffer.size == ENTRY_SIZE) return null
309307

310308
if (ownedBy === mutator.ownership) {
311309
buffer = buffer.removeEntryAtIndex(keyIndex)
@@ -316,17 +314,16 @@ internal class TrieNode<K, V>(
316314
return TrieNode(dataMap xor positionMask, nodeMap, newBuffer, mutator.ownership)
317315
}
318316

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

326-
private fun mutableCollisionRemoveEntryAtIndex(i: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
323+
private fun mutableCollisionRemoveEntryAtIndex(i: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
324+
// assert(buffer.size > ENTRY_SIZE)
327325
mutator.size--
328326
mutator.operationResult = valueAtKeyIndex(i)
329-
if (buffer.size == ENTRY_SIZE) return null
330327

331328
if (ownedBy === mutator.ownership) {
332329
buffer = buffer.removeEntryAtIndex(i)
@@ -393,7 +390,7 @@ internal class TrieNode<K, V>(
393390
return TrieNode(0, 0, newBuffer, mutator.ownership)
394391
}
395392

396-
private fun collisionRemove(key: K): TrieNode<K, V>? {
393+
private fun collisionRemove(key: K): TrieNode<K, V> {
397394
for (i in 0 until buffer.size step ENTRY_SIZE) {
398395
if (key == keyAtIndex(i)) {
399396
return collisionRemoveEntryAtIndex(i)
@@ -402,7 +399,7 @@ internal class TrieNode<K, V>(
402399
return this
403400
}
404401

405-
private fun mutableCollisionRemove(key: K, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
402+
private fun mutableCollisionRemove(key: K, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
406403
for (i in 0 until buffer.size step ENTRY_SIZE) {
407404
if (key == keyAtIndex(i)) {
408405
return mutableCollisionRemoveEntryAtIndex(i, mutator)
@@ -411,7 +408,7 @@ internal class TrieNode<K, V>(
411408
return this
412409
}
413410

414-
private fun collisionRemove(key: K, value: V): TrieNode<K, V>? {
411+
private fun collisionRemove(key: K, value: V): TrieNode<K, V> {
415412
for (i in 0 until buffer.size step ENTRY_SIZE) {
416413
if (key == keyAtIndex(i) && value == valueAtKeyIndex(i)) {
417414
return collisionRemoveEntryAtIndex(i)
@@ -420,7 +417,7 @@ internal class TrieNode<K, V>(
420417
return this
421418
}
422419

423-
private fun mutableCollisionRemove(key: K, value: V, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
420+
private fun mutableCollisionRemove(key: K, value: V, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
424421
for (i in 0 until buffer.size step ENTRY_SIZE) {
425422
if (key == keyAtIndex(i) && value == valueAtKeyIndex(i)) {
426423
return mutableCollisionRemoveEntryAtIndex(i, mutator)
@@ -536,7 +533,7 @@ internal class TrieNode<K, V>(
536533
return mutableInsertEntryAt(keyPositionMask, key, value, mutator.ownership)
537534
}
538535

539-
fun remove(keyHash: Int, key: K, shift: Int): TrieNode<K, V>? {
536+
fun remove(keyHash: Int, key: K, shift: Int): TrieNode<K, V> {
540537
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
541538

542539
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -556,7 +553,6 @@ internal class TrieNode<K, V>(
556553
} else {
557554
targetNode.remove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR)
558555
}
559-
checkNotNull(newNode)
560556
if (targetNode === newNode) return this
561557
return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
562558
}
@@ -565,7 +561,7 @@ internal class TrieNode<K, V>(
565561
return this
566562
}
567563

568-
fun mutableRemove(keyHash: Int, key: K, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
564+
fun mutableRemove(keyHash: Int, key: K, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
569565
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
570566

571567
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -585,7 +581,6 @@ internal class TrieNode<K, V>(
585581
} else {
586582
targetNode.mutableRemove(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
587583
}
588-
checkNotNull(newNode)
589584
if (ownedBy === mutator.ownership || targetNode !== newNode) {
590585
return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
591586
}
@@ -596,7 +591,7 @@ internal class TrieNode<K, V>(
596591
return this
597592
}
598593

599-
fun remove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): TrieNode<K, V>? {
594+
fun remove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): TrieNode<K, V> {
600595
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
601596

602597
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -616,7 +611,6 @@ internal class TrieNode<K, V>(
616611
} else {
617612
targetNode.remove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR)
618613
}
619-
checkNotNull(newNode)
620614
if (targetNode === newNode) return this
621615
return updateNodeAtIndex(nodeIndex, keyPositionMask, newNode)
622616
}
@@ -625,7 +619,7 @@ internal class TrieNode<K, V>(
625619
return this
626620
}
627621

628-
fun mutableRemove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
622+
fun mutableRemove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
629623
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
630624

631625
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -645,7 +639,6 @@ internal class TrieNode<K, V>(
645639
} else {
646640
targetNode.mutableRemove(keyHash, key, value, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
647641
}
648-
checkNotNull(newNode)
649642
if (ownedBy === mutator.ownership || targetNode !== newNode) {
650643
return mutableUpdateNodeAtIndex(nodeIndex, keyPositionMask, newNode, mutator.ownership)
651644
}

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
@@ -188,18 +188,17 @@ internal class TrieNode<E>(
188188
}
189189

190190

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

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

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

204203
if (ownedBy === owner) {
205204
buffer = buffer.removeCellAtIndex(cellIndex)
@@ -210,16 +209,12 @@ internal class TrieNode<E>(
210209
return TrieNode(bitmap xor positionMask, newBuffer, owner)
211210
}
212211

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

220-
private fun mutableCollisionRemoveElementAtIndex(i: Int, owner: MutabilityOwnership): TrieNode<E>? {
221-
if (buffer.size == 1) return null
222-
217+
private fun mutableCollisionRemoveElementAtIndex(i: Int, owner: MutabilityOwnership): TrieNode<E> {
223218
if (ownedBy === owner) {
224219
buffer = buffer.removeCellAtIndex(i)
225220
return this
@@ -249,15 +244,15 @@ internal class TrieNode<E>(
249244
return TrieNode(0, newBuffer, mutator.ownership)
250245
}
251246

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

260-
private fun mutableCollisionRemove(element: E, mutator: PersistentHashSetBuilder<*>): TrieNode<E>? {
255+
private fun mutableCollisionRemove(element: E, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
261256
val index = buffer.indexOf(element)
262257
if (index != -1) {
263258
mutator.size--
@@ -333,7 +328,7 @@ internal class TrieNode<E>(
333328
return mutableMoveElementToNode(cellIndex, elementHash, element, shift, mutator.ownership)
334329
}
335330

336-
fun remove(elementHash: Int, element: E, shift: Int): TrieNode<E>? {
331+
fun remove(elementHash: Int, element: E, shift: Int): TrieNode<E> {
337332
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
338333

339334
if (hasNoCellAt(cellPositionMask)) { // element is absent
@@ -348,7 +343,6 @@ internal class TrieNode<E>(
348343
} else {
349344
targetNode.remove(elementHash, element, shift + LOG_MAX_BRANCHING_FACTOR)
350345
}
351-
checkNotNull(newNode)
352346
if (targetNode === newNode) return this
353347
return updateNodeAtIndex(cellIndex, newNode)
354348
}
@@ -359,7 +353,7 @@ internal class TrieNode<E>(
359353
return this
360354
}
361355

362-
fun mutableRemove(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E>? {
356+
fun mutableRemove(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
363357
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
364358

365359
if (hasNoCellAt(cellPositionMask)) { // element is absent
@@ -374,7 +368,6 @@ internal class TrieNode<E>(
374368
} else {
375369
targetNode.mutableRemove(elementHash, element, shift + LOG_MAX_BRANCHING_FACTOR, mutator)
376370
}
377-
checkNotNull(newNode)
378371
if (ownedBy === mutator.ownership || targetNode !== newNode) {
379372
return mutableUpdateNodeAtIndex(cellIndex, newNode, mutator.ownership)
380373
}

0 commit comments

Comments
 (0)