KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > evictor > EvictActionTest


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

8
9 package com.sleepycat.je.evictor;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13
14 import junit.framework.TestCase;
15
16 import com.sleepycat.bind.tuple.IntegerBinding;
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.Environment;
24 import com.sleepycat.je.EnvironmentConfig;
25 import com.sleepycat.je.EnvironmentMutableConfig;
26 import com.sleepycat.je.LockMode;
27 import com.sleepycat.je.OperationStatus;
28 import com.sleepycat.je.config.EnvironmentParams;
29 import com.sleepycat.je.dbi.EnvironmentImpl;
30 import com.sleepycat.je.dbi.MemoryBudget;
31 import com.sleepycat.je.junit.JUnitThread;
32 import com.sleepycat.je.tree.IN;
33 import com.sleepycat.je.txn.Txn;
34 import com.sleepycat.je.util.TestUtils;
35
36 /**
37  * This tests exercises the act of eviction and determines whether the
38  * expected nodes have been evicted properly.
39  */

40 public class EvictActionTest extends TestCase {
41
42     private static final boolean DEBUG = false;
43     private static final int NUM_KEYS = 60;
44     private static final int NUM_DUPS = 30;
45     private static final int BIG_CACHE_SIZE = 500000;
46     private static final int SMALL_CACHE_SIZE = (int)
47     MemoryBudget.MIN_MAX_MEMORY_SIZE;
48
49     private File JavaDoc envHome = null;
50     private Environment env = null;
51     private Database db = null;
52
53     public EvictActionTest() {
54         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
55     }
56
57     public void setUp()
58         throws IOException JavaDoc {
59
60     IN.ACCUMULATED_LIMIT = 0;
61     Txn.ACCUMULATED_LIMIT = 0;
62
63         TestUtils.removeLogFiles("Setup", envHome, false);
64     }
65     
66     public void tearDown()
67         throws Exception JavaDoc {
68
69         TestUtils.removeLogFiles("TearDown", envHome, false);
70
71         if (env != null) {
72             try {
73                 env.close();
74             } catch (Throwable JavaDoc e) {
75                 System.out.println("tearDown: " + e);
76             }
77         }
78
79         envHome = null;
80         env = null;
81         db = null;
82     }
83
84     public void testEvict()
85         throws Throwable JavaDoc {
86
87         try {
88             doEvict(50, SMALL_CACHE_SIZE, true);
89         } catch (Throwable JavaDoc t) {
90             t.printStackTrace();
91             throw t;
92         }
93     }
94
95     public void testNoNeedToEvict()
96         throws Throwable JavaDoc {
97
98         try {
99             doEvict(80, BIG_CACHE_SIZE, false);
100         } catch (Throwable JavaDoc t) {
101             t.printStackTrace();
102             throw t;
103         }
104     }
105
106     /**
107      * Evict in very controlled circumstances. Check that we first strip
108      * BINs and later evict BINS.
109      */

110     private void doEvict(int floor,
111                          int maxMem,
112                          boolean shouldEvict)
113         throws Throwable JavaDoc {
114
115         try {
116             openEnv(floor, maxMem);
117             insertData(NUM_KEYS);
118
119             /* Evict once after insert. */
120             evictAndCheck(shouldEvict, NUM_KEYS);
121
122             /* Evict again after verification. */
123             evictAndCheck(shouldEvict, NUM_KEYS);
124
125             closeEnv();
126         } catch (Throwable JavaDoc t) {
127             t.printStackTrace();
128             throw (t);
129         }
130     }
131
132     public void testSetCacheSize()
133         throws DatabaseException {
134
135         /* Start with large cache size. */
136         openEnv(80, BIG_CACHE_SIZE);
137         EnvironmentMutableConfig config = env.getMutableConfig();
138         insertData(NUM_KEYS);
139
140         /* No need to evict. */
141         verifyData(NUM_KEYS);
142         evictAndCheck(false, NUM_KEYS);
143
144         /* Set small cache size. */
145         config.setCacheSize(SMALL_CACHE_SIZE);
146         env.setMutableConfig(config);
147
148         /* Expect eviction. */
149         verifyData(NUM_KEYS);
150         evictAndCheck(true, NUM_KEYS);
151
152         /* Set large cache size. */
153         config.setCacheSize(BIG_CACHE_SIZE);
154         env.setMutableConfig(config);
155
156         /* Expect no eviction. */
157         verifyData(NUM_KEYS);
158         evictAndCheck(false, NUM_KEYS);
159
160         closeEnv();
161     }
162
163     public void testSetCachePercent()
164         throws DatabaseException {
165
166         int nKeys = NUM_KEYS * 500;
167
168         /* Start with large cache size. */
169         openEnv(80, BIG_CACHE_SIZE);
170         EnvironmentMutableConfig config = env.getMutableConfig();
171         config.setCacheSize(0);
172         config.setCachePercent(90);
173         env.setMutableConfig(config);
174         insertData(nKeys);
175
176         /* No need to evict. */
177         verifyData(nKeys);
178         evictAndCheck(false, nKeys);
179
180         /* Set small cache percent. */
181         config.setCacheSize(0);
182         config.setCachePercent(1);
183         env.setMutableConfig(config);
184
185         /* Expect eviction. */
186         verifyData(nKeys);
187         evictAndCheck(true, nKeys);
188
189         /* Set large cache percent. */
190         config.setCacheSize(0);
191         config.setCachePercent(90);
192         env.setMutableConfig(config);
193
194         /* Expect no eviction. */
195         verifyData(nKeys);
196         evictAndCheck(false, nKeys);
197
198         closeEnv();
199     }
200
201     public void testThreadedCacheSizeChanges()
202         throws DatabaseException {
203
204         final int N_ITERS = 10;
205         openEnv(80, BIG_CACHE_SIZE);
206         insertData(NUM_KEYS);
207
208         JUnitThread writer = new JUnitThread("Writer") {
209             public void testBody()
210                 throws DatabaseException {
211                 for (int i = 0; i < N_ITERS; i += 1) {
212                     env.evictMemory();
213                     /* insertData will update if data exists. */
214                     insertData(NUM_KEYS);
215                     env.evictMemory();
216                     EnvironmentMutableConfig config = env.getMutableConfig();
217                     config.setCacheSize(SMALL_CACHE_SIZE);
218                     env.setMutableConfig(config);
219                 }
220             }
221         };
222
223         JUnitThread reader = new JUnitThread("Reader") {
224             public void testBody()
225                 throws DatabaseException {
226                 for (int i = 0; i < N_ITERS; i += 1) {
227                     env.evictMemory();
228                     verifyData(NUM_KEYS);
229                     env.evictMemory();
230                     EnvironmentMutableConfig config = env.getMutableConfig();
231                     config.setCacheSize(BIG_CACHE_SIZE);
232                     env.setMutableConfig(config);
233                 }
234             }
235         };
236
237         writer.start();
238         reader.start();
239
240         try {
241             writer.finishTest();
242         } catch (Throwable JavaDoc e) {
243             try {
244                 reader.finishTest();
245             } catch (Throwable JavaDoc ignore) { }
246             e.printStackTrace();
247             fail(e.toString());
248         }
249
250         try {
251             reader.finishTest();
252         } catch (Throwable JavaDoc e) {
253             e.printStackTrace();
254             fail(e.toString());
255         }
256
257         closeEnv();
258     }
259
260     /**
261      * Open an environment and database.
262      */

263     private void openEnv(int floor,
264                          int maxMem)
265         throws DatabaseException {
266
267         /* Convert floor percentage into bytes. */
268         long evictBytes = maxMem - ((maxMem * floor) / 100);
269
270         /* Make a non-txnal env w/no daemons and small nodes. */
271         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
272         envConfig.setAllowCreate(true);
273         envConfig.setTxnNoSync(Boolean.getBoolean(TestUtils.NO_SYNC));
274         envConfig.setConfigParam(EnvironmentParams.
275                                  ENV_RUN_EVICTOR.getName(), "false");
276         envConfig.setConfigParam(EnvironmentParams.
277                                  ENV_RUN_INCOMPRESSOR.getName(), "false");
278         envConfig.setConfigParam(EnvironmentParams.
279                                  ENV_RUN_CLEANER.getName(), "false");
280         envConfig.setConfigParam(EnvironmentParams.
281                                  ENV_RUN_CHECKPOINTER.getName(), "false");
282         envConfig.setConfigParam(EnvironmentParams.
283                                  EVICTOR_EVICT_BYTES.getName(),
284                                  (new Long JavaDoc(evictBytes)).toString());
285         envConfig.setConfigParam(EnvironmentParams.
286                                  MAX_MEMORY.getName(),
287                                  new Integer JavaDoc(maxMem).toString());
288         /* Don't track detail with a tiny cache size. */
289         envConfig.setConfigParam
290             (EnvironmentParams.CLEANER_TRACK_DETAIL.getName(), "false");
291         envConfig.setConfigParam(EnvironmentParams.LOG_MEM_SIZE.getName(),
292                  EnvironmentParams.LOG_MEM_SIZE_MIN_STRING);
293         envConfig.setConfigParam(EnvironmentParams.NUM_LOG_BUFFERS.getName(),
294                  "2");
295
296         /*
297          * Disable critical eviction, we want to test under controlled
298          * circumstances.
299          */

300         envConfig.setConfigParam(EnvironmentParams.
301                                  EVICTOR_CRITICAL_PERCENTAGE.getName(),
302                                  "1000");
303
304         /* Make small nodes */
305         envConfig.setConfigParam(EnvironmentParams.
306                                  NODE_MAX.getName(), "4");
307         envConfig.setConfigParam(EnvironmentParams.
308                                  NODE_MAX_DUPTREE.getName(), "4");
309         env = new Environment(envHome, envConfig);
310
311         /* Open a database. */
312         DatabaseConfig dbConfig = new DatabaseConfig();
313         dbConfig.setAllowCreate(true);
314         dbConfig.setSortedDuplicates(true);
315         db = env.openDatabase(null, "foo", dbConfig);
316     }
317
318     private void closeEnv()
319         throws DatabaseException {
320
321         db.close();
322         db = null;
323         env.close();
324         env = null;
325     }
326
327     private void insertData(int nKeys)
328         throws DatabaseException {
329
330         DatabaseEntry key = new DatabaseEntry();
331         DatabaseEntry data = new DatabaseEntry();
332         for (int i = 0; i < nKeys; i++) {
333
334             IntegerBinding.intToEntry(i, key);
335
336             if ((i % 5) == 0) {
337                 for (int j = 10; j < (NUM_DUPS + 10); j++) {
338                     IntegerBinding.intToEntry(j, data);
339                     db.put(null, key, data);
340                 }
341             } else {
342                 IntegerBinding.intToEntry(i+1, data);
343                 db.put(null, key, data);
344             }
345         }
346     }
347
348     private void verifyData(int nKeys)
349         throws DatabaseException {
350
351         /* Full scan of data, make sure we can bring everything back in. */
352         Cursor cursor = db.openCursor(null, null);
353         DatabaseEntry data = new DatabaseEntry();
354         DatabaseEntry key = new DatabaseEntry();
355         
356         for (int i = 0; i < nKeys; i++) {
357             if ((i % 5) ==0) {
358                 for (int j = 10; j < (NUM_DUPS + 10); j++) {
359                     assertEquals(OperationStatus.SUCCESS,
360                                  cursor.getNext(key, data, LockMode.DEFAULT));
361                     assertEquals(i, IntegerBinding.entryToInt(key));
362                     assertEquals(j, IntegerBinding.entryToInt(data));
363                 }
364             } else {
365                 assertEquals(OperationStatus.SUCCESS,
366                              cursor.getNext(key, data, LockMode.DEFAULT));
367                 assertEquals(i, IntegerBinding.entryToInt(key));
368                 assertEquals(i+1, IntegerBinding.entryToInt(data));
369             }
370         }
371
372         assertEquals(OperationStatus.NOTFOUND,
373                      cursor.getNext(key, data, LockMode.DEFAULT));
374         cursor.close();
375     }
376
377     private void evictAndCheck(boolean shouldEvict, int nKeys)
378         throws DatabaseException {
379
380         EnvironmentImpl envImpl = DbInternal.envGetEnvironmentImpl(env);
381         MemoryBudget mb = envImpl.getMemoryBudget();
382
383         /*
384          * The following batches are run in a single evictMemory() call:
385          * 1st eviction will strip DBINs.
386          * 2nd will evict DBINs
387          * 3rd will evict DINs
388          * 4th will strip BINs
389          * 5th will evict BINs
390          * 6th will evict INs
391          * 7th will evict INs
392          */

393         long preEvictMem = mb.getCacheMemoryUsage();
394         TestUtils.validateNodeMemUsage(envImpl, true);
395         env.evictMemory();
396         long postEvictMem = mb.getCacheMemoryUsage();
397
398         TestUtils.validateNodeMemUsage(envImpl, true);
399         if (DEBUG) {
400             System.out.println("preEvict=" + preEvictMem +
401                                " postEvict=" + postEvictMem);
402         }
403
404         if (shouldEvict) {
405             assertTrue("preEvict=" + preEvictMem +
406                        " postEvict=" + postEvictMem +
407                        " maxMem=" + mb.getMaxMemory(),
408                        (preEvictMem > postEvictMem));
409         } else {
410             assertTrue("preEvict=" + preEvictMem +
411                        " postEvict=" + postEvictMem,
412                        (preEvictMem == postEvictMem));
413         }
414
415         verifyData(nKeys);
416         TestUtils.validateNodeMemUsage(envImpl, true);
417     }
418 }
419
Popular Tags