summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2017-02-19 14:47:02 +1000
committerJason Zaugg <jzaugg@gmail.com>2017-03-03 16:04:43 +1000
commit898fa00a76286786427b093f0161ea0d3d3bae29 (patch)
treebfee66012c1423057f234fa3918da31e98ce049d /src
parentdb8520e5c45d9ce24912849fad16a5c1b54a09b9 (diff)
downloadscala-898fa00a76286786427b093f0161ea0d3d3bae29.tar.gz
scala-898fa00a76286786427b093f0161ea0d3d3bae29.tar.bz2
scala-898fa00a76286786427b093f0161ea0d3d3bae29.zip
SI-10187 Support mutation of mutable.HashMap in getOrElseUpdate
Scala 2.12.1 included optimizations to `HashMape.getOrElseUpdate` to avoid recomputing the index in the hash table when adding an the element. However, this index could be stale if the callback added elements to the map and triggered a resize. This commit checks that the table is unchanged before reusing the index, restoring the 2.12.0 behaviour.
Diffstat (limited to 'src')
-rw-r--r--src/library/scala/collection/mutable/HashMap.scala12
1 files changed, 10 insertions, 2 deletions
diff --git a/src/library/scala/collection/mutable/HashMap.scala b/src/library/scala/collection/mutable/HashMap.scala
index 11ff1f0893..de61ebb796 100644
--- a/src/library/scala/collection/mutable/HashMap.scala
+++ b/src/library/scala/collection/mutable/HashMap.scala
@@ -73,10 +73,18 @@ extends AbstractMap[A, B]
}
override def getOrElseUpdate(key: A, defaultValue: => B): B = {
- val i = index(elemHashCode(key))
+ val hash = elemHashCode(key)
+ val i = index(hash)
val entry = findEntry(key, i)
if (entry != null) entry.value
- else addEntry(createNewEntry(key, defaultValue), i)
+ else {
+ val table0 = table
+ val default = defaultValue
+ // Avoid recomputing index if the `defaultValue()` hasn't triggered
+ // a table resize.
+ val newEntryIndex = if (table0 eq table) i else index(hash)
+ addEntry(createNewEntry(key, default), newEntryIndex)
+ }
}
/* inlined HashTable.findEntry0 to preserve its visibility */