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 2016/03/07 22:50:09 UTC

svn commit: r1733992 [1/2] - in /uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima: cas/impl/ jcas/cas/ jcas/tcas/ util/

Author: schor
Date: Mon Mar  7 21:50:08 2016
New Revision: 1733992

URL: http://svn.apache.org/viewvc?rev=1733992&view=rev
Log:
[UIMA-4824] [UIMA-4820] remove no longer needed feature register things, preserve info needed for delta de/ser. some renames of common getter/setter to start with "_".

Modified:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LinearTypeOrderBuilderImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeImpl_array.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/TypeSystemImpl.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/CommonList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/NonEmptyFSList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/NonEmptyFloatList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/NonEmptyIntegerList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/NonEmptyList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/NonEmptyStringList.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/Sofa.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/cas/TOP.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/jcas/tcas/Annotation.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/util/CasCopier.java
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/util/Misc.java

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java Mon Mar  7 21:50:08 2016
@@ -25,6 +25,7 @@ import java.io.InputStream;
 import java.io.PrintWriter;
 import java.io.StringWriter;
 import java.io.UnsupportedEncodingException;
+import java.lang.ref.WeakReference;
 import java.net.URL;
 import java.nio.ByteBuffer;
 import java.util.ArrayList;
@@ -271,7 +272,7 @@ public class CASImpl extends AbstractCas
      * They hold the same data (constant per CAS) but are accessed with different indexes
      */
     private final BitSet featureCodesInIndexKeys = new BitSet(1024); // 128 bytes
-    private final BitSet featureJiInIndexKeys = new BitSet(1024);  // indexed by JCas Feature Index, not feature code.
+//    private final BitSet featureJiInIndexKeys = new BitSet(1024);  // indexed by JCas Feature Index, not feature code.
     
     // A map from SofaNumbers which are also view numbers to IndexRepositories.
     // these numbers are dense, and start with 1.  1 is the initial view.  0 is the base case
@@ -389,8 +390,18 @@ public class CASImpl extends AbstractCas
     private EmptyIntegerList emptyIntegerList;
     private EmptyStringList emptyStringList;
 
+    /**
+     * Created at startup time, lives as long as the CAS lives
+     */
     private final BinaryCasSerDes bcsd;
     
+    /**
+     * Created when doing binary or form4 non-delta serialization, used in subsequent delta deserialization
+     * Created when doing binary or form4 non-delta deserialization, used in subsequent delta serialization
+     * Reset with CasReset or deltaMergesComplete API call 
+     */
+    private CommonSerDesSequential csds;
+    
     private SharedViewData(CASImpl baseCAS, int initialHeapSize, TypeSystemImpl tsi) {
       this.baseCAS = baseCAS;
       this.tsi = tsi;
@@ -411,6 +422,7 @@ public class CASImpl extends AbstractCas
       // misc
       flushEnabled = true;      
       componentInfo = null;
+      csds = null;
     }
     
     /**
@@ -439,7 +451,7 @@ public class CASImpl extends AbstractCas
       // type system + index spec
       tsi = null;
       featureCodesInIndexKeys.clear();
-      featureJiInIndexKeys.clear();
+//      featureJiInIndexKeys.clear();
       emptyFloatList = null; // these cleared in case new ts redefines?
       emptyFSList = null;
       emptyIntegerList = null;
@@ -527,12 +539,12 @@ public class CASImpl extends AbstractCas
     return svd.fsTobeAddedbackSingle;
   }
   
-  void featureCodes_inIndexKeysAdd(int featCode, int registryIndex) {
+  void featureCodes_inIndexKeysAdd(int featCode/*, int registryIndex*/) {
     svd.featureCodesInIndexKeys.set(featCode);
-    // skip adding if no JCas registry entry for this feature
-    if (registryIndex >= 0) {
-      svd.featureJiInIndexKeys.set(registryIndex);
-    }
+//     skip adding if no JCas registry entry for this feature
+//    if (registryIndex >= 0) {
+//      svd.featureJiInIndexKeys.set(registryIndex);
+//    }
   }
     
   // The index repository. Referenced by XmiCasSerializer
@@ -1365,26 +1377,7 @@ public class CASImpl extends AbstractCas
   public int ll_getArraySize(int id) {
     return getArraySize(getFsFromId_checked(id));
   }
-      
-  /*
-   * Support code for JCas setters
-   * Only called from JCasGen'd code
-   * 
-   */
-  final public void setWithCheckAndJournalJFRI(TOP fs, int jcasFieldRegistryIndex, Runnable setter) {
-    if (fs._inSetSortedIndex()) {
-      boolean wasRemoved = checkForInvalidFeatureSettingJFRI(fs, jcasFieldRegistryIndex);
-      setter.run();
-      if (wasRemoved) {
-        maybeAddback(fs);
-      }
-    } else {
-      setter.run();
-    }
-    
-    maybeLogUpdateJFRI(fs, jcasFieldRegistryIndex);
-  }
-  
+        
   final public void setWithCheckAndJournal(TOP fs, int featCode, Runnable setter) {
     if (fs._inSetSortedIndex()) {
       boolean wasRemoved = checkForInvalidFeatureSetting(fs, featCode);
@@ -1419,13 +1412,6 @@ public class CASImpl extends AbstractCas
     setter.run();
     maybeLogUpdate(fs, fi);
   }
-
-  public void setWithJournalJFRI(FeatureStructureImplC fs, int jcasFieldRegistryIndex, Runnable setter) {
-    setter.run();
-    maybeLogUpdateJFRI(fs, jcasFieldRegistryIndex);
-  }
-
-  
   
   /**
    * 
@@ -1445,13 +1431,6 @@ public class CASImpl extends AbstractCas
     }
   }
   
-  final public void maybeLogUpdateJFRI(FeatureStructureImplC fs, int jcasFieldRegistryIndex) {
-    if (this.svd.trackingMark != null && !this.svd.trackingMark.isNew(fs._id)) {
-      this.logFSUpdate((TOP) fs, getFeatFromJCasFieldRegistryIndex(jcasFieldRegistryIndex));
-    }
-  }
-
-
   final public void maybeLogUpdate(FeatureStructureImplC fs, int featCode) {
     if (this.svd.trackingMark != null && !this.svd.trackingMark.isNew(fs._id)) {
       this.logFSUpdate((TOP)fs, getFeatFromCode_checked(featCode));
@@ -1496,149 +1475,24 @@ public class CASImpl extends AbstractCas
    * @param feat    the feature to set
    * @param value -
    */
-  public void setLongValue(FeatureStructureImplC fsIn, FeatureImpl feat, int v1, int v2) {
+  public void setLongValue(FeatureStructureImplC fsIn, FeatureImpl feat, long v) {
     TOP fs = (TOP) fsIn;
     if (fs._inSetSortedIndex()) {
       boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat.getCode());
-      setLongValueNcNj(fsIn, feat, v1, v2);
+      fs._setLongValueNcNj(feat, v);
       if (wasRemoved) {
         maybeAddback(fs);
       }
     } else {
-      setLongValueNcNj(fsIn, feat, v1, v2);
+      fs._setLongValueNcNj(feat, v);
     }
     maybeLogUpdate(fs, feat);
   }
-  
-  /**
-   * version for longs, uses two slots, skipping index validation and journaling, for cas copier
-   * Only called from FeatureStructureImplC after determining 
-   *   there is no local field to use
-   * Is here because of 3 calls to things in this class
-   * @param fs      the feature structure
-   * @param feat    the feature to set
-   * @param value -
-   */
-  public void setLongValueNcNj(FeatureStructureImplC fsIn, FeatureImpl feat, int v1, int v2) {
-    int offset = feat.getAdjustedOffset();
-    fsIn._intData[offset] = v1;
-    fsIn._intData[offset + 1] = v2;
-  }
-  
-//  
-//  /**
-//   * @param fs      the feature structure
-//   * @param feat    the feature to set
-//   * @param value -
-//   */
-//  
-//  public void setFeatureValue(FeatureStructureImplC fs, FeatureImpl feat, Object value) {
-//    fs.setRefValueCJ(feat, value);
-////    boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat.getCode());
-////    fs._refData[feat.getAdjustedOffset()] = value;
-////    if (wasRemoved) {
-////      maybeAddback(fs);
-////    }
-////    maybeLogUpdate(fs, feat);
-//  }
-
-//  /**
-//   * Set the value of a feature of a FS without checking for index corruption
-//   * (typically because the feature isn't one that can be used as a key, or
-//   * the context is one where the FS is being created, and is guaranteed not to be in any index (yet))
-//   * 
-//   * @param fs      The FS.
-//   * @param feat    The feature.
-//   * @param value     The new value for the feature.
-//   */
-//  void setFeatureValueNoIndexCorruptionCheck(FeatureStructureImplC fs, FeatureImpl feat, int value) {
-//    fs._intData[feat.getAdjustedOffset()] = value;   
-//    maybeLogUpdate(fs, feat);
-//  }
-
-  /**
-   * Set the value of a feature whose range is a FS.
-   * Skips the check for index corruption because the value can't be an index key.
-   * 
-   * @param fs      The FS.
-   * @param feat    The feature.
-   * @param value     The FS value for the feature.
-   */
-  void setFeatureValueNoIndexCorruptionCheck(FeatureStructureImplC fs, FeatureImpl feat, TOP value) {
-    fs.setFeatureValueNoIndexCorruptionCheck(feat, value);
-//    fs._refData[feat.getAdjustedOffset()] = value;   
-//    maybeLogUpdate(fs, feat);
-  }  
-
-//  /**
-//   * Set the value of a feature in the FS without journaling
-//   *   (because it's for a new FS above the mark)
-//   * @param fs      The Feature Structure.
-//   * @param featOffset The offset
-//   * @param value     The new value for the feature.
-//   */
-//  void setFeatureValueNotJournaled(FeatureStructureImplC fs, int featOffset, int value) {
-//    fs._intData[featOffset] = value;
-//  }
-
-//  /**
-//   * Set the value of a feature in the FS without journaling
-//   *   (because it's for a new FS above the mark)
-//   * @param fs      The Feature Structure.
-//   * @param featOffset The offset
-//   * @param value     The new value for the feature.
-//   */
-//  void setFeatureValueNotJournaled(FeatureStructureImplC fs, int featOffset, Object value) {
-//    fs._refData[featOffset] = value;
-//  }
-
-//  public void setFeatureValue(int fsRef, int featureCode, int value) {
-//    setFeatureValue(getFsFromId_checked(fsRef), getFeatFromCode(featureCode), value);
-//  }
-  
-//  
-//  public void setFeatureValue(int fsRef, int featureCode, Object value) {
-//    setFeatureValue(getFsFromId_checked(fsRef), getFeatFromCode(featureCode), value);
-//  }
-//  
+    
   void setFeatureValue(int fsRef, int featureCode, TOP value) {
     getFsFromId_checked(fsRef).setFeatureValue(getFeatFromCode_checked(featureCode), value); 
   }
   
-  public String getFeatureValueAsString(FeatureStructureImplC fs, FeatureImpl feat) {
-    TypeImpl range = feat.getRangeImpl();
-    if (feat.isInInt) {
-      switch (range.getCode()) {
-      case TypeSystemImpl.floatTypeCode :
-        return Float.toString(fs.getFloatValue(feat));
-      case TypeSystemImpl.booleanTypeCode :
-        return Boolean.toString(fs.getBooleanValue(feat));
-      case TypeSystemImpl.longTypeCode :
-        return Long.toString(fs.getLongValue(feat));
-      case TypeSystemImpl.doubleTypeCode :
-        return Double.toString(fs.getDoubleValue(feat));
-      default: 
-        return Integer.toString(fs.getIntValue(feat));
-      }
-    }
-    
-    if (range instanceof TypeImpl_string) {
-      return fs.getStringValue(feat);
-    }
-    
-    if (range.getCode() == TypeSystemImpl.javaObjectTypeCode) {
-      return serializeJavaObject(fs.getJavaObjectValue(feat));
-    }
-    
-    if (range.isRefType) {
-      TOP ref = fs.getFeatureValue(feat);
-      return (ref == null) ? null : ref.toString();
-    }
-    
-    Misc.internalError();
-    return null;  // needed to avoid compile error
-  }
-
   /**
    * Supports setting slots to "0" for null values
    * @param fs The feature structure to update
@@ -1691,7 +1545,7 @@ public class CASImpl extends AbstractCas
     throw new UnsupportedOperationException("Deserializing JavaObjects not yet implemented");
   }
 
-  private String serializeJavaObject(Object s) {
+  static String serializeJavaObject(Object s) {
     throw new UnsupportedOperationException("Serializing JavaObjects not yet implemented");
   }
 
@@ -2408,12 +2262,8 @@ public class CASImpl extends AbstractCas
   }
   
   /**
-   * This is the method all normal FS feature "setters" call before doing the set operation.
-   * <p style="margin-left:2em">
-   *   The binary deserializers bypass these setters, and directly update the heap values, so they have
-   *   a different impl to avoid index corruption.
-   * <p>
-   * It may do nothing (for performance, it needs to be enabled by a JVM property).
+   * This is the method all normal FS feature "setters" call before doing the set operation
+   * on values where the range could be used as an index key.
    * <p>
    * If enabled, it will check if the update may corrupt any index in any view.  The check tests
    * whether the feature is being used as a key in one or more indexes and if the FS is in one or more 
@@ -2450,7 +2300,7 @@ public class CASImpl extends AbstractCas
   }
  
   /**
-   * version for deserializers, using their own store for toBeAdded
+   * version for deserializers, and for set document language, using their own store for toBeAdded
    * @param fs -
    * @param featCode -
    * @param toBeAdded -
@@ -2463,9 +2313,9 @@ public class CASImpl extends AbstractCas
       }
  
       boolean wasRemoved = removeFromCorruptableIndexAnyView(fs, toBeAdded);
-      if (wasRemoved && doCorruptReport()) {
-        featModWhileInIndexReport(fs, featCode);
-      }
+//      if (wasRemoved && doCorruptReport()) {
+//        featModWhileInIndexReport(fs, featCode);
+//      }
       return wasRemoved;
     }
     return false;
@@ -2483,28 +2333,28 @@ public class CASImpl extends AbstractCas
     if (doInvalidFeatSettingCheck(fs)) {
  
       boolean wasRemoved = removeFromCorruptableIndexAnyView(fs, toBeAdded);
-      if (wasRemoved && doCorruptReport()) {
-        featModWhileInIndexReport(fs, null);
-      }
+//      if (wasRemoved && doCorruptReport()) {
+//        featModWhileInIndexReport(fs, null);
+//      }
       return wasRemoved;
     }
     return false;
   }
   
-  // version of above, but using jcasFieldRegistryIndex
-  private boolean checkForInvalidFeatureSettingJFRI(TOP fs, int jcasFieldRegistryIndex) {
-    if (doInvalidFeatSettingCheck(fs) &&
-        svd.featureJiInIndexKeys.get(jcasFieldRegistryIndex)) {
-      
-      boolean wasRemoved = checkForInvalidFeatureSetting2(fs);
-      
-      if (wasRemoved && doCorruptReport()) {
-        featModWhileInIndexReport(fs, getFeatFromJCasFieldRegistryIndex(jcasFieldRegistryIndex));
-      }
-      return wasRemoved;
-    }
-    return false;
-  }
+//  // version of above, but using jcasFieldRegistryIndex
+//  private boolean checkForInvalidFeatureSettingJFRI(TOP fs, int jcasFieldRegistryIndex) {
+//    if (doInvalidFeatSettingCheck(fs) &&
+//        svd.featureJiInIndexKeys.get(jcasFieldRegistryIndex)) {
+//      
+//      boolean wasRemoved = checkForInvalidFeatureSetting2(fs);
+//      
+////      if (wasRemoved && doCorruptReport()) {
+////        featModWhileInIndexReport(fs, getFeatFromRegistry(jcasFieldRegistryIndex));
+////      }
+//      return wasRemoved;
+//    }
+//    return false;
+//  }
   
   private boolean checkForInvalidFeatureSetting2(TOP fs) {
     final int ssz = svd.fssTobeAddedback.size();
@@ -2517,9 +2367,9 @@ public class CASImpl extends AbstractCas
         );            
   }
 
-  private FeatureImpl getFeatFromJCasFieldRegistryIndex(int jcasFieldRegistryIndex) {
-    return getFSClassRegistry().featuresFromJFRI[jcasFieldRegistryIndex];
-  }
+//  public FeatureImpl getFeatFromRegistry(int jcasFieldRegistryIndex) {
+//    return getFSClassRegistry().featuresFromJFRI[jcasFieldRegistryIndex];
+//  }
   
   private boolean doCorruptReport() {
     return 
@@ -3574,13 +3424,14 @@ public class CASImpl extends AbstractCas
     String newDoc = this.mySofaRef.getLocalStringData();
     if (null != newDoc) {
       Annotation docAnnot = getDocumentAnnotationNoCreate();
-      if (docAnnot != null) {
-        boolean wasRemoved = this.removeFromCorruptableIndexAnyView(docAnnot, this.getAddbackSingle());
-        docAnnot.setIntValue(getTypeSystemImpl().endFeat, newDoc.length());
+      if (docAnnot != null) {     
+        // use a local instance of the memory because this may be called as a side effect of updating a sofa
+        FSsTobeAddedback tobeAddedback = FSsTobeAddedback.createSingle();
+        boolean wasRemoved = this.checkForInvalidFeatureSetting(
+            docAnnot, getTypeSystemImpl().endFeat.getCode(), tobeAddedback);
+        docAnnot._setIntValueNfc(getTypeSystemImpl().endFeat, newDoc.length());
         if (wasRemoved) {
-          this.addbackSingle(docAnnot);
-        } else {
-          resetAddbackSingleInUse();
+          tobeAddedback.addback(docAnnot);
         }
       } else {
         // not in the index (yet)
@@ -4192,6 +4043,15 @@ public class CASImpl extends AbstractCas
     this.svd.id2fs.walkReachablePlusFSsSorted(action);
   }
   
+  /**
+   * called for delta serialization - walks just the new items above the line
+   * @param action -
+   * @param fromId - the id of the first item to walk from
+   */
+  public void walkReachablePlusFSsSorted(Consumer<TOP> action, int fromId) {
+    this.svd.id2fs.walkReachablePlueFSsSorted(action, fromId);
+  }
+  
 //  /**
 //   * Get the Java class corresponding to a particular type
 //   * Only valid after type system commit
@@ -4218,7 +4078,7 @@ public class CASImpl extends AbstractCas
   }
   
   private Object getFsGenerator(int typecode) {
-    return getTypeSystemImpl().getFSClassRegistry().getGenerator(typecode);
+    return getTypeSystemImpl().getGenerator(typecode);
   }
   
   public final void checkArrayPreconditions(int len) throws CASRuntimeException {
@@ -4303,7 +4163,7 @@ public class CASImpl extends AbstractCas
   public static void copyFeature(TOP fsSrc, FeatureImpl fi, TOP fsTgt) {
     if (!copyFeatureExceptFsRef(fsSrc, fi, fsTgt, fi)) {
       if (!fi.isAnnotBaseSofaRef) {
-        fsTgt.setFeatureValueNcNj(fi, fsSrc.getFeatureValueNc(fi));
+        fsTgt._setFeatureValueNcNj(fi, fsSrc._getFeatureValueNc(fi));
       }
     }
   }
@@ -4321,15 +4181,15 @@ public class CASImpl extends AbstractCas
    */
   public static boolean copyFeatureExceptFsRef(TOP fsSrc, FeatureImpl fiSrc, TOP fsTgt, FeatureImpl fiTgt) {
     switch (fiSrc.getRangeImpl().getCode()) {
-    case TypeSystemImpl.booleanTypeCode    : fsTgt.setBooleanValueNcNj(   fiTgt, fsSrc.getBooleanValueNc(   fiSrc)); break;
-    case TypeSystemImpl.byteTypeCode       : fsTgt.setByteValueNcNj(      fiTgt, fsSrc.getByteValueNc(      fiSrc)); break;
-    case TypeSystemImpl.shortTypeCode      : fsTgt.setShortValueNcNj(     fiTgt, fsSrc.getShortValueNc(     fiSrc)); break;
-    case TypeSystemImpl.intTypeCode        : fsTgt.setIntValueNcNj(       fiTgt, fsSrc.getIntValueNc(       fiSrc)); break;
-    case TypeSystemImpl.longTypeCode       : fsTgt.setLongValueNcNj(      fiTgt, fsSrc.getLongValueNc(      fiSrc)); break;
-    case TypeSystemImpl.floatTypeCode      : fsTgt.setFloatValueNcNj(     fiTgt, fsSrc.getFloatValueNc(     fiSrc)); break;
-    case TypeSystemImpl.doubleTypeCode     : fsTgt.setDoubleValueNcNj(    fiTgt, fsSrc.getDoubleValueNc(    fiSrc)); break;
-    case TypeSystemImpl.stringTypeCode     : fsTgt.setStringValueNcNj(    fiTgt, fsSrc.getStringValueNc(    fiSrc)); break;
-    case TypeSystemImpl.javaObjectTypeCode : fsTgt.setJavaObjectValueNcNj(fiTgt, fsSrc.getJavaObjectValue(fiSrc)); break;
+    case TypeSystemImpl.booleanTypeCode    : fsTgt._setBooleanValueNcNj(   fiTgt, fsSrc._getBooleanValueNc(   fiSrc)); break;
+    case TypeSystemImpl.byteTypeCode       : fsTgt._setByteValueNcNj(      fiTgt, fsSrc._getByteValueNc(      fiSrc)); break;
+    case TypeSystemImpl.shortTypeCode      : fsTgt._setShortValueNcNj(     fiTgt, fsSrc._getShortValueNc(     fiSrc)); break;
+    case TypeSystemImpl.intTypeCode        : fsTgt._setIntValueNcNj(       fiTgt, fsSrc._getIntValueNc(       fiSrc)); break;
+    case TypeSystemImpl.longTypeCode       : fsTgt._setLongValueNcNj(      fiTgt, fsSrc._getLongValueNc(      fiSrc)); break;
+    case TypeSystemImpl.floatTypeCode      : fsTgt._setFloatValueNcNj(     fiTgt, fsSrc._getFloatValueNc(     fiSrc)); break;
+    case TypeSystemImpl.doubleTypeCode     : fsTgt._setDoubleValueNcNj(    fiTgt, fsSrc._getDoubleValueNc(    fiSrc)); break;
+    case TypeSystemImpl.stringTypeCode     : fsTgt._setStringValueNcNj(    fiTgt, fsSrc._getStringValueNc(    fiSrc)); break;
+    case TypeSystemImpl.javaObjectTypeCode : fsTgt._setJavaObjectValueNcNj(fiTgt, fsSrc.getJavaObjectValue(fiSrc)); break;
                // skip setting sofaRef - it's final and can't be set
     default: return false;
     } // end of switch
@@ -4347,5 +4207,27 @@ public class CASImpl extends AbstractCas
     return svd.bcsd;
   }
   
+  /**
+   * @return the saved CommonSerDesSequential info
+   */
+  CommonSerDesSequential getCsds() {
+    return svd.csds; 
+  }
+  
+  void setCsds(CommonSerDesSequential csds) {
+    svd.csds = csds;
+  }
+  
+  CommonSerDesSequential newCsds() {
+    return svd.csds = new CommonSerDesSequential(this.getBaseCAS());
+  }
+  
+  /**
+   * A space-freeing optimization for use cases where (multiple) delta CASes are being deserialized into this CAS and merged.
+   */
+  public void deltaMergesComplete() {
+    svd.csds = null;
+  }
+  
 
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSClassRegistry.java Mon Mar  7 21:50:08 2016
@@ -26,45 +26,37 @@ import java.lang.invoke.LambdaMetafactor
 import java.lang.invoke.MethodHandle;
 import java.lang.invoke.MethodHandles;
 import java.lang.invoke.MethodType;
+import java.lang.reflect.Field;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.lang.reflect.Parameter;
 import java.util.ArrayList;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import org.apache.uima.UIMAFramework;
 import org.apache.uima.UIMARuntimeException;
 import org.apache.uima.cas.BuiltinTypeKinds;
 import org.apache.uima.cas.CAS;
 import org.apache.uima.cas.CASException;
 import org.apache.uima.cas.CASRuntimeException;
-import org.apache.uima.cas.Feature;
-import org.apache.uima.cas.function.JCas_getter_boolean;
-import org.apache.uima.cas.function.JCas_getter_byte;
-import org.apache.uima.cas.function.JCas_getter_double;
-import org.apache.uima.cas.function.JCas_getter_float;
-import org.apache.uima.cas.function.JCas_getter_generic;
-import org.apache.uima.cas.function.JCas_getter_int;
-import org.apache.uima.cas.function.JCas_getter_long;
-import org.apache.uima.cas.function.JCas_getter_short;
-import org.apache.uima.cas.function.JCas_setter_boolean;
-import org.apache.uima.cas.function.JCas_setter_byte;
-import org.apache.uima.cas.function.JCas_setter_double;
-import org.apache.uima.cas.function.JCas_setter_float;
-import org.apache.uima.cas.function.JCas_setter_generic;
-import org.apache.uima.cas.function.JCas_setter_int;
-import org.apache.uima.cas.function.JCas_setter_long;
-import org.apache.uima.cas.function.JCas_setter_short;
-import org.apache.uima.jcas.cas.AnnotationBase;
-import org.apache.uima.jcas.cas.Sofa;
 import org.apache.uima.jcas.cas.TOP;
+import org.apache.uima.util.Level;
+import org.apache.uima.util.Logger;
 import org.apache.uima.util.Misc;
 
 /*
+ * There is one class instance of this per class loader.
+ *   - Builtin JCas Types are loaded and shared among all type systems, once, when this class is loaded.
+ * 
  * There is one instance of this class per type system impl instance.
  *   - The type system impl instance points to this object
  *   - It is constructed when the type system is committed
  *   - Multiple simultaneous versions are possible with multiple type systems, but
  *      -- supporting different JCas cover classes requires using different ClassLoaders for the type system.
  * 
- * It may be shared 
+ * The instance may be shared 
  *   - by multiple CASes (in a CAS pool, for instance, when these CASes are sharing the same type system).
  *   - by all views of those CASes.
  *   - by multiple different pipelines, built using the same merged type system instance
@@ -83,18 +75,15 @@ import org.apache.uima.util.Misc;
  *              -- running with PEARs which have different definitions of JCas cover classes than their containing pipelines
  *              -- running with multiple, different pipelines, under a single type system class loader
  *          
- *   At typeSystemCommit time, this data structure is created and initialized with default
- *     (non-JCas) generators for all types. 
- *     - The built-in JCas types are loaded; these override the standard default generator.
+ *   At typeSystemCommit time, this data structure is created and initialized: 
+ *     - The built-in JCas types are loaded
  *     
- *     - The user-defined JCas classes are not loaded until the first call to create a JCas.
- *       -- this permits running without any customized JCas classes, which may be advantageous in some
- *          use cases, such as one where multiple different type systems are sequentially loaded 
- *          (think of an application which deserializes a CAS does some "generic processing", and repeats.)
+ *     - The user-defined JCas classes are loaded (not lazy, but eager), provided the type system is a new one.
+ *       (If the type system is "equal" to an existing committed one, that one is used instead).
  *          
- *     - When the JCas is initialized, the type system set of types is used to attempt to locate
- *       and load JCas class definitions.
- *       -- User classes defined with the name of UIMA types, but which are not JCas definitions, are not used.
+ *       -- User classes defined with the name of UIMA types, but which are not JCas definitions, are not used as 
+ *          JCas types.  This permits uses cases where users define a class which (perhaps at a later integration time)
+ *          has the same name as a UIMA type, but is not a JCas class.
  *       -- These classes, once loaded, remain loaded because of Java's design, unless the ClassLoader
  *          used to load them is Garbage Collected.
  *          --- The ClassLoader used is the same ClassLoader used for the type system, because
@@ -105,14 +94,20 @@ import org.apache.uima.util.Misc;
  *       -- represented by multiple classloaders, each one corresponding to a different PEAR or other classpath
  *     - can be invoked for a set of classloaders
  *     - is run manually, outside of normal UIMA pipeline operation, as a stand-alone utility
- *     
+ *   
+ *   Assigning slots for features:
+ *     - each type being loaded runs static final initializers to set for (a subset of) all features the offset
+ *       in the int or ref storage arrays for those values. 
+ *     - These call a static method in JCasRegistry: register[Int/Ref]Feature, which assigns the next available slot
+ *       via accessing/updating a thread local instance of TypeSystemImpl.SlotAllocate.
+ *     - Because the only slots     
  */
 
 public class FSClassRegistry {
   
-  private static final boolean GETTER = true;
-  private static final boolean SETTER = false;
-  
+//  private static final boolean GETTER = true;
+//  private static final boolean SETTER = false;
+    
   private static final MethodHandles.Lookup lookup = MethodHandles.lookup();
   
   private static final MethodType findConstructorJCasCoverType      = methodType(void.class, TypeImpl.class, CASImpl.class);
@@ -126,62 +121,111 @@ public class FSClassRegistry {
   private static final MethodType fsGeneratorType      = methodType(TOP.class, TypeImpl.class, CASImpl.class);
   private static final MethodType fsGeneratorArrayType = methodType(TOP.class, TypeImpl.class, CASImpl.class, int.class);
 
-  // must preceed first (static) use
-  static private ThreadLocal<ArrayList<Exception>> errorSet = new ThreadLocal<ArrayList<Exception>>();
-
-  public static class GetterSetter {
-    final Object getter;
-    final Object setter;
-    GetterSetter(Object getter, Object setter) {
-      this.getter = getter;
-      this.setter = setter;
+  static private class ErrorReport {
+    final Exception e;
+    final boolean doThrow;
+    ErrorReport(Exception e, boolean doThrow) {
+      this.e = e;
+      this.doThrow = doThrow;
     }
   }
+  // must precede first (static) use
+  static private ThreadLocal<List<ErrorReport>> errorSet = new ThreadLocal<>();
+ 
+
+//  public static class GetterSetter {
+//    final Object getter;
+//    final Object setter;
+//    final Object setterNcNj;
+//    GetterSetter(Object getter, Object setter, Object setterNcNj) {
+//      this.getter = getter;
+//      this.setter = setter;
+//      this.setterNcNj = setterNcNj;
+//    }
+//  }
   
-  private static class JCasClassInfo {
+  /**
+   * One instance per JCas Class, loaded or not
+   * 
+   * Created when potentially loading JCas classes.
+   * 
+   * Entries kept in a global static hashmap, key = typename (string)
+   *   Entries reused potentially by multiple type systems.
+   *   - Entries copied into global static array for built-ins, indexed by type code,
+   *   - Entries copied into instance array for particular type system, indexed by type code. 
+   * 
+   * Info used for identifying the target of a "new" operator - could be generator for superclass.
+   * One entry per defined JCas class; no instance if no JCas class is defined.
+   */
+  public static class JCasClassInfo {
+    
+    /**
+     * For createFS(type) use
+     */
     final Object generator;
-    final Class<?> jcasClass;
+   
     /**
-     * map from the feature short name to the getter/setter Lambda
+     * The corresponding loaded JCas Class
      */
-    final Map<String, GetterSetter> gettersAndSetters = new HashMap<>(1);
+    final Class<?> jcasClass;
+    
+//    /**
+//     * map from the feature short name to the getter/setter Lambda
+//     */
+//    final Map<String, GetterSetter> gettersAndSetters = new HashMap<>(1);
     
-    JCasClassInfo(Class<?> jcasClass, Object generator) {
+    JCasClassInfo(String typeName, Class<?> jcasClass, Object generator) {
       this.generator = generator;
       this.jcasClass = jcasClass;
+      
+      // add to map
+      type2JCas.put(typeName, this);
     }
   }
 
   /**
+   * Map from all type names from all type systems loaded under this class loader to the JCasClassInfo for that type.
+   * 
+   * Set after the JCas Class is attempted to be loaded for the first time.
+   */
+  public static final Map<String, JCasClassInfo> type2JCas = new HashMap<>(64);
+  
+  /**
    * precomputed generators for built-in types
+   * These instances are shared for all type systems
    */
   private static final JCasClassInfo[] jcasClassesInfoForBuiltins;
   static {
     TypeSystemImpl tsi = TypeSystemImpl.staticTsi;
     jcasClassesInfoForBuiltins = new JCasClassInfo[tsi.getTypeArraySize()]; 
-    ClassLoader cl = TypeSystemImpl.class.getClassLoader();
+        
+    // walk in subsumption order, supertype before subtype
+    loadBuiltins(tsi.topType);
+    
+    reportErrors();
+  }
+  
+  private static void loadBuiltins(TypeImpl ti) {
+    String typeName = ti.getName();
     
-    for (String typeName : BuiltinTypeKinds.creatableBuiltinJCas) {
-      TypeImpl ti = tsi.getType(typeName);
-      Class<?> builtinClass = maybeLoadJCas(typeName, cl);
+    if (BuiltinTypeKinds.creatableBuiltinJCas.contains(typeName) || typeName.equals(CAS.TYPE_NAME_SOFA)) {
+      TypeSystemImpl.typeBeingLoadedThreadLocal.set(ti);
+      Class<?> builtinClass = maybeLoadJCas(typeName);
       assert (builtinClass != null);  // builtin types must be present
       // copy down to subtypes, if needed, done later
       JCasClassInfo jcasClassInfo = createJCasClassInfo(builtinClass, ti); 
       jcasClassesInfoForBuiltins[ti.getCode()] = jcasClassInfo; 
-      setupGetterSetter(ti, jcasClassInfo);
+//      setupGetterSetter(ti, jcasClassInfo);
     }
     
-    /** special handling for Sofa, a non-creatable type */
-    TypeImpl ti = tsi.getType(CAS.TYPE_NAME_SOFA);
-    jcasClassesInfoForBuiltins[ti.getCode()] = createJCasClassInfo(Sofa.class, ti); 
-    
-    reportErrors();
+    for (TypeImpl subType : ti.getDirectSubtypes()) {
+      TypeSystemImpl.typeBeingLoadedThreadLocal.set(subType);
+      loadBuiltins(subType);
+    }
   }
   
-  // the loaded JCas cover classes, generators, setters, and getters.  index is typecode; value is JCas cover class which may belong to a supertype.
-  private final JCasClassInfo[] jcasClassesInfo; 
 
-  final FeatureImpl[] featuresFromJFRI;
+//  final FeatureImpl[] featuresFromJFRI;
   
   /**
    * install the default (non-JCas) generator for all types in the type system and the
@@ -195,17 +239,17 @@ public class FSClassRegistry {
    */
   FSClassRegistry(TypeSystemImpl ts, boolean isDoUserJCasLoading) {
     
-    jcasClassesInfo = new JCasClassInfo[ts.getTypeArraySize()];
-    
+    ts.jcasClassesInfo = new JCasClassInfo[ts.getTypeArraySize()];
+
     /**
      * copy in built-ins
      */
     for (int i = 0; i < jcasClassesInfoForBuiltins.length; i++) {
   
       JCasClassInfo jci = jcasClassesInfoForBuiltins[i];
-      jcasClassesInfo[i] = jci;
+      ts.jcasClassesInfo[i] = jci;
       if (jci != null) {
-        int v = Misc.getStaticIntField(getJCasClass(i), "typeIndexID");
+        int v = Misc.getStaticIntField(ts.getJCasClass(i), "typeIndexID");
         // v is negative if not found, which is the case for types like FloatList (these can't be instantiated)
         if (v >= 0) {
           ts.setJCasRegisteredType(v, ts.getTypeForCode(i));
@@ -221,122 +265,153 @@ public class FSClassRegistry {
     
     if (isDoUserJCasLoading) {
       /**
-       * Two pass loading is needed.  
-       *   - The first one loads the JCas Cover Classes initializes everything except the getters and setters
-       *   - The second pass updates the JCasClassInfo for the getters, and setters, which depend on 
-       *     having the TypeImpl' javaClass field be accurate (reflect any loaded JCas types)
+       * Two passes are needed loading is needed.  
+       *   - The first one loads the JCas Cover Classes initializes everything
+       *      -- some of the classes might already be loaded (including the builtins which are loaded once per class loader)
+       *   - The second pass performs the conformance checks between the loaded JCas cover classes, and the current type system.
+       *     This depends on having the TypeImpl's javaClass field be accurate (reflect any loaded JCas types)
        */
-      maybeLoadJCasAndSubtypes(ts, ts.topType, jcasClassesInfo[TypeSystemImpl.topTypeCode]);
-      setupGettersSetters(ts, ts.topType, jcasClassesInfo);
+      maybeLoadJCasAndSubtypes(ts, ts.topType, ts.jcasClassesInfo[TypeSystemImpl.topTypeCode]);
+      checkConformance(ts, ts.topType);
+//      setupGettersSetters(ts, ts.topType, jcasClassesInfo);
     }
     
     // walk the type system and extract all the registry indexes
     // While walking, update the FeatureImpl with the registry index
-    ArrayList<FeatureImpl> ffjfri = getFeatureFromJFRI(ts, ts.topType, new ArrayList<FeatureImpl>());
+//    ArrayList<FeatureImpl> ffjfri = getFeatureFromJFRI(ts, ts.topType, new ArrayList<FeatureImpl>());
     
-    featuresFromJFRI = new FeatureImpl[ffjfri.size()];
-    ffjfri.toArray(featuresFromJFRI);
+//    featuresFromJFRI = new FeatureImpl[ffjfri.size()];
+//    ffjfri.toArray(featuresFromJFRI);
     
     reportErrors();
   }
 
+//  /**
+//   * Walk type system from TOP, depth first
+//   *   - for each type, for all the features introduced, 
+//   *     -- collect if exists the field registry # and also save in the FeatureImpl
+//   * @param ts
+//   * @param ti
+//   * @param collector
+//   * @return
+//   */
+//  private ArrayList<FeatureImpl> getFeatureFromJFRI(TypeSystemImpl ts, TypeImpl ti, ArrayList<FeatureImpl> collector) {
+//    Class<?> clazz = getJCasClass(ti.getCode());
+//    for (FeatureImpl fi : ti.getMergedStaticFeaturesIntroducedByThisType()) {
+//      int indexJFRI = Misc.getStaticIntFieldNoInherit(clazz, "_FI_" + fi.getShortName());
+//      if (indexJFRI != Integer.MIN_VALUE) {  // that value is code for not found
+//        fi.registryIndex = indexJFRI;
+//        Misc.setWithExpand(collector, indexJFRI, fi);
+////      } else {
+////        System.out.println("debug: not found " + clazz.getName() + ", feature = " + fi.getShortName());
+//      }
+//    }
+//    
+//    for (TypeImpl subtype : ti.getDirectSubtypes()) {
+//      getFeatureFromJFRI(ts, subtype, collector);
+//    }
+//    return collector;
+//  } 
+
   /**
-   * Walk type system from TOP, depth first
-   *   - for each type, for all the features introduced, 
-   *     -- collect if exists the field registry # and also save in the FeatureImpl
+   * Called for all the types, including the built-ins.
    * @param ts
    * @param ti
-   * @param collector
-   * @return
+   * @param copyDownDefault_jcasClassInfo
    */
-  private ArrayList<FeatureImpl> getFeatureFromJFRI(TypeSystemImpl ts, TypeImpl ti, ArrayList<FeatureImpl> collector) {
-    Class<?> clazz = getJCasClass(ti.getCode());
-    for (FeatureImpl fi : ti.getMergedStaticFeaturesIntroducedByThisType()) {
-      int indexJFRI = Misc.getStaticIntFieldNoInherit(clazz, "_FI_" + fi.getShortName());
-      if (indexJFRI != Integer.MIN_VALUE) {  // that value is code for not found
-        fi.registryIndex = indexJFRI;
-        Misc.setWithExpand(collector, indexJFRI, fi);
-//      } else {
-//        System.out.println("debug: not found " + clazz.getName() + ", feature = " + fi.getShortName());
-      }
-    }
-    
-    for (TypeImpl subtype : ti.getDirectSubtypes()) {
-      getFeatureFromJFRI(ts, subtype, collector);
-    }
-    return collector;
-  }
-  
-  
-
   private void maybeLoadJCasAndSubtypes(TypeSystemImpl ts, TypeImpl ti, JCasClassInfo copyDownDefault_jcasClassInfo) {
-    final int typecode = ti.getCode();
-    Class<?> clazz;
-    boolean isBuiltin = BuiltinTypeKinds.creatableBuiltinJCas.contains(ti.getName());
-
-    JCasClassInfo jcasClassInfo = copyDownDefault_jcasClassInfo;  // initialize in case no JCas for this type
+    JCasClassInfo jcasClassInfo = type2JCas.get(ti.getName());
+    if (jcasClassInfo == null) {
+      // not yet loaded.  if Built-in, always skip this body
+      jcasClassInfo = copyDownDefault_jcasClassInfo;  // initialize in case no JCas for this type
     
-    if (!isBuiltin) {
-      clazz = maybeLoadJCas(ti.getName(), ti.getClass().getClassLoader()); 
+    
+      Class<?> clazz;
+  
+      TypeSystemImpl.typeBeingLoadedThreadLocal.set(ti);    
+      clazz = maybeLoadJCas(ti.getName());  
+      
       if (null != clazz && TOP.class.isAssignableFrom(clazz)) {
         jcasClassInfo = createJCasClassInfo(clazz, ti); 
-        int i = Misc.getStaticIntFieldNoInherit(clazz, "typeIndexID");
-        if (i >= 0) {
+        if (!Modifier.isAbstract(clazz.getModifiers())) { // skip next for abstract classes
+          int i = Misc.getStaticIntFieldNoInherit(clazz, "typeIndexID");
+          // if i is negative, this means there's no value for this field
+          assert(i >= 0);
           ts.setJCasRegisteredType(i, ti);
         }
-      }
-      jcasClassesInfo[typecode] = jcasClassInfo;  // sets new one or default one
+      } 
     }
-      
-    for (TypeImpl subtype : ti.getDirectSubtypes()) {
-      maybeLoadJCasAndSubtypes(ts, subtype, jcasClassesInfo[typecode]);
-    }
-  }
-  
-  private static void setupGettersSetters(TypeSystemImpl ts, TypeImpl ti, JCasClassInfo[] jci) {
-    boolean isBuiltin = BuiltinTypeKinds.creatableBuiltinJCas.contains(ti.getName());
-
-    if (!isBuiltin) {
-      setupGetterSetter(ti, jci[ti.getCode()]);
+    
+    // this check is done even after the class is first loaded, in case the type system changed.
+    //   -- if the new type system is equal to a previous one, then no new FSClassRegistry is created.
+        
+    ts.jcasClassesInfo[ti.getCode()] = jcasClassInfo;  // sets new one or default one
+    
+    if (!ti.isPrimitive()) {  // bypass this for primitives because the jcasClassInfo is the "inherited one" of TOP
+      ti.setJavaClass(jcasClassInfo.jcasClass);
     }
     
     for (TypeImpl subtype : ti.getDirectSubtypes()) {
-      setupGettersSetters(ts, subtype, jci);
+      TypeSystemImpl.typeBeingLoadedThreadLocal.set(subtype);
+      maybeLoadJCasAndSubtypes(ts, subtype, jcasClassInfo);
     }
   }
   
-  private static void setupGetterSetter(TypeImpl ti, JCasClassInfo jcasClassInfo) {
-
-      final Class<?> jcasClass = jcasClassInfo.jcasClass;
-
-      if (jcasClass.getName().equals(typeName2ClassName(ti.getName()))) {  // skip if this type is using a superclass JCas class
-        for (FeatureImpl fi : ti.getMergedStaticFeaturesIntroducedByThisType()) {
-          if (!isFieldInClass(fi, jcasClass)) {
-            continue;
-          }
-          Object getter = createGetterOrSetter(jcasClass, fi, GETTER);
-          Object setter = createGetterOrSetter(jcasClass, fi, SETTER);
-          
-          GetterSetter prev = jcasClassInfo.gettersAndSetters.put(fi.getShortName(), new GetterSetter(getter, setter));
-          if (prev != null) {
-            throw new CASRuntimeException(CASRuntimeException.INTERNAL_ERROR);
-          }
-        }            
-      }
-  }
-   
-  private static Class<?> maybeLoadJCas(String typeName, ClassLoader cl) {
+//  private static void setupGettersSetters(TypeSystemImpl ts, TypeImpl ti, JCasClassInfo[] jci) {
+//    boolean isBuiltin = BuiltinTypeKinds.creatableBuiltinJCas.contains(ti.getName());
+//
+//    if (!isBuiltin) {
+//      setupGetterSetter(ti, jci[ti.getCode()]);
+//    }
+//    
+//    for (TypeImpl subtype : ti.getDirectSubtypes()) {
+//      setupGettersSetters(ts, subtype, jci);
+//    }
+//  }
+  
+//  private static void setupGetterSetter(TypeImpl ti, JCasClassInfo jcasClassInfo) {
+//
+//      final Class<?> jcasClass = jcasClassInfo.jcasClass;
+//
+//      if (jcasClass.getName().equals(typeName2ClassName(ti.getName()))) {  // skip if this type is using a superclass JCas class
+//        for (FeatureImpl fi : ti.getMergedStaticFeaturesIntroducedByThisType()) {
+//          if (!isFieldInClass(fi, jcasClass)) {
+//            continue;
+//          }
+//          Object getter = createGetterOrSetter(jcasClass, fi, GETTER, false);
+//          Object setter = createGetterOrSetter(jcasClass, fi, SETTER, false);
+//          Object setterNcNj = null; // createGetterOrSetter(jcasClass, fi, SETTER, true);
+//          
+//          GetterSetter prev = jcasClassInfo.gettersAndSetters.put(fi.getShortName(), new GetterSetter(getter, setter, setterNcNj));
+//          if (prev != null) {
+//            throw new CASRuntimeException(CASRuntimeException.INTERNAL_ERROR);
+//          }
+//        }            
+//      }
+//  }
+  
+  /**
+   * Called to load (if possible) a corresponding JCas class for a UIMA type.
+   * Called at Class Init time for built-in types
+   * Called at TypeSystemCommit for non-built-in types
+   *   Runs the static initializers in the loaded JCas classes - doing resolve
+   *   
+   * @param typeName -
+   * @param cl the class loader to use
+   * @return the loaded / resolved class
+   */
+  private static Class<?> maybeLoadJCas(String typeName) {
     Class<?> clazz = null;
     String className = typeName2ClassName(typeName);
     try {
-      clazz = Class.forName(className, true, cl);
+      clazz = Class.forName(className, true, FSClassRegistry.class.getClassLoader());
     } catch (ClassNotFoundException e) {
       // This is normal, if there is no JCas for this class
     }
     return clazz;
   }
   
-  private static String typeName2ClassName(String typeName) {
+  public static String typeName2ClassName(String typeName) {
     if (typeName.startsWith(CAS.UIMA_CAS_PREFIX)) {
       return "org.apache.uima.jcas.cas." + typeName.substring(CAS.UIMA_CAS_PREFIX.length());
     }
@@ -345,6 +420,16 @@ public class FSClassRegistry {
     }
     return typeName;
   }
+  
+  public static String javaClassName2UimaTypeName(String className) {
+    if (className.startsWith("org.apache.uima.jcas.cas.")) { 
+      return CAS.UIMA_CAS_PREFIX + className.substring("org.apache.uima.jcas.cas.".length());
+    }
+    if (className.startsWith("org.apache.uima.jcas.tcas.")) { 
+      return CAS.UIMA_TCAS_PREFIX + className.substring("org.apache.uima.jcas.tcas.".length());
+    }
+    return className;
+  }
       
   /**
    * Return a Functional Interface for a generator for creating instances of a type.
@@ -354,8 +439,7 @@ public class FSClassRegistry {
    * @return a Functional Interface whose createFS method takes a casImpl 
    *         and when subsequently invoked, returns a new instance of the class
    */
-  private static Object createGenerator(Class<?> jcasClass, TypeImpl typeImpl) {
-    boolean isArray = typeImpl.isArray();
+  private static Object createGenerator(Class<?> jcasClass, boolean isArray) {
     try {
       MethodHandle mh = lookup.findConstructor(jcasClass, isArray ? findConstructorJCasCoverTypeArray 
                                                                   : findConstructorJCasCoverType);
@@ -375,152 +459,295 @@ public class FSClassRegistry {
                      : (FsGenerator) callSite.getTarget().invokeExact();
     } catch (Throwable e) {
       if (e instanceof NoSuchMethodException) {
-        throw new CASRuntimeException(e, CASRuntimeException.JCAS_CAS_NOT_V3, jcasClass.getName());
+        add2errors(errorSet, new CASRuntimeException(e, CASRuntimeException.JCAS_CAS_NOT_V3, jcasClass.getName()));
+        return null;
       }
       throw new UIMARuntimeException(e, UIMARuntimeException.INTERNAL_ERROR);
     }
   }
   
+//  /**
+//   * Return a Functional Interface for a getter for getting the value of a feature, 
+//   * called by APIs using the non-JCas style of access via features, 
+//   * but accessing the values via the JCas cover class getter methods.
+//   * 
+//   * The caller of these methods is the FeatureStructureImplC methods.  
+//   * 
+//   * There are these return values:
+//   *   boolean, byte, short, int, long, float, double, String, FeatureStructure
+//   *   
+//   */
+//  // static for setting up builtin values
+//  private static Object createGetterOrSetter(Class<?> jcasClass, FeatureImpl fi, boolean isGetter, boolean ncnj) {
+//    
+//    TypeImpl range = fi.getRangeImpl();
+//    String name = ncnj ? ("_" + fi.getGetterSetterName(isGetter) + "NcNj")
+//                       :        fi.getGetterSetterName(isGetter); 
+//    
+//    try {
+//      /* get an early-bound getter    
+//      /* Instead of findSpecial, we use findVirtual, in case the method is overridden by a subtype loaded later */
+//      MethodHandle mh = lookup.findVirtual(
+//          jcasClass,  // class having the method code for the getter 
+//          name,       // the name of the method for the getter or setter 
+//          isGetter ? methodType(range.javaClass)
+//                   : methodType(void.class, range.javaClass) // return value, e.g. int.class, xyz.class, FeatureStructureImplC.class
+//        );
+//      
+//      // getter methodtype is return_type, FeatureStructure.class
+//      //   return_type is int, byte, etc. primitive (except string/substring), or
+//      //   object (to correspond with erasure)
+//      // setter methodtype is void.class, FeatureStructure.class, javaclass
+//      MethodType mhMt = isGetter ? methodType(range.getJavaPrimitiveClassOrObject(), FeatureStructureImplC.class)
+//                                 : methodType(void.class, FeatureStructureImplC.class, range.getJavaPrimitiveClassOrObject());
+//      MethodType iMt =  isGetter ? methodType(range.javaClass, jcasClass)
+//                                 : methodType(void.class, jcasClass, range.javaClass);
+//      
+////      System.out.format("mh method type for %s method %s is %s%n", 
+////          jcasClass.getSimpleName(), 
+////          fi.getGetterSetterName(isGetter),
+////          mhMt);
+//          
+//      CallSite callSite = LambdaMetafactory.metafactory(
+//          lookup,     // lookup context for the getter
+//          isGetter ? "get" : "set", // name of the method in the Function Interface                 
+//          methodType(isGetter ? range.getter_funct_intfc_class : range.setter_funct_intfc_class),  // callsite signature = just the functional interface return value
+//          mhMt,                      // samMethodType signature and return type of method impl by function object 
+//          mh,  // method handle to constructor 
+//          iMt);
+//    
+//      if (range.getJavaClass() == boolean.class) {
+//        return isGetter ? (JCas_getter_boolean) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_boolean) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == byte.class) {
+//        return isGetter ? (JCas_getter_byte) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_byte) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == short.class) {
+//        return isGetter ? (JCas_getter_short) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_short) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == int.class) {
+//        return isGetter ? (JCas_getter_int) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_int) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == long.class) {
+//        return isGetter ? (JCas_getter_long) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_long) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == float.class) {
+//        return isGetter ? (JCas_getter_float) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_float) callSite.getTarget().invokeExact();
+//      } else if (range.getJavaClass() == double.class) {
+//        return isGetter ? (JCas_getter_double) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_double) callSite.getTarget().invokeExact();
+//      } else {
+//        return isGetter ? (JCas_getter_generic<?>) callSite.getTarget().invokeExact() 
+//                        : (JCas_setter_generic<?>) callSite.getTarget().invokeExact();
+//      }
+//    } catch (NoSuchMethodException e) {
+//      if ((jcasClass == Sofa.class && !isGetter) ||
+//          (jcasClass == AnnotationBase.class && !isGetter)) {
+//        return null;
+//      }  
+//      // report missing setter or getter
+//      /* Unable to find required {0} method for JCAS type {1} with {2} type of {3}. */
+//      CASException casEx = new CASException(CASException.JCAS_GETTER_SETTER_MISSING, 
+//          name,
+//          jcasClass.getName(),
+//          isGetter ? "return" : "argument",
+//          range.javaClass.getName()     
+//          );
+//      ArrayList<Exception> es = errorSet.get();
+//      if (es == null) {
+//        es = new ArrayList<Exception>();
+//        errorSet.set(es);
+//      }
+//      es.add(casEx);
+//      return null;
+//    } catch (Throwable e) {
+//      throw new UIMARuntimeException(e, UIMARuntimeException.INTERNAL_ERROR);
+//    }
+//  }
+   
+//  GetterSetter getGetterSetter(int typecode, String featShortName) {
+//    return jcasClassesInfo[typecode].gettersAndSetters.get(featShortName);
+//  }
+   
+  // static for setting up static builtin values
   /**
-   * Return a Functional Interface for a getter for getting the value of a feature, 
-   * called by APIs using the non-JCas style of access via features, 
-   * but accessing the values via the JCas cover class getter methods.
+   * Called after succeeding at loading, once per load for an exact matching JCas Class 
+   *   - class was already checked to insure is of proper type for JCas
+   *   - skips creating-generator-for-Sofa - since "new Sofa(...)" is not a valid way to create a sofa   
    * 
-   * The caller of these methods is the FeatureStructureImplC methods.  
+   * @param jcasClass the JCas class that corresponds to the type
+   * @param ti the type
+   * @return the info for this JCas that is shared across all type systems under this class loader
+   */
+  private static JCasClassInfo createJCasClassInfo(Class<?> jcasClass, TypeImpl ti) {
+    boolean noGenerator = ti.getCode() == TypeSystemImpl.sofaTypeCode ||
+                          Modifier.isAbstract(jcasClass.getModifiers()); 
+    Object generator = noGenerator ? null : createGenerator(jcasClass, ti.isArray());
+    JCasClassInfo jcasClassInfo = new JCasClassInfo(ti.getName(), jcasClass, generator);
+    return jcasClassInfo;
+  }
+  
+//  static boolean isFieldInClass(Feature feat, Class<?> clazz) {
+//    try {
+//      return null != clazz.getDeclaredField("_FI_" + feat.getShortName());
+//    } catch (NoSuchFieldException e) {
+//      return false;
+//    }    
+//  }
+  
+  
+  private void checkConformance(TypeSystemImpl ts, TypeImpl ti) {
+    if (ti.isPrimitive()) return;
+    JCasClassInfo jcasClassInfo = type2JCas.get(ti.getName());
+    if (null != jcasClassInfo) { // skip if the UIMA class has an abstract (non-creatable) JCas class)      
+      checkConformance(type2JCas.get(ti.getName()).jcasClass, ts, ti);
+    }
+    
+    for (TypeImpl subtype : ti.getDirectSubtypes()) {
+      checkConformance(ts, subtype);
+    }
+  }
+  
+  /**
+   * Checks that a JCas class definition conforms to the current type in the current type system.
+   * Checks that the superclass chain contains some match to the super type chain.
+   * Checks that the return value for the getters for features matches the feature's range.
+   * Checks that static _FI_xxx values from the JCas class == the adjusted feature offsets in the type system
    * 
-   * There are these return values:
-   *   boolean, byte, short, int, long, float, double, String, FeatureStructure
-   *   
+   * @param clazz - the JCas class to check
+   * @param tsi -
+   * @param ti -
    */
-  // static for setting up builtin values
-  private static Object createGetterOrSetter(Class<?> jcasClass, FeatureImpl fi, boolean isGetter) {
+  private static void checkConformance(Class<?> clazz, TypeSystemImpl tsi, TypeImpl ti) {
+
+    // skip the test if the jcasClassInfo is being inherited
+    //   because that has already been checked
+    if (!clazz.getName().equals(typeName2ClassName(ti.getName()))) {
+      return;
+    }
     
-    TypeImpl range = fi.getRangeImpl();
+    // check supertype
+   
+    // one of the supertypes must match a superclass of the class
+    boolean isOk = false;
+    List<Class<?>> superClasses = new ArrayList<>();
+   outer:
+    for (TypeImpl superType : ti.getAllSuperTypes()) {
+      JCasClassInfo jci = type2JCas.get(superType.getName());
+      if (jci == null) continue;
+      Class<?> superClass = clazz.getSuperclass();
+      superClasses.add(superClass);
+      while (superClass != FeatureStructureImplC.class && superClass != Object.class) {
+        if (jci.jcasClass == superClass) {
+          isOk = true;
+          break outer;
+        }
+        superClass = superClass.getSuperclass();
+        superClasses.add(superClass);
+      }
+    }
     
-    try {
-      /* get an early-bound getter    
-      /* Instead of findSpecial, we use findVirtual, in case the method is overridden by a subtype loaded later */
-      MethodHandle mh = lookup.findVirtual(
-          jcasClass,  // class having the method code for the getter 
-          fi.getGetterSetterName(isGetter), // the name of the method for the getter 
-          isGetter ? methodType(range.javaClass)
-                   : methodType(void.class, range.javaClass) // return value, e.g. int.class, xyz.class, FeatureStructureImplC.class
-        );
+    if (!isOk && superClasses.size() > 0) {
+      /** JCas Class's supertypes for "{0}", "{1}" and the corresponding UIMA Supertypes for "{2}", "{3}" don't have an intersection. */
+      add2errors(errorSet, 
+                 new CASRuntimeException(CASRuntimeException.JCAS_CAS_MISMATCH_SUPERTYPE, 
+                     clazz.getName(), Misc.ppList(superClasses), ti.getName(), Misc.ppList(ti.getAllSuperTypes())),
+                 true);  // throwable error
+    }
+
+    // the range of all the features must match the getters
+
+    for (Method m : clazz.getDeclaredMethods()) {
       
-      // getter methodtype is return_type, FeatureStructure.class
-      //   return_type is int, byte, etc. primitive (except string/substring), or
-      //   object (to correspond with erasure)
-      // setter methodtype is void.class, FeatureStructure.class, javaclass
-      MethodType mhMt = isGetter ? methodType(range.getJavaPrimitiveClassOrObject(), FeatureStructureImplC.class)
-                                 : methodType(void.class, FeatureStructureImplC.class, range.getJavaPrimitiveClassOrObject());
-      MethodType iMt =  isGetter ? methodType(range.javaClass, jcasClass)
-                                 : methodType(void.class, jcasClass, range.javaClass);
+      String mname = m.getName(); 
+      if (mname.length() <= 3 || !mname.startsWith("get")) continue;
+      String suffix = (mname.length() == 4) ? "" : mname.substring(4); 
+      String fname = Character.toLowerCase(mname.charAt(3)) + suffix; 
+      FeatureImpl fi = ti.getFeatureByBaseName(fname);
+      if (fi == null) {
+        fname = mname.charAt(3) + suffix;
+        if (fi == null) continue;
+      }
       
-//      System.out.format("mh method type for %s method %s is %s%n", 
-//          jcasClass.getSimpleName(), 
-//          fi.getGetterSetterName(isGetter),
-//          mhMt);
-          
-      CallSite callSite = LambdaMetafactory.metafactory(
-          lookup,     // lookup context for the getter
-          isGetter ? "get" : "set", // name of the method in the Function Interface                 
-          methodType(isGetter ? range.getter_funct_intfc_class : range.setter_funct_intfc_class),  // callsite signature = just the functional interface return value
-          mhMt,                      // samMethodType signature and return type of method impl by function object 
-          mh,  // method handle to constructor 
-          iMt);
+      // have the feature, check the range
+      Class<?> returnClass = m.getReturnType(); // for primitive, is int.class, etc.
+      TypeImpl range = fi.getRangeImpl();
+      Class<?> rangeClass = range.getJavaClass();
+      if (fi.getRangeImpl().isArray()) {
+        Parameter[] p = m.getParameters();
+        if (p.length == 1 && p[0].getType() == int.class) {
+          rangeClass = range.getComponentType().getJavaClass();
+        }
+      }
+      if (!returnClass.isAssignableFrom(rangeClass)) {
+        /** CAS type system type "{0}" defines field "{1}" with range "{2}", but JCas class has range "{3}". */
+        add2errors(errorSet, 
+                   new CASRuntimeException(CASRuntimeException.JCAS_TYPE_RANGE_MISMATCH, 
+                       ti.getName(), fi.getShortName(), rangeClass, returnClass),
+                   true);  // throw  
+      }
+    }
     
-      if (range.getJavaClass() == boolean.class) {
-        return isGetter ? (JCas_getter_boolean) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_boolean) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == byte.class) {
-        return isGetter ? (JCas_getter_byte) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_byte) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == short.class) {
-        return isGetter ? (JCas_getter_short) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_short) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == int.class) {
-        return isGetter ? (JCas_getter_int) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_int) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == long.class) {
-        return isGetter ? (JCas_getter_long) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_long) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == float.class) {
-        return isGetter ? (JCas_getter_float) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_float) callSite.getTarget().invokeExact();
-      } else if (range.getJavaClass() == double.class) {
-        return isGetter ? (JCas_getter_double) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_double) callSite.getTarget().invokeExact();
+    for (Field f : clazz.getDeclaredFields()) {
+      String fname = f.getName();
+      if (fname.length() <= 5 || !fname.startsWith("_FI_")) continue;
+      String featName = fname.substring(4);
+      FeatureImpl fi = ti.getFeatureByBaseName(featName);
+      if (fi == null) {
+        add2errors(errorSet, 
+                   new CASRuntimeException(CASRuntimeException.JCAS_FIELD_MISSING_IN_TYPE_SYSTEM, clazz.getName(), featName), 
+                   false);  // don't throw on this error, field is set to -1 and will throw if trying to use it        
       } else {
-        return isGetter ? (JCas_getter_generic<?>) callSite.getTarget().invokeExact() 
-                        : (JCas_setter_generic<?>) callSite.getTarget().invokeExact();
-      }
-    } catch (NoSuchMethodException e) {
-      if ((jcasClass == Sofa.class && !isGetter) ||
-          (jcasClass == AnnotationBase.class && !isGetter)) {
-        return null;
-      }  
-      // report missing setter or getter
-      /* Unable to find required {0} method for JCAS type {1} with {2} type of {3}. */
-      CASException casEx = new CASException(CASException.JCAS_GETTER_SETTER_MISSING, 
-          fi.getGetterSetterName(isGetter),
-          jcasClass.getName(),
-          isGetter ? "return" : "argument",
-          range.javaClass.getName()     
-          );
-      ArrayList<Exception> es = errorSet.get();
-      if (es == null) {
-        es = new ArrayList<Exception>();
-        errorSet.set(es);
+        int staticOffsetInClass = Misc.getStaticIntFieldNoInherit(clazz, fname);
+        if (fi.getAdjustedOffset() != staticOffsetInClass) {
+          /** In JCAS class "{0}", UIMA field "{1}" was set up at type system type adjusted offset "{2}" but 
+           * a different type system being used with the same JCas class has this offset at "{3}", which is not allowed. */
+          add2errors(errorSet, 
+                     new CASRuntimeException(CASRuntimeException.JCAS_FIELD_MISSING_IN_TYPE_SYSTEM,
+                        clazz.getName(), fi.getName(), staticOffsetInClass, fi.getAdjustedOffset()),
+                     staticOffsetInClass != -1);  // throw unless static offset is -1
+        }
       }
-      es.add(casEx);
-      return null;
-    } catch (Throwable e) {
-      throw new UIMARuntimeException(e, UIMARuntimeException.INTERNAL_ERROR);
     }
   }
- 
-  
-  Object getGenerator(int typecode) {
-    return jcasClassesInfo[typecode].generator;
-  }
-  
-  GetterSetter getGetterSetter(int typecode, String featShortName) {
-    return jcasClassesInfo[typecode].gettersAndSetters.get(featShortName);
-  }
   
-  Class<?> getJCasClass(int typecode) {
-    return jcasClassesInfo[typecode].jcasClass; 
-  }
-  
-  // static for setting up static builtin values
-  private static JCasClassInfo createJCasClassInfo(Class<?> jcasClass, TypeImpl ti) {
-    ti.setJavaClass(jcasClass);
-    JCasClassInfo jcasClassInfo = new JCasClassInfo(jcasClass, ti.getName().equals(CAS.TYPE_NAME_SOFA) ? null : createGenerator(jcasClass, ti));
-    
-    return jcasClassInfo;
+  static void add2errors(ThreadLocal<List<ErrorReport>> errors, Exception e) {
+    add2errors(errors, e, true);
   }
   
-  static boolean isFieldInClass(Feature feat, Class<?> clazz) {
-    try {
-      return null != clazz.getDeclaredField("_F_" + feat.getShortName());
-    } catch (NoSuchFieldException e) {
-      return false;
-    }    
+  static void add2errors(ThreadLocal<List<ErrorReport>> errors, Exception e, boolean doThrow) {
+    List<ErrorReport> es = errors.get();
+    if (es == null) {
+      es = new ArrayList<ErrorReport>();
+      errors.set(es);
+    }
+    es.add(new ErrorReport(e, doThrow));
   }
   
   static void reportErrors() {
-    ArrayList<Exception> es = errorSet.get();
+    boolean throwWhenDone = false;
+    List<ErrorReport> es = errorSet.get();
     if (es != null) {
       StringBuilder msg = new StringBuilder(100);
       msg.append('\n');
-      for (Exception f : es) {
-        msg.append(f.getMessage());
+      for (ErrorReport f : es) {
+        msg.append(f.e.getMessage());
+        throwWhenDone = throwWhenDone || f.doThrow;
         msg.append('\n');
       }
       errorSet.set(null); // reset after reporting
-      throw new CASRuntimeException(CASException.JCAS_INIT_ERROR, msg);
+      if (throwWhenDone) {
+        throw new CASRuntimeException(CASException.JCAS_INIT_ERROR, msg);
+      } else {
+        Logger logger = UIMAFramework.getLogger();
+        if (null == logger) {
+          throw new CASRuntimeException(CASException.JCAS_INIT_ERROR, msg);
+        } else {
+          logger.log(Level.WARNING, msg.toString());
+        }          
+      }
     }
-  }
-  
+  }  
 }
   
\ No newline at end of file

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java Mon Mar  7 21:50:08 2016
@@ -521,7 +521,7 @@ public class FSIndexRepositoryImpl imple
         for (int i = 0, nKeys = comp.getNumberOfKeys(); i < nKeys; i++) {
           if (comp.getKeyType(i) == FSIndexComparator.FEATURE_KEY) {
             FeatureImpl fi = comp.getKeyFeature(i);
-            cas.featureCodes_inIndexKeysAdd(fi.getCode(), fi.registryIndex);
+            cas.featureCodes_inIndexKeysAdd(fi.getCode()/*, fi.registryIndex*/);
           }
         }
       }
@@ -1643,14 +1643,8 @@ public class FSIndexRepositoryImpl imple
       if (fsx1 == fsx2) return 0;
       Annotation fs1 = (Annotation) fsx1;
       Annotation fs2 = (Annotation) fsx2;
-
-      int result =  Integer.compare(fs1.getBegin(), fs2.getBegin());
-      if (result != 0) return result;
-
-      result = Integer.compare(fs1.getEnd(), fs2.getEnd());
-      if (result != 0) return -result;  // reverse compare
-
-      return lto.compare(fs1, fs2);          
+      
+      return fs1.compareAnnotation(fs2, lto);
     };
   }
   
@@ -1665,14 +1659,7 @@ public class FSIndexRepositoryImpl imple
       final Annotation fs1 = (Annotation) fsx1;
       final Annotation fs2 = (Annotation) fsx2;
       
-      final int r1, r2, r3;
-      if ((r1 = Integer.compare(fs1.getBegin(), fs2.getBegin())) != 0) return r1;
-
-      if ((r2 = Integer.compare(fs1.getEnd(), fs2.getEnd())) != 0) return -r2;  // reverse compare
-      
-      if ((r3 = lto.compare(fs1, fs2)) != 0) return r3;
-
-      return Integer.compare(fs1._id,  fs2._id);
+      return fs1.compareAnnotationWithId(fs2, lto);
     };
     
     return this.sii.annotationFsComparatorWithId;

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureImpl.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureImpl.java Mon Mar  7 21:50:08 2016
@@ -42,7 +42,8 @@ public class FeatureImpl implements Feat
   private       int featureOffset = -1;  
   private       int adjustedFeatureOffset = -1; // the offset in the storage array for this feature, adjusted to exclude JCas implemented features; set at commit time
   
-                int registryIndex = -1; // set from JCas classes feature registry
+                // not used 2/29/16 to be removed
+//                int registryIndex = -1; // set from JCas classes feature registry
                                         // used to setup index corruption bitset                
           final boolean isInInt;        // specifies which array the data is in
 
@@ -59,8 +60,9 @@ public class FeatureImpl implements Feat
   public final boolean isAnnotBaseSofaRef;
   private final String shortName;     //         feat
     
-  protected Object jcasGetter;  // null or the functional interface to call to get this feature
-  protected Object jcasSetter;  // null or the functional interface to call to set this feature
+//  protected Object jcasGetter;  // null or the functional interface to call to get this feature
+//  protected Object jcasSetter;  // null or the functional interface to call to set this feature
+//  protected Object jcasSetterNcNj; // null or the functional interface to call to set this feature, no check for corruption, no journaling
     
   private final SlotKind slotKind;
   /** type class of the range, including CasSerializer List constants */
@@ -189,41 +191,35 @@ public class FeatureImpl implements Feat
     adjustedFeatureOffset = offset;
   }
 
-  /**
-   * @return the functionalGetter
-   */
-  Object getJCasGetter() {
-    return jcasGetter;
-  }
-
-  /**
-   * @param functionalGetter the functionalGetter to set
-   */
-  void setJCasGetter(Object functionalGetter) {
-    this.jcasGetter = functionalGetter;
-  }
-
-  /**
-   * @return the functionalSetter
-   */
-  Object getJCasSetter() {
-    return jcasSetter;
-  }
-
-  /**
-   * the setter is either a nonJCas or JCas style
-   * 
-   * NonJCas is equivalent to:
-   *   _casView.setWithCheckAndJournal(this, fi.getCode(), () -> _intData[fi.getAdjustedOffset()] = v);
-   *   
-   * JCas is equivalent to
-   *    (this) -> this.setXYZ(v)
-   *      
-   * @param functionalSetter the functionalSetter to set
-   */
-  void setJCasSetter(Object functionalSetter) {
-    this.jcasSetter = functionalSetter;
-  }
+//  /**
+//   * @return the functionalGetter
+//   */
+//  Object getJCasGetter() {
+//    return jcasGetter;
+//  }
+//
+//  /**
+//   * @param functionalGetter the functionalGetter to set
+//   */
+//  void setJCasGetter(Object functionalGetter) {
+//    this.jcasGetter = functionalGetter;
+//  }
+//
+//  /**
+//   * @return the functionalSetter
+//   */
+//  Object getJCasSetter() {
+//    return jcasSetter;
+//  }
+//  
+//  /**
+//   * @return the functional setter with no index corruption checking, no journalling
+//   */
+//  Object getJCasSetterNcNj() {
+//    return jcasSetterNcNj;
+//  }
+  
+  /* Set for these values done directly in TypeSystemImpl, computeAdjustedFeatureOffsets */
   
   TypeImpl getHighestDefiningType() {
     return highestDefiningType;

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FsIndex_singletype.java Mon Mar  7 21:50:08 2016
@@ -226,30 +226,30 @@ public abstract class FsIndex_singletype
       if (key instanceof FeatureImpl) {
         FeatureImpl fi = (FeatureImpl) key;
         if (fi.getRange() instanceof TypeImpl_string) { // string and string subtypes
-          result = Misc.compareStrings(fs1.getStringValueNc(fi), fs2.getStringValueNc(fi));
+          result = Misc.compareStrings(fs1._getStringValueNc(fi), fs2._getStringValueNc(fi));
         } else {
           switch (keyTypeCodes[i]) {
           case TypeSystemImpl.booleanTypeCode:
-            result = Integer.compare(fs1.getBooleanValueNc(fi) ? 1 : 0,
-                                     fs2.getBooleanValueNc(fi) ? 1 : 0);
+            result = Integer.compare(fs1._getBooleanValueNc(fi) ? 1 : 0,
+                                     fs2._getBooleanValueNc(fi) ? 1 : 0);
             break;
           case TypeSystemImpl.byteTypeCode:
-            result = Integer.compare(fs1.getByteValueNc(fi), fs2.getByteValueNc(fi));
+            result = Integer.compare(fs1._getByteValueNc(fi), fs2._getByteValueNc(fi));
             break;
           case TypeSystemImpl.shortTypeCode:
-            result = Integer.compare(fs1.getShortValueNc(fi), fs2.getShortValueNc(fi));
+            result = Integer.compare(fs1._getShortValueNc(fi), fs2._getShortValueNc(fi));
             break;
           case TypeSystemImpl.intTypeCode:
-            result = Integer.compare(fs1.getIntValueNc(fi), fs2.getIntValueNc(fi));
+            result = Integer.compare(fs1._getIntValueNc(fi), fs2._getIntValueNc(fi));
             break;
           case TypeSystemImpl.longTypeCode:
-            result = Long.compare(fs1.getLongValueNc(fi), fs2.getLongValueNc(fi));
+            result = Long.compare(fs1._getLongValueNc(fi), fs2._getLongValueNc(fi));
             break;
           case TypeSystemImpl.floatTypeCode:
-            result = Float.compare(fs1.getFloatValueNc(fi), fs2.getFloatValueNc(fi));
+            result = Float.compare(fs1._getFloatValueNc(fi), fs2._getFloatValueNc(fi));
             break;
           case TypeSystemImpl.doubleTypeCode:
-            result = Double.compare(fs1.getDoubleValueNc(fi), fs2.getDoubleValueNc(fi));
+            result = Double.compare(fs1._getDoubleValueNc(fi), fs2._getDoubleValueNc(fi));
             break;
             // next is compared above before the switch
 //          case TypeSystemImpl.stringTypeCode:

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/Id2FS.java Mon Mar  7 21:50:08 2016
@@ -21,6 +21,9 @@ package org.apache.uima.cas.impl;
 
 import java.lang.ref.WeakReference;
 import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
 import java.util.function.Consumer;
 
 import org.apache.uima.cas.CASRuntimeException;
@@ -34,9 +37,10 @@ import org.apache.uima.jcas.cas.TOP;
  * 
  * New additions always have increasing int keys.
  * 
- * Removes not supported; the weak refs allow garbage collection to reclaim the feature structure space.
+ * IN THIS IMPL, the id is the index into the array.
+ * IN THIS IMPL, Searching is by simple index lookup in an ArrayList
  * 
- * Searching is by simple index lookup in an ArrayList
+ * Removes not supported; the weak refs allow garbage collection to reclaim the feature structure space.
  * 
  * Alternative: a map based on sorted arrays, searched by binary search
  */
@@ -95,11 +99,40 @@ public class Id2FS {
    * @param action
    */
   void walkReachablePlusFSsSorted(Consumer<TOP> action) {
-    for (WeakReference<TOP> wr : id2fsw.subList(1, id2fsw.size())) {
+    walkReachablePlueFSsSorted(action, 1);
+  }
+  
+  /**
+   * walk a part of the id2fsw list; for delta, just the part above the line
+   * @param action
+   * @param items the part of the id2fsw list to walk
+   */
+  void walkReachablePlueFSsSorted(Consumer<TOP> action, int fromId) {
+//    int i;
+//    if (fromId == 1) {
+//      i = fromId;
+//    } else {
+//      TOP holdkey = TOP.createSearchKey(fromId); // hold to kep from getting GC'd
+//      WeakReference<TOP> key = new WeakReference<TOP>(holdkey);
+//      i = Collections.binarySearch(id2fsw, key, new Comparator<WeakReference<TOP>>() {
+//        @Override
+//        public int compare(WeakReference<TOP> o1, WeakReference<TOP> o2) {
+//          TOP k1 = o1.get();
+//          if (k1 == null) return -1;
+//          return k1.compareTo(holdkey);
+//        }
+//      });
+//      
+//      if (i < 0) {
+//        i = -(i + 1); // i is (-(insertion point) - 1) 
+//      }
+//    }
+    // in this impl, the id is the index.
+    for (WeakReference<TOP> wr : id2fsw.subList(fromId, id2fsw.size())) {
       TOP fs = wr.get();
       if (null != fs) {
         action.accept(fs);
       }
-    }
+    }   
   }
 }

Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LinearTypeOrderBuilderImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LinearTypeOrderBuilderImpl.java?rev=1733992&r1=1733991&r2=1733992&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LinearTypeOrderBuilderImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/LinearTypeOrderBuilderImpl.java Mon Mar  7 21:50:08 2016
@@ -111,8 +111,11 @@ public class LinearTypeOrderBuilderImpl
      */
     @Override
     public int compare(FeatureStructure fs1, FeatureStructure fs2) {
-      return Short.compare(this.typeCodeToOrder[fs1._getTypeCode()], 
-                           this.typeCodeToOrder[fs2._getTypeCode()]);
+      TypeImpl t1 = ((FeatureStructureImplC)fs1)._typeImpl;
+      TypeImpl t2 = ((FeatureStructureImplC)fs2)._typeImpl;
+      if (t1 == t2) return 0;
+      return Short.compare(this.typeCodeToOrder[t1.getCode()], 
+                           this.typeCodeToOrder[t2.getCode()]);
     }
 
     // Look-up.