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