KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > test > SR11297Test


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

8
9 package com.sleepycat.je.test;
10
11 import java.io.File JavaDoc;
12 import java.io.IOException JavaDoc;
13
14 import junit.framework.TestCase;
15
16 import com.sleepycat.je.CheckpointConfig;
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.EnvironmentConfig;
24 import com.sleepycat.je.Environment;
25 import com.sleepycat.je.OperationStatus;
26 import com.sleepycat.je.config.EnvironmentParams;
27 import com.sleepycat.je.log.FileManager;
28 import com.sleepycat.je.util.TestUtils;
29
30 /**
31  * Fix for SR11297. When the first BIN in database was empty,
32  * CursorImpl.positionFirstOrLast(true, null) was returning false, causing
33  * Cursor.getFirst to return NOTFOUND. This test reproduces that problem by
34  * creating a database with the first BIN empty and the second BIN non-empty.
35  *
36  * <p>A specific sequence where partial compression takes place is necessary to
37  * reproduce the problem. A duplicate is added as the first entry in the first
38  * BIN, then that BIN is filled and one entry is added to the next BIN. Then
39  * all records in the first BIN are deleted. compress() is called once, which
40  * deletes the duplicate tree and all entries in the first BIN, but the first
41  * BIN will not be deleted until the next compression. At that point in time,
42  * getFirst failed to find the record in the second BIN.</p>
43  */

44 public class SR11297Test extends TestCase {
45
46     /* Minimum child entries per BIN. */
47     private static int N_ENTRIES = 4;
48
49     private static CheckpointConfig forceCheckpoint = new CheckpointConfig();
50     static {
51         forceCheckpoint.setForce(true);
52     }
53
54     private File JavaDoc envHome;
55     private Environment env;
56
57     public SR11297Test() {
58         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
59     }
60
61     public void setUp()
62         throws IOException JavaDoc {
63
64         TestUtils.removeLogFiles("Setup", envHome, false);
65         TestUtils.removeFiles("Setup", envHome, FileManager.DEL_SUFFIX);
66     }
67     
68     public void tearDown()
69         throws Exception JavaDoc {
70
71         try {
72             if (env != null) {
73                 env.close();
74             }
75         } catch (Throwable JavaDoc e) {
76             System.out.println("tearDown: " + e);
77         }
78                 
79         try {
80             //*
81
TestUtils.removeLogFiles("tearDown", envHome, true);
82             TestUtils.removeFiles("tearDown", envHome, FileManager.DEL_SUFFIX);
83             //*/
84
} catch (Throwable JavaDoc e) {
85             System.out.println("tearDown: " + e);
86         }
87
88         envHome = null;
89         env = null;
90     }
91
92     private void openEnv()
93         throws DatabaseException, IOException JavaDoc {
94
95         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
96     DbInternal.disableParameterValidation(envConfig);
97         envConfig.setAllowCreate(true);
98         /* Make as small a log as possible to save space in CVS. */
99         envConfig.setConfigParam
100             (EnvironmentParams.ENV_RUN_INCOMPRESSOR.getName(), "false");
101         envConfig.setConfigParam
102             (EnvironmentParams.ENV_RUN_CLEANER.getName(), "false");
103         envConfig.setConfigParam
104             (EnvironmentParams.ENV_RUN_EVICTOR.getName(), "false");
105         envConfig.setConfigParam
106             (EnvironmentParams.ENV_RUN_CHECKPOINTER.getName(), "false");
107         /* Use a 100 MB log file size to ensure only one file is written. */
108         envConfig.setConfigParam(EnvironmentParams.LOG_FILE_MAX.getName(),
109                                  Integer.toString(100 * (1 << 20)));
110         /* Force BINDelta. */
111         envConfig.setConfigParam
112             (EnvironmentParams.BIN_DELTA_PERCENT.getName(),
113              Integer.toString(75));
114         /* Force INDelete. */
115         envConfig.setConfigParam
116             (EnvironmentParams.NODE_MAX.getName(),
117              Integer.toString(N_ENTRIES));
118         env = new Environment(envHome, envConfig);
119     }
120
121     private void closeEnv()
122         throws DatabaseException {
123
124         env.close();
125         env = null;
126     }
127
128     public void test11297()
129         throws DatabaseException, IOException JavaDoc {
130
131         openEnv();
132
133         /* Write db0 and db1. */
134         for (int i = 0; i < 2; i += 1) {
135             DatabaseConfig dbConfig = new DatabaseConfig();
136             dbConfig.setAllowCreate(true);
137             dbConfig.setSortedDuplicates(true);
138             Database db = env.openDatabase(null, "db" + i, dbConfig);
139
140             /* Write: {0, 0}, {0, 1}, {1, 0}, {2, 0}, {3, 0} */
141             for (int j = 0; j < N_ENTRIES; j += 1) {
142                 db.put(null, entry(j), entry(0));
143             }
144             db.put(null, entry(0), entry(1));
145
146             /* Delete everything but the last record. */
147             for (int j = 0; j < N_ENTRIES - 1; j += 1) {
148                 db.delete(null, entry(j));
149             }
150
151             db.close();
152         }
153
154         checkFirstRecord();
155         env.compress();
156         checkFirstRecord();
157
158         closeEnv();
159     }
160
161     /**
162      * First and only record in db1 should be {3,0}.
163      */

164     private void checkFirstRecord()
165         throws DatabaseException {
166
167         DatabaseConfig dbConfig = new DatabaseConfig();
168         dbConfig.setAllowCreate(false);
169         dbConfig.setReadOnly(true);
170         dbConfig.setSortedDuplicates(true);
171         Database db = env.openDatabase(null, "db1", dbConfig);
172         Cursor cursor = db.openCursor(null, null);
173         DatabaseEntry key = new DatabaseEntry();
174         DatabaseEntry data = new DatabaseEntry();
175         OperationStatus status = cursor.getFirst(key, data, null);
176         assertEquals(OperationStatus.SUCCESS, status);
177         assertEquals(3, value(key));
178         assertEquals(0, value(data));
179         cursor.close();
180         db.close();
181     }
182
183     static DatabaseEntry entry(int val) {
184
185         byte[] data = new byte[] { (byte) val };
186         return new DatabaseEntry(data);
187     }
188
189     static int value(DatabaseEntry entry) {
190
191         byte[] data = entry.getData();
192         if (data.length != 1) {
193             throw new IllegalStateException JavaDoc("len=" + data.length);
194         }
195         return data[0];
196     }
197 }
198
Popular Tags