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.assertNull;
27  import static org.junit.Assert.assertTrue;
28  import static org.junit.Assert.fail;
29  
30  import java.io.IOException;
31  import java.util.NoSuchElementException;
32  import java.util.UUID;
33  
34  import org.apache.directory.mavibot.btree.exception.BTreeAlreadyManagedException;
35  import org.apache.directory.mavibot.btree.exception.DuplicateValueNotAllowedException;
36  import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
37  import org.apache.directory.mavibot.btree.serializer.IntSerializer;
38  import org.apache.directory.mavibot.btree.serializer.LongSerializer;
39  import org.apache.directory.mavibot.btree.serializer.StringSerializer;
40  import org.junit.Test;
41  
42  
43  /**
44   * TODO BTreeDuplicateKeyTest.
45   *
46   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
47   */
48  public class InMemoryBTreeDuplicateKeyTest
49  {
50      @Test
51      public void testInsertNullValue() throws IOException, KeyNotFoundException
52      {
53          IntSerializer serializer = IntSerializer.INSTANCE;
54  
55          BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master", serializer, serializer );
56  
57          btree.insert( 1, null );
58  
59          TupleCursor<Integer, Integer> cursor = btree.browse();
60          assertTrue( cursor.hasNext() );
61  
62          Tuple<Integer, Integer> t = cursor.next();
63  
64          assertEquals( Integer.valueOf( 1 ), t.getKey() );
65          assertEquals( null, t.getValue() );
66  
67          cursor.close();
68          btree.close();
69      }
70  
71  
72      @Test
73      public void testBrowseEmptyTree() throws IOException, KeyNotFoundException
74      {
75          IntSerializer serializer = IntSerializer.INSTANCE;
76  
77          BTree<Integer, Integer> btree = BTreeFactory.createInMemoryBTree( "master", serializer, serializer );
78  
79          TupleCursor<Integer, Integer> cursor = btree.browse();
80          assertFalse( cursor.hasNext() );
81          assertFalse( cursor.hasPrev() );
82  
83          try
84          {
85              cursor.next();
86              fail( "Should not reach here" );
87          }
88          catch ( NoSuchElementException e )
89          {
90              assertTrue( true );
91          }
92  
93          try
94          {
95              cursor.prev();
96              fail( "Should not reach here" );
97          }
98          catch ( NoSuchElementException e )
99          {
100             assertTrue( true );
101         }
102 
103         cursor.close();
104         btree.close();
105     }
106 
107 
108     @Test
109     public void testDuplicateKey() throws IOException, KeyNotFoundException
110     {
111         IntSerializer serializer = IntSerializer.INSTANCE;
112 
113         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
114         config.setAllowDuplicates( true );
115         config.setName( "master" );
116         config.setSerializers( serializer, serializer );
117         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
118 
119         btree.insert( 1, 1 );
120         btree.insert( 1, 2 );
121 
122         TupleCursor<Integer, Integer> cursor = btree.browse();
123         assertTrue( cursor.hasNext() );
124 
125         Tuple<Integer, Integer> t = cursor.next();
126 
127         assertEquals( Integer.valueOf( 1 ), t.getKey() );
128         assertEquals( Integer.valueOf( 1 ), t.getValue() );
129 
130         assertTrue( cursor.hasNext() );
131 
132         t = cursor.next();
133 
134         assertEquals( Integer.valueOf( 1 ), t.getKey() );
135         assertEquals( Integer.valueOf( 2 ), t.getValue() );
136 
137         assertFalse( cursor.hasNext() );
138 
139         // test backward move
140         assertTrue( cursor.hasPrev() );
141 
142         t = cursor.prev();
143 
144         assertEquals( Integer.valueOf( 1 ), t.getKey() );
145         assertEquals( Integer.valueOf( 1 ), t.getValue() );
146 
147         assertFalse( cursor.hasPrev() );
148 
149         // again forward
150         assertTrue( cursor.hasNext() );
151 
152         t = cursor.next();
153 
154         assertEquals( Integer.valueOf( 1 ), t.getKey() );
155         assertEquals( Integer.valueOf( 2 ), t.getValue() );
156 
157         assertFalse( cursor.hasNext() );
158 
159         cursor.close();
160         btree.close();
161     }
162 
163 
164     @Test
165     public void testGetDuplicateKey() throws Exception
166     {
167         IntSerializer serializer = IntSerializer.INSTANCE;
168 
169         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
170         config.setAllowDuplicates( true );
171         config.setName( "master" );
172         config.setSerializers( serializer, serializer );
173         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
174 
175         Integer retVal = btree.insert( 1, 1 );
176         assertNull( retVal );
177 
178         retVal = btree.insert( 1, 2 );
179         assertNull( retVal );
180 
181         // check the return value when an existing value is added again
182         retVal = btree.insert( 1, 2 );
183         assertEquals( Integer.valueOf( 2 ), retVal );
184 
185         assertEquals( Integer.valueOf( 1 ), btree.get( 1 ) );
186         assertTrue( btree.contains( 1, 1 ) );
187         assertTrue( btree.contains( 1, 2 ) );
188 
189         assertFalse( btree.contains( 1, 0 ) );
190         assertFalse( btree.contains( 0, 1 ) );
191         assertFalse( btree.contains( 0, 0 ) );
192         assertFalse( btree.contains( null, 0 ) );
193         assertFalse( btree.contains( 0, null ) );
194         assertFalse( btree.contains( null, null ) );
195 
196         btree.close();
197     }
198 
199 
200     @Test
201     public void testRemoveDuplicateKey() throws Exception
202     {
203         IntSerializer serializer = IntSerializer.INSTANCE;
204 
205         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
206         config.setAllowDuplicates( true );
207         config.setName( "master" );
208         config.setSerializers( serializer, serializer );
209         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
210 
211         btree.insert( 1, 1 );
212         btree.insert( 1, 2 );
213 
214         // We should have only one element in the tree (even if it has 2 values)
215         assertEquals( 2l, btree.getNbElems() );
216 
217         Tuple<Integer, Integer> t = btree.delete( 1, 1 );
218         assertEquals( Integer.valueOf( 1 ), t.getKey() );
219         assertEquals( Integer.valueOf( 1 ), t.getValue() );
220 
221         assertEquals( 1l, btree.getNbElems() );
222 
223         t = btree.delete( 1, 2 );
224         assertEquals( Integer.valueOf( 1 ), t.getKey() );
225         assertNull( t.getValue() );
226 
227         assertEquals( 0l, btree.getNbElems() );
228 
229         t = btree.delete( 1, 2 );
230         assertNull( t );
231 
232         btree.close();
233     }
234 
235 
236     @Test
237     public void testFullPage() throws Exception
238     {
239         StringSerializer serializer = StringSerializer.INSTANCE;
240 
241         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
242         config.setAllowDuplicates( true );
243         config.setName( "master" );
244         config.setSerializers( serializer, serializer );
245         BTree<String, String> btree = new InMemoryBTree<String, String>( config );
246 
247         int i = 7;
248 
249         for ( char ch = 'a'; ch <= 'z'; ch++ )
250         {
251             for ( int k = 0; k < i; k++ )
252             {
253                 String val = ch + Integer.toString( k );
254                 btree.insert( String.valueOf( ch ), val );
255             }
256         }
257 
258         TupleCursor<String, String> cursor = btree.browse();
259 
260         char ch = 'a';
261         int k = 0;
262 
263         while ( cursor.hasNext() )
264         {
265             Tuple<String, String> t = cursor.next();
266             assertEquals( String.valueOf( ch ), t.getKey() );
267             k++;
268 
269             if ( ( k % i ) == 0 )
270             {
271                 ch++;
272             }
273         }
274 
275         assertEquals( ( 'z' + 1 ), ch );
276 
277         ch = 'z';
278         cursor.afterLast();
279 
280         while ( cursor.hasPrev() )
281         {
282             Tuple<String, String> t = cursor.prev();
283             assertEquals( String.valueOf( ch ), t.getKey() );
284             k--;
285 
286             if ( ( k % i ) == 0 )
287             {
288                 ch--;
289             }
290         }
291 
292         assertEquals( ( 'a' - 1 ), ch );
293 
294         cursor.close();
295         btree.close();
296     }
297 
298 
299     @Test
300     public void testMoveFirst() throws Exception
301     {
302         StringSerializer serializer = StringSerializer.INSTANCE;
303 
304         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
305         config.setAllowDuplicates( true );
306         config.setName( "master" );
307         config.setSerializers( serializer, serializer );
308         BTree<String, String> btree = new InMemoryBTree<String, String>( config );
309 
310         for ( char ch = 'a'; ch <= 'z'; ch++ )
311         {
312             btree.insert( String.valueOf( ch ), UUID.randomUUID().toString() );
313         }
314 
315         assertEquals( 26, btree.getNbElems() );
316 
317         // add one more value for 'a'
318         btree.insert( String.valueOf( 'a' ), UUID.randomUUID().toString() );
319 
320         assertEquals( 27, btree.getNbElems() );
321 
322         TupleCursor<String, String> cursor = btree.browseFrom( "c" );
323 
324         int i = 0;
325 
326         while ( cursor.hasNext() )
327         {
328             assertNotNull( cursor.next() );
329             i++;
330         }
331 
332         assertEquals( 24, i );
333 
334         // now move the cursor first
335         cursor.beforeFirst();
336         assertTrue( cursor.hasNext() );
337         Tuple<String, String> tuple = cursor.next();
338 
339         assertEquals( "a", tuple.getKey() );
340 
341         i = 0;
342 
343         while ( cursor.hasNext() )
344         {
345             tuple = cursor.next();
346             assertNotNull( tuple );
347             i++;
348         }
349 
350         assertEquals( 26, i );
351 
352         cursor.close();
353 
354         // Rebrowse
355         cursor = btree.browse();
356 
357         i = 0;
358 
359         while ( cursor.hasNext() )
360         {
361             assertNotNull( cursor.next() );
362             i++;
363         }
364 
365         assertEquals( 27, i );
366 
367         // now move the cursor first
368         cursor.beforeFirst();
369         assertTrue( cursor.hasNext() );
370         assertEquals( "a", cursor.nextKey().getKey() );
371 
372         i = 0;
373 
374         while ( cursor.hasNext() )
375         {
376             tuple = cursor.nextKey();
377             String key = tuple.getKey();
378             assertNotNull( key );
379             i++;
380         }
381 
382         assertEquals( 25, i );
383 
384         btree.close();
385     }
386 
387 
388     @Test(expected = NoSuchElementException.class)
389     public void testMoveLast() throws Exception
390     {
391         StringSerializer serializer = StringSerializer.INSTANCE;
392 
393         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
394         config.setAllowDuplicates( true );
395         config.setName( "master" );
396         config.setSerializers( serializer, serializer );
397         BTree<String, String> btree = new InMemoryBTree<String, String>( config );
398 
399         for ( char ch = 'a'; ch <= 'z'; ch++ )
400         {
401             btree.insert( String.valueOf( ch ), UUID.randomUUID().toString() );
402         }
403 
404         btree.insert( String.valueOf( 'z' ), UUID.randomUUID().toString() );
405 
406         TupleCursor<String, String> cursor = btree.browseFrom( "c" );
407         cursor.afterLast();
408 
409         assertFalse( cursor.hasNext() );
410         assertTrue( cursor.hasPrev() );
411         assertEquals( "z", cursor.prev().getKey() );
412         // the key, 'z', has two values
413         assertEquals( "z", cursor.prev().getKey() );
414         assertEquals( "y", cursor.prev().getKey() );
415 
416         cursor.beforeFirst();
417         assertEquals( "a", cursor.next().getKey() );
418 
419         cursor.afterLast();
420         assertFalse( cursor.hasNext() );
421 
422         // make sure it throws NoSuchElementException
423         try
424         {
425             cursor.next();
426         }
427         finally
428         {
429             btree.close();
430         }
431     }
432 
433 
434     @Test(expected = NoSuchElementException.class)
435     public void testNextPrevKey() throws Exception
436     {
437         StringSerializer serializer = StringSerializer.INSTANCE;
438 
439         InMemoryBTreeConfiguration<String, String> config = new InMemoryBTreeConfiguration<String, String>();
440         config.setAllowDuplicates( true );
441         config.setName( "master" );
442         config.setSerializers( serializer, serializer );
443         BTree<String, String> btree = new InMemoryBTree<String, String>( config );
444 
445         int i = 7;
446 
447         // Insert keys from a to z with 7 values for each key
448         for ( char ch = 'a'; ch <= 'z'; ch++ )
449         {
450             for ( int k = 0; k < i; k++ )
451             {
452                 btree.insert( String.valueOf( ch ), String.valueOf( k ) );
453             }
454         }
455 
456         TupleCursor<String, String> cursor = btree.browse();
457 
458         assertTrue( cursor.hasNext() );
459         assertFalse( cursor.hasPrev() );
460 
461         for ( int k = 0; k < 2; k++ )
462         {
463             assertEquals( "a", cursor.next().getKey() );
464         }
465 
466         assertEquals( "a", cursor.next().getKey() );
467 
468         Tuple<String, String> tuple = cursor.nextKey();
469 
470         assertEquals( "b", tuple.getKey() );
471 
472         for ( char ch = 'b'; ch < 'z'; ch++ )
473         {
474             assertEquals( String.valueOf( ch ), cursor.next().getKey() );
475             tuple = cursor.nextKey();
476             char t = ch;
477             assertEquals( String.valueOf( ++t ), tuple.getKey() );
478         }
479 
480         for ( int k = 0; k < i; k++ )
481         {
482             assertEquals( "z", cursor.next().getKey() );
483         }
484 
485         assertFalse( cursor.hasNextKey() );
486         assertTrue( cursor.hasPrevKey() );
487         tuple = cursor.prev();
488         assertEquals( "z", tuple.getKey() );
489         assertEquals( "6", tuple.getValue() );
490 
491         for ( char ch = 'z'; ch > 'a'; ch-- )
492         {
493             char t = ch;
494             t--;
495 
496             assertEquals( String.valueOf( ch ), cursor.prev().getKey() );
497 
498             tuple = cursor.prevKey();
499 
500             assertEquals( String.valueOf( t ), tuple.getKey() );
501         }
502 
503         for ( int k = 5; k >= 0; k-- )
504         {
505             tuple = cursor.prev();
506             assertEquals( "a", tuple.getKey() );
507             assertEquals( String.valueOf( k ), tuple.getValue() );
508         }
509 
510         assertTrue( cursor.hasNext() );
511         assertFalse( cursor.hasPrev() );
512         tuple = cursor.next();
513         assertEquals( "a", tuple.getKey() );
514         assertEquals( "0", tuple.getValue() );
515 
516         cursor.close();
517 
518         cursor = btree.browseFrom( "y" );
519         tuple = cursor.prevKey();
520         assertNotNull( tuple );
521         assertEquals( "y", tuple.getKey() );
522         assertEquals( "6", tuple.getValue() );
523         cursor.close();
524 
525         cursor = btree.browse();
526         cursor.beforeFirst();
527         assertFalse( cursor.hasPrev() );
528 
529         // make sure it throws NoSuchElementException
530         try
531         {
532             cursor.prev();
533         }
534         finally
535         {
536             btree.close();
537         }
538     }
539 
540 
541     /**
542      * Test for moving between two leaves. When moveToNextNonDuplicateKey is called
543      * and cursor is on the last element of the current leaf.
544      *
545      * @throws Exception
546      */
547     @Test
548     public void testMoveToNextAndPrevWithPageBoundaries() throws Exception
549     {
550         IntSerializer serializer = IntSerializer.INSTANCE;
551 
552         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
553         config.setAllowDuplicates( true );
554         config.setName( "master" );
555         config.setPageSize( 4 );
556         config.setSerializers( serializer, serializer );
557         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
558 
559         int i = 7;
560         for ( int k = 0; k < i; k++ )
561         {
562             btree.insert( k, k );
563         }
564 
565         // 3 is the last element of the first leaf
566         TupleCursor<Integer, Integer> cursor = btree.browseFrom( 3 );
567         Tuple<Integer, Integer> tuple = cursor.nextKey();
568 
569         assertNotNull( tuple );
570         assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
571         assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
572         cursor.close();
573 
574         cursor = btree.browseFrom( 3 );
575         tuple = cursor.prevKey();
576 
577         assertNotNull( tuple );
578         assertEquals( Integer.valueOf( 2 ), tuple.getKey() );
579         assertEquals( Integer.valueOf( 2 ), tuple.getValue() );
580         cursor.close();
581 
582         // 4 is the first element of the second leaf
583         cursor = btree.browseFrom( 4 );
584         tuple = cursor.prevKey();
585 
586         assertNotNull( tuple );
587         assertEquals( Integer.valueOf( 3 ), tuple.getKey() );
588         assertEquals( Integer.valueOf( 3 ), tuple.getValue() );
589 
590         assertTrue( cursor.hasNext() );
591         tuple = cursor.next();
592         assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
593         assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
594 
595         cursor.close();
596 
597         // test the extremes of the BTree instead of that of leaves
598         cursor = btree.browseFrom( 5 );
599         tuple = cursor.nextKey();
600         assertFalse( cursor.hasNext() );
601         assertTrue( cursor.hasPrev() );
602 
603         assertEquals( Integer.valueOf( 6 ), tuple.getKey() );
604         assertEquals( Integer.valueOf( 6 ), tuple.getValue() );
605         cursor.close();
606 
607         cursor = btree.browse();
608         cursor.beforeFirst();
609         assertTrue( cursor.hasNext() );
610         assertFalse( cursor.hasPrev() );
611 
612         tuple = cursor.next();
613 
614         assertEquals( Integer.valueOf( 0 ), tuple.getKey() );
615         assertEquals( Integer.valueOf( 0 ), tuple.getValue() );
616 
617         cursor.close();
618         btree.close();
619     }
620 
621 
622     @Test
623     public void testNextAfterPrev() throws Exception
624     {
625         IntSerializer serializer = IntSerializer.INSTANCE;
626 
627         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
628         config.setAllowDuplicates( true );
629         config.setName( "master" );
630         config.setPageSize( 4 );
631         config.setSerializers( serializer, serializer );
632         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
633 
634         int i = 7;
635         for ( int k = 0; k < i; k++ )
636         {
637             btree.insert( k, k );
638         }
639 
640         // 3 is the last element of the first leaf
641         TupleCursor<Integer, Integer> cursor = btree.browseFrom( 4 );
642 
643         assertTrue( cursor.hasNext() );
644         Tuple<Integer, Integer> tuple = cursor.next();
645         assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
646         assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
647 
648         assertTrue( cursor.hasPrev() );
649         tuple = cursor.prev();
650         assertEquals( Integer.valueOf( 3 ), tuple.getKey() );
651         assertEquals( Integer.valueOf( 3 ), tuple.getValue() );
652 
653         assertTrue( cursor.hasNext() );
654         tuple = cursor.next();
655         assertEquals( Integer.valueOf( 4 ), tuple.getKey() );
656         assertEquals( Integer.valueOf( 4 ), tuple.getValue() );
657 
658         cursor.close();
659         btree.close();
660     }
661 
662 
663     /**
664      * Test for moving after a key and traversing backwards.
665      *
666      * @throws Exception
667      */
668     @Test
669     public void testMoveToNextAndTraverseBackward() throws Exception
670     {
671         IntSerializer serializer = IntSerializer.INSTANCE;
672 
673         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
674         config.setAllowDuplicates( true );
675         config.setName( "master" );
676         config.setPageSize( 8 );
677         config.setSerializers( serializer, serializer );
678         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
679 
680         int i = 5;
681         for ( int k = 0; k < i; k++ )
682         {
683             btree.insert( k, k );
684         }
685 
686         // 4 is the last element in the tree
687         TupleCursor<Integer, Integer> cursor = btree.browseFrom( 4 );
688         cursor.nextKey();
689 
690         int currentKey = 4;
691         while ( cursor.hasPrev() )
692         {
693             assertEquals( Integer.valueOf( currentKey ), cursor.prev().getKey() );
694             currentKey--;
695         }
696 
697         cursor.close();
698         btree.close();
699     }
700 
701 
702     /**
703      * Test for moving after a key and traversing backwards.
704      *
705      * @throws Exception
706      */
707     @Test
708     public void testMoveToPrevAndTraverseForward() throws Exception
709     {
710         IntSerializer serializer = IntSerializer.INSTANCE;
711 
712         InMemoryBTreeConfiguration<Integer, Integer> config = new InMemoryBTreeConfiguration<Integer, Integer>();
713         config.setAllowDuplicates( true );
714         config.setName( "master" );
715         config.setPageSize( 8 );
716         config.setSerializers( serializer, serializer );
717         BTree<Integer, Integer> btree = new InMemoryBTree<Integer, Integer>( config );
718 
719         int i = 5;
720 
721         for ( int k = 0; k < i; k++ )
722         {
723             btree.insert( k, k );
724         }
725 
726         // 4 is the last element in the tree
727         TupleCursor<Integer, Integer> cursor = btree.browseFrom( 0 );
728 
729         int currentKey = 0;
730 
731         while ( cursor.hasNext() )
732         {
733             assertEquals( Integer.valueOf( currentKey ), cursor.next().getKey() );
734             currentKey++;
735         }
736 
737         cursor.close();
738         btree.close();
739     }
740 
741 
742     /**
743      * Test that a BTree which forbid duplicate values does not accept them
744      */
745     @Test(expected = DuplicateValueNotAllowedException.class)
746     public void testBTreeForbidDups() throws IOException, BTreeAlreadyManagedException
747     {
748         BTree<Long, String> singleValueBtree = BTreeFactory.createInMemoryBTree( "test2", LongSerializer.INSTANCE,
749             StringSerializer.INSTANCE, BTree.FORBID_DUPLICATES );
750 
751         for ( long i = 0; i < 64; i++ )
752         {
753             singleValueBtree.insert( i, Long.toString( i ) );
754         }
755 
756         try
757         {
758             singleValueBtree.insert( 18L, "Duplicate" );
759             fail();
760         }
761         finally
762         {
763             singleValueBtree.close();
764         }
765     }
766 }