Author: schor
Date: Fri May  3 14:31:30 2013
New Revision: 1478810

URL: http://svn.apache.org/r1478810
Log:
[UIMA-2434] test case: reuse existing iterators - is now supported.  Verify 
concurrent mod exception when removing all.  Fix impl to support resizing down 
for all 3 types of indexes, if they've grown. Fix impl to set concurrent 
modification flag.  Update javadocs for moveToNext / Previous to indicate they 
may throw ConcurrentModificationException, and to say that moveToFirst/Last is 
OK after modification.

Modified:
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/FSIterator.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSBagIndex.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIntArrayIndex.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSRBTSetIndex.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSVectorIndex.java
    
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/rb_trees/IntArrayRBT.java
    
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/FSIterator.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/FSIterator.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/FSIterator.java 
(original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/FSIterator.java 
Fri May  3 14:31:30 2013
@@ -19,6 +19,7 @@
 
 package org.apache.uima.cas;
 
+import java.util.ConcurrentModificationException;
 import java.util.Iterator;
 import java.util.NoSuchElementException;
 
@@ -84,23 +85,25 @@ public interface FSIterator<T extends Fe
 
   /**
    * Advance the iterator. This may invalidate the iterator.
+   * @exception ConcurrentModificationException if the underlying indexes 
being iterated over were modified
    */
   void moveToNext();
 
   /**
    * Move the iterator one element back. This may invalidate the iterator.
+   * @exception ConcurrentModificationException if the underlying indexes 
being iterated over were modified
    */
   void moveToPrevious();
 
   /**
    * Move the iterator to the first element. The iterator will be valid iff 
the underlying
-   * collection is non-empty.
+   * collection is non-empty.  Allowed even if the underlying indexes being 
iterated over were modified.
    */
   void moveToFirst();
 
   /**
    * Move the iterator to the last element. The iterator will be valid iff the 
underlying collection
-   * is non-empty.
+   * is non-empty.  Allowed even if the underlying indexes being iterated over 
were modified.
    */
   void moveToLast();
 
@@ -112,6 +115,7 @@ public interface FSIterator<T extends Fe
    * 
    * @param fs
    *          The feature structure the iterator should be set to.
+   * @exception ConcurrentModificationException if the underlying indexes 
being iterated over were modified
    */
   void moveTo(FeatureStructure fs);
 

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSBagIndex.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSBagIndex.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSBagIndex.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSBagIndex.java
 Fri May  3 14:31:30 2013
@@ -186,9 +186,12 @@ public class FSBagIndex extends FSLeafIn
   }
 
   public void flush() {
-    this.index.removeAllElements();
-    // don't do this - some iterators/ indexes are holding references to the 
index, and don't pick up the new one.
-//    this.index = new IntVector(this.initialSize);
+    // done this way to reset to initial size if it grows
+    if (this.index.size() > this.initialSize) {
+      this.index = new IntVector(this.initialSize);
+    } else {
+      this.index.removeAllElements();
+    }
   }
 
   public final boolean insert(int fs) {

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
 Fri May  3 14:31:30 2013
@@ -181,7 +181,9 @@ public class FSIndexRepositoryImpl imple
     // The IICP
     private IndexIteratorCachePair iicp;
 
-    // An array of integer arrays, one for each subtype.
+    // An array of ComparableIntPointerIterators, one for each subtype.
+    //   Each instance of these has a Class.this kind of ref to a particular 
variety of FSLeafIndex (bag, set, sorted) corresponding to 1 type
+    //   This array has the indexes for all the subtypes
     private ComparableIntPointerIterator[] indexes;
 
     int lastValidIndex;
@@ -1409,12 +1411,12 @@ public class FSIndexRepositoryImpl imple
    */
   public void removeAllExcludingSubtypes(Type type) {
     final int typeCode = ((TypeImpl) type).getCode();
+    incrementIllegalIndexUpdateDetector(typeCode);
     // get a list of all indexes defined over this type
     // Includes indexes defined on supertypes of this type
     final ArrayList<IndexIteratorCachePair> allIndexesForType = 
this.indexArray[typeCode];
     for (IndexIteratorCachePair iicp : allIndexesForType) {
       iicp.index.flush();
-//      boolean fff = iicp.iteratorCache.get(0) == iicp.index;
     }
   }
   

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIntArrayIndex.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIntArrayIndex.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIntArrayIndex.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIntArrayIndex.java
 Fri May  3 14:31:30 2013
@@ -155,9 +155,12 @@ public class FSIntArrayIndex<T extends F
 
   // The index, a vector of FS references.
   private IntVector index;
+  
+  final private int initialSize;
 
   FSIntArrayIndex(CASImpl cas, Type type, int initialSize, int indexType) {
     super(cas, type, indexType);
+    this.initialSize = initialSize;
     this.index = new IntVector(initialSize);
   }
 
@@ -174,7 +177,12 @@ public class FSIntArrayIndex<T extends F
   }
 
   public void flush() {
-    this.index.removeAllElements();
+    // do this way to reset size if it grew
+    if (this.index.size() > this.initialSize) {
+      this.index = new IntVector(initialSize);
+    } else {
+      this.index.removeAllElements();
+    }
   }
 
   // public final boolean insert(int fs) {

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSRBTSetIndex.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSRBTSetIndex.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSRBTSetIndex.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSRBTSetIndex.java
 Fri May  3 14:31:30 2013
@@ -56,7 +56,7 @@ class FSRBTSetIndex<T extends FeatureStr
 
   public void flush() {
     this.tree.flush();
-//    this.tree = new CompIntArrayRBT(this);  // not this way - some 
indexes/iterators are holding on to references to the old tree...
+//    this.tree = new CompIntArrayRBT(this);  // not this way - iterators are 
holding on to references to the old tree...
   }
 
   /**

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSVectorIndex.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSVectorIndex.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSVectorIndex.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSVectorIndex.java
 Fri May  3 14:31:30 2013
@@ -153,9 +153,11 @@ public class FSVectorIndex<T extends Fea
   }
 
   public void flush() {
-    this.index.removeAllElements();
-    // not this way in case someone's holding on to a ref to the actual index 
object
-//    this.index = new IntVector(this.initialSize);
+    if (this.index.size() > this.initialSize) {
+      this.index = new IntVector(this.initialSize); 
+    } else {
+      this.index.removeAllElements();
+    }
   }
 
   public final boolean insert(int fs) {

Modified: 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/rb_trees/IntArrayRBT.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/rb_trees/IntArrayRBT.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/rb_trees/IntArrayRBT.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/main/java/org/apache/uima/internal/util/rb_trees/IntArrayRBT.java
 Fri May  3 14:31:30 2013
@@ -397,6 +397,8 @@ public class IntArrayRBT {
   private static final int default_growth_factor = 2;
 
   private static final int default_multiplication_limit = 2000000;
+  
+  final private int initialSize;
 
   private int growth_factor;
 
@@ -429,8 +431,10 @@ public class IntArrayRBT {
     initVars();
     // Increase initialSize by one since we use one slot for sentinel.
     ++initialSize;
+    this.initialSize = initialSize;
     this.growth_factor = default_growth_factor;
     this.multiplication_limit = default_multiplication_limit;
+    setupArrays();
     // Init the arrays.
     if (useklrp) {
       klrp = new int[initialSize << 2];
@@ -446,6 +450,23 @@ public class IntArrayRBT {
     setParent(NIL, NIL);
     this.color[NIL] = black;
   }
+  
+  private void setupArrays() {
+    // Init the arrays.
+    if (useklrp) {
+      klrp = new int[initialSize << 2];
+    } else {
+      this.key = new int[initialSize];
+      this.left = new int[initialSize];
+      this.right = new int[initialSize];
+      this.parent = new int[initialSize];
+    }
+    this.color = new boolean[initialSize];
+    setLeft(NIL, NIL);
+    setRight(NIL, NIL);
+    setParent(NIL, NIL);
+    this.color[NIL] = black;    
+  }
 
   private void initVars() {
     this.root = NIL;
@@ -457,6 +478,16 @@ public class IntArrayRBT {
   public void flush() {
     // All we do for flush is set the root to NIL and the size to 0.
     initVars();
+    // and potentially release extra storage
+    if (useklrp) {
+      if (klrp.length > (initialSize << 2)) {
+        setupArrays();
+      }
+    } else {
+      if (key.length > initialSize) {
+        setupArrays();
+      }
+    }
   }
 
   public final int size() {

Modified: 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java
URL: 
http://svn.apache.org/viewvc/uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java?rev=1478810&r1=1478809&r2=1478810&view=diff
==============================================================================
--- 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java
 (original)
+++ 
uima/uimaj/trunk/uimaj-core/src/test/java/org/apache/uima/cas/test/IteratorTest.java
 Fri May  3 14:31:30 2013
@@ -781,18 +781,29 @@ public class IteratorTest extends TestCa
     FSIndex<FeatureStructure> subbagIndex = 
ir.getIndex(CASTestSetup.ANNOT_BAG_INDEX, this.subsentenceType);
     FSIndex<AnnotationFS>     subsortedIndex = 
this.cas.getAnnotationIndex(this.subsentenceType);
 
-    ir.removeAllIncludingSubtypes(sentenceType);
-
     FSIterator<FeatureStructure> setIt = setIndex.iterator();
     FSIterator<FeatureStructure> bagIt = bagIndex.iterator();
     FSIterator<AnnotationFS> sortedIt = sortedIndex.iterator();
-    
-    // subindexes
 
     FSIterator<FeatureStructure> subsetIt = subsetIndex.iterator();
     FSIterator<FeatureStructure> subbagIt = subbagIndex.iterator();
     FSIterator<AnnotationFS> subsortedIt = subsortedIndex.iterator();
 
+    verifyMoveToFirst(setIt, true);
+    verifyMoveToFirst(bagIt, true);
+    verifyMoveToFirst(sortedIt, true);
+    verifyMoveToFirst(subsetIt, true);
+    verifyMoveToFirst(subbagIt, true);
+    verifyMoveToFirst(subsortedIt, true);
+    
+    ir.removeAllIncludingSubtypes(sentenceType);
+    verifyConcMod(setIt);
+    verifyConcMod(bagIt);
+    verifyConcMod(sortedIt);
+    verifyConcMod(subsetIt);
+    verifyConcMod(subbagIt);
+    verifyConcMod(subsortedIt);
+
     verifyMoveToFirst(setIt, false);
     verifyMoveToFirst(bagIt, false);
     verifyMoveToFirst(sortedIt, false);
@@ -800,8 +811,6 @@ public class IteratorTest extends TestCa
     verifyMoveToFirst(subbagIt, false);
     verifyMoveToFirst(subsortedIt, false);
 
-//    addAnnotations(fsArray, ts.getType("Sentence"));
-//    addAnnotations(subFsArray, ts.getType("SubTypeOfSentence"));
     for (AnnotationFS fs : fsArray) {
       ir.addFS(fs);
     }
@@ -818,14 +827,6 @@ public class IteratorTest extends TestCa
 
     ir.removeAllExcludingSubtypes(this.sentenceType);
     
-    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);
@@ -839,14 +840,6 @@ public class IteratorTest extends TestCa
     
     ir.removeAllExcludingSubtypes(subsentenceType);
 
-    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);
@@ -855,6 +848,17 @@ public class IteratorTest extends TestCa
     verifyMoveToFirst(subsortedIt, false);
   }
   
+
+  private void verifyConcMod(FSIterator<?> it) {
+    boolean caught = false;
+    try {
+      it.moveToNext();
+    } catch (Exception e) {
+      caught = true;
+    }
+    assertTrue(caught);
+  }
+  
   
   public void testInvalidIndexRequest() {
     boolean exc = false;


Reply via email to