1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 2002,2008 Oracle. All rights reserved. 5 * 6 * $Id: CollectionTest.java,v 12.10 2008/02/07 17:12:31 mark Exp $ 7 */ 8 9package com.sleepycat.collections.test; 10 11import java.util.ArrayList; 12import java.util.Collection; 13import java.util.Collections; 14import java.util.Enumeration; 15import java.util.HashMap; 16import java.util.Iterator; 17import java.util.List; 18import java.util.ListIterator; 19import java.util.Map; 20import java.util.NoSuchElementException; 21import java.util.Set; 22import java.util.SortedMap; 23import java.util.SortedSet; 24 25import junit.framework.Test; 26import junit.framework.TestCase; 27import junit.framework.TestSuite; 28 29import com.sleepycat.bind.EntityBinding; 30import com.sleepycat.bind.EntryBinding; 31import com.sleepycat.collections.MapEntryParameter; 32import com.sleepycat.collections.StoredCollection; 33import com.sleepycat.collections.StoredCollections; 34import com.sleepycat.collections.StoredContainer; 35import com.sleepycat.collections.StoredEntrySet; 36import com.sleepycat.collections.StoredIterator; 37import com.sleepycat.collections.StoredKeySet; 38import com.sleepycat.collections.StoredList; 39import com.sleepycat.collections.StoredMap; 40import com.sleepycat.collections.StoredSortedEntrySet; 41import com.sleepycat.collections.StoredSortedKeySet; 42import com.sleepycat.collections.StoredSortedMap; 43import com.sleepycat.collections.StoredSortedValueSet; 44import com.sleepycat.collections.StoredValueSet; 45import com.sleepycat.collections.TransactionRunner; 46import com.sleepycat.collections.TransactionWorker; 47import com.sleepycat.compat.DbCompat; 48import com.sleepycat.db.Database; 49import com.sleepycat.db.DatabaseException; 50import com.sleepycat.db.Environment; 51import com.sleepycat.util.ExceptionUnwrapper; 52import com.sleepycat.util.test.SharedTestUtils; 53import com.sleepycat.util.test.TestEnv; 54 55/** 56 * @author Mark Hayes 57 */ 58public class CollectionTest extends TestCase { 59 60 private static final int NONE = 0; 61 private static final int SUB = 1; 62 private static final int HEAD = 2; 63 private static final int TAIL = 3; 64 65 /* 66 * For long tests we permute testStoredIterator to test both StoredIterator 67 * and BlockIterator. When testing BlockIterator, we permute the maxKey 68 * over the array values below. BlockIterator's block size is 10. So we 69 * test below the block size (6), at the block size (10), and above it (14 70 * and 22). 71 */ 72 private static final int DEFAULT_MAX_KEY = 6; 73 private static final int[] MAX_KEYS = {6, 10, 14, 22}; 74 75 private boolean testStoredIterator; 76 private int maxKey; /* Must be a multiple of 2. */ 77 private int beginKey = 1; 78 private int endKey; 79 80 private Environment env; 81 private Database store; 82 private Database index; 83 private boolean isEntityBinding; 84 private boolean isAutoCommit; 85 private TestStore testStore; 86 private String testName; 87 private EntryBinding keyBinding; 88 private EntryBinding valueBinding; 89 private EntityBinding entityBinding; 90 private TransactionRunner readRunner; 91 private TransactionRunner writeRunner; 92 private TransactionRunner writeIterRunner; 93 private TestEnv testEnv; 94 95 private StoredMap map; 96 private StoredMap imap; // insertable map (primary store for indexed map) 97 private StoredSortedMap smap; // sorted map (null or equal to map) 98 private StoredMap saveMap; 99 private StoredSortedMap saveSMap; 100 private int rangeType; 101 private StoredList list; 102 private StoredList ilist; // insertable list (primary store for index list) 103 private StoredList saveList; 104 private StoredKeySet keySet; 105 private StoredValueSet valueSet; 106 107 /** 108 * Runs a command line collection test. 109 * @see #usage 110 */ 111 public static void main(String[] args) 112 throws Exception { 113 114 if (args.length == 1 && 115 (args[0].equals("-h") || args[0].equals("-help"))) { 116 usage(); 117 } else { 118 junit.framework.TestResult tr = 119 junit.textui.TestRunner.run(suite(args)); 120 if (tr.errorCount() > 0 || 121 tr.failureCount() > 0) { 122 System.exit(1); 123 } else { 124 System.exit(0); 125 } 126 } 127 } 128 129 private static void usage() { 130 131 System.out.println( 132 "Usage: java com.sleepycat.collections.test.CollectionTest\n" + 133 " -h | -help\n" + 134 " [testName]...\n" + 135 " where testName has the format:\n" + 136 " <env>-<store>-{entity|value}\n" + 137 " <env> is:\n" + 138 " bdb | cdb | txn\n" + 139 " <store> is:\n" + 140 " btree-uniq | btree-dup | btree-dupsort | btree-recnum |\n" + 141 " hash-uniq | hash-dup | hash-dupsort |\n" + 142 " queue | recno | recno-renum\n" + 143 " For example: bdb-btree-uniq-entity\n" + 144 " If no arguments are given then all tests are run."); 145 System.exit(2); 146 } 147 148 public static Test suite() 149 throws Exception { 150 151 return suite(null); 152 } 153 154 static Test suite(String[] args) 155 throws Exception { 156 157 if (SharedTestUtils.runLongTests()) { 158 TestSuite suite = new TestSuite(); 159 160 /* StoredIterator tests. */ 161 permuteTests(args, suite, true, DEFAULT_MAX_KEY); 162 163 /* BlockIterator tests with different maxKey values. */ 164 for (int i = 0; i < MAX_KEYS.length; i += 1) { 165 permuteTests(args, suite, false, MAX_KEYS[i]); 166 } 167 168 return suite; 169 } else { 170 return baseSuite(args); 171 } 172 } 173 174 private static void permuteTests(String[] args, 175 TestSuite suite, 176 boolean storedIter, 177 int maxKey) 178 throws Exception { 179 180 TestSuite baseTests = baseSuite(args); 181 Enumeration e = baseTests.tests(); 182 while (e.hasMoreElements()) { 183 CollectionTest t = (CollectionTest) e.nextElement(); 184 t.setParams(storedIter, maxKey); 185 suite.addTest(t); 186 } 187 } 188 189 private static TestSuite baseSuite(String[] args) 190 throws Exception { 191 192 TestSuite suite = new TestSuite(); 193 for (int i = 0; i < TestEnv.ALL.length; i += 1) { 194 for (int j = 0; j < TestStore.ALL.length; j += 1) { 195 for (int k = 0; k < 2; k += 1) { 196 boolean entityBinding = (k != 0); 197 198 addTest(args, suite, new CollectionTest( 199 TestEnv.ALL[i], TestStore.ALL[j], 200 entityBinding, false)); 201 202 if (TestEnv.ALL[i].isTxnMode()) { 203 addTest(args, suite, new CollectionTest( 204 TestEnv.ALL[i], TestStore.ALL[j], 205 entityBinding, true)); 206 } 207 } 208 } 209 } 210 return suite; 211 } 212 213 private static void addTest(String[] args, TestSuite suite, 214 CollectionTest test) { 215 216 if (args == null || args.length == 0) { 217 suite.addTest(test); 218 } else { 219 for (int t = 0; t < args.length; t += 1) { 220 if (args[t].equals(test.testName)) { 221 suite.addTest(test); 222 break; 223 } 224 } 225 } 226 } 227 228 public CollectionTest(TestEnv testEnv, TestStore testStore, 229 boolean isEntityBinding, boolean isAutoCommit) { 230 231 super(null); 232 233 this.testEnv = testEnv; 234 this.testStore = testStore; 235 this.isEntityBinding = isEntityBinding; 236 this.isAutoCommit = isAutoCommit; 237 238 keyBinding = testStore.getKeyBinding(); 239 valueBinding = testStore.getValueBinding(); 240 entityBinding = testStore.getEntityBinding(); 241 242 setParams(false, DEFAULT_MAX_KEY); 243 } 244 245 private void setParams(boolean storedIter, int maxKey) { 246 247 this.testStoredIterator = storedIter; 248 this.maxKey = maxKey; 249 this.endKey = maxKey; 250 251 testName = testEnv.getName() + '-' + testStore.getName() + 252 (isEntityBinding ? "-entity" : "-value") + 253 (isAutoCommit ? "-autoCommit" : "") + 254 (testStoredIterator ? "-storedIter" : "") + 255 ((maxKey != DEFAULT_MAX_KEY) ? ("-maxKey-" + maxKey) : ""); 256 } 257 258 public void tearDown() 259 throws Exception { 260 261 setName(testName); 262 } 263 264 public void runTest() 265 throws Exception { 266 267 SharedTestUtils.printTestName(SharedTestUtils.qualifiedTestName(this)); 268 try { 269 env = testEnv.open(testName); 270 271 // For testing auto-commit, use a normal (transactional) runner for 272 // all reading and for writing via an iterator, and a do-nothing 273 // runner for writing via collections; if auto-commit is tested, 274 // the per-collection auto-commit property will be set elsewhere. 275 // 276 TransactionRunner normalRunner = newTransactionRunner(env); 277 normalRunner.setAllowNestedTransactions( 278 DbCompat.NESTED_TRANSACTIONS); 279 TransactionRunner nullRunner = new NullTransactionRunner(env); 280 readRunner = nullRunner; 281 if (isAutoCommit) { 282 writeRunner = nullRunner; 283 writeIterRunner = testStoredIterator ? normalRunner 284 : nullRunner; 285 } else { 286 writeRunner = normalRunner; 287 writeIterRunner = normalRunner; 288 } 289 290 store = testStore.open(env, "unindexed.db"); 291 testUnindexed(); 292 store.close(); 293 store = null; 294 295 TestStore indexOf = testStore.getIndexOf(); 296 if (indexOf != null) { 297 store = indexOf.open(env, "indexed.db"); 298 index = testStore.openIndex(store, "index.db"); 299 testIndexed(); 300 index.close(); 301 index = null; 302 store.close(); 303 store = null; 304 } 305 env.close(); 306 env = null; 307 } catch (Exception e) { 308 throw ExceptionUnwrapper.unwrap(e); 309 } finally { 310 if (index != null) { 311 try { 312 index.close(); 313 } catch (Exception e) { 314 } 315 } 316 if (store != null) { 317 try { 318 store.close(); 319 } catch (Exception e) { 320 } 321 } 322 if (env != null) { 323 try { 324 env.close(); 325 } catch (Exception e) { 326 } 327 } 328 /* Ensure that GC can cleanup. */ 329 index = null; 330 store = null; 331 env = null; 332 readRunner = null; 333 writeRunner = null; 334 writeIterRunner = null; 335 map = null; 336 imap = null; 337 smap = null; 338 saveMap = null; 339 saveSMap = null; 340 list = null; 341 ilist = null; 342 saveList = null; 343 keySet = null; 344 valueSet = null; 345 testEnv = null; 346 testStore = null; 347 } 348 } 349 350 /** 351 * Is overridden in XACollectionTest. 352 */ 353 protected TransactionRunner newTransactionRunner(Environment env) 354 throws DatabaseException { 355 356 return new TransactionRunner(env); 357 } 358 359 void testCreation(StoredContainer cont, int expectSize) 360 throws Exception { 361 362 assertEquals(index != null, cont.isSecondary()); 363 assertEquals(testStore.isOrdered(), cont.isOrdered()); 364 assertEquals(testStore.areKeyRangesAllowed(), 365 cont.areKeyRangesAllowed()); 366 assertEquals(testStore.areKeysRenumbered(), cont.areKeysRenumbered()); 367 assertEquals(testStore.areDuplicatesAllowed(), 368 cont.areDuplicatesAllowed()); 369 assertEquals(testEnv.isTxnMode(), cont.isTransactional()); 370 assertEquals(expectSize, cont.size()); 371 } 372 373 void testMapCreation(Map map) 374 throws Exception { 375 376 assertTrue(map.values() instanceof Set); 377 assertEquals(testStore.areKeyRangesAllowed(), 378 map.keySet() instanceof SortedSet); 379 assertEquals(testStore.areKeyRangesAllowed(), 380 map.entrySet() instanceof SortedSet); 381 assertEquals(testStore.areKeyRangesAllowed() && isEntityBinding, 382 map.values() instanceof SortedSet); 383 } 384 385 void testUnindexed() 386 throws Exception { 387 388 // create primary map 389 if (testStore.areKeyRangesAllowed()) { 390 if (isEntityBinding) { 391 smap = new StoredSortedMap(store, keyBinding, 392 entityBinding, 393 testStore.getKeyAssigner()); 394 valueSet = new StoredSortedValueSet(store, entityBinding, 395 true); 396 } else { 397 smap = new StoredSortedMap(store, keyBinding, 398 valueBinding, 399 testStore.getKeyAssigner()); 400 // sorted value set is not possible since key cannot be derived 401 // for performing subSet, etc. 402 } 403 keySet = new StoredSortedKeySet(store, keyBinding, true); 404 map = smap; 405 } else { 406 if (isEntityBinding) { 407 map = new StoredMap(store, keyBinding, entityBinding, 408 testStore.getKeyAssigner()); 409 valueSet = new StoredValueSet(store, entityBinding, true); 410 } else { 411 map = new StoredMap(store, keyBinding, valueBinding, 412 testStore.getKeyAssigner()); 413 valueSet = new StoredValueSet(store, valueBinding, true); 414 } 415 smap = null; 416 keySet = new StoredKeySet(store, keyBinding, true); 417 } 418 imap = map; 419 420 // create primary list 421 if (testStore.hasRecNumAccess()) { 422 if (isEntityBinding) { 423 ilist = new StoredList(store, entityBinding, 424 testStore.getKeyAssigner()); 425 } else { 426 ilist = new StoredList(store, valueBinding, 427 testStore.getKeyAssigner()); 428 } 429 list = ilist; 430 } else { 431 try { 432 if (isEntityBinding) { 433 ilist = new StoredList(store, entityBinding, 434 testStore.getKeyAssigner()); 435 } else { 436 ilist = new StoredList(store, valueBinding, 437 testStore.getKeyAssigner()); 438 } 439 fail(); 440 } catch (IllegalArgumentException expected) {} 441 } 442 443 testCreation(map, 0); 444 if (list != null) { 445 testCreation(list, 0); 446 } 447 testMapCreation(map); 448 addAll(); 449 testAll(); 450 } 451 452 void testIndexed() 453 throws Exception { 454 455 // create primary map 456 if (isEntityBinding) { 457 map = new StoredMap(store, keyBinding, entityBinding, 458 testStore.getKeyAssigner()); 459 } else { 460 map = new StoredMap(store, keyBinding, valueBinding, 461 testStore.getKeyAssigner()); 462 } 463 imap = map; 464 smap = null; 465 // create primary list 466 if (testStore.hasRecNumAccess()) { 467 if (isEntityBinding) { 468 list = new StoredList(store, entityBinding, 469 testStore.getKeyAssigner()); 470 } else { 471 list = new StoredList(store, valueBinding, 472 testStore.getKeyAssigner()); 473 } 474 ilist = list; 475 } 476 477 addAll(); 478 readAll(); 479 480 // create indexed map (keySet/valueSet) 481 if (testStore.areKeyRangesAllowed()) { 482 if (isEntityBinding) { 483 map = smap = new StoredSortedMap(index, keyBinding, 484 entityBinding, true); 485 valueSet = new StoredSortedValueSet(index, entityBinding, 486 true); 487 } else { 488 map = smap = new StoredSortedMap(index, keyBinding, 489 valueBinding, true); 490 // sorted value set is not possible since key cannot be derived 491 // for performing subSet, etc. 492 } 493 keySet = new StoredSortedKeySet(index, keyBinding, true); 494 } else { 495 if (isEntityBinding) { 496 map = new StoredMap(index, keyBinding, entityBinding, true); 497 valueSet = new StoredValueSet(index, entityBinding, true); 498 } else { 499 map = new StoredMap(index, keyBinding, valueBinding, true); 500 valueSet = new StoredValueSet(index, valueBinding, true); 501 } 502 smap = null; 503 keySet = new StoredKeySet(index, keyBinding, true); 504 } 505 506 // create indexed list 507 if (testStore.hasRecNumAccess()) { 508 if (isEntityBinding) { 509 list = new StoredList(index, entityBinding, true); 510 } else { 511 list = new StoredList(index, valueBinding, true); 512 } 513 } else { 514 try { 515 if (isEntityBinding) { 516 list = new StoredList(index, entityBinding, true); 517 } else { 518 list = new StoredList(index, valueBinding, true); 519 } 520 fail(); 521 } catch (IllegalArgumentException expected) {} 522 } 523 524 testCreation(map, maxKey); 525 testCreation((StoredContainer) map.values(), maxKey); 526 testCreation((StoredContainer) map.keySet(), maxKey); 527 testCreation((StoredContainer) map.entrySet(), maxKey); 528 if (list != null) { 529 testCreation(list, maxKey); 530 } 531 testMapCreation(map); 532 testAll(); 533 } 534 535 void testAll() 536 throws Exception { 537 538 checkKeySetAndValueSet(); 539 readAll(); 540 updateAll(); 541 readAll(); 542 if (!map.areKeysRenumbered()) { 543 removeOdd(); 544 readEven(); 545 addOdd(); 546 readAll(); 547 removeOddIter(); 548 readEven(); 549 if (imap.areDuplicatesAllowed()) { 550 addOddDup(); 551 } else { 552 addOdd(); 553 } 554 readAll(); 555 removeOddEntry(); 556 readEven(); 557 addOdd(); 558 readAll(); 559 if (isEntityBinding) { 560 removeOddEntity(); 561 readEven(); 562 addOddEntity(); 563 readAll(); 564 } 565 bulkOperations(); 566 } 567 if (isListAddAllowed()) { 568 removeOddList(); 569 readEvenList(); 570 addOddList(); 571 readAll(); 572 if (!isEntityBinding) { 573 removeOddListValue(); 574 readEvenList(); 575 addOddList(); 576 readAll(); 577 } 578 } 579 if (list != null) { 580 bulkListOperations(); 581 } else { 582 listOperationsNotAllowed(); 583 } 584 if (smap != null) { 585 readWriteRange(SUB, 1, 1); 586 readWriteRange(HEAD, 1, 1); 587 readWriteRange(SUB, 1, maxKey); 588 readWriteRange(HEAD, 1, maxKey); 589 readWriteRange(TAIL, 1, maxKey); 590 readWriteRange(SUB, 1, 3); 591 readWriteRange(HEAD, 1, 3); 592 readWriteRange(SUB, 2, 2); 593 readWriteRange(SUB, 2, maxKey); 594 readWriteRange(TAIL, 2, maxKey); 595 readWriteRange(SUB, maxKey, maxKey); 596 readWriteRange(TAIL, maxKey, maxKey); 597 readWriteRange(SUB, maxKey + 1, maxKey + 1); 598 readWriteRange(TAIL, maxKey + 1, maxKey + 1); 599 readWriteRange(SUB, 0, 0); 600 readWriteRange(HEAD, 0, 0); 601 } 602 updateAll(); 603 readAll(); 604 if (map.areDuplicatesAllowed()) { 605 readWriteDuplicates(); 606 readAll(); 607 } else { 608 duplicatesNotAllowed(); 609 readAll(); 610 } 611 if (testEnv.isCdbMode()) { 612 testCdbLocking(); 613 } 614 removeAll(); 615 if (isListAddAllowed()) { 616 testIterAddList(); 617 clearAll(); 618 } 619 if (imap.areDuplicatesAllowed()) { 620 testIterAddDuplicates(); 621 clearAll(); 622 } 623 if (isListAddAllowed()) { 624 addAllList(); 625 readAll(); 626 removeAllList(); 627 } 628 appendAll(); 629 } 630 631 void checkKeySetAndValueSet() { 632 633 // use bulk operations to check that explicitly constructed 634 // keySet/valueSet are equivalent 635 assertEquals(keySet, imap.keySet()); 636 if (valueSet != null) { 637 assertEquals(valueSet, imap.values()); 638 } 639 } 640 641 Iterator iterator(Collection storedCollection) { 642 643 if (testStoredIterator) { 644 return ((StoredCollection) storedCollection).storedIterator(); 645 } else { 646 return storedCollection.iterator(); 647 } 648 } 649 650 void addAll() 651 throws Exception { 652 653 writeRunner.run(new TransactionWorker() { 654 public void doWork() throws Exception { 655 assertTrue(imap.isEmpty()); 656 Iterator iter = iterator(imap.entrySet()); 657 try { 658 assertTrue(!iter.hasNext()); 659 } finally { 660 StoredIterator.close(iter); 661 } 662 assertEquals(0, imap.keySet().toArray().length); 663 assertEquals(0, imap.keySet().toArray(new Object[0]).length); 664 assertEquals(0, imap.entrySet().toArray().length); 665 assertEquals(0, imap.entrySet().toArray(new Object[0]).length); 666 assertEquals(0, imap.values().toArray().length); 667 assertEquals(0, imap.values().toArray(new Object[0]).length); 668 669 for (int i = beginKey; i <= endKey; i += 1) { 670 Long key = makeKey(i); 671 Object val = makeVal(i); 672 assertNull(imap.get(key)); 673 assertTrue(!imap.keySet().contains(key)); 674 assertTrue(!imap.values().contains(val)); 675 assertNull(imap.put(key, val)); 676 assertEquals(val, imap.get(key)); 677 assertTrue(imap.keySet().contains(key)); 678 assertTrue(imap.values().contains(val)); 679 assertTrue(imap.duplicates(key).contains(val)); 680 if (!imap.areDuplicatesAllowed()) { 681 assertEquals(val, imap.put(key, val)); 682 } 683 checkDupsSize(1, imap.duplicates(key)); 684 } 685 assertTrue(!imap.isEmpty()); 686 } 687 }); 688 } 689 690 void appendAll() 691 throws Exception { 692 693 writeRunner.run(new TransactionWorker() { 694 public void doWork() throws Exception { 695 assertTrue(imap.isEmpty()); 696 697 TestKeyAssigner keyAssigner = testStore.getKeyAssigner(); 698 if (keyAssigner != null) { 699 keyAssigner.reset(); 700 } 701 702 for (int i = beginKey; i <= endKey; i += 1) { 703 boolean useList = (i & 1) == 0; 704 Long key = makeKey(i); 705 Object val = makeVal(i); 706 assertNull(imap.get(key)); 707 if (keyAssigner != null) { 708 if (useList && ilist != null) { 709 assertEquals(i - 1, ilist.append(val)); 710 } else { 711 assertEquals(key, imap.append(val)); 712 } 713 assertEquals(val, imap.get(key)); 714 } else { 715 Long recnoKey; 716 if (useList && ilist != null) { 717 recnoKey = new Long(ilist.append(val) + 1); 718 } else { 719 recnoKey = (Long) imap.append(val); 720 } 721 assertNotNull(recnoKey); 722 Object recnoVal; 723 if (isEntityBinding) { 724 recnoVal = makeEntity(recnoKey.intValue(), i); 725 } else { 726 recnoVal = val; 727 } 728 assertEquals(recnoVal, imap.get(recnoKey)); 729 } 730 } 731 } 732 }); 733 } 734 735 void updateAll() 736 throws Exception { 737 738 writeRunner.run(new TransactionWorker() { 739 public void doWork() throws Exception { 740 for (int i = beginKey; i <= endKey; i += 1) { 741 Long key = makeKey(i); 742 Object val = makeVal(i); 743 if (!imap.areDuplicatesAllowed()) { 744 assertEquals(val, imap.put(key, val)); 745 } 746 if (isEntityBinding) { 747 assertTrue(!imap.values().add(val)); 748 } 749 checkDupsSize(1, imap.duplicates(key)); 750 if (ilist != null) { 751 int idx = i - 1; 752 assertEquals(val, ilist.set(idx, val)); 753 } 754 } 755 updateIter(map.entrySet()); 756 updateIter(map.values()); 757 if (beginKey <= endKey) { 758 ListIterator iter = (ListIterator) iterator(map.keySet()); 759 try { 760 assertNotNull(iter.next()); 761 iter.set(makeKey(beginKey)); 762 fail(); 763 } catch (UnsupportedOperationException e) { 764 } finally { 765 StoredIterator.close(iter); 766 } 767 } 768 if (list != null) { 769 updateIter(list); 770 } 771 } 772 }); 773 } 774 775 void updateIter(final Collection coll) 776 throws Exception { 777 778 writeIterRunner.run(new TransactionWorker() { 779 public void doWork() throws Exception { 780 ListIterator iter = (ListIterator) iterator(coll); 781 try { 782 for (int i = beginKey; i <= endKey; i += 1) { 783 assertTrue(iter.hasNext()); 784 Object obj = iter.next(); 785 if (map.isOrdered()) { 786 assertEquals(i, intIter(coll, obj)); 787 } 788 if (index != null) { 789 try { 790 setValuePlusOne(iter, obj); 791 fail(); 792 } catch (UnsupportedOperationException e) {} 793 } else if 794 (((StoredCollection) coll).areDuplicatesOrdered()) { 795 try { 796 setValuePlusOne(iter, obj); 797 fail(); 798 } catch (RuntimeException e) { 799 Exception e2 = ExceptionUnwrapper.unwrap(e); 800 assertTrue(e2.getClass().getName(), 801 e2 instanceof IllegalArgumentException || 802 e2 instanceof DatabaseException); 803 } 804 } else { 805 setValuePlusOne(iter, obj); 806 /* Ensure iterator position is correct. */ 807 if (map.isOrdered()) { 808 assertTrue(iter.hasPrevious()); 809 obj = iter.previous(); 810 assertEquals(i, intIter(coll, obj)); 811 assertTrue(iter.hasNext()); 812 obj = iter.next(); 813 assertEquals(i, intIter(coll, obj)); 814 } 815 } 816 } 817 assertTrue(!iter.hasNext()); 818 } finally { 819 StoredIterator.close(iter); 820 } 821 } 822 }); 823 } 824 825 void setValuePlusOne(ListIterator iter, Object obj) { 826 827 if (obj instanceof Map.Entry) { 828 Map.Entry entry = (Map.Entry) obj; 829 Long key = (Long) entry.getKey(); 830 Object oldVal = entry.getValue(); 831 Object val = makeVal(key.intValue() + 1); 832 if (isEntityBinding) { 833 try { 834 // must fail on attempt to change the key via an entity 835 entry.setValue(val); 836 fail(); 837 } catch (IllegalArgumentException e) {} 838 val = makeEntity(key.intValue(), key.intValue() + 1); 839 } 840 entry.setValue(val); 841 assertEquals(val, entry.getValue()); 842 assertEquals(val, map.get(key)); 843 assertTrue(map.duplicates(key).contains(val)); 844 checkDupsSize(1, map.duplicates(key)); 845 entry.setValue(oldVal); 846 assertEquals(oldVal, entry.getValue()); 847 assertEquals(oldVal, map.get(key)); 848 assertTrue(map.duplicates(key).contains(oldVal)); 849 checkDupsSize(1, map.duplicates(key)); 850 } else { 851 Object oldVal = obj; 852 Long key = makeKey(intVal(obj)); 853 Object val = makeVal(key.intValue() + 1); 854 if (isEntityBinding) { 855 try { 856 // must fail on attempt to change the key via an entity 857 iter.set(val); 858 fail(); 859 } catch (IllegalArgumentException e) {} 860 val = makeEntity(key.intValue(), key.intValue() + 1); 861 } 862 iter.set(val); 863 assertEquals(val, map.get(key)); 864 assertTrue(map.duplicates(key).contains(val)); 865 checkDupsSize(1, map.duplicates(key)); 866 iter.set(oldVal); 867 assertEquals(oldVal, map.get(key)); 868 assertTrue(map.duplicates(key).contains(oldVal)); 869 checkDupsSize(1, map.duplicates(key)); 870 } 871 } 872 873 void removeAll() 874 throws Exception { 875 876 writeIterRunner.run(new TransactionWorker() { 877 public void doWork() throws Exception { 878 assertTrue(!map.isEmpty()); 879 ListIterator iter = null; 880 try { 881 if (list != null) { 882 iter = (ListIterator) iterator(list); 883 } else { 884 iter = (ListIterator) iterator(map.values()); 885 } 886 iteratorSetAndRemoveNotAllowed(iter); 887 888 Object val = iter.next(); 889 assertNotNull(val); 890 iter.remove(); 891 iteratorSetAndRemoveNotAllowed(iter); 892 893 if (index == null) { 894 val = iter.next(); 895 assertNotNull(val); 896 iter.set(val); 897 898 if (map.areDuplicatesAllowed()) { 899 iter.add(makeVal(intVal(val), intVal(val) + 1)); 900 iteratorSetAndRemoveNotAllowed(iter); 901 } 902 } 903 } finally { 904 StoredIterator.close(iter); 905 } 906 map.clear(); 907 assertTrue(map.isEmpty()); 908 assertTrue(map.entrySet().isEmpty()); 909 assertTrue(map.keySet().isEmpty()); 910 assertTrue(map.values().isEmpty()); 911 for (int i = beginKey; i <= endKey; i += 1) { 912 Long key = makeKey(i); 913 Object val = makeVal(i); 914 assertNull(map.get(key)); 915 assertTrue(!map.duplicates(key).contains(val)); 916 checkDupsSize(0, map.duplicates(key)); 917 } 918 } 919 }); 920 } 921 922 void clearAll() 923 throws Exception { 924 925 writeRunner.run(new TransactionWorker() { 926 public void doWork() throws Exception { 927 map.clear(); 928 assertTrue(map.isEmpty()); 929 } 930 }); 931 } 932 933 /** 934 * Tests that removing while iterating works properly, especially when 935 * removing everything in the key range or everything from some point to 936 * the end of the range. [#15858] 937 */ 938 void removeIter() 939 throws Exception { 940 941 writeIterRunner.run(new TransactionWorker() { 942 public void doWork() throws Exception { 943 ListIterator iter; 944 945 /* Save contents. */ 946 HashMap<Object,Object> savedMap = 947 new HashMap<Object,Object>(map); 948 assertEquals(savedMap, map); 949 950 /* Remove all moving forward. */ 951 iter = (ListIterator) iterator(map.keySet()); 952 try { 953 while (iter.hasNext()) { 954 assertNotNull(iter.next()); 955 iter.remove(); 956 } 957 assertTrue(!iter.hasNext()); 958 assertTrue(!iter.hasPrevious()); 959 assertTrue(map.isEmpty()); 960 } finally { 961 StoredIterator.close(iter); 962 } 963 964 /* Restore contents. */ 965 imap.putAll(savedMap); 966 assertEquals(savedMap, map); 967 968 /* Remove all moving backward. */ 969 iter = (ListIterator) iterator(map.keySet()); 970 try { 971 while (iter.hasNext()) { 972 assertNotNull(iter.next()); 973 } 974 while (iter.hasPrevious()) { 975 assertNotNull(iter.previous()); 976 iter.remove(); 977 } 978 assertTrue(!iter.hasNext()); 979 assertTrue(!iter.hasPrevious()); 980 assertTrue(map.isEmpty()); 981 } finally { 982 StoredIterator.close(iter); 983 } 984 985 /* Restore contents. */ 986 imap.putAll(savedMap); 987 assertEquals(savedMap, map); 988 989 int first = Math.max(1, beginKey); 990 int last = Math.min(maxKey, endKey); 991 992 /* Skip N forward, remove all from that point forward. */ 993 for (int readTo = first + 1; readTo <= last; readTo += 1) { 994 iter = (ListIterator) iterator(map.keySet()); 995 try { 996 for (int i = first; i < readTo; i += 1) { 997 assertTrue(iter.hasNext()); 998 assertNotNull(iter.next()); 999 } 1000 for (int i = readTo; i <= last; i += 1) { 1001 assertTrue(iter.hasNext()); 1002 assertNotNull(iter.next()); 1003 iter.remove(); 1004 } 1005 assertTrue(!iter.hasNext()); 1006 assertTrue(iter.hasPrevious()); 1007 assertEquals(readTo - first, map.size()); 1008 } finally { 1009 StoredIterator.close(iter); 1010 } 1011 1012 /* Restore contents. */ 1013 for (Map.Entry entry : savedMap.entrySet()) { 1014 if (!imap.entrySet().contains(entry)) { 1015 imap.put(entry.getKey(), entry.getValue()); 1016 } 1017 } 1018 assertEquals(savedMap, map); 1019 } 1020 1021 /* Skip N backward, remove all from that point backward. */ 1022 for (int readTo = last - 1; readTo >= first; readTo -= 1) { 1023 iter = (ListIterator) iterator(map.keySet()); 1024 try { 1025 while (iter.hasNext()) { 1026 assertNotNull(iter.next()); 1027 } 1028 for (int i = last; i > readTo; i -= 1) { 1029 assertTrue(iter.hasPrevious()); 1030 assertNotNull(iter.previous()); 1031 } 1032 for (int i = readTo; i >= first; i -= 1) { 1033 assertTrue(iter.hasPrevious()); 1034 assertNotNull(iter.previous()); 1035 iter.remove(); 1036 } 1037 assertTrue(!iter.hasPrevious()); 1038 assertTrue(iter.hasNext()); 1039 assertEquals(last - readTo, map.size()); 1040 } finally { 1041 StoredIterator.close(iter); 1042 } 1043 1044 /* Restore contents. */ 1045 for (Map.Entry entry : savedMap.entrySet()) { 1046 if (!imap.entrySet().contains(entry)) { 1047 imap.put(entry.getKey(), entry.getValue()); 1048 } 1049 } 1050 assertEquals(savedMap, map); 1051 } 1052 } 1053 }); 1054 } 1055 1056 void iteratorSetAndRemoveNotAllowed(ListIterator i) { 1057 1058 try { 1059 i.remove(); 1060 fail(); 1061 } catch (IllegalStateException e) {} 1062 1063 if (index == null) { 1064 try { 1065 Object val = makeVal(1); 1066 i.set(val); 1067 fail(); 1068 } catch (IllegalStateException e) {} 1069 } 1070 } 1071 1072 void removeOdd() 1073 throws Exception { 1074 1075 writeRunner.run(new TransactionWorker() { 1076 public void doWork() throws Exception { 1077 boolean toggle = false; 1078 for (int i = beginKey; i <= endKey; i += 2) { 1079 toggle = !toggle; 1080 Long key = makeKey(i); 1081 Object val = makeVal(i); 1082 if (toggle) { 1083 assertTrue(map.keySet().contains(key)); 1084 assertTrue(map.keySet().remove(key)); 1085 assertTrue(!map.keySet().contains(key)); 1086 } else { 1087 assertTrue(map.containsValue(val)); 1088 Object oldVal = map.remove(key); 1089 assertEquals(oldVal, val); 1090 assertTrue(!map.containsKey(key)); 1091 assertTrue(!map.containsValue(val)); 1092 } 1093 assertNull(map.get(key)); 1094 assertTrue(!map.duplicates(key).contains(val)); 1095 checkDupsSize(0, map.duplicates(key)); 1096 } 1097 } 1098 }); 1099 } 1100 1101 void removeOddEntity() 1102 throws Exception { 1103 1104 writeRunner.run(new TransactionWorker() { 1105 public void doWork() throws Exception { 1106 for (int i = beginKey; i <= endKey; i += 2) { 1107 Long key = makeKey(i); 1108 Object val = makeVal(i); 1109 assertTrue(map.values().contains(val)); 1110 assertTrue(map.values().remove(val)); 1111 assertTrue(!map.values().contains(val)); 1112 assertNull(map.get(key)); 1113 assertTrue(!map.duplicates(key).contains(val)); 1114 checkDupsSize(0, map.duplicates(key)); 1115 } 1116 } 1117 }); 1118 } 1119 1120 void removeOddEntry() 1121 throws Exception { 1122 1123 writeRunner.run(new TransactionWorker() { 1124 public void doWork() throws Exception { 1125 for (int i = beginKey; i <= endKey; i += 2) { 1126 Long key = makeKey(i); 1127 Object val = mapEntry(i); 1128 assertTrue(map.entrySet().contains(val)); 1129 assertTrue(map.entrySet().remove(val)); 1130 assertTrue(!map.entrySet().contains(val)); 1131 assertNull(map.get(key)); 1132 } 1133 } 1134 }); 1135 } 1136 1137 void removeOddIter() 1138 throws Exception { 1139 1140 writeIterRunner.run(new TransactionWorker() { 1141 public void doWork() throws Exception { 1142 Iterator iter = iterator(map.keySet()); 1143 try { 1144 for (int i = beginKey; i <= endKey; i += 1) { 1145 assertTrue(iter.hasNext()); 1146 Long key = (Long) iter.next(); 1147 assertNotNull(key); 1148 if (map instanceof SortedMap) { 1149 assertEquals(makeKey(i), key); 1150 } 1151 if ((key.intValue() & 1) != 0) { 1152 iter.remove(); 1153 } 1154 } 1155 } finally { 1156 StoredIterator.close(iter); 1157 } 1158 } 1159 }); 1160 } 1161 1162 void removeOddList() 1163 throws Exception { 1164 1165 writeRunner.run(new TransactionWorker() { 1166 public void doWork() throws Exception { 1167 for (int i = beginKey; i <= endKey; i += 2) { 1168 // remove by index 1169 // (with entity binding, embbeded keys in values are 1170 // being changed so we can't use values for comparison) 1171 int idx = (i - beginKey) / 2; 1172 Object val = makeVal(i); 1173 if (!isEntityBinding) { 1174 assertTrue(list.contains(val)); 1175 assertEquals(val, list.get(idx)); 1176 assertEquals(idx, list.indexOf(val)); 1177 } 1178 assertNotNull(list.get(idx)); 1179 if (isEntityBinding) { 1180 assertNotNull(list.remove(idx)); 1181 } else { 1182 assertTrue(list.contains(val)); 1183 assertEquals(val, list.remove(idx)); 1184 } 1185 assertTrue(!list.remove(val)); 1186 assertTrue(!list.contains(val)); 1187 assertTrue(!val.equals(list.get(idx))); 1188 } 1189 } 1190 }); 1191 } 1192 1193 void removeOddListValue() 1194 throws Exception { 1195 1196 writeRunner.run(new TransactionWorker() { 1197 public void doWork() throws Exception { 1198 for (int i = beginKey; i <= endKey; i += 2) { 1199 // for non-entity case remove by value 1200 // (with entity binding, embbeded keys in values are 1201 // being changed so we can't use values for comparison) 1202 int idx = (i - beginKey) / 2; 1203 Object val = makeVal(i); 1204 assertTrue(list.contains(val)); 1205 assertEquals(val, list.get(idx)); 1206 assertEquals(idx, list.indexOf(val)); 1207 assertTrue(list.remove(val)); 1208 assertTrue(!list.remove(val)); 1209 assertTrue(!list.contains(val)); 1210 assertTrue(!val.equals(list.get(idx))); 1211 } 1212 } 1213 }); 1214 } 1215 1216 void addOdd() 1217 throws Exception { 1218 1219 writeRunner.run(new TransactionWorker() { 1220 public void doWork() throws Exception { 1221 // add using Map.put() 1222 for (int i = beginKey; i <= endKey; i += 2) { 1223 Long key = makeKey(i); 1224 Object val = makeVal(i); 1225 assertNull(imap.get(key)); 1226 assertNull(imap.put(key, val)); 1227 assertEquals(val, imap.get(key)); 1228 assertTrue(imap.duplicates(key).contains(val)); 1229 checkDupsSize(1, imap.duplicates(key)); 1230 if (isEntityBinding) { 1231 assertTrue(!imap.values().add(val)); 1232 } 1233 if (!imap.areDuplicatesAllowed()) { 1234 assertEquals(val, imap.put(key, val)); 1235 } 1236 } 1237 } 1238 }); 1239 } 1240 1241 void addOddEntity() 1242 throws Exception { 1243 1244 writeRunner.run(new TransactionWorker() { 1245 public void doWork() throws Exception { 1246 // add using Map.values().add() 1247 for (int i = beginKey; i <= endKey; i += 2) { 1248 Long key = makeKey(i); 1249 Object val = makeVal(i); 1250 assertNull(imap.get(key)); 1251 assertTrue(!imap.values().contains(val)); 1252 assertTrue(imap.values().add(val)); 1253 assertEquals(val, imap.get(key)); 1254 assertTrue(imap.values().contains(val)); 1255 assertTrue(imap.duplicates(key).contains(val)); 1256 checkDupsSize(1, imap.duplicates(key)); 1257 if (isEntityBinding) { 1258 assertTrue(!imap.values().add(val)); 1259 } 1260 } 1261 } 1262 }); 1263 } 1264 1265 void addOddDup() 1266 throws Exception { 1267 1268 writeRunner.run(new TransactionWorker() { 1269 public void doWork() throws Exception { 1270 // add using Map.duplicates().add() 1271 for (int i = beginKey; i <= endKey; i += 2) { 1272 Long key = makeKey(i); 1273 Object val = makeVal(i); 1274 assertNull(imap.get(key)); 1275 assertTrue(!imap.values().contains(val)); 1276 assertTrue(imap.duplicates(key).add(val)); 1277 assertEquals(val, imap.get(key)); 1278 assertTrue(imap.values().contains(val)); 1279 assertTrue(imap.duplicates(key).contains(val)); 1280 checkDupsSize(1, imap.duplicates(key)); 1281 assertTrue(!imap.duplicates(key).add(val)); 1282 if (isEntityBinding) { 1283 assertTrue(!imap.values().add(val)); 1284 } 1285 } 1286 } 1287 }); 1288 } 1289 1290 void addOddList() 1291 throws Exception { 1292 1293 writeRunner.run(new TransactionWorker() { 1294 public void doWork() throws Exception { 1295 for (int i = beginKey; i <= endKey; i += 2) { 1296 int idx = i - beginKey; 1297 Object val = makeVal(i); 1298 assertTrue(!list.contains(val)); 1299 assertTrue(!val.equals(list.get(idx))); 1300 list.add(idx, val); 1301 assertTrue(list.contains(val)); 1302 assertEquals(val, list.get(idx)); 1303 } 1304 } 1305 }); 1306 } 1307 1308 void addAllList() 1309 throws Exception { 1310 1311 writeRunner.run(new TransactionWorker() { 1312 public void doWork() throws Exception { 1313 for (int i = beginKey; i <= endKey; i += 1) { 1314 int idx = i - beginKey; 1315 Object val = makeVal(i); 1316 assertTrue(!list.contains(val)); 1317 assertTrue(list.add(val)); 1318 assertTrue(list.contains(val)); 1319 assertEquals(val, list.get(idx)); 1320 } 1321 } 1322 }); 1323 } 1324 1325 void removeAllList() 1326 throws Exception { 1327 1328 writeRunner.run(new TransactionWorker() { 1329 public void doWork() throws Exception { 1330 assertTrue(!list.isEmpty()); 1331 list.clear(); 1332 assertTrue(list.isEmpty()); 1333 for (int i = beginKey; i <= endKey; i += 1) { 1334 int idx = i - beginKey; 1335 assertNull(list.get(idx)); 1336 } 1337 } 1338 }); 1339 } 1340 1341 void testIterAddList() 1342 throws Exception { 1343 1344 writeIterRunner.run(new TransactionWorker() { 1345 public void doWork() throws Exception { 1346 ListIterator i = (ListIterator) iterator(list); 1347 try { 1348 assertTrue(!i.hasNext()); 1349 i.add(makeVal(3)); 1350 assertTrue(!i.hasNext()); 1351 assertTrue(i.hasPrevious()); 1352 assertEquals(3, intVal(i.previous())); 1353 1354 i.add(makeVal(1)); 1355 assertTrue(i.hasPrevious()); 1356 assertTrue(i.hasNext()); 1357 assertEquals(1, intVal(i.previous())); 1358 assertTrue(i.hasNext()); 1359 assertEquals(1, intVal(i.next())); 1360 assertTrue(i.hasNext()); 1361 assertEquals(3, intVal(i.next())); 1362 assertEquals(3, intVal(i.previous())); 1363 1364 assertTrue(i.hasNext()); 1365 i.add(makeVal(2)); 1366 assertTrue(i.hasNext()); 1367 assertTrue(i.hasPrevious()); 1368 assertEquals(2, intVal(i.previous())); 1369 assertTrue(i.hasNext()); 1370 assertEquals(2, intVal(i.next())); 1371 assertTrue(i.hasNext()); 1372 assertEquals(3, intVal(i.next())); 1373 1374 assertTrue(!i.hasNext()); 1375 i.add(makeVal(4)); 1376 i.add(makeVal(5)); 1377 assertTrue(!i.hasNext()); 1378 assertEquals(5, intVal(i.previous())); 1379 assertEquals(4, intVal(i.previous())); 1380 assertEquals(3, intVal(i.previous())); 1381 assertEquals(2, intVal(i.previous())); 1382 assertEquals(1, intVal(i.previous())); 1383 assertTrue(!i.hasPrevious()); 1384 } finally { 1385 StoredIterator.close(i); 1386 } 1387 } 1388 }); 1389 } 1390 1391 void testIterAddDuplicates() 1392 throws Exception { 1393 1394 writeIterRunner.run(new TransactionWorker() { 1395 public void doWork() throws Exception { 1396 assertNull(imap.put(makeKey(1), makeVal(1))); 1397 ListIterator i = 1398 (ListIterator) iterator(imap.duplicates(makeKey(1))); 1399 try { 1400 if (imap.areDuplicatesOrdered()) { 1401 i.add(makeVal(1, 4)); 1402 i.add(makeVal(1, 2)); 1403 i.add(makeVal(1, 3)); 1404 while (i.hasPrevious()) i.previous(); 1405 assertEquals(1, intVal(i.next())); 1406 assertEquals(2, intVal(i.next())); 1407 assertEquals(3, intVal(i.next())); 1408 assertEquals(4, intVal(i.next())); 1409 assertTrue(!i.hasNext()); 1410 } else { 1411 assertEquals(1, intVal(i.next())); 1412 i.add(makeVal(1, 2)); 1413 i.add(makeVal(1, 3)); 1414 assertTrue(!i.hasNext()); 1415 assertTrue(i.hasPrevious()); 1416 assertEquals(3, intVal(i.previous())); 1417 assertEquals(2, intVal(i.previous())); 1418 assertEquals(1, intVal(i.previous())); 1419 assertTrue(!i.hasPrevious()); 1420 i.add(makeVal(1, 4)); 1421 i.add(makeVal(1, 5)); 1422 assertTrue(i.hasNext()); 1423 assertEquals(5, intVal(i.previous())); 1424 assertEquals(4, intVal(i.previous())); 1425 assertTrue(!i.hasPrevious()); 1426 assertEquals(4, intVal(i.next())); 1427 assertEquals(5, intVal(i.next())); 1428 assertEquals(1, intVal(i.next())); 1429 assertEquals(2, intVal(i.next())); 1430 assertEquals(3, intVal(i.next())); 1431 assertTrue(!i.hasNext()); 1432 } 1433 } finally { 1434 StoredIterator.close(i); 1435 } 1436 } 1437 }); 1438 } 1439 1440 void readAll() 1441 throws Exception { 1442 1443 readRunner.run(new TransactionWorker() { 1444 public void doWork() throws Exception { 1445 // map 1446 1447 assertNotNull(map.toString()); 1448 for (int i = beginKey; i <= endKey; i += 1) { 1449 Long key = makeKey(i); 1450 Object val = map.get(key); 1451 assertEquals(makeVal(i), val); 1452 assertTrue(map.containsKey(key)); 1453 assertTrue(map.containsValue(val)); 1454 assertTrue(map.keySet().contains(key)); 1455 assertTrue(map.values().contains(val)); 1456 assertTrue(map.duplicates(key).contains(val)); 1457 checkDupsSize(1, map.duplicates(key)); 1458 } 1459 assertNull(map.get(makeKey(-1))); 1460 assertNull(map.get(makeKey(0))); 1461 assertNull(map.get(makeKey(beginKey - 1))); 1462 assertNull(map.get(makeKey(endKey + 1))); 1463 checkDupsSize(0, map.duplicates(makeKey(-1))); 1464 checkDupsSize(0, map.duplicates(makeKey(0))); 1465 checkDupsSize(0, map.duplicates(makeKey(beginKey - 1))); 1466 checkDupsSize(0, map.duplicates(makeKey(endKey + 1))); 1467 1468 // entrySet 1469 1470 Set set = map.entrySet(); 1471 assertNotNull(set.toString()); 1472 assertEquals(beginKey > endKey, set.isEmpty()); 1473 Iterator iter = iterator(set); 1474 try { 1475 for (int i = beginKey; i <= endKey; i += 1) { 1476 assertTrue(iter.hasNext()); 1477 Map.Entry entry = (Map.Entry) iter.next(); 1478 Long key = (Long) entry.getKey(); 1479 Object val = entry.getValue(); 1480 if (map instanceof SortedMap) { 1481 assertEquals(intKey(key), i); 1482 } 1483 assertEquals(intKey(key), intVal(val)); 1484 assertTrue(set.contains(entry)); 1485 } 1486 assertTrue(!iter.hasNext()); 1487 } finally { 1488 StoredIterator.close(iter); 1489 } 1490 Map.Entry[] entries = 1491 (Map.Entry[]) set.toArray(new Map.Entry[0]); 1492 assertNotNull(entries); 1493 assertEquals(endKey - beginKey + 1, entries.length); 1494 for (int i = beginKey; i <= endKey; i += 1) { 1495 Map.Entry entry = entries[i - beginKey]; 1496 assertNotNull(entry); 1497 if (map instanceof SortedMap) { 1498 assertEquals(makeKey(i), entry.getKey()); 1499 assertEquals(makeVal(i), entry.getValue()); 1500 } 1501 } 1502 readIterator(set, iterator(set), beginKey, endKey); 1503 if (smap != null) { 1504 SortedSet sset = (SortedSet) set; 1505 if (beginKey == 1 && endKey >= 1) { 1506 readIterator(sset, 1507 iterator(sset.subSet(mapEntry(1), 1508 mapEntry(2))), 1509 1, 1); 1510 } 1511 if (beginKey <= 2 && endKey >= 2) { 1512 readIterator(sset, 1513 iterator(sset.subSet(mapEntry(2), 1514 mapEntry(3))), 1515 2, 2); 1516 } 1517 if (beginKey <= endKey) { 1518 readIterator(sset, 1519 iterator(sset.subSet 1520 (mapEntry(endKey), 1521 mapEntry(endKey + 1))), 1522 endKey, endKey); 1523 } 1524 if (isSubMap()) { 1525 if (beginKey <= endKey) { 1526 if (rangeType != TAIL) { 1527 try { 1528 sset.subSet(mapEntry(endKey + 1), 1529 mapEntry(endKey + 2)); 1530 fail(); 1531 } catch (IllegalArgumentException e) {} 1532 } 1533 if (rangeType != HEAD) { 1534 try { 1535 sset.subSet(mapEntry(0), 1536 mapEntry(1)); 1537 fail(); 1538 } catch (IllegalArgumentException e) {} 1539 } 1540 } 1541 } else { 1542 readIterator(sset, 1543 iterator(sset.subSet 1544 (mapEntry(endKey + 1), 1545 mapEntry(endKey + 2))), 1546 endKey, endKey - 1); 1547 readIterator(sset, 1548 iterator(sset.subSet(mapEntry(0), 1549 mapEntry(1))), 1550 0, -1); 1551 } 1552 } 1553 1554 // keySet 1555 1556 set = map.keySet(); 1557 assertNotNull(set.toString()); 1558 assertEquals(beginKey > endKey, set.isEmpty()); 1559 iter = iterator(set); 1560 try { 1561 for (int i = beginKey; i <= endKey; i += 1) { 1562 assertTrue(iter.hasNext()); 1563 Long key = (Long) iter.next(); 1564 assertTrue(set.contains(key)); 1565 Object val = map.get(key); 1566 if (map instanceof SortedMap) { 1567 assertEquals(key, makeKey(i)); 1568 } 1569 assertEquals(intKey(key), intVal(val)); 1570 } 1571 assertTrue("" + beginKey + ' ' + endKey, !iter.hasNext()); 1572 } finally { 1573 StoredIterator.close(iter); 1574 } 1575 Long[] keys = (Long[]) set.toArray(new Long[0]); 1576 assertNotNull(keys); 1577 assertEquals(endKey - beginKey + 1, keys.length); 1578 for (int i = beginKey; i <= endKey; i += 1) { 1579 Long key = keys[i - beginKey]; 1580 assertNotNull(key); 1581 if (map instanceof SortedMap) { 1582 assertEquals(makeKey(i), key); 1583 } 1584 } 1585 readIterator(set, iterator(set), beginKey, endKey); 1586 1587 // values 1588 1589 Collection coll = map.values(); 1590 assertNotNull(coll.toString()); 1591 assertEquals(beginKey > endKey, coll.isEmpty()); 1592 iter = iterator(coll); 1593 try { 1594 for (int i = beginKey; i <= endKey; i += 1) { 1595 assertTrue(iter.hasNext()); 1596 Object val = iter.next(); 1597 if (map instanceof SortedMap) { 1598 assertEquals(makeVal(i), val); 1599 } 1600 } 1601 assertTrue(!iter.hasNext()); 1602 } finally { 1603 StoredIterator.close(iter); 1604 } 1605 Object[] values = coll.toArray(); 1606 assertNotNull(values); 1607 assertEquals(endKey - beginKey + 1, values.length); 1608 for (int i = beginKey; i <= endKey; i += 1) { 1609 Object val = values[i - beginKey]; 1610 assertNotNull(val); 1611 if (map instanceof SortedMap) { 1612 assertEquals(makeVal(i), val); 1613 } 1614 } 1615 readIterator(coll, iterator(coll), beginKey, endKey); 1616 1617 // list 1618 1619 if (list != null) { 1620 assertNotNull(list.toString()); 1621 assertEquals(beginKey > endKey, list.isEmpty()); 1622 for (int i = beginKey; i <= endKey; i += 1) { 1623 int idx = i - beginKey; 1624 Object val = list.get(idx); 1625 assertEquals(makeVal(i), val); 1626 assertTrue(list.contains(val)); 1627 assertEquals(idx, list.indexOf(val)); 1628 assertEquals(idx, list.lastIndexOf(val)); 1629 } 1630 ListIterator li = (ListIterator) iterator(list); 1631 try { 1632 for (int i = beginKey; i <= endKey; i += 1) { 1633 int idx = i - beginKey; 1634 assertTrue(li.hasNext()); 1635 assertEquals(idx, li.nextIndex()); 1636 Object val = li.next(); 1637 assertEquals(makeVal(i), val); 1638 assertEquals(idx, li.previousIndex()); 1639 } 1640 assertTrue(!li.hasNext()); 1641 } finally { 1642 StoredIterator.close(li); 1643 } 1644 if (beginKey < endKey) { 1645 li = list.listIterator(1); 1646 try { 1647 for (int i = beginKey + 1; i <= endKey; i += 1) { 1648 int idx = i - beginKey; 1649 assertTrue(li.hasNext()); 1650 assertEquals(idx, li.nextIndex()); 1651 Object val = li.next(); 1652 assertEquals(makeVal(i), val); 1653 assertEquals(idx, li.previousIndex()); 1654 } 1655 assertTrue(!li.hasNext()); 1656 } finally { 1657 StoredIterator.close(li); 1658 } 1659 } 1660 values = list.toArray(); 1661 assertNotNull(values); 1662 assertEquals(endKey - beginKey + 1, values.length); 1663 for (int i = beginKey; i <= endKey; i += 1) { 1664 Object val = values[i - beginKey]; 1665 assertNotNull(val); 1666 assertEquals(makeVal(i), val); 1667 } 1668 readIterator(list, iterator(list), beginKey, endKey); 1669 } 1670 1671 // first/last 1672 1673 if (smap != null) { 1674 if (beginKey <= endKey && 1675 beginKey >= 1 && beginKey <= maxKey) { 1676 assertEquals(makeKey(beginKey), 1677 smap.firstKey()); 1678 assertEquals(makeKey(beginKey), 1679 ((SortedSet) smap.keySet()).first()); 1680 Object entry = ((SortedSet) smap.entrySet()).first(); 1681 assertEquals(makeKey(beginKey), 1682 ((Map.Entry) entry).getKey()); 1683 if (smap.values() instanceof SortedSet) { 1684 assertEquals(makeVal(beginKey), 1685 ((SortedSet) smap.values()).first()); 1686 } 1687 } else { 1688 assertNull(smap.firstKey()); 1689 assertNull(((SortedSet) smap.keySet()).first()); 1690 assertNull(((SortedSet) smap.entrySet()).first()); 1691 if (smap.values() instanceof SortedSet) { 1692 assertNull(((SortedSet) smap.values()).first()); 1693 } 1694 } 1695 if (beginKey <= endKey && 1696 endKey >= 1 && endKey <= maxKey) { 1697 assertEquals(makeKey(endKey), 1698 smap.lastKey()); 1699 assertEquals(makeKey(endKey), 1700 ((SortedSet) smap.keySet()).last()); 1701 Object entry = ((SortedSet) smap.entrySet()).last(); 1702 assertEquals(makeKey(endKey), 1703 ((Map.Entry) entry).getKey()); 1704 if (smap.values() instanceof SortedSet) { 1705 assertEquals(makeVal(endKey), 1706 ((SortedSet) smap.values()).last()); 1707 } 1708 } else { 1709 assertNull(smap.lastKey()); 1710 assertNull(((SortedSet) smap.keySet()).last()); 1711 assertNull(((SortedSet) smap.entrySet()).last()); 1712 if (smap.values() instanceof SortedSet) { 1713 assertNull(((SortedSet) smap.values()).last()); 1714 } 1715 } 1716 } 1717 } 1718 }); 1719 } 1720 1721 void readEven() 1722 throws Exception { 1723 1724 readRunner.run(new TransactionWorker() { 1725 public void doWork() throws Exception { 1726 int readBegin = ((beginKey & 1) != 0) ? 1727 (beginKey + 1) : beginKey; 1728 int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey; 1729 int readIncr = 2; 1730 1731 // map 1732 1733 for (int i = beginKey; i <= endKey; i += 1) { 1734 Long key = makeKey(i); 1735 if ((i & 1) == 0) { 1736 Object val = map.get(key); 1737 assertEquals(makeVal(i), val); 1738 assertTrue(map.containsKey(key)); 1739 assertTrue(map.containsValue(val)); 1740 assertTrue(map.keySet().contains(key)); 1741 assertTrue(map.values().contains(val)); 1742 assertTrue(map.duplicates(key).contains(val)); 1743 checkDupsSize(1, map.duplicates(key)); 1744 } else { 1745 Object val = makeVal(i); 1746 assertTrue(!map.containsKey(key)); 1747 assertTrue(!map.containsValue(val)); 1748 assertTrue(!map.keySet().contains(key)); 1749 assertTrue(!map.values().contains(val)); 1750 assertTrue(!map.duplicates(key).contains(val)); 1751 checkDupsSize(0, map.duplicates(key)); 1752 } 1753 } 1754 1755 // entrySet 1756 1757 Set set = map.entrySet(); 1758 assertEquals(beginKey > endKey, set.isEmpty()); 1759 Iterator iter = iterator(set); 1760 try { 1761 for (int i = readBegin; i <= readEnd; i += readIncr) { 1762 assertTrue(iter.hasNext()); 1763 Map.Entry entry = (Map.Entry) iter.next(); 1764 Long key = (Long) entry.getKey(); 1765 Object val = entry.getValue(); 1766 if (map instanceof SortedMap) { 1767 assertEquals(intKey(key), i); 1768 } 1769 assertEquals(intKey(key), intVal(val)); 1770 assertTrue(set.contains(entry)); 1771 } 1772 assertTrue(!iter.hasNext()); 1773 } finally { 1774 StoredIterator.close(iter); 1775 } 1776 1777 // keySet 1778 1779 set = map.keySet(); 1780 assertEquals(beginKey > endKey, set.isEmpty()); 1781 iter = iterator(set); 1782 try { 1783 for (int i = readBegin; i <= readEnd; i += readIncr) { 1784 assertTrue(iter.hasNext()); 1785 Long key = (Long) iter.next(); 1786 assertTrue(set.contains(key)); 1787 Object val = map.get(key); 1788 if (map instanceof SortedMap) { 1789 assertEquals(key, makeKey(i)); 1790 } 1791 assertEquals(intKey(key), intVal(val)); 1792 } 1793 assertTrue(!iter.hasNext()); 1794 } finally { 1795 StoredIterator.close(iter); 1796 } 1797 1798 // values 1799 1800 Collection coll = map.values(); 1801 assertEquals(beginKey > endKey, coll.isEmpty()); 1802 iter = iterator(coll); 1803 try { 1804 for (int i = readBegin; i <= readEnd; i += readIncr) { 1805 assertTrue(iter.hasNext()); 1806 Object val = iter.next(); 1807 if (map instanceof SortedMap) { 1808 assertEquals(makeVal(i), val); 1809 } 1810 } 1811 assertTrue(!iter.hasNext()); 1812 } finally { 1813 StoredIterator.close(iter); 1814 } 1815 1816 1817 // list not used since keys may not be renumbered for this 1818 // method to work in general 1819 1820 // first/last 1821 1822 if (smap != null) { 1823 if (readBegin <= readEnd && 1824 readBegin >= 1 && readBegin <= maxKey) { 1825 assertEquals(makeKey(readBegin), 1826 smap.firstKey()); 1827 assertEquals(makeKey(readBegin), 1828 ((SortedSet) smap.keySet()).first()); 1829 Object entry = ((SortedSet) smap.entrySet()).first(); 1830 assertEquals(makeKey(readBegin), 1831 ((Map.Entry) entry).getKey()); 1832 if (smap.values() instanceof SortedSet) { 1833 assertEquals(makeVal(readBegin), 1834 ((SortedSet) smap.values()).first()); 1835 } 1836 } else { 1837 assertNull(smap.firstKey()); 1838 assertNull(((SortedSet) smap.keySet()).first()); 1839 assertNull(((SortedSet) smap.entrySet()).first()); 1840 if (smap.values() instanceof SortedSet) { 1841 assertNull(((SortedSet) smap.values()).first()); 1842 } 1843 } 1844 if (readBegin <= readEnd && 1845 readEnd >= 1 && readEnd <= maxKey) { 1846 assertEquals(makeKey(readEnd), 1847 smap.lastKey()); 1848 assertEquals(makeKey(readEnd), 1849 ((SortedSet) smap.keySet()).last()); 1850 Object entry = ((SortedSet) smap.entrySet()).last(); 1851 assertEquals(makeKey(readEnd), 1852 ((Map.Entry) entry).getKey()); 1853 if (smap.values() instanceof SortedSet) { 1854 assertEquals(makeVal(readEnd), 1855 ((SortedSet) smap.values()).last()); 1856 } 1857 } else { 1858 assertNull(smap.lastKey()); 1859 assertNull(((SortedSet) smap.keySet()).last()); 1860 assertNull(((SortedSet) smap.entrySet()).last()); 1861 if (smap.values() instanceof SortedSet) { 1862 assertNull(((SortedSet) smap.values()).last()); 1863 } 1864 } 1865 } 1866 } 1867 }); 1868 } 1869 1870 void readEvenList() 1871 throws Exception { 1872 1873 readRunner.run(new TransactionWorker() { 1874 public void doWork() throws Exception { 1875 int readBegin = ((beginKey & 1) != 0) ? 1876 (beginKey + 1) : beginKey; 1877 int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey; 1878 int readIncr = 2; 1879 1880 assertEquals(beginKey > endKey, list.isEmpty()); 1881 ListIterator iter = (ListIterator) iterator(list); 1882 try { 1883 int idx = 0; 1884 for (int i = readBegin; i <= readEnd; i += readIncr) { 1885 assertTrue(iter.hasNext()); 1886 assertEquals(idx, iter.nextIndex()); 1887 Object val = iter.next(); 1888 assertEquals(idx, iter.previousIndex()); 1889 if (isEntityBinding) { 1890 assertEquals(i, intVal(val)); 1891 } else { 1892 assertEquals(makeVal(i), val); 1893 } 1894 idx += 1; 1895 } 1896 assertTrue(!iter.hasNext()); 1897 } finally { 1898 StoredIterator.close(iter); 1899 } 1900 } 1901 }); 1902 } 1903 1904 void readIterator(Collection coll, Iterator iter, 1905 int beginValue, int endValue) { 1906 1907 ListIterator li = (ListIterator) iter; 1908 boolean isList = (coll instanceof List); 1909 Iterator clone = null; 1910 try { 1911 // at beginning 1912 assertTrue(!li.hasPrevious()); 1913 assertTrue(!li.hasPrevious()); 1914 try { li.previous(); } catch (NoSuchElementException e) {} 1915 if (isList) { 1916 assertEquals(-1, li.previousIndex()); 1917 } 1918 if (endValue < beginValue) { 1919 // is empty 1920 assertTrue(!iter.hasNext()); 1921 try { iter.next(); } catch (NoSuchElementException e) {} 1922 if (isList) { 1923 assertEquals(Integer.MAX_VALUE, li.nextIndex()); 1924 } 1925 } 1926 // loop thru all and collect in array 1927 int[] values = new int[endValue - beginValue + 1]; 1928 for (int i = beginValue; i <= endValue; i += 1) { 1929 assertTrue(iter.hasNext()); 1930 int idx = i - beginKey; 1931 if (isList) { 1932 assertEquals(idx, li.nextIndex()); 1933 } 1934 int value = intIter(coll, iter.next()); 1935 if (isList) { 1936 assertEquals(idx, li.previousIndex()); 1937 } 1938 values[i - beginValue] = value; 1939 if (((StoredCollection) coll).isOrdered()) { 1940 assertEquals(i, value); 1941 } else { 1942 assertTrue(value >= beginValue); 1943 assertTrue(value <= endValue); 1944 } 1945 } 1946 // at end 1947 assertTrue(!iter.hasNext()); 1948 try { iter.next(); } catch (NoSuchElementException e) {} 1949 if (isList) { 1950 assertEquals(Integer.MAX_VALUE, li.nextIndex()); 1951 } 1952 // clone at same position 1953 clone = StoredCollections.iterator(iter); 1954 assertTrue(!clone.hasNext()); 1955 // loop thru in reverse 1956 for (int i = endValue; i >= beginValue; i -= 1) { 1957 assertTrue(li.hasPrevious()); 1958 int idx = i - beginKey; 1959 if (isList) { 1960 assertEquals(idx, li.previousIndex()); 1961 } 1962 int value = intIter(coll, li.previous()); 1963 if (isList) { 1964 assertEquals(idx, li.nextIndex()); 1965 } 1966 assertEquals(values[i - beginValue], value); 1967 } 1968 // clone should not have changed 1969 assertTrue(!clone.hasNext()); 1970 // at beginning 1971 assertTrue(!li.hasPrevious()); 1972 try { li.previous(); } catch (NoSuchElementException e) {} 1973 if (isList) { 1974 assertEquals(-1, li.previousIndex()); 1975 } 1976 // loop thru with some back-and-forth 1977 for (int i = beginValue; i <= endValue; i += 1) { 1978 assertTrue(iter.hasNext()); 1979 int idx = i - beginKey; 1980 if (isList) { 1981 assertEquals(idx, li.nextIndex()); 1982 } 1983 Object obj = iter.next(); 1984 if (isList) { 1985 assertEquals(idx, li.previousIndex()); 1986 } 1987 assertEquals(obj, li.previous()); 1988 if (isList) { 1989 assertEquals(idx, li.nextIndex()); 1990 } 1991 assertEquals(obj, iter.next()); 1992 if (isList) { 1993 assertEquals(idx, li.previousIndex()); 1994 } 1995 int value = intIter(coll, obj); 1996 assertEquals(values[i - beginValue], value); 1997 } 1998 // at end 1999 assertTrue(!iter.hasNext()); 2000 try { iter.next(); } catch (NoSuchElementException e) {} 2001 if (isList) { 2002 assertEquals(Integer.MAX_VALUE, li.nextIndex()); 2003 } 2004 } finally { 2005 StoredIterator.close(iter); 2006 StoredIterator.close(clone); 2007 } 2008 } 2009 2010 void bulkOperations() 2011 throws Exception { 2012 2013 writeRunner.run(new TransactionWorker() { 2014 public void doWork() throws Exception { 2015 HashMap hmap = new HashMap(); 2016 for (int i = Math.max(1, beginKey); 2017 i <= Math.min(maxKey, endKey); 2018 i += 1) { 2019 hmap.put(makeKey(i), makeVal(i)); 2020 } 2021 assertEquals(hmap, map); 2022 assertEquals(hmap.entrySet(), map.entrySet()); 2023 assertEquals(hmap.keySet(), map.keySet()); 2024 assertEquals(map.values(), hmap.values()); 2025 2026 assertTrue(map.entrySet().containsAll(hmap.entrySet())); 2027 assertTrue(map.keySet().containsAll(hmap.keySet())); 2028 assertTrue(map.values().containsAll(hmap.values())); 2029 2030 map.clear(); 2031 assertTrue(map.isEmpty()); 2032 imap.putAll(hmap); 2033 assertEquals(hmap, map); 2034 2035 assertTrue(map.entrySet().removeAll(hmap.entrySet())); 2036 assertTrue(map.entrySet().isEmpty()); 2037 assertTrue(!map.entrySet().removeAll(hmap.entrySet())); 2038 assertTrue(imap.entrySet().addAll(hmap.entrySet())); 2039 assertTrue(map.entrySet().containsAll(hmap.entrySet())); 2040 assertTrue(!imap.entrySet().addAll(hmap.entrySet())); 2041 assertEquals(hmap, map); 2042 2043 assertTrue(!map.entrySet().retainAll(hmap.entrySet())); 2044 assertEquals(hmap, map); 2045 assertTrue(map.entrySet().retainAll(Collections.EMPTY_SET)); 2046 assertTrue(map.isEmpty()); 2047 imap.putAll(hmap); 2048 assertEquals(hmap, map); 2049 2050 assertTrue(map.values().removeAll(hmap.values())); 2051 assertTrue(map.values().isEmpty()); 2052 assertTrue(!map.values().removeAll(hmap.values())); 2053 if (isEntityBinding) { 2054 assertTrue(imap.values().addAll(hmap.values())); 2055 assertTrue(map.values().containsAll(hmap.values())); 2056 assertTrue(!imap.values().addAll(hmap.values())); 2057 } else { 2058 imap.putAll(hmap); 2059 } 2060 assertEquals(hmap, map); 2061 2062 assertTrue(!map.values().retainAll(hmap.values())); 2063 assertEquals(hmap, map); 2064 assertTrue(map.values().retainAll(Collections.EMPTY_SET)); 2065 assertTrue(map.isEmpty()); 2066 imap.putAll(hmap); 2067 assertEquals(hmap, map); 2068 2069 assertTrue(map.keySet().removeAll(hmap.keySet())); 2070 assertTrue(map.keySet().isEmpty()); 2071 assertTrue(!map.keySet().removeAll(hmap.keySet())); 2072 assertTrue(imap.keySet().addAll(hmap.keySet())); 2073 assertTrue(imap.keySet().containsAll(hmap.keySet())); 2074 if (index != null) { 2075 assertTrue(map.keySet().isEmpty()); 2076 } 2077 assertTrue(!imap.keySet().addAll(hmap.keySet())); 2078 // restore values to non-null 2079 imap.keySet().removeAll(hmap.keySet()); 2080 imap.putAll(hmap); 2081 assertEquals(hmap, map); 2082 2083 assertTrue(!map.keySet().retainAll(hmap.keySet())); 2084 assertEquals(hmap, map); 2085 assertTrue(map.keySet().retainAll(Collections.EMPTY_SET)); 2086 assertTrue(map.isEmpty()); 2087 imap.putAll(hmap); 2088 assertEquals(hmap, map); 2089 } 2090 }); 2091 } 2092 2093 void bulkListOperations() 2094 throws Exception { 2095 2096 writeRunner.run(new TransactionWorker() { 2097 public void doWork() throws Exception { 2098 ArrayList alist = new ArrayList(); 2099 for (int i = beginKey; i <= endKey; i += 1) { 2100 alist.add(makeVal(i)); 2101 } 2102 2103 assertEquals(alist, list); 2104 assertTrue(list.containsAll(alist)); 2105 2106 if (isListAddAllowed()) { 2107 list.clear(); 2108 assertTrue(list.isEmpty()); 2109 assertTrue(ilist.addAll(alist)); 2110 assertEquals(alist, list); 2111 } 2112 2113 assertTrue(!list.retainAll(alist)); 2114 assertEquals(alist, list); 2115 2116 if (isListAddAllowed()) { 2117 assertTrue(list.retainAll(Collections.EMPTY_SET)); 2118 assertTrue(list.isEmpty()); 2119 assertTrue(ilist.addAll(alist)); 2120 assertEquals(alist, list); 2121 } 2122 2123 if (isListAddAllowed() && !isEntityBinding) { 2124 // deleting in a renumbered list with entity binding will 2125 // change the values dynamically, making it very difficult 2126 // to test 2127 assertTrue(list.removeAll(alist)); 2128 assertTrue(list.isEmpty()); 2129 assertTrue(!list.removeAll(alist)); 2130 assertTrue(ilist.addAll(alist)); 2131 assertTrue(list.containsAll(alist)); 2132 assertEquals(alist, list); 2133 } 2134 2135 if (isListAddAllowed() && !isEntityBinding) { 2136 // addAll at an index is also very difficult to test with 2137 // an entity binding 2138 2139 // addAll at first index 2140 ilist.addAll(beginKey, alist); 2141 assertTrue(list.containsAll(alist)); 2142 assertEquals(2 * alist.size(), countElements(list)); 2143 for (int i = beginKey; i <= endKey; i += 1) 2144 ilist.remove(beginKey); 2145 assertEquals(alist, list); 2146 2147 // addAll at last index 2148 ilist.addAll(endKey, alist); 2149 assertTrue(list.containsAll(alist)); 2150 assertEquals(2 * alist.size(), countElements(list)); 2151 for (int i = beginKey; i <= endKey; i += 1) 2152 ilist.remove(endKey); 2153 assertEquals(alist, list); 2154 2155 // addAll in the middle 2156 ilist.addAll(endKey - 1, alist); 2157 assertTrue(list.containsAll(alist)); 2158 assertEquals(2 * alist.size(), countElements(list)); 2159 for (int i = beginKey; i <= endKey; i += 1) 2160 ilist.remove(endKey - 1); 2161 assertEquals(alist, list); 2162 } 2163 } 2164 }); 2165 } 2166 2167 void readWriteRange(final int type, final int rangeBegin, 2168 final int rangeEnd) 2169 throws Exception { 2170 2171 writeRunner.run(new TransactionWorker() { 2172 public void doWork() throws Exception { 2173 setRange(type, rangeBegin, rangeEnd); 2174 createOutOfRange(rangeBegin, rangeEnd); 2175 if (rangeType != TAIL) { 2176 writeOutOfRange(new Long(rangeEnd + 1)); 2177 } 2178 if (rangeType != HEAD) { 2179 writeOutOfRange(new Long(rangeBegin - 1)); 2180 } 2181 if (rangeBegin <= rangeEnd) { 2182 updateAll(); 2183 } 2184 if (rangeBegin < rangeEnd && !map.areKeysRenumbered()) { 2185 bulkOperations(); 2186 removeIter(); 2187 } 2188 readAll(); 2189 clearRange(); 2190 } 2191 }); 2192 } 2193 2194 void setRange(int type, int rangeBegin, int rangeEnd) { 2195 2196 rangeType = type; 2197 saveMap = map; 2198 saveSMap = smap; 2199 saveList = list; 2200 int listBegin = rangeBegin - beginKey; 2201 boolean canMakeSubList = (list != null && listBegin>= 0); 2202 if (!canMakeSubList) { 2203 list = null; 2204 } 2205 if (list != null) { 2206 try { 2207 list.subList(-1, 0); 2208 fail(); 2209 } catch (IndexOutOfBoundsException e) { } 2210 } 2211 switch (type) { 2212 2213 case SUB: 2214 smap = (StoredSortedMap) smap.subMap(makeKey(rangeBegin), 2215 makeKey(rangeEnd + 1)); 2216 if (canMakeSubList) { 2217 list = (StoredList) list.subList(listBegin, 2218 rangeEnd + 1 - beginKey); 2219 } 2220 // check for equivalent ranges 2221 assertEquals(smap, 2222 ((StoredSortedMap) saveSMap).subMap( 2223 makeKey(rangeBegin), true, 2224 makeKey(rangeEnd + 1), false)); 2225 assertEquals(smap.entrySet(), 2226 ((StoredSortedEntrySet) saveSMap.entrySet()).subSet( 2227 mapEntry(rangeBegin), true, 2228 mapEntry(rangeEnd + 1), false)); 2229 assertEquals(smap.keySet(), 2230 ((StoredSortedKeySet) saveSMap.keySet()).subSet( 2231 makeKey(rangeBegin), true, 2232 makeKey(rangeEnd + 1), false)); 2233 if (smap.values() instanceof SortedSet) { 2234 assertEquals(smap.values(), 2235 ((StoredSortedValueSet) saveSMap.values()).subSet( 2236 makeVal(rangeBegin), true, 2237 makeVal(rangeEnd + 1), false)); 2238 } 2239 break; 2240 case HEAD: 2241 smap = (StoredSortedMap) smap.headMap(makeKey(rangeEnd + 1)); 2242 if (canMakeSubList) { 2243 list = (StoredList) list.subList(0, 2244 rangeEnd + 1 - beginKey); 2245 } 2246 // check for equivalent ranges 2247 assertEquals(smap, 2248 ((StoredSortedMap) saveSMap).headMap( 2249 makeKey(rangeEnd + 1), false)); 2250 assertEquals(smap.entrySet(), 2251 ((StoredSortedEntrySet) saveSMap.entrySet()).headSet( 2252 mapEntry(rangeEnd + 1), false)); 2253 assertEquals(smap.keySet(), 2254 ((StoredSortedKeySet) saveSMap.keySet()).headSet( 2255 makeKey(rangeEnd + 1), false)); 2256 if (smap.values() instanceof SortedSet) { 2257 assertEquals(smap.values(), 2258 ((StoredSortedValueSet) saveSMap.values()).headSet( 2259 makeVal(rangeEnd + 1), false)); 2260 } 2261 break; 2262 case TAIL: 2263 smap = (StoredSortedMap) smap.tailMap(makeKey(rangeBegin)); 2264 if (canMakeSubList) { 2265 list = (StoredList) list.subList(listBegin, 2266 maxKey + 1 - beginKey); 2267 } 2268 // check for equivalent ranges 2269 assertEquals(smap, 2270 ((StoredSortedMap) saveSMap).tailMap( 2271 makeKey(rangeBegin), true)); 2272 assertEquals(smap.entrySet(), 2273 ((StoredSortedEntrySet) saveSMap.entrySet()).tailSet( 2274 mapEntry(rangeBegin), true)); 2275 assertEquals(smap.keySet(), 2276 ((StoredSortedKeySet) saveSMap.keySet()).tailSet( 2277 makeKey(rangeBegin), true)); 2278 if (smap.values() instanceof SortedSet) { 2279 assertEquals(smap.values(), 2280 ((StoredSortedValueSet) saveSMap.values()).tailSet( 2281 makeVal(rangeBegin), true)); 2282 } 2283 break; 2284 default: throw new RuntimeException(); 2285 } 2286 map = smap; 2287 beginKey = rangeBegin; 2288 if (rangeBegin < 1 || rangeEnd > maxKey) { 2289 endKey = rangeBegin - 1; // force empty range for readAll() 2290 } else { 2291 endKey = rangeEnd; 2292 } 2293 } 2294 2295 void clearRange() { 2296 2297 rangeType = NONE; 2298 beginKey = 1; 2299 endKey = maxKey; 2300 map = saveMap; 2301 smap = saveSMap; 2302 list = saveList; 2303 } 2304 2305 void createOutOfRange(int rangeBegin, int rangeEnd) 2306 throws Exception { 2307 2308 // map 2309 2310 if (rangeType != TAIL) { 2311 try { 2312 smap.subMap(makeKey(rangeBegin), makeKey(rangeEnd + 2)); 2313 fail(); 2314 } catch (IllegalArgumentException e) { } 2315 try { 2316 smap.headMap(makeKey(rangeEnd + 2)); 2317 fail(); 2318 } catch (IllegalArgumentException e) { } 2319 checkDupsSize(0, smap.duplicates(makeKey(rangeEnd + 2))); 2320 } 2321 if (rangeType != HEAD) { 2322 try { 2323 smap.subMap(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1)); 2324 fail(); 2325 } catch (IllegalArgumentException e) { } 2326 try { 2327 smap.tailMap(makeKey(rangeBegin - 1)); 2328 fail(); 2329 } catch (IllegalArgumentException e) { } 2330 checkDupsSize(0, smap.duplicates(makeKey(rangeBegin - 1))); 2331 } 2332 2333 // keySet 2334 2335 if (rangeType != TAIL) { 2336 SortedSet sset = (SortedSet) map.keySet(); 2337 try { 2338 sset.subSet(makeKey(rangeBegin), makeKey(rangeEnd + 2)); 2339 fail(); 2340 } catch (IllegalArgumentException e) { } 2341 try { 2342 sset.headSet(makeKey(rangeEnd + 2)); 2343 fail(); 2344 } catch (IllegalArgumentException e) { } 2345 try { 2346 iterator(sset.subSet(makeKey(rangeEnd + 1), 2347 makeKey(rangeEnd + 2))); 2348 fail(); 2349 } catch (IllegalArgumentException e) { } 2350 } 2351 if (rangeType != HEAD) { 2352 SortedSet sset = (SortedSet) map.keySet(); 2353 try { 2354 sset.subSet(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1)); 2355 fail(); 2356 } catch (IllegalArgumentException e) { } 2357 try { 2358 sset.tailSet(makeKey(rangeBegin - 1)); 2359 fail(); 2360 } catch (IllegalArgumentException e) { } 2361 try { 2362 iterator(sset.subSet(makeKey(rangeBegin - 1), 2363 makeKey(rangeBegin))); 2364 fail(); 2365 } catch (IllegalArgumentException e) { } 2366 } 2367 2368 // entrySet 2369 2370 if (rangeType != TAIL) { 2371 SortedSet sset = (SortedSet) map.entrySet(); 2372 try { 2373 sset.subSet(mapEntry(rangeBegin), mapEntry(rangeEnd + 2)); 2374 fail(); 2375 } catch (IllegalArgumentException e) { } 2376 try { 2377 sset.headSet(mapEntry(rangeEnd + 2)); 2378 fail(); 2379 } catch (IllegalArgumentException e) { } 2380 try { 2381 iterator(sset.subSet(mapEntry(rangeEnd + 1), 2382 mapEntry(rangeEnd + 2))); 2383 fail(); 2384 } catch (IllegalArgumentException e) { } 2385 } 2386 if (rangeType != HEAD) { 2387 SortedSet sset = (SortedSet) map.entrySet(); 2388 try { 2389 sset.subSet(mapEntry(rangeBegin - 1), mapEntry(rangeEnd + 1)); 2390 fail(); 2391 } catch (IllegalArgumentException e) { } 2392 try { 2393 sset.tailSet(mapEntry(rangeBegin - 1)); 2394 fail(); 2395 } catch (IllegalArgumentException e) { } 2396 try { 2397 iterator(sset.subSet(mapEntry(rangeBegin - 1), 2398 mapEntry(rangeBegin))); 2399 fail(); 2400 } catch (IllegalArgumentException e) { } 2401 } 2402 2403 // values 2404 2405 if (map.values() instanceof SortedSet) { 2406 SortedSet sset = (SortedSet) map.values(); 2407 if (rangeType != TAIL) { 2408 try { 2409 sset.subSet(makeVal(rangeBegin), 2410 makeVal(rangeEnd + 2)); 2411 fail(); 2412 } catch (IllegalArgumentException e) { } 2413 try { 2414 sset.headSet(makeVal(rangeEnd + 2)); 2415 fail(); 2416 } catch (IllegalArgumentException e) { } 2417 } 2418 if (rangeType != HEAD) { 2419 try { 2420 sset.subSet(makeVal(rangeBegin - 1), 2421 makeVal(rangeEnd + 1)); 2422 fail(); 2423 } catch (IllegalArgumentException e) { } 2424 try { 2425 sset.tailSet(makeVal(rangeBegin - 1)); 2426 fail(); 2427 } catch (IllegalArgumentException e) { } 2428 } 2429 } 2430 2431 // list 2432 2433 if (list != null) { 2434 int size = rangeEnd - rangeBegin + 1; 2435 try { 2436 list.subList(0, size + 1); 2437 fail(); 2438 } catch (IndexOutOfBoundsException e) { } 2439 try { 2440 list.subList(-1, size); 2441 fail(); 2442 } catch (IndexOutOfBoundsException e) { } 2443 try { 2444 list.subList(2, 1); 2445 fail(); 2446 } catch (IndexOutOfBoundsException e) { } 2447 try { 2448 list.subList(size, size); 2449 fail(); 2450 } catch (IndexOutOfBoundsException e) { } 2451 } 2452 } 2453 2454 void writeOutOfRange(Long badNewKey) 2455 throws Exception { 2456 2457 try { 2458 map.put(badNewKey, makeVal(badNewKey)); 2459 fail(); 2460 } catch (IllegalArgumentException e) { 2461 assertTrue(e.toString(), index == null); 2462 } catch (UnsupportedOperationException e) { 2463 assertTrue(index != null); 2464 } 2465 try { 2466 map.keySet().add(badNewKey); 2467 fail(); 2468 } catch (IllegalArgumentException e) { 2469 assertTrue(index == null); 2470 } catch (UnsupportedOperationException e) { 2471 assertTrue(index != null); 2472 } 2473 try { 2474 map.values().add(makeEntity(badNewKey)); 2475 fail(); 2476 } catch (IllegalArgumentException e) { 2477 assertTrue(isEntityBinding && index == null); 2478 } catch (UnsupportedOperationException e) { 2479 assertTrue(!(isEntityBinding && index == null)); 2480 } 2481 if (list != null) { 2482 int i = badNewKey.intValue() - beginKey; 2483 try { 2484 list.set(i, makeVal(i)); 2485 fail(); 2486 } catch (IndexOutOfBoundsException e) { 2487 assertTrue(index == null); 2488 } catch (UnsupportedOperationException e) { 2489 assertTrue(index != null); 2490 } 2491 try { 2492 list.add(i, makeVal(badNewKey)); 2493 fail(); 2494 } catch (UnsupportedOperationException e) { 2495 } 2496 } 2497 } 2498 2499 void readWriteDuplicates() 2500 throws Exception { 2501 2502 writeRunner.run(new TransactionWorker() { 2503 public void doWork() throws Exception { 2504 if (index == null) { 2505 readWritePrimaryDuplicates(beginKey); 2506 readWritePrimaryDuplicates(beginKey + 1); 2507 readWritePrimaryDuplicates(endKey); 2508 readWritePrimaryDuplicates(endKey - 1); 2509 } else { 2510 readWriteIndexedDuplicates(beginKey); 2511 readWriteIndexedDuplicates(beginKey + 1); 2512 readWriteIndexedDuplicates(endKey); 2513 readWriteIndexedDuplicates(endKey - 1); 2514 } 2515 } 2516 }); 2517 } 2518 2519 void readWritePrimaryDuplicates(int i) 2520 throws Exception { 2521 2522 Collection dups; 2523 // make duplicate values 2524 final Long key = makeKey(i); 2525 final Object[] values = new Object[5]; 2526 for (int j = 0; j < values.length; j += 1) { 2527 values[j] = isEntityBinding 2528 ? makeEntity(i, i + j) 2529 : makeVal(i + j); 2530 } 2531 // add duplicates 2532 outerLoop: for (int writeMode = 0;; writeMode += 1) { 2533 //System.out.println("write mode " + writeMode); 2534 switch (writeMode) { 2535 case 0: 2536 case 1: { 2537 // write with Map.put() 2538 for (int j = 1; j < values.length; j += 1) { 2539 map.put(key, values[j]); 2540 } 2541 break; 2542 } 2543 case 2: { 2544 // write with Map.duplicates().add() 2545 dups = map.duplicates(key); 2546 for (int j = 1; j < values.length; j += 1) { 2547 dups.add(values[j]); 2548 } 2549 break; 2550 } 2551 case 3: { 2552 // write with Map.duplicates().iterator().add() 2553 writeIterRunner.run(new TransactionWorker() { 2554 public void doWork() throws Exception { 2555 Collection dups = map.duplicates(key); 2556 Iterator iter = iterator(dups); 2557 assertEquals(values[0], iter.next()); 2558 assertTrue(!iter.hasNext()); 2559 try { 2560 for (int j = 1; j < values.length; j += 1) { 2561 ((ListIterator) iter).add(values[j]); 2562 } 2563 } finally { 2564 StoredIterator.close(iter); 2565 } 2566 } 2567 }); 2568 break; 2569 } 2570 case 4: { 2571 // write with Map.values().add() 2572 if (!isEntityBinding) { 2573 continue; 2574 } 2575 Collection set = map.values(); 2576 for (int j = 1; j < values.length; j += 1) { 2577 set.add(values[j]); 2578 } 2579 break; 2580 } 2581 default: { 2582 break outerLoop; 2583 } 2584 } 2585 checkDupsSize(values.length, map.duplicates(key)); 2586 // read duplicates 2587 readDuplicates(i, key, values); 2588 // remove duplicates 2589 switch (writeMode) { 2590 case 0: { 2591 // remove with Map.remove() 2592 checkDupsSize(values.length, map.duplicates(key)); 2593 map.remove(key); // remove all values 2594 checkDupsSize(0, map.duplicates(key)); 2595 map.put(key, values[0]); // put back original value 2596 checkDupsSize(1, map.duplicates(key)); 2597 break; 2598 } 2599 case 1: { 2600 // remove with Map.keySet().remove() 2601 map.keySet().remove(key); // remove all values 2602 map.put(key, values[0]); // put back original value 2603 break; 2604 } 2605 case 2: { 2606 // remove with Map.duplicates().clear() 2607 dups = map.duplicates(key); 2608 dups.clear(); // remove all values 2609 dups.add(values[0]); // put back original value 2610 break; 2611 } 2612 case 3: { 2613 // remove with Map.duplicates().iterator().remove() 2614 writeIterRunner.run(new TransactionWorker() { 2615 public void doWork() throws Exception { 2616 Collection dups = map.duplicates(key); 2617 Iterator iter = iterator(dups); 2618 try { 2619 for (int j = 0; j < values.length; j += 1) { 2620 assertEquals(values[j], iter.next()); 2621 if (j != 0) { 2622 iter.remove(); 2623 } 2624 } 2625 } finally { 2626 StoredIterator.close(iter); 2627 } 2628 } 2629 }); 2630 break; 2631 } 2632 case 4: { 2633 // remove with Map.values().remove() 2634 if (!isEntityBinding) { 2635 throw new IllegalStateException(); 2636 } 2637 Collection set = map.values(); 2638 for (int j = 1; j < values.length; j += 1) { 2639 set.remove(values[j]); 2640 } 2641 break; 2642 } 2643 default: throw new IllegalStateException(); 2644 } 2645 // verify that only original value is present 2646 dups = map.duplicates(key); 2647 assertTrue(dups.contains(values[0])); 2648 for (int j = 1; j < values.length; j += 1) { 2649 assertTrue(!dups.contains(values[j])); 2650 } 2651 checkDupsSize(1, dups); 2652 } 2653 } 2654 2655 void readWriteIndexedDuplicates(int i) 2656 throws Exception { 2657 2658 Object key = makeKey(i); 2659 Object[] values = new Object[3]; 2660 values[0] = makeVal(i); 2661 for (int j = 1; j < values.length; j += 1) { 2662 values[j] = isEntityBinding 2663 ? makeEntity(endKey + j, i) 2664 : makeVal(i); 2665 } 2666 // add duplicates 2667 for (int j = 1; j < values.length; j += 1) { 2668 imap.put(makeKey(endKey + j), values[j]); 2669 } 2670 // read duplicates 2671 readDuplicates(i, key, values); 2672 // remove duplicates 2673 for (int j = 1; j < values.length; j += 1) { 2674 imap.remove(makeKey(endKey + j)); 2675 } 2676 checkDupsSize(1, map.duplicates(key)); 2677 } 2678 2679 void readDuplicates(int i, Object key, Object[] values) { 2680 2681 boolean isOrdered = map.isOrdered(); 2682 Collection dups; 2683 Iterator iter; 2684 // read with Map.duplicates().iterator() 2685 dups = map.duplicates(key); 2686 checkDupsSize(values.length, dups); 2687 iter = iterator(dups); 2688 try { 2689 for (int j = 0; j < values.length; j += 1) { 2690 assertTrue(iter.hasNext()); 2691 Object val = iter.next(); 2692 assertEquals(values[j], val); 2693 } 2694 assertTrue(!iter.hasNext()); 2695 } finally { 2696 StoredIterator.close(iter); 2697 } 2698 // read with Map.values().iterator() 2699 Collection clone = ((StoredCollection) map.values()).toList(); 2700 iter = iterator(map.values()); 2701 try { 2702 for (int j = beginKey; j < i; j += 1) { 2703 Object val = iter.next(); 2704 assertTrue(clone.remove(makeVal(j))); 2705 if (isOrdered) { 2706 assertEquals(makeVal(j), val); 2707 } 2708 } 2709 for (int j = 0; j < values.length; j += 1) { 2710 Object val = iter.next(); 2711 assertTrue(clone.remove(values[j])); 2712 if (isOrdered) { 2713 assertEquals(values[j], val); 2714 } 2715 } 2716 for (int j = i + 1; j <= endKey; j += 1) { 2717 Object val = iter.next(); 2718 assertTrue(clone.remove(makeVal(j))); 2719 if (isOrdered) { 2720 assertEquals(makeVal(j), val); 2721 } 2722 } 2723 assertTrue(!iter.hasNext()); 2724 assertTrue(clone.isEmpty()); 2725 } finally { 2726 StoredIterator.close(iter); 2727 } 2728 // read with Map.entrySet().iterator() 2729 clone = ((StoredCollection) map.entrySet()).toList(); 2730 iter = iterator(map.entrySet()); 2731 try { 2732 for (int j = beginKey; j < i; j += 1) { 2733 Map.Entry entry = (Map.Entry) iter.next(); 2734 assertTrue(clone.remove(mapEntry(j))); 2735 if (isOrdered) { 2736 assertEquals(makeVal(j), entry.getValue()); 2737 assertEquals(makeKey(j), entry.getKey()); 2738 } 2739 } 2740 for (int j = 0; j < values.length; j += 1) { 2741 Map.Entry entry = (Map.Entry) iter.next(); 2742 assertTrue(clone.remove(mapEntry(makeKey(i), values[j]))); 2743 if (isOrdered) { 2744 assertEquals(values[j], entry.getValue()); 2745 assertEquals(makeKey(i), entry.getKey()); 2746 } 2747 } 2748 for (int j = i + 1; j <= endKey; j += 1) { 2749 Map.Entry entry = (Map.Entry) iter.next(); 2750 assertTrue(clone.remove(mapEntry(j))); 2751 if (isOrdered) { 2752 assertEquals(makeVal(j), entry.getValue()); 2753 assertEquals(makeKey(j), entry.getKey()); 2754 } 2755 } 2756 assertTrue(!iter.hasNext()); 2757 assertTrue(clone.isEmpty()); 2758 } finally { 2759 StoredIterator.close(iter); 2760 } 2761 // read with Map.keySet().iterator() 2762 clone = ((StoredCollection) map.keySet()).toList(); 2763 iter = iterator(map.keySet()); 2764 try { 2765 for (int j = beginKey; j < i; j += 1) { 2766 Object val = iter.next(); 2767 assertTrue(clone.remove(makeKey(j))); 2768 if (isOrdered) { 2769 assertEquals(makeKey(j), val); 2770 } 2771 } 2772 if (true) { 2773 // only one key is iterated for all duplicates 2774 Object val = iter.next(); 2775 assertTrue(clone.remove(makeKey(i))); 2776 if (isOrdered) { 2777 assertEquals(makeKey(i), val); 2778 } 2779 } 2780 for (int j = i + 1; j <= endKey; j += 1) { 2781 Object val = iter.next(); 2782 assertTrue(clone.remove(makeKey(j))); 2783 if (isOrdered) { 2784 assertEquals(makeKey(j), val); 2785 } 2786 } 2787 assertTrue(!iter.hasNext()); 2788 assertTrue(clone.isEmpty()); 2789 } finally { 2790 StoredIterator.close(iter); 2791 } 2792 } 2793 2794 void duplicatesNotAllowed() { 2795 2796 Collection dups = map.duplicates(makeKey(beginKey)); 2797 try { 2798 dups.add(makeVal(beginKey)); 2799 fail(); 2800 } catch (UnsupportedOperationException expected) { } 2801 ListIterator iter = (ListIterator) iterator(dups); 2802 try { 2803 iter.add(makeVal(beginKey)); 2804 fail(); 2805 } catch (UnsupportedOperationException expected) { 2806 } finally { 2807 StoredIterator.close(iter); 2808 } 2809 } 2810 2811 void listOperationsNotAllowed() { 2812 2813 ListIterator iter = (ListIterator) iterator(map.values()); 2814 try { 2815 try { 2816 iter.nextIndex(); 2817 fail(); 2818 } catch (UnsupportedOperationException expected) { } 2819 try { 2820 iter.previousIndex(); 2821 fail(); 2822 } catch (UnsupportedOperationException expected) { } 2823 } finally { 2824 StoredIterator.close(iter); 2825 } 2826 } 2827 2828 void testCdbLocking() { 2829 2830 Iterator readIterator; 2831 Iterator writeIterator; 2832 StoredKeySet set = (StoredKeySet) map.keySet(); 2833 2834 // can open two CDB read cursors 2835 readIterator = set.storedIterator(false); 2836 try { 2837 Iterator readIterator2 = set.storedIterator(false); 2838 StoredIterator.close(readIterator2); 2839 } finally { 2840 StoredIterator.close(readIterator); 2841 } 2842 2843 // can open two CDB write cursors 2844 writeIterator = set.storedIterator(true); 2845 try { 2846 Iterator writeIterator2 = set.storedIterator(true); 2847 StoredIterator.close(writeIterator2); 2848 } finally { 2849 StoredIterator.close(writeIterator); 2850 } 2851 2852 // cannot open CDB write cursor when read cursor is open, 2853 readIterator = set.storedIterator(false); 2854 try { 2855 writeIterator = set.storedIterator(true); 2856 fail(); 2857 StoredIterator.close(writeIterator); 2858 } catch (IllegalStateException e) { 2859 } finally { 2860 StoredIterator.close(readIterator); 2861 } 2862 2863 if (index == null) { 2864 // cannot put() with read cursor open 2865 readIterator = set.storedIterator(false); 2866 try { 2867 map.put(makeKey(1), makeVal(1)); 2868 fail(); 2869 } catch (IllegalStateException e) { 2870 } finally { 2871 StoredIterator.close(readIterator); 2872 } 2873 2874 // cannot append() with write cursor open with RECNO/QUEUE only 2875 writeIterator = set.storedIterator(true); 2876 try { 2877 if (testStore.isQueueOrRecno()) { 2878 try { 2879 map.append(makeVal(1)); 2880 fail(); 2881 } catch (IllegalStateException e) {} 2882 } else { 2883 map.append(makeVal(1)); 2884 } 2885 } finally { 2886 StoredIterator.close(writeIterator); 2887 } 2888 } 2889 } 2890 2891 Object makeVal(int key) { 2892 2893 if (isEntityBinding) { 2894 return makeEntity(key); 2895 } else { 2896 return new Long(key + 100); 2897 } 2898 } 2899 2900 Object makeVal(int key, int val) { 2901 2902 if (isEntityBinding) { 2903 return makeEntity(key, val); 2904 } else { 2905 return makeVal(val); 2906 } 2907 } 2908 2909 Object makeEntity(int key, int val) { 2910 2911 return new TestEntity(key, val + 100); 2912 } 2913 2914 int intVal(Object val) { 2915 2916 if (isEntityBinding) { 2917 return ((TestEntity) val).value - 100; 2918 } else { 2919 return ((Long) val).intValue() - 100; 2920 } 2921 } 2922 2923 int intKey(Object key) { 2924 2925 return ((Long) key).intValue(); 2926 } 2927 2928 Object makeVal(Long key) { 2929 2930 return makeVal(key.intValue()); 2931 } 2932 2933 Object makeEntity(int key) { 2934 2935 return makeEntity(key, key); 2936 } 2937 2938 Object makeEntity(Long key) { 2939 2940 return makeEntity(key.intValue()); 2941 } 2942 2943 int intIter(Collection coll, Object value) { 2944 2945 if (coll instanceof StoredKeySet) { 2946 return intKey(value); 2947 } else { 2948 if (coll instanceof StoredEntrySet) { 2949 value = ((Map.Entry) value).getValue(); 2950 } 2951 return intVal(value); 2952 } 2953 } 2954 2955 Map.Entry mapEntry(Object key, Object val) { 2956 2957 return new MapEntryParameter(key, val); 2958 } 2959 2960 Map.Entry mapEntry(int key) { 2961 2962 return new MapEntryParameter(makeKey(key), makeVal(key)); 2963 } 2964 2965 Long makeKey(int key) { 2966 2967 return new Long(key); 2968 } 2969 2970 boolean isSubMap() { 2971 2972 return rangeType != NONE; 2973 } 2974 2975 void checkDupsSize(int expected, Collection coll) { 2976 2977 assertEquals(expected, coll.size()); 2978 if (coll instanceof StoredCollection) { 2979 StoredIterator i = ((StoredCollection) coll).storedIterator(false); 2980 try { 2981 int actual = 0; 2982 if (i.hasNext()) { 2983 i.next(); 2984 actual = i.count(); 2985 } 2986 assertEquals(expected, actual); 2987 } finally { 2988 StoredIterator.close(i); 2989 } 2990 } 2991 } 2992 2993 private boolean isListAddAllowed() { 2994 2995 return list != null && testStore.isQueueOrRecno() && 2996 list.areKeysRenumbered(); 2997 } 2998 2999 private int countElements(Collection coll) { 3000 3001 int count = 0; 3002 Iterator iter = iterator(coll); 3003 try { 3004 while (iter.hasNext()) { 3005 iter.next(); 3006 count += 1; 3007 } 3008 } finally { 3009 StoredIterator.close(iter); 3010 } 3011 return count; 3012 } 3013} 3014