KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2002,2006 Oracle. All rights reserved.
5  *
6  * $Id: TxnTest.java,v 1.58 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.io.IOException JavaDoc;
13 import java.io.RandomAccessFile JavaDoc;
14
15 import junit.framework.TestCase;
16
17 import com.sleepycat.je.Cursor;
18 import com.sleepycat.je.Database;
19 import com.sleepycat.je.DatabaseConfig;
20 import com.sleepycat.je.DatabaseEntry;
21 import com.sleepycat.je.DatabaseException;
22 import com.sleepycat.je.DbInternal;
23 import com.sleepycat.je.DeadlockException;
24 import com.sleepycat.je.Environment;
25 import com.sleepycat.je.EnvironmentConfig;
26 import com.sleepycat.je.EnvironmentMutableConfig;
27 import com.sleepycat.je.LockMode;
28 import com.sleepycat.je.LockNotGrantedException;
29 import com.sleepycat.je.LockStats;
30 import com.sleepycat.je.OperationStatus;
31 import com.sleepycat.je.Transaction;
32 import com.sleepycat.je.TransactionConfig;
33 import com.sleepycat.je.config.EnvironmentParams;
34 import com.sleepycat.je.dbi.DatabaseImpl;
35 import com.sleepycat.je.dbi.EnvironmentImpl;
36 import com.sleepycat.je.dbi.MemoryBudget;
37 import com.sleepycat.je.log.FileManager;
38 import com.sleepycat.je.tree.ChildReference;
39 import com.sleepycat.je.tree.IN;
40 import com.sleepycat.je.tree.LN;
41 import com.sleepycat.je.tree.WithRootLatched;
42 import com.sleepycat.je.txn.Txn;
43 import com.sleepycat.je.util.TestUtils;
44
45 /*
46  * Simple transaction testing
47  */

48 public class TxnTest extends TestCase {
49     private File JavaDoc envHome;
50     private Environment env;
51     private Database db;
52
53     public TxnTest()
54         throws DatabaseException {
55
56         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
57     }
58
59     public void setUp()
60         throws IOException JavaDoc, DatabaseException {
61
62     IN.ACCUMULATED_LIMIT = 0;
63     Txn.ACCUMULATED_LIMIT = 0;
64
65         TestUtils.removeFiles("Setup", envHome, FileManager.JE_SUFFIX);
66
67         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
68         envConfig.setConfigParam(EnvironmentParams.NODE_MAX.getName(), "6");
69         envConfig.setTransactional(true);
70         envConfig.setAllowCreate(true);
71         env = new Environment(envHome, envConfig);
72
73         DatabaseConfig dbConfig = new DatabaseConfig();
74         dbConfig.setTransactional(true);
75         dbConfig.setAllowCreate(true);
76         db = env.openDatabase(null, "foo", dbConfig);
77     }
78
79     public void tearDown()
80         throws IOException JavaDoc, DatabaseException {
81
82         db.close();
83         env.close();
84         TestUtils.removeFiles("TearDown", envHome, FileManager.JE_SUFFIX);
85     }
86
87     /**
88      * Test transaction locking and releasing
89      */

90     public void testBasicLocking()
91         throws Throwable JavaDoc {
92
93         try {
94
95             LN ln = new LN(new byte[0]);
96
97             /*
98              * Make a null txn that will lock. Take a lock and then end the
99              * operation.
100              */

101             EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env);
102             MemoryBudget mb = envImpl.getMemoryBudget();
103             
104             long beforeLock = mb.getCacheMemoryUsage();
105             Locker nullTxn = new BasicLocker(envImpl);
106
107             LockGrantType lockGrant = nullTxn.lock
108                 (ln.getNodeId(), LockType.READ, false,
109                  DbInternal.dbGetDatabaseImpl(db)).
110         getLockGrant();
111             assertEquals(LockGrantType.NEW, lockGrant);
112             long afterLock = mb.getCacheMemoryUsage();
113             checkHeldLocks(nullTxn, 1, 0);
114
115             nullTxn.operationEnd();
116             long afterRelease = mb.getCacheMemoryUsage();
117             checkHeldLocks(nullTxn, 0, 0);
118             checkCacheUsage(beforeLock, afterLock, afterRelease,
119                             LockManager.TOTAL_LOCK_OVERHEAD +
120                             MemoryBudget.LOCKINFO_OVERHEAD);
121
122             /* Take a lock, release it. */
123             beforeLock = mb.getCacheMemoryUsage();
124             lockGrant = nullTxn.lock
125                 (ln.getNodeId(), LockType.READ, false,
126                  DbInternal.dbGetDatabaseImpl(db)).
127         getLockGrant();
128             afterLock = mb.getCacheMemoryUsage();
129             assertEquals(LockGrantType.NEW, lockGrant);
130             checkHeldLocks(nullTxn, 1, 0);
131
132             nullTxn.releaseLock(ln.getNodeId());
133             checkHeldLocks(nullTxn, 0, 0);
134             afterRelease = mb.getCacheMemoryUsage();
135             checkCacheUsage(beforeLock, afterLock, afterRelease,
136                             LockManager.TOTAL_LOCK_OVERHEAD +
137                             MemoryBudget.LOCKINFO_OVERHEAD);
138
139             /*
140              * Make a user transaction, check lock and release.
141              */

142             beforeLock = mb.getCacheMemoryUsage();
143             Txn userTxn = new Txn(envImpl, new TransactionConfig());
144             lockGrant = userTxn.lock
145                 (ln.getNodeId(), LockType.READ, false,
146                  DbInternal.dbGetDatabaseImpl(db)).
147         getLockGrant();
148             afterLock = mb.getCacheMemoryUsage();
149
150             assertEquals(LockGrantType.NEW, lockGrant);
151             checkHeldLocks(userTxn, 1, 0);
152
153             /* Try demoting, nothing should happen. */
154             try {
155                 userTxn.demoteLock(ln.getNodeId());
156                 fail("exception not thrown on phoney demoteLock");
157             } catch (AssertionError JavaDoc e){
158             }
159             checkHeldLocks(userTxn, 1, 0);
160             long afterDemotion = mb.getCacheMemoryUsage();
161             assertEquals(afterLock, afterDemotion);
162
163             /* Make it a write lock, then demote. */
164             lockGrant = userTxn.lock
165                 (ln.getNodeId(), LockType.WRITE, false,
166                  DbInternal.dbGetDatabaseImpl(db)).
167         getLockGrant();
168             assertEquals(LockGrantType.PROMOTION, lockGrant);
169             long afterWriteLock = mb.getCacheMemoryUsage();
170             assertTrue(afterWriteLock > afterLock);
171             assertTrue(afterLock > beforeLock);
172
173             checkHeldLocks(userTxn, 0, 1);
174             userTxn.demoteLock(ln.getNodeId());
175             checkHeldLocks(userTxn, 1, 0);
176
177             /* Shouldn't release at operation end. */
178             userTxn.operationEnd();
179             checkHeldLocks(userTxn, 1, 0);
180
181             userTxn.releaseLock(ln.getNodeId());
182             checkHeldLocks(userTxn, 0, 0);
183             userTxn.commit(Txn.TXN_SYNC);
184             afterRelease = mb.getCacheMemoryUsage();
185             assertTrue(afterLock > beforeLock);
186         } catch (Throwable JavaDoc t) {
187             /* print stack trace before going to teardown. */
188             t.printStackTrace();
189             throw t;
190         }
191     }
192
193     private void checkHeldLocks(Locker txn,
194                 int numReadLocks,
195                 int numWriteLocks)
196         throws DatabaseException {
197
198         LockStats stat = txn.collectStats(new LockStats());
199         assertEquals(numReadLocks, stat.getNReadLocks());
200         assertEquals(numWriteLocks, stat.getNWriteLocks());
201     }
202
203     /**
204      * Test transaction commit, from the locking point of view.
205      */

206     public void testCommit()
207         throws Throwable JavaDoc {
208
209         try {
210             LN ln1 = new LN(new byte[0]);
211             LN ln2 = new LN(new byte[0]);
212                                           
213             EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env);
214             Txn userTxn = new Txn(envImpl, new TransactionConfig());
215
216             /* Get read lock 1. */
217             LockGrantType lockGrant = userTxn.lock
218                 (ln1.getNodeId(), LockType.READ, false,
219                  DbInternal.dbGetDatabaseImpl(db)).
220         getLockGrant();
221             assertEquals(LockGrantType.NEW, lockGrant);
222             checkHeldLocks(userTxn, 1, 0);
223
224             /* Get read lock 2. */
225             lockGrant = userTxn.lock
226                 (ln2.getNodeId(), LockType.READ, false,
227                  DbInternal.dbGetDatabaseImpl(db)).
228         getLockGrant();
229             assertEquals(LockGrantType.NEW, lockGrant);
230             checkHeldLocks(userTxn, 2, 0);
231
232             /* Upgrade read lock 2 to a write. */
233             lockGrant = userTxn.lock
234                 (ln2.getNodeId(), LockType.WRITE, false,
235                  DbInternal.dbGetDatabaseImpl(db)).
236         getLockGrant();
237             assertEquals(LockGrantType.PROMOTION, lockGrant);
238             checkHeldLocks(userTxn, 1, 1);
239
240             /* Read lock 1 again, shouldn't increase count. */
241             lockGrant = userTxn.lock
242                 (ln1.getNodeId(), LockType.READ, false,
243                  DbInternal.dbGetDatabaseImpl(db)).
244         getLockGrant();
245             assertEquals(LockGrantType.EXISTING, lockGrant);
246             checkHeldLocks(userTxn, 1, 1);
247
248             /* Shouldn't release at operation end. */
249             long commitLsn = userTxn.commit(Txn.TXN_SYNC);
250             checkHeldLocks(userTxn, 0, 0);
251
252             TxnCommit commitRecord =
253                 (TxnCommit) envImpl.getLogManager().get(commitLsn);
254
255             assertEquals(userTxn.getId(), commitRecord.getId());
256             assertEquals(userTxn.getLastLsn(), commitRecord.getLastLsn());
257         } catch (Throwable JavaDoc t) {
258             /* Print stack trace before going to teardown. */
259             t.printStackTrace();
260             throw t;
261         }
262     }
263
264     /**
265      * Make sure an abort never tries to split the tree.
266      */

267     public void testAbortNoSplit()
268         throws Throwable JavaDoc {
269
270         try {
271             Transaction txn = env.beginTransaction(null, null);
272
273             DatabaseEntry keyDbt = new DatabaseEntry();
274             DatabaseEntry dataDbt = new DatabaseEntry();
275             dataDbt.setData(new byte[1]);
276         
277             /* Insert enough data so that the tree is ripe for a split. */
278             int numForSplit = 25;
279             for (int i = 0; i < numForSplit; i++) {
280                 keyDbt.setData(TestUtils.getTestArray(i));
281                 db.put(txn, keyDbt, dataDbt);
282             }
283
284             /* Check that we're ready for a split. */
285             DatabaseImpl database = DbInternal.dbGetDatabaseImpl(db);
286             CheckReadyToSplit splitChecker = new CheckReadyToSplit(database);
287             database.getTree().withRootLatchedShared(splitChecker);
288             assertTrue(splitChecker.getReadyToSplit());
289
290             /*
291              * Make another txn that will get a read lock on the map
292              * LSN. Then abort the first txn. It shouldn't try to do a
293              * split, if it does, we'll run into the
294              * no-latches-while-locking check.
295              */

296             Transaction txnSpoiler = env.beginTransaction(null, null);
297             DatabaseConfig dbConfig = new DatabaseConfig();
298             dbConfig.setTransactional(true);
299             Database dbSpoiler = env.openDatabase(txnSpoiler, "foo", dbConfig);
300
301             txn.abort();
302
303             /*
304              * The database should be empty
305              */

306             Cursor cursor = dbSpoiler.openCursor(txnSpoiler, null);
307             
308             assertTrue(cursor.getFirst(keyDbt, dataDbt, LockMode.DEFAULT) !=
309                        OperationStatus.SUCCESS);
310             cursor.close();
311             txnSpoiler.abort();
312         } catch (Throwable JavaDoc t) {
313             /* print stack trace before going to teardown. */
314             t.printStackTrace();
315             throw t;
316         }
317     }
318
319     public void testTransactionName()
320         throws Throwable JavaDoc {
321
322         try {
323             Transaction txn = env.beginTransaction(null, null);
324         txn.setName("blort");
325         assertEquals("blort", txn.getName());
326             txn.abort();
327
328             /*
329              * [#14349] Make sure the txn is printable after closing. We
330              * once had a NullPointerException.
331              */

332             String JavaDoc s = txn.toString();
333         } catch (Throwable JavaDoc t) {
334             /* print stack trace before going to teardown. */
335             t.printStackTrace();
336             throw t;
337         }
338     }
339
340     /**
341      * Test all combinations of sync, nosync, and writeNoSync for txn
342      * commits.
343      */

344
345     /* SyncCombo expresses all the combinations of txn sync properties. */
346     private static class SyncCombo {
347         private boolean envNoSync;
348         private boolean envWriteNoSync;
349         private boolean txnNoSync;
350         private boolean txnWriteNoSync;
351         private boolean txnSync;
352         boolean expectSync;
353         boolean expectWrite;
354
355         SyncCombo(int envWriteNoSync,
356                   int envNoSync,
357                   int txnSync,
358                   int txnWriteNoSync,
359                   int txnNoSync,
360                   boolean expectSync,
361                   boolean expectWrite) {
362             this.envNoSync = (envNoSync == 0) ? false : true;
363             this.envWriteNoSync = (envWriteNoSync == 0) ? false : true;
364             this.txnNoSync = (txnNoSync == 0) ? false : true;
365             this.txnWriteNoSync = (txnWriteNoSync == 0) ? false : true;
366             this.txnSync = (txnSync == 0) ? false : true;
367             this.expectSync = expectSync;
368             this.expectWrite = expectWrite;
369         }
370
371         TransactionConfig getTxnConfig() {
372             TransactionConfig txnConfig = new TransactionConfig();
373             txnConfig.setSync(txnSync);
374             txnConfig.setWriteNoSync(txnWriteNoSync);
375             txnConfig.setNoSync(txnNoSync);
376             return txnConfig;
377         }
378
379         void setEnvironmentMutableConfig(Environment env)
380             throws DatabaseException {
381             EnvironmentMutableConfig config = env.getMutableConfig();
382             config.setTxnNoSync(envNoSync);
383             config.setTxnWriteNoSync(envWriteNoSync);
384             env.setMutableConfig(config);
385         }
386     }
387
388     public void testSyncCombo()
389         throws Throwable JavaDoc {
390
391         RandomAccessFile JavaDoc logFile =
392             new RandomAccessFile JavaDoc(new File JavaDoc(envHome, "00000000.jdb"), "r");
393         try {
394             SyncCombo [] testCombinations = {
395             /* Env Env Txn Txn Txn Expect Expect
396              * WrNoSy NoSy Sync WrNoSy NoSyc Sync Write */

397             new SyncCombo( 0, 0, 0, 0, 0, true, true),
398             new SyncCombo( 0, 0, 0, 0, 1, false, false),
399             new SyncCombo( 0, 0, 0, 1, 0, false, true),
400             new SyncCombo( 0, 0, 0, 1, 1, false, true),
401             new SyncCombo( 0, 0, 1, 0, 0, true, true),
402             new SyncCombo( 0, 0, 1, 0, 1, true, true),
403             new SyncCombo( 0, 0, 1, 1, 0, true, true),
404             new SyncCombo( 0, 0, 1, 1, 1, true, true),
405             new SyncCombo( 0, 1, 0, 0, 0, false, false),
406             new SyncCombo( 0, 1, 0, 0, 1, false, false),
407             new SyncCombo( 0, 1, 0, 1, 0, false, true),
408             new SyncCombo( 0, 1, 0, 1, 1, false, true),
409             new SyncCombo( 0, 1, 1, 0, 0, true, true),
410             new SyncCombo( 0, 1, 1, 0, 1, true, true),
411             new SyncCombo( 0, 1, 1, 1, 0, true, true),
412             new SyncCombo( 0, 1, 1, 1, 1, true, true),
413             new SyncCombo( 1, 0, 0, 0, 0, false, true),
414             new SyncCombo( 1, 0, 0, 0, 1, false, false),
415             new SyncCombo( 1, 0, 0, 1, 0, false, true),
416             new SyncCombo( 1, 0, 0, 1, 1, false, true),
417             new SyncCombo( 1, 0, 1, 0, 0, true, true),
418             new SyncCombo( 1, 0, 1, 0, 1, true, true),
419             new SyncCombo( 1, 0, 1, 1, 0, true, true),
420             new SyncCombo( 1, 0, 1, 1, 1, true, true),
421             new SyncCombo( 1, 1, 0, 0, 0, false, true),
422             new SyncCombo( 1, 1, 0, 0, 1, false, false),
423             new SyncCombo( 1, 1, 0, 1, 0, false, true),
424             new SyncCombo( 1, 1, 0, 1, 1, false, true),
425             new SyncCombo( 1, 1, 1, 0, 0, true, true),
426             new SyncCombo( 1, 1, 1, 0, 1, true, true),
427             new SyncCombo( 1, 1, 1, 1, 0, true, true),
428             new SyncCombo( 1, 1, 1, 1, 1, true, true)};
429
430             /* envNoSync=false with default env config */
431             assertTrue(!env.getMutableConfig().getTxnNoSync());
432
433             /* envWriteNoSync=false with default env config */
434             assertTrue(!env.getMutableConfig().getTxnWriteNoSync());
435
436             /*
437              * For each combination of settings, call commit and
438              * check that we have the expected sync and log
439              * write. Make sure that commitSync(), commitNoSync always
440              * override all preferences.
441              */

442             for (int i = 0; i < testCombinations.length; i++) {
443                 SyncCombo combo = testCombinations[i];
444                 TransactionConfig txnConfig = combo.getTxnConfig();
445                 combo.setEnvironmentMutableConfig(env);
446                 syncExplicit(logFile, txnConfig,
447                              combo.expectSync, combo.expectWrite);
448             }
449
450             SyncCombo [] autoCommitCombinations = {
451             /* Env Env Txn Txn Txn Expect Expect
452              * WrNoSy NoSy Sync WrNoSy NoSyc Sync Write */

453             new SyncCombo( 0, 0, 0, 0, 0, true, true),
454             new SyncCombo( 0, 1, 0, 0, 0, false, false),
455             new SyncCombo( 1, 0, 0, 0, 0, false, true),
456             new SyncCombo( 1, 1, 0, 0, 0, false, true)};
457
458             for (int i = 0; i < autoCommitCombinations.length; i++) {
459                 SyncCombo combo = autoCommitCombinations[i];
460                 combo.setEnvironmentMutableConfig(env);
461                 syncAutoCommit(logFile, combo.expectSync, combo.expectWrite);
462             }
463         } catch (Throwable JavaDoc t) {
464             /* print stack trace before going to teardown. */
465             t.printStackTrace();
466             throw t;
467         } finally {
468             logFile.close();
469         }
470     }
471
472     /**
473      * Does an explicit commit and returns whether an fsync occured.
474      */

475     private void syncExplicit(RandomAccessFile JavaDoc lastLogFile,
476                               TransactionConfig config,
477                               boolean expectSync,
478                               boolean expectWrite)
479         throws DatabaseException, IOException JavaDoc {
480
481         DatabaseEntry key = new DatabaseEntry(new byte[1]);
482         DatabaseEntry data = new DatabaseEntry(new byte[1]);
483
484         long beforeSyncs = getNSyncs();
485         Transaction txn = env.beginTransaction(null, config);
486         db.put(txn, key, data);
487         long beforeLength = lastLogFile.length();
488         txn.commit();
489         long afterSyncs = getNSyncs();
490         long afterLength = lastLogFile.length();
491         boolean syncOccurred = afterSyncs > beforeSyncs;
492         boolean writeOccurred = afterLength > beforeLength;
493         assertEquals(expectSync, syncOccurred);
494         assertEquals(expectWrite, writeOccurred);
495
496         /*
497          * Make sure explicit sync/noSync/writeNoSync always works.
498          */

499
500         /* Expect a sync and write. */
501         beforeSyncs = getNSyncs();
502         beforeLength = lastLogFile.length();
503         txn = env.beginTransaction(null, config);
504         db.put(txn, key, data);
505         txn.commitSync();
506         afterSyncs = getNSyncs();
507         afterLength = lastLogFile.length();
508         assert(afterSyncs > beforeSyncs);
509         assert(afterLength > beforeLength);
510
511         /* Expect neither a sync nor write. */
512         beforeSyncs = getNSyncs();
513         beforeLength = lastLogFile.length();
514         txn = env.beginTransaction(null, config);
515         db.put(txn, key, data);
516         txn.commitNoSync();
517         afterSyncs = getNSyncs();
518         afterLength = lastLogFile.length();
519         assert(afterSyncs == beforeSyncs);
520         assert(afterLength == beforeLength);
521
522         /* Expect no sync but do expect a write. */
523         beforeSyncs = getNSyncs();
524         beforeLength = lastLogFile.length();
525         txn = env.beginTransaction(null, config);
526         db.put(txn, key, data);
527         txn.commitWriteNoSync();
528         afterSyncs = getNSyncs();
529         afterLength = lastLogFile.length();
530         assert(afterSyncs == beforeSyncs);
531         assert(afterLength > beforeLength);
532     }
533
534     /**
535      * Does an auto-commit and returns whether an fsync occured.
536      */

537     private void syncAutoCommit(RandomAccessFile JavaDoc lastLogFile,
538                                 boolean expectSync,
539                                 boolean expectWrite)
540         throws DatabaseException, IOException JavaDoc {
541
542         DatabaseEntry key = new DatabaseEntry(new byte[1]);
543         DatabaseEntry data = new DatabaseEntry(new byte[1]);
544         long beforeSyncs = getNSyncs();
545         long beforeLength = lastLogFile.length();
546         db.put(null, key, data);
547         long afterLength = lastLogFile.length();
548         long afterSyncs = getNSyncs();
549         boolean syncOccurred = afterSyncs > beforeSyncs;
550         assertEquals(expectSync, syncOccurred);
551         assertEquals(expectWrite, (afterLength > beforeLength));
552     }
553
554     /**
555      * Returns number of fsyncs statistic.
556      */

557     private long getNSyncs() {
558         return DbInternal.envGetEnvironmentImpl(env)
559                          .getFileManager()
560                          .getNFSyncs();
561     }
562
563     public void testNoWaitConfig()
564         throws Throwable JavaDoc {
565
566         try {
567             TransactionConfig defaultConfig = new TransactionConfig();
568             TransactionConfig noWaitConfig = new TransactionConfig();
569             noWaitConfig.setNoWait(true);
570             Transaction txn;
571
572             /* noWait=false */
573
574             assertTrue(!isNoWaitTxn(null));
575
576             txn = env.beginTransaction(null, null);
577             assertTrue(!isNoWaitTxn(txn));
578             txn.abort();
579
580             txn = env.beginTransaction(null, defaultConfig);
581             assertTrue(!isNoWaitTxn(txn));
582             txn.abort();
583
584             /* noWait=true */
585
586             txn = env.beginTransaction(null, noWaitConfig);
587             assertTrue(isNoWaitTxn(txn));
588             txn.abort();
589
590         } catch (Throwable JavaDoc t) {
591             /* print stack trace before going to teardown. */
592             t.printStackTrace();
593             throw t;
594         }
595     }
596
597     /**
598      * Returns whether the given txn is a no-wait txn, or if the txn parameter
599      * is null returns whether an auto-commit txn is a no-wait txn.
600      */

601     private boolean isNoWaitTxn(Transaction txn)
602         throws DatabaseException {
603
604         DatabaseEntry key = new DatabaseEntry(new byte[1]);
605         DatabaseEntry data = new DatabaseEntry(new byte[1]);
606
607         /* Use a wait txn to get a write lock. */
608         Transaction txn2 = env.beginTransaction(null, null);
609         db.put(txn2, key, data);
610
611         try {
612             db.put(txn, key, data);
613             throw new IllegalStateException JavaDoc
614                 ("Lock should not have been granted");
615         } catch (LockNotGrantedException e) {
616             return true;
617         } catch (DeadlockException e) {
618             return false;
619         } finally {
620             txn2.abort();
621         }
622     }
623
624     /*
625      * Assert that cache utilization is correctly incremented by locks and
626      * txns, and decremented after release.
627      */

628     private void checkCacheUsage(long beforeLock,
629                                  long afterLock,
630                                  long afterRelease,
631                                  long expectedSize) {
632         assertEquals(beforeLock, afterRelease);
633         assertEquals(afterLock, (beforeLock + expectedSize));
634     }
635
636     class CheckReadyToSplit implements WithRootLatched {
637         private boolean readyToSplit;
638         private DatabaseImpl database;
639
640         CheckReadyToSplit(DatabaseImpl database) {
641             readyToSplit = false;
642             this.database = database;
643         }
644         
645         public boolean getReadyToSplit() {
646             return readyToSplit;
647         }
648
649         public IN doWork(ChildReference root)
650             throws DatabaseException {
651
652             IN rootIN = (IN) root.fetchTarget(database, null);
653             readyToSplit = rootIN.needsSplitting();
654             return null;
655         }
656     }
657 }
658
Popular Tags