Skip to content

Commit c2d6724

Browse files
authored
Merge pull request scala#7108 from retronym/champ/some-box
Avoid Some boxing in HashMap.apply
2 parents e8521eb + d997702 commit c2d6724

File tree

1 file changed

+28
-3
lines changed

1 file changed

+28
-3
lines changed

src/library/scala/collection/immutable/ChampHashMap.scala

Lines changed: 28 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,12 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
7979
rootNode.containsKey(key, keyUnimprovedHash, keyHash, 0)
8080
}
8181

82+
override def apply(key: K): V = {
83+
val keyUnimprovedHash = key.##
84+
val keyHash = improve(keyUnimprovedHash)
85+
rootNode.apply(key, keyUnimprovedHash, keyHash, 0)
86+
}
87+
8288
def get(key: K): Option[V] = {
8389
val keyUnimprovedHash = key.##
8490
val keyHash = improve(keyUnimprovedHash)
@@ -100,7 +106,7 @@ final class HashMap[K, +V] private[immutable] (private[immutable] val rootNode:
100106
if (newRootNode ne rootNode) {
101107
val replaced = rootNode.size == newRootNode.size
102108
val newCachedJavaKeySetHashCode = cachedJavaKeySetHashCode + (if (replaced) 0 else keyHash)
103-
HashMap(newRootNode.get, newCachedJavaKeySetHashCode)
109+
HashMap(newRootNode, newCachedJavaKeySetHashCode)
104110
} else
105111
this
106112
}
@@ -589,8 +595,7 @@ private[immutable] object MapNode {
589595

590596

591597
private[immutable] sealed abstract class MapNode[K, +V] extends Node[MapNode[K, V @uV]] {
592-
final def get: MapNode[K, V] = this
593-
598+
def apply(key: K, originalHash: Int, hash: Int, shift: Int): V
594599
def get(key: K, originalHash: Int, hash: Int, shift: Int): Option[V]
595600
def getOrElse[V1 >: V](key: K, originalHash: Int, hash: Int, shift: Int, f: => V1): V1
596601

@@ -671,6 +676,24 @@ private final class BitmapIndexedMapNode[K, +V](
671676
def getNode(index: Int) =
672677
content(content.length - 1 - index).asInstanceOf[MapNode[K, V]]
673678

679+
def apply(key: K, originalHash: Int, keyHash: Int, shift: Int): V = {
680+
val mask = maskFrom(keyHash, shift)
681+
val bitpos = bitposFrom(mask)
682+
683+
if ((dataMap & bitpos) != 0) {
684+
val index = indexFrom(dataMap, mask, bitpos)
685+
val key0 = this.getKey(index)
686+
return if (key == key0) this.getValue(index) else throw new NoSuchElementException
687+
}
688+
689+
if ((nodeMap & bitpos) != 0) {
690+
val index = indexFrom(nodeMap, mask, bitpos)
691+
return this.getNode(index).apply(key, originalHash, keyHash, shift + BitPartitionSize)
692+
}
693+
694+
throw new NoSuchElementException
695+
}
696+
674697
def get(key: K, originalHash: Int, keyHash: Int, shift: Int): Option[V] = {
675698
val mask = maskFrom(keyHash, shift)
676699
val bitpos = bitposFrom(mask)
@@ -1082,6 +1105,8 @@ private final class HashCollisionMapNode[K, +V ](
10821105

10831106
def size = content.length
10841107

1108+
def apply(key: K, originalHash: Int, hash: Int, shift: Int): V = get(key, originalHash, hash, shift).getOrElse(throw new NoSuchElementException)
1109+
10851110
def get(key: K, originalHash: Int, hash: Int, shift: Int): Option[V] =
10861111
if (this.hash == hash) {
10871112
val index = indexOf(key)

0 commit comments

Comments
 (0)