summaryrefslogtreecommitdiff
path: root/test/files/run
diff options
context:
space:
mode:
authorRex Kerr <ichoran@gmail.com>2013-11-11 03:45:48 -0800
committerRex Kerr <ichoran@gmail.com>2013-11-18 01:41:50 -0800
commit992b90ebcc8cd3415c288a7258015ec35ed9098e (patch)
treeebb02a319ee664b28c981c99bad840ddc5f834d6 /test/files/run
parent05aedd936e7e7bcf0fa2443abd58b39732f173a9 (diff)
downloadscala-992b90ebcc8cd3415c288a7258015ec35ed9098e.tar.gz
scala-992b90ebcc8cd3415c288a7258015ec35ed9098e.tar.bz2
scala-992b90ebcc8cd3415c288a7258015ec35ed9098e.zip
New AnyRefMap fixes SI-5263 to the extent practical.
An open addressing hash map based on a similar scheme to mutable.LongMap. It delivers performance equivalent to Java's HashMap for pretty much all AnyRefs, plus it works nicely with Scala's collections. Revisions made sure that all return types in the public API are specified. Also switched to a leading-zeros method of calculating the initial mask (to save a few ns). Also edited out java.util comparison numbers and moved constants to companion.
Diffstat (limited to 'test/files/run')
-rw-r--r--test/files/run/mutable-anyrefmap.scala91
1 files changed, 91 insertions, 0 deletions
diff --git a/test/files/run/mutable-anyrefmap.scala b/test/files/run/mutable-anyrefmap.scala
new file mode 100644
index 0000000000..ff615d0daf
--- /dev/null
+++ b/test/files/run/mutable-anyrefmap.scala
@@ -0,0 +1,91 @@
+object Test extends App {
+
+ import scala.collection.mutable.HashMap;
+ import scala.collection.mutable.AnyRefMap;
+
+ val keys = Array(
+ null, "perch", "herring", "salmon", "pike", "cod", ""
+ )
+
+ val rn = new scala.util.Random(42L)
+ var arm = AnyRefMap.empty[String, Int]
+ val hm = HashMap.empty[String, Int]
+
+ def checkConsistent = hm.forall{ case (k,v) => arm.get(k).exists(_ == v) }
+
+ assert {
+ (0 to 10000).forall{ i =>
+ val k = keys(rn.nextInt(keys.length))
+ if (rn.nextInt(100) < 2) arm = arm.clone()
+ if (rn.nextInt(100) < 5) arm.repack()
+ if (rn.nextBoolean) {
+ hm += ((k, i))
+ rn.nextInt(6) match {
+ case 0 => arm += ((k, i))
+ case 1 => arm += (k, i)
+ case 2 => arm(k) = i
+ case 3 => arm.put(k,i)
+ case 4 => arm ++= List((k,i))
+ case _ => if (!arm.contains(k)) arm.getOrElseUpdate(k,i)
+ else arm += (k,i)
+ }
+ }
+ else {
+ hm -= k
+ rn.nextInt(2) match {
+ case 0 => arm -= k
+ case _ => arm --= List(k)
+ }
+ }
+ checkConsistent
+ }
+ }
+
+ assert {
+ val mapped =
+ arm.map{ case (k,v) => (if (k==null) "" else k+k) -> v.toString }
+ mapped.getClass == arm.getClass
+ }
+
+ assert {
+ val arm2 = new AnyRefMap[java.lang.Integer,Unit](2000000)
+ for (i <- 0 until 1000000) arm2(java.lang.Integer.valueOf(i)) = ()
+
+ arm2.size == 1000000 &&
+ (0 to 1100000 by 100000).map(java.lang.Integer.valueOf).forall(i => (arm2 contains i) == i < 1000000)
+ }
+
+ arm = AnyRefMap("heron" -> 22, "dove" -> 5, "budgie" -> 0)
+
+ assert{
+ var s = ""
+ arm.foreachKey(s += _)
+
+ s.length == "herondovebudgie".length &&
+ s.contains("heron") &&
+ s.contains("dove") &&
+ s.contains("budgie")
+ }
+
+ assert{ var s = 0L; arm.foreachValue(s += _); s == 27L }
+
+ assert {
+ val m2 = arm.mapValuesNow(_+2)
+ arm.transformValues(_+2)
+ m2 == arm && !(m2 eq arm) && (for ((_,v) <- arm) yield v).sum == 33L
+ }
+
+ assert {
+ val arm2 = new AnyRefMap[String, String](x => if (x==null) "null" else x)
+ arm2 += ("cod" -> "fish", "Rarity" -> "unicorn")
+ val hm2 = (new HashMap[String,String]) ++= arm2
+
+ List(null, "cod", "sparrow", "Rarity").forall(i =>
+ arm2.get(i) == hm2.get(i) &&
+ arm2.getOrElse(i, "") == hm2.getOrElse(i, "") &&
+ arm2(i) == hm2.get(i).getOrElse(if (i==null) "null" else i.toString) &&
+ arm2.getOrNull(i) == hm2.get(i).orNull
+ )
+ }
+}
+