KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > collections > KeyRangeTest


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

8
9 package com.sleepycat.collections;
10
11 import java.io.File JavaDoc;
12 import java.util.Arrays JavaDoc;
13 import java.util.Comparator JavaDoc;
14
15 import junit.framework.Test;
16 import junit.framework.TestCase;
17 import junit.framework.TestSuite;
18
19 import com.sleepycat.bind.ByteArrayBinding;
20 import com.sleepycat.collections.test.DbTestUtil;
21 import com.sleepycat.compat.DbCompat;
22 import com.sleepycat.je.Database;
23 import com.sleepycat.je.DatabaseConfig;
24 import com.sleepycat.je.DatabaseEntry;
25 import com.sleepycat.je.DatabaseException;
26 import com.sleepycat.je.Environment;
27 import com.sleepycat.je.EnvironmentConfig;
28 import com.sleepycat.je.OperationStatus;
29 import com.sleepycat.util.keyrange.KeyRange;
30 import com.sleepycat.util.keyrange.KeyRangeException;
31
32 /**
33  * @author Mark Hayes
34  */

35 public class KeyRangeTest extends TestCase {
36
37     private static boolean VERBOSE = false;
38
39     private static final byte FF = (byte) 0xFF;
40
41     private static final byte[][] KEYS = {
42         /* 0 */ {1},
43         /* 1 */ {FF},
44         /* 2 */ {FF, 0},
45         /* 3 */ {FF, 0x7F},
46         /* 4 */ {FF, FF},
47         /* 5 */ {FF, FF, 0},
48         /* 6 */ {FF, FF, 0x7F},
49         /* 7 */ {FF, FF, FF},
50     };
51     private static byte[][] EXTREME_KEY_BYTES = {
52         /* 0 */ {0},
53         /* 1 */ {FF, FF, FF, FF},
54     };
55
56     private Environment env;
57     private Database store;
58     private DataView view;
59     private DataCursor cursor;
60
61     public static void main(String JavaDoc[] args)
62         throws Exception JavaDoc {
63
64         junit.framework.TestResult tr =
65             junit.textui.TestRunner.run(suite());
66         if (tr.errorCount() > 0 ||
67             tr.failureCount() > 0) {
68             System.exit(1);
69         } else {
70             System.exit(0);
71         }
72     }
73
74     public static Test suite() {
75
76         return new TestSuite(KeyRangeTest.class);
77     }
78
79     public KeyRangeTest(String JavaDoc name) {
80
81         super(name);
82     }
83
84     public void setUp()
85         throws Exception JavaDoc {
86
87         DbTestUtil.printTestName(DbTestUtil.qualifiedTestName(this));
88     }
89
90     private void openDb(Comparator JavaDoc comparator)
91         throws Exception JavaDoc {
92
93         File JavaDoc dir = DbTestUtil.getNewDir();
94         ByteArrayBinding dataBinding = new ByteArrayBinding();
95         EnvironmentConfig envConfig = new EnvironmentConfig();
96         envConfig.setAllowCreate(true);
97         DbCompat.setInitializeCache(envConfig, true);
98         env = new Environment(dir, envConfig);
99         DatabaseConfig dbConfig = new DatabaseConfig();
100         DbCompat.setTypeBtree(dbConfig);
101         dbConfig.setAllowCreate(true);
102     if (comparator != null) {
103         DbCompat.setBtreeComparator(dbConfig, comparator);
104     }
105         store = DbCompat.openDatabase(env, null, "test.db", null, dbConfig);
106         view = new DataView(store, dataBinding, dataBinding, null, true, null);
107     }
108
109     private void closeDb()
110         throws Exception JavaDoc {
111         
112         store.close();
113         store = null;
114         env.close();
115         env = null;
116     }
117
118     public void tearDown()
119         throws Exception JavaDoc {
120
121         try {
122             if (store != null) {
123                 store.close();
124             }
125         } catch (Exception JavaDoc e) {
126             System.out.println("Exception ignored during close: " + e);
127         }
128         try {
129             if (env != null) {
130                 env.close();
131             }
132         } catch (Exception JavaDoc e) {
133             System.out.println("Exception ignored during close: " + e);
134         }
135         /* Ensure that GC can cleanup. */
136         env = null;
137         store = null;
138         view = null;
139         cursor = null;
140     }
141
142     public void testScan() throws Exception JavaDoc {
143         openDb(null);
144         doScan(false);
145         closeDb();
146     }
147
148     public void testScanComparator() throws Exception JavaDoc {
149         openDb(new ReverseComparator());
150         doScan(true);
151         closeDb();
152     }
153
154     private void doScan(boolean reversed) throws Exception JavaDoc {
155
156         byte[][] keys = new byte[KEYS.length][];
157         final int end = KEYS.length - 1;
158         cursor = new DataCursor(view, true);
159         for (int i = 0; i <= end; i++) {
160             keys[i] = KEYS[i];
161             cursor.put(keys[i], KEYS[i], null, false);
162         }
163         cursor.close();
164         byte[][] extremeKeys = new byte[EXTREME_KEY_BYTES.length][];
165         for (int i = 0; i < extremeKeys.length; i++) {
166             extremeKeys[i] = EXTREME_KEY_BYTES[i];
167         }
168
169         // with empty range
170

171         cursor = new DataCursor(view, false);
172         expectRange(KEYS, 0, end, reversed);
173         cursor.close();
174
175         // begin key only, inclusive
176

177         for (int i = 0; i <= end; i++) {
178             cursor = newCursor(view, keys[i], true, null, false, reversed);
179             expectRange(KEYS, i, end, reversed);
180             cursor.close();
181         }
182
183         // begin key only, exclusive
184

185         for (int i = 0; i <= end; i++) {
186             cursor = newCursor(view, keys[i], false, null, false, reversed);
187             expectRange(KEYS, i + 1, end, reversed);
188             cursor.close();
189         }
190
191         // end key only, inclusive
192

193         for (int i = 0; i <= end; i++) {
194             cursor = newCursor(view, null, false, keys[i], true, reversed);
195             expectRange(KEYS, 0, i, reversed);
196             cursor.close();
197         }
198
199         // end key only, exclusive
200

201         for (int i = 0; i <= end; i++) {
202             cursor = newCursor(view, null, false, keys[i], false, reversed);
203             expectRange(KEYS, 0, i - 1, reversed);
204             cursor.close();
205         }
206
207         // begin and end keys, inclusive and exclusive
208

209         for (int i = 0; i <= end; i++) {
210             for (int j = i; j <= end; j++) {
211                 // begin inclusive, end inclusive
212

213                 cursor = newCursor(view, keys[i], true, keys[j],
214                                         true, reversed);
215                 expectRange(KEYS, i, j, reversed);
216                 cursor.close();
217
218                 // begin inclusive, end exclusive
219

220                 cursor = newCursor(view, keys[i], true, keys[j],
221                                         false, reversed);
222                 expectRange(KEYS, i, j - 1, reversed);
223                 cursor.close();
224
225                 // begin exclusive, end inclusive
226

227                 cursor = newCursor(view, keys[i], false, keys[j],
228                                         true, reversed);
229                 expectRange(KEYS, i + 1, j, reversed);
230                 cursor.close();
231
232                 // begin exclusive, end exclusive
233

234                 cursor = newCursor(view, keys[i], false, keys[j],
235                                         false, reversed);
236                 expectRange(KEYS, i + 1, j - 1, reversed);
237                 cursor.close();
238             }
239         }
240
241         // single key range
242

243         for (int i = 0; i <= end; i++) {
244             cursor = new DataCursor(view, false, keys[i]);
245             expectRange(KEYS, i, i, reversed);
246             cursor.close();
247         }
248
249         // start with lower extreme (before any existing key)
250

251         cursor = newCursor(view, extremeKeys[0], true, null, false, reversed);
252         expectRange(KEYS, 0, end, reversed);
253         cursor.close();
254
255         // start with higher extreme (after any existing key)
256

257         cursor = newCursor(view, null, false, extremeKeys[1], true, reversed);
258         expectRange(KEYS, 0, end, reversed);
259         cursor.close();
260     }
261
262     private DataCursor newCursor(DataView view,
263                                  Object JavaDoc beginKey, boolean beginInclusive,
264                                  Object JavaDoc endKey, boolean endInclusive,
265                                  boolean reversed)
266         throws Exception JavaDoc {
267
268         if (reversed) {
269             return new DataCursor(view, false,
270                                   endKey, endInclusive,
271                                   beginKey, beginInclusive);
272         } else {
273             return new DataCursor(view, false,
274                                   beginKey, beginInclusive,
275                                   endKey, endInclusive);
276         }
277     }
278
279     private void expectRange(byte[][] bytes, int first, int last,
280                              boolean reversed)
281         throws DatabaseException {
282
283         int i;
284         boolean init;
285         for (init = true, i = first;; i++, init = false) {
286             if (checkRange(bytes, first, last, i <= last,
287                            reversed, !reversed, init, i)) {
288                 break;
289             }
290         }
291         for (init = true, i = last;; i--, init = false) {
292             if (checkRange(bytes, first, last, i >= first,
293                            reversed, reversed, init, i)) {
294                 break;
295             }
296         }
297     }
298
299     private boolean checkRange(byte[][] bytes, int first, int last,
300                                boolean inRange, boolean reversed,
301                                boolean forward, boolean init,
302                                int i)
303         throws DatabaseException {
304
305         OperationStatus s;
306         if (forward) {
307             if (init) {
308                 s = cursor.getFirst(false);
309             } else {
310                 s = cursor.getNext(false);
311             }
312         } else {
313             if (init) {
314                 s = cursor.getLast(false);
315             } else {
316                 s = cursor.getPrev(false);
317             }
318         }
319
320         String JavaDoc msg = " " + (forward ? "next" : "prev") + " i=" + i +
321                      " first=" + first + " last=" + last +
322                      (reversed ? " reversed" : " not reversed");
323
324         // check that moving past ends doesn't move the cursor
325
if (s == OperationStatus.SUCCESS && i == first) {
326             OperationStatus s2 = reversed ? cursor.getNext(false)
327                                           : cursor.getPrev(false);
328             assertEquals(msg, OperationStatus.NOTFOUND, s2);
329         }
330         if (s == OperationStatus.SUCCESS && i == last) {
331             OperationStatus s2 = reversed ? cursor.getPrev(false)
332                                           : cursor.getNext(false);
333             assertEquals(msg, OperationStatus.NOTFOUND, s2);
334         }
335
336         byte[] val = (s == OperationStatus.SUCCESS)
337                         ? ((byte[]) cursor.getCurrentValue())
338                         : null;
339
340         if (inRange) {
341             assertNotNull("RangeNotFound" + msg, val);
342
343             if (!Arrays.equals(val, bytes[i])){
344                 printBytes(val);
345                 printBytes(bytes[i]);
346                 fail("RangeKeyNotEqual" + msg);
347             }
348             if (VERBOSE) {
349                 System.out.println("GotRange" + msg);
350             }
351             return false;
352         } else {
353             assertEquals("RangeExceeded" + msg, OperationStatus.NOTFOUND, s);
354             return true;
355         }
356     }
357
358     private void printBytes(byte[] bytes) {
359
360         for (int i = 0; i < bytes.length; i += 1) {
361             System.out.print(Integer.toHexString(bytes[i] & 0xFF));
362             System.out.print(' ');
363         }
364         System.out.println();
365     }
366
367     public void testSubRanges() {
368
369         DatabaseEntry begin = new DatabaseEntry();
370         DatabaseEntry begin2 = new DatabaseEntry();
371         DatabaseEntry end = new DatabaseEntry();
372         DatabaseEntry end2 = new DatabaseEntry();
373         KeyRange range = new KeyRange(null);
374         KeyRange range2;
375
376         /* Base range [1, 2] */
377         begin.setData(new byte[] { 1 });
378         end.setData(new byte[] { 2 });
379         range = range.subRange(begin, true, end, true);
380
381         /* Subrange (0, 1] is invalid **. */
382         begin2.setData(new byte[] { 0 });
383         end2.setData(new byte[] { 1 });
384         try {
385             range2 = range.subRange(begin2, false, end2, true);
386             fail();
387         } catch (KeyRangeException expected) {}
388
389         /* Subrange [1, 3) is invalid. */
390         begin2.setData(new byte[] { 1 });
391         end2.setData(new byte[] { 3 });
392         try {
393             range2 = range.subRange(begin2, true, end2, false);
394             fail();
395         } catch (KeyRangeException expected) {}
396
397         /* Subrange [2, 2] is valid. */
398         begin2.setData(new byte[] { 2 });
399         end2.setData(new byte[] { 2 });
400         range2 = range.subRange(begin2, true, end2, true);
401
402         /* Subrange [0, 1] is invalid. */
403         begin2.setData(new byte[] { 0 });
404         end2.setData(new byte[] { 1 });
405         try {
406             range2 = range.subRange(begin2, true, end2, true);
407             fail();
408         } catch (KeyRangeException expected) {}
409
410         /* Subrange (0, 3] is invalid. */
411         begin2.setData(new byte[] { 0 });
412         end2.setData(new byte[] { 3 });
413         try {
414             range2 = range.subRange(begin2, false, end2, true);
415             fail();
416         } catch (KeyRangeException expected) {}
417
418         /* Subrange [3, 3) is invalid. */
419         begin2.setData(new byte[] { 3 });
420         end2.setData(new byte[] { 3 });
421         try {
422             range2 = range.subRange(begin2, true, end2, false);
423             fail();
424         } catch (KeyRangeException expected) {}
425     }
426
427     public static class ReverseComparator implements Comparator JavaDoc {
428         public int compare(Object JavaDoc o1, Object JavaDoc o2) {
429             byte[] d1 = (byte[]) o1;
430             byte[] d2 = (byte[]) o2;
431             int cmp = KeyRange.compareBytes(d1, 0, d1.length,
432                                             d2, 0, d2.length);
433             if (cmp < 0) {
434                 return 1;
435             } else if (cmp > 0) {
436                 return -1;
437             } else {
438                 return 0;
439             }
440         }
441     }
442 }
443
Popular Tags