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 2015/11/01 14:12:23 UTC

svn commit: r1711751 - /uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/

Author: schor
Date: Sun Nov  1 13:12:22 2015
New Revision: 1711751

URL: http://svn.apache.org/viewvc?rev=1711751&view=rev
Log:
[UIMA-4665][UIMA-4664]Internal iterator support classes. Diagrams here: https://cwiki.apache.org/confluence/display/UIMA/v3+Indexes+and+Iterators. 

Added:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_aggregation_common.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_singletype.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_list.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_ordered.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_snapshot.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_unordered.java

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_aggregation_common.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_aggregation_common.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_aggregation_common.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_aggregation_common.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,191 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.Arrays;
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIndex;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+/**
+ * Aggregate several FS iterators.  Simply iterates over one after the other
+ * without any no sorting or merging.
+ * Used by getAllIndexedFS and FsIterator_subtypes_unordered
+ * 
+ * The iterators can be for single types or for types with subtypes.
+ *   Exception: if the ll_index is accessed, it is presumed to be of type FsIndex_subtypes.
+ * 
+ * Doesn't do concurrent mod checking - that's done if wanted by the individual iterators
+ * being aggregated over.  
+ * This results in allowing a few concurrent modifications, when crossing from one iterator to another
+ * in moveToNext/Previous (because those get translated to move to first/last, which reset concurrent modification)
+ */
+class FsIterator_aggregation_common<T extends FeatureStructure> 
+          implements LowLevelIterator<T> {
+  
+  final private FSIterator<T>[] iterators;
+  
+  private int lastValidIndex;
+  
+  final private FSIndex<T> index;
+  
+  FsIterator_aggregation_common(FSIterator<T>[] iterators, FSIndex<T> index) {
+    this.iterators = iterators;
+    this.index = index;
+  }
+  
+  public T get() throws NoSuchElementException {
+    if (!isValid()) {
+      throw new NoSuchElementException();
+    }
+    return iterators[lastValidIndex].get();
+  }
+
+  public boolean isValid() {
+    return lastValidIndex >= 0 &&
+           lastValidIndex < iterators.length &&
+           iterators[lastValidIndex].isValid();
+  }
+
+  public void moveTo(FeatureStructure fs) {
+    for (int i = 0, nbrIt = iterators.length; i < nbrIt; i++) {
+      FSIterator<T> it = iterators[i];
+      if (((LowLevelIterator<T>)it).ll_getIndex().contains(fs)) {
+        lastValidIndex = i;
+        it.moveTo(fs);
+        return;
+      }
+    }
+    moveToFirst();  // default if not found
+  }
+
+  public void moveToFirst() {
+    for (int i = 0, nbrIt = iterators.length; i < nbrIt; i++) {
+      FSIterator<T> it = iterators[i];
+      it.moveToFirst();
+      if (it.isValid()) {
+        lastValidIndex = i;
+        return;
+      }
+    }
+    lastValidIndex = -1; // no valid index
+  }
+
+  public void moveToLast() {
+    for (int i = iterators.length -1; i >= 0; i--) {
+      FSIterator<T> it = iterators[i];
+      it.moveToLast();
+      if (it.isValid()) {
+        lastValidIndex = i;
+        return;
+      }
+    }
+    lastValidIndex = -1; // no valid index
+  }
+
+  public void moveToNext() {
+    // No point in going anywhere if iterator is not valid.
+    if (!isValid()) {
+      return;
+    }
+    
+    FSIterator<T> it = iterators[lastValidIndex];
+    it.moveToNext();
+
+    if (it.isValid()) {
+      return;
+    }
+    
+    for (int i = lastValidIndex + 1, nbrIt = iterators.length; i < nbrIt; i++) {
+      it = iterators[i];
+      it.moveToFirst();
+      if (it.isValid()) {
+        lastValidIndex = i;
+        return;
+      }
+    }
+    lastValidIndex = iterators.length;  // invalid position
+  }
+    
+
+  public void moveToPrevious() {
+    // No point in going anywhere if iterator is not valid.
+    if (!isValid()) {
+      return;
+    }
+    
+    FSIterator<T> it = iterators[lastValidIndex];
+    it.moveToPrevious();
+
+    if (it.isValid()) {
+      return;
+    }
+    
+    for (int i = lastValidIndex - 1; i >=  0; i--) {
+      it = iterators[i];
+      it.moveToLast();
+      if (it.isValid()) {
+        lastValidIndex = i;
+        return;
+      }
+    }
+    lastValidIndex = -1;  // invalid position
+  }
+
+  public int ll_indexSize() {
+    int sum = 0;
+    for (int i = iterators.length - 1; i >=  0; i--) {
+      FSIterator<T> it = iterators[i];
+      sum += ((LowLevelIterator<T>)it).ll_indexSize();
+    }
+    return sum;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#copy()
+   */
+  @Override
+  public FSIterator<T> copy() {
+    FsIterator_aggregation_common<T> it = new FsIterator_aggregation_common<T>(iterators.clone(), index);
+    for (int i = 0; i < iterators.length; i++) {
+      it.iterators[i] = iterators[i].copy();
+    }
+    
+    if (!isValid()) {
+      it.moveToFirst();
+      it.moveToPrevious();  // make it also invalid
+    } else {
+      T targetFs = get();
+      it.moveTo(get());  // moves to left-most match
+      while (targetFs != it.get()) {
+        it.moveToNext();
+      }
+    }
+    return it;
+  }
+
+
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return (LowLevelIndex<T>) index;
+  }  
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_bag.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,146 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+import org.apache.uima.internal.util.ObjHashSet;
+
+class FsIterator_bag<T extends FeatureStructure> extends FsIterator_singletype<T> {
+
+  private ObjHashSet<T> bag;
+  
+  private int position = -1;  
+  
+  private boolean isGoingForward = true;
+
+  final private FsIndex_bag<T> fsBagIndex; // just an optimization, is == to fsLeafIndexImpl from super class, allows dispatch w/o casting
+
+  FsIterator_bag(FsIndex_bag<T> fsBagIndex, int[] detectIllegalIndexUpdates, int typeCode) {
+    super(detectIllegalIndexUpdates, typeCode, null);
+    this.fsBagIndex = fsBagIndex;  // need for copy()
+    bag = (ObjHashSet<T>) fsBagIndex.getObjHashSet();
+    moveToFirst();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#isValid()
+   */
+  @Override
+  public boolean isValid() {
+    return (position >= 0) && (position < bag.getCapacity());
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#get()
+   */
+  @Override
+  public T get() {
+    checkConcurrentModification();
+    if (isValid()) {
+      return bag.get(position);
+    }
+    throw new NoSuchElementException();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToFirst()
+   */
+  @Override
+  public void moveToFirst() {
+    resetConcurrentModification();
+    isGoingForward = true;
+    position = (bag.size() == 0) ? -1 : bag.moveToNextFilled(0);
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToLast()
+   *  If empty, make position -1 (invalid)
+   */
+  @Override
+  public void moveToLast() {
+    resetConcurrentModification();
+    isGoingForward = false;
+    position =  (bag.size() == 0) ? -1 : bag.moveToPreviousFilled(bag.getCapacity() -1);
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToNext()
+   */
+  @Override
+  public void moveToNext() {
+    checkConcurrentModification(); 
+    if (isValid()) {
+      isGoingForward = true;
+      position = bag.moveToNextFilled(++position);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToPrevious()
+   */
+  @Override
+  public void moveToPrevious() {
+    checkConcurrentModification();
+    if (isValid()) {
+      isGoingForward = false;
+      position = bag.moveToPreviousFilled(--position);
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveTo(org.apache.uima.cas.FeatureStructure)
+   */
+  @Override
+  public void moveTo(FeatureStructure fs) {
+    resetConcurrentModification();
+    position = bag.moveTo(fs);
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#copy()
+   */
+  @Override
+  public FsIterator_bag<T> copy() {
+    FsIterator_bag<T> copy = new FsIterator_bag<T>(this.fsBagIndex, this.detectIllegalIndexUpdates, this.typeCode);
+    copy.position = position;
+    copy.isGoingForward = isGoingForward;   
+    return copy;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize()
+   */  @Override
+  public int ll_indexSize() {
+    return bag.size();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_getIndex()
+   */
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return fsBagIndex;
+  }
+
+}
+

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_set_sorted.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,199 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.Comparator;
+import java.util.Iterator;
+import java.util.NavigableSet;
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FeatureStructure;
+
+class FsIterator_set_sorted<T extends FeatureStructure> extends FsIterator_singletype<T> {
+
+  // We use FeatureStructure instead of T because the 
+  // signature of getting a "matching" element limits the type to the declared type, and 
+  // in UIMA we can use, say an Annotation instance as a moveTo arg, for a navSet of some subtype of Annotation.
+  final private NavigableSet<FeatureStructure> navSet;  // == fsSortIndex.getNavigableSet()
+  
+  final private FsIndex_set_sorted<T> fsSetSortIndex;
+  
+  private T currentElement;
+  
+  private boolean isGoingForward = true;
+  
+  /**
+   * true if a next() set the the currentElement, and advanced position to next
+   *
+   * if true, then
+   *   currentElement is the one that get should return, and position is already advanced
+   * if false, then 
+   *   get needs to do a next() to retrieve the now-currentElement, and advances position to next
+   */
+  private boolean isCurrentElementFromLastGet = false;
+
+  private Iterator<T> iterator; 
+  
+  FsIterator_set_sorted(FsIndex_set_sorted<T> fsSetSortIndex, int[] detectIllegalIndexUpdates, int typeCode, Comparator<FeatureStructure> comp) {
+    super(detectIllegalIndexUpdates, typeCode, comp);
+    this.fsSetSortIndex = fsSetSortIndex;
+    this.navSet = fsSetSortIndex.getNavigableSet();
+    iterator = (Iterator<T>) navSet.iterator();  // can't use fsSortIndex.iterator - that recursively calls this
+  }
+
+  @Override
+  public boolean isValid() {return isCurrentElementFromLastGet ? true : iterator.hasNext();}
+
+  @Override
+  public void moveToFirst() {
+    resetConcurrentModification();
+    iterator = (Iterator<T>) navSet.iterator();
+    isGoingForward = true;
+    isCurrentElementFromLastGet = false;
+  }
+
+  @Override
+  public void moveToLast() {
+    resetConcurrentModification();
+    iterator =  (Iterator<T>) navSet.descendingIterator();
+    isGoingForward = false;
+    isCurrentElementFromLastGet = false;
+  }
+
+  @Override
+  public void moveToNext() {
+    if (!isValid()) {
+      return;
+    }
+  
+    checkConcurrentModification();
+    if (isGoingForward) {
+      if (isCurrentElementFromLastGet) {
+        isCurrentElementFromLastGet = false;
+      } else {
+        currentElement = iterator.next();
+        // leave isCurrentElementFromLastGet false because we just moved to next, but haven't retrieved that value
+      } 
+    } else {
+      //reverse direction
+      if (!isCurrentElementFromLastGet) {
+        currentElement = iterator.next();  // need current value to do reverse iterator starting point
+      }
+      assert(currentElement != null);
+      iterator = (Iterator<T>) navSet.tailSet(currentElement, false).iterator();
+      isGoingForward = true;
+      isCurrentElementFromLastGet = false;
+    }
+  }
+
+  @Override
+  public void moveToPrevious() {
+    if (!isValid()) {
+      return;
+    }
+
+    checkConcurrentModification();
+    if (!isGoingForward) {
+      if (isCurrentElementFromLastGet) {
+        isCurrentElementFromLastGet = false;
+      } else {
+        currentElement = iterator.next();
+        // leave isCurrentElementFromLastGet false
+      } 
+    } else {
+      //reverse direction
+      if (!isCurrentElementFromLastGet) {
+        currentElement = iterator.next();  // need current value to do reverse iterator starting point
+      }
+      assert(currentElement != null);
+      iterator = (Iterator<T>) navSet.headSet(currentElement, false).descendingIterator();
+      isGoingForward = false;
+      isCurrentElementFromLastGet = false;
+    }  
+  }
+
+  @Override
+  public T get() {
+    if (!isValid()) {
+      throw new NoSuchElementException();
+    }
+    checkConcurrentModification();
+    if (!isCurrentElementFromLastGet) {
+      currentElement = iterator.next();
+      isCurrentElementFromLastGet = true;
+    }
+    return currentElement;
+  }
+
+  /**
+   * @see org.apache.uima.internal.util.IntPointerIterator#copy()
+   */
+  @Override
+  public FsIterator_set_sorted<T> copy() {
+    return new FsIterator_set_sorted<T>(this.fsSetSortIndex, this.detectIllegalIndexUpdates, typeCode, this.comparator);
+  }
+
+  /**
+   * move to the "left most" fs that is equal using the comparator
+   *   - this means the one after a LT compare or the beginning.
+   * reset isCurrentElementFromLastSet
+   * set isGoingForward
+   * @param fs the template FS indicating the position
+   */
+  @Override
+  public void moveTo(FeatureStructure fs) {
+    isGoingForward = true;
+    isCurrentElementFromLastGet = false;
+    currentElement = null;
+    resetConcurrentModification();    
+    Iterator<T> it = (Iterator<T>) navSet.headSet(fs, false).descendingIterator();
+
+    // if the 1st previous element doesn't exist, then start at the first element 
+    if (!it.hasNext()) {
+      moveToFirst();
+      return;
+    }
+    
+    // it iterator is valid.  Move backwards until either hit the end or find element not equal
+    T elementBefore = null;
+    boolean comparedEqual = false;  // value is ignored, but needed for Java compile
+    while (it.hasNext() && 
+           (comparedEqual = (0 == comparator.compare(elementBefore = it.next(), fs))));     
+    
+    if (comparedEqual) { // then we ran off the end
+      moveToFirst();
+      return;
+    }
+    
+    iterator = (Iterator<T>) navSet.tailSet(elementBefore, false).iterator();
+    return;
+  }
+  
+  @Override
+  public int ll_indexSize() {
+    return fsSetSortIndex.size();
+  }
+  
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return fsSetSortIndex;
+  }
+}
+

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_singletype.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_singletype.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_singletype.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_singletype.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,60 @@
+package org.apache.uima.cas.impl;
+
+import java.util.Comparator;
+import java.util.ConcurrentModificationException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+public abstract class FsIterator_singletype<T extends FeatureStructure>
+                    implements LowLevelIterator<T>, 
+                               Comparable<FsIterator_singletype<T>> {
+
+  private int modificationSnapshot; // to catch illegal modifications
+
+  /**
+   * This is a ref to the shared value in the FSIndexRepositoryImpl
+   * OR it may be null which means skip the checking (done for some internal routines
+   * which know they are not updating the index, and assume no other thread is)
+   */
+  final protected int[] detectIllegalIndexUpdates; // shared copy with Index Repository
+
+  protected final int typeCode;  // needed for the detect concurrent modification
+  
+  /**
+   * The generic type is FeatureStructure to allow comparing between
+   * an instance of T and some other template type which can be a supertype of T, as long as
+   * the keys are defined in both.
+   */
+  final protected Comparator<FeatureStructure> comparator;
+
+  public FsIterator_singletype(int[] detectConcurrentMods, int typeCode, Comparator<FeatureStructure> comparator){
+    this.comparator = comparator;
+    this.detectIllegalIndexUpdates = detectConcurrentMods;
+    this.typeCode = typeCode;
+    resetConcurrentModification();
+    // subtypes do moveToFirst after they finish initialization
+  }
+    
+  protected <I extends FSIterator<T>> I checkConcurrentModification() {
+    if ((null != detectIllegalIndexUpdates) && (modificationSnapshot != detectIllegalIndexUpdates[typeCode])) {
+      throw new ConcurrentModificationException();
+    }
+    return (I) this;
+  }
+  
+  protected void resetConcurrentModification() {  
+    this.modificationSnapshot = (null == this.detectIllegalIndexUpdates) ? 0 : this.detectIllegalIndexUpdates[typeCode];
+  }
+
+  @Override
+  public int compareTo(FsIterator_singletype<T> o) {
+    if (comparator != null) {
+      return comparator.compare(this.get(), o.get());
+    } 
+    return Integer.compare(this.get().get_id(), o.get().get_id());
+  }
+   
+  @Override
+  public abstract FsIterator_singletype<T> copy();
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+
+public abstract class FsIterator_subtypes<T extends FeatureStructure> implements LowLevelIterator<T> {
+
+  // The IICP
+  final protected FsIndex_iicp<T> iicp;
+ 
+  public FsIterator_subtypes(FsIndex_iicp<T> iicp) {
+    this.iicp = iicp;
+  } 
+  
+  protected FsIndex_iicp<? extends FeatureStructure> getIicp() {
+    return iicp;
+  }
+  
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return iicp.fsIndex_singletype;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize()
+   */
+  @Override
+  public int ll_indexSize() {
+    return ll_getIndex().size();
+  }
+
+  final static FsIterator_subtypes FS_ITERATOR_EMPTY = new FsIterator_subtypes(null) {
+    @Override
+    public boolean isValid() {return false;}
+    @Override
+    public FeatureStructure get() throws NoSuchElementException { throw new NoSuchElementException(); }
+    @Override
+    public void moveToNext() {}
+    @Override
+    public void moveToPrevious() {}
+    @Override
+    public void moveToFirst() {}
+    @Override
+    public void moveToLast() {}
+    @Override
+    public void moveTo(FeatureStructure fs) {}
+    @Override
+    public FSIterator<FeatureStructure> copy() { return this; }
+  };
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_list.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_list.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_list.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_list.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,75 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.function.Function;
+
+import org.apache.uima.cas.FeatureStructure;
+
+public abstract class FsIterator_subtypes_list <T extends FeatureStructure>  extends FsIterator_subtypes<T> {
+
+  // An array of iterators, one for each subtype.
+  //   This array has the indexes for all the subtypes that were non-empty at the time of iterator creation
+  protected FsIterator_singletype<T>[] iterators;
+
+  protected int lastValidIndex = 0;
+   
+  public FsIterator_subtypes_list(FsIndex_iicp<T> iicp) {
+    super(iicp);
+    this.iterators = initIterators();
+//    can't do moveToFirst, subtypes haven't yet set up enough things (like comparator)
+    // subtypes must do this call after setup complete
+//    moveToFirst();  // needed in order to set up lastvalid index, etc.
+  }
+  
+  // skip including iterators for empty indexes
+  //   The concurrent modification exception notification doesn't occur when subsequent "adds" are done, but
+  //   that is the same as current: 
+  //   where the move to first would mark the iterator "invalid" (because it was initially empty) and it would be
+  //     subsequently ignored - same effect
+  private FsIterator_singletype<T>[] initIterators() {
+    iicp.createIndexIteratorCache();
+    final ArrayList<FsIndex_singletype<FeatureStructure>> cachedSubIndexes = iicp.cachedSubFsLeafIndexes;
+    
+    // map from single-type index to iterator over that single type
+    Function<FsIndex_singletype<FeatureStructure>, FsIterator_singletype<T>> m = 
+        fsIndex_singletype -> (FsIterator_singletype<T>)(fsIndex_singletype.iterator());
+    
+    FsIterator_singletype<T>[] r = cachedSubIndexes.stream()
+        .filter(leafIndex -> leafIndex.size() > 0)  // filter out empty ones
+        .map(m)  // map fsIndex_singletype to an iterator over that
+        .toArray(FsIterator_singletype[]::new);
+
+    // if all are empty, put the first one in (to avoid handling 0 as a special case)
+    return (r.length != 0) ? r : new FsIterator_singletype[] {m.apply(cachedSubIndexes.get(0))};
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize()
+   */
+  @Override
+  public int ll_indexSize() {
+    return Arrays.stream(iterators).mapToInt(it -> it.ll_getIndex().size()).sum();
+  }
+  
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_ordered.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_ordered.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_ordered.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_ordered.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,423 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.Comparator;
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+/**
+ * Performs an ordered iteration among a set of iterators, each one corresponding to
+ *   the type or subtype of the uppermost type.
+ *   
+ * The set of iterators is maintained in an array, with the 0th element being the current valid iterator.
+ * 
+ * This class doesn't do concurrent mod checking - that's done by the individual iterators.
+ *
+ * @param <T>
+ */
+public class FsIterator_subtypes_ordered<T extends FeatureStructure> 
+                    extends FsIterator_subtypes_list<T> {
+ 
+  /**
+   * The number of elements to keep in order before the binary heap starts. This section helps the
+   * performance in cases where a couple of types dominate the index.
+   */
+  private static final int SORTED_SECTION = 3;
+  
+  private boolean wentForward = true;
+  
+  final private Comparator<FeatureStructure> comparator; 
+
+  public FsIterator_subtypes_ordered(FsIndex_iicp<T> iicp) {
+    super(iicp);
+    this.comparator = iicp.fsIndex_singletype;
+    moveToFirst();
+  } 
+  
+  /**
+   * Move operators have to move a group of iterators for this type and all its subtypes
+   */
+  
+  @Override
+  public void moveToFirst() {
+    
+    int lvi = this.iterators.length - 1;
+    // Need to consider all iterators.
+    // Set all iterators to insertion point.
+    int i = 0;
+    while (i <= lvi) {
+      final FsIterator_singletype<T> it = this.iterators[i];
+      it.moveToFirst();
+      if (it.isValid()) {
+        heapify_up(it, i, 1);
+        ++i;
+      } else {
+        // swap this iterator with the last possibly valid one
+        // lvi might be equal to i, this will not be a problem
+        this.iterators[i] = this.iterators[lvi];
+        this.iterators[lvi] = it;
+        --lvi;
+      }
+    }
+    // configured to continue with forward iterations
+    this.wentForward = true;
+    this.lastValidIndex = lvi;
+  }
+  
+  @Override
+  public void moveToLast() {
+    int lvi = this.iterators.length - 1;
+    // Need to consider all iterators.
+    // Set all iterators to insertion point.
+    int i = 0;
+    while (i <= lvi) {
+      final FsIterator_singletype<T> it = this.iterators[i];
+      it.resetConcurrentModification();
+      it.moveToLast();
+      if (it.isValid()) {
+        heapify_up(it, i, -1);
+        ++i;
+      } else {
+        // swap this iterator with the last possibly valid one
+        // lvi might be equal to i, this will not be a problem
+        this.iterators[i] = this.iterators[lvi];
+        this.iterators[lvi] = it;
+        --lvi;
+      }
+    }
+    // configured to continue with backward iterations
+    this.wentForward = false;
+    this.lastValidIndex = lvi;
+  }
+
+  @Override
+  public void moveToNext() {
+    if (!isValid()) {
+      return;
+    }
+
+    final FsIterator_singletype<T> it0 = iterators[0].checkConcurrentModification();
+
+    if (this.wentForward) {
+      it0.moveToNext();
+      heapify_down(it0, 1);
+    } else {
+      // We need to increment everything.
+      int lvi = this.iterators.length - 1;
+      int i = 1;
+      while (i <= lvi) {
+        // Any iterator other than the current one needs to be
+        // incremented until it's pointing at something that's
+        // greater than the current element.
+        final FsIterator_singletype<T> it = iterators[i].checkConcurrentModification();
+        // If the iterator we're considering is not valid, we
+        // set it to the first element. This should be it for this iterator...
+        if (!it.isValid()) {
+          it.moveToFirst();
+        }
+        // Increment the iterator while it is valid and pointing
+        // at something smaller than the current element.
+        while (it.isValid() && is_before(it, it0, 1)) {
+          it.moveToNext();
+        }
+
+        // find placement
+        if (it.isValid()) {
+          heapify_up(it, i, 1);
+          ++i;
+        } else {
+          // swap this iterator with the last possibly valid one
+          // lvi might be equal to i, this will not be a problem
+          this.iterators[i] = this.iterators[lvi];
+          this.iterators[lvi] = it;
+          --lvi;
+        }
+      }
+
+      this.lastValidIndex = lvi;
+      this.wentForward = true;
+
+      it0.moveToNext();
+      heapify_down(it0, 1);
+    }
+  }
+
+  @Override
+  public void moveToPrevious() {
+    if (!isValid()) {
+      return;
+    }
+
+    final FsIterator_singletype<T> it0 = iterators[0].checkConcurrentModification();
+    if (!this.wentForward) {
+      it0.moveToPrevious();
+      // this also takes care of invalid iterators
+      heapify_down(it0, -1);
+    } else {
+      // We need to decrement everything.
+      int lvi = this.iterators.length - 1;
+      int i = 1;
+      while (i <= lvi) {
+        // Any iterator other than the current one needs to be
+        // decremented until it's pointing at something that's
+        // smaller than the current element.
+        final FsIterator_singletype<T> it = iterators[i].checkConcurrentModification();
+        // If the iterator we're considering is not valid, we
+        // set it to the last element. This should be it for this iterator...
+        if (!it.isValid()) {
+          it.moveToLast();
+        }
+        // Decrement the iterator while it is valid and pointing
+        // at something greater than the current element.
+        while (it.isValid() && is_before(it, it0, -1)) {
+          it.moveToPrevious();
+        }
+
+        // find placement
+        if (it.isValid()) {
+          heapify_up(it, i, -1);
+          ++i;
+        } else {
+          // swap this iterator with the last possibly valid one
+          // lvi might be equal to i, this will not be a problem
+          this.iterators[i] = this.iterators[lvi];
+          this.iterators[lvi] = it;
+          --lvi;
+        }
+      }
+
+      this.lastValidIndex = lvi;
+      this.wentForward = false;
+
+      it0.moveToPrevious();
+      heapify_down(it0, -1);
+    }
+  }
+
+
+  /**
+   * Test the order with which the two iterators should be used. Introduces arbitrary ordering for
+   * equivalent FSs. Only called with valid iterators.
+   * 
+   * @param l
+   * @param r
+   * @param dir
+   *          Direction of movement, 1 for forward, -1 for backward
+   * @return true if the left iterator needs to be used before the right one.
+   */
+  private boolean is_before(FsIterator_singletype<T> l, FsIterator_singletype<T> r,
+      int dir) {
+
+    final T fsLeft = l.get();
+    final T fsRight = r.get();
+    
+    int d = comparator.compare(fsLeft, fsRight);
+
+    // If two FSs are identical wrt the comparator of the index,
+    // we still need to be able to distinguish them to be able to have a
+    // well-defined sequence. In that case, we arbitrarily order FSs by
+    // their
+    // addresses. We need to do this in order to be able to ensure that a
+    // reverse iterator produces the reverse order of the forward iterator.
+    if (d == 0) {
+      d = fsLeft.get_id() - fsRight.get_id();
+    }
+    return d * dir < 0;
+  }
+
+  /**
+   * Move the idx'th element up in the heap until it finds its proper position.
+   * 
+   * @param it
+   *          indexes[idx]
+   * @param idx
+   *          Element to move
+   * @param dir
+   *          Direction of iterator movement, 1 for forward, -1 for backward
+   */
+  private void heapify_up(FsIterator_singletype<T> it, int idx, int dir) {
+//    FSIndexFlat<? extends FeatureStructure> flatIndexInfo = iicp.flatIndex;
+//    if (null != flatIndexInfo) {
+//      flatIndexInfo.incrementReorderingCount();
+//    }
+    int nidx;
+
+    while (idx > SORTED_SECTION) {
+      nidx = (idx + SORTED_SECTION - 1) >> 1;
+      if (!is_before(it, this.iterators[nidx], dir)) {
+        this.iterators[idx] = it;
+        return;
+      }
+      this.iterators[idx] = this.iterators[nidx];
+      idx = nidx;
+    }
+
+    while (idx > 0) {
+      nidx = idx - 1;
+      if (!is_before(it, this.iterators[nidx], dir)) {
+        this.iterators[idx] = it;
+        return;
+      }
+      this.iterators[idx] = this.iterators[nidx];
+      idx = nidx;
+    }
+
+    this.iterators[idx] = it;
+  }
+
+  /**
+   * Move the top element down in the heap until it finds its proper position.
+   * 
+   * @param it
+   *          indexes[0]
+   * @param dir
+   *          Direction of iterator movement, 1 for forward, -1 for backward
+   */
+  private void heapify_down(FsIterator_singletype<T> it, int dir) {
+//    FSIndexFlat<? extends FeatureStructure> flatIndexInfo = iicp.flatIndex;
+//    if (null != flatIndexInfo) {
+//      flatIndexInfo.incrementReorderingCount();
+//    }
+
+    if (!it.isValid()) {
+      final FsIterator_singletype<T> itl = this.iterators[this.lastValidIndex].checkConcurrentModification();
+      this.iterators[this.lastValidIndex] = it;
+      this.iterators[0] = itl;
+      --this.lastValidIndex;
+      it = itl;
+    }
+
+    final int num = this.lastValidIndex;
+    if ((num < 1) || !is_before(this.iterators[1].checkConcurrentModification(), it, dir)) {
+      return;
+    }
+
+    int idx = 1;
+    this.iterators[0] = this.iterators[1];
+    final int end = Math.min(num, SORTED_SECTION);
+    int nidx = idx + 1;
+
+    // make sure we don't leave the iterator in a completely invalid state
+    // (i.e. one it can't recover from using moveTo/moveToFirst/moveToLast)
+    // in case of a concurrent modification
+    try {
+      while (nidx <= end) {
+        if (!is_before(this.iterators[nidx].checkConcurrentModification(), it, dir)) {
+          return; // passes through finally
+        }
+
+        this.iterators[idx] = this.iterators[nidx];
+        idx = nidx;
+        nidx = idx + 1;
+      }
+
+      nidx = SORTED_SECTION + 1;
+      while (nidx <= num) {
+        if ((nidx < num)
+            && is_before(this.iterators[nidx+1].checkConcurrentModification(),
+                this.iterators[nidx].checkConcurrentModification(), dir)) {
+          ++nidx;
+        }
+
+        if (!is_before(this.iterators[nidx], it, dir)) {
+          return;
+        }
+
+        this.iterators[idx] = this.iterators[nidx];
+        idx = nidx;
+        nidx = (nidx << 1) - (SORTED_SECTION - 1);
+      }
+    } finally {
+      this.iterators[idx] = it;
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#isValid()
+   */
+  @Override
+  public boolean isValid() {
+    return lastValidIndex >= 0;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#get()
+   */
+  @Override
+  public T get() throws NoSuchElementException {
+    if (!isValid()) {
+      throw new NoSuchElementException();
+    }
+    return iterators[0].checkConcurrentModification().get();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveTo(org.apache.uima.cas.FeatureStructure)
+   */
+  @Override
+  public void moveTo(FeatureStructure fs) {
+    int lvi = this.iterators.length - 1;
+    // Need to consider all iterators.
+    // Set all iterators to insertion point.
+    int i = 0;
+    while (i <= lvi) {
+      final FsIterator_singletype<T> it = this.iterators[i];
+      it.moveTo(fs);
+      if (it.isValid()) {
+        heapify_up(it, i, 1);
+        ++i;
+      } else {
+        // swap this iterator with the last possibly valid one
+        // lvi might be equal to i, this will not be a problem
+        this.iterators[i] = this.iterators[lvi];
+        this.iterators[lvi] = it;
+        --lvi;
+      }
+    }
+    // configured to continue with forward iterations
+    this.wentForward = true;
+    this.lastValidIndex = lvi;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#copy()
+   */
+  @Override
+  public FSIterator<T> copy() {
+    FsIterator_subtypes_ordered<T> it = new FsIterator_subtypes_ordered<T>(iicp);
+    if (!isValid()) {
+      it.moveToPrevious();  // mark new one also invalid
+    } else {
+      T posFs = get();
+      it.moveTo(posFs);  // moves to left-most position
+      while(it.get() != posFs) {
+        it.moveToNext();
+      }
+    }
+    return it;
+  }
+
+  
+
+  
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_snapshot.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_snapshot.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_snapshot.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_snapshot.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,167 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIndex;
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+public class FsIterator_subtypes_snapshot<T extends FeatureStructure> implements LowLevelIterator<T>, Comparator<T> {
+  
+//  final private FsIndex_flat<T> flatIndex;  // a newly created one, just for this iterator
+  final private T[] snapshot;  // local for ref speed
+  private int pos = 0; 
+  final private boolean is_unordered;
+  final private LowLevelIndex<T> indexForComparator;
+    
+  public FsIterator_subtypes_snapshot(FsIndex_flat<T> flatIndex) {
+    this.indexForComparator = flatIndex;
+    this.snapshot = (T[]) flatIndex.getFlatArray();
+    this.is_unordered = flatIndex.getIndexingStrategy() != FSIndex.SORTED_INDEX;
+  }
+  
+  public FsIterator_subtypes_snapshot(T[] snapshot, LowLevelIndex<FeatureStructure> index, boolean is_unordered) {
+    this.indexForComparator = (LowLevelIndex<T>) index;
+    this.snapshot = snapshot;
+    this.is_unordered = is_unordered;
+  }
+  
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#isValid()
+   */
+  @Override
+  public boolean isValid() {
+    return (0 <= pos) && (pos < snapshot.length);
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#get()
+   */
+  @Override
+  public T get() throws NoSuchElementException {
+    if (isValid()) {
+      return snapshot[pos];
+    }
+    throw new NoSuchElementException();
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToNext()
+   */
+  @Override
+  public void moveToNext() {
+    if (isValid()) {
+      pos++;
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToPrevious()
+   */
+  @Override
+  public void moveToPrevious() {
+    if (isValid()) {
+      pos--;
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToFirst()
+   */
+  @Override
+  public void moveToFirst() {
+    pos = 0;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveToLast()
+   */
+  @Override
+  public void moveToLast() {
+    pos = snapshot.length - 1;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#moveTo(org.apache.uima.cas.FeatureStructure)
+   */
+  @Override
+  public void moveTo(FeatureStructure fs) {
+    if (is_unordered) {
+      int i = 0;
+      while ((i < snapshot.length) && indexForComparator.compare(snapshot[i],  fs) < 0) {
+        i++;
+      }
+      pos = i;
+    } else {
+      int c = Arrays.binarySearch(snapshot, 0, snapshot.length, (T)fs, this);
+      if (c < 0) {
+        // was not found, c is (-(insertion point) - 1)
+        //    insertion point      c                pos
+        //         0               -1                0
+        //         1               -2                1
+        //       size - 1       -(size - 1) - 1     size - 1
+        //        size           -size - 1          size (invalid)
+        pos = (-c) - 1;   
+      } else {
+        // found an equal.  need to move to leftmost
+        c--;
+        while ((c >= 0) && indexForComparator.compare(snapshot[c],  fs) == 0) {
+          c--;
+        }
+        pos = c + 1;
+      }
+    }
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.FSIterator#copy()
+   */
+  @Override
+  public FSIterator<T> copy() {
+    FsIterator_subtypes_snapshot<T> it = new FsIterator_subtypes_snapshot<T>(
+        this.snapshot, (LowLevelIndex<FeatureStructure>) this.indexForComparator, this.is_unordered);
+    it.pos = pos;
+    return it;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize()
+   */
+  @Override
+  public int ll_indexSize() {
+    return snapshot.length;
+  }
+
+  /* (non-Javadoc)
+   * @see org.apache.uima.cas.impl.LowLevelIterator#ll_getIndex()
+   */
+  @Override
+  public LowLevelIndex<T> ll_getIndex() {
+    return indexForComparator;
+  }
+  
+  public int compare(FeatureStructure fs1, FeatureStructure fs2) {
+    return this.indexForComparator.compare(fs1, fs2);
+  }
+}

Added: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_unordered.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_unordered.java?rev=1711751&view=auto
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_unordered.java (added)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIterator_subtypes_unordered.java Sun Nov  1 13:12:22 2015
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ * 
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ * 
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.uima.cas.impl;
+
+import java.util.NoSuchElementException;
+
+import org.apache.uima.cas.FSIterator;
+import org.apache.uima.cas.FeatureStructure;
+
+/**
+ * This class has an instance created temporarily to reuse the 
+ * computation of the iterator array, for use by the FsIterator_aggregation_common.
+ * @param <T> the type of the iterator
+ */
+public class FsIterator_subtypes_unordered<T extends FeatureStructure> extends FsIterator_subtypes_list<T> {
+ 
+  public FsIterator_subtypes_unordered(FsIndex_iicp<T> iicp) {
+    super(iicp);
+  } 
+  
+  // these methods are never called but are needed to allow creation of the temporary instance of this.
+  
+  @Override
+  public boolean isValid() {throw new UnsupportedOperationException();}
+  @Override
+  public T get() throws NoSuchElementException {throw new UnsupportedOperationException();}
+  @Override
+  public void moveToNext() {throw new UnsupportedOperationException();}
+  @Override
+  public void moveToPrevious() {throw new UnsupportedOperationException();}
+  @Override
+  public void moveToFirst() {}  // can't throw, should be a no-op.
+  @Override
+  public void moveToLast() {throw new UnsupportedOperationException();}
+  @Override
+  public void moveTo(FeatureStructure fs) {throw new UnsupportedOperationException();}
+  @Override
+  public FSIterator<T> copy() {throw new UnsupportedOperationException();}
+  @Override
+  public boolean hasNext() {throw new UnsupportedOperationException();}
+  @Override
+  public T next() {throw new UnsupportedOperationException();}
+}