summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/mutable/HashMap.scala31
1 files changed, 31 insertions, 0 deletions
diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala
index eab4202353..11ff1f0893 100644
--- a/src/library/scala/collection/mutable/HashMap.scala
+++ b/src/library/scala/collection/mutable/HashMap.scala
@@ -72,6 +72,37 @@ extends AbstractMap[A, B]
else Some(e.value)
}
+ override def getOrElseUpdate(key: A, defaultValue: => B): B = {
+ val i = index(elemHashCode(key))
+ val entry = findEntry(key, i)
+ if (entry != null) entry.value
+ else addEntry(createNewEntry(key, defaultValue), i)
+ }
+
+ /* inlined HashTable.findEntry0 to preserve its visibility */
+ private[this] def findEntry(key: A, h: Int): Entry = {
+ var e = table(h).asInstanceOf[Entry]
+ while (notFound(key, e))
+ e = e.next
+ e
+ }
+ private[this] def notFound(key: A, e: Entry): Boolean = (e != null) && !elemEquals(e.key, key)
+
+ /* inlined HashTable.addEntry0 to preserve its visibility */
+ private[this] def addEntry(e: Entry, h: Int): B = {
+ if (tableSize >= threshold) addEntry(e)
+ else addEntry0(e, h)
+ e.value
+ }
+
+ /* extracted to make addEntry inlinable */
+ private[this] def addEntry0(e: Entry, h: Int) {
+ e.next = table(h).asInstanceOf[Entry]
+ table(h) = e
+ tableSize += 1
+ nnSizeMapAdd(h)
+ }
+
override def put(key: A, value: B): Option[B] = {
val e = findOrAddEntry(key, value)
if (e eq null) None