You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2017/01/13 15:36:44 UTC

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

Author: schor
Date: Fri Jan 13 15:36:44 2017
New Revision: 1778615

URL: http://svn.apache.org/viewvc?rev=1778615&view=rev
Log:
[UIMA-5249][UIMA-5233] backwards compatibility: add back FSGenerator with signature suitable for v2, an interface, only for lessening compile errors.  Rename the v3 version of this FsGenerator3. add uima.enable_id_to_feature_structure_map_for_all_fs. add copy on write tracing incl index modifications. more validity checking for using addBack structures. Switch id2fs map to thread-safe jcasHashMap, update to new style API for that.

Modified:
    uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.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=1778615&r1=1778614&r2=1778615&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 Fri Jan 13 15:36:44 2017
@@ -128,7 +128,8 @@ public class CASImpl extends AbstractCas
   
   public static final boolean IS_USE_V2_IDS = false;  // if false, ids increment by 1
   private static final boolean trace = false; // debug
-  public static final boolean traceFSs = false;  // debug - trace FS creation and update  
+  public static final boolean traceFSs = false;  // debug - trace FS creation and update
+  public static final boolean traceCow = false;  // debug - trace copy on write actions, index adds / deletes 
   private static final String traceFile = "traceFSs.log.txt";
   private static final PrintStream traceOut;
   static {
@@ -216,6 +217,9 @@ public class CASImpl extends AbstractCas
       !IS_REPORT_FS_UPDATE_CORRUPTS_INDEX &&
       !IS_THROW_EXCEPTION_CORRUPT_INDEX;
  
+  public static final String ALWAYS_HOLD_ONTO_FSS = "uima.enable_id_to_feature_structure_map_for_all_fss";
+  static final boolean IS_ALWAYS_HOLD_ONTO_FSS =    // debug
+      Misc.getNoValueSystemProperty(ALWAYS_HOLD_ONTO_FSS);
 //  private static final int REF_DATA_FOR_ALLOC_SIZE = 1024;
 //  private static final int INT_DATA_FOR_ALLOC_SIZE = 1024;
 //  
@@ -373,14 +377,14 @@ public class CASImpl extends AbstractCas
      * Pear generators are mostly null except for instances where the PEAR has redefined
      * the JCas cover class
      */
-    private FsGenerator[] generators;
+    private FsGenerator3[] generators;
     /**
      * When generating a new instance of a FS in a PEAR where there's an alternate JCas class impl,
      * generate the base version, and make the alternate a trampoline to it.
      *   Note: in future, if it is known that this FS is never used outside of this PEAR, then can
      *         skip generating the double version
      */
-    private FsGenerator[] baseGenerators; 
+    private FsGenerator3[] baseGenerators; 
     
     // If this CAS can be flushed (reset) or not.
     // often, the framework disables this before calling users code
@@ -510,7 +514,8 @@ public class CASImpl extends AbstractCas
     private LongSet lllongSet = null;
     
     // For tracing FS creation and updating, normally disabled
-    private final  StringBuilder traceFScreationSb = traceFSs ? new StringBuilder() : null;
+    private final StringBuilder traceFScreationSb = traceFSs ? new StringBuilder() : null;
+    private final StringBuilder traceCowSb = traceCow ? new StringBuilder() : null;
     private int traceFSid = 0; 
     private boolean traceFSisCreate;
     private final IntVector id2addr = traceFSs ? new IntVector() : null;
@@ -736,7 +741,9 @@ public class CASImpl extends AbstractCas
    * not in SharedViewData to reduce object traversal when
    * generating FSs
    */
-  FeatureStructureImplC pearBaseFs = null;  
+  FeatureStructureImplC pearBaseFs = null;
+  
+//  private StackTraceElement[] addbackSingleTrace = null;  // for debug use only, normally commented out  
 
   // CASImpl(TypeSystemImpl typeSystem) {
   // this(typeSystem, DEFAULT_INITIAL_HEAP_SIZE);
@@ -908,11 +915,21 @@ public class CASImpl extends AbstractCas
     }
     svd.fsTobeAddedbackSingleInUse = false;
   }
-    
+   
+  private FSsTobeAddedback getAddback(int size) {
+    if (svd.fsTobeAddedbackSingleInUse) {
+      Misc.internalError();
+    }
+    return svd.fssTobeAddedback.get(size - 1);
+  }
+  
   FSsTobeAddedbackSingle getAddbackSingle() {
     if (svd.fsTobeAddedbackSingleInUse) {
-      throw new RuntimeException(); // internal error
+//      System.out.println(Misc.dumpCallers(addbackSingleTrace, 2, 100));
+      Misc.internalError();
     }
+//    addbackSingleTrace = Thread.currentThread().getStackTrace();
+    
     svd.fsTobeAddedbackSingleInUse = true;
     svd.fsTobeAddedbackSingle.clear();  // safety
     return svd.fsTobeAddedbackSingle;
@@ -990,12 +1007,12 @@ public class CASImpl extends AbstractCas
                      // to insure sofa precedes the ref of it
     }
 
-    FsGenerator g = svd.generators[ti.getCode()];  // get generator or null
-    if (g != null) {
-      return (T) g.createFS(ti, this);
-    } else { // pear case, with no overriding pear - use base
-      return (T) createFsFromGenerator(svd.baseGenerators, ti);
-    }
+    FsGenerator3 g = svd.generators[ti.getCode()];  // get generator or null
+    
+    return (g != null) 
+             ? (T) g.createFS(ti, this)
+              // pear case, with no overriding pear - use base    
+             : (T) createFsFromGenerator(svd.baseGenerators, ti);
 
 //    
 //    
@@ -1022,7 +1039,7 @@ public class CASImpl extends AbstractCas
    */
   boolean maybeMakeBaseVersionForPear(FeatureStructureImplC fs, TypeImpl ti) {
     if (!inPearContext()) return false;
-    FsGenerator g = svd.generators[ti.getCode()];  // get pear generator or null
+    FsGenerator3 g = svd.generators[ti.getCode()];  // get pear generator or null
     if (g == null) return false;
     TOP baseFs;
     try {
@@ -1038,7 +1055,7 @@ public class CASImpl extends AbstractCas
     return true;
   }
  
-  private TOP createFsFromGenerator(FsGenerator[] gs, TypeImpl ti) {
+  private TOP createFsFromGenerator(FsGenerator3[] gs, TypeImpl ti) {
 //    if (ti == null || gs == null || gs[ti.getCode()] == null) {
 //      System.out.println("debug");
 //    }
@@ -1802,6 +1819,7 @@ public class CASImpl extends AbstractCas
       if (wasRemoved) {
         maybeAddback(fs);
       }
+      
     } else {
       fs._setLongValueNcNj(feat, v);
     }
@@ -2371,7 +2389,11 @@ public class CASImpl extends AbstractCas
     }
     TOP fs = (TOP) createFS(ti);
     if (!fs._isPearTrampoline()) {
-      svd.id2fs.put(fs);  // hold on to it if nothing else is
+      if (IS_ALWAYS_HOLD_ONTO_FSS) {
+        svd.id2fs.putUnconditionally(fs);  // hold on to it if nothing else is
+      } else {
+        svd.id2fs.put(fs);
+      }
     }
     return fs._id;
   }
@@ -2403,7 +2425,11 @@ public class CASImpl extends AbstractCas
   @Override
   public int ll_createArray(int typeCode, int arrayLength) {
     TOP fs = createArray(getTypeFromCode_checked(typeCode), arrayLength);
-    svd.id2fs.put(fs);
+    if (IS_ALWAYS_HOLD_ONTO_FSS) {
+      svd.id2fs.putUnconditionally(fs);
+    } else {
+      svd.id2fs.put(fs);
+    }
     return fs._id;      
   }
 
@@ -2518,6 +2544,7 @@ public class CASImpl extends AbstractCas
     if (fst._isPearTrampoline()) {
       return fst._id;  // no need to hold on to this one - it's in jcas hash maps
     }
+    // uncond. because this method can be called multiple times
     svd.id2fs.putUnconditionally(fst);  // hold on to it
     return ((FeatureStructureImplC)fs)._id;
   }
@@ -2750,11 +2777,15 @@ public class CASImpl extends AbstractCas
     final int ssz = svd.fssTobeAddedback.size();
 
     // next method skips if the fsRef is not in the index (cache)
-    return removeFromCorruptableIndexAnyView(
+    boolean wasRemoved = removeFromCorruptableIndexAnyView(
         fs, 
-        (ssz > 0) ? svd.fssTobeAddedback.get(ssz - 1) : 
+        (ssz > 0) ? getAddback(ssz) :   // validates single not in use
                     getAddbackSingle()  // validates single usage at a time
-        );            
+        );
+    if (!wasRemoved && svd.fsTobeAddedbackSingleInUse) {
+      svd.fsTobeAddedbackSingleInUse = false;
+    }
+    return wasRemoved;
   }
 
 //  public FeatureImpl getFeatFromRegistry(int jcasFieldRegistryIndex) {
@@ -2849,7 +2880,7 @@ public class CASImpl extends AbstractCas
                                   (FSIndexRepositoryImpl) fs._casView.getIndexRepository(), 
                                   toBeAdded, 
                                   isSkipBagIndexes);
-      fs._resetInSetSortedIndex();
+      fs._resetInSetSortedIndex(); 
       return r;
     }
     
@@ -4534,7 +4565,11 @@ public class CASImpl extends AbstractCas
    */
   public void setId2FSs(FeatureStructure ... fss) {
     for (FeatureStructure fs : fss) {
-      svd.id2fs.put((TOP)fs);
+      if (IS_ALWAYS_HOLD_ONTO_FSS) {
+        svd.id2fs.putUnconditionally((TOP)fs);
+      } else {
+        svd.id2fs.put((TOP)fs);
+      }
     }
   }
   
@@ -4829,7 +4864,7 @@ public class CASImpl extends AbstractCas
     final TOP fs = (TOP) aFs;
     final CASImpl view = fs._casView;
     final TypeImpl ti = fs._getTypeImpl();
-    final FsGenerator generator = view.svd.generators[ti.getCode()];
+    final FsGenerator3 generator = view.svd.generators[ti.getCode()];
     if (null == generator) {
       return aFs;
     }
@@ -4845,30 +4880,29 @@ public class CASImpl extends AbstractCas
    * @param g
    * @return
    */
-  private TOP pearConvert(TOP fs, FsGenerator g) {
-    TOP r = svd.id2tramp.getReserve(fs._id);
-    if (r != null) {
+  private TOP pearConvert(TOP fs, FsGenerator3 g) {
+    return svd.id2tramp.putIfAbsent(fs._id, k -> {
+
+      svd.reuseId = k;  // create new FS using base FS's ID
+      pearBaseFs = fs;
+      TOP r;
+      // createFS below is modified because of pearBaseFs non-null to 
+      // "share" the int and data arrays
+      try {
+        r = g.createFS(fs._getTypeImpl(), this);
+      } finally {
+        svd.reuseId = 0;
+        pearBaseFs = null;
+      }
+      assert r != null;
+      if (r instanceof UimaSerializable) {
+        throw new UnsupportedOperationException(
+            "Pears with Alternate implementations of JCas classes implementing UimaSerializable not supported.");
+//        ((UimaSerializable) fs)._save_to_cas_data();  // updates in r too
+//        ((UimaSerializable) r)._init_from_cas_data();
+      }
       return r;
-    }
-    
-    svd.reuseId = fs._id;  // create new FS using base FS's ID
-    pearBaseFs = fs;
-    // createFS below is modified because of pearBasFs non-null to 
-    // "share" the int and data arrays
-    try {
-      r = g.createFS(fs._getTypeImpl(), this);
-    } finally {
-      svd.reuseId = 0;
-      pearBaseFs = null;
-    }
-    if (r instanceof UimaSerializable) {
-      throw new UnsupportedOperationException(
-          "Pears with Alternate implementations of JCas classes implementing UimaSerializable not supported.");
-//      ((UimaSerializable) fs)._save_to_cas_data();  // updates in r too
-//      ((UimaSerializable) r)._init_from_cas_data();
-    }
-    svd.id2tramp.put(r);
-    return r;
+    });
   }
   
   /**
@@ -4878,7 +4912,7 @@ public class CASImpl extends AbstractCas
    * @return the corresponding base fs
    */
   <T extends TOP> T getBaseFsFromTrampoline(T fs) {
-    TOP r = svd.id2base.getReserve(fs._id);
+    TOP r = svd.id2base.get(fs._id);
     assert r != null;
     return (T) r;
   }
@@ -4892,7 +4926,14 @@ public class CASImpl extends AbstractCas
     if (b.length() > 0) {
       traceFSflush();
     }
-    
+    // normally commented-out for matching with v2
+//    // mark annotations created by subiterator
+//    if (fs._getTypeCode() == TypeSystemConstants.annotTypeCode) {
+//      StackTraceElement[] stktr = Thread.currentThread().getStackTrace();
+//      if (stktr.length > 7 && stktr[6].getClassName().equals("org.apache.uima.cas.impl.Subiterator")) {
+//        b.append('*');
+//      }
+//    }
     svd.id2addr.add(svd.nextId2Addr);
     svd.nextId2Addr += fs._getTypeImpl().getFsSpaceReq((TOP)fs);
     traceFSfs(fs);
@@ -4915,6 +4956,50 @@ public class CASImpl extends AbstractCas
     b.append(" t:").append(Misc.elide(fs._getTypeImpl().getShortName(), 10));    
   }
   
+  void traceIndexMod(boolean isAdd, TOP fs, boolean isAddbackOrSkipBag) {
+    StringBuilder b = svd.traceCowSb;
+    b.setLength(0);
+    b.append(isAdd ? (isAddbackOrSkipBag ? "abk_idx " : "add_idx ")
+                   : (isAddbackOrSkipBag ? "rmv_auto_idx " : "rmv_norm_idx "));
+//    b.append(fs.toString());
+    b.append(fs._getTypeImpl().getShortName()).append(":").append(fs._id);
+    if (fs instanceof Annotation) {
+      Annotation ann = (Annotation) fs;
+      b.append(" begin: ").append(ann.getBegin());
+      b.append(" end: ").append(ann.getEnd());
+      b.append(" txt: \"").append(Misc.elide(ann.getCoveredText(), 10)).append("\"");
+    }
+    traceOut.println(b);         
+  }
+  
+  void traceCowCopy(FsIndex_singletype<?> index) {
+    StringBuilder b = svd.traceCowSb;
+    b.setLength(0);
+    b.append("cow-copy:");
+    b.append(" i: ").append(index);
+    traceOut.println(b);
+  }
+  
+  void traceCowCopyUse(FsIndex_singletype<?> index) {
+    StringBuilder b = svd.traceCowSb;
+    b.setLength(0);
+    b.append("cow-copy-used:");
+    b.append(" i: ").append(index);
+    traceOut.println(b);
+  }
+
+
+  void traceCowReinit(String kind, FsIndex_singletype<?> index) { 
+    StringBuilder b = svd.traceCowSb;
+    b.setLength(0);
+    b.append("cow-redo: ");
+    b.append(kind);
+    b.append(" i: ").append(index);
+    b.append(" c: ");
+    b.append(Misc.getCaller());
+    traceOut.println(b);
+  }
+
   /** only used for tracing, enables tracing 2 slots for long/double */
   private FeatureImpl prevFi;
   
@@ -5239,6 +5324,11 @@ public class CASImpl extends AbstractCas
     return svd.bcsd.reinit(istream);
   }
   
+  void maybeHoldOntoFS(FeatureStructureImplC fs) {
+    if (IS_ALWAYS_HOLD_ONTO_FSS) {
+      svd.id2fs.putUnconditionally((TOP)fs);
+    }
+  }
   
 //  int allocIntData(int sz) {
 //