KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > recovery > RecoveryDeltaTest


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

8 package com.sleepycat.je.recovery;
9
10 import java.util.Hashtable JavaDoc;
11 import java.util.List JavaDoc;
12
13 import com.sleepycat.je.Cursor;
14 import com.sleepycat.je.DatabaseEntry;
15 import com.sleepycat.je.DatabaseException;
16 import com.sleepycat.je.LockMode;
17 import com.sleepycat.je.OperationStatus;
18 import com.sleepycat.je.Transaction;
19 import com.sleepycat.je.config.EnvironmentParams;
20
21 /**
22  * Exercise delta BIN logging.
23  */

24 public class RecoveryDeltaTest extends RecoveryTestBase {
25
26     /**
27      * The recovery delta tests set extra properties.
28      */

29     public void setExtraProperties()
30     throws DatabaseException {
31
32         /* Always run with delta logging cranked up. */
33         envConfig.setConfigParam
34             (EnvironmentParams.BIN_DELTA_PERCENT.getName(), "75");
35
36         /*
37          * Make sure that the environments in this unit test always
38          * run with checkpointing off, so we can call it explcitly.
39          */

40         envConfig.setConfigParam
41             (EnvironmentParams.ENV_RUN_CHECKPOINTER.getName(), "false");
42         /*
43          * Make sure that the environments in this unit test always
44          * run with the compressor off, so we get known results
45          */

46         envConfig.setConfigParam
47             (EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), "false");
48     }
49
50     /**
51      * Test the interaction of compression and deltas. After a compress,
52      * the next entry must be a full one.
53      */

54     public void testCompress()
55         throws Throwable JavaDoc {
56
57         createEnvAndDbs(1 << 20, true, NUM_DBS);
58         int numRecs = 20;
59         try {
60             // Set up an repository of expected data
61
Hashtable JavaDoc expectedData = new Hashtable JavaDoc();
62
63             // insert all the data
64
Transaction txn = env.beginTransaction(null, null);
65             insertData(txn, 0, numRecs - 1, expectedData, 1, true, NUM_DBS);
66             txn.commit();
67
68             // delete every other record
69
txn = env.beginTransaction(null, null);
70             deleteData(txn, expectedData, false, true, NUM_DBS);
71             txn.commit();
72
73
74             // Ask the compressor to run.
75
env.compress();
76             
77             // force a checkpoint, should avoid deltas..
78
env.checkpoint(forceConfig);
79             
80             closeEnv();
81
82             recoverAndVerify(expectedData, NUM_DBS);
83             
84         } catch (Throwable JavaDoc t) {
85             // print stacktrace before trying to clean up files
86
t.printStackTrace();
87             throw t;
88         }
89     }
90
91     /**
92      * Test a recovery that processes deltas.
93      */

94     public void testRecoveryDelta()
95         throws Throwable JavaDoc {
96
97         createEnvAndDbs(1 << 20, true, NUM_DBS);
98         int numRecs = 20;
99         try {
100             /* Set up a repository of expected data */
101             Hashtable JavaDoc expectedData = new Hashtable JavaDoc();
102
103             /*
104              * Force a checkpoint, to flush a full version of the BIN
105              * to disk, so the next checkpoint can cause deltas
106              */

107             env.checkpoint(forceConfig);
108
109             /* insert data */
110             Transaction txn = env.beginTransaction(null, null);
111             insertData(txn, 0, numRecs - 1, expectedData, 1, true, NUM_DBS);
112             txn.commit();
113
114             /* This checkpoint should write deltas. Although there's
115              * just been one spate of insertions, those insertions caused
116              * some BIN splitting, so many BINS have a logged version
117              * on disk. This is what causes the deltas.
118              */

119             env.checkpoint(forceConfig);
120             
121             closeEnv();
122             List JavaDoc infoList = recoverAndVerify(expectedData, NUM_DBS);
123
124             /* Check that this recovery processed deltas */
125             RecoveryInfo firstInfo = (RecoveryInfo) infoList.get(0);
126             assertTrue(firstInfo.numBinDeltas > 0);
127
128         } catch (Throwable JavaDoc t) {
129             // print stacktrace before trying to clean up files
130
t.printStackTrace();
131             throw t;
132         }
133     }
134    
135     /**
136      * This test checks that reconstituting the bin deals properly with
137      * the knownDeleted flag
138      * insert key1, abort, checkpoint, -- after abort, childref KD = true;
139      * insert key1, commit, -- after commit, childref KD = false
140      * delete key1, abort, -- BinDelta should have KD = false
141      * checkpoint to write deltas,
142      * recover. verify key1 is present. -- reconstituteBIN should make KD=false
143      */

144     public void testKnownDeleted()
145         throws Throwable JavaDoc {
146
147         createEnvAndDbs(1 << 20, true, NUM_DBS);
148         int numRecs = 20;
149         try {
150             
151             /* Set up a repository of expected data */
152             Hashtable JavaDoc expectedData = new Hashtable JavaDoc();
153
154             /* Insert data and abort. */
155             Transaction txn = env.beginTransaction(null, null);
156             insertData(txn, 0, numRecs - 1, expectedData, 1, false, NUM_DBS);
157
158             /*
159              * Add cursors to pin down BINs. Otherwise the checkpoint that
160              * follows will compress away all the values.
161              */

162             Cursor [][] cursors = new Cursor[NUM_DBS][numRecs];
163             addCursors(cursors);
164             txn.abort();
165
166             /*
167              * Force a checkpoint, to flush a full version of the BIN
168              * to disk, so the next checkpoint can cause deltas.
169              * These checkpointed BINS have known deleted flags set.
170              */

171             env.checkpoint(forceConfig);
172             removeCursors(cursors);
173             
174
175             /*
176              * Insert every other data value, makes some known deleted flags
177              * false.
178              */

179             txn = env.beginTransaction(null, null);
180             insertData(txn, 0, numRecs - 1, expectedData, 1,
181                        true, true, NUM_DBS);
182             txn.commit();
183
184             /* Delete data and abort, keeps known delete flag true */
185             txn = env.beginTransaction(null, null);
186             deleteData(txn, expectedData, true, false, NUM_DBS);
187             txn.abort();
188
189             /* This checkpoint should write deltas. */
190             cursors = new Cursor[NUM_DBS][numRecs/2];
191             addCursors(cursors);
192             env.checkpoint(forceConfig);
193             removeCursors(cursors);
194             
195             closeEnv();
196             List JavaDoc infoList = recoverAndVerify(expectedData, NUM_DBS);
197
198             /* Check that this recovery processed deltas */
199             RecoveryInfo firstInfo = (RecoveryInfo) infoList.get(0);
200             assertTrue(firstInfo.numBinDeltas > 0);
201
202         } catch (Throwable JavaDoc t) {
203             // print stacktrace before trying to clean up files
204
t.printStackTrace();
205             throw t;
206         }
207     }
208     
209     /* Add cursors on each value to prevent compression. */
210     private void addCursors(Cursor [][] cursors)
211         throws DatabaseException {
212
213         DatabaseEntry key = new DatabaseEntry();
214         DatabaseEntry data = new DatabaseEntry();
215
216         /* Pin each record with a cursor. */
217         for (int d = 0; d < NUM_DBS; d++) {
218             for (int i = 0; i < cursors[d].length; i++) {
219                 cursors[d][i] = dbs[d].openCursor(null, null);
220         
221                 for (int j = 0; j < i; j++) {
222                     OperationStatus status =
223                         cursors[d][i].getNext(key, data,
224                                               LockMode.READ_UNCOMMITTED);
225                     assertEquals(OperationStatus.SUCCESS, status);
226                 }
227             }
228         }
229     }
230
231     private void removeCursors(Cursor[][] cursors)
232         throws DatabaseException {
233         for (int d = 0; d < NUM_DBS; d++) {
234             for (int i = 0; i < cursors[d].length; i++) {
235                 cursors[d][i].close();
236             }
237         }
238     }
239 }
240
Popular Tags