00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 package com.sleepycat.collections.test;
00011
00012 import java.util.ArrayList;
00013 import java.util.Collection;
00014 import java.util.Collections;
00015 import java.util.HashMap;
00016 import java.util.Iterator;
00017 import java.util.List;
00018 import java.util.ListIterator;
00019 import java.util.Map;
00020 import java.util.NoSuchElementException;
00021 import java.util.Set;
00022 import java.util.SortedMap;
00023 import java.util.SortedSet;
00024
00025 import junit.framework.Test;
00026 import junit.framework.TestCase;
00027 import junit.framework.TestSuite;
00028
00029 import com.sleepycat.bind.EntityBinding;
00030 import com.sleepycat.bind.EntryBinding;
00031 import com.sleepycat.collections.CurrentTransaction;
00032 import com.sleepycat.collections.MapEntryParameter;
00033 import com.sleepycat.collections.StoredCollection;
00034 import com.sleepycat.collections.StoredCollections;
00035 import com.sleepycat.collections.StoredContainer;
00036 import com.sleepycat.collections.StoredEntrySet;
00037 import com.sleepycat.collections.StoredIterator;
00038 import com.sleepycat.collections.StoredKeySet;
00039 import com.sleepycat.collections.StoredList;
00040 import com.sleepycat.collections.StoredMap;
00041 import com.sleepycat.collections.StoredSortedEntrySet;
00042 import com.sleepycat.collections.StoredSortedKeySet;
00043 import com.sleepycat.collections.StoredSortedMap;
00044 import com.sleepycat.collections.StoredSortedValueSet;
00045 import com.sleepycat.collections.StoredValueSet;
00046 import com.sleepycat.collections.TransactionRunner;
00047 import com.sleepycat.collections.TransactionWorker;
00048 import com.sleepycat.compat.DbCompat;
00049 import com.sleepycat.db.Database;
00050 import com.sleepycat.db.DatabaseException;
00051 import com.sleepycat.db.Environment;
00052 import com.sleepycat.util.ExceptionUnwrapper;
00053
00057 public class CollectionTest extends TestCase {
00058
00059 private static final int NONE = 0;
00060 private static final int SUB = 1;
00061 private static final int HEAD = 2;
00062 private static final int TAIL = 3;
00063
00064 private static final int MAX_KEY = 6;
00065
00066 private int beginKey = 1;
00067 private int endKey = MAX_KEY;
00068
00069 private Environment env;
00070 private CurrentTransaction currentTxn;
00071 private Database store;
00072 private Database index;
00073 private boolean isEntityBinding;
00074 private boolean isAutoCommit;
00075 private TestStore testStore;
00076 private String testName;
00077 private EntryBinding keyBinding;
00078 private EntryBinding valueBinding;
00079 private EntityBinding entityBinding;
00080 private TransactionRunner readRunner;
00081 private TransactionRunner writeRunner;
00082 private TransactionRunner writeIterRunner;
00083 private TestEnv testEnv;
00084
00085 private StoredMap map;
00086 private StoredMap imap;
00087 private StoredSortedMap smap;
00088 private StoredMap saveMap;
00089 private StoredSortedMap saveSMap;
00090 private int rangeType;
00091 private StoredList list;
00092 private StoredList ilist;
00093 private StoredList saveList;
00094 private StoredKeySet keySet;
00095 private StoredValueSet valueSet;
00096
00101 public static void main(String[] args)
00102 throws Exception {
00103
00104 if (args.length == 1 &&
00105 (args[0].equals("-h") || args[0].equals("-help"))) {
00106 usage();
00107 } else {
00108 junit.framework.TestResult tr =
00109 junit.textui.TestRunner.run(suite(args));
00110 if (tr.errorCount() > 0 ||
00111 tr.failureCount() > 0) {
00112 System.exit(1);
00113 } else {
00114 System.exit(0);
00115 }
00116 }
00117 }
00118
00119 private static void usage() {
00120
00121 System.out.println(
00122 "Usage: java com.sleepycat.collections.test.CollectionTest\n" +
00123 " -h | -help\n" +
00124 " [testName]...\n" +
00125 " where testName has the format:\n" +
00126 " <env>-<store>-{entity|value}\n" +
00127 " <env> is:\n" +
00128 " bdb | cdb | txn\n" +
00129 " <store> is:\n" +
00130 " btree-uniq | btree-dup | btree-dupsort | btree-recnum |\n" +
00131 " hash-uniq | hash-dup | hash-dupsort |\n" +
00132 " queue | recno | recno-renum\n" +
00133 " For example: bdb-btree-uniq-entity\n" +
00134 " If no arguments are given then all tests are run.");
00135 System.exit(2);
00136 }
00137
00138 public static Test suite()
00139 throws Exception {
00140
00141 return suite(null);
00142 }
00143
00144 static Test suite(String[] args)
00145 throws Exception {
00146
00147 TestSuite suite = new TestSuite();
00148 for (int i = 0; i < TestEnv.ALL.length; i += 1) {
00149 for (int j = 0; j < TestStore.ALL.length; j += 1) {
00150 for (int k = 0; k < 2; k += 1) {
00151 boolean entityBinding = (k != 0);
00152
00153 addTest(args, suite, new CollectionTest(
00154 TestEnv.ALL[i], TestStore.ALL[j],
00155 entityBinding, false));
00156
00157 if (TestEnv.ALL[i].isTxnMode()) {
00158 addTest(args, suite, new CollectionTest(
00159 TestEnv.ALL[i], TestStore.ALL[j],
00160 entityBinding, true));
00161 }
00162 }
00163 }
00164 }
00165 return suite;
00166 }
00167
00168 private static void addTest(String[] args, TestSuite suite,
00169 CollectionTest test) {
00170
00171 if (args == null || args.length == 0) {
00172 suite.addTest(test);
00173 } else {
00174 for (int t = 0; t < args.length; t += 1) {
00175 if (args[t].equals(test.testName)) {
00176 suite.addTest(test);
00177 break;
00178 }
00179 }
00180 }
00181 }
00182
00183 public CollectionTest(TestEnv testEnv, TestStore testStore,
00184 boolean isEntityBinding, boolean isAutoCommit) {
00185
00186 super(null);
00187
00188 this.testEnv = testEnv;
00189 this.testStore = testStore;
00190 this.isEntityBinding = isEntityBinding;
00191 this.isAutoCommit = isAutoCommit;
00192
00193 keyBinding = testStore.getKeyBinding();
00194 valueBinding = testStore.getValueBinding();
00195 entityBinding = testStore.getEntityBinding();
00196
00197 testName = testEnv.getName() + '-' + testStore.getName() +
00198 (isEntityBinding ? "-entity" : "-value") +
00199 (isAutoCommit ? "-autocommit" : "");
00200 setName(testName);
00201 }
00202
00203 public void runTest()
00204 throws Exception {
00205
00206 DbTestUtil.printTestName(DbTestUtil.qualifiedTestName(this));
00207 try {
00208 env = testEnv.open(testName);
00209 currentTxn = CurrentTransaction.getInstance(env);
00210
00211
00212
00213
00214
00215
00216 TransactionRunner normalRunner = newTransactionRunner(env);
00217 normalRunner.setAllowNestedTransactions(
00218 DbCompat.NESTED_TRANSACTIONS);
00219 TransactionRunner nullRunner = new NullTransactionRunner(env);
00220 readRunner = nullRunner;
00221 writeIterRunner = normalRunner;
00222 if (isAutoCommit) {
00223 writeRunner = nullRunner;
00224 } else {
00225 writeRunner = normalRunner;
00226 }
00227
00228 store = testStore.open(env, "unindexed.db");
00229 testUnindexed();
00230 store.close();
00231 store = null;
00232
00233 TestStore indexOf = testStore.getIndexOf();
00234 if (indexOf != null) {
00235 store = indexOf.open(env, "indexed.db");
00236 index = testStore.openIndex(store, "index.db");
00237 testIndexed();
00238 index.close();
00239 index = null;
00240 store.close();
00241 store = null;
00242 }
00243 env.close();
00244 env = null;
00245 } catch (Exception e) {
00246 throw ExceptionUnwrapper.unwrap(e);
00247 } finally {
00248 if (index != null) {
00249 try {
00250 index.close();
00251 } catch (Exception e) {
00252 }
00253 }
00254 if (store != null) {
00255 try {
00256 store.close();
00257 } catch (Exception e) {
00258 }
00259 }
00260 if (env != null) {
00261 try {
00262 env.close();
00263 } catch (Exception e) {
00264 }
00265 }
00266
00267 index = null;
00268 store = null;
00269 env = null;
00270 currentTxn = null;
00271 readRunner = null;
00272 writeRunner = null;
00273 writeIterRunner = null;
00274 map = null;
00275 imap = null;
00276 smap = null;
00277 saveMap = null;
00278 saveSMap = null;
00279 list = null;
00280 ilist = null;
00281 saveList = null;
00282 keySet = null;
00283 valueSet = null;
00284 testEnv = null;
00285 testStore = null;
00286 }
00287 }
00288
00292 protected TransactionRunner newTransactionRunner(Environment env)
00293 throws DatabaseException {
00294
00295 return new TransactionRunner(env);
00296 }
00297
00298 void testCreation(StoredContainer cont)
00299 throws Exception {
00300
00301 assertEquals(index != null, cont.isSecondary());
00302 assertEquals(testStore.isOrdered(), cont.isOrdered());
00303 assertEquals(testStore.areKeysRenumbered(), cont.areKeysRenumbered());
00304 assertEquals(testStore.areDuplicatesAllowed(),
00305 cont.areDuplicatesAllowed());
00306 assertEquals(testEnv.isTxnMode(), cont.isTransactional());
00307 try {
00308 cont.size();
00309 fail();
00310 }
00311 catch (UnsupportedOperationException expected) {}
00312 }
00313
00314 void testMapCreation(Map map)
00315 throws Exception {
00316
00317 assertTrue(map.values() instanceof Set);
00318 assertEquals(testStore.isOrdered(),
00319 map.keySet() instanceof SortedSet);
00320 assertEquals(testStore.isOrdered(),
00321 map.entrySet() instanceof SortedSet);
00322 assertEquals(testStore.isOrdered() && isEntityBinding,
00323 map.values() instanceof SortedSet);
00324 }
00325
00326 void testUnindexed()
00327 throws Exception {
00328
00329
00330 if (testStore.isOrdered()) {
00331 if (isEntityBinding) {
00332 smap = new StoredSortedMap(store, keyBinding,
00333 entityBinding,
00334 testStore.getKeyAssigner());
00335 valueSet = new StoredSortedValueSet(store, entityBinding,
00336 true);
00337 } else {
00338 smap = new StoredSortedMap(store, keyBinding,
00339 valueBinding,
00340 testStore.getKeyAssigner());
00341
00342
00343 }
00344 keySet = new StoredSortedKeySet(store, keyBinding, true);
00345 map = smap;
00346 } else {
00347 if (isEntityBinding) {
00348 map = new StoredMap(store, keyBinding, entityBinding,
00349 testStore.getKeyAssigner());
00350 valueSet = new StoredValueSet(store, entityBinding, true);
00351 } else {
00352 map = new StoredMap(store, keyBinding, valueBinding,
00353 testStore.getKeyAssigner());
00354 valueSet = new StoredValueSet(store, valueBinding, true);
00355 }
00356 smap = null;
00357 keySet = new StoredKeySet(store, keyBinding, true);
00358 }
00359 imap = map;
00360
00361
00362 if (testStore.hasRecNumAccess()) {
00363 if (isEntityBinding) {
00364 ilist = new StoredList(store, entityBinding,
00365 testStore.getKeyAssigner());
00366 } else {
00367 ilist = new StoredList(store, valueBinding,
00368 testStore.getKeyAssigner());
00369 }
00370 list = ilist;
00371 } else {
00372 try {
00373 if (isEntityBinding) {
00374 ilist = new StoredList(store, entityBinding,
00375 testStore.getKeyAssigner());
00376 } else {
00377 ilist = new StoredList(store, valueBinding,
00378 testStore.getKeyAssigner());
00379 }
00380 fail();
00381 } catch (IllegalArgumentException expected) {}
00382 }
00383
00384 testCreation(map);
00385 if (list != null) {
00386 testCreation(list);
00387 assertNotNull(smap);
00388 }
00389 testMapCreation(map);
00390 addAll();
00391 testAll();
00392 }
00393
00394 void testIndexed()
00395 throws Exception {
00396
00397
00398 if (isEntityBinding) {
00399 map = new StoredMap(store, keyBinding, entityBinding,
00400 testStore.getKeyAssigner());
00401 } else {
00402 map = new StoredMap(store, keyBinding, valueBinding,
00403 testStore.getKeyAssigner());
00404 }
00405 imap = map;
00406 smap = null;
00407
00408 if (testStore.hasRecNumAccess()) {
00409 if (isEntityBinding) {
00410 list = new StoredList(store, entityBinding,
00411 testStore.getKeyAssigner());
00412 } else {
00413 list = new StoredList(store, valueBinding,
00414 testStore.getKeyAssigner());
00415 }
00416 ilist = list;
00417 }
00418
00419 addAll();
00420 readAll();
00421
00422
00423 if (testStore.isOrdered()) {
00424 if (isEntityBinding) {
00425 map = smap = new StoredSortedMap(index, keyBinding,
00426 entityBinding, true);
00427 valueSet = new StoredSortedValueSet(index, entityBinding,
00428 true);
00429 } else {
00430 map = smap = new StoredSortedMap(index, keyBinding,
00431 valueBinding, true);
00432
00433
00434 }
00435 keySet = new StoredSortedKeySet(index, keyBinding, true);
00436 } else {
00437 if (isEntityBinding) {
00438 map = new StoredMap(index, keyBinding, entityBinding, true);
00439 valueSet = new StoredValueSet(index, entityBinding, true);
00440 } else {
00441 map = new StoredMap(index, keyBinding, valueBinding, true);
00442 valueSet = new StoredValueSet(index, valueBinding, true);
00443 }
00444 smap = null;
00445 keySet = new StoredKeySet(index, keyBinding, true);
00446 }
00447
00448
00449 if (testStore.hasRecNumAccess()) {
00450 if (isEntityBinding) {
00451 list = new StoredList(index, entityBinding, true);
00452 } else {
00453 list = new StoredList(index, valueBinding, true);
00454 }
00455 } else {
00456 try {
00457 if (isEntityBinding) {
00458 list = new StoredList(index, entityBinding, true);
00459 } else {
00460 list = new StoredList(index, valueBinding, true);
00461 }
00462 fail();
00463 }
00464 catch (IllegalArgumentException expected) {}
00465 }
00466
00467 testCreation(map);
00468 testCreation((StoredContainer) map.values());
00469 testCreation((StoredContainer) map.keySet());
00470 testCreation((StoredContainer) map.entrySet());
00471 if (list != null) {
00472 testCreation(list);
00473 assertNotNull(smap);
00474 }
00475 testMapCreation(map);
00476 testAll();
00477 }
00478
00479 void testAll()
00480 throws Exception {
00481
00482 checkKeySetAndValueSet();
00483 readAll();
00484 updateAll();
00485 readAll();
00486 if (!map.areKeysRenumbered()) {
00487 removeOdd();
00488 readEven();
00489 addOdd();
00490 readAll();
00491 removeOddIter();
00492 readEven();
00493 if (imap.areDuplicatesAllowed()) {
00494 addOddDup();
00495 } else {
00496 addOdd();
00497 }
00498 readAll();
00499 removeOddEntry();
00500 readEven();
00501 addOdd();
00502 readAll();
00503 if (isEntityBinding) {
00504 removeOddEntity();
00505 readEven();
00506 addOddEntity();
00507 readAll();
00508 }
00509 bulkOperations();
00510 }
00511 if (isListAddAllowed()) {
00512 removeOddList();
00513 readEvenList();
00514 addOddList();
00515 readAll();
00516 if (!isEntityBinding) {
00517 removeOddListValue();
00518 readEvenList();
00519 addOddList();
00520 readAll();
00521 }
00522 }
00523 if (list != null) {
00524 bulkListOperations();
00525 } else {
00526 listOperationsNotAllowed();
00527 }
00528 if (smap != null) {
00529 readWriteRange(SUB, 1, 1);
00530 readWriteRange(HEAD, 1, 1);
00531 readWriteRange(SUB, 1, MAX_KEY);
00532 readWriteRange(HEAD, 1, MAX_KEY);
00533 readWriteRange(TAIL, 1, MAX_KEY);
00534 readWriteRange(SUB, 1, 3);
00535 readWriteRange(HEAD, 1, 3);
00536 readWriteRange(SUB, 2, 2);
00537 readWriteRange(SUB, 2, MAX_KEY);
00538 readWriteRange(TAIL, 2, MAX_KEY);
00539 readWriteRange(SUB, MAX_KEY, MAX_KEY);
00540 readWriteRange(TAIL, MAX_KEY, MAX_KEY);
00541 readWriteRange(SUB, MAX_KEY + 1, MAX_KEY + 1);
00542 readWriteRange(TAIL, MAX_KEY + 1, MAX_KEY + 1);
00543 readWriteRange(SUB, 0, 0);
00544 readWriteRange(HEAD, 0, 0);
00545 }
00546 updateAll();
00547 readAll();
00548 if (map.areDuplicatesAllowed()) {
00549 readWriteDuplicates();
00550 readAll();
00551 } else {
00552 duplicatesNotAllowed();
00553 readAll();
00554 }
00555 if (testEnv.isCdbMode()) {
00556 testCdbLocking();
00557 }
00558 removeAll();
00559 if (isListAddAllowed()) {
00560 testIterAddList();
00561 clearAll();
00562 }
00563 if (imap.areDuplicatesAllowed()) {
00564 testIterAddDuplicates();
00565 clearAll();
00566 }
00567 if (isListAddAllowed()) {
00568 addAllList();
00569 readAll();
00570 removeAllList();
00571 }
00572 appendAll();
00573 }
00574
00575 void checkKeySetAndValueSet() {
00576
00577
00578
00579 assertTrue(imap.keySet().equals(keySet));
00580 if (valueSet != null) {
00581 assertTrue(imap.values().equals(valueSet));
00582 }
00583 }
00584
00585 void addAll()
00586 throws Exception {
00587
00588 writeRunner.run(new TransactionWorker() {
00589 public void doWork() throws Exception {
00590 assertTrue(imap.isEmpty());
00591 Iterator iter = imap.entrySet().iterator();
00592 try {
00593 assertTrue(!iter.hasNext());
00594 } finally {
00595 StoredIterator.close(iter);
00596 }
00597 assertEquals(0, imap.keySet().toArray().length);
00598 assertEquals(0, imap.keySet().toArray(new Object[0]).length);
00599 assertEquals(0, imap.entrySet().toArray().length);
00600 assertEquals(0, imap.entrySet().toArray(new Object[0]).length);
00601 assertEquals(0, imap.values().toArray().length);
00602 assertEquals(0, imap.values().toArray(new Object[0]).length);
00603
00604 for (int i = beginKey; i <= endKey; i += 1) {
00605 Long key = makeKey(i);
00606 Object val = makeVal(i);
00607 assertNull(imap.get(key));
00608 assertTrue(!imap.keySet().contains(key));
00609 assertTrue(!imap.values().contains(val));
00610 assertNull(imap.put(key, val));
00611 assertEquals(val, imap.get(key));
00612 assertTrue(imap.keySet().contains(key));
00613 assertTrue(imap.values().contains(val));
00614 assertTrue(imap.duplicates(key).contains(val));
00615 if (!imap.areDuplicatesAllowed()) {
00616 assertEquals(val, imap.put(key, val));
00617 }
00618 checkDupsSize(1, imap.duplicates(key));
00619 }
00620 assertTrue(!imap.isEmpty());
00621 }
00622 });
00623 }
00624
00625 void appendAll()
00626 throws Exception {
00627
00628 writeRunner.run(new TransactionWorker() {
00629 public void doWork() throws Exception {
00630 assertTrue(imap.isEmpty());
00631
00632 TestKeyAssigner keyAssigner = testStore.getKeyAssigner();
00633 if (keyAssigner != null) {
00634 keyAssigner.reset();
00635 }
00636
00637 for (int i = beginKey; i <= endKey; i += 1) {
00638 boolean useList = (i & 1) == 0;
00639 Long key = makeKey(i);
00640 Object val = makeVal(i);
00641 assertNull(imap.get(key));
00642 if (keyAssigner != null) {
00643 if (useList && ilist != null) {
00644 assertEquals(i - 1, ilist.append(val));
00645 } else {
00646 assertEquals(key, imap.append(val));
00647 }
00648 assertEquals(val, imap.get(key));
00649 } else {
00650 Long recnoKey;
00651 if (useList && ilist != null) {
00652 recnoKey = new Long(ilist.append(val) + 1);
00653 } else {
00654 recnoKey = (Long) imap.append(val);
00655 }
00656 assertNotNull(recnoKey);
00657 Object recnoVal;
00658 if (isEntityBinding) {
00659 recnoVal = makeEntity(recnoKey.intValue(), i);
00660 } else {
00661 recnoVal = val;
00662 }
00663 assertEquals(recnoVal, imap.get(recnoKey));
00664 }
00665 }
00666 }
00667 });
00668 }
00669
00670 void updateAll()
00671 throws Exception {
00672
00673 writeRunner.run(new TransactionWorker() {
00674 public void doWork() throws Exception {
00675 for (int i = beginKey; i <= endKey; i += 1) {
00676 Long key = makeKey(i);
00677 Object val = makeVal(i);
00678 if (!imap.areDuplicatesAllowed()) {
00679 assertEquals(val, imap.put(key, val));
00680 }
00681 if (isEntityBinding) {
00682 assertTrue(!imap.values().add(val));
00683 }
00684 checkDupsSize(1, imap.duplicates(key));
00685 if (ilist != null) {
00686 int idx = i - 1;
00687 assertEquals(val, ilist.set(idx, val));
00688 }
00689 }
00690 updateIter(map.entrySet());
00691 updateIter(map.values());
00692 if (beginKey <= endKey) {
00693 ListIterator iter = (ListIterator) map.keySet().iterator();
00694 try {
00695 assertNotNull(iter.next());
00696 iter.set(makeKey(beginKey));
00697 fail();
00698 } catch (UnsupportedOperationException e) {
00699 } finally {
00700 StoredIterator.close(iter);
00701 }
00702 }
00703 if (list != null) {
00704 updateIter(list);
00705 }
00706 }
00707 });
00708 }
00709
00710 void updateIter(final Collection coll)
00711 throws Exception {
00712
00713 writeIterRunner.run(new TransactionWorker() {
00714 public void doWork() throws Exception {
00715 ListIterator iter = (ListIterator) coll.iterator();
00716 try {
00717 for (int i = beginKey; i <= endKey; i += 1) {
00718 assertTrue(iter.hasNext());
00719 Object obj = iter.next();
00720 if (index != null) {
00721 try {
00722 setValuePlusOne(iter, obj);
00723 fail();
00724 }
00725 catch (UnsupportedOperationException e) {}
00726 } else if
00727 (((StoredCollection) coll).areDuplicatesOrdered()) {
00728 try {
00729 setValuePlusOne(iter, obj);
00730 fail();
00731 } catch (RuntimeException e) {
00732 Exception e2 = ExceptionUnwrapper.unwrap(e);
00733 assertTrue(e2.getClass().getName(),
00734 e2 instanceof IllegalArgumentException ||
00735 e2 instanceof DatabaseException);
00736 }
00737 } else {
00738 setValuePlusOne(iter, obj);
00739 }
00740 }
00741 assertTrue(!iter.hasNext());
00742 } finally {
00743 StoredIterator.close(iter);
00744 }
00745 }
00746 });
00747 }
00748
00749 void setValuePlusOne(ListIterator iter, Object obj) {
00750
00751 if (obj instanceof Map.Entry) {
00752 Map.Entry entry = (Map.Entry) obj;
00753 Long key = (Long) entry.getKey();
00754 Object oldVal = entry.getValue();
00755 Object val = makeVal(key.intValue() + 1);
00756 if (isEntityBinding) {
00757 try {
00758
00759 entry.setValue(val);
00760 fail();
00761 }
00762 catch (IllegalArgumentException e) {}
00763 val = makeEntity(key.intValue(), key.intValue() + 1);
00764 }
00765 entry.setValue(val);
00766 assertEquals(val, entry.getValue());
00767 assertEquals(val, map.get(key));
00768 assertTrue(map.duplicates(key).contains(val));
00769 checkDupsSize(1, map.duplicates(key));
00770 entry.setValue(oldVal);
00771 assertEquals(oldVal, entry.getValue());
00772 assertEquals(oldVal, map.get(key));
00773 assertTrue(map.duplicates(key).contains(oldVal));
00774 checkDupsSize(1, map.duplicates(key));
00775 } else {
00776 Object oldVal = obj;
00777 Long key = makeKey(intVal(obj));
00778 Object val = makeVal(key.intValue() + 1);
00779 if (isEntityBinding) {
00780 try {
00781
00782 iter.set(val);
00783 fail();
00784 }
00785 catch (IllegalArgumentException e) {}
00786 val = makeEntity(key.intValue(), key.intValue() + 1);
00787 }
00788 iter.set(val);
00789 assertEquals(val, map.get(key));
00790 assertTrue(map.duplicates(key).contains(val));
00791 checkDupsSize(1, map.duplicates(key));
00792 iter.set(oldVal);
00793 assertEquals(oldVal, map.get(key));
00794 assertTrue(map.duplicates(key).contains(oldVal));
00795 checkDupsSize(1, map.duplicates(key));
00796 }
00797 }
00798
00799 void removeAll()
00800 throws Exception {
00801
00802 writeIterRunner.run(new TransactionWorker() {
00803 public void doWork() throws Exception {
00804 assertTrue(!map.isEmpty());
00805 ListIterator iter = null;
00806 try {
00807 if (list != null) {
00808 iter = list.listIterator();
00809 } else {
00810 iter = (ListIterator) map.values().iterator();
00811 }
00812 iteratorSetAndRemoveNotAllowed(iter);
00813
00814 Object val = iter.next();
00815 assertNotNull(val);
00816 iter.remove();
00817 iteratorSetAndRemoveNotAllowed(iter);
00818
00819 if (index == null) {
00820 val = iter.next();
00821 assertNotNull(val);
00822 iter.set(val);
00823
00824 if (map.areDuplicatesAllowed()) {
00825 iter.add(makeVal(intVal(val), intVal(val) + 1));
00826 iteratorSetAndRemoveNotAllowed(iter);
00827 }
00828 }
00829 } finally {
00830 StoredIterator.close(iter);
00831 }
00832 map.clear();
00833 assertTrue(map.isEmpty());
00834 assertTrue(map.entrySet().isEmpty());
00835 assertTrue(map.keySet().isEmpty());
00836 assertTrue(map.values().isEmpty());
00837 for (int i = beginKey; i <= endKey; i += 1) {
00838 Long key = makeKey(i);
00839 Object val = makeVal(i);
00840 assertNull(map.get(key));
00841 assertTrue(!map.duplicates(key).contains(val));
00842 checkDupsSize(0, map.duplicates(key));
00843 }
00844 }
00845 });
00846 }
00847
00848 void clearAll()
00849 throws Exception {
00850
00851 writeRunner.run(new TransactionWorker() {
00852 public void doWork() throws Exception {
00853 map.clear();
00854 assertTrue(map.isEmpty());
00855 }
00856 });
00857 }
00858
00859 void iteratorSetAndRemoveNotAllowed(ListIterator i) {
00860
00861 try {
00862 i.remove();
00863 fail();
00864 } catch (IllegalStateException e) {}
00865
00866 if (index == null) {
00867 try {
00868 Object val = makeVal(1);
00869 i.set(val);
00870 fail();
00871 }
00872 catch (IllegalStateException e) {}
00873 }
00874 }
00875
00876 void removeOdd()
00877 throws Exception {
00878
00879 writeRunner.run(new TransactionWorker() {
00880 public void doWork() throws Exception {
00881 boolean toggle = false;
00882 for (int i = beginKey; i <= endKey; i += 2) {
00883 toggle = !toggle;
00884 Long key = makeKey(i);
00885 Object val = makeVal(i);
00886 if (toggle) {
00887 assertTrue(map.keySet().contains(key));
00888 assertTrue(map.keySet().remove(key));
00889 assertTrue(!map.keySet().contains(key));
00890 } else {
00891 assertTrue(map.containsValue(val));
00892 Object oldVal = map.remove(key);
00893 assertEquals(oldVal, val);
00894 assertTrue(!map.containsKey(key));
00895 assertTrue(!map.containsValue(val));
00896 }
00897 assertNull(map.get(key));
00898 assertTrue(!map.duplicates(key).contains(val));
00899 checkDupsSize(0, map.duplicates(key));
00900 }
00901 }
00902 });
00903 }
00904
00905 void removeOddEntity()
00906 throws Exception {
00907
00908 writeRunner.run(new TransactionWorker() {
00909 public void doWork() throws Exception {
00910 for (int i = beginKey; i <= endKey; i += 2) {
00911 Long key = makeKey(i);
00912 Object val = makeVal(i);
00913 assertTrue(map.values().contains(val));
00914 assertTrue(map.values().remove(val));
00915 assertTrue(!map.values().contains(val));
00916 assertNull(map.get(key));
00917 assertTrue(!map.duplicates(key).contains(val));
00918 checkDupsSize(0, map.duplicates(key));
00919 }
00920 }
00921 });
00922 }
00923
00924 void removeOddEntry()
00925 throws Exception {
00926
00927 writeRunner.run(new TransactionWorker() {
00928 public void doWork() throws Exception {
00929 for (int i = beginKey; i <= endKey; i += 2) {
00930 Long key = makeKey(i);
00931 Object val = mapEntry(i);
00932 assertTrue(map.entrySet().contains(val));
00933 assertTrue(map.entrySet().remove(val));
00934 assertTrue(!map.entrySet().contains(val));
00935 assertNull(map.get(key));
00936 }
00937 }
00938 });
00939 }
00940
00941 void removeOddIter()
00942 throws Exception {
00943
00944 writeIterRunner.run(new TransactionWorker() {
00945 public void doWork() throws Exception {
00946 Iterator iter = map.keySet().iterator();
00947 try {
00948 for (int i = beginKey; i <= endKey; i += 1) {
00949 assertTrue(iter.hasNext());
00950 Long key = (Long) iter.next();
00951 assertNotNull(key);
00952 if (map instanceof SortedMap) {
00953 assertEquals(makeKey(i), key);
00954 }
00955 if ((key.intValue() & 1) != 0) {
00956 iter.remove();
00957 }
00958 }
00959 } finally {
00960 StoredIterator.close(iter);
00961 }
00962 }
00963 });
00964 }
00965
00966 void removeOddList()
00967 throws Exception {
00968
00969 writeRunner.run(new TransactionWorker() {
00970 public void doWork() throws Exception {
00971 for (int i = beginKey; i <= endKey; i += 2) {
00972
00973
00974
00975 int idx = (i - beginKey) / 2;
00976 Object val = makeVal(i);
00977 if (!isEntityBinding) {
00978 assertTrue(list.contains(val));
00979 assertEquals(val, list.get(idx));
00980 assertEquals(idx, list.indexOf(val));
00981 }
00982 assertNotNull(list.get(idx));
00983 if (isEntityBinding) {
00984 assertNotNull(list.remove(idx));
00985 } else {
00986 assertTrue(list.contains(val));
00987 assertEquals(val, list.remove(idx));
00988 }
00989 assertTrue(!list.remove(val));
00990 assertTrue(!list.contains(val));
00991 assertTrue(!val.equals(list.get(idx)));
00992 }
00993 }
00994 });
00995 }
00996
00997 void removeOddListValue()
00998 throws Exception {
00999
01000 writeRunner.run(new TransactionWorker() {
01001 public void doWork() throws Exception {
01002 for (int i = beginKey; i <= endKey; i += 2) {
01003
01004
01005
01006 int idx = (i - beginKey) / 2;
01007 Object val = makeVal(i);
01008 assertTrue(list.contains(val));
01009 assertEquals(val, list.get(idx));
01010 assertEquals(idx, list.indexOf(val));
01011 assertTrue(list.remove(val));
01012 assertTrue(!list.remove(val));
01013 assertTrue(!list.contains(val));
01014 assertTrue(!val.equals(list.get(idx)));
01015 }
01016 }
01017 });
01018 }
01019
01020 void addOdd()
01021 throws Exception {
01022
01023 writeRunner.run(new TransactionWorker() {
01024 public void doWork() throws Exception {
01025
01026 for (int i = beginKey; i <= endKey; i += 2) {
01027 Long key = makeKey(i);
01028 Object val = makeVal(i);
01029 assertNull(imap.get(key));
01030 assertNull(imap.put(key, val));
01031 assertEquals(val, imap.get(key));
01032 assertTrue(imap.duplicates(key).contains(val));
01033 checkDupsSize(1, imap.duplicates(key));
01034 if (isEntityBinding) {
01035 assertTrue(!imap.values().add(val));
01036 }
01037 if (!imap.areDuplicatesAllowed()) {
01038 assertEquals(val, imap.put(key, val));
01039 }
01040 }
01041 }
01042 });
01043 }
01044
01045 void addOddEntity()
01046 throws Exception {
01047
01048 writeRunner.run(new TransactionWorker() {
01049 public void doWork() throws Exception {
01050
01051 for (int i = beginKey; i <= endKey; i += 2) {
01052 Long key = makeKey(i);
01053 Object val = makeVal(i);
01054 assertNull(imap.get(key));
01055 assertTrue(!imap.values().contains(val));
01056 assertTrue(imap.values().add(val));
01057 assertEquals(val, imap.get(key));
01058 assertTrue(imap.values().contains(val));
01059 assertTrue(imap.duplicates(key).contains(val));
01060 checkDupsSize(1, imap.duplicates(key));
01061 if (isEntityBinding) {
01062 assertTrue(!imap.values().add(val));
01063 }
01064 }
01065 }
01066 });
01067 }
01068
01069 void addOddDup()
01070 throws Exception {
01071
01072 writeRunner.run(new TransactionWorker() {
01073 public void doWork() throws Exception {
01074
01075 for (int i = beginKey; i <= endKey; i += 2) {
01076 Long key = makeKey(i);
01077 Object val = makeVal(i);
01078 assertNull(imap.get(key));
01079 assertTrue(!imap.values().contains(val));
01080 assertTrue(imap.duplicates(key).add(val));
01081 assertEquals(val, imap.get(key));
01082 assertTrue(imap.values().contains(val));
01083 assertTrue(imap.duplicates(key).contains(val));
01084 checkDupsSize(1, imap.duplicates(key));
01085 assertTrue(!imap.duplicates(key).add(val));
01086 if (isEntityBinding) {
01087 assertTrue(!imap.values().add(val));
01088 }
01089 }
01090 }
01091 });
01092 }
01093
01094 void addOddList()
01095 throws Exception {
01096
01097 writeRunner.run(new TransactionWorker() {
01098 public void doWork() throws Exception {
01099 for (int i = beginKey; i <= endKey; i += 2) {
01100 int idx = i - beginKey;
01101 Object val = makeVal(i);
01102 assertTrue(!list.contains(val));
01103 assertTrue(!val.equals(list.get(idx)));
01104 list.add(idx, val);
01105 assertTrue(list.contains(val));
01106 assertEquals(val, list.get(idx));
01107 }
01108 }
01109 });
01110 }
01111
01112 void addAllList()
01113 throws Exception {
01114
01115 writeRunner.run(new TransactionWorker() {
01116 public void doWork() throws Exception {
01117 for (int i = beginKey; i <= endKey; i += 1) {
01118 int idx = i - beginKey;
01119 Object val = makeVal(i);
01120 assertTrue(!list.contains(val));
01121 assertTrue(list.add(val));
01122 assertTrue(list.contains(val));
01123 assertEquals(val, list.get(idx));
01124 }
01125 }
01126 });
01127 }
01128
01129 void removeAllList()
01130 throws Exception {
01131
01132 writeRunner.run(new TransactionWorker() {
01133 public void doWork() throws Exception {
01134 assertTrue(!list.isEmpty());
01135 list.clear();
01136 assertTrue(list.isEmpty());
01137 for (int i = beginKey; i <= endKey; i += 1) {
01138 int idx = i - beginKey;
01139 Object val = makeVal(i);
01140 assertNull(list.get(idx));
01141 }
01142 }
01143 });
01144 }
01145
01146 void testIterAddList()
01147 throws Exception {
01148
01149 writeIterRunner.run(new TransactionWorker() {
01150 public void doWork() throws Exception {
01151 ListIterator i = list.listIterator();
01152 try {
01153 assertTrue(!i.hasNext());
01154 i.add(makeVal(3));
01155 assertTrue(!i.hasNext());
01156 assertTrue(i.hasPrevious());
01157 assertEquals(3, intVal(i.previous()));
01158
01159 i.add(makeVal(1));
01160 assertTrue(i.hasPrevious());
01161 assertTrue(i.hasNext());
01162 assertEquals(1, intVal(i.previous()));
01163 assertTrue(i.hasNext());
01164 assertEquals(1, intVal(i.next()));
01165 assertTrue(i.hasNext());
01166 assertEquals(3, intVal(i.next()));
01167 assertEquals(3, intVal(i.previous()));
01168
01169 assertTrue(i.hasNext());
01170 i.add(makeVal(2));
01171 assertTrue(i.hasNext());
01172 assertTrue(i.hasPrevious());
01173 assertEquals(2, intVal(i.previous()));
01174 assertTrue(i.hasNext());
01175 assertEquals(2, intVal(i.next()));
01176 assertTrue(i.hasNext());
01177 assertEquals(3, intVal(i.next()));
01178
01179 assertTrue(!i.hasNext());
01180 i.add(makeVal(4));
01181 i.add(makeVal(5));
01182 assertTrue(!i.hasNext());
01183 assertEquals(5, intVal(i.previous()));
01184 assertEquals(4, intVal(i.previous()));
01185 assertEquals(3, intVal(i.previous()));
01186 assertEquals(2, intVal(i.previous()));
01187 assertEquals(1, intVal(i.previous()));
01188 assertTrue(!i.hasPrevious());
01189 } finally {
01190 StoredIterator.close(i);
01191 }
01192 }
01193 });
01194 }
01195
01196 void testIterAddDuplicates()
01197 throws Exception {
01198
01199 writeIterRunner.run(new TransactionWorker() {
01200 public void doWork() throws Exception {
01201 assertNull(imap.put(makeKey(1), makeVal(1)));
01202 ListIterator i =
01203 (ListIterator) imap.duplicates(makeKey(1)).iterator();
01204 try {
01205 if (imap.areDuplicatesOrdered()) {
01206 i.add(makeVal(1, 4));
01207 i.add(makeVal(1, 2));
01208 i.add(makeVal(1, 3));
01209 while (i.hasPrevious()) i.previous();
01210 assertEquals(1, intVal(i.next()));
01211 assertEquals(2, intVal(i.next()));
01212 assertEquals(3, intVal(i.next()));
01213 assertEquals(4, intVal(i.next()));
01214 assertTrue(!i.hasNext());
01215 } else {
01216 assertEquals(1, intVal(i.next()));
01217 i.add(makeVal(1, 2));
01218 i.add(makeVal(1, 3));
01219 assertTrue(!i.hasNext());
01220 assertTrue(i.hasPrevious());
01221 assertEquals(3, intVal(i.previous()));
01222 assertEquals(2, intVal(i.previous()));
01223 assertEquals(1, intVal(i.previous()));
01224 assertTrue(!i.hasPrevious());
01225 i.add(makeVal(1, 4));
01226 i.add(makeVal(1, 5));
01227 assertTrue(i.hasNext());
01228 assertEquals(5, intVal(i.previous()));
01229 assertEquals(4, intVal(i.previous()));
01230 assertTrue(!i.hasPrevious());
01231 assertEquals(4, intVal(i.next()));
01232 assertEquals(5, intVal(i.next()));
01233 assertEquals(1, intVal(i.next()));
01234 assertEquals(2, intVal(i.next()));
01235 assertEquals(3, intVal(i.next()));
01236 assertTrue(!i.hasNext());
01237 }
01238 } finally {
01239 StoredIterator.close(i);
01240 }
01241 }
01242 });
01243 }
01244
01245 void readAll()
01246 throws Exception {
01247
01248 readRunner.run(new TransactionWorker() {
01249 public void doWork() throws Exception {
01250
01251
01252 assertNotNull(map.toString());
01253 for (int i = beginKey; i <= endKey; i += 1) {
01254 Long key = makeKey(i);
01255 Object val = map.get(key);
01256 assertEquals(makeVal(i), val);
01257 assertTrue(map.containsKey(key));
01258 assertTrue(map.containsValue(val));
01259 assertTrue(map.keySet().contains(key));
01260 assertTrue(map.values().contains(val));
01261 assertTrue(map.duplicates(key).contains(val));
01262 checkDupsSize(1, map.duplicates(key));
01263 }
01264 assertNull(map.get(makeKey(-1)));
01265 assertNull(map.get(makeKey(0)));
01266 assertNull(map.get(makeKey(beginKey - 1)));
01267 assertNull(map.get(makeKey(endKey + 1)));
01268 checkDupsSize(0, map.duplicates(makeKey(-1)));
01269 checkDupsSize(0, map.duplicates(makeKey(0)));
01270 checkDupsSize(0, map.duplicates(makeKey(beginKey - 1)));
01271 checkDupsSize(0, map.duplicates(makeKey(endKey + 1)));
01272
01273
01274
01275 Set set = map.entrySet();
01276 assertNotNull(set.toString());
01277 assertEquals(beginKey > endKey, set.isEmpty());
01278 Iterator iter = set.iterator();
01279 try {
01280 for (int i = beginKey; i <= endKey; i += 1) {
01281 assertTrue(iter.hasNext());
01282 Map.Entry entry = (Map.Entry) iter.next();
01283 Long key = (Long) entry.getKey();
01284 Object val = entry.getValue();
01285 if (map instanceof SortedMap) {
01286 assertEquals(intKey(key), i);
01287 }
01288 assertEquals(intKey(key), intVal(val));
01289 assertTrue(set.contains(entry));
01290 }
01291 assertTrue(!iter.hasNext());
01292 } finally {
01293 StoredIterator.close(iter);
01294 }
01295 Map.Entry[] entries =
01296 (Map.Entry[]) set.toArray(new Map.Entry[0]);
01297 assertNotNull(entries);
01298 assertEquals(endKey - beginKey + 1, entries.length);
01299 for (int i = beginKey; i <= endKey; i += 1) {
01300 Map.Entry entry = entries[i - beginKey];
01301 assertNotNull(entry);
01302 if (map instanceof SortedMap) {
01303 assertEquals(makeKey(i), entry.getKey());
01304 assertEquals(makeVal(i), entry.getValue());
01305 }
01306 }
01307 readIterator(set, set.iterator(), beginKey, endKey);
01308 if (smap != null) {
01309 SortedSet sset = (SortedSet) set;
01310 if (beginKey == 1 && endKey >= 1) {
01311 readIterator(sset, sset.subSet(mapEntry(1),
01312 mapEntry(2))
01313 .iterator(), 1, 1);
01314 }
01315 if (beginKey <= 2 && endKey >= 2) {
01316 readIterator(sset, sset.subSet(mapEntry(2),
01317 mapEntry(3))
01318 .iterator(), 2, 2);
01319 }
01320 if (beginKey <= endKey) {
01321 readIterator(sset, sset.subSet(
01322 mapEntry(endKey),
01323 mapEntry(endKey + 1))
01324 .iterator(),
01325 endKey, endKey);
01326 }
01327 if (isSubMap()) {
01328 if (beginKey <= endKey) {
01329 if (rangeType != TAIL) {
01330 try {
01331 sset.subSet(mapEntry(endKey + 1),
01332 mapEntry(endKey + 2));
01333 fail();
01334 } catch (IllegalArgumentException e) {}
01335 }
01336 if (rangeType != HEAD) {
01337 try {
01338 sset.subSet(mapEntry(0),
01339 mapEntry(1));
01340 fail();
01341 } catch (IllegalArgumentException e) {}
01342 }
01343 }
01344 } else {
01345 readIterator(sset, sset.subSet(
01346 mapEntry(endKey + 1),
01347 mapEntry(endKey + 2))
01348 .iterator(),
01349 endKey, endKey - 1);
01350 readIterator(sset, sset.subSet(mapEntry(0),
01351 mapEntry(1))
01352 .iterator(),
01353 0, -1);
01354 }
01355 }
01356
01357
01358
01359 set = map.keySet();
01360 assertNotNull(set.toString());
01361 assertEquals(beginKey > endKey, set.isEmpty());
01362 iter = set.iterator();
01363 try {
01364 for (int i = beginKey; i <= endKey; i += 1) {
01365 assertTrue(iter.hasNext());
01366 Long key = (Long) iter.next();
01367 assertTrue(set.contains(key));
01368 Object val = map.get(key);
01369 if (map instanceof SortedMap) {
01370 assertEquals(key, makeKey(i));
01371 }
01372 assertEquals(intKey(key), intVal(val));
01373 }
01374 assertTrue("" + beginKey + ' ' + endKey, !iter.hasNext());
01375 } finally {
01376 StoredIterator.close(iter);
01377 }
01378 Long[] keys = (Long[]) set.toArray(new Long[0]);
01379 assertNotNull(keys);
01380 assertEquals(endKey - beginKey + 1, keys.length);
01381 for (int i = beginKey; i <= endKey; i += 1) {
01382 Long key = keys[i - beginKey];
01383 assertNotNull(key);
01384 if (map instanceof SortedMap) {
01385 assertEquals(makeKey(i), key);
01386 }
01387 }
01388 readIterator(set, set.iterator(), beginKey, endKey);
01389
01390
01391
01392 Collection coll = map.values();
01393 assertNotNull(coll.toString());
01394 assertEquals(beginKey > endKey, coll.isEmpty());
01395 iter = coll.iterator();
01396 try {
01397 for (int i = beginKey; i <= endKey; i += 1) {
01398 assertTrue(iter.hasNext());
01399 Object val = iter.next();
01400 if (map instanceof SortedMap) {
01401 assertEquals(makeVal(i), val);
01402 }
01403 }
01404 assertTrue(!iter.hasNext());
01405 } finally {
01406 StoredIterator.close(iter);
01407 }
01408 Object[] values = coll.toArray();
01409 assertNotNull(values);
01410 assertEquals(endKey - beginKey + 1, values.length);
01411 for (int i = beginKey; i <= endKey; i += 1) {
01412 Object val = values[i - beginKey];
01413 assertNotNull(val);
01414 if (map instanceof SortedMap) {
01415 assertEquals(makeVal(i), val);
01416 }
01417 }
01418 readIterator(coll, coll.iterator(), beginKey, endKey);
01419
01420
01421
01422 if (list != null) {
01423 assertNotNull(list.toString());
01424 assertEquals(beginKey > endKey, list.isEmpty());
01425 for (int i = beginKey; i <= endKey; i += 1) {
01426 int idx = i - beginKey;
01427 Object val = list.get(idx);
01428 assertEquals(makeVal(i), val);
01429 assertTrue(list.contains(val));
01430 assertEquals(idx, list.indexOf(val));
01431 assertEquals(idx, list.lastIndexOf(val));
01432 }
01433 ListIterator li = list.listIterator();
01434 try {
01435 for (int i = beginKey; i <= endKey; i += 1) {
01436 int idx = i - beginKey;
01437 assertTrue(li.hasNext());
01438 assertEquals(idx, li.nextIndex());
01439 Object val = li.next();
01440 assertEquals(makeVal(i), val);
01441 assertEquals(idx, li.previousIndex());
01442 }
01443 assertTrue(!li.hasNext());
01444 } finally {
01445 StoredIterator.close(li);
01446 }
01447 if (beginKey < endKey) {
01448 li = list.listIterator(1);
01449 try {
01450 for (int i = beginKey + 1; i <= endKey; i += 1) {
01451 int idx = i - beginKey;
01452 assertTrue(li.hasNext());
01453 assertEquals(idx, li.nextIndex());
01454 Object val = li.next();
01455 assertEquals(makeVal(i), val);
01456 assertEquals(idx, li.previousIndex());
01457 }
01458 assertTrue(!li.hasNext());
01459 } finally {
01460 StoredIterator.close(li);
01461 }
01462 }
01463 values = list.toArray();
01464 assertNotNull(values);
01465 assertEquals(endKey - beginKey + 1, values.length);
01466 for (int i = beginKey; i <= endKey; i += 1) {
01467 Object val = values[i - beginKey];
01468 assertNotNull(val);
01469 assertEquals(makeVal(i), val);
01470 }
01471 readIterator(list, list.iterator(), beginKey, endKey);
01472 }
01473
01474
01475
01476 if (smap != null) {
01477 if (beginKey <= endKey &&
01478 beginKey >= 1 && beginKey <= MAX_KEY) {
01479 assertEquals(makeKey(beginKey),
01480 smap.firstKey());
01481 assertEquals(makeKey(beginKey),
01482 ((SortedSet) smap.keySet()).first());
01483 Object entry = ((SortedSet) smap.entrySet()).first();
01484 assertEquals(makeKey(beginKey),
01485 ((Map.Entry) entry).getKey());
01486 if (smap.values() instanceof SortedSet) {
01487 assertEquals(makeVal(beginKey),
01488 ((SortedSet) smap.values()).first());
01489 }
01490 } else {
01491 assertNull(smap.firstKey());
01492 assertNull(((SortedSet) smap.keySet()).first());
01493 assertNull(((SortedSet) smap.entrySet()).first());
01494 if (smap.values() instanceof SortedSet) {
01495 assertNull(((SortedSet) smap.values()).first());
01496 }
01497 }
01498 if (beginKey <= endKey &&
01499 endKey >= 1 && endKey <= MAX_KEY) {
01500 assertEquals(makeKey(endKey),
01501 smap.lastKey());
01502 assertEquals(makeKey(endKey),
01503 ((SortedSet) smap.keySet()).last());
01504 Object entry = ((SortedSet) smap.entrySet()).last();
01505 assertEquals(makeKey(endKey),
01506 ((Map.Entry) entry).getKey());
01507 if (smap.values() instanceof SortedSet) {
01508 assertEquals(makeVal(endKey),
01509 ((SortedSet) smap.values()).last());
01510 }
01511 } else {
01512 assertNull(smap.lastKey());
01513 assertNull(((SortedSet) smap.keySet()).last());
01514 assertNull(((SortedSet) smap.entrySet()).last());
01515 if (smap.values() instanceof SortedSet) {
01516 assertNull(((SortedSet) smap.values()).last());
01517 }
01518 }
01519 }
01520 }
01521 });
01522 }
01523
01524 void readEven()
01525 throws Exception {
01526
01527 readRunner.run(new TransactionWorker() {
01528 public void doWork() throws Exception {
01529 int readBegin = ((beginKey & 1) != 0) ?
01530 (beginKey + 1) : beginKey;
01531 int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey;
01532 int readIncr = 2;
01533
01534
01535
01536 for (int i = beginKey; i <= endKey; i += 1) {
01537 Long key = makeKey(i);
01538 if ((i & 1) == 0) {
01539 Object val = map.get(key);
01540 assertEquals(makeVal(i), val);
01541 assertTrue(map.containsKey(key));
01542 assertTrue(map.containsValue(val));
01543 assertTrue(map.keySet().contains(key));
01544 assertTrue(map.values().contains(val));
01545 assertTrue(map.duplicates(key).contains(val));
01546 checkDupsSize(1, map.duplicates(key));
01547 } else {
01548 Object val = makeVal(i);
01549 assertTrue(!map.containsKey(key));
01550 assertTrue(!map.containsValue(val));
01551 assertTrue(!map.keySet().contains(key));
01552 assertTrue(!map.values().contains(val));
01553 assertTrue(!map.duplicates(key).contains(val));
01554 checkDupsSize(0, map.duplicates(key));
01555 }
01556 }
01557
01558
01559
01560 Set set = map.entrySet();
01561 assertEquals(beginKey > endKey, set.isEmpty());
01562 Iterator iter = set.iterator();
01563 try {
01564 for (int i = readBegin; i <= readEnd; i += readIncr) {
01565 assertTrue(iter.hasNext());
01566 Map.Entry entry = (Map.Entry) iter.next();
01567 Long key = (Long) entry.getKey();
01568 Object val = entry.getValue();
01569 if (map instanceof SortedMap) {
01570 assertEquals(intKey(key), i);
01571 }
01572 assertEquals(intKey(key), intVal(val));
01573 assertTrue(set.contains(entry));
01574 }
01575 assertTrue(!iter.hasNext());
01576 } finally {
01577 StoredIterator.close(iter);
01578 }
01579
01580
01581
01582 set = map.keySet();
01583 assertEquals(beginKey > endKey, set.isEmpty());
01584 iter = set.iterator();
01585 try {
01586 for (int i = readBegin; i <= readEnd; i += readIncr) {
01587 assertTrue(iter.hasNext());
01588 Long key = (Long) iter.next();
01589 assertTrue(set.contains(key));
01590 Object val = map.get(key);
01591 if (map instanceof SortedMap) {
01592 assertEquals(key, makeKey(i));
01593 }
01594 assertEquals(intKey(key), intVal(val));
01595 }
01596 assertTrue(!iter.hasNext());
01597 } finally {
01598 StoredIterator.close(iter);
01599 }
01600
01601
01602
01603 Collection coll = map.values();
01604 assertEquals(beginKey > endKey, coll.isEmpty());
01605 iter = coll.iterator();
01606 try {
01607 for (int i = readBegin; i <= readEnd; i += readIncr) {
01608 assertTrue(iter.hasNext());
01609 Object val = iter.next();
01610 if (map instanceof SortedMap) {
01611 assertEquals(makeVal(i), val);
01612 }
01613 }
01614 assertTrue(!iter.hasNext());
01615 } finally {
01616 StoredIterator.close(iter);
01617 }
01618
01619
01620
01621
01622
01623
01624
01625 if (smap != null) {
01626 if (readBegin <= readEnd &&
01627 readBegin >= 1 && readBegin <= MAX_KEY) {
01628 assertEquals(makeKey(readBegin),
01629 smap.firstKey());
01630 assertEquals(makeKey(readBegin),
01631 ((SortedSet) smap.keySet()).first());
01632 Object entry = ((SortedSet) smap.entrySet()).first();
01633 assertEquals(makeKey(readBegin),
01634 ((Map.Entry) entry).getKey());
01635 if (smap.values() instanceof SortedSet) {
01636 assertEquals(makeVal(readBegin),
01637 ((SortedSet) smap.values()).first());
01638 }
01639 } else {
01640 assertNull(smap.firstKey());
01641 assertNull(((SortedSet) smap.keySet()).first());
01642 assertNull(((SortedSet) smap.entrySet()).first());
01643 if (smap.values() instanceof SortedSet) {
01644 assertNull(((SortedSet) smap.values()).first());
01645 }
01646 }
01647 if (readBegin <= readEnd &&
01648 readEnd >= 1 && readEnd <= MAX_KEY) {
01649 assertEquals(makeKey(readEnd),
01650 smap.lastKey());
01651 assertEquals(makeKey(readEnd),
01652 ((SortedSet) smap.keySet()).last());
01653 Object entry = ((SortedSet) smap.entrySet()).last();
01654 assertEquals(makeKey(readEnd),
01655 ((Map.Entry) entry).getKey());
01656 if (smap.values() instanceof SortedSet) {
01657 assertEquals(makeVal(readEnd),
01658 ((SortedSet) smap.values()).last());
01659 }
01660 } else {
01661 assertNull(smap.lastKey());
01662 assertNull(((SortedSet) smap.keySet()).last());
01663 assertNull(((SortedSet) smap.entrySet()).last());
01664 if (smap.values() instanceof SortedSet) {
01665 assertNull(((SortedSet) smap.values()).last());
01666 }
01667 }
01668 }
01669 }
01670 });
01671 }
01672
01673 void readEvenList()
01674 throws Exception {
01675
01676 readRunner.run(new TransactionWorker() {
01677 public void doWork() throws Exception {
01678 int readBegin = ((beginKey & 1) != 0) ?
01679 (beginKey + 1) : beginKey;
01680 int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey;
01681 int readIncr = 2;
01682
01683 assertEquals(beginKey > endKey, list.isEmpty());
01684 ListIterator iter = list.listIterator();
01685 try {
01686 int idx = 0;
01687 for (int i = readBegin; i <= readEnd; i += readIncr) {
01688 assertTrue(iter.hasNext());
01689 assertEquals(idx, iter.nextIndex());
01690 Object val = iter.next();
01691 assertEquals(idx, iter.previousIndex());
01692 if (isEntityBinding) {
01693 assertEquals(i, intVal(val));
01694 } else {
01695 assertEquals(makeVal(i), val);
01696 }
01697 idx += 1;
01698 }
01699 assertTrue(!iter.hasNext());
01700 } finally {
01701 StoredIterator.close(iter);
01702 }
01703 }
01704 });
01705 }
01706
01707 void readIterator(Collection coll, Iterator iter,
01708 int beginValue, int endValue) {
01709
01710 ListIterator li = (ListIterator) iter;
01711 boolean isList = (coll instanceof List);
01712 Iterator clone = null;
01713 try {
01714
01715 assertTrue(!li.hasPrevious());
01716 assertTrue(!li.hasPrevious());
01717 try { li.previous(); } catch (NoSuchElementException e) {}
01718 if (isList) {
01719 assertEquals(-1, li.previousIndex());
01720 }
01721 if (endValue < beginValue) {
01722
01723 assertTrue(!iter.hasNext());
01724 try { iter.next(); } catch (NoSuchElementException e) {}
01725 if (isList) {
01726 assertEquals(Integer.MAX_VALUE, li.nextIndex());
01727 }
01728 }
01729
01730 StoredIterator si = (StoredIterator) iter;
01731 int[] values = new int[endValue - beginValue + 1];
01732 for (int i = beginValue; i <= endValue; i += 1) {
01733 assertTrue(iter.hasNext());
01734 int idx = i - beginKey;
01735 if (isList) {
01736 assertEquals(idx, li.nextIndex());
01737 }
01738 int value = intIter(coll, iter.next());
01739 if (isList) {
01740 assertEquals(idx, li.previousIndex());
01741 }
01742 values[i - beginValue] = value;
01743 if (si.getCollection().isOrdered()) {
01744 assertEquals(i, value);
01745 } else {
01746 assertTrue(value >= beginValue);
01747 assertTrue(value <= endValue);
01748 }
01749 }
01750
01751 assertTrue(!iter.hasNext());
01752 try { iter.next(); } catch (NoSuchElementException e) {}
01753 if (isList) {
01754 assertEquals(Integer.MAX_VALUE, li.nextIndex());
01755 }
01756
01757 clone = StoredCollections.iterator(iter);
01758 assertTrue(!clone.hasNext());
01759
01760 for (int i = endValue; i >= beginValue; i -= 1) {
01761 assertTrue(li.hasPrevious());
01762 int idx = i - beginKey;
01763 if (isList) {
01764 assertEquals(idx, li.previousIndex());
01765 }
01766 int value = intIter(coll, li.previous());
01767 if (isList) {
01768 assertEquals(idx, li.nextIndex());
01769 }
01770 assertEquals(values[i - beginValue], value);
01771 }
01772
01773 assertTrue(!clone.hasNext());
01774
01775 assertTrue(!li.hasPrevious());
01776 try { li.previous(); } catch (NoSuchElementException e) {}
01777 if (isList) {
01778 assertEquals(-1, li.previousIndex());
01779 }
01780
01781 for (int i = beginValue; i <= endValue; i += 1) {
01782 assertTrue(iter.hasNext());
01783 int idx = i - beginKey;
01784 if (isList) {
01785 assertEquals(idx, li.nextIndex());
01786 }
01787 Object obj = iter.next();
01788 if (isList) {
01789 assertEquals(idx, li.previousIndex());
01790 }
01791 assertEquals(obj, li.previous());
01792 if (isList) {
01793 assertEquals(idx, li.nextIndex());
01794 }
01795 assertEquals(obj, iter.next());
01796 if (isList) {
01797 assertEquals(idx, li.previousIndex());
01798 }
01799 int value = intIter(coll, obj);
01800 assertEquals(values[i - beginValue], value);
01801 }
01802
01803 assertTrue(!iter.hasNext());
01804 try { iter.next(); } catch (NoSuchElementException e) {}
01805 if (isList) {
01806 assertEquals(Integer.MAX_VALUE, li.nextIndex());
01807 }
01808 } finally {
01809 StoredIterator.close(iter);
01810 StoredIterator.close(clone);
01811 }
01812 }
01813
01814 void bulkOperations()
01815 throws Exception {
01816
01817 writeRunner.run(new TransactionWorker() {
01818 public void doWork() throws Exception {
01819 HashMap hmap = new HashMap();
01820 for (int i = Math.max(1, beginKey);
01821 i <= Math.min(MAX_KEY, endKey);
01822 i += 1) {
01823 hmap.put(makeKey(i), makeVal(i));
01824 }
01825 assertTrue(map.equals(hmap));
01826 assertTrue(map.entrySet().equals(hmap.entrySet()));
01827 assertTrue(map.keySet().equals(hmap.keySet()));
01828 assertTrue(map.values().equals(hmap.values()));
01829
01830 assertTrue(map.entrySet().containsAll(hmap.entrySet()));
01831 assertTrue(map.keySet().containsAll(hmap.keySet()));
01832 assertTrue(map.values().containsAll(hmap.values()));
01833
01834 map.clear();
01835 assertTrue(map.isEmpty());
01836 imap.putAll(hmap);
01837 assertTrue(map.equals(hmap));
01838
01839 assertTrue(map.entrySet().removeAll(hmap.entrySet()));
01840 assertTrue(map.entrySet().isEmpty());
01841 assertTrue(!map.entrySet().removeAll(hmap.entrySet()));
01842 assertTrue(imap.entrySet().addAll(hmap.entrySet()));
01843 assertTrue(map.entrySet().containsAll(hmap.entrySet()));
01844 assertTrue(!imap.entrySet().addAll(hmap.entrySet()));
01845 assertTrue(map.equals(hmap));
01846
01847 assertTrue(!map.entrySet().retainAll(hmap.entrySet()));
01848 assertTrue(map.equals(hmap));
01849 assertTrue(map.entrySet().retainAll(Collections.EMPTY_SET));
01850 assertTrue(map.isEmpty());
01851 imap.putAll(hmap);
01852 assertTrue(map.equals(hmap));
01853
01854 assertTrue(map.values().removeAll(hmap.values()));
01855 assertTrue(map.values().isEmpty());
01856 assertTrue(!map.values().removeAll(hmap.values()));
01857 if (isEntityBinding) {
01858 assertTrue(imap.values().addAll(hmap.values()));
01859 assertTrue(map.values().containsAll(hmap.values()));
01860 assertTrue(!imap.values().addAll(hmap.values()));
01861 } else {
01862 imap.putAll(hmap);
01863 }
01864 assertTrue(map.equals(hmap));
01865
01866 assertTrue(!map.values().retainAll(hmap.values()));
01867 assertTrue(map.equals(hmap));
01868 assertTrue(map.values().retainAll(Collections.EMPTY_SET));
01869 assertTrue(map.isEmpty());
01870 imap.putAll(hmap);
01871 assertTrue(map.equals(hmap));
01872
01873 assertTrue(map.keySet().removeAll(hmap.keySet()));
01874 assertTrue(map.keySet().isEmpty());
01875 assertTrue(!map.keySet().removeAll(hmap.keySet()));
01876 assertTrue(imap.keySet().addAll(hmap.keySet()));
01877 assertTrue(imap.keySet().containsAll(hmap.keySet()));
01878 if (index != null) {
01879 assertTrue(map.keySet().isEmpty());
01880 }
01881 assertTrue(!imap.keySet().addAll(hmap.keySet()));
01882
01883 imap.keySet().removeAll(hmap.keySet());
01884 imap.putAll(hmap);
01885 assertTrue(map.equals(hmap));
01886
01887 assertTrue(!map.keySet().retainAll(hmap.keySet()));
01888 assertTrue(map.equals(hmap));
01889 assertTrue(map.keySet().retainAll(Collections.EMPTY_SET));
01890 assertTrue(map.isEmpty());
01891 imap.putAll(hmap);
01892 assertTrue(map.equals(hmap));
01893 }
01894 });
01895 }
01896
01897 void bulkListOperations()
01898 throws Exception {
01899
01900 writeRunner.run(new TransactionWorker() {
01901 public void doWork() throws Exception {
01902 ArrayList alist = new ArrayList();
01903 for (int i = beginKey; i <= endKey; i += 1) {
01904 alist.add(makeVal(i));
01905 }
01906
01907 assertTrue(list.equals(alist));
01908 assertTrue(list.containsAll(alist));
01909
01910 if (isListAddAllowed()) {
01911 list.clear();
01912 assertTrue(list.isEmpty());
01913 assertTrue(ilist.addAll(alist));
01914 assertTrue(list.equals(alist));
01915 }
01916
01917 assertTrue(!list.retainAll(alist));
01918 assertTrue(list.equals(alist));
01919
01920 if (isListAddAllowed()) {
01921 assertTrue(list.retainAll(Collections.EMPTY_SET));
01922 assertTrue(list.isEmpty());
01923 assertTrue(ilist.addAll(alist));
01924 assertTrue(list.equals(alist));
01925 }
01926
01927 if (isListAddAllowed() && !isEntityBinding) {
01928
01929
01930
01931 assertTrue(list.removeAll(alist));
01932 assertTrue(list.isEmpty());
01933 assertTrue(!list.removeAll(alist));
01934 assertTrue(ilist.addAll(alist));
01935 assertTrue(list.containsAll(alist));
01936 assertTrue(list.equals(alist));
01937 }
01938
01939 if (isListAddAllowed() && !isEntityBinding) {
01940
01941
01942
01943
01944 ilist.addAll(beginKey, alist);
01945 assertTrue(list.containsAll(alist));
01946 assertEquals(2 * alist.size(), countElements(list));
01947 for (int i = beginKey; i <= endKey; i += 1)
01948 ilist.remove(beginKey);
01949 assertTrue(list.equals(alist));
01950
01951
01952 ilist.addAll(endKey, alist);
01953 assertTrue(list.containsAll(alist));
01954 assertEquals(2 * alist.size(), countElements(list));
01955 for (int i = beginKey; i <= endKey; i += 1)
01956 ilist.remove(endKey);
01957 assertTrue(list.equals(alist));
01958
01959
01960 ilist.addAll(endKey - 1, alist);
01961 assertTrue(list.containsAll(alist));
01962 assertEquals(2 * alist.size(), countElements(list));
01963 for (int i = beginKey; i <= endKey; i += 1)
01964 ilist.remove(endKey - 1);
01965 assertTrue(list.equals(alist));
01966 }
01967 }
01968 });
01969 }
01970
01971 void readWriteRange(final int type, final int rangeBegin,
01972 final int rangeEnd)
01973 throws Exception {
01974
01975 writeRunner.run(new TransactionWorker() {
01976 public void doWork() throws Exception {
01977 setRange(type, rangeBegin, rangeEnd);
01978 createOutOfRange(rangeBegin, rangeEnd);
01979 if (rangeType != TAIL) {
01980 writeOutOfRange(new Long(rangeEnd + 1));
01981 }
01982 if (rangeType != HEAD) {
01983 writeOutOfRange(new Long(rangeBegin - 1));
01984 }
01985 if (rangeBegin <= rangeEnd) {
01986 updateAll();
01987 }
01988 if (rangeBegin < rangeEnd && !map.areKeysRenumbered()) {
01989 bulkOperations();
01990 }
01991 readAll();
01992 clearRange();
01993 }
01994 });
01995 }
01996
01997 void setRange(int type, int rangeBegin, int rangeEnd) {
01998
01999 rangeType = type;
02000 saveMap = map;
02001 saveSMap = smap;
02002 saveList = list;
02003 int listBegin = rangeBegin - beginKey;
02004 boolean canMakeSubList = (list != null && listBegin>= 0);
02005 if (!canMakeSubList) {
02006 list = null;
02007 }
02008 if (list != null) {
02009 try {
02010 list.subList(-1, 0);
02011 fail();
02012 } catch (IndexOutOfBoundsException e) { }
02013 }
02014 switch (type) {
02015
02016 case SUB:
02017 smap = (StoredSortedMap) smap.subMap(makeKey(rangeBegin),
02018 makeKey(rangeEnd + 1));
02019 if (canMakeSubList) {
02020 list = (StoredList) list.subList(listBegin,
02021 rangeEnd + 1 - beginKey);
02022 }
02023
02024 assertEquals(smap,
02025 ((StoredSortedMap) saveSMap).subMap(
02026 makeKey(rangeBegin), true,
02027 makeKey(rangeEnd + 1), false));
02028 assertEquals(smap.entrySet(),
02029 ((StoredSortedEntrySet) saveSMap.entrySet()).subSet(
02030 mapEntry(rangeBegin), true,
02031 mapEntry(rangeEnd + 1), false));
02032 assertEquals(smap.keySet(),
02033 ((StoredSortedKeySet) saveSMap.keySet()).subSet(
02034 makeKey(rangeBegin), true,
02035 makeKey(rangeEnd + 1), false));
02036 if (smap.values() instanceof SortedSet) {
02037 assertEquals(smap.values(),
02038 ((StoredSortedValueSet) saveSMap.values()).subSet(
02039 makeVal(rangeBegin), true,
02040 makeVal(rangeEnd + 1), false));
02041 }
02042 break;
02043 case HEAD:
02044 smap = (StoredSortedMap) smap.headMap(makeKey(rangeEnd + 1));
02045 if (canMakeSubList) {
02046 list = (StoredList) list.subList(0,
02047 rangeEnd + 1 - beginKey);
02048 }
02049
02050 assertEquals(smap,
02051 ((StoredSortedMap) saveSMap).headMap(
02052 makeKey(rangeEnd + 1), false));
02053 assertEquals(smap.entrySet(),
02054 ((StoredSortedEntrySet) saveSMap.entrySet()).headSet(
02055 mapEntry(rangeEnd + 1), false));
02056 assertEquals(smap.keySet(),
02057 ((StoredSortedKeySet) saveSMap.keySet()).headSet(
02058 makeKey(rangeEnd + 1), false));
02059 if (smap.values() instanceof SortedSet) {
02060 assertEquals(smap.values(),
02061 ((StoredSortedValueSet) saveSMap.values()).headSet(
02062 makeVal(rangeEnd + 1), false));
02063 }
02064 break;
02065 case TAIL:
02066 smap = (StoredSortedMap) smap.tailMap(makeKey(rangeBegin));
02067 if (canMakeSubList) {
02068 list = (StoredList) list.subList(listBegin,
02069 MAX_KEY + 1 - beginKey);
02070 }
02071
02072 assertEquals(smap,
02073 ((StoredSortedMap) saveSMap).tailMap(
02074 makeKey(rangeBegin), true));
02075 assertEquals(smap.entrySet(),
02076 ((StoredSortedEntrySet) saveSMap.entrySet()).tailSet(
02077 mapEntry(rangeBegin), true));
02078 assertEquals(smap.keySet(),
02079 ((StoredSortedKeySet) saveSMap.keySet()).tailSet(
02080 makeKey(rangeBegin), true));
02081 if (smap.values() instanceof SortedSet) {
02082 assertEquals(smap.values(),
02083 ((StoredSortedValueSet) saveSMap.values()).tailSet(
02084 makeVal(rangeBegin), true));
02085 }
02086 break;
02087 default: throw new RuntimeException();
02088 }
02089 map = smap;
02090 beginKey = rangeBegin;
02091 if (rangeBegin < 1 || rangeEnd > MAX_KEY) {
02092 endKey = rangeBegin - 1;
02093 } else {
02094 endKey = rangeEnd;
02095 }
02096 }
02097
02098 void clearRange() {
02099
02100 rangeType = NONE;
02101 beginKey = 1;
02102 endKey = MAX_KEY;
02103 map = saveMap;
02104 smap = saveSMap;
02105 list = saveList;
02106 }
02107
02108 void createOutOfRange(int rangeBegin, int rangeEnd)
02109 throws Exception {
02110
02111
02112
02113 if (rangeType != TAIL) {
02114 try {
02115 smap.subMap(makeKey(rangeBegin), makeKey(rangeEnd + 2));
02116 fail();
02117 } catch (IllegalArgumentException e) { }
02118 try {
02119 smap.headMap(makeKey(rangeEnd + 2));
02120 fail();
02121 } catch (IllegalArgumentException e) { }
02122 checkDupsSize(0, smap.duplicates(makeKey(rangeEnd + 2)));
02123 }
02124 if (rangeType != HEAD) {
02125 try {
02126 smap.subMap(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1));
02127 fail();
02128 } catch (IllegalArgumentException e) { }
02129 try {
02130 smap.tailMap(makeKey(rangeBegin - 1));
02131 fail();
02132 }
02133 catch (IllegalArgumentException e) { }
02134 checkDupsSize(0, smap.duplicates(makeKey(rangeBegin - 1)));
02135 }
02136
02137
02138
02139 if (rangeType != TAIL) {
02140 SortedSet sset = (SortedSet) map.keySet();
02141 try {
02142 sset.subSet(makeKey(rangeBegin), makeKey(rangeEnd + 2));
02143 fail();
02144 } catch (IllegalArgumentException e) { }
02145 try {
02146 sset.headSet(makeKey(rangeEnd + 2));
02147 fail();
02148 } catch (IllegalArgumentException e) { }
02149 try {
02150 sset.subSet(makeKey(rangeEnd + 1),
02151 makeKey(rangeEnd + 2)).iterator();
02152 fail();
02153 } catch (IllegalArgumentException e) { }
02154 }
02155 if (rangeType != HEAD) {
02156 SortedSet sset = (SortedSet) map.keySet();
02157 try {
02158 sset.subSet(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1));
02159 fail();
02160 } catch (IllegalArgumentException e) { }
02161 try {
02162 sset.tailSet(makeKey(rangeBegin - 1));
02163 fail();
02164 }
02165 catch (IllegalArgumentException e) { }
02166 try {
02167 sset.subSet(makeKey(rangeBegin - 1),
02168 makeKey(rangeBegin)).iterator();
02169 fail();
02170 }
02171 catch (IllegalArgumentException e) { }
02172 }
02173
02174
02175
02176 if (rangeType != TAIL) {
02177 SortedSet sset = (SortedSet) map.entrySet();
02178 try {
02179 sset.subSet(mapEntry(rangeBegin), mapEntry(rangeEnd + 2));
02180 fail();
02181 } catch (IllegalArgumentException e) { }
02182 try {
02183 sset.headSet(mapEntry(rangeEnd + 2));
02184 fail();
02185 } catch (IllegalArgumentException e) { }
02186 try {
02187 sset.subSet(mapEntry(rangeEnd + 1),
02188 mapEntry(rangeEnd + 2)).iterator();
02189 fail();
02190 } catch (IllegalArgumentException e) { }
02191 }
02192 if (rangeType != HEAD) {
02193 SortedSet sset = (SortedSet) map.entrySet();
02194 try {
02195 sset.subSet(mapEntry(rangeBegin - 1), mapEntry(rangeEnd + 1));
02196 fail();
02197 } catch (IllegalArgumentException e) { }
02198 try {
02199 sset.tailSet(mapEntry(rangeBegin - 1));
02200 fail();
02201 } catch (IllegalArgumentException e) { }
02202 try {
02203 sset.subSet(mapEntry(rangeBegin - 1),
02204 mapEntry(rangeBegin)).iterator();
02205 fail();
02206 }
02207 catch (IllegalArgumentException e) { }
02208 }
02209
02210
02211
02212 if (map.values() instanceof SortedSet) {
02213 SortedSet sset = (SortedSet) map.values();
02214 if (rangeType != TAIL) {
02215 try {
02216 sset.subSet(makeVal(rangeBegin),
02217 makeVal(rangeEnd + 2));
02218 fail();
02219 } catch (IllegalArgumentException e) { }
02220 try {
02221 sset.headSet(makeVal(rangeEnd + 2));
02222 fail();
02223 } catch (IllegalArgumentException e) { }
02224 }
02225 if (rangeType != HEAD) {
02226 try {
02227 sset.subSet(makeVal(rangeBegin - 1),
02228 makeVal(rangeEnd + 1));
02229 fail();
02230 } catch (IllegalArgumentException e) { }
02231 try {
02232 sset.tailSet(makeVal(rangeBegin - 1));
02233 fail();
02234 }
02235 catch (IllegalArgumentException e) { }
02236 }
02237 }
02238
02239
02240
02241 if (list != null) {
02242 int size = rangeEnd - rangeBegin + 1;
02243 try {
02244 list.subList(0, size + 1);
02245 fail();
02246 } catch (IndexOutOfBoundsException e) { }
02247 try {
02248 list.subList(-1, size);
02249 fail();
02250 } catch (IndexOutOfBoundsException e) { }
02251 try {
02252 list.subList(2, 1);
02253 fail();
02254 } catch (IndexOutOfBoundsException e) { }
02255 try {
02256 list.subList(size, size);
02257 fail();
02258 }
02259 catch (IndexOutOfBoundsException e) { }
02260 }
02261 }
02262
02263 void writeOutOfRange(Long badNewKey)
02264 throws Exception {
02265
02266 try {
02267 map.put(badNewKey, makeVal(badNewKey));
02268 fail();
02269 } catch (IllegalArgumentException e) {
02270 assertTrue(e.toString(), index == null);
02271 } catch (UnsupportedOperationException e) {
02272 assertTrue(index != null);
02273 }
02274 try {
02275 map.keySet().add(badNewKey);
02276 fail();
02277 } catch (IllegalArgumentException e) {
02278 assertTrue(index == null);
02279 } catch (UnsupportedOperationException e) {
02280 assertTrue(index != null);
02281 }
02282 try {
02283 map.values().add(makeEntity(badNewKey));
02284 fail();
02285 } catch (IllegalArgumentException e) {
02286 assertTrue(isEntityBinding && index == null);
02287 } catch (UnsupportedOperationException e) {
02288 assertTrue(!(isEntityBinding && index == null));
02289 }
02290 if (list != null) {
02291 int i = badNewKey.intValue() - beginKey;
02292 try {
02293 list.set(i, makeVal(i));
02294 fail();
02295 } catch (IndexOutOfBoundsException e) {
02296 assertTrue(index == null);
02297 } catch (UnsupportedOperationException e) {
02298 assertTrue(index != null);
02299 }
02300 try {
02301 list.add(i, makeVal(badNewKey));
02302 fail();
02303 }
02304 catch (UnsupportedOperationException e) {
02305 }
02306 }
02307 }
02308
02309 void readWriteDuplicates()
02310 throws Exception {
02311
02312 writeRunner.run(new TransactionWorker() {
02313 public void doWork() throws Exception {
02314 if (index == null) {
02315 readWritePrimaryDuplicates(beginKey);
02316 readWritePrimaryDuplicates(beginKey + 1);
02317 readWritePrimaryDuplicates(endKey);
02318 readWritePrimaryDuplicates(endKey - 1);
02319 } else {
02320 readWriteIndexedDuplicates(beginKey);
02321 readWriteIndexedDuplicates(beginKey + 1);
02322 readWriteIndexedDuplicates(endKey);
02323 readWriteIndexedDuplicates(endKey - 1);
02324 }
02325 }
02326 });
02327 }
02328
02329 void readWritePrimaryDuplicates(int i)
02330 throws Exception {
02331
02332 Collection dups;
02333
02334 final Long key = makeKey(i);
02335 final Object[] values = new Object[5];
02336 for (int j = 0; j < values.length; j += 1) {
02337 values[j] = isEntityBinding
02338 ? makeEntity(i, i + j)
02339 : makeVal(i + j);
02340 }
02341
02342 outerLoop: for (int writeMode = 0;; writeMode += 1) {
02343
02344 switch (writeMode) {
02345 case 0:
02346 case 1: {
02347
02348 for (int j = 1; j < values.length; j += 1) {
02349 map.put(key, values[j]);
02350 }
02351 break;
02352 }
02353 case 2: {
02354
02355 dups = map.duplicates(key);
02356 for (int j = 1; j < values.length; j += 1) {
02357 dups.add(values[j]);
02358 }
02359 break;
02360 }
02361 case 3: {
02362
02363 writeIterRunner.run(new TransactionWorker() {
02364 public void doWork() throws Exception {
02365 Collection dups = map.duplicates(key);
02366 Iterator iter = dups.iterator();
02367 assertEquals(values[0], iter.next());
02368 assertTrue(!iter.hasNext());
02369 try {
02370 for (int j = 1; j < values.length; j += 1) {
02371 ((ListIterator) iter).add(values[j]);
02372 }
02373 } finally {
02374 StoredIterator.close(iter);
02375 }
02376 }
02377 });
02378 break;
02379 }
02380 case 4: {
02381
02382 if (!isEntityBinding) {
02383 continue;
02384 }
02385 Collection set = map.values();
02386 for (int j = 1; j < values.length; j += 1) {
02387 set.add(values[j]);
02388 }
02389 break;
02390 }
02391 default: {
02392 break outerLoop;
02393 }
02394 }
02395 checkDupsSize(values.length, map.duplicates(key));
02396
02397 readDuplicates(i, key, values);
02398
02399 switch (writeMode) {
02400 case 0: {
02401
02402 checkDupsSize(values.length, map.duplicates(key));
02403 map.remove(key);
02404 checkDupsSize(0, map.duplicates(key));
02405 map.put(key, values[0]);
02406 checkDupsSize(1, map.duplicates(key));
02407 break;
02408 }
02409 case 1: {
02410
02411 map.keySet().remove(key);
02412 map.put(key, values[0]);
02413 break;
02414 }
02415 case 2: {
02416
02417 dups = map.duplicates(key);
02418 dups.clear();
02419 dups.add(values[0]);
02420 break;
02421 }
02422 case 3: {
02423
02424 writeIterRunner.run(new TransactionWorker() {
02425 public void doWork() throws Exception {
02426 Collection dups = map.duplicates(key);
02427 Iterator iter = dups.iterator();
02428 try {
02429 for (int j = 0; j < values.length; j += 1) {
02430 assertEquals(values[j], iter.next());
02431 if (j != 0) {
02432 iter.remove();
02433 }
02434 }
02435 } finally {
02436 StoredIterator.close(iter);
02437 }
02438 }
02439 });
02440 break;
02441 }
02442 case 4: {
02443
02444 if (!isEntityBinding) {
02445 throw new IllegalStateException();
02446 }
02447 Collection set = map.values();
02448 for (int j = 1; j < values.length; j += 1) {
02449 set.remove(values[j]);
02450 }
02451 break;
02452 }
02453 default: throw new IllegalStateException();
02454 }
02455
02456 dups = map.duplicates(key);
02457 assertTrue(dups.contains(values[0]));
02458 for (int j = 1; j < values.length; j += 1) {
02459 assertTrue(!dups.contains(values[j]));
02460 }
02461 checkDupsSize(1, dups);
02462 }
02463 }
02464
02465 void readWriteIndexedDuplicates(int i)
02466 throws Exception {
02467
02468 Object key = makeKey(i);
02469 Object[] values = new Object[3];
02470 values[0] = makeVal(i);
02471 for (int j = 1; j < values.length; j += 1) {
02472 values[j] = isEntityBinding
02473 ? makeEntity(endKey + j, i)
02474 : makeVal(i);
02475 }
02476
02477 for (int j = 1; j < values.length; j += 1) {
02478 imap.put(makeKey(endKey + j), values[j]);
02479 }
02480
02481 readDuplicates(i, key, values);
02482
02483 for (int j = 1; j < values.length; j += 1) {
02484 imap.remove(makeKey(endKey + j));
02485 }
02486 checkDupsSize(1, map.duplicates(key));
02487 }
02488
02489 void readDuplicates(int i, Object key, Object[] values) {
02490
02491 boolean isOrdered = map.isOrdered();
02492 Collection dups;
02493 Iterator iter;
02494
02495 dups = map.duplicates(key);
02496 checkDupsSize(values.length, dups);
02497 iter = dups.iterator();
02498 try {
02499 for (int j = 0; j < values.length; j += 1) {
02500 assertTrue(iter.hasNext());
02501 Object val = iter.next();
02502 assertEquals(values[j], val);
02503 }
02504 assertTrue(!iter.hasNext());
02505 } finally {
02506 StoredIterator.close(iter);
02507 }
02508
02509 Collection clone = ((StoredCollection) map.values()).toList();
02510 iter = map.values().iterator();
02511 try {
02512 for (int j = beginKey; j < i; j += 1) {
02513 Object val = iter.next();
02514 assertTrue(clone.remove(makeVal(j)));
02515 if (isOrdered) {
02516 assertEquals(makeVal(j), val);
02517 }
02518 }
02519 for (int j = 0; j < values.length; j += 1) {
02520 Object val = iter.next();
02521 assertTrue(clone.remove(values[j]));
02522 if (isOrdered) {
02523 assertEquals(values[j], val);
02524 }
02525 }
02526 for (int j = i + 1; j <= endKey; j += 1) {
02527 Object val = iter.next();
02528 assertTrue(clone.remove(makeVal(j)));
02529 if (isOrdered) {
02530 assertEquals(makeVal(j), val);
02531 }
02532 }
02533 assertTrue(!iter.hasNext());
02534 assertTrue(clone.isEmpty());
02535 } finally {
02536 StoredIterator.close(iter);
02537 }
02538
02539 clone = ((StoredCollection) map.entrySet()).toList();
02540 iter = map.entrySet().iterator();
02541 try {
02542 for (int j = beginKey; j < i; j += 1) {
02543 Map.Entry entry = (Map.Entry) iter.next();
02544 assertTrue(clone.remove(mapEntry(j)));
02545 if (isOrdered) {
02546 assertEquals(makeVal(j), entry.getValue());
02547 assertEquals(makeKey(j), entry.getKey());
02548 }
02549 }
02550 for (int j = 0; j < values.length; j += 1) {
02551 Map.Entry entry = (Map.Entry) iter.next();
02552 assertTrue(clone.remove(mapEntry(makeKey(i), values[j])));
02553 if (isOrdered) {
02554 assertEquals(values[j], entry.getValue());
02555 assertEquals(makeKey(i), entry.getKey());
02556 }
02557 }
02558 for (int j = i + 1; j <= endKey; j += 1) {
02559 Map.Entry entry = (Map.Entry) iter.next();
02560 assertTrue(clone.remove(mapEntry(j)));
02561 if (isOrdered) {
02562 assertEquals(makeVal(j), entry.getValue());
02563 assertEquals(makeKey(j), entry.getKey());
02564 }
02565 }
02566 assertTrue(!iter.hasNext());
02567 assertTrue(clone.isEmpty());
02568 } finally {
02569 StoredIterator.close(iter);
02570 }
02571
02572 clone = ((StoredCollection) map.keySet()).toList();
02573 iter = map.keySet().iterator();
02574 try {
02575 for (int j = beginKey; j < i; j += 1) {
02576 Object val = iter.next();
02577 assertTrue(clone.remove(makeKey(j)));
02578 if (isOrdered) {
02579 assertEquals(makeKey(j), val);
02580 }
02581 }
02582 if (true) {
02583
02584 Object val = iter.next();
02585 assertTrue(clone.remove(makeKey(i)));
02586 if (isOrdered) {
02587 assertEquals(makeKey(i), val);
02588 }
02589 }
02590 for (int j = i + 1; j <= endKey; j += 1) {
02591 Object val = iter.next();
02592 assertTrue(clone.remove(makeKey(j)));
02593 if (isOrdered) {
02594 assertEquals(makeKey(j), val);
02595 }
02596 }
02597 assertTrue(!iter.hasNext());
02598 assertTrue(clone.isEmpty());
02599 } finally {
02600 StoredIterator.close(iter);
02601 }
02602 }
02603
02604 void duplicatesNotAllowed() {
02605
02606 Collection dups = map.duplicates(makeKey(beginKey));
02607 try {
02608 dups.add(makeVal(beginKey));
02609 fail();
02610 } catch (UnsupportedOperationException expected) { }
02611 ListIterator iter = (ListIterator) dups.iterator();
02612 try {
02613 iter.add(makeVal(beginKey));
02614 fail();
02615 } catch (UnsupportedOperationException expected) {
02616 } finally {
02617 StoredIterator.close(iter);
02618 }
02619 }
02620
02621 void listOperationsNotAllowed() {
02622
02623 ListIterator iter = (ListIterator) map.values().iterator();
02624 try {
02625 try {
02626 iter.nextIndex();
02627 fail();
02628 } catch (UnsupportedOperationException expected) { }
02629 try {
02630 iter.previousIndex();
02631 fail();
02632 } catch (UnsupportedOperationException expected) { }
02633 } finally {
02634 StoredIterator.close(iter);
02635 }
02636 }
02637
02638 void testCdbLocking() {
02639
02640 Iterator readIterator;
02641 Iterator writeIterator;
02642 StoredKeySet set = (StoredKeySet) map.keySet();
02643
02644
02645 readIterator = set.iterator(false);
02646 try {
02647 Iterator readIterator2 = set.iterator(false);
02648 StoredIterator.close(readIterator2);
02649 } finally {
02650 StoredIterator.close(readIterator);
02651 }
02652
02653
02654 writeIterator = set.iterator(true);
02655 try {
02656 Iterator writeIterator2 = set.iterator(true);
02657 StoredIterator.close(writeIterator2);
02658 } finally {
02659 StoredIterator.close(writeIterator);
02660 }
02661
02662
02663 readIterator = set.iterator(false);
02664 try {
02665 writeIterator = set.iterator(true);
02666 fail();
02667 StoredIterator.close(writeIterator);
02668 } catch (IllegalStateException e) {
02669 } finally {
02670 StoredIterator.close(readIterator);
02671 }
02672
02673 if (index == null) {
02674
02675 readIterator = set.iterator(false);
02676 try {
02677 map.put(makeKey(1), makeVal(1));
02678 fail();
02679 } catch (IllegalStateException e) {
02680 } finally {
02681 StoredIterator.close(readIterator);
02682 }
02683
02684
02685 writeIterator = set.iterator(true);
02686 try {
02687 if (testStore.isQueueOrRecno()) {
02688 try {
02689 map.append(makeVal(1));
02690 fail();
02691 } catch (IllegalStateException e) {}
02692 } else {
02693 map.append(makeVal(1));
02694 }
02695 } finally {
02696 StoredIterator.close(writeIterator);
02697 }
02698 }
02699 }
02700
02701 Object makeVal(int key) {
02702
02703 if (isEntityBinding) {
02704 return makeEntity(key);
02705 } else {
02706 return new Long(key + 100);
02707 }
02708 }
02709
02710 Object makeVal(int key, int val) {
02711
02712 if (isEntityBinding) {
02713 return makeEntity(key, val);
02714 } else {
02715 return makeVal(val);
02716 }
02717 }
02718
02719 Object makeEntity(int key, int val) {
02720
02721 return new TestEntity(key, val + 100);
02722 }
02723
02724 int intVal(Object val) {
02725
02726 if (isEntityBinding) {
02727 return ((TestEntity) val).value - 100;
02728 } else {
02729 return ((Long) val).intValue() - 100;
02730 }
02731 }
02732
02733 int intKey(Object key) {
02734
02735 return ((Long) key).intValue();
02736 }
02737
02738 Object makeVal(Long key) {
02739
02740 return makeVal(key.intValue());
02741 }
02742
02743 Object makeEntity(int key) {
02744
02745 return makeEntity(key, key);
02746 }
02747
02748 Object makeEntity(Long key) {
02749
02750 return makeEntity(key.intValue());
02751 }
02752
02753 int intIter(Collection coll, Object value) {
02754
02755 if (coll instanceof StoredKeySet) {
02756 return intKey(value);
02757 } else {
02758 if (coll instanceof StoredEntrySet) {
02759 value = ((Map.Entry) value).getValue();
02760 }
02761 return intVal(value);
02762 }
02763 }
02764
02765 Map.Entry mapEntry(Object key, Object val) {
02766
02767 return new MapEntryParameter(key, val);
02768 }
02769
02770 Map.Entry mapEntry(int key) {
02771
02772 return new MapEntryParameter(makeKey(key), makeVal(key));
02773 }
02774
02775 Long makeKey(int key) {
02776
02777 return new Long(key);
02778 }
02779
02780 boolean isSubMap() {
02781
02782 return rangeType != NONE;
02783 }
02784
02785 void checkDupsSize(int expected, Collection coll) {
02786
02787 assertEquals(expected, coll.size());
02788 if (coll instanceof StoredCollection) {
02789 StoredIterator i = ((StoredCollection) coll).iterator(false);
02790 try {
02791 int actual = 0;
02792 if (i.hasNext()) {
02793 i.next();
02794 actual = i.count();
02795 }
02796 assertEquals(expected, actual);
02797 } finally {
02798 StoredIterator.close(i);
02799 }
02800 }
02801 }
02802
02803 private boolean isListAddAllowed() {
02804
02805 return list != null && testStore.isQueueOrRecno() &&
02806 list.areKeysRenumbered();
02807 }
02808
02809 private int countElements(Collection coll) {
02810
02811 int count = 0;
02812 Iterator iter = coll.iterator();
02813 try {
02814 while (iter.hasNext()) {
02815 iter.next();
02816 count += 1;
02817 }
02818 } finally {
02819 StoredIterator.close(iter);
02820 }
02821 return count;
02822 }
02823 }