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