1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.directory.server.core.partition.impl.btree.jdbm;
20
21
22 import org.slf4j.Logger;
23 import org.slf4j.LoggerFactory;
24 import org.junit.Before;
25 import org.junit.After;
26 import org.junit.Test;
27 import static org.junit.Assert.*;
28
29 import org.apache.directory.server.xdbm.Table;
30 import org.apache.directory.server.xdbm.Tuple;
31 import org.apache.directory.server.core.cursor.Cursor;
32 import org.apache.directory.server.schema.SerializableComparator;
33 import org.apache.directory.server.schema.registries.ComparatorRegistry;
34 import org.apache.directory.shared.ldap.schema.syntax.ComparatorDescription;
35
36 import java.io.File;
37 import java.util.Comparator;
38 import java.util.Iterator;
39
40 import jdbm.RecordManager;
41 import jdbm.helper.IntegerSerializer;
42 import jdbm.recman.BaseRecordManager;
43
44 import javax.naming.NamingException;
45
46
47
48
49
50
51
52
53 public class JdbmTableWithDuplicatesTest
54 {
55 private static final Logger LOG = LoggerFactory.getLogger( JdbmTableWithDuplicatesTest.class.getSimpleName() );
56 private static final String TEST_OUTPUT_PATH = "test.output.path";
57 private static final int SIZE = 15;
58
59 transient Table<Integer,Integer> table;
60 transient File dbFile;
61 transient RecordManager recman;
62
63
64 @Before
65 public void createTable() throws Exception
66 {
67 destryTable();
68 File tmpDir = null;
69 if ( System.getProperty( TEST_OUTPUT_PATH, null ) != null )
70 {
71 tmpDir = new File( System.getProperty( TEST_OUTPUT_PATH ) );
72 }
73
74 dbFile = File.createTempFile( getClass().getSimpleName(), "db", tmpDir );
75 recman = new BaseRecordManager( dbFile.getAbsolutePath() );
76
77
78 SerializableComparator.setRegistry( new MockComparatorRegistry() );
79
80 table = new JdbmTable<Integer,Integer>( "test", SIZE, recman,
81 new SerializableComparator<Integer>( "" ),
82 new SerializableComparator<Integer>( "" ),
83 new IntegerSerializer(), new IntegerSerializer() );
84 LOG.debug( "Created new table and populated it with data" );
85 }
86
87
88 @After
89 public void destryTable() throws Exception
90 {
91 if ( table != null )
92 {
93 table.close();
94 }
95
96 table = null;
97
98 if ( recman != null )
99 {
100 recman.close();
101 }
102
103 recman = null;
104
105 if ( dbFile != null )
106 {
107 String fileToDelete = dbFile.getAbsolutePath();
108 new File( fileToDelete + ".db" ).delete();
109 new File( fileToDelete + ".lg" ).delete();
110
111 dbFile.delete();
112 }
113
114 dbFile = null;
115 }
116
117
118 @Test
119 public void testSerializers() throws Exception
120 {
121 assertNotNull( ( ( JdbmTable ) table ).getKeySerializer() );
122 assertNotNull( ( ( JdbmTable ) table ).getValueSerializer() );
123 }
124
125
126 @Test
127 public void testCountOneArg() throws Exception
128 {
129 assertEquals( 0, table.count( 3 ) );
130 assertEquals( 0, table.count( null ) );
131 }
132
133
134 @Test( expected = NullPointerException.class )
135 public void testNullKeyComparator() throws Exception
136 {
137 assertNotNull( ( ( JdbmTable ) table ).getKeyComparator() );
138 new JdbmTable<Integer,Integer>( "test", SIZE, recman,
139 null,
140 new SerializableComparator<Integer>( "" ),
141 null, new IntegerSerializer() );
142 }
143
144
145 @Test( expected = NullPointerException.class )
146 public void testNullValueComparator() throws Exception
147 {
148 assertNotNull( ( ( JdbmTable ) table ).getValueComparator() );
149 new JdbmTable<Integer,Integer>( "test", SIZE, recman,
150 new SerializableComparator<Integer>( "" ),
151 null,
152 null, new IntegerSerializer() );
153 }
154
155
156 @Test
157 public void testCloseReopen() throws Exception
158 {
159 table.put( 1, 2 );
160 assertTrue( 2 == table.get( 1 ) );
161 table.close();
162 table = new JdbmTable<Integer,Integer>( "test", SIZE, recman,
163 new SerializableComparator<Integer>( "" ),
164 new SerializableComparator<Integer>( "" ),
165 new IntegerSerializer(), new IntegerSerializer() );
166 assertTrue( 2 == table.get( 1 ) );
167 }
168
169
170 @Test
171 public void testConfigMethods() throws Exception
172 {
173 assertTrue( table.isDupsEnabled() );
174 assertEquals( "test", table.getName() );
175 assertNotNull( table.getKeyComparator() );
176 }
177
178
179 @Test
180 public void testWhenEmpty() throws Exception
181 {
182
183 assertEquals( 0, table.count() );
184 assertEquals( 0, table.count( 1 ) );
185
186
187 assertNull( table.get( 0 ) );
188 assertNull( table.get( null ) );
189
190
191 table.remove( 1 );
192 assertFalse( table.has( 1 ) );
193
194
195 assertFalse( table.has( 1 ) );
196 assertFalse( table.has( 1, 0 ) );
197 assertFalse( table.hasGreaterOrEqual( 1 ) );
198 assertFalse( table.hasLessOrEqual( 1 ) );
199 assertFalse( table.hasGreaterOrEqual( 1, 0 ) );
200 assertFalse( table.hasLessOrEqual( 1, 0 ) );
201 }
202
203
204 @Test
205 public void testPut() throws Exception
206 {
207 final int SIZE = 15;
208
209 for ( int ii = 0; ii < SIZE; ii++ )
210 {
211 table.put( ii, ii );
212 }
213 assertEquals( SIZE, table.count() );
214 table.put( 0, 0 );
215 assertTrue( table.has( 0, 0 ) );
216
217
218 for ( int ii = 0; ii < SIZE*2; ii++ )
219 {
220 table.put( SIZE*2, ii );
221 }
222 assertEquals( SIZE*3, table.count() );
223
224 table.put( 0, 0 );
225 assertTrue( table.has( 0, 0 ) );
226
227 table.put( SIZE*2, 0 );
228 assertTrue( table.has( SIZE*2, 0 ) );
229 }
230
231
232 @Test
233 public void testHas() throws Exception
234 {
235 assertFalse( table.has( 1 ) );
236
237 for ( int ii = 0; ii < SIZE*2; ii++ )
238 {
239 table.put( 1, ii );
240 }
241 assertEquals( SIZE*2, table.count() );
242
243 assertTrue( table.has( 1 ) );
244 assertTrue( table.has( 1, 0 ) );
245 assertFalse( table.has( 1, SIZE*2 ) );
246
247 assertTrue( table.hasGreaterOrEqual( 1, 0 ) );
248 assertTrue( table.hasLessOrEqual( 1, 0 ) );
249 assertFalse( table.hasLessOrEqual( 1, -1 ) );
250
251 assertTrue( table.hasGreaterOrEqual( 1, SIZE*2 - 1 ) );
252 assertTrue( table.hasLessOrEqual( 1, SIZE*2 - 1 ) );
253 assertTrue( table.hasGreaterOrEqual( 1, SIZE*2 - 1 ) );
254 assertTrue( table.hasLessOrEqual( 1, SIZE*2 ) );
255 assertFalse( table.hasGreaterOrEqual( 1, SIZE*2 ) );
256 assertFalse( table.has( 1, SIZE*2 ) );
257
258
259 table.put( 1, SIZE*2 );
260
261 assertTrue( table.has( 1 ) );
262 assertTrue( table.has( 1, 0 ) );
263 assertTrue( table.has( 1, SIZE*2 ) );
264 assertFalse( table.has( null, null ) );
265
266 assertTrue( table.hasGreaterOrEqual( 1, 0 ) );
267 assertTrue( table.hasLessOrEqual( 1, 0 ) );
268 assertFalse( table.hasLessOrEqual( 1, -1 ) );
269 assertFalse( table.hasGreaterOrEqual( null, null ) );
270 assertFalse( table.hasLessOrEqual( null, null ) );
271
272 assertTrue( table.hasGreaterOrEqual( 1, SIZE*2 ) );
273 assertTrue( table.hasLessOrEqual( 1, SIZE*2 ) );
274 assertTrue( table.hasGreaterOrEqual( 1, SIZE*2 ) );
275 assertTrue( table.hasLessOrEqual( 1, SIZE*2 + 1 ) );
276 assertFalse( table.hasGreaterOrEqual( 1, SIZE*2 + 1 ) );
277 assertFalse( table.has( 1, SIZE*2 + 1 ) );
278
279
280 for ( int ii = 0; ii < SIZE; ii++ )
281 {
282
283 table.put( ii, ii );
284 }
285
286 assertFalse( table.has( -1 ) );
287 assertTrue( table.hasGreaterOrEqual( -1 ) );
288 assertFalse( table.hasLessOrEqual( -1 ) );
289
290 assertTrue( table.has( 0 ) );
291 assertTrue( table.hasGreaterOrEqual( 0 ) );
292 assertTrue( table.hasLessOrEqual( 0 ) );
293
294 assertTrue( table.has( SIZE - 1 ) );
295 assertTrue( table.hasGreaterOrEqual( SIZE - 1 ) );
296 assertTrue( table.hasLessOrEqual( SIZE - 1 ) );
297
298 assertFalse( table.has( SIZE ) );
299 assertFalse( table.hasGreaterOrEqual( SIZE ) );
300 assertTrue( table.hasLessOrEqual( SIZE ) );
301
302 for ( int ii = 0; ii < SIZE; ii++ )
303 {
304 if ( ii == 1 )
305 {
306 continue;
307 }
308 table.remove( ii, ii );
309 }
310
311
312 for ( int ii = 0; ii < SIZE * 2 + 1; ii++ )
313 {
314 table.remove( 1, ii );
315 }
316
317 Cursor<Tuple<Integer, Integer>> cursor = table.cursor();
318
319 cursor.beforeFirst();
320 while ( cursor.next() )
321 {
322
323 }
324
325 assertFalse( table.hasLessOrEqual( 1 ) );
326 assertFalse( table.hasLessOrEqual( 1, 10 ) );
327 assertFalse( table.hasGreaterOrEqual( 1 ) );
328 assertFalse( table.hasGreaterOrEqual( 1, 0 ) );
329
330 table.put( 1, 0 );
331
332 }
333
334
335 @Test
336 public void testRemove() throws Exception
337 {
338 assertEquals( 0, table.count() );
339
340 table.put( 1, 1 );
341 table.put( 1, 2 );
342 assertEquals( 2, table.count() );
343 table.remove( 1 );
344 assertFalse( table.has( 1 ) );
345 assertEquals( 0, table.count() );
346
347 table.put( 10, 10 );
348 assertEquals( 1, table.count() );
349 table.remove( 10, 11 );
350 assertFalse( table.has( 10, 11 ) );
351 assertEquals( 1, table.count() );
352 table.remove( 10, 10 );
353 assertFalse( table.has( 10, 10 ) );
354 assertEquals( 0, table.count() );
355
356
357 for ( int ii = 0; ii < SIZE*2; ii++ )
358 {
359 table.put( 0, ii );
360 }
361
362 assertEquals( SIZE*2, table.count() );
363 table.remove( 0, 100 );
364 assertFalse( table.has( 0, 100 ) );
365 assertEquals( SIZE*2, table.count() );
366
367 table.remove( 0 );
368 assertNull( table.get( 0 ) );
369 }
370
371
372 @Test
373 public void testLoadData() throws Exception
374 {
375
376 for ( int ii = 0; ii < SIZE; ii++ )
377 {
378 table.put( ii, ii );
379 }
380
381 assertEquals( 15, table.count() );
382 assertEquals( 1, table.count( 0 ) );
383
384
385
386
387
388
389
390 if ( table.isCountExact() )
391 {
392 assertEquals( 5, table.lessThanCount( 5 ) );
393 assertEquals( 9, table.greaterThanCount( 5 ) );
394 }
395 else
396 {
397 assertEquals( SIZE, table.lessThanCount( 5 ) );
398 assertEquals( SIZE, table.greaterThanCount( 5 ) );
399 }
400 }
401
402
403 @Test
404 public void testDuplicateLimit() throws Exception
405 {
406 for ( int ii = 0; ii < SIZE; ii++ )
407 {
408 table.put( 1, ii );
409 }
410 assertEquals( SIZE, table.count() );
411 assertEquals( SIZE, table.count( 1 ) );
412
413
414 table.put( 1, SIZE );
415 assertEquals( SIZE + 1, table.count() );
416 assertEquals( SIZE + 1, table.count( 1 ) );
417
418
419 table.put( 1, SIZE + 1 );
420 assertEquals( SIZE + 2, table.count() );
421 assertEquals( SIZE + 2, table.count( 1 ) );
422 assertEquals( 0, ( int ) table.get( 1 ) );
423
424
425 table.remove( 1, SIZE + 1 );
426 assertFalse( table.has( 1, SIZE + 1 ) );
427 assertTrue( table.has( 1, SIZE ) );
428 assertEquals( SIZE + 1, table.count() );
429 assertEquals( SIZE + 1, table.count( 1 ) );
430
431
432 table.remove( 1, SIZE );
433 assertFalse( table.has( 1, SIZE ) );
434 assertEquals( SIZE, table.count() );
435 assertEquals( SIZE, table.count( 1 ) );
436 assertTrue( 0 == table.get( 1 ) );
437
438 for ( int ii = SIZE - 1; ii >= 0; ii-- )
439 {
440 table.remove( 1, ii );
441 }
442 assertEquals( 0, table.count() );
443
444 for ( int ii = 0; ii < SIZE - 1; ii++ )
445 {
446 table.put( 1, ii );
447 }
448 assertEquals( SIZE - 1, table.count() );
449 table.remove( 1 );
450 assertEquals( 0, table.count() );
451 }
452
453
454
455
456
457
458 @Test
459 public void testNullOrEmptyKeyValueAfterDuplicateLimit() throws Exception
460 {
461 testDuplicateLimit();
462 assertEquals( 0, table.count() );
463
464 try
465 {
466 table.put( 1, null );
467 fail( "should never get here due to IllegalArgumentException" );
468 }
469 catch( IllegalArgumentException e )
470 {
471 assertNotNull( e );
472 }
473
474 try
475 {
476 table.put( null, 1 );
477 fail( "should never get here due to IllegalArgumentException" );
478 }
479 catch( IllegalArgumentException e )
480 {
481 assertNotNull( e );
482 }
483
484 assertEquals( 0, table.count() );
485 assertEquals( null, table.get( 1 ) );
486
487
488 table.remove( 1 );
489 table.put( 1, 1 );
490 table.put( 1, 2 );
491 assertEquals( 2, table.count( 1 ) );
492 table.remove( 1, 1 );
493 assertEquals( 1, table.count( 1 ) );
494 assertTrue( 2 == table.get( 1 ) );
495
496 table.remove( 1, 2 );
497 assertNull( table.get( 1 ) );
498 assertEquals( 0, table.count( 1 ) );
499 assertFalse( table.has( 1 ) );
500 }
501
502
503 @Test
504 public void testMiscellaneous() throws Exception
505 {
506 assertNotNull( ( ( JdbmTable ) table ).getMarshaller() );
507 ( ( JdbmTable ) table ).close();
508
509
510 table = new JdbmTable<Integer,Integer>( "test", SIZE, recman,
511 new SerializableComparator<Integer>( "" ),
512 new SerializableComparator<Integer>( "" ),
513 new IntegerSerializer(), null );
514 assertNull( ( ( JdbmTable ) table ).getValueSerializer() );
515 for ( int ii = 0; ii < SIZE + 1; ii++ )
516 {
517 table.put( 0, ii );
518 }
519 table.remove( 0 );
520 assertFalse( table.has( 0 ) );
521 }
522
523
524
525
526
527
528 @Test
529 public void testNullOrEmptyKeyValue() throws Exception
530 {
531 assertEquals( 0, table.count() );
532
533 try
534 {
535 table.put( 1, null );
536 fail( "should never get here due to IllegalArgumentException" );
537 }
538 catch( IllegalArgumentException e )
539 {
540 assertNotNull( e );
541 }
542
543 try
544 {
545 table.put( null, 2 );
546 fail( "should never get here due to IllegalArgumentException" );
547 }
548 catch( IllegalArgumentException e )
549 {
550 assertNotNull( e );
551 }
552
553 assertEquals( 0, table.count() );
554 assertEquals( null, table.get( 1 ) );
555
556
557 table.remove( 1 );
558 table.put( 1, 1 );
559 table.put( 1, 2 );
560 assertEquals( 2, table.count( 1 ) );
561 table.remove( 1, 1 );
562 assertEquals( 1, table.count( 1 ) );
563 assertTrue( 2 == table.get( 1 ) );
564
565 table.remove( 1, 2 );
566 assertNull( table.get( 1 ) );
567 assertEquals( 0, table.count( 1 ) );
568 assertFalse( table.has( 1 ) );
569 }
570
571
572 private class MockComparatorRegistry implements ComparatorRegistry
573 {
574 private Comparator<Integer> comparator = new Comparator<Integer>()
575 {
576 public int compare( Integer i1, Integer i2 )
577 {
578 return i1.compareTo( i2 );
579 }
580 };
581
582 public String getSchemaName( String oid ) throws NamingException
583 {
584 return null;
585 }
586
587
588 public void register( ComparatorDescription description, Comparator comparator ) throws NamingException
589 {
590 }
591
592
593 public Comparator lookup( String oid ) throws NamingException
594 {
595 return comparator;
596 }
597
598
599 public boolean hasComparator( String oid )
600 {
601 return true;
602 }
603
604
605 public Iterator<String> oidIterator()
606 {
607 return null;
608 }
609
610
611 public Iterator<ComparatorDescription> comparatorDescriptionIterator()
612 {
613 return null;
614 }
615
616
617 public void unregister( String oid ) throws NamingException
618 {
619 }
620
621
622 public void unregisterSchemaElements( String schemaName )
623 {
624 }
625
626
627 public void renameSchema( String originalSchemaName, String newSchemaName )
628 {
629 }
630 }
631 }