1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.directory.mavibot.btree;
21
22
23 import static org.junit.Assert.assertEquals;
24
25 import java.io.IOException;
26 import java.util.Random;
27 import java.util.concurrent.CountDownLatch;
28 import java.util.concurrent.atomic.AtomicBoolean;
29
30 import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
31 import org.apache.directory.mavibot.btree.serializer.LongSerializer;
32 import org.apache.directory.mavibot.btree.serializer.StringSerializer;
33 import org.junit.AfterClass;
34 import org.junit.BeforeClass;
35 import org.junit.Test;
36 import org.junit.Ignore;
37
38
39
40
41
42
43
44 public class MultiThreadedInMemoryBtreeTest
45 {
46
47 private static BTree<Long, String> btree;
48
49
50
51
52
53
54 @BeforeClass
55 public static void setup() throws IOException
56 {
57 btree = BTreeFactory.createInMemoryBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE );
58 }
59
60
61
62
63
64 @AfterClass
65 public static void shutdown() throws IOException
66 {
67 btree.close();
68 }
69
70
71
72
73
74
75 private void create50KBTree() throws IOException
76 {
77 Random random = new Random( System.nanoTime() );
78
79 int nbElems = 50000;
80
81
82 btree.setPageSize( 32 );
83
84 for ( int i = 0; i < nbElems; i++ )
85 {
86 Long key = ( long ) random.nextLong();
87 String value = Long.toString( key );
88
89 try
90 {
91 btree.insert( key, value );
92
93 if ( i % 10000 == 0 )
94 {
95 System.out.println( "Written " + i + " elements" );
96 }
97 }
98 catch ( Exception e )
99 {
100 e.printStackTrace();
101 System.out.println( btree );
102 System.out.println( "Error while adding " + value );
103 return;
104 }
105 }
106 }
107
108
109
110
111
112
113
114 private int testBrowse() throws IOException, KeyNotFoundException
115 {
116 TupleCursor<Long, String> cursor = btree.browse();
117
118 int nb = 0;
119 long elem = Long.MIN_VALUE;
120
121 while ( cursor.hasNext() )
122 {
123 Tuple<Long, String> res = cursor.next();
124
125 if ( res.getKey() > elem )
126 {
127 elem = res.getKey();
128 nb++;
129 }
130 }
131
132 cursor.close();
133
134 return nb;
135 }
136
137
138
139
140
141
142
143
144 @Test
145 public void testBrowseMultiThreads() throws InterruptedException
146 {
147 int nbThreads = 100;
148 final CountDownLatch latch = new CountDownLatch( nbThreads );
149
150 Thread writer = new Thread()
151 {
152 public void run()
153 {
154 try
155 {
156 create50KBTree();
157 }
158 catch ( Exception e )
159 {
160 }
161 }
162 };
163
164 long t0 = System.currentTimeMillis();
165
166
167 writer.start();
168
169 for ( int i = 0; i < nbThreads; i++ )
170 {
171 Thread test = new Thread()
172 {
173 public void run()
174 {
175 try
176 {
177 int res = 0;
178 int previous = -1;
179
180 while ( previous < res )
181 {
182 previous = res;
183 res = testBrowse();
184 Thread.sleep( 500 );
185 }
186
187 latch.countDown();
188 }
189 catch ( Exception e )
190 {
191 }
192 }
193 };
194
195
196 test.start();
197 }
198
199
200 latch.await();
201
202 long t1 = System.currentTimeMillis();
203
204 System.out.println( " Time to create 50K entries and to have " + nbThreads + " threads reading them : "
205 + ( ( t1 - t0 ) / 1000 ) + " seconds" );
206 }
207
208
209
210
211
212
213 @Test
214 public void testInsertMultiThreads() throws InterruptedException, IOException
215 {
216 int nbThreads = 100;
217 final CountDownLatch latch = new CountDownLatch( nbThreads );
218 final AtomicBoolean error = new AtomicBoolean(false);
219
220
221
222 long t0 = System.currentTimeMillis();
223
224 class MyThread extends Thread
225 {
226 private int prefix = 0;
227
228 public void run()
229 {
230 try
231 {
232
233 for ( int j = 0; j < 1000; j++ )
234 {
235 long value = prefix * 1000 + j;
236 String valStr = Long.toString( value );
237
238 btree.insert( value, valStr );
239
240 if ( j % 100 == 0 )
241 {
242
243
244
245
246
247
248
249
250
251
252
253 }
254 }
255
256 latch.countDown();
257 }
258 catch ( Exception e )
259 {
260 e.printStackTrace();
261 System.out.println( e.getMessage() );
262 }
263 }
264
265 public MyThread( int prefix )
266 {
267 this.prefix = prefix;
268 }
269 }
270
271 for ( int i = 0; i < nbThreads; i++ )
272 {
273 MyThread test = new MyThread( i );
274
275
276 test.start();
277 }
278
279
280 latch.await();
281
282 if ( error.get() )
283 {
284 System.out.println( "ERROR -----------------" );
285 return;
286 }
287
288 long t1 = System.currentTimeMillis();
289
290
291 assertEquals( -1L, checkBtree( 1000, nbThreads ) );
292
293 System.out.println( " Time to create 1M entries : "
294 + ( ( t1 - t0 ) ) + " milliseconds" );
295 }
296
297
298 private long checkBtree( int prefix, int nbElems, int currentElem ) throws IOException
299 {
300 long i = 0L;
301
302 try
303 {
304 for ( i = 0L; i < currentElem; i++ )
305 {
306 long key = prefix * nbElems + i;
307 assertEquals( Long.toString( key ), btree.get( key ) );
308 }
309
310 return -1L;
311 }
312 catch ( KeyNotFoundException knfe )
313 {
314 System.out.println( "cannot find " + ( prefix * nbElems + i ) );
315 return i;
316 }
317 }
318
319
320 private long checkBtree( int nbElems, int nbThreads ) throws IOException
321 {
322 long i = 0L;
323
324 try
325 {
326 for ( long j = 0; j < nbThreads; j++ )
327 {
328 for ( i = 0L; i < nbElems; i++ )
329 {
330 long key = j * nbElems + i;
331 assertEquals( Long.toString( key ), btree.get( key ) );
332 }
333 }
334
335 return -1L;
336 }
337 catch ( KeyNotFoundException knfe )
338 {
339 System.out.println( "cannot find " + i );
340 return i;
341 }
342 }
343 }