summaryrefslogtreecommitdiff
path: root/test/files/run/ctries-new
diff options
context:
space:
mode:
Diffstat (limited to 'test/files/run/ctries-new')
-rw-r--r--test/files/run/ctries-new/concmap.scala62
-rw-r--r--test/files/run/ctries-new/iterator.scala114
-rw-r--r--test/files/run/ctries-new/lnode.scala18
-rw-r--r--test/files/run/ctries-new/main.scala7
-rw-r--r--test/files/run/ctries-new/snapshot.scala88
5 files changed, 139 insertions, 150 deletions
diff --git a/test/files/run/ctries-new/concmap.scala b/test/files/run/ctries-new/concmap.scala
index 3ec0256afb..76916564a7 100644
--- a/test/files/run/ctries-new/concmap.scala
+++ b/test/files/run/ctries-new/concmap.scala
@@ -5,17 +5,17 @@ import collection.concurrent.TrieMap
object ConcurrentMapSpec extends Spec {
-
+
val initsz = 500
val secondsz = 750
-
+
def test() {
"support put" in {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) assert(ct.put(new Wrap(i), i) == None)
for (i <- 0 until initsz) assert(ct.put(new Wrap(i), -i) == Some(i))
}
-
+
"support put if absent" in {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
@@ -24,7 +24,7 @@ object ConcurrentMapSpec extends Spec {
for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), -i) == None)
for (i <- initsz until secondsz) assert(ct.putIfAbsent(new Wrap(i), i) == Some(-i))
}
-
+
"support remove if mapped to a specific value" in {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
@@ -32,7 +32,7 @@ object ConcurrentMapSpec extends Spec {
for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == true)
for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), i) == false)
}
-
+
"support replace if mapped to a specific value" in {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
@@ -41,7 +41,7 @@ object ConcurrentMapSpec extends Spec {
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == false)
for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i, 0) == false)
}
-
+
"support replace if present" in {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until initsz) ct.update(new Wrap(i), i)
@@ -49,17 +49,17 @@ object ConcurrentMapSpec extends Spec {
for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i) == Some(-i))
for (i <- initsz until secondsz) assert(ct.replace(new Wrap(i), i) == None)
}
-
+
def assertEqual(a: Any, b: Any) = {
if (a != b) println(a, b)
assert(a == b)
}
-
+
"support replace if mapped to a specific value, using several threads" in {
val ct = new TrieMap[Wrap, Int]
val sz = 55000
for (i <- 0 until sz) ct.update(new Wrap(i), i)
-
+
class Updater(index: Int, offs: Int) extends Thread {
override def run() {
var repeats = 0
@@ -74,24 +74,24 @@ object ConcurrentMapSpec extends Spec {
//println("Thread %d repeats: %d".format(index, repeats))
}
}
-
+
val threads = for (i <- 0 until 16) yield new Updater(i, sz / 32 * i)
threads.foreach(_.start())
threads.foreach(_.join())
-
+
for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), i)
-
+
val threads2 = for (i <- 0 until 15) yield new Updater(i, sz / 32 * i)
threads2.foreach(_.start())
threads2.foreach(_.join())
-
+
for (i <- 0 until sz) assertEqual(ct(new Wrap(i)), -i)
}
-
+
"support put if absent, several threads" in {
val ct = new TrieMap[Wrap, Int]
val sz = 110000
-
+
class Updater(offs: Int) extends Thread {
override def run() {
for (i <- 0 until sz) {
@@ -101,19 +101,19 @@ object ConcurrentMapSpec extends Spec {
}
}
}
-
+
val threads = for (i <- 0 until 16) yield new Updater(sz / 32 * i)
threads.foreach(_.start())
threads.foreach(_.join())
-
+
for (i <- 0 until sz) assert(ct(new Wrap(i)) == i)
}
-
+
"support remove if mapped to a specific value, several threads" in {
val ct = new TrieMap[Wrap, Int]
val sz = 55000
for (i <- 0 until sz) ct.update(new Wrap(i), i)
-
+
class Remover(offs: Int) extends Thread {
override def run() {
for (i <- 0 until sz) {
@@ -123,19 +123,19 @@ object ConcurrentMapSpec extends Spec {
}
}
}
-
+
val threads = for (i <- 0 until 16) yield new Remover(sz / 32 * i)
threads.foreach(_.start())
threads.foreach(_.join())
-
+
for (i <- 0 until sz) assert(ct.get(new Wrap(i)) == None)
}
-
+
"have all or none of the elements depending on the oddity" in {
val ct = new TrieMap[Wrap, Int]
val sz = 65000
for (i <- 0 until sz) ct(new Wrap(i)) = i
-
+
class Modifier(index: Int, offs: Int) extends Thread {
override def run() {
for (j <- 0 until sz) {
@@ -151,38 +151,38 @@ object ConcurrentMapSpec extends Spec {
}
}
}
-
+
def modify(n: Int) = {
val threads = for (i <- 0 until n) yield new Modifier(i, sz / n * i)
threads.foreach(_.start())
threads.foreach(_.join())
}
-
+
modify(16)
for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), Some(i))
modify(15)
for (i <- 0 until sz) assertEqual(ct.get(new Wrap(i)), None)
}
-
+
"compute size correctly" in {
val ct = new TrieMap[Wrap, Int]
val sz = 36450
for (i <- 0 until sz) ct(new Wrap(i)) = i
-
+
assertEqual(ct.size, sz)
assertEqual(ct.size, sz)
}
-
+
"compute size correctly in parallel" in {
val ct = new TrieMap[Wrap, Int]
val sz = 36450
for (i <- 0 until sz) ct(new Wrap(i)) = i
val pct = ct.par
-
+
assertEqual(pct.size, sz)
assertEqual(pct.size, sz)
}
-
+
}
-
+
}
diff --git a/test/files/run/ctries-new/iterator.scala b/test/files/run/ctries-new/iterator.scala
index b953a40e00..bb1175e61b 100644
--- a/test/files/run/ctries-new/iterator.scala
+++ b/test/files/run/ctries-new/iterator.scala
@@ -1,144 +1,134 @@
-
-
-
-
import collection._
import collection.concurrent.TrieMap
-
-
object IteratorSpec extends Spec {
-
+
def test() {
"work for an empty trie" in {
val ct = new TrieMap
val it = ct.iterator
-
+
it.hasNext shouldEqual (false)
evaluating { it.next() }.shouldProduce [NoSuchElementException]
}
-
+
def nonEmptyIteratorCheck(sz: Int) {
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
-
+
val it = ct.iterator
val tracker = mutable.Map[Wrap, Int]()
for (i <- 0 until sz) {
assert(it.hasNext == true)
tracker += it.next
}
-
+
it.hasNext shouldEqual (false)
evaluating { it.next() }.shouldProduce [NoSuchElementException]
tracker.size shouldEqual (sz)
tracker shouldEqual (ct)
}
-
+
"work for a 1 element trie" in {
nonEmptyIteratorCheck(1)
}
-
+
"work for a 2 element trie" in {
nonEmptyIteratorCheck(2)
}
-
+
"work for a 3 element trie" in {
nonEmptyIteratorCheck(3)
}
-
+
"work for a 5 element trie" in {
nonEmptyIteratorCheck(5)
}
-
+
"work for a 10 element trie" in {
nonEmptyIteratorCheck(10)
}
-
+
"work for a 20 element trie" in {
nonEmptyIteratorCheck(20)
}
-
+
"work for a 50 element trie" in {
nonEmptyIteratorCheck(50)
}
-
+
"work for a 100 element trie" in {
nonEmptyIteratorCheck(100)
}
-
+
"work for a 1k element trie" in {
nonEmptyIteratorCheck(1000)
}
-
+
"work for a 5k element trie" in {
nonEmptyIteratorCheck(5000)
}
-
+
"work for a 75k element trie" in {
nonEmptyIteratorCheck(75000)
}
-
+
"work for a 250k element trie" in {
nonEmptyIteratorCheck(500000)
}
-
+
def nonEmptyCollideCheck(sz: Int) {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until sz) ct.put(new DumbHash(i), i)
-
+
val it = ct.iterator
val tracker = mutable.Map[DumbHash, Int]()
for (i <- 0 until sz) {
assert(it.hasNext == true)
tracker += it.next
}
-
+
it.hasNext shouldEqual (false)
evaluating { it.next() }.shouldProduce [NoSuchElementException]
tracker.size shouldEqual (sz)
tracker shouldEqual (ct)
}
-
+
"work for colliding hashcodes, 2 element trie" in {
nonEmptyCollideCheck(2)
}
-
+
"work for colliding hashcodes, 3 element trie" in {
nonEmptyCollideCheck(3)
}
-
+
"work for colliding hashcodes, 5 element trie" in {
nonEmptyCollideCheck(5)
}
-
+
"work for colliding hashcodes, 10 element trie" in {
nonEmptyCollideCheck(10)
}
-
+
"work for colliding hashcodes, 100 element trie" in {
nonEmptyCollideCheck(100)
}
-
+
"work for colliding hashcodes, 500 element trie" in {
nonEmptyCollideCheck(500)
}
-
+
"work for colliding hashcodes, 5k element trie" in {
nonEmptyCollideCheck(5000)
}
-
+
def assertEqual(a: Map[Wrap, Int], b: Map[Wrap, Int]) {
if (a != b) {
println(a.size + " vs " + b.size)
- // println(a)
- // println(b)
- // println(a.toSeq.sortBy((x: (Wrap, Int)) => x._1.i))
- // println(b.toSeq.sortBy((x: (Wrap, Int)) => x._1.i))
}
assert(a == b)
}
-
+
"be consistent when taken with concurrent modifications" in {
val sz = 25000
val W = 15
@@ -146,40 +136,40 @@ object IteratorSpec extends Spec {
val checks = 5
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
-
+
class Modifier extends Thread {
override def run() {
for (i <- 0 until sz) ct.putIfAbsent(new Wrap(i), i) match {
case Some(_) => ct.remove(new Wrap(i))
- case None =>
+ case None =>
}
}
}
-
+
def consistentIteration(ct: TrieMap[Wrap, Int], checks: Int) {
class Iter extends Thread {
override def run() {
val snap = ct.readOnlySnapshot()
val initial = mutable.Map[Wrap, Int]()
for (kv <- snap) initial += kv
-
+
for (i <- 0 until checks) {
assertEqual(snap.iterator.toMap, initial)
}
}
}
-
+
val iter = new Iter
iter.start()
iter.join()
}
-
+
val threads = for (_ <- 0 until W) yield new Modifier
threads.foreach(_.start())
for (_ <- 0 until S) consistentIteration(ct, checks)
threads.foreach(_.join())
}
-
+
"be consistent with a concurrent removal with a well defined order" in {
val sz = 150000
val sgroupsize = 10
@@ -187,17 +177,16 @@ object IteratorSpec extends Spec {
val removerslowdown = 50
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
-
+
class Remover extends Thread {
override def run() {
for (i <- 0 until sz) {
assert(ct.remove(new Wrap(i)) == Some(i))
for (i <- 0 until removerslowdown) ct.get(new Wrap(i)) // slow down, mate
}
- //println("done removing")
}
}
-
+
def consistentIteration(it: Iterator[(Wrap, Int)]) = {
class Iter extends Thread {
override def run() {
@@ -210,7 +199,7 @@ object IteratorSpec extends Spec {
}
new Iter
}
-
+
val remover = new Remover
remover.start()
for (_ <- 0 until sgroupnum) {
@@ -218,27 +207,25 @@ object IteratorSpec extends Spec {
iters.foreach(_.start())
iters.foreach(_.join())
}
- //println("done with iterators")
remover.join()
}
-
+
"be consistent with a concurrent insertion with a well defined order" in {
val sz = 150000
val sgroupsize = 10
val sgroupnum = 10
val inserterslowdown = 50
val ct = new TrieMap[Wrap, Int]
-
+
class Inserter extends Thread {
override def run() {
for (i <- 0 until sz) {
assert(ct.put(new Wrap(i), i) == None)
for (i <- 0 until inserterslowdown) ct.get(new Wrap(i)) // slow down, mate
}
- //println("done inserting")
}
}
-
+
def consistentIteration(it: Iterator[(Wrap, Int)]) = {
class Iter extends Thread {
override def run() {
@@ -251,7 +238,7 @@ object IteratorSpec extends Spec {
}
new Iter
}
-
+
val inserter = new Inserter
inserter.start()
for (_ <- 0 until sgroupnum) {
@@ -259,31 +246,30 @@ object IteratorSpec extends Spec {
iters.foreach(_.start())
iters.foreach(_.join())
}
- //println("done with iterators")
inserter.join()
}
-
+
"work on a yet unevaluated snapshot" in {
val sz = 50000
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.update(new Wrap(i), i)
-
+
val snap = ct.snapshot()
val it = snap.iterator
-
+
while (it.hasNext) it.next()
}
-
+
"be duplicated" in {
val sz = 50
val ct = collection.parallel.mutable.ParTrieMap((0 until sz) zip (0 until sz): _*)
val it = ct.splitter
for (_ <- 0 until (sz / 2)) it.next()
val dupit = it.dup
-
+
it.toList shouldEqual dupit.toList
}
-
+
}
-
+
}
diff --git a/test/files/run/ctries-new/lnode.scala b/test/files/run/ctries-new/lnode.scala
index 92a31088e5..4cc97050e5 100644
--- a/test/files/run/ctries-new/lnode.scala
+++ b/test/files/run/ctries-new/lnode.scala
@@ -5,23 +5,23 @@ import collection.concurrent.TrieMap
object LNodeSpec extends Spec {
-
+
val initsz = 1500
val secondsz = 1750
-
+
def test() {
"accept elements with the same hash codes" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
}
-
+
"lookup elements with the same hash codes" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == Some(i))
for (i <- initsz until secondsz) assert(ct.get(new DumbHash(i)) == None)
}
-
+
"remove elements with the same hash codes" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.update(new DumbHash(i), i)
@@ -31,7 +31,7 @@ object LNodeSpec extends Spec {
}
for (i <- 0 until initsz) assert(ct.get(new DumbHash(i)) == None)
}
-
+
"put elements with the same hash codes if absent" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) ct.put(new DumbHash(i), i)
@@ -40,7 +40,7 @@ object LNodeSpec extends Spec {
for (i <- initsz until secondsz) assert(ct.putIfAbsent(new DumbHash(i), i) == None)
for (i <- initsz until secondsz) assert(ct.lookup(new DumbHash(i)) == i)
}
-
+
"replace elements with the same hash codes" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
@@ -49,13 +49,13 @@ object LNodeSpec extends Spec {
for (i <- 0 until initsz) assert(ct.lookup(new DumbHash(i)) == -i)
for (i <- 0 until initsz) assert(ct.replace(new DumbHash(i), -i, i) == true)
}
-
+
"remove elements with the same hash codes if mapped to a specific value" in {
val ct = new TrieMap[DumbHash, Int]
for (i <- 0 until initsz) assert(ct.put(new DumbHash(i), i) == None)
for (i <- 0 until initsz) assert(ct.remove(new DumbHash(i), i) == true)
}
-
+
}
-
+
}
diff --git a/test/files/run/ctries-new/main.scala b/test/files/run/ctries-new/main.scala
index d7fe087e4d..34f3ec2ccf 100644
--- a/test/files/run/ctries-new/main.scala
+++ b/test/files/run/ctries-new/main.scala
@@ -21,6 +21,9 @@ object Test {
trait Spec {
+ implicit def implicitously = scala.language.implicitConversions
+ implicit def reflectively = scala.language.reflectiveCalls
+
implicit def str2ops(s: String) = new {
def in[U](body: =>U) {
// just execute body
@@ -37,11 +40,11 @@ trait Spec {
var produced = false
try body
catch {
- case e => if (e.getClass == implicitly[ClassTag[T]].runtimeClass) produced = true
+ case e: Throwable => if (e.getClass == implicitly[ClassTag[T]].runtimeClass) produced = true
} finally {
assert(produced, "Did not produce exception of type: " + implicitly[ClassTag[T]])
}
}
}
-} \ No newline at end of file
+}
diff --git a/test/files/run/ctries-new/snapshot.scala b/test/files/run/ctries-new/snapshot.scala
index 5fe77d445b..57155d49c6 100644
--- a/test/files/run/ctries-new/snapshot.scala
+++ b/test/files/run/ctries-new/snapshot.scala
@@ -8,22 +8,22 @@ import collection.concurrent.TrieMap
object SnapshotSpec extends Spec {
-
+
def test() {
"support snapshots" in {
val ctn = new TrieMap
ctn.snapshot()
ctn.readOnlySnapshot()
-
+
val ct = new TrieMap[Int, Int]
for (i <- 0 until 100) ct.put(i, i)
ct.snapshot()
ct.readOnlySnapshot()
}
-
+
"empty 2 quiescent snapshots in isolation" in {
val sz = 4000
-
+
class Worker(trie: TrieMap[Wrap, Int]) extends Thread {
override def run() {
for (i <- 0 until sz) {
@@ -34,46 +34,46 @@ object SnapshotSpec extends Spec {
}
}
}
-
+
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct.put(new Wrap(i), i)
val snapt = ct.snapshot()
-
+
val original = new Worker(ct)
val snapshot = new Worker(snapt)
original.start()
snapshot.start()
original.join()
snapshot.join()
-
+
for (i <- 0 until sz) {
assert(ct.get(new Wrap(i)) == None)
assert(snapt.get(new Wrap(i)) == None)
}
}
-
+
def consistentReadOnly(name: String, readonly: Map[Wrap, Int], sz: Int, N: Int) {
@volatile var e: Exception = null
-
+
// reads possible entries once and stores them
// then reads all these N more times to check if the
// state stayed the same
class Reader(trie: Map[Wrap, Int]) extends Thread {
setName("Reader " + name)
-
+
override def run() =
try check()
catch {
case ex: Exception => e = ex
}
-
+
def check() {
val initial = mutable.Map[Wrap, Int]()
for (i <- 0 until sz) trie.get(new Wrap(i)) match {
case Some(i) => initial.put(new Wrap(i), i)
case None => // do nothing
}
-
+
for (k <- 0 until N) {
for (i <- 0 until sz) {
val tres = trie.get(new Wrap(i))
@@ -84,21 +84,21 @@ object SnapshotSpec extends Spec {
}
}
}
-
+
val reader = new Reader(readonly)
reader.start()
reader.join()
-
+
if (e ne null) {
e.printStackTrace()
throw e
}
}
-
+
// traverses the trie `rep` times and modifies each entry
class Modifier(trie: TrieMap[Wrap, Int], index: Int, rep: Int, sz: Int) extends Thread {
setName("Modifier %d".format(index))
-
+
override def run() {
for (k <- 0 until rep) {
for (i <- 0 until sz) trie.putIfAbsent(new Wrap(i), i) match {
@@ -108,85 +108,85 @@ object SnapshotSpec extends Spec {
}
}
}
-
+
// removes all the elements from the trie
class Remover(trie: TrieMap[Wrap, Int], index: Int, totremovers: Int, sz: Int) extends Thread {
setName("Remover %d".format(index))
-
+
override def run() {
for (i <- 0 until sz) trie.remove(new Wrap((i + sz / totremovers * index) % sz))
}
}
-
+
"have a consistent quiescent read-only snapshot" in {
val sz = 10000
val N = 100
val W = 10
-
+
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val readonly = ct.readOnlySnapshot()
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
-
+
threads.foreach(_.start())
consistentReadOnly("qm", readonly, sz, N)
threads.foreach(_.join())
}
-
+
// now, we check non-quiescent snapshots, as these permit situations
// where a thread is caught in the middle of the update when a snapshot is taken
-
+
"have a consistent non-quiescent read-only snapshot, concurrent with removes only" in {
val sz = 1250
val W = 100
val S = 5000
-
+
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Remover(ct, i, W, sz)
-
+
threads.foreach(_.start())
for (i <- 0 until S) consistentReadOnly("non-qr", ct.readOnlySnapshot(), sz, 5)
threads.foreach(_.join())
}
-
+
"have a consistent non-quiescent read-only snapshot, concurrent with modifications" in {
val sz = 1000
val N = 7000
val W = 10
val S = 7000
-
+
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
-
+
threads.foreach(_.start())
for (i <- 0 until S) consistentReadOnly("non-qm", ct.readOnlySnapshot(), sz, 5)
threads.foreach(_.join())
}
-
+
def consistentNonReadOnly(name: String, trie: TrieMap[Wrap, Int], sz: Int, N: Int) {
@volatile var e: Exception = null
-
+
// reads possible entries once and stores them
// then reads all these N more times to check if the
// state stayed the same
class Worker extends Thread {
setName("Worker " + name)
-
+
override def run() =
try check()
catch {
case ex: Exception => e = ex
}
-
+
def check() {
val initial = mutable.Map[Wrap, Int]()
for (i <- 0 until sz) trie.get(new Wrap(i)) match {
case Some(i) => initial.put(new Wrap(i), i)
case None => // do nothing
}
-
+
for (k <- 0 until N) {
// modify
for ((key, value) <- initial) {
@@ -194,7 +194,7 @@ object SnapshotSpec extends Spec {
val newv = -oldv
trie.replace(key, oldv, newv)
}
-
+
// check
for (i <- 0 until sz) if (initial.contains(new Wrap(i))) {
val expected = if (k % 2 == 0) -i else i
@@ -206,27 +206,27 @@ object SnapshotSpec extends Spec {
}
}
}
-
+
val worker = new Worker
worker.start()
worker.join()
-
+
if (e ne null) {
e.printStackTrace()
throw e
}
}
-
+
"have a consistent non-quiescent snapshot, concurrent with modifications" in {
val sz = 9000
val N = 1000
val W = 10
val S = 400
-
+
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
val threads = for (i <- 0 until W) yield new Modifier(ct, i, N, sz)
-
+
threads.foreach(_.start())
for (i <- 0 until S) {
consistentReadOnly("non-qm", ct.snapshot(), sz, 5)
@@ -234,7 +234,7 @@ object SnapshotSpec extends Spec {
}
threads.foreach(_.join())
}
-
+
"work when many concurrent snapshots are taken, concurrent with modifications" in {
val sz = 12000
val W = 10
@@ -243,7 +243,7 @@ object SnapshotSpec extends Spec {
val snaptimes = 600
val ct = new TrieMap[Wrap, Int]
for (i <- 0 until sz) ct(new Wrap(i)) = i
-
+
class Snapshooter extends Thread {
setName("Snapshooter")
override def run() {
@@ -254,14 +254,14 @@ object SnapshotSpec extends Spec {
}
}
}
-
+
val mods = for (i <- 0 until W) yield new Modifier(ct, i, modifytimes, sz)
val shooters = for (i <- 0 until S) yield new Snapshooter
val threads = mods ++ shooters
threads.foreach(_.start())
threads.foreach(_.join())
}
-
+
}
-
+
}