KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > dbi > INListTest


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

8
9 package com.sleepycat.je.dbi;
10
11 import java.io.File JavaDoc;
12 import java.util.HashSet JavaDoc;
13 import java.util.Iterator JavaDoc;
14 import java.util.Set JavaDoc;
15
16 import junit.framework.TestCase;
17
18 import com.sleepycat.je.Database;
19 import com.sleepycat.je.DatabaseConfig;
20 import com.sleepycat.je.DbInternal;
21 import com.sleepycat.je.Environment;
22 import com.sleepycat.je.EnvironmentConfig;
23 import com.sleepycat.je.config.EnvironmentParams;
24 import com.sleepycat.je.junit.JUnitThread;
25 import com.sleepycat.je.log.FileManager;
26 import com.sleepycat.je.tree.IN;
27 import com.sleepycat.je.util.TestUtils;
28
29 public class INListTest extends TestCase {
30     private static String JavaDoc DB_NAME = "INListTestDb";
31     private File JavaDoc envHome;
32     private volatile int sequencer = 0;
33     private Environment env;
34     private EnvironmentImpl envImpl;
35     private Database db;
36     private DatabaseImpl dbImpl;
37     private DatabaseConfig dbConfig;
38     private INList inList1 = null;
39
40     public INListTest() {
41         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
42         dbConfig = new DatabaseConfig();
43         dbConfig.setAllowCreate(true);
44
45     }
46
47     public void setUp()
48         throws Exception JavaDoc {
49
50         TestUtils.removeFiles("Setup", envHome, FileManager.JE_SUFFIX);
51         sequencer = 0;
52         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
53         envConfig.setAllowCreate(true);
54         envConfig.setConfigParam(EnvironmentParams.ENV_RUN_EVICTOR.getName(),
55                                  "false");
56         env = new Environment(envHome, envConfig);
57         envImpl = DbInternal.envGetEnvironmentImpl(env);
58
59         inList1 = new INList(envImpl);
60         db = env.openDatabase(null, DB_NAME, dbConfig);
61         dbImpl = DbInternal.dbGetDatabaseImpl(db);
62     }
63
64     public void tearDown()
65     throws Exception JavaDoc {
66
67         inList1 = null;
68         db.close();
69     env.close();
70         TestUtils.removeFiles("TearDown", envHome, FileManager.JE_SUFFIX);
71     }
72
73     public void testMajorMinorLatching()
74     throws Throwable JavaDoc {
75         
76         JUnitThread tester1 =
77             new JUnitThread("testMajorMinorLatching-Thread1") {
78                 public void testBody() {
79
80                     try {
81                         /* Create two initial elements. */
82                         for (int i = 0; i < 2; i++) {
83                             IN in = new IN(dbImpl, null, 1, 1);
84                             inList1.add(in);
85                         }
86
87                         /*
88                          * Acquire the major latch in preparation for an
89                          * iteration.
90                          */

91                         inList1.latchMajor();
92
93                         /* Wait for tester2 to try to acquire the
94                            /* minor latch */

95                         sequencer = 1;
96                         while (sequencer <= 1) {
97                             Thread.yield();
98                         }
99
100                         /*
101                          * Sequencer is now 2. There should only be
102                          * two elements in the list right now even
103                          * though thread 2 added a third one.
104                          */

105                         int count = 0;
106                         Iterator JavaDoc iter = inList1.iterator();
107                         while (iter.hasNext()) {
108                             iter.next();
109                             count++;
110                         }
111
112                         assertEquals(2, count);
113
114                         /*
115                          * Allow thread2 to run again. It will
116                          * add another element and throw control
117                          * back to thread 1.
118                          */

119                         sequencer++; // now it's 3
120
while (sequencer <= 3) {
121                             Thread.yield();
122                         }
123
124                         /*
125                          * Thread2 has exited. Release the major
126                          * latch so that the addedINs can be added
127                          * into the main in set.
128                          */

129                         inList1.releaseMajorLatch();
130
131                         /*
132                          * Check that the entry added by tester2 was really
133                          * added.
134                          */

135                         inList1.latchMajor();
136                         count = 0;
137                         iter = inList1.iterator();
138                         while (iter.hasNext()) {
139                             iter.next();
140                             count++;
141                         }
142
143                         assertEquals(4, count);
144                         inList1.releaseMajorLatch();
145                     } catch (Throwable JavaDoc T) {
146                         T.printStackTrace(System.out);
147                         fail("Thread 1 caught some Throwable: " + T);
148                     }
149                 }
150             };
151
152         JUnitThread tester2 =
153             new JUnitThread("testMajorMinorLatching-Thread2") {
154                 public void testBody() {
155
156                     try {
157                         /* Wait for tester1 to start */
158                         while (sequencer < 1) {
159                             Thread.yield();
160                         }
161
162                         assertEquals(1, sequencer);
163
164                         /*
165                          * Acquire the minor latch in preparation for some
166                          * concurrent additions.
167                          */

168                         inList1.add(new IN(dbImpl, null, 1, 1));
169                         sequencer++;
170
171                         /* Sequencer is now 2. */
172
173                         while (sequencer < 3) {
174                             Thread.yield();
175                         }
176
177                         assertEquals(3, sequencer);
178                         /* Add one more element. */
179                         inList1.add(new IN(dbImpl, null, 1, 1));
180                         sequencer++;
181                     } catch (Throwable JavaDoc T) {
182                         T.printStackTrace(System.out);
183                         fail("Thread 2 caught some Throwable: " + T);
184                     }
185                 }
186             };
187
188         tester1.start();
189         tester2.start();
190         tester1.finishTest();
191         tester2.finishTest();
192     }
193
194     /*
195      * Some actions hold the major inlist latch, but can provoke additions or
196      * removals of objects from the inlist. For example, the evictor may cause
197      * a fetch of an IN. Make sure the latching works, and iterators can safely
198      * be used during the time of the latch.
199      */

200     public void testFetchingWhenHoldingLatch()
201         throws Exception JavaDoc {
202
203         Set JavaDoc expectedNodes = new HashSet JavaDoc();
204
205         /* Create 3 initial elements. */
206         IN startIN = null;
207         for (int i = 0; i < 3; i++) {
208             startIN = new IN(dbImpl, null, 1, 1);
209             inList1.add(startIN);
210             expectedNodes.add(startIN);
211         }
212
213         inList1.latchMajor();
214         try {
215             /* Add two more nodes; they should go onto the minor list. */
216             IN inA = new IN(dbImpl, null, 1, 1);
217             inList1.add(inA);
218             IN inB = new IN(dbImpl, null, 1, 1);
219             inList1.add(inB);
220
221             /* We should see the original 3 items. */
222             checkContents(expectedNodes);
223
224             /*
225              * Now remove an item on the major list, and one from the
226              * minor list. (i.e, what would happen if we evicted.)
227              */

228             inList1.removeLatchAlreadyHeld(startIN);
229
230             /* We should see the original 2 items. */
231             expectedNodes.remove(startIN);
232             checkContents(expectedNodes);
233
234             /*
235              * Remove an item from the minor list. This ends up flushing the
236              * minor list into the major list.
237              */

238             inList1.removeLatchAlreadyHeld(inA);
239             expectedNodes.add(inB);
240             checkContents(expectedNodes);
241
242             /* re-add INA */
243             inList1.add(inA);
244
245             /* release the major latch, should flush the major list. */
246             inList1.releaseMajorLatch();
247
248             inList1.latchMajor();
249             expectedNodes.add(inA);
250             checkContents(expectedNodes);
251
252         } finally {
253             inList1.releaseMajorLatchIfHeld();
254         }
255     }
256
257     private void checkContents(Set JavaDoc expectedNodes)
258         throws Exception JavaDoc {
259
260         Set JavaDoc seen = new HashSet JavaDoc();
261         Iterator JavaDoc iter = inList1.iterator();
262         while (iter.hasNext()) {
263             IN foo = (IN)iter.next();
264             assertTrue(expectedNodes.contains(foo));
265             assertTrue(!seen.contains(foo));
266             seen.add(foo);
267         }
268         assertEquals(expectedNodes.size(), seen.size());
269     }
270 }
271
Popular Tags