/*-
* See the file LICENSE for redistribution information.
*
* Copyright (c) 2002-2003
* Sleepycat Software. All rights reserved.
*
* $Id: CollectionTest.java,v 1.20 2003/10/18 19:51:25 mhayes Exp $
*/
package com.sleepycat.bdb.test;
import com.sleepycat.bdb.bind.DataBinding;
import com.sleepycat.bdb.bind.EntityBinding;
import com.sleepycat.db.DbEnv;
import com.sleepycat.bdb.CurrentTransaction;
import com.sleepycat.bdb.DataIndex;
import com.sleepycat.bdb.DataStore;
import com.sleepycat.bdb.TransactionRunner;
import com.sleepycat.bdb.TransactionWorker;
import com.sleepycat.bdb.collection.MapEntry;
import com.sleepycat.bdb.collection.StoredCollection;
import com.sleepycat.bdb.collection.StoredCollections;
import com.sleepycat.bdb.collection.StoredContainer;
import com.sleepycat.bdb.collection.StoredEntrySet;
import com.sleepycat.bdb.collection.StoredIterator;
import com.sleepycat.bdb.collection.StoredKeySet;
import com.sleepycat.bdb.collection.StoredValueSet;
import com.sleepycat.bdb.collection.StoredList;
import com.sleepycat.bdb.collection.StoredMap;
import com.sleepycat.bdb.collection.StoredSortedMap;
import com.sleepycat.bdb.collection.StoredSortedEntrySet;
import com.sleepycat.bdb.collection.StoredSortedKeySet;
import com.sleepycat.bdb.collection.StoredSortedValueSet;
import com.sleepycat.bdb.util.ExceptionUnwrapper;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;
import java.util.SortedMap;
import java.util.SortedSet;
import junit.framework.Test;
import junit.framework.TestCase;
import junit.framework.TestSuite;
/**
* @author Mark Hayes
*/
public class CollectionTest extends TestCase {
private static final int NONE = 0;
private static final int SUB = 1;
private static final int HEAD = 2;
private static final int TAIL = 3;
private static final int MAX_KEY = 6; // must be a multiple of 2
private int beginKey = 1;
private int endKey = MAX_KEY;
private DbEnv env;
private CurrentTransaction currentTxn;
private DataStore store;
private DataIndex index;
private boolean isEntityBinding;
private boolean isAutoCommit;
private TestStore testStore;
private String testName;
private DataBinding keyBinding;
private DataBinding valueBinding;
private EntityBinding entityBinding;
private TransactionRunner readRunner;
private TransactionRunner writeRunner;
private TransactionRunner writeIterRunner;
private TestEnv testEnv;
private StoredMap map;
private StoredMap imap; // insertable map (primary store for indexed map)
private StoredSortedMap smap; // sorted map (null or equal to map)
private StoredMap saveMap;
private StoredSortedMap saveSMap;
private int rangeType;
private StoredList list;
private StoredList ilist; // insertable list (primary store for index list)
private StoredList saveList;
private StoredKeySet keySet;
private StoredValueSet valueSet;
/**
* Runs a command line collection test.
* @see #usage
*/
public static void main(String[] args)
throws Exception {
if (args.length == 1 &&
(args[0].equals("-h") || args[0].equals("-help"))) {
usage();
} else {
junit.textui.TestRunner.run(suite(args));
}
}
private static void usage() {
System.out.println(
"Usage: java com.sleepycat.bdb.test.CollectionTest\n" +
" -h | -help\n" +
" [testName]...\n" +
" where testName has the format:\n" +
" <env>-<store>-{entity|value}\n" +
" <env> is:\n" +
" bdb | cdb | txn\n" +
" <store> is:\n" +
" btree-uniq | btree-dup | btree-dupsort | btree-recnum |\n" +
" hash-uniq | hash-dup | hash-dupsort |\n" +
" queue | recno | recno-renum\n" +
" For example: bdb-btree-uniq-entity\n" +
" If no arguments are given then all tests are run.");
System.exit(2);
}
public static Test suite()
throws Exception {
return suite(null);
}
static Test suite(String[] args)
throws Exception {
TestSuite suite = new TestSuite();
for (int i = 0; i < TestEnv.ALL.length; i += 1) {
for (int j = 0; j < TestStore.ALL.length; j += 1) {
for (int k = 0; k < 2; k += 1) {
boolean entityBinding = (k != 0);
addTest(args, suite, new CollectionTest(
TestEnv.ALL[i], TestStore.ALL[j],
entityBinding, false));
if (TestEnv.ALL[i] == TestEnv.TXN) {
addTest(args, suite, new CollectionTest(
TestEnv.ALL[i], TestStore.ALL[j],
entityBinding, true));
}
}
}
}
return suite;
}
private static void addTest(String[] args, TestSuite suite,
CollectionTest test) {
if (args == null || args.length == 0) {
suite.addTest(test);
} else {
for (int t = 0; t < args.length; t += 1) {
if (args[t].equals(test.testName)) {
suite.addTest(test);
break;
}
}
}
}
public CollectionTest(TestEnv testEnv, TestStore testStore,
boolean isEntityBinding, boolean isAutoCommit) {
super(null);
this.testEnv = testEnv;
this.testStore = testStore;
this.isEntityBinding = isEntityBinding;
this.isAutoCommit = isAutoCommit;
keyBinding = testStore.getKeyBinding();
valueBinding = testStore.getValueBinding();
entityBinding = testStore.getEntityBinding();
testName = testEnv.getName() + '-' + testStore.getName() +
(isEntityBinding ? "-entity" : "-value") +
(isAutoCommit ? "-autocommit" : "");
setName(testName);
}
public void runTest()
throws Exception {
System.out.println(DbTestUtil.qualifiedTestName(this));
try {
env = testEnv.open(testName);
currentTxn = CurrentTransaction.getInstance(env);
// For testing auto-commit, use a normal (transactional) runner for
// all reading and for writing via an iterator, and a do-nothing
// runner for writing via collections; if auto-commit is tested,
// the per-collection auto-commit property will be set elsewhere.
//
TransactionRunner normalRunner = new TransactionRunner(env);
TransactionRunner nullRunner = new NullTransactionRunner(env);
readRunner = nullRunner;
writeIterRunner = normalRunner;
if (isAutoCommit)
writeRunner = nullRunner;
else
writeRunner = normalRunner;
store = testStore.open(env, "unindexed.db");
testUnindexed();
store.close();
TestStore indexOf = testStore.getIndexOf();
if (indexOf != null) {
store = indexOf.open(env, "indexed.db");
index = testStore.openIndex(store, "index.db");
testIndexed();
store.close();
}
env.close(0);
} catch (Exception e) {
throw ExceptionUnwrapper.unwrap(e);
}
}
void testCreation(StoredContainer cont)
throws Exception {
assertEquals(index != null, cont.isIndexed());
assertEquals(testStore.isOrdered(), cont.isOrdered());
assertEquals(testStore.areKeysRenumbered(), cont.areKeysRenumbered());
assertEquals(testStore.areDuplicatesAllowed(),
cont.areDuplicatesAllowed());
assertEquals(isAutoCommit, cont.isAutoCommit());
assertEquals(testEnv == TestEnv.TXN, cont.isTransactional());
try {
cont.size();
fail();
}
catch (UnsupportedOperationException expected) {}
}
void testMapCreation(Map map)
throws Exception {
assertTrue(map.values() instanceof Set);
assertEquals(testStore.isOrdered(),
map.keySet() instanceof SortedSet);
assertEquals(testStore.isOrdered(),
map.entrySet() instanceof SortedSet);
assertEquals(testStore.isOrdered() &&
(isEntityBinding || index != null),
map.values() instanceof SortedSet);
}
void testUnindexed()
throws Exception {
// create primary map
if (testStore.isOrdered()) {
if (isEntityBinding) {
smap = new StoredSortedMap(store, keyBinding,
entityBinding, true);
valueSet = new StoredSortedValueSet(store, entityBinding,
true);
} else {
smap = new StoredSortedMap(store, keyBinding,
valueBinding, true);
// non-indexed sorted value set is not possible since key
// cannot be derived for performing subSet, etc.
}
keySet = new StoredSortedKeySet(store, keyBinding, true);
map = smap;
} else {
if (isEntityBinding) {
map = new StoredMap(store, keyBinding, entityBinding, true);
valueSet = new StoredValueSet(store, entityBinding, true);
} else {
map = new StoredMap(store, keyBinding, valueBinding, true);
valueSet = new StoredValueSet(store, valueBinding, true);
}
smap = null;
keySet = new StoredKeySet(store, keyBinding, true);
}
imap = map;
// create primary list
if (testStore.hasRecNumAccess()) {
if (isEntityBinding) {
ilist = new StoredList(store, entityBinding, true);
} else {
ilist = new StoredList(store, valueBinding, true);
}
list = ilist;
} else {
try {
if (isEntityBinding) {
ilist = new StoredList(store, entityBinding, true);
} else {
ilist = new StoredList(store, valueBinding, true);
}
fail();
} catch (IllegalArgumentException expected) {}
}
setAutoCommit();
testCreation(map);
if (list != null) {
testCreation(list);
assertNotNull(smap);
}
testMapCreation(map);
addAll();
testAll();
}
void testIndexed()
throws Exception {
// create primary map
if (isEntityBinding) {
map = new StoredMap(store, keyBinding, entityBinding, true);
} else {
map = new StoredMap(store, keyBinding, valueBinding, true);
}
imap = map;
smap = null;
// create primary list
if (testStore.hasRecNumAccess()) {
if (isEntityBinding) {
list = new StoredList(store, entityBinding, true);
} else {
list = new StoredList(store, valueBinding, true);
}
ilist = list;
}
setAutoCommit();
addAll();
readAll();
// create indexed map (keySet/valueSet)
if (testStore.isOrdered()) {
if (isEntityBinding) {
map = smap = new StoredSortedMap(index, keyBinding,
entityBinding, true);
valueSet = new StoredSortedValueSet(index, entityBinding,
true);
} else {
map = smap = new StoredSortedMap(index, keyBinding,
valueBinding, true);
valueSet = new StoredSortedValueSet(index, valueBinding, true);
}
keySet = new StoredSortedKeySet(index, keyBinding, true);
} else {
if (isEntityBinding) {
map = new StoredMap(index, keyBinding, entityBinding, true);
valueSet = new StoredValueSet(index, entityBinding, true);
} else {
map = new StoredMap(index, keyBinding, valueBinding, true);
valueSet = new StoredValueSet(index, valueBinding, true);
}
smap = null;
keySet = new StoredKeySet(index, keyBinding, true);
}
// create indexed list
if (testStore.hasRecNumAccess()) {
if (isEntityBinding) {
list = new StoredList(index, entityBinding, true);
} else {
list = new StoredList(index, valueBinding, true);
}
} else {
try {
if (isEntityBinding) {
list = new StoredList(index, entityBinding, true);
} else {
list = new StoredList(index, valueBinding, true);
}
fail();
}
catch (IllegalArgumentException expected) {}
}
setAutoCommit();
testCreation(map);
testCreation((StoredContainer) map.values());
testCreation((StoredContainer) map.keySet());
testCreation((StoredContainer) map.entrySet());
if (list != null) {
testCreation(list);
assertNotNull(smap);
}
testMapCreation(map);
testAll();
}
void setAutoCommit() {
if (isAutoCommit) {
if (map != null)
map = (StoredMap)
StoredCollections.autoCommitMap(map);
if (imap != null)
imap = (StoredMap)
StoredCollections.autoCommitMap(imap);
if (smap != null)
smap = (StoredSortedMap)
StoredCollections.autoCommitSortedMap(smap);
if (keySet != null)
keySet = (StoredKeySet)
StoredCollections.autoCommitSet(keySet);
if (valueSet != null)
valueSet = (StoredValueSet)
StoredCollections.autoCommitSet(valueSet);
if (list != null)
list = (StoredList)
StoredCollections.autoCommitList(list);
if (ilist != null)
ilist = (StoredList)
StoredCollections.autoCommitList(ilist);
}
}
void testAll()
throws Exception {
checkKeySetAndValueSet();
readAll();
updateAll();
readAll();
if (!map.areKeysRenumbered()) {
removeOdd();
readEven();
addOdd();
readAll();
removeOddIter();
readEven();
if (imap.areDuplicatesAllowed()) {
addOddDup();
} else {
addOdd();
}
readAll();
removeOddEntry();
readEven();
addOdd();
readAll();
if (isEntityBinding) {
removeOddEntity();
readEven();
addOddEntity();
readAll();
}
bulkOperations();
}
if (isListAddAllowed()) {
removeOddList();
readEvenList();
addOddList();
readAll();
if (!isEntityBinding) {
removeOddListValue();
readEvenList();
addOddList();
readAll();
}
}
if (list != null) {
bulkListOperations();
} else {
listOperationsNotAllowed();
}
if (smap != null) {
readWriteRange(SUB, 1, 1);
readWriteRange(HEAD, 1, 1);
readWriteRange(SUB, 1, MAX_KEY);
readWriteRange(HEAD, 1, MAX_KEY);
readWriteRange(TAIL, 1, MAX_KEY);
readWriteRange(SUB, 1, 3);
readWriteRange(HEAD, 1, 3);
readWriteRange(SUB, 2, 2);
readWriteRange(SUB, 2, MAX_KEY);
readWriteRange(TAIL, 2, MAX_KEY);
readWriteRange(SUB, MAX_KEY, MAX_KEY);
readWriteRange(TAIL, MAX_KEY, MAX_KEY);
readWriteRange(SUB, MAX_KEY + 1, MAX_KEY + 1);
readWriteRange(TAIL, MAX_KEY + 1, MAX_KEY + 1);
readWriteRange(SUB, 0, 0);
readWriteRange(HEAD, 0, 0);
}
updateAll();
readAll();
if (map.areDuplicatesAllowed()) {
readWriteDuplicates();
readAll();
} else {
duplicatesNotAllowed();
readAll();
}
if (testEnv.isCdbMode()) {
testCdbLocking();
}
removeAll();
if (isListAddAllowed()) {
testIterAddList();
clearAll();
}
if (imap.areDuplicatesAllowed()) {
testIterAddDuplicates();
clearAll();
}
if (isListAddAllowed()) {
addAllList();
readAll();
removeAllList();
}
appendAll();
}
void checkKeySetAndValueSet() {
// use bulk operations to check that explicitly constructed
// keySet/valueSet are equivalent
assertTrue(imap.keySet().equals(keySet));
if (valueSet != null)
assertTrue(imap.values().equals(valueSet));
}
void addAll()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertTrue(imap.isEmpty());
Iterator iter = imap.entrySet().iterator();
try {
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
assertEquals(0, imap.keySet().toArray().length);
assertEquals(0, imap.keySet().toArray(new Object[0]).length);
assertEquals(0, imap.entrySet().toArray().length);
assertEquals(0, imap.entrySet().toArray(new Object[0]).length);
assertEquals(0, imap.values().toArray().length);
assertEquals(0, imap.values().toArray(new Object[0]).length);
for (int i = beginKey; i <= endKey; i += 1) {
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(imap.get(key));
assertTrue(!imap.keySet().contains(key));
assertTrue(!imap.values().contains(val));
assertNull(imap.put(key, val));
assertEquals(val, imap.get(key));
assertTrue(imap.keySet().contains(key));
assertTrue(imap.values().contains(val));
assertTrue(imap.duplicates(key).contains(val));
if (!imap.areDuplicatesAllowed()) {
assertEquals(val, imap.put(key, val));
}
checkDupsSize(1, imap.duplicates(key));
}
assertTrue(!imap.isEmpty());
}
});
}
void appendAll()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertTrue(imap.isEmpty());
TestKeyAssigner keyAssigner =
(TestKeyAssigner) store.getKeyAssigner();
if (keyAssigner != null) keyAssigner.reset();
for (int i = beginKey; i <= endKey; i += 1) {
boolean useList = (i & 1) == 0;
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(imap.get(key));
if (keyAssigner != null) {
if (useList && ilist != null)
assertEquals(i - 1, ilist.append(val));
else
assertEquals(key, imap.append(val));
assertEquals(val, imap.get(key));
} else {
Long recnoKey;
if (useList && ilist != null)
recnoKey = new Long(ilist.append(val) + 1);
else
recnoKey = (Long) imap.append(val);
assertNotNull(recnoKey);
Object recnoVal;
if (isEntityBinding)
recnoVal = makeEntity(recnoKey.intValue(), i);
else
recnoVal = val;
assertEquals(recnoVal, imap.get(recnoKey));
}
}
}
});
}
void updateAll()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 1) {
Long key = makeKey(i);
Object val = makeVal(i);
if (!imap.areDuplicatesAllowed()) {
assertEquals(val, imap.put(key, val));
}
if (isEntityBinding) {
assertTrue(!imap.values().add(val));
}
checkDupsSize(1, imap.duplicates(key));
if (ilist != null) {
int idx = i - 1;
assertEquals(val, ilist.set(idx, val));
}
}
updateIter(map.entrySet());
updateIter(map.values());
if (beginKey <= endKey) {
ListIterator iter = (ListIterator) map.keySet().iterator();
try {
assertNotNull(iter.next());
iter.set(makeKey(beginKey));
fail();
} catch (UnsupportedOperationException e) {
} finally {
StoredIterator.close(iter);
}
}
if (list != null) updateIter(list);
}
});
}
void updateIter(final Collection coll)
throws Exception {
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
ListIterator iter = (ListIterator) coll.iterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
assertTrue(iter.hasNext());
Object obj = iter.next();
if (index != null) {
try {
setValuePlusOne(iter, obj);
fail();
}
catch (UnsupportedOperationException e) {}
} else if
(((StoredCollection) coll).areDuplicatesOrdered()) {
try {
setValuePlusOne(iter, obj);
fail();
} catch (IllegalArgumentException e) {}
} else {
setValuePlusOne(iter, obj);
}
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
}
});
}
void setValuePlusOne(ListIterator iter, Object obj) {
if (obj instanceof Map.Entry) {
Map.Entry entry = (Map.Entry) obj;
Long key = (Long) entry.getKey();
Object oldVal = entry.getValue();
Object val = makeVal(key.intValue() + 1);
if (isEntityBinding) {
try {
// must fail on attempt to change the key via an entity
entry.setValue(val);
fail();
}
catch (IllegalArgumentException e) {}
val = makeEntity(key.intValue(), key.intValue() + 1);
}
entry.setValue(val);
assertEquals(val, entry.getValue());
assertEquals(val, map.get(key));
assertTrue(map.duplicates(key).contains(val));
checkDupsSize(1, map.duplicates(key));
entry.setValue(oldVal);
assertEquals(oldVal, entry.getValue());
assertEquals(oldVal, map.get(key));
assertTrue(map.duplicates(key).contains(oldVal));
checkDupsSize(1, map.duplicates(key));
} else {
Object oldVal = obj;
Long key = makeKey(intVal(obj));
Object val = makeVal(key.intValue() + 1);
if (isEntityBinding) {
try {
// must fail on attempt to change the key via an entity
iter.set(val);
fail();
}
catch (IllegalArgumentException e) {}
val = makeEntity(key.intValue(), key.intValue() + 1);
}
iter.set(val);
assertEquals(val, map.get(key));
assertTrue(map.duplicates(key).contains(val));
checkDupsSize(1, map.duplicates(key));
iter.set(oldVal);
assertEquals(oldVal, map.get(key));
assertTrue(map.duplicates(key).contains(oldVal));
checkDupsSize(1, map.duplicates(key));
}
}
void removeAll()
throws Exception {
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertTrue(!map.isEmpty());
ListIterator iter = null;
try {
if (list != null)
iter = list.listIterator();
else
iter = (ListIterator) map.values().iterator();
iteratorSetAndRemoveNotAllowed(iter);
assertNotNull(iter.next());
iter.remove();
iteratorSetAndRemoveNotAllowed(iter);
if (index == null) {
Object val = iter.next();
assertNotNull(val);
iter.set(val);
if (map.areDuplicatesAllowed()) {
iter.add(makeVal(intVal(val), intVal(val) + 1));
iteratorSetAndRemoveNotAllowed(iter);
}
}
} finally {
StoredIterator.close(iter);
}
map.clear();
assertTrue(map.isEmpty());
assertTrue(map.entrySet().isEmpty());
assertTrue(map.keySet().isEmpty());
assertTrue(map.values().isEmpty());
for (int i = beginKey; i <= endKey; i += 1) {
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(map.get(key));
assertTrue(!map.duplicates(key).contains(val));
checkDupsSize(0, map.duplicates(key));
}
}
});
}
void clearAll()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
map.clear();
assertTrue(map.isEmpty());
}
});
}
void iteratorSetAndRemoveNotAllowed(ListIterator i) {
try {
i.remove();
fail();
} catch (IllegalStateException e) {}
if (index == null) {
try {
Object val = makeVal(1);
i.set(val);
fail();
}
catch (IllegalStateException e) {}
}
}
void removeOdd()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
boolean toggle = false;
for (int i = beginKey; i <= endKey; i += 2) {
toggle = !toggle;
Long key = makeKey(i);
Object val = makeVal(i);
if (toggle) {
assertTrue(map.keySet().contains(key));
assertTrue(map.keySet().remove(key));
assertTrue(!map.keySet().contains(key));
} else {
assertTrue(map.containsValue(val));
Object oldVal = map.remove(key);
assertEquals(oldVal, val);
assertTrue(!map.containsKey(key));
assertTrue(!map.containsValue(val));
}
assertNull(map.get(key));
assertTrue(!map.duplicates(key).contains(val));
checkDupsSize(0, map.duplicates(key));
}
}
});
}
void removeOddEntity()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 2) {
Long key = makeKey(i);
Object val = makeVal(i);
assertTrue(map.values().contains(val));
assertTrue(map.values().remove(val));
assertTrue(!map.values().contains(val));
assertNull(map.get(key));
assertTrue(!map.duplicates(key).contains(val));
checkDupsSize(0, map.duplicates(key));
}
}
});
}
void removeOddEntry()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 2) {
Long key = makeKey(i);
Object val = mapEntry(i);
assertTrue(map.entrySet().contains(val));
assertTrue(map.entrySet().remove(val));
assertTrue(!map.entrySet().contains(val));
assertNull(map.get(key));
}
}
});
}
void removeOddIter()
throws Exception {
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
Iterator iter = map.keySet().iterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
assertTrue(iter.hasNext());
Long key = (Long) iter.next();
assertNotNull(key);
if (map instanceof SortedMap) {
assertEquals(makeKey(i), key);
}
if ((key.intValue() & 1) != 0) {
iter.remove();
}
}
} finally {
StoredIterator.close(iter);
}
}
});
}
void removeOddList()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 2) {
// remove by index
// (with entity binding, embbeded keys in values are
// being changed so we can't use values for comparison)
int idx = (i - beginKey) / 2;
Object val = makeVal(i);
if (!isEntityBinding) {
assertTrue(list.contains(val));
assertEquals(val, list.get(idx));
assertEquals(idx, list.indexOf(val));
}
assertNotNull(list.get(idx));
if (isEntityBinding) {
assertNotNull(list.remove(idx));
} else {
assertTrue(list.contains(val));
assertEquals(val, list.remove(idx));
}
assertTrue(!list.remove(val));
assertTrue(!list.contains(val));
assertTrue(!val.equals(list.get(idx)));
}
}
});
}
void removeOddListValue()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 2) {
// for non-entity case remove by value
// (with entity binding, embbeded keys in values are
// being changed so we can't use values for comparison)
int idx = (i - beginKey) / 2;
Object val = makeVal(i);
assertTrue(list.contains(val));
assertEquals(val, list.get(idx));
assertEquals(idx, list.indexOf(val));
assertTrue(list.remove(val));
assertTrue(!list.remove(val));
assertTrue(!list.contains(val));
assertTrue(!val.equals(list.get(idx)));
}
}
});
}
void addOdd()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
// add using Map.put()
for (int i = beginKey; i <= endKey; i += 2) {
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(imap.get(key));
assertNull(imap.put(key, val));
assertEquals(val, imap.get(key));
assertTrue(imap.duplicates(key).contains(val));
checkDupsSize(1, imap.duplicates(key));
if (isEntityBinding) {
assertTrue(!imap.values().add(val));
}
if (!imap.areDuplicatesAllowed()) {
assertEquals(val, imap.put(key, val));
}
}
}
});
}
void addOddEntity()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
// add using Map.values().add()
for (int i = beginKey; i <= endKey; i += 2) {
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(imap.get(key));
assertTrue(!imap.values().contains(val));
assertTrue(imap.values().add(val));
assertEquals(val, imap.get(key));
assertTrue(imap.values().contains(val));
assertTrue(imap.duplicates(key).contains(val));
checkDupsSize(1, imap.duplicates(key));
if (isEntityBinding) {
assertTrue(!imap.values().add(val));
}
}
}
});
}
void addOddDup()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
// add using Map.duplicates().add()
for (int i = beginKey; i <= endKey; i += 2) {
Long key = makeKey(i);
Object val = makeVal(i);
assertNull(imap.get(key));
assertTrue(!imap.values().contains(val));
assertTrue(imap.duplicates(key).add(val));
assertEquals(val, imap.get(key));
assertTrue(imap.values().contains(val));
assertTrue(imap.duplicates(key).contains(val));
checkDupsSize(1, imap.duplicates(key));
assertTrue(!imap.duplicates(key).add(val));
if (isEntityBinding) {
assertTrue(!imap.values().add(val));
}
}
}
});
}
void addOddList()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 2) {
int idx = i - beginKey;
Object val = makeVal(i);
assertTrue(!list.contains(val));
assertTrue(!val.equals(list.get(idx)));
list.add(idx, val);
assertTrue(list.contains(val));
assertEquals(val, list.get(idx));
}
}
});
}
void addAllList()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
for (int i = beginKey; i <= endKey; i += 1) {
int idx = i - beginKey;
Object val = makeVal(i);
assertTrue(!list.contains(val));
assertTrue(list.add(val));
assertTrue(list.contains(val));
assertEquals(val, list.get(idx));
}
}
});
}
void removeAllList()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertTrue(!list.isEmpty());
list.clear();
assertTrue(list.isEmpty());
for (int i = beginKey; i <= endKey; i += 1) {
int idx = i - beginKey;
Object val = makeVal(i);
assertNull(list.get(idx));
}
}
});
}
void testIterAddList()
throws Exception {
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
ListIterator i = list.listIterator();
try {
assertTrue(!i.hasNext());
i.add(makeVal(3));
assertTrue(!i.hasNext());
assertTrue(i.hasPrevious());
assertEquals(3, intVal(i.previous()));
i.add(makeVal(1));
assertTrue(i.hasPrevious());
assertTrue(i.hasNext());
assertEquals(1, intVal(i.previous()));
assertTrue(i.hasNext());
assertEquals(1, intVal(i.next()));
assertTrue(i.hasNext());
assertEquals(3, intVal(i.next()));
assertEquals(3, intVal(i.previous()));
assertTrue(i.hasNext());
i.add(makeVal(2));
assertTrue(i.hasNext());
assertTrue(i.hasPrevious());
assertEquals(2, intVal(i.previous()));
assertTrue(i.hasNext());
assertEquals(2, intVal(i.next()));
assertTrue(i.hasNext());
assertEquals(3, intVal(i.next()));
assertTrue(!i.hasNext());
i.add(makeVal(4));
i.add(makeVal(5));
assertTrue(!i.hasNext());
assertEquals(5, intVal(i.previous()));
assertEquals(4, intVal(i.previous()));
assertEquals(3, intVal(i.previous()));
assertEquals(2, intVal(i.previous()));
assertEquals(1, intVal(i.previous()));
assertTrue(!i.hasPrevious());
} finally {
StoredIterator.close(i);
}
}
});
}
void testIterAddDuplicates()
throws Exception {
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
assertNull(imap.put(makeKey(1), makeVal(1)));
ListIterator i =
(ListIterator) imap.duplicates(makeKey(1)).iterator();
try {
if (imap.areDuplicatesOrdered()) {
i.add(makeVal(1, 4));
i.add(makeVal(1, 2));
i.add(makeVal(1, 3));
while (i.hasPrevious()) i.previous();
assertEquals(1, intVal(i.next()));
assertEquals(2, intVal(i.next()));
assertEquals(3, intVal(i.next()));
assertEquals(4, intVal(i.next()));
assertTrue(!i.hasNext());
} else {
assertEquals(1, intVal(i.next()));
i.add(makeVal(1, 2));
i.add(makeVal(1, 3));
assertTrue(!i.hasNext());
assertTrue(i.hasPrevious());
assertEquals(3, intVal(i.previous()));
assertEquals(2, intVal(i.previous()));
assertEquals(1, intVal(i.previous()));
assertTrue(!i.hasPrevious());
i.add(makeVal(1, 4));
i.add(makeVal(1, 5));
assertTrue(i.hasNext());
assertEquals(5, intVal(i.previous()));
assertEquals(4, intVal(i.previous()));
assertTrue(!i.hasPrevious());
assertEquals(4, intVal(i.next()));
assertEquals(5, intVal(i.next()));
assertEquals(1, intVal(i.next()));
assertEquals(2, intVal(i.next()));
assertEquals(3, intVal(i.next()));
assertTrue(!i.hasNext());
}
} finally {
StoredIterator.close(i);
}
}
});
}
void readAll()
throws Exception {
readRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
// map
assertNotNull(map.toString());
for (int i = beginKey; i <= endKey; i += 1) {
Long key = makeKey(i);
Object val = map.get(key);
assertEquals(makeVal(i), val);
assertTrue(map.containsKey(key));
assertTrue(map.containsValue(val));
assertTrue(map.keySet().contains(key));
assertTrue(map.values().contains(val));
assertTrue(map.duplicates(key).contains(val));
checkDupsSize(1, map.duplicates(key));
}
assertNull(map.get(makeKey(-1)));
assertNull(map.get(makeKey(0)));
assertNull(map.get(makeKey(beginKey - 1)));
assertNull(map.get(makeKey(endKey + 1)));
checkDupsSize(0, map.duplicates(makeKey(-1)));
checkDupsSize(0, map.duplicates(makeKey(0)));
checkDupsSize(0, map.duplicates(makeKey(beginKey - 1)));
checkDupsSize(0, map.duplicates(makeKey(endKey + 1)));
// entrySet
Set set = map.entrySet();
assertNotNull(set.toString());
assertEquals(beginKey > endKey, set.isEmpty());
Iterator iter = set.iterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
assertTrue(iter.hasNext());
Map.Entry entry = (Map.Entry) iter.next();
Long key = (Long) entry.getKey();
Object val = entry.getValue();
if (map instanceof SortedMap) {
assertEquals(intKey(key), i);
}
assertEquals(intKey(key), intVal(val));
assertTrue(set.contains(entry));
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
Map.Entry[] entries =
(Map.Entry[]) set.toArray(new Map.Entry[0]);
assertNotNull(entries);
assertEquals(endKey - beginKey + 1, entries.length);
for (int i = beginKey; i <= endKey; i += 1) {
Map.Entry entry = entries[i - beginKey];
assertNotNull(entry);
if (map instanceof SortedMap) {
assertEquals(makeKey(i), entry.getKey());
assertEquals(makeVal(i), entry.getValue());
}
}
readIterator(set, set.iterator(), beginKey, endKey);
if (smap != null) {
SortedSet sset = (SortedSet) set;
if (beginKey == 1 && endKey >= 1) {
readIterator(sset, sset.subSet(mapEntry(1),
mapEntry(2))
.iterator(), 1, 1);
}
if (beginKey <= 2 && endKey >= 2) {
readIterator(sset, sset.subSet(mapEntry(2),
mapEntry(3))
.iterator(), 2, 2);
}
if (beginKey <= endKey) {
readIterator(sset, sset.subSet(
mapEntry(endKey),
mapEntry(endKey + 1))
.iterator(),
endKey, endKey);
}
if (isSubMap()) {
if (beginKey <= endKey) {
if (rangeType != TAIL) {
try {
sset.subSet(mapEntry(endKey + 1),
mapEntry(endKey + 2));
fail();
} catch (IllegalArgumentException e) {}
}
if (rangeType != HEAD) {
try {
sset.subSet(mapEntry(0),
mapEntry(1));
fail();
} catch (IllegalArgumentException e) {}
}
}
} else {
readIterator(sset, sset.subSet(
mapEntry(endKey + 1),
mapEntry(endKey + 2))
.iterator(),
endKey, endKey - 1);
readIterator(sset, sset.subSet(mapEntry(0),
mapEntry(1))
.iterator(),
0, -1);
}
}
// keySet
set = map.keySet();
assertNotNull(set.toString());
assertEquals(beginKey > endKey, set.isEmpty());
iter = set.iterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
assertTrue(iter.hasNext());
Long key = (Long) iter.next();
assertTrue(set.contains(key));
Object val = map.get(key);
if (map instanceof SortedMap) {
assertEquals(key, makeKey(i));
}
assertEquals(intKey(key), intVal(val));
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
Long[] keys = (Long[]) set.toArray(new Long[0]);
assertNotNull(keys);
assertEquals(endKey - beginKey + 1, keys.length);
for (int i = beginKey; i <= endKey; i += 1) {
Long key = keys[i - beginKey];
assertNotNull(key);
if (map instanceof SortedMap) {
assertEquals(makeKey(i), key);
}
}
readIterator(set, set.iterator(), beginKey, endKey);
// values
Collection coll = map.values();
assertNotNull(coll.toString());
assertEquals(beginKey > endKey, coll.isEmpty());
iter = coll.iterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
assertTrue(iter.hasNext());
Object val = iter.next();
if (map instanceof SortedMap) {
assertEquals(makeVal(i), val);
}
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
Object[] values = coll.toArray();
assertNotNull(values);
assertEquals(endKey - beginKey + 1, values.length);
for (int i = beginKey; i <= endKey; i += 1) {
Object val = values[i - beginKey];
assertNotNull(val);
if (map instanceof SortedMap) {
assertEquals(makeVal(i), val);
}
}
readIterator(coll, coll.iterator(), beginKey, endKey);
// list
if (list != null) {
assertNotNull(list.toString());
assertEquals(beginKey > endKey, list.isEmpty());
for (int i = beginKey; i <= endKey; i += 1) {
int idx = i - beginKey;
Object val = list.get(idx);
assertEquals(makeVal(i), val);
assertTrue(list.contains(val));
assertEquals(idx, list.indexOf(val));
assertEquals(idx, list.lastIndexOf(val));
}
ListIterator li = list.listIterator();
try {
for (int i = beginKey; i <= endKey; i += 1) {
int idx = i - beginKey;
assertTrue(li.hasNext());
assertEquals(idx, li.nextIndex());
Object val = li.next();
assertEquals(makeVal(i), val);
assertEquals(idx, li.previousIndex());
}
assertTrue(!li.hasNext());
} finally {
StoredIterator.close(li);
}
if (beginKey < endKey) {
li = list.listIterator(1);
try {
for (int i = beginKey + 1; i <= endKey; i += 1) {
int idx = i - beginKey;
assertTrue(li.hasNext());
assertEquals(idx, li.nextIndex());
Object val = li.next();
assertEquals(makeVal(i), val);
assertEquals(idx, li.previousIndex());
}
assertTrue(!li.hasNext());
} finally {
StoredIterator.close(li);
}
}
values = list.toArray();
assertNotNull(values);
assertEquals(endKey - beginKey + 1, values.length);
for (int i = beginKey; i <= endKey; i += 1) {
Object val = values[i - beginKey];
assertNotNull(val);
assertEquals(makeVal(i), val);
}
readIterator(list, list.iterator(), beginKey, endKey);
}
// first/last
if (smap != null) {
if (beginKey <= endKey &&
beginKey >= 1 && beginKey <= MAX_KEY) {
assertEquals(makeKey(beginKey),
smap.firstKey());
assertEquals(makeKey(beginKey),
((SortedSet) smap.keySet()).first());
Object entry = ((SortedSet) smap.entrySet()).first();
assertEquals(makeKey(beginKey),
((Map.Entry) entry).getKey());
if (smap.values() instanceof SortedSet) {
assertEquals(makeVal(beginKey),
((SortedSet) smap.values()).first());
}
} else {
assertNull(smap.firstKey());
assertNull(((SortedSet) smap.keySet()).first());
assertNull(((SortedSet) smap.entrySet()).first());
if (smap.values() instanceof SortedSet) {
assertNull(((SortedSet) smap.values()).first());
}
}
if (beginKey <= endKey &&
endKey >= 1 && endKey <= MAX_KEY) {
assertEquals(makeKey(endKey),
smap.lastKey());
assertEquals(makeKey(endKey),
((SortedSet) smap.keySet()).last());
Object entry = ((SortedSet) smap.entrySet()).last();
assertEquals(makeKey(endKey),
((Map.Entry) entry).getKey());
if (smap.values() instanceof SortedSet) {
assertEquals(makeVal(endKey),
((SortedSet) smap.values()).last());
}
} else {
assertNull(smap.lastKey());
assertNull(((SortedSet) smap.keySet()).last());
assertNull(((SortedSet) smap.entrySet()).last());
if (smap.values() instanceof SortedSet) {
assertNull(((SortedSet) smap.values()).last());
}
}
}
}
});
}
void readEven()
throws Exception {
readRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
int readBegin = ((beginKey & 1) != 0) ?
(beginKey + 1) : beginKey;
int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey;
int readIncr = 2;
// map
for (int i = beginKey; i <= endKey; i += 1) {
Long key = makeKey(i);
if ((i & 1) == 0) {
Object val = map.get(key);
assertEquals(makeVal(i), val);
assertTrue(map.containsKey(key));
assertTrue(map.containsValue(val));
assertTrue(map.keySet().contains(key));
assertTrue(map.values().contains(val));
assertTrue(map.duplicates(key).contains(val));
checkDupsSize(1, map.duplicates(key));
} else {
Object val = makeVal(i);
assertTrue(!map.containsKey(key));
assertTrue(!map.containsValue(val));
assertTrue(!map.keySet().contains(key));
assertTrue(!map.values().contains(val));
assertTrue(!map.duplicates(key).contains(val));
checkDupsSize(0, map.duplicates(key));
}
}
// entrySet
Set set = map.entrySet();
assertEquals(beginKey > endKey, set.isEmpty());
Iterator iter = set.iterator();
try {
for (int i = readBegin; i <= readEnd; i += readIncr) {
assertTrue(iter.hasNext());
Map.Entry entry = (Map.Entry) iter.next();
Long key = (Long) entry.getKey();
Object val = entry.getValue();
if (map instanceof SortedMap) {
assertEquals(intKey(key), i);
}
assertEquals(intKey(key), intVal(val));
assertTrue(set.contains(entry));
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
// keySet
set = map.keySet();
assertEquals(beginKey > endKey, set.isEmpty());
iter = set.iterator();
try {
for (int i = readBegin; i <= readEnd; i += readIncr) {
assertTrue(iter.hasNext());
Long key = (Long) iter.next();
assertTrue(set.contains(key));
Object val = map.get(key);
if (map instanceof SortedMap) {
assertEquals(key, makeKey(i));
}
assertEquals(intKey(key), intVal(val));
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
// values
Collection coll = map.values();
assertEquals(beginKey > endKey, coll.isEmpty());
iter = coll.iterator();
try {
for (int i = readBegin; i <= readEnd; i += readIncr) {
assertTrue(iter.hasNext());
Object val = iter.next();
if (map instanceof SortedMap) {
assertEquals(makeVal(i), val);
}
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
// list not used since keys may not be renumbered for this
// method to work in general
// first/last
if (smap != null) {
if (readBegin <= readEnd &&
readBegin >= 1 && readBegin <= MAX_KEY) {
assertEquals(makeKey(readBegin),
smap.firstKey());
assertEquals(makeKey(readBegin),
((SortedSet) smap.keySet()).first());
Object entry = ((SortedSet) smap.entrySet()).first();
assertEquals(makeKey(readBegin),
((Map.Entry) entry).getKey());
if (smap.values() instanceof SortedSet) {
assertEquals(makeVal(readBegin),
((SortedSet) smap.values()).first());
}
} else {
assertNull(smap.firstKey());
assertNull(((SortedSet) smap.keySet()).first());
assertNull(((SortedSet) smap.entrySet()).first());
if (smap.values() instanceof SortedSet) {
assertNull(((SortedSet) smap.values()).first());
}
}
if (readBegin <= readEnd &&
readEnd >= 1 && readEnd <= MAX_KEY) {
assertEquals(makeKey(readEnd),
smap.lastKey());
assertEquals(makeKey(readEnd),
((SortedSet) smap.keySet()).last());
Object entry = ((SortedSet) smap.entrySet()).last();
assertEquals(makeKey(readEnd),
((Map.Entry) entry).getKey());
if (smap.values() instanceof SortedSet) {
assertEquals(makeVal(readEnd),
((SortedSet) smap.values()).last());
}
} else {
assertNull(smap.lastKey());
assertNull(((SortedSet) smap.keySet()).last());
assertNull(((SortedSet) smap.entrySet()).last());
if (smap.values() instanceof SortedSet) {
assertNull(((SortedSet) smap.values()).last());
}
}
}
}
});
}
void readEvenList()
throws Exception {
readRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
int readBegin = ((beginKey & 1) != 0) ?
(beginKey + 1) : beginKey;
int readEnd = ((endKey & 1) != 0) ? (endKey - 1) : endKey;
int readIncr = 2;
assertEquals(beginKey > endKey, list.isEmpty());
ListIterator iter = list.listIterator();
try {
int idx = 0;
for (int i = readBegin; i <= readEnd; i += readIncr) {
assertTrue(iter.hasNext());
assertEquals(idx, iter.nextIndex());
Object val = iter.next();
assertEquals(idx, iter.previousIndex());
if (isEntityBinding) {
assertEquals(i, intVal(val));
} else {
assertEquals(makeVal(i), val);
}
idx += 1;
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
}
});
}
void readIterator(Collection coll, Iterator iter,
int beginValue, int endValue) {
ListIterator li = (ListIterator) iter;
boolean isList = (coll instanceof List);
Iterator clone = null;
try {
// at beginning
assertTrue(!li.hasPrevious());
try { li.previous(); } catch (NoSuchElementException e) {}
if (isList) assertEquals(-1, li.previousIndex());
if (endValue < beginValue) {
// is empty
assertTrue(!iter.hasNext());
try { iter.next(); } catch (NoSuchElementException e) {}
if (isList) assertEquals(Integer.MAX_VALUE, li.nextIndex());
}
// loop thru all and collect in array
StoredIterator si = (StoredIterator) iter;
int[] values = new int[endValue - beginValue + 1];
for (int i = beginValue; i <= endValue; i += 1) {
assertTrue(iter.hasNext());
int idx = i - beginKey;
if (isList) assertEquals(idx, li.nextIndex());
int value = intIter(coll, iter.next());
if (isList) assertEquals(idx, li.previousIndex());
values[i - beginValue] = value;
if (si.getCollection().isOrdered()) {
assertEquals(i, value);
} else {
assertTrue(value >= beginValue);
assertTrue(value <= endValue);
}
}
// at end
assertTrue(!iter.hasNext());
try { iter.next(); } catch (NoSuchElementException e) {}
if (isList) assertEquals(Integer.MAX_VALUE, li.nextIndex());
// clone at same position
clone = StoredCollections.iterator(iter);
assertTrue(!clone.hasNext());
// loop thru in reverse
for (int i = endValue; i >= beginValue; i -= 1) {
assertTrue(li.hasPrevious());
int idx = i - beginKey;
if (isList) assertEquals(idx, li.previousIndex());
int value = intIter(coll, li.previous());
if (isList) assertEquals(idx, li.nextIndex());
assertEquals(values[i - beginValue], value);
}
// clone should not have changed
assertTrue(!clone.hasNext());
// at beginning
assertTrue(!li.hasPrevious());
try { li.previous(); } catch (NoSuchElementException e) {}
if (isList) assertEquals(-1, li.previousIndex());
// loop thru with some back-and-forth
for (int i = beginValue; i <= endValue; i += 1) {
assertTrue(iter.hasNext());
int idx = i - beginKey;
if (isList) assertEquals(idx, li.nextIndex());
Object obj = iter.next();
if (isList) assertEquals(idx, li.previousIndex());
assertEquals(obj, li.previous());
if (isList) assertEquals(idx, li.nextIndex());
assertEquals(obj, iter.next());
if (isList) assertEquals(idx, li.previousIndex());
int value = intIter(coll, obj);
assertEquals(values[i - beginValue], value);
}
// at end
assertTrue(!iter.hasNext());
try { iter.next(); } catch (NoSuchElementException e) {}
if (isList) assertEquals(Integer.MAX_VALUE, li.nextIndex());
} finally {
StoredIterator.close(iter);
StoredIterator.close(clone);
}
}
void bulkOperations()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
HashMap hmap = new HashMap();
for (int i = beginKey; i <= endKey; i += 1) {
hmap.put(makeKey(i), makeVal(i));
}
assertTrue(map.equals(hmap));
assertTrue(map.entrySet().equals(hmap.entrySet()));
assertTrue(map.keySet().equals(hmap.keySet()));
assertTrue(map.values().equals(hmap.values()));
assertTrue(map.entrySet().containsAll(hmap.entrySet()));
assertTrue(map.keySet().containsAll(hmap.keySet()));
assertTrue(map.values().containsAll(hmap.values()));
map.clear();
assertTrue(map.isEmpty());
imap.putAll(hmap);
assertTrue(map.equals(hmap));
assertTrue(map.entrySet().removeAll(hmap.entrySet()));
assertTrue(map.entrySet().isEmpty());
assertTrue(!map.entrySet().removeAll(hmap.entrySet()));
assertTrue(imap.entrySet().addAll(hmap.entrySet()));
assertTrue(map.entrySet().containsAll(hmap.entrySet()));
assertTrue(!imap.entrySet().addAll(hmap.entrySet()));
assertTrue(map.equals(hmap));
assertTrue(!map.entrySet().retainAll(hmap.entrySet()));
assertTrue(map.equals(hmap));
assertTrue(map.entrySet().retainAll(Collections.EMPTY_SET));
assertTrue(map.isEmpty());
imap.putAll(hmap);
assertTrue(map.equals(hmap));
assertTrue(map.values().removeAll(hmap.values()));
assertTrue(map.values().isEmpty());
assertTrue(!map.values().removeAll(hmap.values()));
if (isEntityBinding) {
assertTrue(imap.values().addAll(hmap.values()));
assertTrue(map.values().containsAll(hmap.values()));
assertTrue(!imap.values().addAll(hmap.values()));
} else {
imap.putAll(hmap);
}
assertTrue(map.equals(hmap));
assertTrue(!map.values().retainAll(hmap.values()));
assertTrue(map.equals(hmap));
assertTrue(map.values().retainAll(Collections.EMPTY_SET));
assertTrue(map.isEmpty());
imap.putAll(hmap);
assertTrue(map.equals(hmap));
assertTrue(map.keySet().removeAll(hmap.keySet()));
assertTrue(map.keySet().isEmpty());
assertTrue(!map.keySet().removeAll(hmap.keySet()));
assertTrue(imap.keySet().addAll(hmap.keySet()));
assertTrue(imap.keySet().containsAll(hmap.keySet()));
if (index != null) assertTrue(map.keySet().isEmpty());
assertTrue(!imap.keySet().addAll(hmap.keySet()));
// restore values to non-null
imap.clear();
imap.putAll(hmap);
assertTrue(map.equals(hmap));
assertTrue(!map.keySet().retainAll(hmap.keySet()));
assertTrue(map.equals(hmap));
assertTrue(map.keySet().retainAll(Collections.EMPTY_SET));
assertTrue(map.isEmpty());
imap.putAll(hmap);
assertTrue(map.equals(hmap));
}
});
}
void bulkListOperations()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
ArrayList alist = new ArrayList();
for (int i = beginKey; i <= endKey; i += 1) {
alist.add(makeVal(i));
}
assertTrue(list.equals(alist));
assertTrue(list.containsAll(alist));
if (isListAddAllowed()) {
list.clear();
assertTrue(list.isEmpty());
assertTrue(ilist.addAll(alist));
assertTrue(list.equals(alist));
}
assertTrue(!list.retainAll(alist));
assertTrue(list.equals(alist));
if (isListAddAllowed()) {
assertTrue(list.retainAll(Collections.EMPTY_SET));
assertTrue(list.isEmpty());
assertTrue(ilist.addAll(alist));
assertTrue(list.equals(alist));
}
if (isListAddAllowed() && !isEntityBinding) {
// deleteeting in a renumbered list with entity binding will
// change the values dynamically, making it very difficult
// to test
assertTrue(list.removeAll(alist));
assertTrue(list.isEmpty());
assertTrue(!list.removeAll(alist));
assertTrue(ilist.addAll(alist));
assertTrue(list.containsAll(alist));
assertTrue(list.equals(alist));
}
if (isListAddAllowed() && !isEntityBinding) {
// addAll at an index is also very difficult to test with
// an entity binding
// addAll at first index
ilist.addAll(beginKey, alist);
assertTrue(list.containsAll(alist));
assertEquals(2 * alist.size(), countElements(list));
for (int i = beginKey; i <= endKey; i += 1)
ilist.remove(beginKey);
assertTrue(list.equals(alist));
// addAll at last index
ilist.addAll(endKey, alist);
assertTrue(list.containsAll(alist));
assertEquals(2 * alist.size(), countElements(list));
for (int i = beginKey; i <= endKey; i += 1)
ilist.remove(endKey);
assertTrue(list.equals(alist));
// addAll in the middle
ilist.addAll(endKey - 1, alist);
assertTrue(list.containsAll(alist));
assertEquals(2 * alist.size(), countElements(list));
for (int i = beginKey; i <= endKey; i += 1)
ilist.remove(endKey - 1);
assertTrue(list.equals(alist));
}
}
});
}
void readWriteRange(final int type, final int rangeBegin,
final int rangeEnd)
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
setRange(type, rangeBegin, rangeEnd);
createOutOfRange(rangeBegin, rangeEnd);
if (rangeType != TAIL)
writeOutOfRange(new Long(rangeEnd + 1));
if (rangeType != HEAD)
writeOutOfRange(new Long(rangeBegin - 1));
if (rangeBegin <= rangeEnd) updateAll();
readAll();
clearRange();
}
});
}
void setRange(int type, int rangeBegin, int rangeEnd) {
rangeType = type;
saveMap = map;
saveSMap = smap;
saveList = list;
int listBegin = rangeBegin - beginKey;
boolean canMakeSubList = (list != null && listBegin>= 0);
if (!canMakeSubList) list = null;
if (list != null) {
try {
list.subList(-1, 0);
fail();
} catch (IndexOutOfBoundsException e) { }
}
switch (type) {
case SUB:
smap = (StoredSortedMap) smap.subMap(makeKey(rangeBegin),
makeKey(rangeEnd + 1));
if (canMakeSubList) {
list = (StoredList) list.subList(listBegin,
rangeEnd + 1 - beginKey);
}
// check for equivalent ranges
assertEquals(smap,
((StoredSortedMap) saveSMap).subMap(
makeKey(rangeBegin), true,
makeKey(rangeEnd + 1), false));
assertEquals(smap.entrySet(),
((StoredSortedEntrySet) saveSMap.entrySet()).subSet(
mapEntry(rangeBegin), true,
mapEntry(rangeEnd + 1), false));
assertEquals(smap.keySet(),
((StoredSortedKeySet) saveSMap.keySet()).subSet(
makeKey(rangeBegin), true,
makeKey(rangeEnd + 1), false));
if (smap.values() instanceof SortedSet) {
assertEquals(smap.values(),
((StoredSortedValueSet) saveSMap.values()).subSet(
makeVal(rangeBegin), true,
makeVal(rangeEnd + 1), false));
}
break;
case HEAD:
smap = (StoredSortedMap) smap.headMap(makeKey(rangeEnd + 1));
if (canMakeSubList) {
list = (StoredList) list.subList(0,
rangeEnd + 1 - beginKey);
}
// check for equivalent ranges
assertEquals(smap,
((StoredSortedMap) saveSMap).headMap(
makeKey(rangeEnd + 1), false));
assertEquals(smap.entrySet(),
((StoredSortedEntrySet) saveSMap.entrySet()).headSet(
mapEntry(rangeEnd + 1), false));
assertEquals(smap.keySet(),
((StoredSortedKeySet) saveSMap.keySet()).headSet(
makeKey(rangeEnd + 1), false));
if (smap.values() instanceof SortedSet) {
assertEquals(smap.values(),
((StoredSortedValueSet) saveSMap.values()).headSet(
makeVal(rangeEnd + 1), false));
}
break;
case TAIL:
smap = (StoredSortedMap) smap.tailMap(makeKey(rangeBegin));
if (canMakeSubList) {
list = (StoredList) list.subList(listBegin,
MAX_KEY + 1 - beginKey);
}
// check for equivalent ranges
assertEquals(smap,
((StoredSortedMap) saveSMap).tailMap(
makeKey(rangeBegin), true));
assertEquals(smap.entrySet(),
((StoredSortedEntrySet) saveSMap.entrySet()).tailSet(
mapEntry(rangeBegin), true));
assertEquals(smap.keySet(),
((StoredSortedKeySet) saveSMap.keySet()).tailSet(
makeKey(rangeBegin), true));
if (smap.values() instanceof SortedSet) {
assertEquals(smap.values(),
((StoredSortedValueSet) saveSMap.values()).tailSet(
makeVal(rangeBegin), true));
}
break;
default: throw new RuntimeException();
}
map = smap;
beginKey = rangeBegin;
if (rangeBegin < 1 || rangeEnd > MAX_KEY) {
endKey = rangeBegin - 1; // force empty range for readAll()
} else {
endKey = rangeEnd;
}
}
void clearRange() {
rangeType = NONE;
beginKey = 1;
endKey = MAX_KEY;
map = saveMap;
smap = saveSMap;
list = saveList;
}
void createOutOfRange(int rangeBegin, int rangeEnd)
throws Exception {
// map
if (rangeType != TAIL) {
try {
smap.subMap(makeKey(rangeBegin), makeKey(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
smap.headMap(makeKey(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
checkDupsSize(0, smap.duplicates(makeKey(rangeEnd + 2)));
}
if (rangeType != HEAD) {
try {
smap.subMap(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1));
fail();
} catch (IllegalArgumentException e) { }
try {
smap.tailMap(makeKey(rangeBegin - 1));
fail();
}
catch (IllegalArgumentException e) { }
checkDupsSize(0, smap.duplicates(makeKey(rangeBegin - 1)));
}
// keySet
if (rangeType != TAIL) {
SortedSet sset = (SortedSet) map.keySet();
try {
sset.subSet(makeKey(rangeBegin), makeKey(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.headSet(makeKey(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.subSet(makeKey(rangeEnd + 1),
makeKey(rangeEnd + 2)).iterator();
fail();
} catch (IllegalArgumentException e) { }
}
if (rangeType != HEAD) {
SortedSet sset = (SortedSet) map.keySet();
try {
sset.subSet(makeKey(rangeBegin - 1), makeKey(rangeEnd + 1));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.tailSet(makeKey(rangeBegin - 1));
fail();
}
catch (IllegalArgumentException e) { }
try {
sset.subSet(makeKey(rangeBegin - 1),
makeKey(rangeBegin)).iterator();
fail();
}
catch (IllegalArgumentException e) { }
}
// entrySet
if (rangeType != TAIL) {
SortedSet sset = (SortedSet) map.entrySet();
try {
sset.subSet(mapEntry(rangeBegin), mapEntry(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.headSet(mapEntry(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.subSet(mapEntry(rangeEnd + 1),
mapEntry(rangeEnd + 2)).iterator();
fail();
} catch (IllegalArgumentException e) { }
}
if (rangeType != HEAD) {
SortedSet sset = (SortedSet) map.entrySet();
try {
sset.subSet(mapEntry(rangeBegin - 1), mapEntry(rangeEnd + 1));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.tailSet(mapEntry(rangeBegin - 1));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.subSet(mapEntry(rangeBegin - 1),
mapEntry(rangeBegin)).iterator();
fail();
}
catch (IllegalArgumentException e) { }
}
// values
if (map.values() instanceof SortedSet) {
SortedSet sset = (SortedSet) map.values();
if (rangeType != TAIL) {
try {
sset.subSet(makeVal(rangeBegin),
makeVal(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.headSet(makeVal(rangeEnd + 2));
fail();
} catch (IllegalArgumentException e) { }
}
if (rangeType != HEAD) {
try {
sset.subSet(makeVal(rangeBegin - 1),
makeVal(rangeEnd + 1));
fail();
} catch (IllegalArgumentException e) { }
try {
sset.tailSet(makeVal(rangeBegin - 1));
fail();
}
catch (IllegalArgumentException e) { }
}
}
// list
if (list != null) {
int size = rangeEnd - rangeBegin + 1;
try {
list.subList(0, size + 1);
fail();
} catch (IndexOutOfBoundsException e) { }
try {
list.subList(-1, size);
fail();
} catch (IndexOutOfBoundsException e) { }
try {
list.subList(2, 1);
fail();
} catch (IndexOutOfBoundsException e) { }
try {
list.subList(size, size);
fail();
}
catch (IndexOutOfBoundsException e) { }
}
}
void writeOutOfRange(Long badNewKey)
throws Exception {
try {
map.put(badNewKey, makeVal(badNewKey));
fail();
} catch (IllegalArgumentException e) {
assertTrue(index == null);
} catch (UnsupportedOperationException e) {
assertTrue(index != null);
}
try {
map.keySet().add(badNewKey);
fail();
} catch (IllegalArgumentException e) {
assertTrue(index == null);
} catch (UnsupportedOperationException e) {
assertTrue(index != null);
}
try {
map.values().add(makeEntity(badNewKey));
fail();
} catch (IllegalArgumentException e) {
assertTrue(isEntityBinding && index == null);
} catch (UnsupportedOperationException e) {
assertTrue(!(isEntityBinding && index == null));
}
if (list != null) {
int i = badNewKey.intValue() - beginKey;
try {
list.set(i, makeVal(i));
fail();
} catch (IndexOutOfBoundsException e) {
assertTrue(index == null);
} catch (UnsupportedOperationException e) {
assertTrue(index != null);
}
try {
list.add(i, makeVal(badNewKey));
fail();
}
catch (UnsupportedOperationException e) {
}
}
}
void readWriteDuplicates()
throws Exception {
writeRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
if (index == null) {
readWritePrimaryDuplicates(beginKey);
readWritePrimaryDuplicates(beginKey + 1);
readWritePrimaryDuplicates(endKey);
readWritePrimaryDuplicates(endKey - 1);
} else {
readWriteIndexedDuplicates(beginKey);
readWriteIndexedDuplicates(beginKey + 1);
readWriteIndexedDuplicates(endKey);
readWriteIndexedDuplicates(endKey - 1);
}
}
});
}
void readWritePrimaryDuplicates(int i)
throws Exception {
Collection dups;
// make duplicate values
final Long key = makeKey(i);
final Object[] values = new Object[5];
for (int j = 0; j < values.length; j += 1) {
values[j] = isEntityBinding
? makeEntity(i, i + j)
: makeVal(i + j);
}
// add duplicates
outerLoop: for (int writeMode = 0;; writeMode += 1) {
//System.out.println("write mode " + writeMode);
switch (writeMode) {
case 0:
case 1: {
// write with Map.put()
for (int j = 1; j < values.length; j += 1) {
map.put(key, values[j]);
}
break;
}
case 2: {
// write with Map.duplicates().add()
dups = map.duplicates(key);
for (int j = 1; j < values.length; j += 1) {
dups.add(values[j]);
}
break;
}
case 3: {
// write with Map.duplicates().iterator().add()
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
Collection dups = map.duplicates(key);
Iterator iter = dups.iterator();
assertEquals(values[0], iter.next());
assertTrue(!iter.hasNext());
try {
for (int j = 1; j < values.length; j += 1) {
((ListIterator) iter).add(values[j]);
}
} finally {
StoredIterator.close(iter);
}
}
});
break;
}
case 4: {
// write with Map.values().add()
if (!isEntityBinding) continue;
Collection set = map.values();
for (int j = 1; j < values.length; j += 1) {
set.add(values[j]);
}
break;
}
default: {
break outerLoop;
}
}
// read duplicates
readDuplicates(i, key, values);
// remove duplicates
switch (writeMode) {
case 0: {
// remove with Map.remove()
map.remove(key); // remove all values
map.put(key, values[0]); // put back original value
break;
}
case 1: {
// remove with Map.keySet().remove()
map.keySet().remove(key); // remove all values
map.put(key, values[0]); // put back original value
break;
}
case 2: {
// remove with Map.duplicates().clear()
dups = map.duplicates(key);
dups.clear(); // remove all values
dups.add(values[0]); // put back original value
break;
}
case 3: {
// remove with Map.duplicates().iterator().remove()
writeIterRunner.run(new TransactionWorker() {
public void doWork() throws Exception {
Collection dups = map.duplicates(key);
Iterator iter = dups.iterator();
try {
for (int j = 0; j < values.length; j += 1) {
assertEquals(values[j], iter.next());
if (j != 0) iter.remove();
}
} finally {
StoredIterator.close(iter);
}
}
});
break;
}
case 4: {
// remove with Map.values().remove()
if (!isEntityBinding) throw new IllegalStateException();
Collection set = map.values();
for (int j = 1; j < values.length; j += 1) {
set.remove(values[j]);
}
break;
}
default: throw new IllegalStateException();
}
// verify that only original value is present
dups = map.duplicates(key);
assertTrue(dups.contains(values[0]));
for (int j = 1; j < values.length; j += 1) {
assertTrue(!dups.contains(values[j]));
}
}
}
void readWriteIndexedDuplicates(int i)
throws Exception {
Object key = makeKey(i);
Object[] values = new Object[3];
values[0] = makeVal(i);
for (int j = 1; j < values.length; j += 1) {
values[j] = isEntityBinding
? makeEntity(endKey + j, i)
: makeVal(i);
}
// add duplicates
for (int j = 1; j < values.length; j += 1) {
imap.put(makeKey(endKey + j), values[j]);
}
// read duplicates
readDuplicates(i, key, values);
// remove duplicates
for (int j = 1; j < values.length; j += 1) {
imap.remove(makeKey(endKey + j));
}
checkDupsSize(1, map.duplicates(key));
}
void readDuplicates(int i, Object key, Object[] values) {
boolean isOrdered = map.isOrdered();
Collection dups;
Iterator iter;
// read with Map.duplicates().iterator()
dups = map.duplicates(key);
iter = dups.iterator();
try {
for (int j = 0; j < values.length; j += 1) {
assertTrue(iter.hasNext());
Object val = iter.next();
assertEquals(values[j], val);
}
assertTrue(!iter.hasNext());
} finally {
StoredIterator.close(iter);
}
// read with Map.values().iterator()
Collection clone = ((StoredCollection) map.values()).toList();
iter = map.values().iterator();
try {
for (int j = beginKey; j < i; j += 1) {
Object val = iter.next();
assertTrue(clone.remove(makeVal(j)));
if (isOrdered) assertEquals(makeVal(j), val);
}
for (int j = 0; j < values.length; j += 1) {
Object val = iter.next();
assertTrue(clone.remove(values[j]));
if (isOrdered) assertEquals(values[j], val);
}
for (int j = i + 1; j <= endKey; j += 1) {
Object val = iter.next();
assertTrue(clone.remove(makeVal(j)));
if (isOrdered) assertEquals(makeVal(j), val);
}
assertTrue(!iter.hasNext());
assertTrue(clone.isEmpty());
} finally {
StoredIterator.close(iter);
}
// read with Map.entrySet().iterator()
clone = ((StoredCollection) map.entrySet()).toList();
iter = map.entrySet().iterator();
try {
for (int j = beginKey; j < i; j += 1) {
Map.Entry entry = (Map.Entry) iter.next();
assertTrue(clone.remove(mapEntry(j)));
if (isOrdered) {
assertEquals(makeVal(j), entry.getValue());
assertEquals(makeKey(j), entry.getKey());
}
}
for (int j = 0; j < values.length; j += 1) {
Map.Entry entry = (Map.Entry) iter.next();
assertTrue(clone.remove(mapEntry(makeKey(i), values[j])));
if (isOrdered) {
assertEquals(values[j], entry.getValue());
assertEquals(makeKey(i), entry.getKey());
}
}
for (int j = i + 1; j <= endKey; j += 1) {
Map.Entry entry = (Map.Entry) iter.next();
assertTrue(clone.remove(mapEntry(j)));
if (isOrdered) {
assertEquals(makeVal(j), entry.getValue());
assertEquals(makeKey(j), entry.getKey());
}
}
assertTrue(!iter.hasNext());
assertTrue(clone.isEmpty());
} finally {
StoredIterator.close(iter);
}
// read with Map.keySet().iterator()
clone = ((StoredCollection) map.keySet()).toList();
iter = map.keySet().iterator();
try {
for (int j = beginKey; j < i; j += 1) {
Object val = iter.next();
assertTrue(clone.remove(makeKey(j)));
if (isOrdered) assertEquals(makeKey(j), val);
}
if (true) {
// only one key is iterated for all duplicates
Object val = iter.next();
assertTrue(clone.remove(makeKey(i)));
if (isOrdered) assertEquals(makeKey(i), val);
}
for (int j = i + 1; j <= endKey; j += 1) {
Object val = iter.next();
assertTrue(clone.remove(makeKey(j)));
if (isOrdered) assertEquals(makeKey(j), val);
}
assertTrue(!iter.hasNext());
assertTrue(clone.isEmpty());
} finally {
StoredIterator.close(iter);
}
}
void duplicatesNotAllowed() {
Collection dups = map.duplicates(makeKey(beginKey));
try {
dups.add(makeVal(beginKey));
fail();
} catch (UnsupportedOperationException expected) { }
ListIterator iter = (ListIterator) dups.iterator();
try {
iter.add(makeVal(beginKey));
fail();
} catch (UnsupportedOperationException expected) {
} finally {
StoredIterator.close(iter);
}
}
void listOperationsNotAllowed() {
ListIterator iter = (ListIterator) map.values().iterator();
try {
try {
iter.nextIndex();
fail();
} catch (UnsupportedOperationException expected) { }
try {
iter.previousIndex();
fail();
} catch (UnsupportedOperationException expected) { }
} finally {
StoredIterator.close(iter);
}
}
void testCdbLocking() {
Iterator readIterator;
Iterator writeIterator;
StoredKeySet set = (StoredKeySet) map.keySet();
// can open two CDB read cursors
readIterator = set.iterator(false);
try {
Iterator readIterator2 = set.iterator(false);
StoredIterator.close(readIterator2);
} finally {
StoredIterator.close(readIterator);
}
// can open two CDB write cursors
writeIterator = set.iterator(true);
try {
Iterator writeIterator2 = set.iterator(true);
StoredIterator.close(writeIterator2);
} finally {
StoredIterator.close(writeIterator);
}
// cannot open CDB write cursor when read cursor is open,
readIterator = set.iterator(false);
try {
writeIterator = set.iterator(true);
fail();
StoredIterator.close(writeIterator);
} catch (IllegalStateException e) {
} finally {
StoredIterator.close(readIterator);
}
if (index == null) {
// cannot put() with read cursor open
readIterator = set.iterator(false);
try {
map.put(makeKey(1), makeVal(1));
fail();
} catch (IllegalStateException e) {
} finally {
StoredIterator.close(readIterator);
}
// cannot put() with write cursor open with RECNO/QUEUE only
writeIterator = set.iterator(true);
try {
if (testStore.isQueueOrRecno()) {
try {
map.put(makeKey(1), makeVal(1));
fail();
} catch (IllegalStateException e) {}
} else {
map.put(makeKey(1), makeVal(1));
}
} finally {
StoredIterator.close(writeIterator);
}
}
}
Object makeVal(int key) {
if (isEntityBinding)
return makeEntity(key);
else
return new Long(key + 100);
}
Object makeVal(int key, int val) {
if (isEntityBinding)
return makeEntity(key, val);
else
return makeVal(val);
}
Object makeEntity(int key, int val) {
return new TestEntity(key, val + 100);
}
int intVal(Object val) {
if (isEntityBinding)
return ((TestEntity) val).value - 100;
else
return ((Long) val).intValue() - 100;
}
int intKey(Object key) {
return ((Long) key).intValue();
}
Object makeVal(Long key) {
return makeVal(key.intValue());
}
Object makeEntity(int key) {
return makeEntity(key, key);
}
Object makeEntity(Long key) {
return makeEntity(key.intValue());
}
int intIter(Collection coll, Object value) {
if (coll instanceof StoredKeySet) {
return intKey(value);
} else {
if (coll instanceof StoredEntrySet) {
value = ((Map.Entry) value).getValue();
}
return intVal(value);
}
}
Map.Entry mapEntry(Object key, Object val) {
return new MapEntry(key, val);
}
Map.Entry mapEntry(int key) {
return new MapEntry(makeKey(key), makeVal(key));
}
Long makeKey(int key) {
return new Long(key);
}
boolean isSubMap() {
return rangeType != NONE;
}
void checkDupsSize(int expected, Collection coll) {
assertEquals(expected, coll.size());
if (coll instanceof StoredCollection) {
StoredIterator i = ((StoredCollection) coll).iterator(false);
try {
int actual = 0;
if (i.hasNext()) {
i.next();
actual = i.count();
}
assertEquals(expected, actual);
} finally {
StoredIterator.close(i);
}
}
}
private boolean isListAddAllowed() {
return list != null && testStore.isQueueOrRecno() &&
list.areKeysRenumbered();
}
private int countElements(Collection coll) {
int count = 0;
Iterator iter = coll.iterator();
try {
while (iter.hasNext()) {
iter.next();
count += 1;
}
} finally {
StoredIterator.close(iter);
}
return count;
}
}