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);