summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/mutable/AnyRefMap.scala15
-rw-r--r--src/library/scala/collection/mutable/LongMap.scala15
-rw-r--r--test/junit/scala/collection/SetMapConsistencyTest.scala12
3 files changed, 38 insertions, 4 deletions
diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala
index df74bb5187..29c92a111c 100644
--- a/src/library/scala/collection/mutable/AnyRefMap.scala
+++ b/src/library/scala/collection/mutable/AnyRefMap.scala
@@ -129,9 +129,20 @@ extends AbstractMap[K, V]
override def getOrElseUpdate(key: K, defaultValue: => V): V = {
val h = hashOf(key)
- val i = seekEntryOrOpen(h, key)
+ var i = seekEntryOrOpen(h, key)
if (i < 0) {
- val value = defaultValue
+ // It is possible that the default value computation was side-effecting
+ // Our hash table may have resized or even contain what we want now
+ // (but if it does, we'll replace it)
+ val value = {
+ val oh = _hashes
+ val ans = defaultValue
+ if (oh ne _hashes) {
+ i = seekEntryOrOpen(h, key)
+ if (i >= 0) _size -= 1
+ }
+ ans
+ }
_size += 1
val j = i & IndexMask
_hashes(j) = h
diff --git a/src/library/scala/collection/mutable/LongMap.scala b/src/library/scala/collection/mutable/LongMap.scala
index 81c381279f..984ae6f7cc 100644
--- a/src/library/scala/collection/mutable/LongMap.scala
+++ b/src/library/scala/collection/mutable/LongMap.scala
@@ -160,9 +160,20 @@ extends AbstractMap[Long, V]
else minValue.asInstanceOf[V]
}
else {
- val i = seekEntryOrOpen(key)
+ var i = seekEntryOrOpen(key)
if (i < 0) {
- val value = defaultValue
+ // It is possible that the default value computation was side-effecting
+ // Our hash table may have resized or even contain what we want now
+ // (but if it does, we'll replace it)
+ val value = {
+ val ok = _keys
+ val ans = defaultValue
+ if (ok ne _keys) {
+ i = seekEntryOrOpen(key)
+ if (i >= 0) _size -= 1
+ }
+ ans
+ }
_size += 1
val j = i & IndexMask
_keys(j) = key
diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala
index c62b074483..7bb8ca958b 100644
--- a/test/junit/scala/collection/SetMapConsistencyTest.scala
+++ b/test/junit/scala/collection/SetMapConsistencyTest.scala
@@ -476,4 +476,16 @@ class SetMapConsistencyTest {
}
assert(test)
}
+
+ @Test
+ def si8213() {
+ val am = new scala.collection.mutable.AnyRefMap[String, Int]
+ for (i <- 0 until 1024) am += i.toString -> i
+ am.getOrElseUpdate("1024", { am.clear; -1 })
+ assert(am == scala.collection.mutable.AnyRefMap("1024" -> -1))
+ val lm = new scala.collection.mutable.LongMap[Int]
+ for (i <- 0 until 1024) lm += i.toLong -> i
+ lm.getOrElseUpdate(1024, { lm.clear; -1 })
+ assert(lm == scala.collection.mutable.LongMap(1024L -> -1))
+ }
}