PageRenderTime 64ms CodeModel.GetById 29ms RepoModel.GetById 0ms app.codeStats 0ms

/jdbm-partition/src/test/java/org/apache/directory/server/core/partition/impl/btree/jdbm/DupsCursorTest.java

https://github.com/jdcasey/directory-server
Java | 1447 lines | 1123 code | 255 blank | 69 comment | 174 complexity | 1f044ed00383aaea12d82672593e87f0 MD5 | raw file
Possible License(s): Apache-2.0
  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. package org.apache.directory.server.core.partition.impl.btree.jdbm;
  20. import static org.junit.Assert.assertEquals;
  21. import static org.junit.Assert.assertFalse;
  22. import static org.junit.Assert.assertNotNull;
  23. import static org.junit.Assert.assertTrue;
  24. import static org.junit.Assert.fail;
  25. import java.io.File;
  26. import jdbm.RecordManager;
  27. import jdbm.helper.DefaultSerializer;
  28. import jdbm.recman.BaseRecordManager;
  29. import org.apache.directory.server.xdbm.Table;
  30. import org.apache.directory.shared.ldap.constants.SchemaConstants;
  31. import org.apache.directory.shared.ldap.cursor.Cursor;
  32. import org.apache.directory.shared.ldap.cursor.InvalidCursorPositionException;
  33. import org.apache.directory.shared.ldap.cursor.Tuple;
  34. import org.apache.directory.shared.ldap.schema.SchemaManager;
  35. import org.apache.directory.shared.ldap.schema.comparators.SerializableComparator;
  36. import org.apache.directory.shared.ldap.schema.ldif.extractor.SchemaLdifExtractor;
  37. import org.apache.directory.shared.ldap.schema.ldif.extractor.impl.DefaultSchemaLdifExtractor;
  38. import org.apache.directory.shared.ldap.schema.loader.ldif.LdifSchemaLoader;
  39. import org.apache.directory.shared.ldap.schema.manager.impl.DefaultSchemaManager;
  40. import org.apache.directory.shared.ldap.util.LdapExceptionUtils;
  41. import org.junit.After;
  42. import org.junit.Before;
  43. import org.junit.BeforeClass;
  44. import org.junit.Test;
  45. import org.slf4j.Logger;
  46. import org.slf4j.LoggerFactory;
  47. /**
  48. * Tests the Cursor functionality of a JdbmTable when duplicate keys are
  49. * supported.
  50. *
  51. * @author <a href="mailto:dev@directory.apache.org">Apache Directory Project</a>
  52. */
  53. public class DupsCursorTest
  54. {
  55. private static final Logger LOG = LoggerFactory.getLogger( DupsCursorTest.class.getSimpleName() );
  56. private static final String TEST_OUTPUT_PATH = "test.output.path";
  57. private static final int SIZE = 15;
  58. transient Table<String,String> table;
  59. transient File dbFile;
  60. transient RecordManager recman;
  61. private static SchemaManager schemaManager;
  62. @BeforeClass
  63. public static void init() throws Exception
  64. {
  65. String workingDirectory = System.getProperty( "workingDirectory" );
  66. if ( workingDirectory == null )
  67. {
  68. String path = DupsContainerCursorTest.class.getResource( "" ).getPath();
  69. int targetPos = path.indexOf( "target" );
  70. workingDirectory = path.substring( 0, targetPos + 6 );
  71. }
  72. File schemaRepository = new File( workingDirectory, "schema" );
  73. SchemaLdifExtractor extractor = new DefaultSchemaLdifExtractor( new File( workingDirectory ) );
  74. extractor.extractOrCopy( true );
  75. LdifSchemaLoader loader = new LdifSchemaLoader( schemaRepository );
  76. schemaManager = new DefaultSchemaManager( loader );
  77. boolean loaded = schemaManager.loadAllEnabled();
  78. if ( !loaded )
  79. {
  80. fail( "Schema load failed : " + LdapExceptionUtils.printErrors( schemaManager.getErrors() ) );
  81. }
  82. }
  83. @Before
  84. public void createTable() throws Exception
  85. {
  86. File tmpDir = null;
  87. if ( System.getProperty( TEST_OUTPUT_PATH, null ) != null )
  88. {
  89. tmpDir = new File( System.getProperty( TEST_OUTPUT_PATH ) );
  90. }
  91. dbFile = File.createTempFile( getClass().getSimpleName(), "db", tmpDir );
  92. recman = new BaseRecordManager( dbFile.getAbsolutePath() );
  93. SerializableComparator<String> comparator = new SerializableComparator<String>( SchemaConstants.INTEGER_ORDERING_MATCH_MR_OID );
  94. comparator.setSchemaManager( schemaManager );
  95. table = new JdbmTable<String,String>( schemaManager, "test", SIZE, recman,
  96. comparator, comparator, null, new DefaultSerializer() );
  97. LOG.debug( "Created new table and populated it with data" );
  98. }
  99. @After
  100. public void destryTable() throws Exception
  101. {
  102. table.close();
  103. table = null;
  104. recman.close();
  105. recman = null;
  106. dbFile.deleteOnExit();
  107. // Remove temporary files
  108. String fileToDelete = dbFile.getAbsolutePath();
  109. new File( fileToDelete ).delete();
  110. new File( fileToDelete + ".db" ).delete();
  111. new File( fileToDelete + ".lg" ).delete();
  112. dbFile = null;
  113. }
  114. @Test
  115. public void testEmptyTableOperations() throws Exception
  116. {
  117. Cursor<Tuple<String,String>> cursor = table.cursor();
  118. assertFalse( cursor.next() );
  119. cursor.afterLast();
  120. assertFalse( cursor.previous() );
  121. cursor.beforeFirst();
  122. assertFalse( cursor.next() );
  123. assertFalse( cursor.first() );
  124. assertFalse( cursor.last() );
  125. }
  126. @Test
  127. public void testNextNoDups() throws Exception
  128. {
  129. // first try without duplicates at all
  130. for ( int i = 0; i < SIZE-1; i++ )
  131. {
  132. String istr = Integer.toString( i );
  133. table.put( istr, istr );
  134. }
  135. Cursor<Tuple<String,String>> cursor = table.cursor();
  136. int i = 0;
  137. while ( cursor.next() )
  138. {
  139. Tuple<String,String> tuple = cursor.get();
  140. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  141. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  142. i++;
  143. }
  144. }
  145. @Test
  146. public void testPreviousNoDups() throws Exception
  147. {
  148. for ( int i = 0; i < SIZE-1; i++ )
  149. {
  150. String istr = Integer.toString( i );
  151. table.put( istr, istr );
  152. }
  153. Cursor<Tuple<String,String>> cursor = table.cursor();
  154. int i = SIZE-2;
  155. while ( cursor.previous() )
  156. {
  157. Tuple<String,String> tuple = cursor.get();
  158. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  159. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  160. i--;
  161. }
  162. }
  163. @Test
  164. public void testNextDups() throws Exception
  165. {
  166. for ( int i = 0; i < SIZE*3; i++ )
  167. {
  168. String istr = Integer.toString( i );
  169. if ( i > 12 && i < 17 + SIZE )
  170. {
  171. table.put( "13", istr );
  172. }
  173. else
  174. {
  175. table.put( istr, istr );
  176. }
  177. }
  178. Cursor<Tuple<String,String>> cursor = table.cursor();
  179. int i = 0;
  180. while ( cursor.next() )
  181. {
  182. Tuple<String,String> tuple = cursor.get();
  183. if ( i > 12 && i < 17 + SIZE )
  184. {
  185. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  186. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  187. }
  188. else
  189. {
  190. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  191. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  192. }
  193. i++;
  194. }
  195. }
  196. @Test
  197. public void testPreviousDups() throws Exception
  198. {
  199. for ( int i = 0; i < SIZE*3; i++ )
  200. {
  201. String istr = Integer.toString( i );
  202. if ( i > 12 && i < 17 + SIZE )
  203. {
  204. table.put( "13", Integer.toString( i ) );
  205. }
  206. else
  207. {
  208. table.put( istr, istr );
  209. }
  210. }
  211. Cursor<Tuple<String,String>> cursor = table.cursor();
  212. cursor.afterLast();
  213. int i = SIZE*3 - 1;
  214. while ( cursor.previous() )
  215. {
  216. Tuple<String,String> tuple = cursor.get();
  217. if ( i > 12 && i < 17 + SIZE )
  218. {
  219. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  220. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  221. }
  222. else
  223. {
  224. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  225. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  226. }
  227. i--;
  228. }
  229. }
  230. @Test
  231. public void testFirstLastUnderDupLimit() throws Exception
  232. {
  233. for ( int i = 0; i < SIZE*2 - 1; i++ )
  234. {
  235. String istr = Integer.toString( i );
  236. if ( i > 12 && i < 17 )
  237. {
  238. table.put( "13", istr );
  239. }
  240. else
  241. {
  242. table.put( istr, istr );
  243. }
  244. }
  245. Cursor<Tuple<String,String>> cursor = table.cursor();
  246. int i = 0;
  247. while ( cursor.next() )
  248. {
  249. Tuple<String,String> tuple = cursor.get();
  250. if ( i > 12 && i < 17 )
  251. {
  252. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  253. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  254. }
  255. else
  256. {
  257. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  258. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  259. }
  260. i++;
  261. }
  262. cursor.first();
  263. i = 0;
  264. do
  265. {
  266. Tuple<String,String> tuple = cursor.get();
  267. if ( i > 12 && i < 17 )
  268. {
  269. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  270. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  271. }
  272. else
  273. {
  274. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  275. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  276. }
  277. i++;
  278. }
  279. while ( cursor.next() );
  280. // now go backwards
  281. cursor.afterLast();
  282. i = SIZE*2-2;
  283. while ( cursor.previous() )
  284. {
  285. Tuple<String,String> tuple = cursor.get();
  286. if ( i > 12 && i < 17 )
  287. {
  288. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  289. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  290. }
  291. else
  292. {
  293. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  294. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  295. }
  296. i--;
  297. }
  298. // now advance to last and go backwards again
  299. cursor.last();
  300. i = SIZE*2-2;
  301. do
  302. {
  303. Tuple<String,String> tuple = cursor.get();
  304. if ( i > 12 && i < 17 )
  305. {
  306. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  307. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  308. }
  309. else
  310. {
  311. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  312. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  313. }
  314. i--;
  315. }
  316. while ( cursor.previous() );
  317. // advance to first then last and go backwards again
  318. cursor.beforeFirst();
  319. cursor.afterLast();
  320. i = SIZE*2-2;
  321. while ( cursor.previous() )
  322. {
  323. Tuple<String,String> tuple = cursor.get();
  324. if ( i > 12 && i < 17 )
  325. {
  326. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  327. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  328. }
  329. else
  330. {
  331. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  332. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  333. }
  334. i--;
  335. }
  336. }
  337. @Test
  338. public void testFirstLastOverDupLimit() throws Exception
  339. {
  340. for ( int i = 0; i < SIZE*3-1; i++ )
  341. {
  342. String istr = Integer.toString( i );
  343. if ( i < 2 + SIZE ) // keys with multiple values
  344. {
  345. table.put( "0", istr );
  346. }
  347. else // keys with single values
  348. {
  349. table.put( istr, istr );
  350. }
  351. }
  352. Cursor<Tuple<String,String>> cursor = table.cursor();
  353. int i = 0;
  354. while ( cursor.next() )
  355. {
  356. Tuple<String,String> tuple = cursor.get();
  357. if ( i < 2 + SIZE )
  358. {
  359. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  360. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  361. }
  362. else
  363. {
  364. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  365. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  366. }
  367. i++;
  368. }
  369. // now go back to first and traverse all over again
  370. cursor.first();
  371. i = 0;
  372. do
  373. {
  374. Tuple<String,String> tuple = cursor.get();
  375. if ( i < 2 + SIZE )
  376. {
  377. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  378. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  379. }
  380. else
  381. {
  382. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  383. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  384. }
  385. i++;
  386. }
  387. while ( cursor.next() );
  388. // now go backwards
  389. cursor.afterLast();
  390. i = SIZE*3-2;
  391. while ( cursor.previous() )
  392. {
  393. Tuple<String,String> tuple = cursor.get();
  394. if ( i < 2 + SIZE )
  395. {
  396. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  397. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  398. }
  399. else
  400. {
  401. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  402. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  403. }
  404. i--;
  405. }
  406. // now advance to last and go backwards again
  407. cursor.last();
  408. i = SIZE*3-2;
  409. do
  410. {
  411. Tuple<String,String> tuple = cursor.get();
  412. if ( i < 2 + SIZE )
  413. {
  414. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  415. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  416. }
  417. else
  418. {
  419. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  420. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  421. }
  422. i--;
  423. }
  424. while ( cursor.previous() );
  425. // advance to first then last and go backwards again
  426. cursor.beforeFirst();
  427. cursor.afterLast();
  428. i = SIZE*3-2;
  429. while ( cursor.previous() )
  430. {
  431. Tuple<String,String> tuple = cursor.get();
  432. if ( i < 2 + SIZE )
  433. {
  434. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  435. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  436. }
  437. else
  438. {
  439. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  440. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  441. }
  442. i--;
  443. }
  444. }
  445. @Test
  446. public void testFirstOverDupLimit() throws Exception
  447. {
  448. for ( int i = 0; i < SIZE*3-1; i++ )
  449. {
  450. String istr = Integer.toString( i );
  451. if ( i < 2 + SIZE ) // keys with multiple values
  452. {
  453. table.put( "0", istr );
  454. }
  455. else // keys with single values
  456. {
  457. table.put( istr, istr );
  458. }
  459. }
  460. Cursor<Tuple<String,String>> cursor = table.cursor();
  461. int i = 0;
  462. while ( cursor.next() )
  463. {
  464. Tuple<String,String> tuple = cursor.get();
  465. if ( i < 2 + SIZE )
  466. {
  467. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  468. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  469. }
  470. else
  471. {
  472. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  473. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  474. }
  475. i++;
  476. }
  477. // now go back to first and traverse all over again
  478. cursor.first();
  479. i = 0;
  480. do
  481. {
  482. Tuple<String,String> tuple = cursor.get();
  483. if ( i < 2 + SIZE )
  484. {
  485. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  486. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  487. }
  488. else
  489. {
  490. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  491. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  492. }
  493. i++;
  494. }
  495. while ( cursor.next() );
  496. // now go backwards
  497. cursor.afterLast();
  498. i = SIZE*3-2;
  499. while ( cursor.previous() )
  500. {
  501. Tuple<String,String> tuple = cursor.get();
  502. if ( i < 2 + SIZE )
  503. {
  504. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  505. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  506. }
  507. else
  508. {
  509. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  510. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  511. }
  512. i--;
  513. }
  514. // now advance to last and go backwards again
  515. cursor.last();
  516. i = SIZE*3-2;
  517. do
  518. {
  519. Tuple<String,String> tuple = cursor.get();
  520. if ( i < 2 + SIZE )
  521. {
  522. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  523. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  524. }
  525. else
  526. {
  527. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  528. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  529. }
  530. i--;
  531. }
  532. while ( cursor.previous() );
  533. // advance to first then last and go backwards again
  534. cursor.beforeFirst();
  535. cursor.afterLast();
  536. i = SIZE*3-2;
  537. while ( cursor.previous() )
  538. {
  539. Tuple<String,String> tuple = cursor.get();
  540. if ( i < 2 + SIZE )
  541. {
  542. assertEquals( 0, Integer.parseInt( tuple.getKey() ) );
  543. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  544. }
  545. else
  546. {
  547. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  548. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  549. }
  550. i--;
  551. }
  552. }
  553. @Test
  554. public void testLastOverDupLimit() throws Exception
  555. {
  556. for ( int i = 0; i < SIZE*3-1; i++ )
  557. {
  558. String istr = Integer.toString( i );
  559. if ( i > 2 + SIZE ) // keys with multiple values
  560. {
  561. table.put( Integer.toString( 3 + SIZE ), istr );
  562. }
  563. else // keys with single values
  564. {
  565. table.put( istr, istr );
  566. }
  567. }
  568. Cursor<Tuple<String,String>> cursor = table.cursor();
  569. int i = 0;
  570. while ( cursor.next() )
  571. {
  572. Tuple<String,String> tuple = cursor.get();
  573. if ( i > 2 + SIZE )
  574. {
  575. assertEquals( 3 + SIZE, Integer.parseInt( tuple.getKey() ) );
  576. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  577. }
  578. else
  579. {
  580. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  581. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  582. }
  583. i++;
  584. }
  585. // now go back to first and traverse all over again
  586. cursor.first();
  587. i = 0;
  588. do
  589. {
  590. Tuple<String,String> tuple = cursor.get();
  591. if ( i > 2 + SIZE )
  592. {
  593. assertEquals( 3 + SIZE, Integer.parseInt( tuple.getKey() ) );
  594. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  595. }
  596. else
  597. {
  598. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  599. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  600. }
  601. i++;
  602. }
  603. while ( cursor.next() );
  604. // now go backwards
  605. cursor.afterLast();
  606. i = SIZE*3-2;
  607. while ( cursor.previous() )
  608. {
  609. Tuple<String,String> tuple = cursor.get();
  610. if ( i > 2 + SIZE )
  611. {
  612. assertEquals( 3 + SIZE, Integer.parseInt( tuple.getKey() ) );
  613. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  614. }
  615. else
  616. {
  617. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  618. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  619. }
  620. i--;
  621. }
  622. // now advance to last and go backwards again
  623. cursor.last();
  624. i = SIZE*3-2;
  625. do
  626. {
  627. Tuple<String,String> tuple = cursor.get();
  628. if ( i > 2 + SIZE )
  629. {
  630. assertEquals( 3 + SIZE, Integer.parseInt( tuple.getKey() ) );
  631. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  632. }
  633. else
  634. {
  635. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  636. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  637. }
  638. i--;
  639. }
  640. while ( cursor.previous() );
  641. // advance to first then last and go backwards again
  642. cursor.beforeFirst();
  643. cursor.afterLast();
  644. i = SIZE*3-2;
  645. while ( cursor.previous() )
  646. {
  647. Tuple<String,String> tuple = cursor.get();
  648. if ( i > 2 + SIZE )
  649. {
  650. assertEquals( 3 + SIZE, Integer.parseInt( tuple.getKey() ) );
  651. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  652. }
  653. else
  654. {
  655. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  656. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  657. }
  658. i--;
  659. }
  660. }
  661. @Test
  662. public void testOnEmptyTable() throws Exception
  663. {
  664. Cursor<Tuple<String,String>> cursor = table.cursor();
  665. assertNotNull( cursor );
  666. assertFalse( cursor.isClosed() );
  667. cursor.before( new Tuple<String, String>( "1", "2" ) );
  668. assertFalse( cursor.available() );
  669. }
  670. @Test
  671. public void testOverDupLimit() throws Exception
  672. {
  673. table.put( "5", "5" );
  674. table.put( "6", "6" );
  675. for ( int i = 0; i < 20; i++ )
  676. {
  677. table.put( "7", Integer.toString( i ) );
  678. }
  679. table.put( "8", "8" );
  680. table.put( "9", "9" );
  681. Cursor<Tuple<String,String>> cursor = table.cursor();
  682. assertNotNull( cursor );
  683. assertFalse( cursor.isClosed() );
  684. cursor.before( new Tuple<String, String>( "7", "2" ) );
  685. assertFalse( cursor.available() );
  686. }
  687. @Test
  688. public void testUnderDupLimit() throws Exception
  689. {
  690. table.put( "5", "5" );
  691. table.put( "6", "6" );
  692. for ( int i = 0; i < 10; i++ )
  693. {
  694. table.put( "7", Integer.toString( i ) );
  695. }
  696. table.put( "8", "8" );
  697. table.put( "9", "9" );
  698. Cursor<Tuple<String,String>> cursor = table.cursor();
  699. assertNotNull( cursor );
  700. assertFalse( cursor.isClosed() );
  701. cursor.before( new Tuple<String, String>( "7", "2" ) );
  702. assertFalse( cursor.available() );
  703. }
  704. @Test
  705. public void testBeforeAfterBelowDupLimit() throws Exception
  706. {
  707. for ( int i = 0; i < SIZE*2 - 1; i++ )
  708. {
  709. String istr = Integer.toString( i );
  710. if ( i > 12 && i < 17 ) // keys with multiple values
  711. {
  712. table.put( "13", Integer.toString( i ) );
  713. }
  714. else if ( i > 17 && i < 21 ) // adds hole with no keys for i
  715. {
  716. }
  717. else // keys with single values
  718. {
  719. table.put( istr, istr );
  720. }
  721. }
  722. // test before to advance just before a key with a single value
  723. int i = 5;
  724. Cursor<Tuple<String,String>> cursor = table.cursor();
  725. cursor.before( new Tuple<String,String>( "5", "5" ) );
  726. while ( cursor.next() )
  727. {
  728. if ( i > 17 && i < 21 )
  729. {
  730. assertFalse( table.has( Integer.toString( i ) ) );
  731. continue;
  732. }
  733. Tuple<String,String> tuple = cursor.get();
  734. if ( i > 12 && i < 17 )
  735. {
  736. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  737. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  738. }
  739. else
  740. {
  741. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  742. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  743. }
  744. i++;
  745. }
  746. // test before to advance just before a key with a single value but
  747. // with a null tuple value which should not advance the dupsCursor
  748. i = 5;
  749. cursor = table.cursor();
  750. cursor.before( new Tuple<String,String>( "5", null ) );
  751. while ( cursor.next() )
  752. {
  753. if ( i > 17 && i < 21 )
  754. {
  755. assertFalse( table.has( Integer.toString( i ) ) );
  756. continue;
  757. }
  758. Tuple<String,String> tuple = cursor.get();
  759. if ( i > 12 && i < 17 )
  760. {
  761. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  762. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  763. }
  764. else
  765. {
  766. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  767. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  768. }
  769. i++;
  770. }
  771. // test before to advance just before a key value pair where the key
  772. // does not exist - using value so we hit check for key equality
  773. i = 21;
  774. cursor = table.cursor();
  775. cursor.before( new Tuple<String,String>( "18", "18" ) );
  776. while ( cursor.next() )
  777. {
  778. if ( i > 17 && i < 21 )
  779. {
  780. assertFalse( table.has( Integer.toString( i ) ) );
  781. continue;
  782. }
  783. Tuple<String,String> tuple = cursor.get();
  784. if ( i > 12 && i < 17 )
  785. {
  786. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  787. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  788. }
  789. else
  790. {
  791. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  792. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  793. }
  794. i++;
  795. }
  796. // test after to advance just after the end
  797. cursor = table.cursor();
  798. cursor.after( new Tuple<String,String>( "111", null ) );
  799. assertFalse( cursor.next() );
  800. // test after to advance just before a key with a single value
  801. i = 6;
  802. cursor = table.cursor();
  803. cursor.after( new Tuple<String,String>( "5", null ) );
  804. while ( cursor.next() )
  805. {
  806. if ( i > 17 && i < 21 )
  807. {
  808. assertFalse( table.has( Integer.toString( i ) ) );
  809. continue;
  810. }
  811. Tuple<String,String> tuple = cursor.get();
  812. if ( i > 12 && i < 17 )
  813. {
  814. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  815. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  816. }
  817. else
  818. {
  819. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  820. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  821. }
  822. i++;
  823. }
  824. // test before to advance just before a key & value with multiple
  825. // values for the key - we should advance just before the value
  826. cursor = table.cursor();
  827. cursor.before( new Tuple<String,String>( "13", "14" ) );
  828. cursor.next();
  829. Tuple<String,String> tuple = cursor.get();
  830. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  831. assertEquals( 14, Integer.parseInt( tuple.getValue() ) );
  832. i = 15;
  833. while ( cursor.next() )
  834. {
  835. if ( i > 17 && i < 21 )
  836. {
  837. assertFalse( table.has( Integer.toString( i ) ) );
  838. continue;
  839. }
  840. tuple = cursor.get();
  841. if ( i > 12 && i < 17 )
  842. {
  843. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  844. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  845. }
  846. else
  847. {
  848. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  849. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  850. }
  851. i++;
  852. }
  853. // test after to advance just before a key & value with multiple
  854. // values for the key - we should advance just before the value
  855. cursor = table.cursor();
  856. cursor.after( new Tuple<String,String>( "13", "14" ) );
  857. cursor.next();
  858. tuple = cursor.get();
  859. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  860. assertEquals( 15, Integer.parseInt( tuple.getValue() ) );
  861. i=16;
  862. while ( cursor.next() )
  863. {
  864. if ( i > 17 && i < 21 )
  865. {
  866. assertFalse( table.has( Integer.toString( i ) ) );
  867. continue;
  868. }
  869. tuple = cursor.get();
  870. if ( i > 12 && i < 17 )
  871. {
  872. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  873. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  874. }
  875. else
  876. {
  877. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  878. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  879. }
  880. i++;
  881. }
  882. // test after to advance just before a key that does not exist
  883. cursor = table.cursor();
  884. cursor.after( new Tuple<String,String>( "18", null ) );
  885. cursor.next();
  886. tuple = cursor.get();
  887. assertEquals( 21, Integer.parseInt( tuple.getKey() ) );
  888. assertEquals( 21, Integer.parseInt( tuple.getValue() ) );
  889. i=22;
  890. while ( cursor.next() )
  891. {
  892. if ( i > 17 && i < 21 )
  893. {
  894. assertFalse( table.has( Integer.toString( i ) ) );
  895. continue;
  896. }
  897. tuple = cursor.get();
  898. if ( i > 12 && i < 17 )
  899. {
  900. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  901. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  902. }
  903. else
  904. {
  905. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  906. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  907. }
  908. i++;
  909. }
  910. // test after to advance just before a key and value where the key
  911. // does not exist - used to force key comparison in after()
  912. cursor = table.cursor();
  913. cursor.after( new Tuple<String,String>( "18", "18" ) );
  914. cursor.next();
  915. tuple = cursor.get();
  916. assertEquals( 21, Integer.parseInt( tuple.getKey() ) );
  917. assertEquals( 21, Integer.parseInt( tuple.getValue() ) );
  918. i=22;
  919. while ( cursor.next() )
  920. {
  921. if ( i > 17 && i < 21 )
  922. {
  923. assertFalse( table.has( Integer.toString( i ) ) );
  924. continue;
  925. }
  926. tuple = cursor.get();
  927. if ( i > 12 && i < 17 )
  928. {
  929. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  930. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  931. }
  932. else
  933. {
  934. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  935. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  936. }
  937. i++;
  938. }
  939. }
  940. @Test
  941. public void testBeforeAfterOverDupLimit() throws Exception
  942. {
  943. for ( int i = 0; i < SIZE*3 - 1; i++ )
  944. {
  945. String istr = Integer.toString( i );
  946. if ( i > 12 && i < 17 + SIZE ) // keys with multiple values
  947. {
  948. table.put( "13", Integer.toString( i ) );
  949. }
  950. else if ( i > 17 + SIZE && i < 21 + SIZE ) // adds hole with no keys for i
  951. {
  952. }
  953. else // keys with single values
  954. {
  955. table.put( istr, istr );
  956. }
  957. }
  958. // test before to advance just before a key with a single value
  959. int i = 5;
  960. Cursor<Tuple<String,String>> cursor = table.cursor();
  961. cursor.before( new Tuple<String,String>( "5", "5" ) );
  962. while ( cursor.next() )
  963. {
  964. if ( i > 17 + SIZE && i < 21 + SIZE )
  965. {
  966. assertFalse( table.has( Integer.toString( i ) ) );
  967. continue;
  968. }
  969. Tuple<String,String> tuple = cursor.get();
  970. if ( i > 12 && i < 17 + SIZE )
  971. {
  972. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  973. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  974. }
  975. else
  976. {
  977. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  978. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  979. }
  980. i++;
  981. }
  982. // test before to advance just before a key with a single value but
  983. // with a null tuple value which should not advance the dupsCursor
  984. i = 5;
  985. cursor = table.cursor();
  986. cursor.before( new Tuple<String,String>( "5", null ) );
  987. while ( cursor.next() )
  988. {
  989. if ( i > 17 + SIZE && i < 21 + SIZE )
  990. {
  991. assertFalse( table.has( Integer.toString( i ) ) );
  992. continue;
  993. }
  994. Tuple<String,String> tuple = cursor.get();
  995. if ( i > 12 && i < 17 + SIZE )
  996. {
  997. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  998. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  999. }
  1000. else
  1001. {
  1002. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1003. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1004. }
  1005. i++;
  1006. }
  1007. // test before to advance just before a key value pair where the key
  1008. // does not exist - using value so we hit check for key equality
  1009. i = 21 + SIZE;
  1010. cursor = table.cursor();
  1011. String istr = Integer.toString( 18 + SIZE );
  1012. cursor.before( new Tuple<String,String>( istr, istr ) );
  1013. while ( cursor.next() )
  1014. {
  1015. if ( i > 17 + SIZE && i < 21 + SIZE )
  1016. {
  1017. assertFalse( table.has( Integer.toString( i ) ) );
  1018. continue;
  1019. }
  1020. Tuple<String,String> tuple = cursor.get();
  1021. if ( i > 12 && i < 17 + SIZE )
  1022. {
  1023. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1024. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1025. }
  1026. else
  1027. {
  1028. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1029. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1030. }
  1031. i++;
  1032. }
  1033. // test after to advance just after the end
  1034. cursor = table.cursor();
  1035. cursor.after( new Tuple<String,String>( "111", null ) );
  1036. assertFalse( cursor.next() );
  1037. // test after to advance just before a key with a single value
  1038. i = 6;
  1039. cursor = table.cursor();
  1040. cursor.after( new Tuple<String,String>( "5", null ) );
  1041. while ( cursor.next() )
  1042. {
  1043. if ( i > 17 + SIZE && i < 21 + SIZE )
  1044. {
  1045. assertFalse( table.has( Integer.toString( i ) ) );
  1046. continue;
  1047. }
  1048. Tuple<String,String> tuple = cursor.get();
  1049. if ( i > 12 && i < 17 + SIZE )
  1050. {
  1051. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1052. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1053. }
  1054. else
  1055. {
  1056. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1057. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1058. }
  1059. i++;
  1060. }
  1061. // test before to advance just before a key & value with multiple
  1062. // values for the key - we should advance just before the value
  1063. cursor = table.cursor();
  1064. cursor.before( new Tuple<String,String>( "13", "14" ) );
  1065. cursor.next();
  1066. Tuple<String,String> tuple = cursor.get();
  1067. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1068. assertEquals( 14, Integer.parseInt( tuple.getValue() ) );
  1069. i = 15;
  1070. while ( cursor.next() )
  1071. {
  1072. if ( i > 17 + SIZE && i < 21 + SIZE )
  1073. {
  1074. assertFalse( table.has( Integer.toString( i ) ) );
  1075. continue;
  1076. }
  1077. tuple = cursor.get();
  1078. if ( i > 12 && i < 17 + SIZE )
  1079. {
  1080. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1081. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1082. }
  1083. else
  1084. {
  1085. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1086. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1087. }
  1088. i++;
  1089. }
  1090. // test after to advance just before a key & value with multiple
  1091. // values for the key - we should advance just before the value
  1092. cursor = table.cursor();
  1093. cursor.after( new Tuple<String,String>( "13", "14" ) );
  1094. cursor.next();
  1095. tuple = cursor.get();
  1096. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1097. assertEquals( 15, Integer.parseInt( tuple.getValue() ) );
  1098. i=16;
  1099. while ( cursor.next() )
  1100. {
  1101. if ( i > 17 + SIZE && i < 21 + SIZE )
  1102. {
  1103. assertFalse( table.has( Integer.toString( i ) ) );
  1104. continue;
  1105. }
  1106. tuple = cursor.get();
  1107. if ( i > 12 && i < 17 + SIZE )
  1108. {
  1109. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1110. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1111. }
  1112. else
  1113. {
  1114. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1115. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1116. }
  1117. i++;
  1118. }
  1119. // test after to advance just before a key that does not exist
  1120. cursor = table.cursor();
  1121. cursor.after( new Tuple<String,String>( Integer.toString( 18 + SIZE ), null ) );
  1122. cursor.next();
  1123. tuple = cursor.get();
  1124. assertEquals( 21 + SIZE, Integer.parseInt( tuple.getKey() ) );
  1125. assertEquals( 21 + SIZE, Integer.parseInt( tuple.getValue() ) );
  1126. i=22 + SIZE;
  1127. while ( cursor.next() )
  1128. {
  1129. if ( i > 17 + SIZE && i < 21 + SIZE )
  1130. {
  1131. assertFalse( table.has( Integer.toString( i ) ) );
  1132. continue;
  1133. }
  1134. tuple = cursor.get();
  1135. if ( i > 12 && i < 17 + SIZE )
  1136. {
  1137. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1138. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1139. }
  1140. else
  1141. {
  1142. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1143. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1144. }
  1145. i++;
  1146. }
  1147. // test after to advance just before a key and value where the key
  1148. // does not exist - used to force key comparison in after()
  1149. cursor = table.cursor();
  1150. cursor.after( new Tuple<String,String>( istr, istr ) );
  1151. cursor.next();
  1152. tuple = cursor.get();
  1153. assertEquals( 21 + SIZE, Integer.parseInt( tuple.getKey() ) );
  1154. assertEquals( 21 + SIZE, Integer.parseInt( tuple.getValue() ) );
  1155. i=22+ SIZE;
  1156. while ( cursor.next() )
  1157. {
  1158. if ( i > 17 + SIZE && i < 21 + SIZE )
  1159. {
  1160. assertFalse( table.has( Integer.toString( i ) ) );
  1161. continue;
  1162. }
  1163. tuple = cursor.get();
  1164. if ( i > 12 && i < 17 + SIZE )
  1165. {
  1166. assertEquals( 13, Integer.parseInt( tuple.getKey() ) );
  1167. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1168. }
  1169. else
  1170. {
  1171. assertEquals( i, Integer.parseInt( tuple.getKey() ) );
  1172. assertEquals( i, Integer.parseInt( tuple.getValue() ) );
  1173. }
  1174. i++;
  1175. }
  1176. }
  1177. @Test
  1178. public void testMiscellaneous() throws Exception
  1179. {
  1180. Cursor<Tuple<String,String>> cursor = table.cursor();
  1181. assertNotNull( cursor );
  1182. assertTrue( cursor.isElementReused() );
  1183. try
  1184. {
  1185. cursor.get();
  1186. fail( "Should never get here due to invalid cursor position exception." );
  1187. }
  1188. catch( InvalidCursorPositionException e )
  1189. {
  1190. }
  1191. }
  1192. }