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.assertNotNull;
25  
26  import java.io.File;
27  import java.lang.reflect.Method;
28  import java.nio.ByteBuffer;
29  
30  import org.apache.directory.mavibot.btree.PageIO;
31  import org.apache.directory.mavibot.btree.RecordManager;
32  import org.junit.Rule;
33  import org.junit.Test;
34  import org.junit.rules.TemporaryFolder;
35  
36  
37  /**
38   * Test the RecordManager.readXXX() methods using reflection
39   * 
40   * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
41   */
42  public class PersistedReadTest
43  {
44      @Rule
45      public TemporaryFolder tempFolder = new TemporaryFolder();
46  
47  
48      /**
49       * Test the readInt method
50       */
51      @Test
52      public void testReadInt() throws Exception
53      {
54          File tempFile = tempFolder.newFile( "mavibot.db" );
55          String tempFileName = tempFile.getAbsolutePath();
56  
57          // Create page size of 32 only
58          RecordManager recordManager = new RecordManager( tempFileName, 32 );
59          Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, int.class, PageIO[].class );
60          Method readIntMethod = RecordManager.class.getDeclaredMethod( "readInt", PageIO[].class, long.class );
61          storeMethod.setAccessible( true );
62          readIntMethod.setAccessible( true );
63  
64          // Allocate some Pages
65          PageIO[] pageIos = new PageIO[2];
66          pageIos[0] = new PageIO();
67          pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
68          pageIos[1] = new PageIO();
69          pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
70  
71          // Set the int at the beginning
72          storeMethod.invoke( recordManager, 0, 0x12345678, pageIos );
73  
74          // Read it back
75          int readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 0 );
76  
77          assertEquals( 0x12345678, readValue );
78  
79          // Set the int at the end of the first page
80          storeMethod.invoke( recordManager, 16, 0x12345678, pageIos );
81  
82          // Read it back
83          readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 16 );
84  
85          assertEquals( 0x12345678, readValue );
86  
87          // Set the int at the end of the first page and overlapping on the second page
88          // 1 byte overlapping
89          storeMethod.invoke( recordManager, 17, 0x12345678, pageIos );
90  
91          // Read it back
92          readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 17 );
93  
94          assertEquals( 0x12345678, readValue );
95  
96          // Set the int at the end of the first page and overlapping on the second page
97          // 2 bytes overlapping
98          storeMethod.invoke( recordManager, 18, 0x12345678, pageIos );
99  
100         // Read it back
101         readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 18 );
102 
103         assertEquals( 0x12345678, readValue );
104 
105         // Set the int at the end of the first page and overlapping on the second page
106         // 3 bytes overlapping
107         storeMethod.invoke( recordManager, 19, 0x12345678, pageIos );
108 
109         // Read it back
110         readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 19 );
111 
112         assertEquals( 0x12345678, readValue );
113 
114         // Set the int at the beginning of the second page
115         storeMethod.invoke( recordManager, 20, 0x12345678, pageIos );
116 
117         // Read it back
118         readValue = ( Integer ) readIntMethod.invoke( recordManager, pageIos, 20 );
119 
120         recordManager.close();
121     }
122 
123 
124     /**
125      * Test the readLong method
126      */
127     @Test
128     public void testReadLong() throws Exception
129     {
130         File tempFile = tempFolder.newFile( "mavibot.db" );
131         String tempFileName = tempFile.getAbsolutePath();
132 
133         // Create page size of 32 only
134         RecordManager recordManager = new RecordManager( tempFileName, 32 );
135         Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, long.class, PageIO[].class );
136         Method readLongMethod = RecordManager.class.getDeclaredMethod( "readLong", PageIO[].class, long.class );
137         storeMethod.setAccessible( true );
138         readLongMethod.setAccessible( true );
139 
140         // Allocate some Pages
141         PageIO[] pageIos = new PageIO[2];
142         pageIos[0] = new PageIO();
143         pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
144         pageIos[1] = new PageIO();
145         pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
146 
147         // Set the int at the beginning
148         storeMethod.invoke( recordManager, 0, 0x0123456789ABCDEFL, pageIos );
149 
150         // Read it back
151         long readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 0 );
152 
153         assertEquals( 0x0123456789ABCDEFL, readValue );
154 
155         // Set the int at the end of the first page
156         storeMethod.invoke( recordManager, 12, 0x0123456789ABCDEFL, pageIos );
157 
158         // Read it back
159         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 12 );
160 
161         assertEquals( 0x0123456789ABCDEFL, readValue );
162 
163         // Set the int at the end of the first page and overlapping on the second page
164         // 1 byte overlapping
165         storeMethod.invoke( recordManager, 13, 0x0123456789ABCDEFL, pageIos );
166 
167         // Read it back
168         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 13 );
169 
170         assertEquals( 0x0123456789ABCDEFL, readValue );
171 
172         // Set the int at the end of the first page and overlapping on the second page
173         // 2 bytes overlapping
174         storeMethod.invoke( recordManager, 14, 0x0123456789ABCDEFL, pageIos );
175 
176         // Read it back
177         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 14 );
178 
179         assertEquals( 0x0123456789ABCDEFL, readValue );
180 
181         // Set the int at the end of the first page and overlapping on the second page
182         // 3 bytes overlapping
183         storeMethod.invoke( recordManager, 15, 0x0123456789ABCDEFL, pageIos );
184 
185         // Read it back
186         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 15 );
187 
188         assertEquals( 0x0123456789ABCDEFL, readValue );
189 
190         // Set the int at the end of the first page and overlapping on the second page
191         // 4 bytes overlapping
192         storeMethod.invoke( recordManager, 16, 0x0123456789ABCDEFL, pageIos );
193 
194         // Read it back
195         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 16 );
196 
197         assertEquals( 0x0123456789ABCDEFL, readValue );
198 
199         // Set the int at the end of the first page and overlapping on the second page
200         // 5 bytes overlapping
201         storeMethod.invoke( recordManager, 17, 0x0123456789ABCDEFL, pageIos );
202 
203         // Read it back
204         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 17 );
205 
206         assertEquals( 0x0123456789ABCDEFL, readValue );
207 
208         // Set the int at the end of the first page and overlapping on the second page
209         // 6 bytes overlapping
210         storeMethod.invoke( recordManager, 18, 0x0123456789ABCDEFL, pageIos );
211 
212         // Read it back
213         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 18 );
214 
215         assertEquals( 0x0123456789ABCDEFL, readValue );
216 
217         // Set the int at the end of the first page and overlapping on the second page
218         // 7 bytes overlapping
219         storeMethod.invoke( recordManager, 19, 0x0123456789ABCDEFL, pageIos );
220 
221         // Read it back
222         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 19 );
223 
224         assertEquals( 0x0123456789ABCDEFL, readValue );
225 
226         // Set the int at the beginning of the second page
227         storeMethod.invoke( recordManager, 20, 0x0123456789ABCDEFL, pageIos );
228 
229         // Read it back
230         readValue = ( Long ) readLongMethod.invoke( recordManager, pageIos, 20 );
231 
232         recordManager.close();
233     }
234 
235 
236     /**
237      * Test the readBytes() method
238      */
239     @Test
240     public void testReadBytes() throws Exception
241     {
242         File tempFile = tempFolder.newFile( "mavibot.db" );
243         String tempFileName = tempFile.getAbsolutePath();
244 
245         // We use smaller pages
246         RecordManager recordManager = new RecordManager( tempFileName, 32 );
247         Method storeMethod = RecordManager.class.getDeclaredMethod( "store", long.class, byte[].class, PageIO[].class );
248         Method readBytesMethod = RecordManager.class.getDeclaredMethod( "readBytes", PageIO[].class, long.class );
249         storeMethod.setAccessible( true );
250         readBytesMethod.setAccessible( true );
251 
252         // Allocate some Pages
253         PageIO[] pageIos = new PageIO[4];
254         pageIos[0] = new PageIO();
255         pageIos[0].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
256         pageIos[1] = new PageIO();
257         pageIos[1].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
258         pageIos[2] = new PageIO();
259         pageIos[2].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
260         pageIos[3] = new PageIO();
261         pageIos[3].setData( ByteBuffer.allocate( recordManager.getPageSize() ) );
262 
263         // We start with 4 bytes
264         byte[] bytes = new byte[]
265             { 0x01, 0x23, 0x45, 0x67 };
266 
267         // Set the bytes at the beginning
268         storeMethod.invoke( recordManager, 0L, bytes, pageIos );
269 
270         // Read the bytes back
271         ByteBuffer readBytes = ( ByteBuffer ) readBytesMethod.invoke( recordManager, pageIos, 0L );
272 
273         // The byte length
274         assertNotNull( readBytes );
275         assertEquals( 4, readBytes.limit() );
276         // The data
277         assertEquals( 0x01, readBytes.get() );
278         assertEquals( 0x23, readBytes.get() );
279         assertEquals( 0x45, readBytes.get() );
280         assertEquals( 0x67, readBytes.get() );
281 
282         // Set the bytes at the end of the first page
283         storeMethod.invoke( recordManager, 12L, bytes, pageIos );
284 
285         // Read the bytes back
286         readBytes = ( ByteBuffer ) readBytesMethod.invoke( recordManager, pageIos, 12L );
287 
288         // The byte length
289         assertNotNull( readBytes );
290         assertEquals( 4, readBytes.limit() );
291         // The data
292         assertEquals( 0x01, readBytes.get() );
293         assertEquals( 0x23, readBytes.get() );
294         assertEquals( 0x45, readBytes.get() );
295         assertEquals( 0x67, readBytes.get() );
296 
297         // Set A full page of bytes in the first page 
298         bytes = new byte[16];
299 
300         for ( int i = 0; i < 16; i++ )
301         {
302             bytes[i] = ( byte ) ( i + 1 );
303         }
304 
305         storeMethod.invoke( recordManager, 0L, bytes, pageIos );
306 
307         // Read the bytes back
308         readBytes = ( ByteBuffer ) readBytesMethod.invoke( recordManager, pageIos, 0L );
309 
310         // The byte length
311         assertNotNull( readBytes );
312         assertEquals( 16, readBytes.limit() );
313 
314         // The data
315         for ( int i = 0; i < 16; i++ )
316         {
317             assertEquals( i + 1, readBytes.get() );
318         }
319 
320         // Write the bytes over 2 pages
321         storeMethod.invoke( recordManager, 15L, bytes, pageIos );
322 
323         // Read the bytes back
324         readBytes = ( ByteBuffer ) readBytesMethod.invoke( recordManager, pageIos, 15L );
325 
326         // The byte length
327         assertNotNull( readBytes );
328         assertEquals( 16, readBytes.limit() );
329         // The data
330         for ( int i = 0; i < 16; i++ )
331         {
332             assertEquals( i + 1, readBytes.get() );
333         }
334 
335         // Write the bytes over 4 pages
336         bytes = new byte[80];
337 
338         for ( int i = 0; i < 80; i++ )
339         {
340             bytes[i] = ( byte ) ( i + 1 );
341         }
342 
343         storeMethod.invoke( recordManager, 2L, bytes, pageIos );
344 
345         // Read the bytes back
346         readBytes = ( ByteBuffer ) readBytesMethod.invoke( recordManager, pageIos, 2L );
347 
348         // The byte length
349         assertNotNull( readBytes );
350         assertEquals( 80, readBytes.limit() );
351 
352         // The data
353         for ( int i = 0; i < 80; i++ )
354         {
355             assertEquals( i + 1, readBytes.get() );
356         }
357 
358         recordManager.close();
359     }
360 }