Skip to content

Commit 36ffd1d

Browse files
committed
Refactor TrieNode of PersistentHashMap
1 parent cc93239 commit 36ffd1d

File tree

4 files changed

+263
-188
lines changed

4 files changed

+263
-188
lines changed

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,8 @@ internal class PersistentHashMap<K, V>(internal val node: TrieNode<K, V>,
9595
}
9696

9797
internal companion object {
98-
private val EMPTY = PersistentHashMap(TrieNode.EMPTY, 0)
98+
private val EMPTY = PersistentHashMap<Nothing, Nothing>(TrieNode.EMPTY, 0)
99+
@Suppress("UNCHECKED_CAST")
99100
internal fun <K, V> emptyOf(): PersistentHashMap<K, V> = EMPTY as PersistentHashMap<K, V>
100101
}
101102
}

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

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -72,28 +72,28 @@ internal abstract class PersistentHashMapBuilderBaseIterator<K, V, T>(private va
7272

7373
private fun resetPath(keyHash: Int, node: TrieNode<*, *>, key: K, pathIndex: Int) {
7474
val shift = pathIndex * LOG_MAX_BRANCHING_FACTOR
75-
val keyPosition = 1 shl ((keyHash shr shift) and MAX_BRANCHING_FACTOR_MINUS_ONE)
75+
val keyPositionMask = 1 shl indexSegment(keyHash, shift)
7676

77-
if (node.hasDataAt(keyPosition)) { // key is directly in buffer
78-
val keyIndex = node.keyDataIndex(keyPosition)
77+
if (node.hasEntryAt(keyPositionMask)) { // key is directly in buffer
78+
val keyIndex = node.entryKeyIndex(keyPositionMask)
7979

8080
// assert(node.keyAtIndex(keyIndex) == key)
8181

82-
path[pathIndex].reset(node.buffer, 2 * Integer.bitCount(node.dataMap), keyIndex)
82+
path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), keyIndex)
8383
return
8484
}
8585

8686
// assert(node.hasNodeAt(keyPosition)) // key is in node
8787

88-
val nodeIndex = node.keyNodeIndex(keyPosition)
88+
val nodeIndex = node.nodeIndex(keyPositionMask)
8989
val targetNode = node.nodeAtIndex(nodeIndex)
9090
if (shift == MAX_SHIFT) { // collision
9191
path[pathIndex].reset(node.buffer, node.buffer.size, 0)
9292
while (path[pathIndex].currentKey() != key) {
9393
path[pathIndex].moveToNextKey()
9494
}
9595
} else {
96-
path[pathIndex].reset(node.buffer, 2 * Integer.bitCount(node.dataMap), nodeIndex)
96+
path[pathIndex].reset(node.buffer, ENTRY_SIZE * node.entryCount(), nodeIndex)
9797
resetPath(keyHash, targetNode, key, pathIndex + 1)
9898
}
9999
}

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

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ internal const val TRIE_MAX_HEIGHT = 7
44

55
internal abstract class TrieNodeBaseIterator<out K, out V, out T> : Iterator<T> {
66
protected var buffer = emptyArray<Any?>()
7+
private set
78
private var dataSize = 0
89
protected var index = 0
910

@@ -90,7 +91,7 @@ internal abstract class PersistentHashMapBaseIterator<K, V, T>(node: TrieNode<K,
9091
private var hasNext = true
9192

9293
init {
93-
path[0].reset(node.buffer, 2 * Integer.bitCount(node.dataMap))
94+
path[0].reset(node.buffer, ENTRY_SIZE * node.entryCount())
9495
pathLastIndex = 0
9596
ensureNextEntryIsReady()
9697
}
@@ -104,7 +105,7 @@ internal abstract class PersistentHashMapBaseIterator<K, V, T>(node: TrieNode<K,
104105
if (pathIndex == TRIE_MAX_HEIGHT - 1) { // collision
105106
path[pathIndex + 1].reset(node.buffer, node.buffer.size)
106107
} else {
107-
path[pathIndex + 1].reset(node.buffer, 2 * Integer.bitCount(node.dataMap))
108+
path[pathIndex + 1].reset(node.buffer, ENTRY_SIZE * node.entryCount())
108109
}
109110
return moveToNextNodeWithData(pathIndex + 1)
110111
}

0 commit comments

Comments
 (0)