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.assertTrue;
26  
27  import java.io.File;
28  import java.io.IOException;
29  import java.util.Random;
30  import java.util.Set;
31  
32  import org.apache.directory.mavibot.btree.BTree;
33  import org.apache.directory.mavibot.btree.Cursor;
34  import org.apache.directory.mavibot.btree.Tuple;
35  import org.apache.directory.mavibot.btree.exception.KeyNotFoundException;
36  import org.apache.directory.mavibot.btree.serializer.IntSerializer;
37  import org.apache.directory.mavibot.btree.serializer.LongSerializer;
38  import org.apache.directory.mavibot.btree.serializer.StringSerializer;
39  import org.junit.Test;
40  
41  
42  /**
43   * A unit test class for BTree flush() operation
44   * 
45   * @author <a href="mailto:labs@labs.apache.org">Mavibot labs Project</a>
46   */
47  public class BTreeFlushTest
48  {
49      // Some values to inject in a btree
50      private static int[] sortedValues = new int[]
51          {
52              0, 1, 2, 4, 5, 6, 8, 9, 11, 12,
53              13, 14, 16, 19, 21, 22, 23, 25, 26, 28,
54              30, 31, 32, 34, 36, 37, 38, 39, 41, 42,
55              44, 45, 47, 50, 52, 53, 54, 55, 56, 58,
56              59, 60, 63, 64, 67, 68, 70, 72, 73, 74,
57              76, 77, 79, 80, 81, 82, 85, 88, 89, 90,
58              92, 93, 95, 97, 98, 100, 101, 102, 103, 104,
59              105, 106, 107, 109, 110, 111, 112, 117, 118, 120,
60              121, 128, 129, 130, 131, 132, 135, 136, 137, 138,
61              139, 140, 141, 142, 143, 146, 147, 148, 149, 150,
62              152, 154, 156, 160, 161, 162, 163, 165, 167, 168,
63              169, 171, 173, 174, 175, 176, 177, 178, 179, 180,
64              181, 182, 183, 189, 190, 193, 194, 195, 199, 200,
65              202, 203, 205, 206, 207, 208, 209, 210, 212, 215,
66              216, 217, 219, 220, 222, 223, 224, 225, 226, 227,
67              228, 230, 231, 235, 236, 238, 239, 241, 242, 243,
68              245, 246, 247, 249, 250, 251, 252, 254, 256, 257,
69              258, 259, 261, 262, 263, 264, 266, 268, 272, 273,
70              274, 276, 277, 278, 279, 282, 283, 286, 289, 290,
71              292, 293, 294, 296, 298, 299, 300, 301, 303, 305,
72              308, 310, 316, 317, 318, 319, 322, 323, 324, 326,
73              327, 329, 331, 333, 334, 335, 336, 337, 338, 339,
74              340, 341, 346, 347, 348, 349, 350, 351, 352, 353,
75              355, 356, 357, 358, 359, 361, 365, 366, 373, 374,
76              375, 379, 380, 381, 382, 384, 385, 387, 388, 389,
77              390, 392, 393, 395, 396, 397, 398, 399, 400, 401,
78              404, 405, 406, 407, 410, 411, 412, 416, 417, 418,
79              420, 421, 422, 424, 426, 427, 428, 430, 431, 432,
80              433, 436, 439, 441, 443, 444, 445, 446, 447, 448,
81              449, 450, 451, 452, 453, 454, 455, 456, 458, 459,
82              464, 466, 469, 470, 471, 472, 475, 477, 478, 482,
83              483, 484, 485, 486, 488, 490, 491, 492, 493, 495,
84              496, 497, 500, 502, 503, 504, 505, 506, 507, 509,
85              510, 514, 516, 518, 520, 521, 523, 524, 526, 527,
86              528, 529, 530, 532, 533, 535, 538, 539, 540, 542,
87              543, 544, 546, 547, 549, 550, 551, 553, 554, 558,
88              559, 561, 563, 564, 566, 567, 568, 569, 570, 571,
89              572, 576, 577, 578, 580, 582, 583, 586, 588, 589,
90              590, 592, 593, 596, 597, 598, 599, 600, 601, 604,
91              605, 606, 607, 609, 610, 613, 615, 617, 618, 619,
92              620, 621, 626, 627, 628, 631, 632, 633, 635, 636,
93              637, 638, 639, 640, 641, 643, 645, 647, 648, 649,
94              650, 651, 652, 653, 655, 656, 658, 659, 660, 662,
95              666, 669, 673, 674, 675, 676, 677, 678, 680, 681,
96              682, 683, 685, 686, 687, 688, 689, 690, 691, 692,
97              693, 694, 696, 698, 699, 700, 701, 705, 708, 709,
98              711, 713, 714, 715, 719, 720, 723, 725, 726, 727,
99              728, 731, 732, 733, 734, 735, 736, 739, 740, 743,
100             744, 745, 746, 747, 749, 750, 752, 753, 762, 763,
101             765, 766, 768, 770, 772, 773, 774, 776, 777, 779,
102             782, 784, 785, 788, 790, 791, 793, 794, 795, 798,
103             799, 800, 801, 803, 804, 805, 808, 810, 812, 813,
104             814, 816, 818, 821, 822, 823, 824, 827, 828, 829,
105             831, 832, 833, 834, 835, 837, 838, 839, 840, 843,
106             846, 847, 849, 852, 853, 854, 856, 857, 859, 860,
107             863, 864, 865, 866, 867, 868, 869, 872, 873, 877,
108             880, 881, 882, 883, 887, 888, 889, 890, 891, 894,
109             895, 897, 898, 899, 902, 904, 905, 907, 908, 910,
110             911, 912, 915, 916, 917, 918, 919, 923, 925, 926,
111             927, 928, 929, 930, 932, 935, 936, 937, 938, 939,
112             944, 945, 947, 952, 953, 954, 955, 956, 957, 958,
113             960, 967, 970, 971, 972, 974, 975, 976, 978, 979,
114             980, 981, 983, 984, 985, 987, 988, 989, 991, 995
115     };
116 
117 
118     private String create100KElementsFile() throws IOException
119     {
120         Random random = new Random( System.nanoTime() );
121 
122         int nbError = 0;
123 
124         long l1 = System.currentTimeMillis();
125         int n = 0;
126         long delta = l1;
127         int nbElems = 100000;
128 
129         BTree<Long, String> btree = new BTree<Long, String>( "test", new LongSerializer(), new StringSerializer() );
130         btree.setPageSize( 32 );
131 
132         for ( int i = 0; i < nbElems; i++ )
133         {
134             Long key = ( long ) random.nextLong();
135             String value = Long.toString( key );
136 
137             try
138             {
139                 btree.insert( key, value );
140             }
141             catch ( Exception e )
142             {
143                 e.printStackTrace();
144                 System.out.println( btree );
145                 System.out.println( "Error while adding " + value );
146                 nbError++;
147 
148                 return null;
149             }
150 
151             if ( i % 10000 == 0 )
152             {
153                 if ( n > 0 )
154                 {
155                     long t0 = System.currentTimeMillis();
156                     System.out.println( "Written " + i + " elements in : " + ( t0 - delta ) + "ms" );
157                     delta = t0;
158                 }
159 
160                 n++;
161             }
162         }
163 
164         long l2 = System.currentTimeMillis();
165 
166         System.out.println( "Delta : " + ( l2 - l1 ) + ", nbError = " + nbError
167             + ", Nb insertion per second : " + ( ( nbElems ) / ( l2 - l1 ) ) * 1000 );
168 
169         // Now, flush the btree
170 
171         File tempFile = File.createTempFile( "mavibot", ".tmp" );
172         tempFile.deleteOnExit();
173 
174         long t0 = System.currentTimeMillis();
175 
176         btree.flush( tempFile );
177 
178         long t1 = System.currentTimeMillis();
179 
180         System.out.println( "Time to flush 100 000 elements : " + ( t1 - t0 ) + "ms" );
181         btree.close();
182 
183         return tempFile.getCanonicalPath();
184     }
185 
186 
187     /**
188      * Checks the created BTree contains the expected values
189      */
190     private boolean checkTreeLong( Set<Long> expected, BTree<Long, String> btree ) throws IOException
191     {
192         // We loop on all the expected value to see if they have correctly been inserted
193         // into the btree
194         for ( Long key : expected )
195         {
196             try
197             {
198                 btree.get( key );
199             }
200             catch ( KeyNotFoundException knfe )
201             {
202                 return false;
203             }
204         }
205 
206         return true;
207     }
208 
209 
210     /**
211      * Test the browse method going backward
212      * @throws Exception
213      */
214     @Test
215     public void testFlushBTree() throws Exception
216     {
217         // Create a BTree with pages containing 8 elements
218         // Create the file, it will be deleted on exit
219         File tempFile = File.createTempFile( "testFlush", null );
220         String path = tempFile.getParent();
221         tempFile.delete();
222 
223         BTree<Integer, String> btree = new BTree<Integer, String>( "test", path, new IntSerializer(), new StringSerializer() );
224         btree.setPageSize( 8 );
225         
226         File journal = btree.getJournal();
227         File data = btree.getFile();
228         
229         try
230         {
231             // Inject the values
232             for ( int value : sortedValues )
233             {
234                 String strValue = "V" + value;
235 
236                 btree.insert( value, strValue );
237             }
238 
239             // The journal must be full
240             assertTrue( journal.length() > 0 );
241 
242             // Now, flush the btree
243             btree.flush();
244 
245             // The journal must be empty
246             assertEquals( 0, journal.length() );
247 
248             // Load the data into a new tree
249             BTree<Integer, String> btreeLoaded = new BTree<Integer, String>( "test", path, new IntSerializer(),
250                 new StringSerializer() );
251             btree.setPageSize( 8 );
252 
253             Cursor<Integer, String> cursor1 = btree.browse();
254             Cursor<Integer, String> cursor2 = btree.browse();
255 
256             while ( cursor1.hasNext() )
257             {
258                 assertTrue( cursor2.hasNext() );
259 
260                 Tuple<Integer, String> tuple1 = cursor1.next();
261                 Tuple<Integer, String> tuple2 = cursor2.next();
262 
263                 assertEquals( tuple1.getKey(), tuple2.getKey() );
264                 assertEquals( tuple1.getValue(), tuple2.getValue() );
265             }
266 
267             assertFalse( cursor2.hasNext() );
268 
269             btree.close();
270             btreeLoaded.close();
271         }
272         finally
273         {
274             data.delete();
275             journal.delete();
276         }
277     }
278 
279 
280     /**
281      * Test the insertion of 5 million elements in a BTree
282      * @throws Exception
283      */
284     @Test
285     public void testLoadBTreeFromFile() throws Exception
286     {
287         String data100K = create100KElementsFile();
288         File dataFile = new File( data100K );
289         BTree<Long, String> btree = new BTree<Long, String>(
290             "test",
291             dataFile.getParent(),
292             new LongSerializer(),
293             new StringSerializer() );
294         btree.setPageSize( 32 );
295     }
296 }