Author: schor
Date: Wed Jul 18 18:28:32 2018
New Revision: 1836215

URL: http://svn.apache.org/viewvc?rev=1836215&view=rev
Log:
[UIMA-5830][UIMA-5829][UIMA-5828][UIMA-5826] many fixes to select

Modified:
    
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
    
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java

Modified: 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java?rev=1836215&r1=1836214&r2=1836215&view=diff
==============================================================================
--- 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
 (original)
+++ 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/SelectFSs.java
 Wed Jul 18 18:28:32 2018
@@ -380,8 +380,8 @@ public interface SelectFSs<T extends Fea
   SelectFSs<T> following(int position, int offset);
 
   /**
-   * For AnnotationIndex, set up a selection that will proceed backwards, 
-   * starting at the first Annotation to the left of the specified position, 
+   * For AnnotationIndex, set up a selection that will go from the beginning 
to  
+   * the first Annotation to the left of the specified position, 
    * whose end &lt;= fs.getBegin().
    * Annotations whose end &gt; fs.getBegin() are skipped.
    * @param annotation the Annotation to use as the position to start before.
@@ -389,28 +389,31 @@ public interface SelectFSs<T extends Fea
    */
   SelectFSs<T> preceding(Annotation annotation);
   /**
-   * For AnnotationIndex, set up a selection that will proceed backwards, 
-   * starting at the first Annotation whose end &lt;= position.
+   * For AnnotationIndex, set up a selection that will go from the beginning 
to  
+   * the first Annotation to the left of the specified position, 
+   * ending at the last Annotation whose end &lt;= position.
    * Annotations whose end &gt; position are skipped.
    * @param position the position to start before.
    * @return the updated SelectFSs object
    */
   SelectFSs<T> preceding(int position);
   /**
-   * For AnnotationIndex, set up a selection that will proceed backwards, 
-   * starting at the first Annotation whose end &lt;= fs.getBegin(),
+   * For AnnotationIndex, set up a selection that will go from the beginning 
to  
+   * the first Annotation to the left of the specified position, 
+   * ending at the last Annotation whose end &lt;= fs.getBegin(),
    * after adjusting by offset items.
    * Annotations whose end &gt; fs.getBegin() are skipped (including during 
the offset positioning)
    * @param annotation the Annotation to use as the position to start before.
-   * @param offset the offset adjustment, positive or negative.  Positive 
moves backwards.
+   * @param offset the offset adjustment, positive or negative. Positive moves 
backwards. 
    * @return the updated SelectFSs object
    */
   SelectFSs<T> preceding(Annotation annotation, int offset);
   /**
-   * For AnnotationIndex, set up a selection that will proceed backwards, 
-   * starting at the first Annotation whose end &lt;= position.
+   * For AnnotationIndex, set up a selection that will go from the beginning 
to  
+   * the first Annotation to the left of the specified position, 
+   * ending at the last Annotation whose end &lt;= position.
    * after adjusting by offset items.
-   * Annotations whose end &gt; fs.getBegin() are skipped (including during 
the offset positioning)
+   * Annotations whose end &gt; position are skipped (including during the 
offset positioning)
    * @param position the position to start before.
    * @param offset the offset adjustment, positive or negative.  Positive 
moves backwards.
    * @return the updated SelectFSs object

Modified: 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java
URL: 
http://svn.apache.org/viewvc/uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java?rev=1836215&r1=1836214&r2=1836215&view=diff
==============================================================================
--- 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java
 (original)
+++ 
uima/uv3/uimaj-v3/trunk/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java
 Wed Jul 18 18:28:32 2018
@@ -20,12 +20,11 @@
 package org.apache.uima.cas.impl;
 
 import java.lang.reflect.Array;
-import java.util.AbstractSequentialList;
+import java.util.AbstractList;
 import java.util.ArrayList;
 import java.util.Comparator;
 import java.util.Iterator;
 import java.util.List;
-import java.util.ListIterator;
 import java.util.Optional;
 import java.util.Spliterator;
 import java.util.function.BiConsumer;
@@ -81,6 +80,7 @@ import org.apache.uima.jcas.tcas.Annotat
  *   
  *   for not-bounded, 
  *     - ignore strict and skipEq
+ *       -- except: preceding implies skipping annotations whose end > 
positioning begin
  *     - order-not-needed only applies if iicp size &gt; 1
  *     - unambig ==&gt; use Subiterator
  *         -- subiterator wraps: according to typePriority and order-not-needed
@@ -91,7 +91,7 @@ import org.apache.uima.jcas.tcas.Annotat
  *     - use subiterator, pass in strict and skipeq
  *     
    finish this javadoc comment edit
- *   extends FeatureStructure, not TOP, because of ref from FSIndex 
+ *   T extends FeatureStructure, not TOP, because of ref from FSIndex 
  *      which uses FeatureStructure for backwards compatibility                
  
  */
 public class SelectFSs_impl <T extends FeatureStructure> implements 
SelectFSs<T> {
@@ -130,6 +130,7 @@ public class SelectFSs_impl <T extends F
   
   private TOP startingFs = null; // this is used for non-annotation 
positioning too
   private AnnotationFS boundingFs = null;
+  private boolean isEmptyBoundingFs = false;
   
   
   /* **********************************************
@@ -392,6 +393,9 @@ public class SelectFSs_impl <T extends F
   
   @Override
   public SelectFSs_impl<T> limit(int alimit) {
+    if (alimit < 0) {
+      throw new IllegalArgumentException("limit argument must be >= 0, but was 
" + alimit);
+    }
     this.limit = alimit;
     return this;
   }
@@ -431,10 +435,15 @@ public class SelectFSs_impl <T extends F
 
   @Override
   public SelectFSs_impl<T> between(AnnotationFS fs1, AnnotationFS fs2) {   // 
AI
-    final boolean reverse = fs1.getEnd() > fs2.getBegin();
-    this.boundingFs = makePosAnnot(
-        (reverse ? fs2 : fs1).getEnd(), 
-        (reverse ? fs1 : fs2).getBegin());
+    final boolean reverse = fs1.getEnd() > fs2.getBegin(); 
+    int begin = (reverse ? fs2 : fs1).getEnd();
+    int end   = (reverse ? fs1 : fs2).getBegin();
+    
+    if (begin > end) {
+      isEmptyBoundingFs = true;
+    } else {
+      this.boundingFs = makePosAnnot(begin, end);
+    }
     this.boundsUse = BoundsUse.coveredBy;
     this.isBackwards = reverse;
 //    this.isIncludeAnnotWithEndBeyondBounds = true; // default    
@@ -481,8 +490,8 @@ public class SelectFSs_impl <T extends F
   private void prepareTerminalOp() {
     if (boundsUse == null) {
       boundsUse = BoundsUse.notBounded;
-    }
-
+    } 
+    
     maybeValidateAltSource();
     
     final boolean isUseAnnotationIndex = 
@@ -507,8 +516,15 @@ public class SelectFSs_impl <T extends F
         ti = (TypeImpl) index.getType();
       }
     } else {
-      if (index != null && ((TypeImpl)index.getType()).subsumes(ti)) {
-        index = ((LowLevelIndex)index).getSubIndex(ti);
+      // type is specified
+      if (index != null) {
+        if (((TypeImpl)index.getType()).subsumes(ti)) {
+          index = ((LowLevelIndex)index).getSubIndex(ti);
+        }
+      } else {
+        if (ti.isAnnotationType()) {
+          forceAnnotationIndex();  // when index is null, but ti is not null 
and is annotation
+        }
       }
     }
     
@@ -524,6 +540,16 @@ public class SelectFSs_impl <T extends F
       isIncludeAnnotBeyondBounds = true;  
     }
     
+    // force ordering 
+    boolean orderingNeeded = 
+        !isUnordered ||
+        shift != 0 ||
+        boundsUse != BoundsUse.notBounded ||
+        isFollowing || isPreceding;
+    
+    isUnordered = ! orderingNeeded;
+    
+    
   }
   
   private void maybeValidateAltSource() {
@@ -578,43 +604,72 @@ public class SelectFSs_impl <T extends F
   public FSIterator<T> fsIterator() {
     if (isFollowing && isBackwards) {
       isBackwards = false;
-      LowLevelIterator<T> baseIterator = fsIterator1();
-      T[] a = (T[]) asArray(baseIterator);
-      FSIterator<T> it = new FsIterator_backwards<>(
-                           new FsIterator_subtypes_snapshot<T>(
-                               a, 
-                               (LowLevelIndex<T>) index, 
-                               IS_ORDERED,
-                               baseIterator.getComparator()));
-      return (limit == 0)
-          ? it
-            // rewrap with limit - needs to be outer shell to get right 
invalid behavior
-          : new FsIterator_limited<>(it, limit);          
+      return make_or_copy_snapshot(fsIterator1(), true);
+//      LowLevelIterator<T> baseIterator = fsIterator1();
+//      FSIterator<T> it;
+//      if (baseIterator instanceof FsIterator_subtypes_snapshot) {
+//        it = new FsIterator_backwards<>(baseIterator.copy()); // avoid 
making another array
+//      } else {
+//        T[] a = (T[]) asArray(baseIterator);
+//        it = new FsIterator_backwards<>(
+//                             new FsIterator_subtypes_snapshot<T>(
+//                                 a, 
+//                                 (LowLevelIndex<T>) index, 
+//                                 IS_ORDERED,
+//                                 baseIterator.getComparator()));
+//      }
+//      return (limit == -1)
+//          ? it
+//            // rewrap with limit - needs to be outer shell to get right 
invalid behavior
+//          : new FsIterator_limited<>(it, limit);          
     }
     
     if (isPreceding) {
-      boolean bkwd = isBackwards;
-      isBackwards = true;
-      LowLevelIterator<T> baseIterator = fsIterator1();
-      T[] a = (T[]) asArray(baseIterator);
-      FSIterator<T> it = new FsIterator_subtypes_snapshot<T>(
-                               a,
-                               (LowLevelIndex<T>) index,
-                               IS_ORDERED,
-                               baseIterator.getComparator());
-      if (!bkwd) {
-        it = new FsIterator_backwards<>(it); // because array is backwards
-      }
-      return (limit == 0) 
-          ? it
-            // rewrap with limit - needs to be outer shell to get right 
invalid behavior
-          : new FsIterator_limited<>(it, limit); 
+      boolean bkwd = isBackwards;   // save isBackwards flag.  
+                                    // since preceding normally operates 
backwards, if this flag is set
+                                    // the user wants to operate "forwards"
+      isBackwards = true;   // because need the iterator to move from the 
position to the front.
+      return make_or_copy_snapshot(fsIterator1(), bkwd);  // this iterator 
fails to skip annotations whose end is > positioning begin
+//      LowLevelIterator<T> baseIterator = fsIterator1();  // this iterator 
fails to skip annotations whose end is > positioning begin
+//      T[] a = (T[]) asArray(baseIterator);
+//      FSIterator<T> it = new FsIterator_subtypes_snapshot<T>(
+//                               a,
+//                               (LowLevelIndex<T>) index,
+//                               IS_ORDERED,
+//                               baseIterator.getComparator());
+//      if (!bkwd) {
+//        it = new FsIterator_backwards<>(it); // because array is backwards
+//      }
+//      return (limit == -1) 
+//          ? it
+//            // rewrap with limit - needs to be outer shell to get right 
invalid behavior
+//          : new FsIterator_limited<>(it, limit); 
     }
     
     // all others, including isFollowing but not backwards
     return fsIterator1();
   }
   
+  private FSIterator<T> make_or_copy_snapshot(LowLevelIterator<T> 
baseIterator, boolean bkwd) {
+    FSIterator<T> it;
+    T[] a = (T[]) asArray(baseIterator);  // array is in forward order because 
+                                          // it's produced by a backwards 
iterator, but then the array is reversed
+    it = new FsIterator_subtypes_snapshot<T>(
+                           a, 
+                               (LowLevelIndex<T>) index, 
+                               IS_ORDERED,
+                               baseIterator.getComparator());
+    
+    if (!bkwd) {
+      it = new FsIterator_backwards<>(it);
+    }
+
+    return (limit == -1)
+        ? it
+          // rewrap with limit - needs to be outer shell to get right invalid 
behavior
+        : new FsIterator_limited<T>(it, limit);
+  }
+  
   private LowLevelIterator<T> fsIterator1() {
     prepareTerminalOp();
     LowLevelIterator<T> it = isAllViews 
@@ -622,6 +677,7 @@ public class SelectFSs_impl <T extends F
                         createFsIterator_for_all_views()
                       : plainFsIterator(index, view);
 
+    it = maybeWrapBackwards(it);                  
     maybePosition(it);
     maybeShift(it);
     return (limit == -1) ? it : new FsIterator_limited<>(it, limit);    
@@ -706,7 +762,7 @@ public class SelectFSs_impl <T extends F
     LowLevelIterator<T> it;
     if (boundsUse == BoundsUse.notBounded) {
       if (!isSortedIndex) {
-        // set index
+        // set index or bag index
         it = (LowLevelIterator<T>) idx.iterator();       
       } else {
         // index is sorted but no bounds are being used.  Varieties:
@@ -714,13 +770,23 @@ public class SelectFSs_impl <T extends F
         //     - overlapping / non-overlapping  (ambiguous, unambiguous)
         //   - any sorted index including AnnotationIndex:
         //     - typePriority / ignore typePriority
-        //     - orderNotNecessary / 
+        //     - orderNotNecessary / orderNeeded
+        //   - preceding: need to skip over annotations whose end is > 
positioning-begin
 
-        it = (isAnnotationIndex) 
-               ? (LowLevelIterator<T>) ai.iterator( ! isNonOverlapping, 
IS_NOT_STRICT /* because unbounded */, isUnordered, ! isTypePriority)
+        it = isAnnotationIndex 
+               ? (LowLevelIterator<T>) ai.iterator( ! isNonOverlapping, 
IS_NOT_STRICT, isUnordered, ! isTypePriority)
                : idx.iterator(isUnordered, ! isTypePriority);
+        if (isPreceding) {
+          // filter the iterator to skip annotations whose end is > the 
position-begin
+          it = new FilteredIterator<T>(it, fs -> 
+          // true if ok, false to skip
+            ((Annotation)fs).getEnd() <= ((Annotation)startingFs).getBegin());
+        }
       }
     } else {
+      if (isEmptyBoundingFs) {
+        return (LowLevelIterator<T>) 
LowLevelIterator.FS_ITERATOR_LOW_LEVEL_EMPTY;
+      }
       // bounds in use, index must be annotation index, is ordered
       it = (LowLevelIterator<T>) new Subiterator<Annotation>(
           (FSIterator<Annotation>) idx.iterator(isUnordered, ! 
isTypePriority), 
@@ -731,14 +797,18 @@ public class SelectFSs_impl <T extends F
           isTypePriority,  
           isSkipSameBeginEndType);
     }
-    
-    
-    it = isBackwards ? new FsIterator_backwards<>(it) : it;
+
+    return it;
+  }
+  
+  private LowLevelIterator<T> maybeWrapBackwards(LowLevelIterator<T> it) {
     if (isBackwards) {
-      it.moveToFirst();  
+      it = new FsIterator_backwards<>(it);
+      it.moveToFirst();
     }
     return it;
   }
+  
     
   private LowLevelIterator<T> altSourceIterator() {
     T[] filtered;
@@ -797,28 +867,43 @@ public class SelectFSs_impl <T extends F
   public Iterator<T> iterator() {
     return fsIterator();
   }
-    
+
+  /*
+   * (non-Javadoc)
+   * @see org.apache.uima.cas.SelectFSs#asList()
+   * 
+   * The operation of this is to make an iterator which is directly 
addressable,
+   * and then return an instance of AbstractList<N>
+   * 
+   */
   @Override
   public <N extends T> List<N> asList() {
-    prepareTerminalOp();
-    
-    return new AbstractSequentialList<N>() {
+ 
+    return new AbstractList<N>() {
+ 
+      /**
+       * iterator used for two purposes:
+       *   - as underlying impl for listIterator 
+       *   - to compute the size
+       */
+      private final LowLevelIterator<T> it = (LowLevelIterator<T>) 
fsIterator();
       
+      N[] a = asArrayFs(it);
+
       @Override
-      public ListIterator<N> listIterator(int startingIndex) {
-        ListIterator<N> it = (ListIterator<N>) fsIterator();
-        for (int i = 0; i < startingIndex; i++) {
-          it.next();
-        }
-        return it;
+      public N get(int i) {
+        return a[i];
       }
 
       @Override
       public int size() {
-        return (index == null) ? -1 : index.size();
+        return it.size();
       }
-      
     };
+      
+      
+     
+    
   }
   
   /* (non-Javadoc)
@@ -826,30 +911,22 @@ public class SelectFSs_impl <T extends F
    */
   @Override
   public <N extends T> N[] asArray(Class<N> clazz) {
-    return asArray(fsIterator(), clazz);
+    return asArray((LowLevelIterator<T>)fsIterator());
   }
 
-  private <N extends T> N[] asArray(FSIterator<T> it, Class<N> clazz) {
-    List<N> al = asArray1(it);    
-    N[] r = (N[]) Array.newInstance(clazz, al.size());
-    return al.toArray(r);    
+  private <N extends T> N[] asArrayFs(LowLevelIterator<T> it) {
+    return (N[]) ((LowLevelIterator<T>)it).getArray();
   }
   
-  private <N extends T> List<N> asArray1(FSIterator<T> it) {
-    List<N> al = new ArrayList<>();
-    while (it.isValid()) {
-      al.add((N) it.getNvc());  // limit iterator might cause it to become 
invalid
-      it.moveToNext();
-    }    
-    return al;    
-  }
-  
-  private FeatureStructure[] asArray(FSIterator<T> it) {
-    List<? super T> al = asArray1(it);
-    FeatureStructure[] r = (FeatureStructure[]) 
Array.newInstance(FeatureStructure.class, al.size());
-    return al.toArray(r);
+  private <N extends T> N[] asArray(LowLevelIterator<T> it) {
+    return (N[]) ((LowLevelIterator<T>)it).getArray();
   }
+    
+//  private FeatureStructure[] asArray(FSIterator<T> it) {
+//    return asArray(it, FeatureStructure.class);
+//  }
   
+
   private Annotation makePosAnnot(int begin, int end) {
     if (end < begin) {
       throw new IllegalArgumentException("End value must be >= Begin value");
@@ -1245,9 +1322,6 @@ public class SelectFSs_impl <T extends F
   public SelectFSs<T> preceding(int position, int offset) {
     return commonPreceding(makePosAnnot(position, Integer.MAX_VALUE), offset);
   }
-
-   
-
   
   /************************
    * NOT USED
@@ -1292,13 +1366,14 @@ public class SelectFSs_impl <T extends F
     this.startingFs = annotation;
     this.shift = offset;
     isPreceding = true;
-    isBackwards = true; // always iterate backwards
     return this;
   }
   
   private void forceAnnotationIndex() {
     if (index == null) {
-      index = (LowLevelIndex<T>) view.getAnnotationIndex();
+      index = (LowLevelIndex<T>) (  (ti == null) ? 
+                                       view.getAnnotationIndex() :
+                                       view.getAnnotationIndex(ti));
     } else {
       if (!(index instanceof AnnotationIndex)) {
         /** Index "{0}" must be an AnnotationIndex. */ 


Reply via email to