summaryrefslogtreecommitdiff
path: root/test/files/run/ctries-new/concmap.scala
blob: 76916564a72f7d1de4b777e9fc62ac7d2d2d9b74 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
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)
      for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
      for (i <- 0 until initsz) assert(ct.putIfAbsent(new Wrap(i), -i) == Some(i))
      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)
      for (i <- 0 until initsz) assert(ct.remove(new Wrap(i), -i - 1) == false)
      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)
      for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i - 1, -i - 2) == false)
      for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), i, -i - 2) == true)
      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)
      for (i <- 0 until initsz) assert(ct.replace(new Wrap(i), -i) == Some(i))
      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
          for (i <- 0 until sz) {
            val j = (offs + i) % sz
            var k = Int.MaxValue
            do {
              if (k != Int.MaxValue) repeats += 1
              k = ct.lookup(new Wrap(j))
            } while (!ct.replace(new Wrap(j), k, -k))
          }
          //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) {
            val j = (offs + i) % sz
            ct.putIfAbsent(new Wrap(j), j)
            assert(ct.lookup(new Wrap(j)) == j)
          }
        }
      }

      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) {
            val j = (offs + i) % sz
            ct.remove(new Wrap(j), j)
            assert(ct.get(new Wrap(j)) == None)
          }
        }
      }

      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) {
            val i = (offs + j) % sz
            var success = false
            do {
              if (ct.contains(new Wrap(i))) {
                success = ct.remove(new Wrap(i)) != None
              } else {
                success = ct.putIfAbsent(new Wrap(i), i) == None
              }
            } while (!success)
          }
        }
      }

      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)
    }

  }

}