summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPerformant Data LLC <performantdata@users.noreply.github.com>2015-10-10 00:02:25 -0700
committerPerformant Data LLC <performantdata@users.noreply.github.com>2015-10-10 00:02:25 -0700
commit1fb32fcf04386f52e72522bd688e69edafd95414 (patch)
treebd1a81c9598de84e3c281e5b83f0d6970e1226ca
parent648c7a1635f88fb14b999a8d36e01a71761b9001 (diff)
downloadscala-1fb32fcf04386f52e72522bd688e69edafd95414.tar.gz
scala-1fb32fcf04386f52e72522bd688e69edafd95414.tar.bz2
scala-1fb32fcf04386f52e72522bd688e69edafd95414.zip
SI-9513 decrement "deleted" count in OpenHashMap.put() when slot reused
-rw-r--r--src/library/scala/collection/mutable/OpenHashMap.scala6
-rw-r--r--test/junit/scala/collection/mutable/OpenHashMapTest.scala42
2 files changed, 47 insertions, 1 deletions
diff --git a/src/library/scala/collection/mutable/OpenHashMap.scala b/src/library/scala/collection/mutable/OpenHashMap.scala
index 24f5761cf5..094f7eb63e 100644
--- a/src/library/scala/collection/mutable/OpenHashMap.scala
+++ b/src/library/scala/collection/mutable/OpenHashMap.scala
@@ -136,7 +136,11 @@ extends AbstractMap[Key, Value]
None
} else {
val res = entry.value
- if (entry.value == None) { size += 1; modCount += 1 }
+ if (entry.value == None) {
+ size += 1
+ deleted -= 1
+ modCount += 1
+ }
entry.value = Some(value)
res
}
diff --git a/test/junit/scala/collection/mutable/OpenHashMapTest.scala b/test/junit/scala/collection/mutable/OpenHashMapTest.scala
new file mode 100644
index 0000000000..5e72727183
--- /dev/null
+++ b/test/junit/scala/collection/mutable/OpenHashMapTest.scala
@@ -0,0 +1,42 @@
+package scala.collection.mutable
+
+import org.junit.Test
+import org.junit.Assert._
+import org.junit.runner.RunWith
+import org.junit.runners.JUnit4
+
+/** Tests for [[OpenHashMap]]. */
+@RunWith(classOf[JUnit4])
+class OpenHashMapTest {
+ /** Test that an [[OpenHashMap]] correctly maintains its internal `deleted` count. */
+ @Test
+ def maintainsDeletedCount {
+ import scala.reflect.runtime.{universe => ru}
+
+ val m = OpenHashMap.empty[Int, Int]
+
+ // Reflect to get the private `deleted` field's value, which should be zero.
+
+ /* TODO Doesn't work, due to SI-9306.
+ val mirror = ru.runtimeMirror(m.getClass.getClassLoader)
+ val mapType = ru.typeOf[OpenHashMap[Int, Int]]
+ val termSym = mapType.decls
+ .filterNot { s => s.isMethod }
+ .filter { s => s.fullName.endsWith("deleted") }
+ .head.asTerm
+
+ val fieldMirror = mirror.reflect(m).reflectField(termSym)
+ */
+ // Use Java reflection instead for now.
+ val field = m.getClass.getDeclaredField("scala$collection$mutable$OpenHashMap$$deleted")
+ field.setAccessible(true)
+
+ m.put(0, 0)
+ m.remove(0)
+ assertEquals(1, field.getInt(m))
+
+ m.put(0, 0) // Add an entry with the same key
+ // TODO assertEquals(0, fieldMirror.get.asInstanceOf[Int])
+ assertEquals(0, field.getInt(m))
+ }
+}