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