You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2017/07/20 14:53:41 UTC
svn commit: r1802503 - in
/uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test:
CASTestSetup.java IndexRepositoryTest.java IteratorTest.java
Author: schor
Date: Thu Jul 20 14:53:41 2017
New Revision: 1802503
URL: http://svn.apache.org/viewvc?rev=1802503&view=rev
Log:
[UIMA-5497] tests for copy on write for iterators
Modified:
uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java
uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java
uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java
Modified: uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java
URL: http://svn.apache.org/viewvc/uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java?rev=1802503&r1=1802502&r2=1802503&view=diff
==============================================================================
--- uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java (original)
+++ uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/CASTestSetup.java Thu Jul 20 14:53:41 2017
@@ -108,6 +108,8 @@ public class CASTestSetup implements An
// Index name constants.
public static final String ANNOT_SET_INDEX = "Annotation Set Index";
+ public static final String ANNOT_SET_INDEX_NO_TYPEORDER = "Annotation Set Index No Type Order";
+
public static final String ANNOT_BAG_INDEX = "Annotation Bag Index";
public static final String ANNOT_SORT_INDEX = "Annotation Sort Index";
@@ -197,7 +199,7 @@ public class CASTestSetup implements An
Type arrayOfIntArray = tsm.getArrayType(intArrayType);
}
- public void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts) {
+ private FSIndexComparator makeComp(FSIndexRepositoryMgr irm, TypeSystem ts) {
FSIndexComparator comp = irm.createComparator();
Type annotation = ts.getType(CAS.TYPE_NAME_ANNOTATION);
comp.setType(annotation);
@@ -205,6 +207,12 @@ public class CASTestSetup implements An
FSIndexComparator.STANDARD_COMPARE);
comp.addKey(annotation.getFeatureByBaseName(CAS.FEATURE_BASE_NAME_END),
FSIndexComparator.REVERSE_STANDARD_COMPARE);
+ return comp;
+ }
+
+ public void initIndexes(FSIndexRepositoryMgr irm, TypeSystem ts) {
+ FSIndexComparator compNoTypeOrder = makeComp(irm, ts);
+ FSIndexComparator comp = makeComp(irm, ts);
LinearTypeOrderBuilder tob = irm.createTypeSortOrder();
try {
tob.add(new String[] { CAS.TYPE_NAME_ANNOTATION, SENT_TYPE, TOKEN_TYPE });
@@ -215,6 +223,6 @@ public class CASTestSetup implements An
irm.createIndex(comp, ANNOT_BAG_INDEX, FSIndex.BAG_INDEX);
irm.createIndex(comp, ANNOT_SET_INDEX, FSIndex.SET_INDEX);
irm.createIndex(comp, ANNOT_SORT_INDEX, FSIndex.SORTED_INDEX);
-
+ irm.createIndex(compNoTypeOrder, ANNOT_SET_INDEX_NO_TYPEORDER, FSIndex.SET_INDEX);
}
}
Modified: uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java
URL: http://svn.apache.org/viewvc/uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java?rev=1802503&r1=1802502&r2=1802503&view=diff
==============================================================================
--- uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java (original)
+++ uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IndexRepositoryTest.java Thu Jul 20 14:53:41 2017
@@ -132,6 +132,26 @@ public class IndexRepositoryTest extends
index = ir.getIndex(CASTestSetup.ANNOT_SORT_INDEX);
assertEquals(2, index.size());
+ // Annotation is supertype of token
+ // test if set observes implicit key of type
+ Type annotType = this.typeSystem.getType(CAS.TYPE_NAME_ANNOTATION);
+ Feature annotBeginFeat = this.typeSystem.getFeatureByFullName(CAS.TYPE_NAME_ANNOTATION + ":begin");
+ cas.getIndexRepository().removeAllIncludingSubtypes(annotType);
+
+ FeatureStructure annotTypeFs3 = this.cas.createFS(annotType);
+ annotTypeFs3.setIntValue(annotBeginFeat, 17);
+
+ cas.addFsToIndexes(tokenTypeFs1);
+ cas.addFsToIndexes(annotTypeFs3);
+
+ index = ir.getIndex(CASTestSetup.ANNOT_SET_INDEX);
+ assertEquals(2, index.size());
+
+ // shows type is implicit key for set compares
+ index = ir.getIndex(CASTestSetup.ANNOT_SET_INDEX_NO_TYPEORDER);
+ assertEquals(2, index.size());
+
+
}
/**
@@ -251,7 +271,7 @@ public class IndexRepositoryTest extends
// fsa[i].setIntValue(beginFeat, i);
}
- for (int iii = 0; iii < 3 /*10000*/; iii++) { // change to 10000 for iterations
+ for (int iii = 0; iii < 6 /*10000*/; iii++) { // change to 10000 for iterations
cas.getIndexRepository().removeAllIncludingSubtypes(cas.getTypeSystem().getTopType());
Modified: uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java
URL: http://svn.apache.org/viewvc/uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java?rev=1802503&r1=1802502&r2=1802503&view=diff
==============================================================================
--- uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java (original)
+++ uima/uv3/uimaj-v3/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java Thu Jul 20 14:53:41 2017
@@ -50,6 +50,7 @@ import org.apache.uima.cas.text.Annotati
import org.apache.uima.internal.util.IntVector;
import org.apache.uima.internal.util.MultiThreadUtils;
import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.TOP;
import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.resource.ResourceInitializationException;
import org.apache.uima.resource.ResourceSpecifier;
@@ -97,26 +98,33 @@ public class IteratorTest extends TestCa
private Type subsentenceType;
private FSIndex<FeatureStructure> bagIndex;
+ /** ss means snapshot */
private FSIndex<FeatureStructure> ssBagIndex;
private FSIndex<FeatureStructure> setIndex;
+ /** ss means snapshot */
private FSIndex<FeatureStructure> ssSetIndex;
private FSIndex<FeatureStructure> sortedIndex;
+ /** ss means snapshot */
private FSIndex<FeatureStructure> ssSortedIndex;
private FSIndex<?> jcasBagIndex;
+ /** ss means snapshot */
private FSIndex<?> jcasSsBagIndex;
private FSIndex<?> jcasSetIndex;
+ /** ss means snapshot */
private FSIndex<?> jcasSsSetIndex;
private FSIndex<?> jcasSortedIndex;
+ /** ss means snapshot */
private FSIndex<?> jcasSsSortedIndex;
private JCas jcas;
private FSIndex<FeatureStructure> wordSetIndex;
+ /** ss means snapshot */
private FSIndex<FeatureStructure> ssWordSetIndex;
private Feature wordFeat;
@@ -363,17 +371,27 @@ public class IteratorTest extends TestCa
this.cas.getIndexRepository().addFS(
this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1));
this.cas.getIndexRepository().addFS(
- this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1));
+ this.cas.createAnnotation(this.sentenceType, i * 2, (i * 2) + 1));
this.cas.getIndexRepository().addFS(
- fsi = (FeatureStructureImplC) this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
+ fsi =
+ this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
this.cas.getIndexRepository().addFS(
- this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
+ this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
this.cas.getIndexRepository().addFS(
- this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
+ this.cas.createAnnotation(this.tokenType, i * 2, (i * 2) + 1));
// //debug
// System.out.format("Token at %,d %n", fsi.getAddress());
}
+ private void createFSsU() {
+ this.cas.getIndexRepository().removeAllIncludingSubtypes(TOP.class);
+
+ for (int i = 0; i < 5; i++) {
+ this.cas.getIndexRepository().addFS(
+ this.cas.createAnnotation(this.annotationType, i * 2, (i * 2) + 1));
+ }
+ }
+
// private void debugls() {
// LowLevelIndexRepository llir = this.cas.ll_getIndexRepository();
// LowLevelIndex setIndexForType = llir.ll_getIndex(CASTestSetup.ANNOT_SET_INDEX, ((TypeImpl)tokenType).getCode());
@@ -383,11 +401,13 @@ public class IteratorTest extends TestCa
// }
private void setupFSs() {
+ this.cas.getIndexRepository().removeAllIncludingSubtypes(TOP.class);
+
for (int i = 0; i < 10; i++) {
- createFSs(i);
+ createFSs(i); // i = 0 .. 9, 5 annot per: annotation, sentence, token, token, token
}
for (int i = 19; i >= 10; i--) {
- createFSs(i);
+ createFSs(i); // i = 19 .. 10 5 annot per: annotation, sentence, token, token, token
}
}
@@ -485,20 +505,38 @@ public class IteratorTest extends TestCa
// /////////////////////////////////////////////////////////////////////////
- // Test fast fail.
+ // Test fast fail. - uima v3 doesn't throw ConcurrentModificationException
+
+// fastFailTst(setIndex, true);
+// fastFailTst(ssSetIndex, false);
+//
+// fastFailTst(bagIndex, true);
+// fastFailTst(ssBagIndex, false);
+//
+// fastFailTst(sortedIndex, true);
+// fastFailTst(ssSortedIndex, false);
+
+ /**
+ * Test copy-on-write -
+ * insure that index mods are ignored in normal iteration
+ * insure that index mods are picked up for moveTo, moveToFirst, moveToLast
+ */
- fastFailTst(setIndex, true);
- fastFailTst(ssSetIndex, false);
- fastFailTst(bagIndex, true);
- fastFailTst(ssBagIndex, false);
+ createFSsU();
+
+ cowTst(setIndex, true);
+ cowTst(ssSetIndex, false);
+
+ cowTst(bagIndex, true);
+ cowTst(ssBagIndex, false);
- fastFailTst(sortedIndex, true);
- fastFailTst(ssSortedIndex, false);
+ cowTst(sortedIndex, true);
+ cowTst(ssSortedIndex, false);
// debugls(); //debug
-
+ setupFSs();
// Test find()
setupWords();
@@ -699,6 +737,62 @@ public class IteratorTest extends TestCa
assertEquals(end, a.getEnd());
}
+
+ /**
+ *
+ * @param index - the index to manipulate
+ * @param isCow - false for "snapshot" indexes - these don't do cow (copy on write) things
+ */
+ private void cowTst(FSIndex<FeatureStructure> index, boolean isCow) {
+ FSIterator<FeatureStructure> it = index.iterator();
+ it.moveToLast();
+ it.moveToFirst();
+ // moved to first, 2.7.0, because new bag iterator is more forgiving re concurrentmodexception
+ FeatureStructure a = it.get();
+
+ cas.removeFsFromIndexes(a);
+ it.next();
+ it.previous();
+ assertTrue(it.get() == a); // gets the removed one
+ it.moveToFirst(); // resets cow, does nothing for snapshot
+ assertTrue(isCow ? (it.get() != a)
+ : (it.get() == a));
+
+ cas.addFsToIndexes(a);
+ it.moveToLast();
+ a = it.get();
+
+ cas.removeFsFromIndexes(a);
+ it.previous();
+ it.next();
+ assertTrue(0 == index.compare(it.get(), a));
+ it.moveToLast();
+ assertTrue(isCow ? (it.get() != a)
+ : (it.get() == a));
+
+ cas.addFsToIndexes(a); // index mod causes cow to copy, and index wr_cow to be set to null
+ it.moveToFirst(); // moveToFirst -> maybeReinitIterator (if cow is copy), new cow, index wr_cow refs it
+
+ it.moveToNext();
+
+ a = it.get();
+
+ cas.removeFsFromIndexes(a); // resets wr_cow to null for assoc. index, because it now ref-ng copy
+ it.previous();
+ it.isValid();
+ it.next();
+ assertTrue(it.get() == a); // gets the removed one
+ it.moveTo(a); // causes COW reset
+ if (isCow && index == setIndex || index == bagIndex) {
+ assertFalse(it.isValid()); // moveTo on set with no match gives invalid iterator
+ } else {
+ assertTrue(isCow
+ ? (it.get() != a)
+ : (it.get() == a));
+ }
+ cas.addFsToIndexes(a); // add it back for subsequent tests
+ }
+
private void fastFailTst(FSIndex<FeatureStructure> index, boolean isShouldFail) {
FSIterator<FeatureStructure> it = index.iterator();
it.moveToLast();
@@ -722,7 +816,7 @@ public class IteratorTest extends TestCa
} catch (ConcurrentModificationException e) {
ok = true;
}
- assertTrue(isShouldFail ? ok : !ok);
+ assertTrue(isShouldFail ? ok : !ok);
it.moveTo(a); // should reset concurrent mod,
ok = true;
@@ -1053,6 +1147,9 @@ public class IteratorTest extends TestCa
for (int i = 0; i < fsArray.length; i++) {
ir.removeFS(fsArray[i]);
ir.removeFS(fsArray[i]); // a 2nd remove should be a no-op https://issues.apache.org/jira/browse/UIMA-2934
+
+ // due to copy on write, need a new instance of set_iterator
+ set_iterator = setIndex.iterator();
set_iterator.moveTo(fsArray[i]);
if (set_iterator.isValid()) {
int oldRef = this.cas.ll_getFSRef(fsArray[i]);
@@ -1060,8 +1157,16 @@ public class IteratorTest extends TestCa
assertTrue(oldRef != newRef);
assertTrue(!set_iterator.get().equals(fsArray[i]));
}
+
+ // due to copy on write, need a new instance of set_iterator
+ bagIt = bagIndex.iterator();
+// assertFalse(bagIt.hasNext()); // invalid test: removing one item from a bag index doesn't remove the "last" element.
+ assertEquals(99, bagIndex.size());
bagIt.moveTo(fsArray[i]);
- assertFalse(bagIt.hasNext());
+ assertFalse(bagIt.isValid());
+
+ // due to copy on write, need a new instance of set_iterator
+ sortedIt = sortedIndex.iterator();
sortedIt.moveTo(fsArray[i]);
if (sortedIt.isValid()) {
assertTrue(!sortedIt.get().equals(fsArray[i]));
@@ -1073,10 +1178,19 @@ public class IteratorTest extends TestCa
ir.removeFS(fsArray[i]);
}
// All iterators should be invalidated when being reset.
+
+ // due to copy on write, need a new instance of set_iterator
+ bagIt = bagIndex.iterator();
bagIt.moveToFirst();
assertFalse(bagIt.isValid());
+
+ // due to copy on write, need a new instance of set_iterator
+ set_iterator = setIndex.iterator();
set_iterator.moveToFirst();
assertFalse(set_iterator.isValid());
+
+ // due to copy on write, need a new instance of set_iterator
+ sortedIt = sortedIndex.iterator();
sortedIt.moveToFirst();
assertFalse(sortedIt.isValid());
}
@@ -1152,6 +1266,15 @@ public class IteratorTest extends TestCa
verifyConcurrantModificationDetected(subbagIt);
verifyConcurrantModificationDetected(subsortedIt);
+ // due to copy on write, need to get new iterators
+ setIt = setIndex.iterator();
+ bagIt = bagIndex.iterator();
+ sortedIt = sortedIndex.iterator();
+
+ subsetIt = subsetIndex.iterator();
+ subbagIt = subbagIndex.iterator();
+ subsortedIt = subsortedIndex.iterator();
+
verifyMoveToFirst(setIt, false);
verifyMoveToFirst(bagIt, false);
verifyMoveToFirst(sortedIt, false);
@@ -1166,6 +1289,15 @@ public class IteratorTest extends TestCa
ir.addFS(fs);
}
+ // due to copy on write, need to get new iterators
+ setIt = setIndex.iterator();
+ bagIt = bagIndex.iterator();
+ sortedIt = sortedIndex.iterator();
+
+ subsetIt = subsetIndex.iterator();
+ subbagIt = subbagIndex.iterator();
+ subsortedIt = subsortedIndex.iterator();
+
verifyMoveToFirst(setIt, true);
verifyMoveToFirst(bagIt, true);
verifyMoveToFirst(sortedIt, true);
@@ -1175,6 +1307,15 @@ public class IteratorTest extends TestCa
ir.removeAllExcludingSubtypes(this.sentenceType);
+ // due to copy on write, need to get new iterators
+ setIt = setIndex.iterator();
+ bagIt = bagIndex.iterator();
+ sortedIt = sortedIndex.iterator();
+
+ subsetIt = subsetIndex.iterator();
+ subbagIt = subbagIndex.iterator();
+ subsortedIt = subsortedIndex.iterator();
+
verifyHaveSubset(setIt, 91, subsentenceType);
verifyHaveSubset(bagIt, 100, subsentenceType);
verifyHaveSubset(sortedIt, 100, subsentenceType);
@@ -1188,6 +1329,15 @@ public class IteratorTest extends TestCa
ir.removeAllExcludingSubtypes(subsentenceType);
+ // due to copy on write, need to get new iterators
+ setIt = setIndex.iterator();
+ bagIt = bagIndex.iterator();
+ sortedIt = sortedIndex.iterator();
+
+ subsetIt = subsetIndex.iterator();
+ subbagIt = subbagIndex.iterator();
+ subsortedIt = subsortedIndex.iterator();
+
verifyHaveSubset(setIt, 91, sentenceType);
verifyHaveSubset(bagIt, 100, sentenceType);
verifyHaveSubset(sortedIt, 100, sentenceType);