KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > sleepycat > je > dbi > DbCursorTest


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

8
9 package com.sleepycat.je.dbi;
10
11 import java.util.Comparator JavaDoc;
12 import java.util.Hashtable JavaDoc;
13
14 import com.sleepycat.je.DbInternal;
15 import com.sleepycat.je.Cursor;
16 import com.sleepycat.je.DatabaseException;
17 import com.sleepycat.je.LockMode;
18 import com.sleepycat.je.OperationStatus;
19 import com.sleepycat.je.util.StringDbt;
20 import com.sleepycat.je.util.TestUtils;
21
22 /**
23  * Various unit tests for CursorImpl.
24  */

25 public class DbCursorTest extends DbCursorTestBase {
26
27     public DbCursorTest()
28         throws DatabaseException {
29
30         super();
31     }
32
33     /**
34      * Put a small number of data items into the database in a specific order
35      * and ensure that they read back in ascending order.
36      */

37     public void testSimpleGetPut()
38         throws Throwable JavaDoc {
39
40         try {
41             initEnv(false);
42             doSimpleCursorPuts();
43
44             DataWalker dw = new DataWalker(simpleDataMap) {
45                     void perData(String JavaDoc foundKey, String JavaDoc foundData) {
46                         assertTrue(foundKey.compareTo(prevKey) >= 0);
47                         prevKey = foundKey;
48                     }
49                 };
50             dw.walkData();
51             assertTrue(dw.nEntries == simpleKeyStrings.length);
52         } catch (Throwable JavaDoc t) {
53             t.printStackTrace();
54             throw t;
55         }
56     }
57
58     /**
59      * Test the internal Cursor.advanceCursor() entrypoint.
60      */

61     public void testCursorAdvance()
62         throws Throwable JavaDoc {
63
64         try {
65             initEnv(false);
66             doSimpleCursorPuts();
67
68         StringDbt foundKey = new StringDbt();
69         StringDbt foundData = new StringDbt();
70         String JavaDoc prevKey = "";
71
72         OperationStatus status = cursor.getFirst(foundKey, foundData,
73                              LockMode.DEFAULT);
74
75         /*
76          * Advance forward and then back to the first. Rest of scan
77          * should be as normal.
78          */

79         DbInternal.advanceCursor(cursor, foundKey, foundData);
80         DbInternal.retrieveNext
81         (cursor, foundKey, foundData, LockMode.DEFAULT, GetMode.PREV);
82         int nEntries = 0;
83         while (status == OperationStatus.SUCCESS) {
84                 String JavaDoc foundKeyString = foundKey.getString();
85                 String JavaDoc foundDataString = foundData.getString();
86
87         assertTrue(foundKeyString.compareTo(prevKey) >= 0);
88         prevKey = foundKeyString;
89                 nEntries++;
90
91         status = cursor.getNext(foundKey, foundData, LockMode.DEFAULT);
92         }
93
94             assertTrue(nEntries == simpleKeyStrings.length);
95         } catch (Throwable JavaDoc t) {
96             t.printStackTrace();
97             throw t;
98         }
99     }
100
101     /**
102      * Put a small number of data items into the database in a specific order
103      * and ensure that they read back in descending order.
104      */

105     public void testSimpleGetPutBackwards()
106         throws Throwable JavaDoc {
107
108         try {
109             initEnv(false);
110             doSimpleCursorPuts();
111
112             DataWalker dw = new BackwardsDataWalker(simpleDataMap) {
113                     void perData(String JavaDoc foundKey, String JavaDoc foundData) {
114                         if (!prevKey.equals("")) {
115                             assertTrue(foundKey.compareTo(prevKey) <= 0);
116                         }
117                         prevKey = foundKey;
118                     }
119
120                     OperationStatus getFirst(StringDbt foundKey,
121                          StringDbt foundData)
122                         throws DatabaseException {
123
124                         return cursor.getLast(foundKey, foundData,
125                                               LockMode.DEFAULT);
126                     }
127
128                     OperationStatus getData(StringDbt foundKey,
129                         StringDbt foundData)
130                         throws DatabaseException {
131
132                         return cursor.getPrev(foundKey, foundData,
133                                               LockMode.DEFAULT);
134                     }
135                 };
136             dw.walkData();
137             assertTrue(dw.nEntries == simpleKeyStrings.length);
138         } catch (Throwable JavaDoc t) {
139             t.printStackTrace();
140             throw t;
141         }
142     }
143
144     /**
145      * Put a small number of data items into the database in a specific order
146      * and ensure that they read back in descending order. When "quux" is
147      * found, insert "fub" into the database and make sure that it is also read
148      * back in the cursor.
149      */

150     public void testSimpleGetPut2()
151         throws Throwable JavaDoc {
152
153         try {
154             initEnv(false);
155             doSimpleGetPut2("quux", "fub");
156         } catch (Throwable JavaDoc t) {
157             t.printStackTrace();
158             throw t;
159         }
160     }
161
162     public void doSimpleGetPut2(String JavaDoc whenFoundDoInsert,
163                                 String JavaDoc newKey)
164         throws DatabaseException {
165
166         doSimpleCursorPuts();
167
168         DataWalker dw =
169             new BackwardsDataWalker(whenFoundDoInsert, newKey, simpleDataMap) {
170                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
171                     throws DatabaseException {
172
173                     if (foundKey.equals(whenFoundDoInsert)) {
174                         putAndVerifyCursor(cursor2, new StringDbt(newKey),
175                                            new StringDbt("ten"), true);
176                         simpleDataMap.put(newKey, "ten");
177                     }
178                 }
179
180                 OperationStatus getFirst(StringDbt foundKey,
181                      StringDbt foundData)
182                     throws DatabaseException {
183
184                     return cursor.getLast(foundKey, foundData,
185                                           LockMode.DEFAULT);
186                 }
187
188                 OperationStatus getData(StringDbt foundKey,
189                     StringDbt foundData)
190                     throws DatabaseException {
191
192                     return cursor.getPrev(foundKey, foundData,
193                                           LockMode.DEFAULT);
194                 }
195             };
196         dw.walkData();
197         assertTrue(dw.nEntries == simpleKeyStrings.length + 1);
198     }
199
200     /**
201      * Iterate through each of the keys in the list of "simple keys". For each
202      * one, create the database afresh, iterate through the entries in
203      * ascending order, and when the key being tested is found, insert the next
204      * highest key into the database. Make sure that the key just inserted is
205      * retrieved during the cursor walk. Lather, rinse, repeat.
206      */

207     public void testSimpleGetPutNextKeyForwardTraverse()
208         throws Throwable JavaDoc {
209
210         try {
211             tearDown();
212             for (int i = 0; i < simpleKeyStrings.length; i++) {
213                 setUp();
214                 initEnv(false);
215                 doSimpleGetPut(true,
216                                simpleKeyStrings[i],
217                                nextKey(simpleKeyStrings[i]),
218                                1);
219                 tearDown();
220             }
221         } catch (Throwable JavaDoc t) {
222             t.printStackTrace();
223             throw t;
224         }
225     }
226
227     /**
228      * Iterate through each of the keys in the list of "simple keys". For each
229      * one, create the database afresh, iterate through the entries in
230      * ascending order, and when the key being tested is found, insert the next
231      * lowest key into the database. Make sure that the key just inserted is
232      * not retrieved during the cursor walk. Lather, rinse, repeat.
233      */

234     public void testSimpleGetPutPrevKeyForwardTraverse()
235         throws Throwable JavaDoc {
236
237         try {
238             tearDown();
239             for (int i = 0; i < simpleKeyStrings.length; i++) {
240                 setUp();
241                 initEnv(false);
242                 doSimpleGetPut(true, simpleKeyStrings[i],
243                                prevKey(simpleKeyStrings[i]), 0);
244                 tearDown();
245             }
246         } catch (Throwable JavaDoc t) {
247             t.printStackTrace();
248             throw t;
249         }
250     }
251
252     /**
253      * Iterate through each of the keys in the list of "simple keys". For each
254      * one, create the database afresh, iterate through the entries in
255      * descending order, and when the key being tested is found, insert the
256      * next lowest key into the database. Make sure that the key just inserted
257      * is retrieved during the cursor walk. Lather, rinse, repeat.
258      */

259     public void testSimpleGetPutPrevKeyBackwardsTraverse()
260         throws Throwable JavaDoc {
261
262         try {
263             tearDown();
264             for (int i = 0; i < simpleKeyStrings.length; i++) {
265                 setUp();
266                 initEnv(false);
267                 doSimpleGetPut(false, simpleKeyStrings[i],
268                                prevKey(simpleKeyStrings[i]), 1);
269                 tearDown();
270             }
271         } catch (Throwable JavaDoc t) {
272             t.printStackTrace();
273         }
274     }
275
276     /**
277      * Iterate through each of the keys in the list of "simple keys". For each
278      * one, create the database afresh, iterate through the entries in
279      * descending order, and when the key being tested is found, insert the
280      * next highest key into the database. Make sure that the key just
281      * inserted is not retrieved during the cursor walk. Lather, rinse,
282      * repeat.
283      */

284     public void testSimpleGetPutNextKeyBackwardsTraverse()
285         throws Throwable JavaDoc {
286
287         try {
288             tearDown();
289             for (int i = 0; i < simpleKeyStrings.length; i++) {
290                 setUp();
291                 initEnv(false);
292                 doSimpleGetPut(true, simpleKeyStrings[i],
293                                prevKey(simpleKeyStrings[i]), 0);
294                 tearDown();
295             }
296         } catch (Throwable JavaDoc t) {
297             t.printStackTrace();
298             throw t;
299         }
300     }
301
302     /**
303      * Helper routine for the above four tests.
304      */

305     private void doSimpleGetPut(boolean forward,
306                                 String JavaDoc whenFoundDoInsert,
307                                 String JavaDoc newKey,
308                                 int additionalEntries)
309         throws DatabaseException {
310
311         doSimpleCursorPuts();
312
313         DataWalker dw;
314         if (forward) {
315             dw = new DataWalker(whenFoundDoInsert, newKey, simpleDataMap) {
316                     void perData(String JavaDoc foundKey, String JavaDoc foundData)
317                         throws DatabaseException {
318
319                         if (foundKey.equals(whenFoundDoInsert)) {
320                             putAndVerifyCursor(cursor2, new StringDbt(newKey),
321                                                new StringDbt("ten"), true);
322                             simpleDataMap.put(newKey, "ten");
323                         }
324                     }
325                 };
326         } else {
327             dw = new BackwardsDataWalker(whenFoundDoInsert,
328                      newKey,
329                                          simpleDataMap) {
330             void perData(String JavaDoc foundKey, String JavaDoc foundData)
331             throws DatabaseException {
332
333             if (foundKey.equals(whenFoundDoInsert)) {
334                 putAndVerifyCursor(cursor2, new StringDbt(newKey),
335                            new StringDbt("ten"), true);
336                 simpleDataMap.put(newKey, "ten");
337             }
338             }
339
340             OperationStatus getFirst(StringDbt foundKey,
341                          StringDbt foundData)
342             throws DatabaseException {
343
344             return cursor.getLast(foundKey, foundData,
345                           LockMode.DEFAULT);
346             }
347
348             OperationStatus getData(StringDbt foundKey,
349                         StringDbt foundData)
350             throws DatabaseException {
351
352             return cursor.getPrev(foundKey, foundData,
353                           LockMode.DEFAULT);
354             }
355                 };
356         }
357         dw.walkData();
358         assertEquals(simpleKeyStrings.length + additionalEntries, dw.nEntries);
359     }
360
361     /**
362      * Put a small number of data items into the database in a specific order
363      * and ensure that they read back in descending order. Replace the data
364      * portion for each one, then read back again and make sure it was replaced
365      * properly.
366      */

367     public void testSimpleReplace()
368         throws Throwable JavaDoc {
369
370         try {
371             initEnv(false);
372             doSimpleReplace();
373         } catch (Throwable JavaDoc t) {
374             t.printStackTrace();
375             throw t;
376         }
377     }
378
379     public void doSimpleReplace()
380         throws DatabaseException {
381
382         doSimpleCursorPuts();
383
384         DataWalker dw =
385             new DataWalker(simpleDataMap) {
386                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
387                     throws DatabaseException {
388
389                     String JavaDoc newData = foundData + "x";
390                     cursor.putCurrent(new StringDbt(newData));
391                     simpleDataMap.put(foundKey, newData);
392                 }
393             };
394         dw.walkData();
395         dw = new DataWalker(simpleDataMap) {
396                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
397                     throws DatabaseException {
398
399                     assertTrue(foundData.equals(simpleDataMap.get(foundKey)));
400                 }
401             };
402         dw.walkData();
403     }
404
405     /**
406      * Insert N_KEYS data items into a tree. Iterate through the tree in
407      * ascending order. After each element is retrieved, insert the next
408      * lowest key into the tree. Ensure that the element just inserted is not
409      * returned by the cursor. Ensure that the elements are returned in
410      * ascending order. Lather, rinse, repeat.
411      */

412     public void testLargeGetPutPrevKeyForwardTraverse()
413         throws Throwable JavaDoc {
414
415         try {
416             initEnv(false);
417             doLargeGetPutPrevKeyForwardTraverse();
418         } catch (Throwable JavaDoc t) {
419             t.printStackTrace();
420             throw t;
421         }
422     }
423
424     /**
425      * Helper routine for above.
426      */

427     private void doLargeGetPutPrevKeyForwardTraverse()
428         throws DatabaseException {
429
430         Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
431         doLargePut(dataMap, N_KEYS);
432
433         DataWalker dw = new DataWalker(dataMap) {
434                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
435                     throws DatabaseException {
436
437                     assertTrue(foundKey.compareTo(prevKey) >= 0);
438                     putAndVerifyCursor(cursor2,
439                                        new StringDbt(prevKey(foundKey)),
440                                        new StringDbt
441                                        (Integer.toString(dataMap.size() +
442                                                          nEntries)),
443                                        true);
444                     prevKey = foundKey;
445                     assertTrue(dataMap.get(foundKey) != null);
446                     dataMap.remove(foundKey);
447                 }
448             };
449         dw.walkData();
450         if (dataMap.size() > 0) {
451             fail("dataMap still has entries");
452         }
453         assertTrue(dw.nEntries == N_KEYS);
454     }
455
456     /**
457      * Insert N_KEYS data items into a tree. Iterate through the tree
458      * in ascending order. Ensure that count() always returns 1 for each
459      * data item returned.
460      */

461     public void testLargeCount()
462         throws Throwable JavaDoc {
463
464         try {
465             initEnv(false);
466             doLargeCount();
467         } catch (Throwable JavaDoc t) {
468             t.printStackTrace();
469             throw t;
470         }
471     }
472
473     /**
474      * Helper routine for above.
475      */

476     private void doLargeCount()
477         throws DatabaseException {
478
479         Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
480         doLargePut(dataMap, N_KEYS);
481
482         DataWalker dw = new DataWalker(dataMap) {
483                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
484                     throws DatabaseException {
485
486                     assertTrue(cursor.count() == 1);
487                     assertTrue(foundKey.compareTo(prevKey) >= 0);
488                     prevKey = foundKey;
489                     assertTrue(dataMap.get(foundKey) != null);
490                     dataMap.remove(foundKey);
491                 }
492             };
493         dw.walkData();
494         if (dataMap.size() > 0) {
495             fail("dataMap still has entries");
496         }
497         assertTrue(dw.nEntries == N_KEYS);
498     }
499
500     public void xxtestGetPerf()
501         throws Throwable JavaDoc {
502
503         try {
504             initEnv(false);
505             final int N = 50000;
506             int count = 0;
507             doLargePutPerf(N);
508
509             StringDbt foundKey = new StringDbt();
510             StringDbt foundData = new StringDbt();
511             OperationStatus status;
512             status = cursor.getFirst(foundKey, foundData, LockMode.DEFAULT);
513
514             while (status == OperationStatus.SUCCESS) {
515                 status = cursor.getNext(foundKey, foundData, LockMode.DEFAULT);
516                 count++;
517             }
518         
519             assertTrue(count == N);
520         } catch (Throwable JavaDoc t) {
521             t.printStackTrace();
522             throw t;
523         }
524     }
525
526     /**
527      * Insert a bunch of key/data pairs. Read them back and replace each of
528      * the data. Read the pairs back again and make sure the replace did the
529      * right thing.
530      */

531     public void testLargeReplace()
532         throws Throwable JavaDoc {
533
534         try {
535             initEnv(false);
536             Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
537             doLargePut(dataMap, N_KEYS);
538
539             DataWalker dw = new DataWalker(dataMap) {
540                     void perData(String JavaDoc foundKey, String JavaDoc foundData)
541                         throws DatabaseException {
542
543                         String JavaDoc newData = foundData + "x";
544                         cursor.putCurrent(new StringDbt(newData));
545                         dataMap.put(foundKey, newData);
546                     }
547                 };
548             dw.walkData();
549             dw = new DataWalker(dataMap) {
550                     void perData(String JavaDoc foundKey, String JavaDoc foundData)
551                         throws DatabaseException {
552
553                         assertTrue(foundData.equals(dataMap.get(foundKey)));
554                         dataMap.remove(foundKey);
555                     }
556                 };
557             dw.walkData();
558             assertTrue(dw.nEntries == N_KEYS);
559             assertTrue(dataMap.size() == 0);
560         } catch (Throwable JavaDoc t) {
561             t.printStackTrace();
562             throw t;
563         }
564     }
565
566     /**
567      * Insert N_KEYS data items into a tree. Iterate through the tree in
568      * descending order. After each element is retrieved, insert the next
569      * highest key into the tree. Ensure that the element just inserted is not
570      * returned by the cursor. Ensure that the elements are returned in
571      * descending order. Lather, rinse, repeat.
572      */

573     public void testLargeGetPutNextKeyBackwardsTraverse()
574         throws Throwable JavaDoc {
575
576         try {
577             tearDown();
578             for (int i = 0; i < N_ITERS; i++) {
579                 setUp();
580                 initEnv(false);
581                 doLargeGetPutNextKeyBackwardsTraverse();
582                 tearDown();
583             }
584         } catch (Throwable JavaDoc t) {
585             t.printStackTrace();
586             throw t;
587         }
588     }
589
590     /**
591      * Helper routine for above.
592      */

593     private void doLargeGetPutNextKeyBackwardsTraverse()
594         throws DatabaseException {
595
596         Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
597         doLargePut(dataMap, N_KEYS);
598
599         DataWalker dw = new BackwardsDataWalker(dataMap) {
600                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
601                     throws DatabaseException {
602
603                     if (!prevKey.equals("")) {
604                         assertTrue(foundKey.compareTo(prevKey) <= 0);
605                     }
606                     putAndVerifyCursor(cursor2,
607                                        new StringDbt(nextKey(foundKey)),
608                                        new StringDbt
609                                        (Integer.toString(dataMap.size() +
610                                                          nEntries)),
611                                        true);
612                     prevKey = foundKey;
613                     assertTrue(dataMap.get(foundKey) != null);
614                     dataMap.remove(foundKey);
615                 }
616
617                 OperationStatus getFirst(StringDbt foundKey,
618                      StringDbt foundData)
619                     throws DatabaseException {
620
621                     return cursor.getLast(foundKey, foundData,
622                                           LockMode.DEFAULT);
623                 }
624
625                 OperationStatus getData(StringDbt foundKey,
626                     StringDbt foundData)
627                     throws DatabaseException {
628
629                     return cursor.getPrev(foundKey, foundData,
630                                           LockMode.DEFAULT);
631                 }
632             };
633         dw.walkData();
634         if (dataMap.size() > 0) {
635             fail("dataMap still has entries");
636         }
637         assertTrue(dw.nEntries == N_KEYS);
638     }
639
640     /**
641      * Insert N_KEYS data items into a tree. Iterate through the tree in
642      * ascending order. After each element is retrieved, insert the next
643      * highest key into the tree. Ensure that the element just inserted is
644      * returned by the cursor. Ensure that the elements are returned in
645      * ascending order. Lather, rinse, repeat.
646      */

647     public void testLargeGetPutNextKeyForwardTraverse()
648         throws Throwable JavaDoc {
649
650         try {
651             initEnv(false);
652             doLargeGetPutNextKeyForwardTraverse(N_KEYS);
653         } catch (Throwable JavaDoc t) {
654             t.printStackTrace();
655             throw t;
656         }
657     }
658
659     /**
660      * Helper routine for above.
661      */

662     private void doLargeGetPutNextKeyForwardTraverse(int nKeys)
663         throws DatabaseException {
664
665         Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
666         Hashtable JavaDoc addedDataMap = new Hashtable JavaDoc();
667         doLargePut(dataMap, nKeys);
668
669         DataWalker dw = new DataWalker(dataMap, addedDataMap) {
670                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
671                     throws DatabaseException {
672
673                     assertTrue(foundKey.compareTo(prevKey) >= 0);
674                     if (addedDataMap.get(foundKey) == null) {
675                         String JavaDoc newKey = nextKey(foundKey);
676                         String JavaDoc newData =
677                             Integer.toString(dataMap.size() + nEntries);
678                         putAndVerifyCursor(cursor2,
679                                            new StringDbt(newKey),
680                                            new StringDbt(newData),
681                                            true);
682                         addedDataMap.put(newKey, newData);
683                         prevKey = foundKey;
684                         assertTrue(dataMap.get(foundKey) != null);
685                         dataMap.remove(foundKey);
686                     } else {
687                         addedDataMap.remove(foundKey);
688                     }
689                 }
690             };
691         dw.walkData();
692         if (dataMap.size() > 0) {
693             fail("dataMap still has entries");
694         }
695         if (addedDataMap.size() > 0) {
696             System.out.println(addedDataMap);
697             fail("addedDataMap still has entries");
698         }
699         assertTrue(dw.nEntries == nKeys * 2);
700     }
701
702     /**
703      * Insert N_KEYS data items into a tree. Iterate through the tree in
704      * descending order. After each element is retrieved, insert the next
705      * lowest key into the tree. Ensure that the element just inserted is
706      * returned by the cursor. Ensure that the elements are returned in
707      * descending order. Lather, rinse, repeat.
708      */

709     public void testLargeGetPutPrevKeyBackwardsTraverse()
710         throws Throwable JavaDoc {
711
712         try {
713             initEnv(false);
714             doLargeGetPutPrevKeyBackwardsTraverse(N_KEYS);
715         } catch (Throwable JavaDoc t) {
716             t.printStackTrace();
717             throw t;
718         }
719     }
720
721     /**
722      * Helper routine for above.
723      */

724     private void doLargeGetPutPrevKeyBackwardsTraverse(int nKeys)
725         throws DatabaseException {
726
727         Hashtable JavaDoc dataMap = new Hashtable JavaDoc();
728         Hashtable JavaDoc addedDataMap = new Hashtable JavaDoc();
729         doLargePut(dataMap, nKeys);
730
731         DataWalker dw = new BackwardsDataWalker(dataMap, addedDataMap) {
732                 void perData(String JavaDoc foundKey, String JavaDoc foundData)
733                     throws DatabaseException {
734
735             if (!prevKey.equals("")) {
736                         assertTrue(foundKey.compareTo(prevKey) <= 0);
737                     }
738                     if (addedDataMap.get(foundKey) == null) {
739                         String JavaDoc newKey = prevKey(foundKey);
740                         String JavaDoc newData =