1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver;
19
20 import junit.framework.TestCase;
21 import org.apache.hadoop.hbase.testclassification.SmallTests;
22 import org.junit.experimental.categories.Category;
23
24 import java.util.Random;
25 import java.util.concurrent.atomic.AtomicBoolean;
26 import java.util.concurrent.atomic.AtomicLong;
27
28
29
30
31
32 @Category(SmallTests.class)
33 public class TestMultiVersionConcurrencyControl extends TestCase {
34 static class Writer implements Runnable {
35 final AtomicBoolean finished;
36 final MultiVersionConcurrencyControl mvcc;
37 final AtomicBoolean status;
38
39 Writer(AtomicBoolean finished, MultiVersionConcurrencyControl mvcc, AtomicBoolean status) {
40 this.finished = finished;
41 this.mvcc = mvcc;
42 this.status = status;
43 }
44
45 private Random rnd = new Random();
46 public boolean failed = false;
47
48 public void run() {
49 while (!finished.get()) {
50 MultiVersionConcurrencyControl.WriteEntry e =
51 mvcc.begin();
52
53
54 int sleepTime = rnd.nextInt(500);
55
56
57 try {
58 if (sleepTime > 0) Thread.sleep(0, sleepTime * 1000);
59 } catch (InterruptedException e1) {
60 }
61 try {
62 mvcc.completeAndWait(e);
63 } catch (RuntimeException ex) {
64
65 System.out.println(ex.toString());
66 ex.printStackTrace();
67 status.set(false);
68 return;
69
70 }
71 }
72 }
73 }
74
75 public void testParallelism() throws Exception {
76 final MultiVersionConcurrencyControl mvcc = new MultiVersionConcurrencyControl();
77
78 final AtomicBoolean finished = new AtomicBoolean(false);
79
80
81 final AtomicBoolean readerFailed = new AtomicBoolean(false);
82 final AtomicLong failedAt = new AtomicLong();
83 Runnable reader = new Runnable() {
84 public void run() {
85 long prev = mvcc.getReadPoint();
86 while (!finished.get()) {
87 long newPrev = mvcc.getReadPoint();
88 if (newPrev < prev) {
89
90 System.out.println("Reader got out of order, prev: " + prev + " next was: " + newPrev);
91 readerFailed.set(true);
92
93 failedAt.set(newPrev);
94 return;
95 }
96 }
97 }
98 };
99
100
101 int n = 20;
102 Thread[] writers = new Thread[n];
103 AtomicBoolean[] statuses = new AtomicBoolean[n];
104 Thread readThread = new Thread(reader);
105
106 for (int i = 0; i < n; ++i) {
107 statuses[i] = new AtomicBoolean(true);
108 writers[i] = new Thread(new Writer(finished, mvcc, statuses[i]));
109 writers[i].start();
110 }
111 readThread.start();
112
113 try {
114 Thread.sleep(10 * 1000);
115 } catch (InterruptedException ex) {
116 }
117
118 finished.set(true);
119
120 readThread.join();
121 for (int i = 0; i < n; ++i) {
122 writers[i].join();
123 }
124
125
126 assertFalse(readerFailed.get());
127 for (int i = 0; i < n; ++i) {
128 assertTrue(statuses[i].get());
129 }
130 }
131 }