summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/library/scala/collection/mutable/AnyRefMap.scala27
-rw-r--r--test/junit/scala/collection/SetMapConsistencyTest.scala21
2 files changed, 32 insertions, 16 deletions
diff --git a/src/library/scala/collection/mutable/AnyRefMap.scala b/src/library/scala/collection/mutable/AnyRefMap.scala
index 29c92a111c..47fb66744e 100644
--- a/src/library/scala/collection/mutable/AnyRefMap.scala
+++ b/src/library/scala/collection/mutable/AnyRefMap.scala
@@ -22,9 +22,9 @@ import generic.CanBuildFrom
* on a map that will no longer have elements removed but will be
* used heavily may save both time and storage space.
*
- * This map is not indended to contain more than 2^29 entries (approximately
- * 500 million). The maximum capacity is 2^30, but performance will degrade
- * rapidly as 2^30 is approached.
+ * This map is not intended to contain more than 2^29^ entries (approximately
+ * 500 million). The maximum capacity is 2^30^, but performance will degrade
+ * rapidly as 2^30^ is approached.
*
*/
final class AnyRefMap[K <: AnyRef, V] private[collection] (defaultEntry: K => V, initialBufferSize: Int, initBlank: Boolean)
@@ -291,24 +291,21 @@ extends AbstractMap[K, V]
private[this] val vz = _values
private[this] var index = 0
- private[this] var found = false
- def hasNext = found || (index<hz.length && {
+ def hasNext: Boolean = index<hz.length && {
var h = hz(index)
- if (h+h != 0) found = true
- else {
+ while (h+h == 0) {
index += 1
- while (index < hz.length && { h = hz(index); h+h == 0 }) index += 1
- found = (index < hz.length)
+ if (index >= hz.length) return false
+ h = hz(index)
}
- found
- })
+ true
+ }
- def next = {
- if (found || hasNext) {
- val ans = (_keys(index).asInstanceOf[K], _values(index).asInstanceOf[V])
+ def next: (K, V) = {
+ if (hasNext) {
+ val ans = (kz(index).asInstanceOf[K], vz(index).asInstanceOf[V])
index += 1
- found = false
ans
}
else throw new NoSuchElementException("next")
diff --git a/test/junit/scala/collection/SetMapConsistencyTest.scala b/test/junit/scala/collection/SetMapConsistencyTest.scala
index 7bb8ca958b..0d6f43db06 100644
--- a/test/junit/scala/collection/SetMapConsistencyTest.scala
+++ b/test/junit/scala/collection/SetMapConsistencyTest.scala
@@ -478,7 +478,7 @@ class SetMapConsistencyTest {
}
@Test
- def si8213() {
+ def testSI8213() {
val am = new scala.collection.mutable.AnyRefMap[String, Int]
for (i <- 0 until 1024) am += i.toString -> i
am.getOrElseUpdate("1024", { am.clear; -1 })
@@ -488,4 +488,23 @@ class SetMapConsistencyTest {
lm.getOrElseUpdate(1024, { lm.clear; -1 })
assert(lm == scala.collection.mutable.LongMap(1024L -> -1))
}
+
+ // Mutating when an iterator is in the wild shouldn't produce random junk in the iterator
+ // Todo: test all sets/maps this way
+ @Test
+ def testSI8154() {
+ def f() = {
+ val xs = scala.collection.mutable.AnyRefMap[String, Int]("a" -> 1)
+ val it = xs.iterator
+ it.hasNext
+ xs.clear()
+
+ if (it.hasNext) Some(it.next)
+ else None
+ }
+ assert(f() match {
+ case Some((a,b)) if (a==null || b==null) => false
+ case _ => true
+ })
+ }
}