KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > txn > LockTest


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: LockTest.java,v 1.44 2006/10/30 21:14:53 bostic Exp $
7  */

8
9 package com.sleepycat.je.txn;
10
11 import java.io.File JavaDoc;
12 import java.util.ArrayList JavaDoc;
13 import java.util.HashSet JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Set JavaDoc;
17
18 import junit.framework.TestCase;
19
20 import com.sleepycat.je.DatabaseException;
21 import com.sleepycat.je.EnvironmentConfig;
22 import com.sleepycat.je.TransactionConfig;
23 import com.sleepycat.je.config.EnvironmentParams;
24 import com.sleepycat.je.dbi.EnvironmentImpl;
25 import com.sleepycat.je.dbi.MemoryBudget;
26 import com.sleepycat.je.util.TestUtils;
27
28 public class LockTest extends TestCase {
29     private EnvironmentImpl envImpl;
30     private File JavaDoc envHome;
31
32     public LockTest() {
33         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
34     }
35
36     public void setUp()
37     throws DatabaseException {
38
39         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
40         envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6");
41         envConfig.setAllowCreate(true);
42         envImpl = new EnvironmentImpl(envHome, envConfig);
43
44     }
45
46     public void tearDown()
47     throws DatabaseException {
48
49         envImpl.close();
50     }
51
52     public void testLockConflicts()
53         throws Exception JavaDoc {
54
55     Locker txn1 = new BasicLocker(envImpl);
56     Locker txn2 = new BasicLocker(envImpl);
57     Locker txn3 = new BasicLocker(envImpl);
58         MemoryBudget mb = envImpl.getMemoryBudget();
59     try {
60             /*
61              * Start fresh. Ask for a read lock from txn1 twice,
62              * should only be one owner. Then add multiple
63              * would-be-writers as waiters.
64              */

65         Lock lock = new Lock(new Long JavaDoc(1));
66         assertEquals(LockGrantType.NEW,
67                          lock.lock(LockType.READ, txn1, false, mb, 0));
68         assertEquals(LockGrantType.EXISTING,
69                          lock.lock(LockType.READ, txn1, false, mb, 0));
70         assertEquals(1, lock.nOwners());
71         assertEquals(0, lock.nWaiters());
72
73             /* ask for a read lock from txn 2, get it. */
74         assertEquals(LockGrantType.NEW,
75                          lock.lock(LockType.READ, txn2, false, mb, 0));
76             /* txn1's write request must wait */
77         assertEquals(LockGrantType.WAIT_PROMOTION,
78                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
79             /* txn2's write request must wait */
80         assertEquals(LockGrantType.WAIT_PROMOTION,
81                          lock.lock(LockType.WRITE, txn2, false, mb, 0));
82         assertEquals(2, lock.nOwners());
83         assertEquals(2, lock.nWaiters());
84
85
86             /* Start fresh. Get a write lock, then get a read lock. */
87         lock = new Lock(new Long JavaDoc(1));
88
89         assertEquals(LockGrantType.NEW,
90                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
91         assertEquals(LockGrantType.EXISTING,
92                          lock.lock(LockType.READ, txn1, false, mb, 0));
93         assertEquals(1, lock.nOwners());
94         assertEquals(0, lock.nWaiters());
95
96             /* Start fresh. Get a read lock, upgrade to a write lock. */
97         lock = new Lock(new Long JavaDoc(1));
98         assertEquals(LockGrantType.NEW,
99                          lock.lock(LockType.READ, txn1, false, mb, 0));
100         assertEquals(LockGrantType.PROMOTION,
101                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
102         assertEquals(1, lock.nOwners());
103         assertEquals(0, lock.nWaiters());
104
105             /*
106              * Start fresh. Get a read lock, then ask for a non-blocking
107              * write lock. The latter should be denied.
108              */

109         lock = new Lock(new Long JavaDoc(1));
110
111         assertEquals(LockGrantType.NEW,
112                          lock.lock(LockType.READ, txn1, false, mb, 0));
113         assertEquals(LockGrantType.DENIED,
114                          lock.lock(LockType.WRITE, txn2, true, mb, 0));
115         assertEquals(1, lock.nOwners());
116         assertEquals(0, lock.nWaiters());
117
118             /* Two write requsts, should be one owner. */
119         lock = new Lock(new Long JavaDoc(1));
120         assertEquals(LockGrantType.NEW,
121                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
122         assertEquals(LockGrantType.EXISTING,
123                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
124         assertEquals(1, lock.nOwners());
125         assertEquals(0, lock.nWaiters());
126
127         /*
128              * Ensure that a read request behind a write request that waits
129          * also waits. blocking requests.
130              */

131         lock = new Lock(new Long JavaDoc(1));
132
133         assertEquals(LockGrantType.NEW,
134                          lock.lock(LockType.READ, txn1, false, mb, 0));
135                
136         assertEquals(LockGrantType.WAIT_NEW,
137                          lock.lock(LockType.WRITE, txn2, false, mb, 0));
138             
139         assertEquals(LockGrantType.WAIT_NEW,
140                          lock.lock(LockType.READ, txn3, false, mb, 0));
141             
142             assertEquals(1, lock.nOwners());
143         assertEquals(2, lock.nWaiters());
144
145         /* Check non blocking requests */
146         lock = new Lock(new Long JavaDoc(1));
147
148         assertEquals(LockGrantType.NEW,
149                          lock.lock(LockType.READ, txn1, false, mb, 0));
150                
151         /* Since non-blocking request, this fails and doesn't go
152            on the wait queue. */

153         assertEquals(LockGrantType.DENIED,
154                          lock.lock(LockType.WRITE, txn2, true, mb, 0));
155         assertEquals(LockGrantType.NEW,
156                          lock.lock(LockType.READ, txn3, true, mb, 0));
157         assertEquals(2, lock.nOwners());
158         assertEquals(0, lock.nWaiters());
159
160         lock = new Lock(new Long JavaDoc(1));
161
162         assertEquals(LockGrantType.NEW,
163                          lock.lock(LockType.READ, txn1, false, mb, 0));
164         assertEquals(LockGrantType.NEW,
165                          lock.lock(LockType.READ, txn2, false, mb, 0));
166         assertEquals(LockGrantType.NEW,
167                          lock.lock(LockType.READ, txn3, false, mb, 0));
168         assertEquals(3, lock.nOwners());
169         assertEquals(0, lock.nWaiters());
170     } finally {
171             txn1.operationEnd();
172             txn2.operationEnd();
173             txn3.operationEnd();
174         }
175     }
176
177     public void testOwners()
178         throws Exception JavaDoc {
179
180     Locker txn1 = new BasicLocker(envImpl);
181     Locker txn2 = new BasicLocker(envImpl);
182     Locker txn3 = new BasicLocker(envImpl);
183     Locker txn4 = new BasicLocker(envImpl);
184         MemoryBudget mb = envImpl.getMemoryBudget();
185
186         try {
187             /*
188              * Build up 3 owners and waiters for a lock, to test the
189              * lazy initialization and optimization for single owner/waiter.
190              */

191             Lock lock = new Lock(new Long JavaDoc(1));
192             /* should be no writer. */
193             assertTrue(lock.getWriteOwnerLocker() == null);
194
195             assertEquals(LockGrantType.NEW,
196                          lock.lock(LockType.READ, txn1, false, mb, 0));
197         assertEquals(LockGrantType.NEW,
198                          lock.lock(LockType.READ, txn2, false, mb, 0));
199         assertEquals(LockGrantType.NEW,
200                          lock.lock(LockType.READ, txn3, false, mb, 0));
201             
202             /* should be no writer. */
203             assertTrue(lock.getWriteOwnerLocker() == null);
204
205             /* should be node 1 */
206             assertEquals(1, lock.getNodeId().longValue());
207
208             /* expect 3 owners, 0 waiters. */
209             Set JavaDoc expectedOwners = new HashSet JavaDoc();
210             expectedOwners.add(new LockInfo(txn1, LockType.READ));
211             expectedOwners.add(new LockInfo(txn2, LockType.READ));
212             expectedOwners.add(new LockInfo(txn3, LockType.READ));
213             checkOwners(expectedOwners, lock, 0);
214
215             /* release the first locker. */
216             lock.release(txn1, mb, 0);
217             expectedOwners = new HashSet JavaDoc();
218             expectedOwners.add(new LockInfo(txn2, LockType.READ));
219             expectedOwners.add(new LockInfo(txn3, LockType.READ));
220             checkOwners(expectedOwners, lock, 0);
221
222             /* Add more. */
223             assertEquals(LockGrantType.NEW,
224                          lock.lock(LockType.READ, txn4, false, mb, 0));
225             expectedOwners = new HashSet JavaDoc();
226             expectedOwners.add(new LockInfo(txn2, LockType.READ));
227             expectedOwners.add(new LockInfo(txn3, LockType.READ));
228             expectedOwners.add(new LockInfo(txn4, LockType.READ));
229             checkOwners(expectedOwners, lock, 0);
230
231             /* release */
232             lock.release(txn2, mb, 0);
233             expectedOwners = new HashSet JavaDoc();
234             expectedOwners.add(new LockInfo(txn3, LockType.READ));
235             expectedOwners.add(new LockInfo(txn4, LockType.READ));
236             checkOwners(expectedOwners, lock, 0);
237
238             /* release */
239             lock.release(txn3, mb, 0);
240             expectedOwners = new HashSet JavaDoc();
241             expectedOwners.add(new LockInfo(txn4, LockType.READ));
242             /* only 1 lock, in the owner set, but not a write owner. */
243             assertTrue(lock.getWriteOwnerLocker() == null);
244
245             /* release */
246             lock.release(txn4, mb, 0);
247             expectedOwners = new HashSet JavaDoc();
248             checkOwners(expectedOwners, lock, 0);
249
250             /* Add owners again. */
251             assertEquals(LockGrantType.NEW,
252                          lock.lock(LockType.READ, txn1, false, mb, 0));
253             assertEquals(LockGrantType.NEW,
254                          lock.lock(LockType.READ, txn2, false, mb, 0));
255             expectedOwners = new HashSet JavaDoc();
256             expectedOwners.add(new LockInfo(txn1, LockType.READ));
257             expectedOwners.add(new LockInfo(txn2, LockType.READ));
258             checkOwners(expectedOwners, lock, 0);
259
260         } catch (Exception JavaDoc e) {
261             e.printStackTrace();
262             throw e;
263         } finally {
264             txn1.operationEnd();
265             txn2.operationEnd();
266             txn3.operationEnd();
267             txn4.operationEnd();
268         }
269     }
270
271     public void testWaiters()
272         throws Exception JavaDoc {
273
274     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
275     Locker txn2 = new AutoTxn(envImpl, new TransactionConfig());
276     Locker txn3 = new AutoTxn(envImpl, new TransactionConfig());
277     Locker txn4 = new AutoTxn(envImpl, new TransactionConfig());
278     Locker txn5 = new AutoTxn(envImpl, new TransactionConfig());
279         MemoryBudget mb = envImpl.getMemoryBudget();
280
281         try {
282             /*
283              * Build up 1 owners and 3waiters for a lock, to test the
284              * lazy initialization and optimization for single owner/waiter.
285              */

286             Lock lock = new Lock(new Long JavaDoc(1));
287             assertEquals(LockGrantType.NEW,
288                          lock.lock(LockType.READ, txn1, false, mb, 0));
289             assertEquals(LockGrantType.NEW,
290                          lock.lock(LockType.READ, txn2, false, mb, 0));
291         assertEquals(LockGrantType.WAIT_NEW,
292                          lock.lock(LockType.WRITE, txn3, false, mb, 0));
293         assertEquals(LockGrantType.WAIT_NEW,
294                          lock.lock(LockType.WRITE, txn4, false, mb, 0));
295         assertEquals(LockGrantType.WAIT_PROMOTION,
296                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
297             
298             /* should be no writer. */
299             assertTrue(lock.getWriteOwnerLocker() == null);
300
301             /* should be node 1 */
302             assertEquals(1, lock.getNodeId().longValue());
303
304             /* expect 2 owners, 3 waiters. */
305             Set JavaDoc expectedOwners = new HashSet JavaDoc();
306             expectedOwners.add(new LockInfo(txn1, LockType.READ));
307             expectedOwners.add(new LockInfo(txn2, LockType.READ));
308             checkOwners(expectedOwners, lock, 3);
309
310             List JavaDoc waiters = new ArrayList JavaDoc();
311             waiters.add(new LockInfo(txn1, LockType.WRITE));
312             waiters.add(new LockInfo(txn3, LockType.WRITE));
313             waiters.add(new LockInfo(txn4, LockType.WRITE));
314             checkWaiters(waiters, lock);
315
316             /* release a waiter, shouldn't change anything. */
317             lock.release(txn4, mb, 0);
318             checkWaiters(waiters, lock);
319
320             /*
321              * Release the other read lock, expect txn1 to be promoted to a
322              * write lock.
323              */

324             lock.release(txn2, mb, 0);
325             expectedOwners = new HashSet JavaDoc();
326             expectedOwners.add(new LockInfo(txn1, LockType.WRITE));
327             checkOwners(expectedOwners, lock, 2);
328
329             waiters.remove(0);
330             checkWaiters(waiters, lock);
331
332             /* release */
333             lock.release(txn1, mb, 0);
334             expectedOwners = new HashSet JavaDoc();
335             expectedOwners.add(new LockInfo(txn3, LockType.WRITE));
336             checkOwners(expectedOwners, lock, 1);
337
338             waiters.remove(0);
339             checkWaiters(waiters, lock);
340
341             /*
342              * Add multiple read lock waiters so that we can promoting multiple
343              * waiters.
344              */

345             assertEquals(LockGrantType.WAIT_NEW,
346                          lock.lock(LockType.READ, txn1, false, mb, 0));
347             assertEquals(LockGrantType.WAIT_NEW,
348                          lock.lock(LockType.READ, txn2, false, mb, 0));
349             assertEquals(LockGrantType.WAIT_NEW,
350                          lock.lock(LockType.READ, txn5, false, mb, 0));
351
352             checkOwners(expectedOwners, lock, 4);
353             waiters.add(new LockInfo(txn1, LockType.READ));
354             waiters.add(new LockInfo(txn2, LockType.READ));
355             waiters.add(new LockInfo(txn5, LockType.READ));
356             checkWaiters(waiters, lock);
357
358             /* flush one of the waiters. */
359             lock.flushWaiter(txn5, mb, 0);
360             waiters.remove(3);
361             checkWaiters(waiters, lock);
362
363             /* re-add. */
364             assertEquals(LockGrantType.WAIT_NEW,
365                          lock.lock(LockType.READ, txn5, false, mb, 0));
366             waiters.add(new LockInfo(txn5, LockType.READ));
367
368             /* release txn3 */
369             lock.release(txn3, mb, 0);
370             expectedOwners = new HashSet JavaDoc();
371             expectedOwners.add(new LockInfo(txn4, LockType.WRITE));
372             checkOwners(expectedOwners, lock, 3);
373             waiters.remove(0);
374             checkWaiters(waiters, lock);
375
376             /* release txn4, expect all read locks to promote. */
377             lock.release(txn4, mb, 0);
378             expectedOwners = new HashSet JavaDoc();
379             expectedOwners.add(new LockInfo(txn1, LockType.READ));
380             expectedOwners.add(new LockInfo(txn2, LockType.READ));
381             expectedOwners.add(new LockInfo(txn5, LockType.READ));
382             checkOwners(expectedOwners, lock, 0);
383             waiters.clear();
384             checkWaiters(waiters, lock);
385
386         } catch (Exception JavaDoc e) {
387             e.printStackTrace();
388             throw e;
389         } finally {
390             txn1.operationEnd();
391             txn2.operationEnd();
392             txn3.operationEnd();
393             txn4.operationEnd();
394             txn5.operationEnd();
395         }
396     }
397
398     public void testPromotion()
399         throws Exception JavaDoc {
400
401     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
402     Locker txn2 = new AutoTxn(envImpl, new TransactionConfig());
403     Locker txn3 = new AutoTxn(envImpl, new TransactionConfig());
404     Locker txn4 = new AutoTxn(envImpl, new TransactionConfig());
405     Locker txn5 = new AutoTxn(envImpl, new TransactionConfig());
406         MemoryBudget mb = envImpl.getMemoryBudget();
407
408         try {
409             /*
410              * Build up 1 owners and 3 read waiters for a lock. Then
411              * check that all the waiters promote properly.
412              */

413             Lock lock = new Lock(new Long JavaDoc(1));
414             assertEquals(LockGrantType.NEW,
415                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
416         assertEquals(LockGrantType.WAIT_NEW,
417                          lock.lock(LockType.READ, txn2, false, mb, 0));
418         assertEquals(LockGrantType.WAIT_NEW,
419                          lock.lock(LockType.READ, txn3, false, mb, 0));
420         assertEquals(LockGrantType.WAIT_NEW,
421                          lock.lock(LockType.READ, txn4, false, mb, 0));
422
423             /* Check that 1 owner, 3 waiters exist. */
424             Set JavaDoc expectedOwners = new HashSet JavaDoc();
425             expectedOwners.add(new LockInfo(txn1, LockType.WRITE));
426             checkOwners(expectedOwners, lock, 3);
427
428             List JavaDoc waiters = new ArrayList JavaDoc();
429             waiters.add(new LockInfo(txn2, LockType.READ));
430             waiters.add(new LockInfo(txn3, LockType.READ));
431             waiters.add(new LockInfo(txn4, LockType.READ));
432             checkWaiters(waiters, lock);
433
434             /* Release the writer, expect all 3 waiters to promote. */
435             lock.release(txn1, mb, 0);
436             expectedOwners = new HashSet JavaDoc();
437             expectedOwners.add(new LockInfo(txn2, LockType.READ));
438             expectedOwners.add(new LockInfo(txn3, LockType.READ));
439             expectedOwners.add(new LockInfo(txn4, LockType.READ));
440             checkOwners(expectedOwners, lock, 0);
441             waiters.clear();
442             checkWaiters(waiters, lock);
443         } catch (Exception JavaDoc e) {
444             e.printStackTrace();
445             throw e;
446         } finally {
447             txn1.operationEnd();
448             txn2.operationEnd();
449             txn3.operationEnd();
450             txn4.operationEnd();
451             txn5.operationEnd();
452         }
453     }
454
455     /**
456      * Tests conflicts between range locks and all other lock types.
457      */

458     public void testRangeConflicts()
459         throws Exception JavaDoc {
460
461
462         /* No owner */
463         checkConflict(null,
464                       LockType.RANGE_READ,
465                       LockGrantType.NEW);
466         checkConflict(null,
467                       LockType.RANGE_WRITE,
468                       LockGrantType.NEW);
469         checkConflict(null,
470                       LockType.RANGE_INSERT,
471                       LockGrantType.NEW);
472
473         /* Owner has READ */
474         checkConflict(LockType.READ,
475                       LockType.RANGE_READ,
476                       LockGrantType.NEW);
477         checkConflict(LockType.READ,
478                       LockType.RANGE_WRITE,
479                       LockGrantType.WAIT_NEW);
480         checkConflict(LockType.READ,
481                       LockType.RANGE_INSERT,
482                       LockGrantType.NEW);
483
484         /* Owner has WRITE */
485         checkConflict(LockType.WRITE,
486                       LockType.RANGE_READ,
487                       LockGrantType.WAIT_NEW);
488         checkConflict(LockType.WRITE,
489                       LockType.RANGE_WRITE,
490                       LockGrantType.WAIT_NEW);
491         checkConflict(LockType.WRITE,
492                       LockType.RANGE_INSERT,
493                       LockGrantType.NEW);
494    
495         /* Owner has RANGE_READ */
496         checkConflict(LockType.RANGE_READ,
497                       LockType.READ,
498                       LockGrantType.NEW);
499         checkConflict(LockType.RANGE_READ,
500                       LockType.WRITE,
501                       LockGrantType.WAIT_NEW);
502         checkConflict(LockType.RANGE_READ,
503                       LockType.RANGE_READ,
504                       LockGrantType.NEW);
505         checkConflict(LockType.RANGE_READ,
506                       LockType.RANGE_WRITE,
507                       LockGrantType.WAIT_NEW);
508         checkConflict(LockType.RANGE_READ,
509                       LockType.RANGE_INSERT,
510                       LockGrantType.WAIT_NEW);
511
512         /* Owner has RANGE_WRITE */
513         checkConflict(LockType.RANGE_WRITE,
514                       LockType.READ,
515                       LockGrantType.WAIT_NEW);
516         checkConflict(LockType.RANGE_WRITE,
517                       LockType.WRITE,
518                       LockGrantType.WAIT_NEW);
519         checkConflict(LockType.RANGE_WRITE,
520                       LockType.RANGE_READ,
521                       LockGrantType.WAIT_NEW);
522         checkConflict(LockType.RANGE_WRITE,
523                       LockType.RANGE_WRITE,
524                       LockGrantType.WAIT_NEW);
525         checkConflict(LockType.RANGE_WRITE,
526                       LockType.RANGE_INSERT,
527                       LockGrantType.WAIT_NEW);
528
529         /* Owner has RANGE_INSERT */
530         checkConflict(LockType.RANGE_INSERT,
531                       LockType.READ,
532                       LockGrantType.NEW);
533         checkConflict(LockType.RANGE_INSERT,
534                       LockType.WRITE,
535                       LockGrantType.NEW);
536         checkConflict(LockType.RANGE_INSERT,
537                       LockType.RANGE_READ,
538                       LockGrantType.WAIT_RESTART);
539         checkConflict(LockType.RANGE_INSERT,
540                       LockType.RANGE_WRITE,
541                       LockGrantType.WAIT_RESTART);
542         checkConflict(LockType.RANGE_INSERT,
543                       LockType.RANGE_INSERT,
544                       LockGrantType.NEW);
545     }
546
547     /**
548      * Tests that when the first request is held and the second request is
549      * requested, the second grant type is returned.
550      */

551     private void checkConflict(LockType firstRequest, LockType secondRequest,
552                                LockGrantType secondGrantType)
553         throws Exception JavaDoc {
554
555     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
556     Locker txn2 = new AutoTxn(envImpl, new TransactionConfig());
557         MemoryBudget mb = envImpl.getMemoryBudget();
558
559         try {
560             Lock lock = new Lock(new Long JavaDoc(1));
561
562             if (firstRequest != null) {
563                 assertEquals(LockGrantType.NEW,
564                              lock.lock(firstRequest, txn1, false, mb, 0));
565             }
566             LockGrantType typeGranted =
567                 lock.lock(secondRequest, txn2, false, mb, 0);
568         assertEquals(secondGrantType, typeGranted);
569
570             boolean wait = (typeGranted == LockGrantType.WAIT_NEW ||
571                             typeGranted == LockGrantType.WAIT_PROMOTION ||
572                             typeGranted == LockGrantType.WAIT_RESTART);
573             boolean given = (typeGranted == LockGrantType.NEW);
574             boolean restart = (typeGranted == LockGrantType.WAIT_RESTART);
575
576             Set JavaDoc expectedOwners = new HashSet JavaDoc();
577             List JavaDoc expectedWaiters = new ArrayList JavaDoc();
578
579             if (firstRequest != null) {
580                 expectedOwners.add(new LockInfo(txn1, firstRequest));
581             }
582             if (given) {
583                 expectedOwners.add(new LockInfo(txn2, secondRequest));
584             } else if (wait) {
585                 if (restart) {
586                     expectedWaiters.add(new LockInfo(txn2, LockType.RESTART));
587                 } else {
588                     expectedWaiters.add(new LockInfo(txn2, secondRequest));
589                 }
590             }
591
592             checkOwners(expectedOwners, lock, expectedWaiters.size());
593             checkWaiters(expectedWaiters, lock);
594
595             lock.release(txn1, mb, 0);
596             if (wait) {
597                 if (restart) {
598                     checkOwners(new HashSet JavaDoc(), lock, 0);
599                 } else {
600                     checkOwners(new HashSet JavaDoc(expectedWaiters), lock, 0);
601                 }
602             }
603             lock.release(txn2, mb, 0);
604             assertEquals(0, lock.nOwners());
605             assertEquals(0, lock.nWaiters());
606         } catch (Exception JavaDoc e) {
607             e.printStackTrace();
608             throw e;
609         } finally {
610             txn1.operationEnd();
611             txn2.operationEnd();
612         }
613     }
614
615     /**
616      * Tests upgrades between range locks and all other lock types.
617      */

618     public void testRangeUpgrades()
619         throws Exception JavaDoc {
620
621         /* Owner has READ */
622         checkUpgrade(LockType.READ,
623                      LockType.RANGE_READ,
624                      LockGrantType.EXISTING,
625                      LockType.RANGE_READ);
626         checkUpgrade(LockType.READ,
627                      LockType.RANGE_WRITE,
628                      LockGrantType.PROMOTION,
629                      LockType.RANGE_WRITE);
630         checkUpgrade(LockType.READ,
631                      LockType.RANGE_INSERT,
632                      null,
633                      LockType.READ);
634
635         /* Owner has WRITE */
636         checkUpgrade(LockType.WRITE,
637                      LockType.RANGE_READ,
638                      LockGrantType.EXISTING,
639                      LockType.RANGE_WRITE);
640         checkUpgrade(LockType.WRITE,
641                      LockType.RANGE_WRITE,
642                      LockGrantType.EXISTING,
643                      LockType.RANGE_WRITE);
644         checkUpgrade(LockType.WRITE,
645                      LockType.RANGE_INSERT,
646                      null,
647                      LockType.WRITE);
648    
649         /* Owner has RANGE_READ */
650         checkUpgrade(LockType.RANGE_READ,
651                      LockType.READ,
652                      LockGrantType.EXISTING,
653                      LockType.RANGE_READ);
654         checkUpgrade(LockType.RANGE_READ,
655                      LockType.WRITE,
656                      LockGrantType.PROMOTION,
657                      LockType.RANGE_WRITE);
658         checkUpgrade(LockType.RANGE_READ,
659                      LockType.RANGE_READ,
660                      LockGrantType.EXISTING,
661                      LockType.RANGE_READ);
662         checkUpgrade(LockType.RANGE_READ,
663                      LockType.RANGE_WRITE,
664                      LockGrantType.PROMOTION,
665                      LockType.RANGE_WRITE);
666         checkUpgrade(LockType.RANGE_READ,
667                      LockType.RANGE_INSERT,
668                      null,
669                      LockType.RANGE_READ);
670
671         /* Owner has RANGE_WRITE */
672         checkUpgrade(LockType.RANGE_WRITE,
673                      LockType.READ,
674                      LockGrantType.EXISTING,
675                      LockType.RANGE_WRITE);
676         checkUpgrade(LockType.RANGE_WRITE,
677                      LockType.WRITE,
678                      LockGrantType.EXISTING,
679                      LockType.RANGE_WRITE);
680         checkUpgrade(LockType.RANGE_WRITE,
681                      LockType.RANGE_READ,
682                      LockGrantType.EXISTING,
683                      LockType.RANGE_WRITE);
684         checkUpgrade(LockType.RANGE_WRITE,
685                      LockType.RANGE_WRITE,
686                      LockGrantType.EXISTING,
687                      LockType.RANGE_WRITE);
688         checkUpgrade(LockType.RANGE_WRITE,
689                      LockType.RANGE_INSERT,
690                      null,
691                      LockType.RANGE_WRITE);
692
693         /* Owner has RANGE_INSERT */
694         checkUpgrade(LockType.RANGE_INSERT,
695                      LockType.READ,
696                      null,
697                      LockType.RANGE_INSERT);
698         checkUpgrade(LockType.RANGE_INSERT,
699                      LockType.WRITE,
700                      null,
701                      LockType.RANGE_INSERT);
702         checkUpgrade(LockType.RANGE_INSERT,
703                      LockType.RANGE_READ,
704                      null,
705                      LockType.RANGE_INSERT);
706         checkUpgrade(LockType.RANGE_INSERT,
707                      LockType.RANGE_WRITE,
708                      null,
709                      LockType.RANGE_INSERT);
710         checkUpgrade(LockType.RANGE_INSERT,
711                      LockType.RANGE_INSERT,
712                      LockGrantType.EXISTING,
713                      LockType.RANGE_INSERT);
714     }
715
716     /**
717      * Tests that when the first request is held and the second request is
718      * requested, the second grant type is returned and the final type is then
719      * held. A null secondGrantType arg means that an assertion is expected.
720      */

721     private void checkUpgrade(LockType firstRequest, LockType secondRequest,
722                               LockGrantType secondGrantType,
723                               LockType finalType)
724         throws Exception JavaDoc {
725
726     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
727         MemoryBudget mb = envImpl.getMemoryBudget();
728
729         try {
730             Lock lock = new Lock(new Long JavaDoc(1));
731
732             assertEquals(LockGrantType.NEW,
733                          lock.lock(firstRequest, txn1, false, mb, 0));
734             LockGrantType typeGranted = null;
735             try {
736                 typeGranted = lock.lock(secondRequest, txn1, false, mb, 0);
737                 if (secondGrantType == null) {
738                     fail("expected AssertionError");
739                 }
740             } catch (AssertionError JavaDoc e) {
741                 if (secondGrantType != null) {
742                     fail(e.toString());
743                 }
744             }
745         assertEquals(secondGrantType, typeGranted);
746
747             Set JavaDoc expectedOwners = new HashSet JavaDoc();
748             expectedOwners.add(new LockInfo(txn1, finalType));
749             checkOwners(expectedOwners, lock, 0);
750             lock.release(txn1, mb, 0);
751             assertEquals(0, lock.nOwners());
752             assertEquals(0, lock.nWaiters());
753         } catch (Exception JavaDoc e) {
754             e.printStackTrace();
755             throw e;
756         } finally {
757             txn1.operationEnd();
758         }
759     }
760
761     /**
762      * Tests that when a range read/write is requested, and a range insert is
763      * waiting but not held, a WAIT_RESTART occurs. This requires that the
764      * waiter list is examined by Lock.lock().
765      */

766     public void testRangeInsertWaiterConflict()
767         throws Exception JavaDoc {
768
769     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
770     Locker txn2 = new AutoTxn(envImpl, new TransactionConfig());
771     Locker txn3 = new AutoTxn(envImpl, new TransactionConfig());
772         MemoryBudget mb = envImpl.getMemoryBudget();
773
774         try {
775             Lock lock = new Lock(new Long JavaDoc(1));
776             assertEquals(LockGrantType.NEW,
777                          lock.lock(LockType.RANGE_READ, txn1, false, mb, 0));
778         assertEquals(LockGrantType.WAIT_NEW,
779                          lock.lock(LockType.RANGE_INSERT, txn2, false, mb, 0));
780         assertEquals(LockGrantType.WAIT_RESTART,
781                          lock.lock(LockType.RANGE_READ, txn3, false, mb, 0));
782
783             /* Check that 1 owner, 1 waiter exist. */
784
785             Set JavaDoc expectedOwners = new HashSet JavaDoc();
786             expectedOwners.add(new LockInfo(txn1, LockType.RANGE_READ));
787             checkOwners(expectedOwners, lock, 2);
788
789             List JavaDoc waiters = new ArrayList JavaDoc();
790             waiters.add(new LockInfo(txn2, LockType.RANGE_INSERT));
791             waiters.add(new LockInfo(txn3, LockType.RESTART));
792             checkWaiters(waiters, lock);
793         } catch (Exception JavaDoc e) {
794             e.printStackTrace();
795             throw e;
796         } finally {
797             txn1.operationEnd();
798             txn2.operationEnd();
799             txn3.operationEnd();
800         }
801     }
802
803     private void checkOwners(Set JavaDoc expectedOwners,
804                              Lock lock,
805                              int numExpectedWaiters) {
806
807         /* check number of owners. */
808         Set JavaDoc owners = lock.getOwnersClone();
809         assertEquals(expectedOwners.size(), owners.size());
810
811         /* check number of waiters. */
812         assertEquals(numExpectedWaiters, lock.nWaiters());
813
814         /* Make sure that isOwner returns the right thing. */
815         Iterator JavaDoc iter = expectedOwners.iterator();
816         while (iter.hasNext()) {
817             LockInfo info = (LockInfo) iter.next();
818
819             /* Make sure it's an owner, of the right type of lock. */
820             assertEquals(info.getLockType().isWriteLock(),
821                          lock.isOwnedWriteLock(info.getLocker()));
822             assertTrue(lock.isOwner(info.getLocker(), info.getLockType()));
823         }
824     }
825       
826     private void checkWaiters(List JavaDoc expectedWaiters,
827                               Lock lock) {
828         List JavaDoc waiters = lock.getWaitersListClone();
829         assertEquals(expectedWaiters.size(), waiters.size());
830
831         /* check order of the list. */
832         for (int i = 0; i < expectedWaiters.size(); i++) {
833             LockInfo info = (LockInfo) expectedWaiters.get(i);
834             LockInfo waiterInfo = (LockInfo) waiters.get(i);
835             assertEquals("i=" + i, info.getLocker(), waiterInfo.getLocker());
836             assertEquals("i=" + i,
837                          info.getLockType(), waiterInfo.getLockType());
838             assertFalse(lock.isOwner(info.getLocker(), info.getLockType()));
839             assertTrue(lock.isWaiter(info.getLocker()));
840         }
841
842                      
843     }
844
845     public void testTransfer()
846         throws Exception JavaDoc {
847
848     Locker txn1 = new AutoTxn(envImpl, new TransactionConfig());
849     Locker txn2 = new AutoTxn(envImpl, new TransactionConfig());
850     Locker txn3 = new AutoTxn(envImpl, new TransactionConfig());
851     Locker txn4 = new AutoTxn(envImpl, new TransactionConfig());
852     Locker txn5 = new AutoTxn(envImpl, new TransactionConfig());
853         MemoryBudget mb = envImpl.getMemoryBudget();
854
855         try {
856             /* Transfer from one locker to another locker. */
857             Lock lock = new Lock(new Long JavaDoc(1));
858             assertEquals(LockGrantType.NEW,
859                          lock.lock(LockType.WRITE, txn1, false, mb, 0));
860             assertEquals(LockGrantType.WAIT_NEW,
861                          lock.lock(LockType.READ, txn2, false, mb, 0));
862             assertTrue(lock.isOwner(txn1, LockType.WRITE));
863             assertFalse(lock.isOwner(txn2, LockType.READ));
864
865             lock.transfer(txn1, txn2, mb, 0);
866             assertFalse(lock.isOwner(txn1, LockType.WRITE));
867             assertFalse(lock.isOwner(txn1, LockType.READ));
868             assertTrue(lock.isOwnedWriteLock(txn2));
869
870             /* Transfer to multiple lockers. */
871             Locker [] destLockers = new Locker[3];
872             destLockers[0] = txn3;
873             destLockers[1] = txn4;
874             destLockers[2] = txn5;
875             lock.demote(txn2);
876             lock.transferMultiple(txn2, destLockers, mb, 0);
877             assertFalse(lock.isOwner(txn2, LockType.WRITE));
878             assertFalse(lock.isOwner(txn2, LockType.READ));
879
880             for (int i = 0; i < destLockers.length; i++) {
881                 assertTrue(lock.isOwner(destLockers[i], LockType.READ));
882                 assertFalse(lock.isOwner(destLockers[i], LockType.WRITE));
883             }
884             
885
886         } finally {
887             txn1.operationEnd();
888             txn2.operationEnd();
889             txn3.operationEnd();
890             txn4.operationEnd();
891             txn5.operationEnd();
892         }
893     }
894 }
895
Popular Tags