View Javadoc
1   /*
2    *  Licensed to the Apache Software Foundation (ASF) under one
3    *  or more contributor license agreements.  See the NOTICE file
4    *  distributed with this work for additional information
5    *  regarding copyright ownership.  The ASF licenses this file
6    *  to you under the Apache License, Version 2.0 (the
7    *  "License"); you may not use this file except in compliance
8    *  with the License.  You may obtain a copy of the License at
9    *
10   *    http://www.apache.org/licenses/LICENSE-2.0
11   *
12   *  Unless required by applicable law or agreed to in writing,
13   *  software distributed under the License is distributed on an
14   *  "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   *  KIND, either express or implied.  See the License for the
16   *  specific language governing permissions and limitations
17   *  under the License.
18   *
19   */
20  package org.apache.directory.mavibot.btree;
21  
22  
23  import static org.junit.Assert.assertEquals;
24  import static org.junit.Assert.assertFalse;
25  import static org.junit.Assert.assertNotNull;
26  import static org.junit.Assert.assertTrue;
27  import static org.junit.Assert.fail;
28  
29  import java.io.File;
30  import java.io.IOException;
31  import java.util.ArrayList;
32  import java.util.HashSet;
33  import java.util.List;
34  import java.util.Set;
35  import java.util.UUID;
36  
37  import org.apache.commons.io.FileUtils;
38  import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
39  import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
40  import org.apache.directory.mavibot.btree.serializer.LongSerializer;
41  import org.apache.directory.mavibot.btree.serializer.StringSerializer;
42  import org.junit.After;
43  import org.junit.Before;
44  import org.junit.Ignore;
45  import org.junit.Rule;
46  import org.junit.Test;
47  import org.junit.rules.TemporaryFolder;
48  
49  
50  /**
51   * test the RecordManager
52   *
53   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
54   */
55  public class RecordManagerTest
56  {
57      private BTree<Long, String> btree = null;
58  
59      private RecordManager recordManager = null;
60  
61      @Rule
62      public TemporaryFolder tempFolder = new TemporaryFolder();
63  
64      private File dataDir = null;
65  
66  
67      @Before
68      public void createBTree() throws IOException
69      {
70          dataDir = tempFolder.newFolder( UUID.randomUUID().toString() );
71  
72          System.out.println( dataDir + "/mavibot.db" );
73  
74          openRecordManagerAndBtree();
75  
76          try
77          {
78              // Create a new BTree
79              btree = recordManager.addBTree( "test", LongSerializer.INSTANCE, StringSerializer.INSTANCE, false );
80          }
81          catch ( Exception e )
82          {
83              throw new RuntimeException( e );
84          }
85      }
86  
87  
88      @After
89      public void cleanup() throws IOException
90      {
91          btree.close();
92  
93          if ( dataDir.exists() )
94          {
95              FileUtils.deleteDirectory( dataDir );
96          }
97      }
98  
99  
100     private void openRecordManagerAndBtree()
101     {
102         try
103         {
104             if ( recordManager != null )
105             {
106                 recordManager.close();
107             }
108 
109             // Now, try to reload the file back
110             recordManager = new RecordManager( dataDir.getAbsolutePath() );
111 
112             // load the last created btree
113             if ( btree != null )
114             {
115                 btree = recordManager.getManagedTree( btree.getName() );
116             }
117         }
118         catch ( Exception e )
119         {
120             throw new RuntimeException( e );
121         }
122     }
123 
124 
125     /**
126      * Test the creation of a RecordManager, and that we can read it back.
127      */
128     @Test
129     @Ignore
130     public void testRecordManager() throws IOException, BTreeAlreadyManagedException
131     {
132         assertEquals( 1, recordManager.getNbManagedTrees() );
133 
134         Set<String> managedBTrees = recordManager.getManagedTrees();
135 
136         assertEquals( 1, managedBTrees.size() );
137         assertTrue( managedBTrees.contains( "test" ) );
138 
139         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
140 
141         assertNotNull( btree1 );
142         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
143         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
144         assertEquals( btree.getName(), btree1.getName() );
145         assertEquals( btree.getNbElems(), btree1.getNbElems() );
146         assertEquals( btree.getPageSize(), btree1.getPageSize() );
147         assertEquals( btree.getRevision(), btree1.getRevision() );
148         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
149     }
150 
151 
152     /**
153      * Test the creation of a RecordManager with a BTree containing data.
154      */
155     @Test
156     public void testRecordManagerWithBTree() throws IOException, BTreeAlreadyManagedException, KeyNotFoundException
157     {
158         // Now, add some elements in the BTree
159         btree.insert( 3L, "V3" );
160         btree.insert( 1L, "V1" );
161         btree.insert( 5L, "V5" );
162 
163         // Now, try to reload the file back
164         openRecordManagerAndBtree();
165 
166         assertEquals( 1, recordManager.getNbManagedTrees() );
167 
168         Set<String> managedBTrees = recordManager.getManagedTrees();
169 
170         assertEquals( 1, managedBTrees.size() );
171         assertTrue( managedBTrees.contains( "test" ) );
172 
173         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
174 
175         assertNotNull( btree1 );
176         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
177         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
178         assertEquals( btree.getName(), btree1.getName() );
179         assertEquals( btree.getNbElems(), btree1.getNbElems() );
180         assertEquals( btree.getPageSize(), btree1.getPageSize() );
181         assertEquals( btree.getRevision(), btree1.getRevision() );
182         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
183 
184         // Check the stored element
185         assertTrue( btree1.hasKey( 1L ) );
186         assertTrue( btree1.hasKey( 3L ) );
187         assertTrue( btree1.hasKey( 5L ) );
188         assertEquals( "V1", btree1.get( 1L ) );
189         assertEquals( "V3", btree1.get( 3L ) );
190         assertEquals( "V5", btree1.get( 5L ) );
191     }
192 
193 
194     /**
195      * Test the creation of a RecordManager with a BTree containing data, enough for some Node to be created.
196      */
197     @Test
198     public void testRecordManagerWithBTreeLeafNode() throws IOException, BTreeAlreadyManagedException,
199         KeyNotFoundException
200     {
201         // Now, add some elements in the BTree
202         for ( long i = 1L; i < 32L; i++ )
203         {
204             btree.insert( i, "V" + i );
205         }
206 
207         for ( long i = 1L; i < 32L; i++ )
208         {
209             if ( !btree.hasKey( i ) )
210             {
211                 System.out.println( "Not found !!! " + i );
212             }
213             assertTrue( btree.hasKey( i ) );
214             assertEquals( "V" + i, btree.get( i ) );
215         }
216 
217         
218         // Now, try to reload the file back
219         openRecordManagerAndBtree();
220 
221         assertEquals( 1, recordManager.getNbManagedTrees() );
222 
223         Set<String> managedBTrees = recordManager.getManagedTrees();
224 
225         assertEquals( 1, managedBTrees.size() );
226         assertTrue( managedBTrees.contains( "test" ) );
227 
228         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
229 
230         assertNotNull( btree1 );
231         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
232         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
233         assertEquals( btree.getName(), btree1.getName() );
234         assertEquals( btree.getNbElems(), btree1.getNbElems() );
235         assertEquals( btree.getPageSize(), btree1.getPageSize() );
236         assertEquals( btree.getRevision(), btree1.getRevision() );
237         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
238 
239         // Check the stored element
240         for ( long i = 1L; i < 32L; i++ )
241         {
242             if ( !btree1.hasKey( i ) )
243             {
244                 System.out.println( "Not found " + i );
245             }
246             assertTrue( btree1.hasKey( i ) );
247             assertEquals( "V" + i, btree1.get( i ) );
248         }
249     }
250 
251 
252     /**
253      * Test the creation of a RecordManager with a BTree containing 100 000 elements
254      */
255     @Test
256     @Ignore("This is a performance test")
257     public void testRecordManagerWithBTreeLeafNode100K() throws IOException, BTreeAlreadyManagedException,
258         KeyNotFoundException
259     {
260         // Don't keep any revision
261         recordManager.setKeepRevisions( false );
262 
263         String fileName = dataDir.getAbsolutePath() + "/mavibot.db";
264         File file = new File( fileName );
265         long fileSize = file.length();
266         long nbElems = 100000L;
267         System.out.println( "----- Size before = " + fileSize );
268 
269         // Now, add some elements in the BTree
270         long t0 = System.currentTimeMillis();
271 
272         for ( Long i = 0L; i < nbElems; i++ )
273         {
274             String value = "V" + i;
275             btree.insert( i, value );
276 
277             /*
278             if ( !recordManager1.check() )
279             {
280                 System.out.println( "Failure while adding element " + i );
281                 fail();
282             }
283             */
284 
285             if ( i % 10000 == 0 )
286             {
287                 fileSize = file.length();
288                 System.out.println( "----- Size after insertion of " + i + " = " + fileSize );
289                 System.out.println( recordManager );
290                 //System.out.println( btree );
291             }
292         }
293         long t1 = System.currentTimeMillis();
294 
295         fileSize = file.length();
296         System.out.println( "Size after insertion of 100 000 elements : " + fileSize );
297         System.out.println( "Time taken to write 100 000 elements : " + ( t1 - t0 ) );
298         System.out.println( "  Nb elem/s : " + ( ( nbElems * 1000 ) / ( t1 - t0 ) ) );
299         System.out.println( "Nb created page " + recordManager.nbCreatedPages.get() );
300         System.out.println( "Nb allocated page " + recordManager.nbReusedPages.get() );
301         System.out.println( "Nb page we have freed " + recordManager.nbFreedPages.get() );
302         System.out.println( recordManager );
303 
304         // Now, try to reload the file back
305         openRecordManagerAndBtree();
306 
307         assertEquals( 1, recordManager.getNbManagedTrees() );
308 
309         Set<String> managedBTrees = recordManager.getManagedTrees();
310 
311         assertEquals( 1, managedBTrees.size() );
312         assertTrue( managedBTrees.contains( "test" ) );
313 
314         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
315 
316         assertNotNull( btree1 );
317         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
318         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
319         assertEquals( btree.getName(), btree1.getName() );
320         assertEquals( btree.getNbElems(), btree1.getNbElems() );
321         assertEquals( btree.getPageSize(), btree1.getPageSize() );
322         assertEquals( btree.getRevision(), btree1.getRevision() );
323         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
324 
325         // Check the stored element
326         long t2 = System.currentTimeMillis();
327         for ( long i = 0L; i < nbElems; i++ )
328         {
329             //assertTrue( btree1.exist( i ) );
330             assertEquals( "V" + i, btree1.get( i ) );
331         }
332         long t3 = System.currentTimeMillis();
333         System.out.println( "Time taken to verify 100 000 elements : " + ( t3 - t2 ) );
334 
335         // Check the stored element a second time
336         long t4 = System.currentTimeMillis();
337         for ( long i = 0L; i < nbElems; i++ )
338         {
339             //assertTrue( btree1.exist( i ) );
340             assertEquals( "V" + i, btree1.get( i ) );
341         }
342         long t5 = System.currentTimeMillis();
343         System.out.println( "Time taken to verify 100 000 elements : " + ( t5 - t4 ) );
344     }
345 
346 
347     private void checkBTreeRevisionBrowse( BTree<Long, String> btree, long revision, long... values )
348         throws IOException,
349         KeyNotFoundException
350     {
351         TupleCursor<Long, String> cursor = btree.browse( revision );
352         List<Long> expected = new ArrayList<Long>( values.length );
353         Set<Long> found = new HashSet<Long>( values.length );
354 
355         for ( long value : values )
356         {
357             expected.add( value );
358         }
359 
360         int nb = 0;
361 
362         while ( cursor.hasNext() )
363         {
364             Tuple<Long, String> res = cursor.next();
365 
366             long key = res.getKey();
367             assertEquals( expected.get( nb ), ( Long ) key );
368             assertFalse( found.contains( key ) );
369             found.add( key );
370             assertEquals( "V" + key, res.getValue() );
371             nb++;
372         }
373 
374         assertEquals( values.length, nb );
375         cursor.close();
376     }
377 
378 
379     private void checkBTreeRevisionBrowseFrom( BTree<Long, String> btree, long revision, long from, long... values )
380         throws IOException,
381         KeyNotFoundException
382     {
383         TupleCursor<Long, String> cursor = btree.browseFrom( revision, from );
384         List<Long> expected = new ArrayList<Long>( values.length );
385         Set<Long> found = new HashSet<Long>( values.length );
386 
387         for ( long value : values )
388         {
389             expected.add( value );
390         }
391 
392         int nb = 0;
393 
394         while ( cursor.hasNext() )
395         {
396             Tuple<Long, String> res = cursor.next();
397 
398             long key = res.getKey();
399             assertEquals( expected.get( nb ), ( Long ) key );
400             assertFalse( found.contains( key ) );
401             found.add( key );
402             assertEquals( "V" + key, res.getValue() );
403             nb++;
404         }
405 
406         assertEquals( values.length, nb );
407         cursor.close();
408 
409     }
410 
411 
412     /**
413      * Test the creation of a RecordManager with a BTree containing data, where we keep the revisions,
414      * and browse the BTree.
415      */
416     @Test
417     public void testRecordManagerBrowseWithKeepRevisions() throws IOException, BTreeAlreadyManagedException,
418         KeyNotFoundException
419     {
420         recordManager.setKeepRevisions( true );
421 
422         // Now, add some elements in the BTree
423         btree.insert( 3L, "V3" );
424         long rev1 = btree.getRevision();
425 
426         btree.insert( 1L, "V1" );
427         long rev2 = btree.getRevision();
428 
429         btree.insert( 5L, "V5" );
430         long rev3 = btree.getRevision();
431 
432         // Check that we can browse each revision
433         // revision 1
434         checkBTreeRevisionBrowse( btree, rev1, 3L );
435 
436         // Revision 2
437         checkBTreeRevisionBrowse( btree, rev2, 1L, 3L );
438 
439         // Revision 3
440         checkBTreeRevisionBrowse( btree, rev3, 1L, 3L, 5L );
441 
442         // Now, try to reload the file back
443         openRecordManagerAndBtree();
444 
445         assertEquals( 1, recordManager.getNbManagedTrees() );
446 
447         Set<String> managedBTrees = recordManager.getManagedTrees();
448 
449         assertEquals( 1, managedBTrees.size() );
450         assertTrue( managedBTrees.contains( "test" ) );
451 
452         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
453 
454         assertNotNull( btree1 );
455         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
456         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
457         assertEquals( btree.getName(), btree1.getName() );
458         assertEquals( btree.getNbElems(), btree1.getNbElems() );
459         assertEquals( btree.getPageSize(), btree1.getPageSize() );
460         assertEquals( btree.getRevision(), btree1.getRevision() );
461         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
462 
463         // Check the stored element
464         assertTrue( btree1.hasKey( 1L ) );
465         assertTrue( btree1.hasKey( 3L ) );
466         assertTrue( btree1.hasKey( 5L ) );
467         assertEquals( "V1", btree1.get( 1L ) );
468         assertEquals( "V3", btree1.get( 3L ) );
469         assertEquals( "V5", btree1.get( 5L ) );
470 
471         // Check that we can read the revision again
472         // revision 1
473         checkBTreeRevisionBrowse( btree, rev1 );
474 
475         // Revision 2
476         checkBTreeRevisionBrowse( btree, rev2 );
477 
478         // Revision 3
479         checkBTreeRevisionBrowse( btree, rev3, 1L, 3L, 5L );
480     }
481 
482 
483     /**
484      * Test the creation of a RecordManager with a BTree containing data, where we keep the revision, and
485      * we browse from a key
486      */
487     @Test
488     public void testRecordManagerBrowseFromWithRevision() throws IOException, BTreeAlreadyManagedException,
489         KeyNotFoundException
490     {
491         recordManager.setKeepRevisions( true );
492 
493         // Now, add some elements in the BTree
494         btree.insert( 3L, "V3" );
495         long rev1 = btree.getRevision();
496 
497         btree.insert( 1L, "V1" );
498         long rev2 = btree.getRevision();
499 
500         btree.insert( 5L, "V5" );
501         long rev3 = btree.getRevision();
502 
503         // Check that we can browse each revision
504         // revision 1
505         checkBTreeRevisionBrowseFrom( btree, rev1, 3L, 3L );
506 
507         // Revision 2
508         checkBTreeRevisionBrowseFrom( btree, rev2, 3L, 3L );
509 
510         // Revision 3
511         checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
512 
513         // Now, try to reload the file back
514         openRecordManagerAndBtree();
515 
516         assertEquals( 1, recordManager.getNbManagedTrees() );
517 
518         Set<String> managedBTrees = recordManager.getManagedTrees();
519 
520         assertEquals( 1, managedBTrees.size() );
521         assertTrue( managedBTrees.contains( "test" ) );
522 
523         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
524 
525         assertNotNull( btree1 );
526         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
527         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
528         assertEquals( btree.getName(), btree1.getName() );
529         assertEquals( btree.getNbElems(), btree1.getNbElems() );
530         assertEquals( btree.getPageSize(), btree1.getPageSize() );
531         assertEquals( btree.getRevision(), btree1.getRevision() );
532         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
533 
534         // Check the stored element
535         assertTrue( btree1.hasKey( 1L ) );
536         assertTrue( btree1.hasKey( 3L ) );
537         assertTrue( btree1.hasKey( 5L ) );
538         assertEquals( "V1", btree1.get( 1L ) );
539         assertEquals( "V3", btree1.get( 3L ) );
540         assertEquals( "V5", btree1.get( 5L ) );
541 
542         // Check that we can read the revision again
543         // revision 1
544         checkBTreeRevisionBrowseFrom( btree, rev1, 3L );
545 
546         // Revision 2
547         checkBTreeRevisionBrowseFrom( btree, rev2, 3L );
548 
549         // Revision 3
550         checkBTreeRevisionBrowseFrom( btree, rev3, 3L, 3L, 5L );
551     }
552 
553 
554     /**
555      * Test a get() from a given revision
556      */
557     @Test
558     public void testGetWithRevision() throws IOException, BTreeAlreadyManagedException,
559         KeyNotFoundException
560     {
561         recordManager.setKeepRevisions( true );
562 
563         // Now, add some elements in the BTree
564         btree.insert( 3L, "V3" );
565         long rev1 = btree.getRevision();
566 
567         btree.insert( 1L, "V1" );
568         long rev2 = btree.getRevision();
569 
570         btree.insert( 5L, "V5" );
571         long rev3 = btree.getRevision();
572 
573         // Delete one element
574         btree.delete( 3L );
575         long rev4 = btree.getRevision();
576 
577         // Check that we can get a value from each revision
578         // revision 1
579         assertEquals( "V3", btree.get( rev1, 3L ) );
580 
581         // revision 2
582         assertEquals( "V1", btree.get( rev2, 1L ) );
583         assertEquals( "V3", btree.get( rev2, 3L ) );
584 
585         // revision 3
586         assertEquals( "V1", btree.get( rev3, 1L ) );
587         assertEquals( "V3", btree.get( rev3, 3L ) );
588         assertEquals( "V5", btree.get( rev3, 5L ) );
589 
590         // revision 4
591         assertEquals( "V1", btree.get( rev4, 1L ) );
592         assertEquals( "V5", btree.get( rev4, 5L ) );
593 
594         try
595         {
596             btree.get( rev4, 3L );
597             fail();
598         }
599         catch ( KeyNotFoundException knfe )
600         {
601             // expected
602         }
603 
604         // Now, try to reload the file back
605         openRecordManagerAndBtree();
606 
607         assertEquals( 1, recordManager.getNbManagedTrees() );
608 
609         Set<String> managedBTrees = recordManager.getManagedTrees();
610 
611         assertEquals( 1, managedBTrees.size() );
612         assertTrue( managedBTrees.contains( "test" ) );
613 
614         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
615 
616         assertNotNull( btree1 );
617         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
618         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
619         assertEquals( btree.getName(), btree1.getName() );
620         assertEquals( btree.getNbElems(), btree1.getNbElems() );
621         assertEquals( btree.getPageSize(), btree1.getPageSize() );
622         assertEquals( btree.getRevision(), btree1.getRevision() );
623         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
624 
625         // Check the stored element
626         assertTrue( btree1.hasKey( 1L ) );
627         assertFalse( btree1.hasKey( 3L ) );
628         assertTrue( btree1.hasKey( 5L ) );
629         assertEquals( "V1", btree1.get( 1L ) );
630         assertEquals( "V5", btree1.get( 5L ) );
631 
632         // Check that we can get a value from each revision
633         // revision 1
634         checkBTreeRevisionBrowse( btree, rev1 );
635 
636         // revision 2
637         checkBTreeRevisionBrowse( btree, rev2 );
638 
639         // revision 3
640         checkBTreeRevisionBrowse( btree, rev3 );
641 
642         // revision 4
643         checkBTreeRevisionBrowse( btree, rev4, 1L, 5L );
644 
645         try
646         {
647             btree.get( rev4, 3L );
648             fail();
649         }
650         catch ( KeyNotFoundException knfe )
651         {
652             // expected
653         }
654     }
655 
656 
657     /**
658      * Test a contain() from a given revision
659      */
660     @Test
661     public void testContainWithRevision() throws IOException, BTreeAlreadyManagedException,
662         KeyNotFoundException
663     {
664         recordManager.setKeepRevisions( true );
665 
666         // Now, add some elements in the BTree
667         btree.insert( 3L, "V3" );
668         long rev1 = btree.getRevision();
669 
670         btree.insert( 1L, "V1" );
671         long rev2 = btree.getRevision();
672 
673         btree.insert( 5L, "V5" );
674         long rev3 = btree.getRevision();
675 
676         // Delete one element
677         btree.delete( 3L );
678         long rev4 = btree.getRevision();
679 
680         // Check that we can get a value from each revision
681         // revision 1
682         assertFalse( btree.contains( rev1, 1L, "V1" ) );
683         assertTrue( btree.contains( rev1, 3L, "V3" ) );
684         assertFalse( btree.contains( rev1, 5L, "V5" ) );
685 
686         // revision 2
687         assertTrue( btree.contains( rev2, 1L, "V1" ) );
688         assertTrue( btree.contains( rev2, 3L, "V3" ) );
689         assertFalse( btree.contains( rev2, 5L, "V5" ) );
690 
691         // revision 3
692         assertTrue( btree.contains( rev3, 1L, "V1" ) );
693         assertTrue( btree.contains( rev3, 3L, "V3" ) );
694         assertTrue( btree.contains( rev3, 5L, "V5" ) );
695 
696         // revision 4
697         assertTrue( btree.contains( rev4, 1L, "V1" ) );
698         assertFalse( btree.contains( rev4, 3L, "V3" ) );
699         assertTrue( btree.contains( rev4, 5L, "V5" ) );
700 
701         // Now, try to reload the file back
702         openRecordManagerAndBtree();
703 
704         assertEquals( 1, recordManager.getNbManagedTrees() );
705 
706         Set<String> managedBTrees = recordManager.getManagedTrees();
707 
708         assertEquals( 1, managedBTrees.size() );
709         assertTrue( managedBTrees.contains( "test" ) );
710 
711         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
712 
713         assertNotNull( btree1 );
714         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
715         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
716         assertEquals( btree.getName(), btree1.getName() );
717         assertEquals( btree.getNbElems(), btree1.getNbElems() );
718         assertEquals( btree.getPageSize(), btree1.getPageSize() );
719         assertEquals( btree.getRevision(), btree1.getRevision() );
720         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
721 
722         // Check the stored element
723         assertTrue( btree1.hasKey( 1L ) );
724         assertFalse( btree1.hasKey( 3L ) );
725         assertTrue( btree1.hasKey( 5L ) );
726         assertEquals( "V1", btree1.get( 1L ) );
727         assertEquals( "V5", btree1.get( 5L ) );
728 
729         // Check that we can get a value from each revision
730         // revision 1
731         assertFalse( btree.contains( rev1, 1L, "V1" ) );
732         assertFalse( btree.contains( rev1, 3L, "V3" ) );
733         assertFalse( btree.contains( rev1, 5L, "V5" ) );
734 
735         // revision 2
736         assertFalse( btree.contains( rev2, 1L, "V1" ) );
737         assertFalse( btree.contains( rev2, 3L, "V3" ) );
738         assertFalse( btree.contains( rev2, 5L, "V5" ) );
739 
740         // revision 3
741         assertFalse( btree.contains( rev3, 1L, "V1" ) );
742         assertFalse( btree.contains( rev3, 3L, "V3" ) );
743         assertFalse( btree.contains( rev3, 5L, "V5" ) );
744 
745         // revision 4
746         assertTrue( btree.contains( rev4, 1L, "V1" ) );
747         assertFalse( btree.contains( rev4, 3L, "V3" ) );
748         assertTrue( btree.contains( rev4, 5L, "V5" ) );
749     }
750 
751 
752     /**
753      * Test a hasKey() from a given revision
754      */
755     @Test
756     public void testHasKeyWithRevision() throws IOException, BTreeAlreadyManagedException,
757         KeyNotFoundException
758     {
759         recordManager.setKeepRevisions( true );
760 
761         // Now, add some elements in the BTree
762         btree.insert( 3L, "V3" );
763         long rev1 = btree.getRevision();
764 
765         btree.insert( 1L, "V1" );
766         long rev2 = btree.getRevision();
767 
768         btree.insert( 5L, "V5" );
769         long rev3 = btree.getRevision();
770 
771         // Delete one element
772         btree.delete( 3L );
773         long rev4 = btree.getRevision();
774 
775         // Check that we can get a value from each revision
776         // revision 1
777         assertFalse( btree.hasKey( rev1, 1L ) );
778         assertTrue( btree.hasKey( rev1, 3L ) );
779         assertFalse( btree.hasKey( rev1, 5L ) );
780 
781         // revision 2
782         assertTrue( btree.hasKey( rev2, 1L ) );
783         assertTrue( btree.hasKey( rev2, 3L ) );
784         assertFalse( btree.hasKey( rev2, 5L ) );
785 
786         // revision 3
787         assertTrue( btree.hasKey( rev3, 1L ) );
788         assertTrue( btree.hasKey( rev3, 3L ) );
789         assertTrue( btree.hasKey( rev3, 5L ) );
790 
791         // revision 4
792         assertTrue( btree.hasKey( rev4, 1L ) );
793         assertFalse( btree.hasKey( rev4, 3L ) );
794         assertTrue( btree.hasKey( rev4, 5L ) );
795 
796         // Now, try to reload the file back
797         openRecordManagerAndBtree();
798 
799         assertEquals( 1, recordManager.getNbManagedTrees() );
800 
801         Set<String> managedBTrees = recordManager.getManagedTrees();
802 
803         assertEquals( 1, managedBTrees.size() );
804         assertTrue( managedBTrees.contains( "test" ) );
805 
806         BTree<Long, String> btree1 = recordManager.getManagedTree( "test" );
807 
808         assertNotNull( btree1 );
809         assertEquals( btree.getComparator().getClass().getName(), btree1.getComparator().getClass().getName() );
810         assertEquals( btree.getKeySerializer().getClass().getName(), btree1.getKeySerializer().getClass().getName() );
811         assertEquals( btree.getName(), btree1.getName() );
812         assertEquals( btree.getNbElems(), btree1.getNbElems() );
813         assertEquals( btree.getPageSize(), btree1.getPageSize() );
814         assertEquals( btree.getRevision(), btree1.getRevision() );
815         assertEquals( btree.getValueSerializer().getClass().getName(), btree1.getValueSerializer().getClass().getName() );
816 
817         // Check the stored element
818         assertTrue( btree1.hasKey( 1L ) );
819         assertFalse( btree1.hasKey( 3L ) );
820         assertTrue( btree1.hasKey( 5L ) );
821         assertEquals( "V1", btree1.get( 1L ) );
822         assertEquals( "V5", btree1.get( 5L ) );
823 
824         // Check that we can get a value from each revision
825         // revision 1
826         assertFalse( btree.hasKey( rev1, 1L ) );
827         assertFalse( btree.hasKey( rev1, 3L ) );
828         assertFalse( btree.hasKey( rev1, 5L ) );
829 
830         // revision 2
831         assertFalse( btree.hasKey( rev2, 1L ) );
832         assertFalse( btree.hasKey( rev2, 3L ) );
833         assertFalse( btree.hasKey( rev2, 5L ) );
834 
835         // revision 3
836         assertFalse( btree.hasKey( rev3, 1L ) );
837         assertFalse( btree.hasKey( rev3, 3L ) );
838         assertFalse( btree.hasKey( rev3, 5L ) );
839 
840         // revision 4
841         assertTrue( btree.hasKey( rev4, 1L ) );
842         assertFalse( btree.hasKey( rev4, 3L ) );
843         assertTrue( btree.hasKey( rev4, 5L ) );
844     }
845 
846 
847     /**
848      * Test with BTrees containing duplicate keys
849      */
850     @Test
851     public void testBTreesDuplicateKeys() throws IOException, BTreeAlreadyManagedException,
852         KeyNotFoundException
853     {
854         int pageSize = 16;
855         int numKeys = 1;
856         String name = "duplicateTree";
857         String[] testValues = new String[]
858             { "00", "01", "02", "03", "04", "05", "06", "07", "08", "09", "0A", "0B", "0C", "0D", "0E", "0F", "10" };
859 
860         BTree<Long, String> dupsTree = BTreeFactory.createPersistedBTree( name, LongSerializer.INSTANCE,
861             StringSerializer.INSTANCE, pageSize, true );
862 
863         recordManager.manage( dupsTree );
864 
865         for ( long i = 0; i < numKeys; i++ )
866         {
867             for ( int k = 0; k < pageSize + 1; k++ )
868             {
869                 dupsTree.insert( i, testValues[k] );
870             }
871         }
872 
873         // Now, try to reload the file back
874         openRecordManagerAndBtree();
875 
876         dupsTree = recordManager.getManagedTree( name );
877 
878         for ( long i = 0; i < numKeys; i++ )
879         {
880             ValueCursor<String> values = dupsTree.getValues( i );
881 
882             for ( int k = 0; k < pageSize + 1; k++ )
883             {
884                 assertTrue( values.next().equals( testValues[k] ) );
885             }
886         }
887     }
888     
889     
890     @Test
891     public void testAdds() throws IOException, BTreeAlreadyManagedException,KeyNotFoundException
892     {
893         btree.insert( 1L, "V1" );
894         btree.insert( 2L, "V2" );
895     }
896 }