KickJava   Java API By Example, From Geeks To Geeks.

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


1 /*-
2  * See the file LICENSE for redistribution information.
3  *
4  * Copyright (c) 2005,2006 Oracle. All rights reserved.
5  *
6  * $Id: SecondarySplitTestMain.java,v 1.5 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 import java.util.Random JavaDoc;
14
15 import com.sleepycat.bind.tuple.LongBinding;
16 import com.sleepycat.je.Cursor;
17 import com.sleepycat.je.Database;
18 import com.sleepycat.je.DatabaseConfig;
19 import com.sleepycat.je.DatabaseEntry;
20 import com.sleepycat.je.DatabaseException;
21 import com.sleepycat.je.Environment;
22 import com.sleepycat.je.EnvironmentConfig;
23 import com.sleepycat.je.LockMode;
24 import com.sleepycat.je.OperationStatus;
25 import com.sleepycat.je.SecondaryConfig;
26 import com.sleepycat.je.SecondaryDatabase;
27 import com.sleepycat.je.SecondaryKeyCreator;
28 import com.sleepycat.je.util.TestUtils;
29
30 /**
31  * Tests that splits during secondary inserts don't cause a LatchException
32  * (latch already held). This was caused by a latch that wasn't released
33  * during a duplicate insert, when a split occurred during the insert. See
34  * [#12841] in Tree.java.
35  *
36  * The record keys are random long values and the record data is the long
37  * time (millis) of the record creation. The secondary database is indexed on
38  * the full data value (the timestamp). When a record is updated, its timstamp
39  * is changed to the current time, cause secondary deletes and inserts. This
40  * scenario is what happened to bring out the bug in SR [#12841].
41  */

42 public class SecondarySplitTestMain {
43
44     private static final int WRITER_THREADS = 2;
45     private static final int INSERTS_PER_ITER = 2;
46     private static final int UPDATES_PER_ITER = 1;
47     private static final int ITERS_PER_THREAD = 20000;
48     private static final int ITERS_PER_TRACE = 1000;
49
50     private File JavaDoc envHome;
51     private Environment env;
52     private Database priDb;
53     private SecondaryDatabase secDb;
54     private Random JavaDoc rnd = new Random JavaDoc(123);
55
56     public static void main(String JavaDoc[] args) {
57         try {
58             SecondarySplitTestMain test = new SecondarySplitTestMain();
59             test.doTest();
60             System.exit(0);
61         } catch (Throwable JavaDoc e) {
62             e.printStackTrace(System.out);
63             System.exit(1);
64         }
65     }
66
67     public SecondarySplitTestMain() throws IOException JavaDoc {
68         envHome = new File JavaDoc(System.getProperty(TestUtils.DEST_DIR));
69     }
70
71     private void doTest()
72         throws Exception JavaDoc {
73
74         TestUtils.removeLogFiles("Setup", envHome, false);
75         open();
76         Thread JavaDoc[] writers = new Thread JavaDoc[WRITER_THREADS];
77         for (int i = 0; i < writers.length; i += 1) {
78             writers[i] = new Writer(i);
79         }
80         for (int i = 0; i < writers.length; i += 1) {
81             writers[i].start();
82         }
83         for (int i = 0; i < writers.length; i += 1) {
84             writers[i].join();
85         }
86         close();
87         TestUtils.removeLogFiles("TearDown", envHome, false);
88         System.out.println("SUCCESS");
89     }
90
91     private void open()
92         throws DatabaseException {
93
94         EnvironmentConfig envConfig = TestUtils.initEnvConfig();
95         envConfig.setAllowCreate(true);
96
97         env = new Environment(envHome, envConfig);
98
99         DatabaseConfig priConfig = new DatabaseConfig();
100         priConfig.setAllowCreate(true);
101
102         priDb = env.openDatabase(null, "pri", priConfig);
103
104         SecondaryConfig secConfig = new SecondaryConfig();
105         secConfig.setAllowCreate(true);
106         secConfig.setSortedDuplicates(true);
107         secConfig.setKeyCreator(new KeyCreator());
108
109         secDb = env.openSecondaryDatabase(null, "sec", priDb, secConfig);
110     }
111
112     private void close()
113         throws DatabaseException {
114
115         secDb.close();
116         secDb = null;
117
118         priDb.close();
119         priDb = null;
120
121         env.close();
122         env = null;
123     }
124
125     static class KeyCreator implements SecondaryKeyCreator {
126
127         public boolean createSecondaryKey(SecondaryDatabase db,
128                                           DatabaseEntry key,
129                                           DatabaseEntry data,
130                                           DatabaseEntry result)
131             throws DatabaseException {
132
133             result.setData(data.getData(), data.getOffset(), data.getSize());
134             return true;
135         }
136     }
137
138     private class Writer extends Thread JavaDoc {
139
140         Writer(int id) {
141             super("[Writer " + id + ']');
142         }
143
144         public void run() {
145
146             int inserts = 0;
147             int updates = 0;
148             DatabaseEntry key = new DatabaseEntry();
149             DatabaseEntry data = new DatabaseEntry();
150             OperationStatus status;
151
152             for (int iter = 1; iter <= ITERS_PER_THREAD; iter += 1) {
153
154                 Cursor cursor = null;
155
156                 try {
157
158                     /* Inserts */
159                     for (int i = 0; i < INSERTS_PER_ITER; i += 1) {
160                         LongBinding.longToEntry(rnd.nextLong(), key);
161                         long time = System.currentTimeMillis();
162                         LongBinding.longToEntry(time, data);
163                         status = priDb.putNoOverwrite(null, key, data);
164                         if (status == OperationStatus.SUCCESS) {
165                             inserts += 1;
166                         } else {
167                             System.out.println
168                                 (getName() + " *** INSERT " + status);
169                         }
170                     }
171
172                     /* Updates */
173                     for (int i = 0; i < UPDATES_PER_ITER; i += 1) {
174
175                         cursor = priDb.openCursor(null, null);
176
177                         LongBinding.longToEntry(rnd.nextLong(), key);
178                         status = cursor.getSearchKeyRange(key, data,
179                                                           LockMode.RMW);
180                         if (status == OperationStatus.NOTFOUND) {
181                             status = cursor.getFirst(key, data, LockMode.RMW);
182                         }
183
184                         if (status == OperationStatus.SUCCESS) {
185                             long time = System.currentTimeMillis();
186                             LongBinding.longToEntry(time, data);
187                             cursor.putCurrent(data);
188                             updates += 1;
189                         } else {
190                             System.out.println
191                                 (getName() + " *** UPDATE " + status);
192                         }
193
194                         cursor.close();
195                         cursor = null;
196                     }
197
198                 } catch (Throwable JavaDoc e) {
199
200                     e.printStackTrace(System.out);
201
202                     if (cursor != null) {
203                         try {
204                             cursor.close();
205                         } catch (Exception JavaDoc e2) {
206                             e2.printStackTrace(System.out);
207                         }
208                     }
209                 }
210
211                 if (iter % ITERS_PER_TRACE == 0) {
212                     System.out.println
213                         (getName() +
214                          " inserts=" + inserts +
215                          " updates=" + updates);
216                 }
217             }
218         }
219     }
220 }
221
Popular Tags