Skip to content

Commit d7ccdc8

Browse files
author
Abduqodiri Qurbonzoda
committed
Check for collision only the leaf node
1 parent ea383a0 commit d7ccdc8

File tree

2 files changed

+51
-54
lines changed

2 files changed

+51
-54
lines changed

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

Lines changed: 34 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ internal class TrieNode<K, V>(
7676
internal var buffer: Array<Any?> = buffer
7777
private set
7878

79-
internal fun isCollision(): Boolean {
79+
@Suppress("NOTHING_TO_INLINE")
80+
internal inline fun isCollision(): Boolean {
8081
return dataMap == 0 && nodeMap == 0 && buffer.isNotEmpty()
8182
}
8283

@@ -471,10 +472,6 @@ internal class TrieNode<K, V>(
471472
}
472473

473474
fun containsKey(keyHash: Int, key: K, shift: Int): Boolean {
474-
if (isCollision()) {
475-
return collisionContainsKey(keyHash, key)
476-
}
477-
478475
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
479476

480477
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -485,15 +482,15 @@ internal class TrieNode<K, V>(
485482
return targetNode.containsKey(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR)
486483
}
487484

485+
if (isCollision()) {
486+
return collisionContainsKey(keyHash, key)
487+
}
488+
488489
// key is absent
489490
return false
490491
}
491492

492493
fun get(keyHash: Int, key: K, shift: Int): V? {
493-
if (isCollision()) {
494-
return collisionGet(keyHash, key)
495-
}
496-
497494
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
498495

499496
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -509,15 +506,15 @@ internal class TrieNode<K, V>(
509506
return targetNode.get(keyHash, key, shift + LOG_MAX_BRANCHING_FACTOR)
510507
}
511508

509+
if (isCollision()) {
510+
return collisionGet(keyHash, key)
511+
}
512+
512513
// key is absent
513514
return null
514515
}
515516

516517
fun put(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): ModificationResult<K, V>? {
517-
if (isCollision()) {
518-
return collisionPut(keyHash, key, value, shift)
519-
}
520-
521518
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
522519

523520
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -538,15 +535,15 @@ internal class TrieNode<K, V>(
538535
return putResult.replaceNode { node -> updateNodeAtIndex(nodeIndex, node) }
539536
}
540537

538+
if (isCollision()) {
539+
return collisionPut(keyHash, key, value, shift)
540+
}
541+
541542
// no entry at this key hash segment
542543
return insertEntryAt(keyPositionMask, key, value).asInsertResult()
543544
}
544545

545546
fun mutablePut(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V> {
546-
if (isCollision()) {
547-
return mutableCollisionPut(keyHash, key, value, shift, mutator)
548-
}
549-
550547
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
551548

552549
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -574,16 +571,16 @@ internal class TrieNode<K, V>(
574571
return mutableUpdateNodeAtIndex(nodeIndex, newNode, mutator.ownership)
575572
}
576573

574+
if (isCollision()) {
575+
return mutableCollisionPut(keyHash, key, value, shift, mutator)
576+
}
577+
577578
// key is absent
578579
mutator.size++
579580
return mutableInsertEntryAt(keyPositionMask, key, value, mutator.ownership)
580581
}
581582

582583
fun remove(keyHash: Int, key: K, shift: Int): TrieNode<K, V>? {
583-
if (isCollision()) {
584-
return collisionRemove(keyHash, key)
585-
}
586-
587584
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
588585

589586
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -606,15 +603,15 @@ internal class TrieNode<K, V>(
606603
}
607604
}
608605

606+
if (isCollision()) {
607+
return collisionRemove(keyHash, key)
608+
}
609+
609610
// key is absent
610611
return this
611612
}
612613

613614
fun mutableRemove(keyHash: Int, key: K, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
614-
if (isCollision()) {
615-
return mutableCollisionRemove(keyHash, key, mutator)
616-
}
617-
618615
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
619616

620617
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -637,15 +634,15 @@ internal class TrieNode<K, V>(
637634
}
638635
}
639636

637+
if (isCollision()) {
638+
return mutableCollisionRemove(keyHash, key, mutator)
639+
}
640+
640641
// key is absent
641642
return this
642643
}
643644

644645
fun remove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int): TrieNode<K, V>? {
645-
if (isCollision()) {
646-
return collisionRemove(keyHash, key, value)
647-
}
648-
649646
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
650647

651648
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -668,15 +665,15 @@ internal class TrieNode<K, V>(
668665
}
669666
}
670667

668+
if (isCollision()) {
669+
return collisionRemove(keyHash, key, value)
670+
}
671+
671672
// key is absent
672673
return this
673674
}
674675

675676
fun mutableRemove(keyHash: Int, key: K, value: @UnsafeVariance V, shift: Int, mutator: PersistentHashMapBuilder<K, V>): TrieNode<K, V>? {
676-
if (isCollision()) {
677-
return mutableCollisionRemove(keyHash, key, value, mutator)
678-
}
679-
680677
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
681678

682679
if (hasEntryAt(keyPositionMask)) { // key is directly in buffer
@@ -699,6 +696,10 @@ internal class TrieNode<K, V>(
699696
}
700697
}
701698

699+
if (isCollision()) {
700+
return mutableCollisionRemove(keyHash, key, value, mutator)
701+
}
702+
702703
// key is absent
703704
return this
704705
}

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

Lines changed: 17 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -268,18 +268,18 @@ internal class TrieNode<E>(
268268
return makeCollisionNode(buffer.removeCellAtIndex(index), mutator.ownership)
269269
}
270270

271-
fun isCollision(): Boolean {
271+
@Suppress("NOTHING_TO_INLINE")
272+
inline fun isCollision(): Boolean {
272273
return bitmap == 0 && buffer.isNotEmpty()
273274
}
274275

275276
fun contains(elementHash: Int, element: E, shift: Int): Boolean {
276-
if (isCollision()) {
277-
return collisionContains(elementHash, element)
278-
}
279-
280277
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
281278

282279
if (hasNoCellAt(cellPositionMask)) { // element is absent
280+
if (isCollision()) {
281+
return collisionContains(elementHash, element)
282+
}
283283
return false
284284
}
285285

@@ -293,13 +293,12 @@ internal class TrieNode<E>(
293293
}
294294

295295
fun add(elementHash: Int, element: E, shift: Int): TrieNode<E> {
296-
if (isCollision()) {
297-
return collisionAdd(elementHash, element, shift)
298-
}
299-
300296
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
301297

302298
if (hasNoCellAt(cellPositionMask)) { // element is absent
299+
if (isCollision()) {
300+
return collisionAdd(elementHash, element, shift)
301+
}
303302
return addElementAt(cellPositionMask, element)
304303
}
305304

@@ -316,13 +315,12 @@ internal class TrieNode<E>(
316315
}
317316

318317
fun mutableAdd(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E> {
319-
if (isCollision()) {
320-
return collisionMutableAdd(elementHash, element, shift, mutator)
321-
}
322-
323318
val cellPosition = 1 shl indexSegment(elementHash, shift)
324319

325320
if (hasNoCellAt(cellPosition)) { // element is absent
321+
if (isCollision()) {
322+
return collisionMutableAdd(elementHash, element, shift, mutator)
323+
}
326324
mutator.size++
327325
return mutableAddElementAt(cellPosition, element, mutator.ownership)
328326
}
@@ -341,13 +339,12 @@ internal class TrieNode<E>(
341339
}
342340

343341
fun remove(elementHash: Int, element: E, shift: Int): TrieNode<E>? {
344-
if (isCollision()) {
345-
return collisionRemove(elementHash, element)
346-
}
347-
348342
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
349343

350344
if (hasNoCellAt(cellPositionMask)) { // element is absent
345+
if (isCollision()) {
346+
return collisionRemove(elementHash, element)
347+
}
351348
return this
352349
}
353350

@@ -369,13 +366,12 @@ internal class TrieNode<E>(
369366
}
370367

371368
fun mutableRemove(elementHash: Int, element: E, shift: Int, mutator: PersistentHashSetBuilder<*>): TrieNode<E>? {
372-
if (isCollision()) {
373-
return collisionMutableRemove(elementHash, element, mutator)
374-
}
375-
376369
val cellPositionMask = 1 shl indexSegment(elementHash, shift)
377370

378371
if (hasNoCellAt(cellPositionMask)) { // element is absent
372+
if (isCollision()) {
373+
return collisionMutableRemove(elementHash, element, mutator)
374+
}
379375
return this
380376
}
381377

0 commit comments

Comments
 (0)