You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2015/10/31 23:38:36 UTC
svn commit: r1711700 [2/2] -
/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=1711700&r1=1711699&r2=1711700&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 Sat Oct 31 22:38:36 2015
@@ -20,21 +20,14 @@
package org.apache.uima.cas.impl;
import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.io.StringWriter;
-import java.net.MalformedURLException;
+import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.nio.ByteBuffer;
-import java.nio.DoubleBuffer;
-import java.nio.FloatBuffer;
-import java.nio.IntBuffer;
-import java.nio.LongBuffer;
-import java.nio.ShortBuffer;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
@@ -43,6 +36,7 @@ import java.util.ListIterator;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
+import java.util.function.Consumer;
import org.apache.uima.UIMAFramework;
import org.apache.uima.UIMARuntimeException;
@@ -54,6 +48,7 @@ import org.apache.uima.cas.CAS;
import org.apache.uima.cas.CASException;
import org.apache.uima.cas.CASRuntimeException;
import org.apache.uima.cas.CasOwner;
+import org.apache.uima.cas.CommonArrayFS;
import org.apache.uima.cas.ComponentInfo;
import org.apache.uima.cas.ConstraintFactory;
import org.apache.uima.cas.DoubleArrayFS;
@@ -69,7 +64,6 @@ import org.apache.uima.cas.FloatArrayFS;
import org.apache.uima.cas.IntArrayFS;
import org.apache.uima.cas.LongArrayFS;
import org.apache.uima.cas.Marker;
-import org.apache.uima.cas.SerialFormat;
import org.apache.uima.cas.ShortArrayFS;
import org.apache.uima.cas.SofaFS;
import org.apache.uima.cas.SofaID;
@@ -77,7 +71,6 @@ import org.apache.uima.cas.StringArrayFS
import org.apache.uima.cas.Type;
import org.apache.uima.cas.TypeSystem;
import org.apache.uima.cas.admin.CASAdminException;
-import org.apache.uima.cas.admin.CASFactory;
import org.apache.uima.cas.admin.CASMgr;
import org.apache.uima.cas.admin.FSIndexComparator;
import org.apache.uima.cas.admin.FSIndexRepositoryMgr;
@@ -86,11 +79,25 @@ import org.apache.uima.cas.impl.FSsTobeA
import org.apache.uima.cas.text.AnnotationFS;
import org.apache.uima.cas.text.AnnotationIndex;
import org.apache.uima.cas.text.Language;
-import org.apache.uima.internal.util.IntVector;
+import org.apache.uima.internal.util.PositiveIntSet;
import org.apache.uima.internal.util.PositiveIntSet_impl;
import org.apache.uima.jcas.JCas;
+import org.apache.uima.jcas.cas.AnnotationBase;
+import org.apache.uima.jcas.cas.BooleanArray;
+import org.apache.uima.jcas.cas.ByteArray;
+import org.apache.uima.jcas.cas.CommonArray;
+import org.apache.uima.jcas.cas.DoubleArray;
+import org.apache.uima.jcas.cas.FSArray;
+import org.apache.uima.jcas.cas.FloatArray;
+import org.apache.uima.jcas.cas.IntegerArray;
+import org.apache.uima.jcas.cas.JavaObjectArray;
+import org.apache.uima.jcas.cas.LongArray;
+import org.apache.uima.jcas.cas.ShortArray;
+import org.apache.uima.jcas.cas.Sofa;
+import org.apache.uima.jcas.cas.StringArray;
+import org.apache.uima.jcas.cas.TOP;
import org.apache.uima.jcas.impl.JCasImpl;
-import org.apache.uima.resource.ResourceInitializationException;
+import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.util.Level;
import org.apache.uima.util.Misc;
@@ -122,15 +129,6 @@ public class CASImpl extends AbstractCas
public static final int FALSE = 0;
- private static final int[] INT0 = new int[0];
-
- public static final int DEFAULT_INITIAL_HEAP_SIZE = 500000;
-
- public static final int DEFAULT_RESET_HEAP_SIZE = 5000000;
-// no longer used 3/2015
-// private static final int resetHeapSize = DEFAULT_RESET_HEAP_SIZE;
-
-
/**
* The UIMA framework detects (unless disabled, for high performance) updates to indexed FS which update
* key values used as keys in indexes. Normally the framework will protect against index corruption by
@@ -178,21 +176,7 @@ public class CASImpl extends AbstractCas
Misc.getNoValueSystemProperty(DISABLE_PROTECT_INDEXES) &&
!IS_REPORT_FS_UPDATE_CORRUPTS_INDEX &&
!IS_THROW_EXCEPTION_CORRUPT_INDEX;
-
- // The offset for the array length cell. An array consists of length+2
- // number
- // of cells, where the first cell contains the type, the second one the
- // length,
- // and the rest the actual content of the array.
- private static final int arrayLengthFeatOffset = 1;
-
- // The number of cells we need to skip to get to the array contents. That
- // is,
- // if we have an array starting at addr, the first cell is at
- // addr+arrayContentOffset.
- private static final int arrayContentOffset = 2;
-
- private static final boolean DEFAULT_USE_FS_CACHE = false;
+
// this next seemingly non-sensical static block
// is to force the classes needed by Eclipse debugging to load
@@ -203,33 +187,74 @@ public class CASImpl extends AbstractCas
new DebugFSLogicalStructure();
}
- private static enum ModifiedHeap { FSHEAP, BYTEHEAP, SHORTHEAP, LONGHEAP };
// Static classes representing shared instance data
// - shared data is computed once for all views
+
+ /**
+ * Journaling changes for computing delta cas.
+ * Each instance represents one or more changes for one feature structure
+ * A particular Feature Structure may have multiple FsChange instances
+ * but we attempt to minimize this
+ */
+ private static class FsChange {
+ /** ref to the FS being modified */
+ final FeatureStructureImplC fs;
+ /**
+ * which feature (by offset) is modified
+ */
+ final boolean[] intData;
+ /**
+ * which feature (by offset) is modified
+ */
+ final boolean[] refData;
+
+
+ final PositiveIntSet arrayUpdates;
+ FsChange(FeatureStructureImplC fs) {
+ this.fs = fs;
+ TypeImpl ti = fs._typeImpl;
+ intData = (ti.highestIntOffset == 0) ? null : new boolean[ti.highestIntOffset];
+ refData = (ti.highestRefOffset == 0) ? null : new boolean[ti.highestRefOffset];
+ arrayUpdates = (ti.isArray()) ? new PositiveIntSet_impl() : null;
+ }
+
+ void addIntData(int v) {
+ intData[v] = true;
+ }
+
+ void addRefData(int v) {
+ refData[v] = true;
+ }
+
+ void addArrayData(int v, int nbrOfConsecutive) {
+ for (int i = 0; i < nbrOfConsecutive; i++) {
+ arrayUpdates.add(v++);
+ }
+ }
+ }
+
// fields shared among all CASes belong to views of a common base CAS
private static class SharedViewData {
-
- final private Heap heap;
+ /**
+ * map from FS ids to FSs.
+ */
+ final private Id2FS id2fs = new Id2FS();
// private SymbolTable stringTable;
// private ArrayList stringList;
- final private StringHeap stringHeap = new StringHeap();
+// final private StringHeap stringHeap = new StringHeap();
- final private ByteHeap byteHeap = new ByteHeap(); // for storing 8 bit values
+// final private ByteHeap byteHeap = new ByteHeap(); // for storing 8 bit values
- final private ShortHeap shortHeap = new ShortHeap(); // for storing 16 bit values
+// final private ShortHeap shortHeap = new ShortHeap(); // for storing 16 bit values
- final private LongHeap longHeap = new LongHeap(); // for storing 64 bit values
-
- // for efficiency in accessing the begin and end offsets of annotations
- private int annotFeatOffset_begin;
- private int annotFeatOffset_end;
+// final private LongHeap longHeap = new LongHeap(); // for storing 64 bit values
// Base CAS for all views
final private CASImpl baseCAS;
- private int cache_not_in_index = 0; // a one item cache of a FS not in the index
+ private FeatureStructure cache_not_in_index = null; // a one item cache of a FS guaranteed to not be in any index
private final PositiveIntSet_impl featureCodesInIndexKeys = new PositiveIntSet_impl();
@@ -243,7 +268,9 @@ public class CASImpl extends AbstractCas
// private Map<Integer, CAS> sofaNbr2ViewMap;
private ArrayList<CAS> sofaNbr2ViewMap;
- // set of instantiated sofaNames
+ /**
+ * a set of instantiated sofaNames
+ */
private Set<String> sofaNameSet;
// Flag that initial Sofa has been created
@@ -264,28 +291,10 @@ public class CASImpl extends AbstractCas
// often, the framework disables this before calling users code
private boolean flushEnabled = true;
- // controls whether Java cover objects for CAS objects,
- // including JCas objects,
- // are cached and reused.
- // If set true, don't also cache the JCas ones - this will
- // duplicate the space with no benefit
- private final boolean useFSCache;
-
- // this is the actual cache. It is simply an array of the same size
- // as the heap, with the CAS object's addr slot filled with
- // a (strong) ref to the Java object.
- // This is a trade off verses using hash tables
-
- // The actual cache.
- // TODO implement the resizing algorithm used for the main heap, here too.
- private FeatureStructure[] fsArray;
-
// not final because set with reinit deserialization
- private CASMetadata casMetadata;
+ private TypeSystemImpl tsi;
private ComponentInfo componentInfo;
-
- private FSGenerator<? extends FeatureStructure>[] localFsGenerators;
/**
* This tracks the changes for delta cas
@@ -297,19 +306,20 @@ public class CASImpl extends AbstractCas
* Cas, to support switching from one tracking marker to
* another (currently not used, but designed to support
* Component Journaling).
+ *
+ * We track changes on a granularity of features
+ * and for features which are arrays, which element of the array
+ * (This last to enable efficient delta serializations of
+ * giant arrays of things, where you've only updated a few items)
+ *
+ * The FsChange doesn't store the changed data, only stores the
+ * ref info needed to get to what was changed.
*/
private MarkerImpl trackingMark;
+
- private IntVector modifiedPreexistingFSs;
-
- private IntVector modifiedFSHeapCells;
-
- private IntVector modifiedByteHeapCells;
-
- private IntVector modifiedShortHeapCells;
-
- private IntVector modifiedLongHeapCells;
-
+ private List<FsChange> modifiedPreexistingFSs;
+
/**
* This list currently only contains at most 1 element.
* If Journaling is implemented, it may contain an
@@ -332,16 +342,17 @@ public class CASImpl extends AbstractCas
*/
private boolean fsTobeAddedbackSingleInUse = false;
+ // used to generate FSIDs, increments by 1 for each use. First id == 1
+ private AtomicInteger fsIdGenerator = new AtomicInteger(0);
+
+ // mostly for debug - counts # times cas is reset
private final AtomicInteger casResets = new AtomicInteger(0);
- private final int casId;
+ // unique ID for a created CAS view, not updated if CAS is reset and reused
+ private final int casId = casIdProvider.incrementAndGet();
- private SharedViewData(boolean useFSCache, Heap heap, CASImpl baseCAS, CASMetadata casMetadata) {
- this.useFSCache = useFSCache;
- this.heap = heap;
+ private SharedViewData(CASImpl baseCAS) {
this.baseCAS = baseCAS;
- this.casMetadata = casMetadata;
- casId = casIdProvider.incrementAndGet();
}
}
@@ -352,8 +363,11 @@ public class CASImpl extends AbstractCas
// package protected to let other things share this info
final SharedViewData svd; // shared view data
- void addbackSingle(int fsAddr) {
- svd.fsTobeAddedbackSingle.addback(fsAddr);
+ // ----------------------------------------
+ // accessors for data in SharedViewData
+ // ----------------------------------------
+ void addbackSingle(FeatureStructureImplC fs) {
+ svd.fsTobeAddedbackSingle.addback(fs);
svd.fsTobeAddedbackSingleInUse = false;
}
@@ -373,9 +387,9 @@ public class CASImpl extends AbstractCas
svd.featureCodesInIndexKeys.add(featCode);
}
- void maybeClearCacheNotInIndex(int fsAddr) {
- if (svd.cache_not_in_index == fsAddr) {
- svd.cache_not_in_index = 0;
+ void maybeClearCacheNotInIndex(FeatureStructure fs) {
+ if (svd.cache_not_in_index == fs) {
+ svd.cache_not_in_index = null;
}
}
@@ -386,8 +400,8 @@ public class CASImpl extends AbstractCas
* Internal use only
* @param fsAddr the address of the feature structure
*/
- public void setCacheNotInIndex(int fsAddr) {
- svd.cache_not_in_index = fsAddr;
+ public void setCacheNotInIndex(FeatureStructure fs) {
+ svd.cache_not_in_index = fs;
}
// The index repository. Referenced by XmiCasSerializer
@@ -396,28 +410,24 @@ public class CASImpl extends AbstractCas
// the sofaFS this view is based on
// SofaFS mySofa;
/**
- * The heap address of the sofa FS for this view, or
- * -1 if the sofa FS is for the initial view, or
- * 0 if there is no sofa FS - for instance, in the "base cas"
+ * The Feature Structure for the sofa FS for this view, or
+ * null
+ * //-1 if the sofa FS is for the initial view, or
+ * // 0 if there is no sofa FS - for instance, in the "base cas"
*/
- private int mySofaRef = 0;
+ private Sofa mySofaRef = null;
private JCas jcas = null;
-
- private final boolean isUsedJcasCache;
-
- private final ArrayList<String> getStringList() {
- ArrayList<String> stringList = new ArrayList<String>();
- stringList.add(null);
- int pos = this.getStringHeap().getLeastStringCode();
- final int end = this.getStringHeap().getLargestStringCode();
- while (pos <= end) {
- stringList.add(this.getStringHeap().getStringForCode(pos));
- ++pos;
- }
- return stringList;
- }
+ /**
+ * Copies of frequently accessed data pulled up for
+ * locality of reference - only an optimization
+ * - each value needs to be reset appropriately
+ * - getters check for null, and if null, do the get.
+ */
+
+ private TypeSystemImpl tsi;
+
/*
* (non-Javadoc)
*
@@ -425,13 +435,6 @@ public class CASImpl extends AbstractCas
* Internal use Never called Kept because it's in the interface.
*/
public void setCAS(CAS cas) {
-
- // this.indexRepository = ((CASImpl)cas).indexRepository; // only for test
- // case, others override later
- // this.svd.casMetadata.fsClassRegistry = casImpl.fsClassReg;
-
- // initTypeCodeVars();
- // this.jcas = in.jcas;
}
// CASImpl(TypeSystemImpl typeSystem) {
@@ -446,10 +449,6 @@ public class CASImpl extends AbstractCas
// initTypeVariables();
// }
- public CASImpl(TypeSystemImpl typeSystem, int initialHeapSize, boolean useJcasCache) {
- this(typeSystem, initialHeapSize, DEFAULT_USE_FS_CACHE, useJcasCache);
- }
-
/*
* Configure a new (base view) CASImpl, **not a new view** typeSystem can be
* null, in which case a new instance of TypeSystemImpl is set up, but not
@@ -458,9 +457,8 @@ public class CASImpl extends AbstractCas
* by calling
*/
- CASImpl(TypeSystemImpl typeSystem, int initialHeapSize, boolean useFSCache, boolean useJcasCache) {
+ public CASImpl(TypeSystemImpl typeSystem) {
super();
- this.isUsedJcasCache = useJcasCache;
TypeSystemImpl ts;
final boolean externalTypeSystem = (typeSystem != null);
@@ -471,7 +469,7 @@ public class CASImpl extends AbstractCas
// FSClassRegistry instances
}
- this.svd = new SharedViewData(useFSCache, new Heap(initialHeapSize), this, ts.casMetadata);
+ this.svd = new SharedViewData(this);
// this.svd.baseCAS = this;
// this.svd.heap = new Heap(initialHeapSize);
@@ -479,7 +477,7 @@ public class CASImpl extends AbstractCas
if (externalTypeSystem) {
commitTypeSystem();
}
-
+
this.svd.sofa2indexMap = new HashMap<Integer, FSIndexRepository>();
this.svd.sofaNbr2ViewMap = new ArrayList<CAS>();
this.svd.sofaNameSet = new HashSet<String>();
@@ -489,22 +487,14 @@ public class CASImpl extends AbstractCas
clearTrackingMarks();
}
- /**
- * Constructor. Use only if you want to use the low-level APIs.
- */
public CASImpl() {
- this(DEFAULT_INITIAL_HEAP_SIZE, CASFactory.USE_JCAS_CACHE_DEFAULT);
- }
-
- public CASImpl(int initialHeapSize, boolean useJcasCache) {
- this((TypeSystemImpl) null, initialHeapSize, useJcasCache);
+ this((TypeSystemImpl) null);
}
// In May 2007, appears to have 1 caller, createCASMgr in Serialization class,
- // could have
- // out-side the framework callers because it is public.
+ // could have out-side the framework callers because it is public.
public CASImpl(CASMgrSerializer ser) {
- this(ser.getTypeSystem(), DEFAULT_INITIAL_HEAP_SIZE, CASFactory.USE_JCAS_CACHE_DEFAULT);
+ this(ser.getTypeSystem());
checkInternalCodes(ser);
// assert(ts != null);
// assert(getTypeSystem() != null);
@@ -512,34 +502,27 @@ public class CASImpl extends AbstractCas
}
// Use this when creating a CAS view
- CASImpl(CASImpl cas, SofaFS aSofa, boolean useJcasCache) {
- this.isUsedJcasCache = useJcasCache;
+ CASImpl(CASImpl cas, SofaFS aSofa) {
// these next fields are final and must be set in the constructor
this.svd = cas.svd;
- // this.mySofa = aSofa;
- if (aSofa != null) {
- // save address of SofaFS
- this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
- } else {
- // this is the InitialView
- this.mySofaRef = -1;
- }
+ this.mySofaRef = (Sofa) aSofa;
// get the indexRepository for this Sofa
- this.indexRepository = (this.mySofaRef == -1) ?
+ this.indexRepository = (this.mySofaRef == null) ?
(FSIndexRepositoryImpl) cas.getSofaIndexRepository(1) :
(FSIndexRepositoryImpl) cas.getSofaIndexRepository(aSofa);
if (null == this.indexRepository) {
// create the indexRepository for this CAS
// use the baseIR to create a lightweight IR copy
- this.indexRepository = new FSIndexRepositoryImpl(
- this,
- (FSIndexRepositoryImpl) cas.getBaseIndexRepository());
+ FSIndexRepositoryImpl baseIndexRepo = (FSIndexRepositoryImpl) cas.getBaseIndexRepository();
+ this.indexRepository = new FSIndexRepositoryImpl(this, baseIndexRepo);
+ // the index creation depends on "indexRepository" already being set
+ baseIndexRepo.name2indexMap.keySet().stream().forEach(key -> this.indexRepository.createIndex(baseIndexRepo, key));
this.indexRepository.commit();
// save new sofa index
- if (this.mySofaRef == -1) {
+ if (this.mySofaRef == null) {
cas.setSofaIndexRepository(1, this.indexRepository);
} else {
cas.setSofaIndexRepository(aSofa, this.indexRepository);
@@ -552,21 +535,24 @@ public class CASImpl extends AbstractCas
if (aSofa != null) {
// save address of SofaFS
- this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
+ this.mySofaRef = (Sofa) aSofa;
} else {
// this is the InitialView
- this.mySofaRef = -1;
+ this.mySofaRef = null;
}
// toss the JCas, if it exists
this.jcas = null;
// create the indexRepository for this Sofa
- this.indexRepository = new FSIndexRepositoryImpl(this, (FSIndexRepositoryImpl) ((CASImpl) cas)
- .getBaseIndexRepository());
+ final FSIndexRepositoryImpl baseIndexRepo = (FSIndexRepositoryImpl) ((CASImpl) cas).getBaseIndexRepository();
+ this.indexRepository = new FSIndexRepositoryImpl(this,baseIndexRepo);
+ // the index creation depends on "indexRepository" already being set
+ baseIndexRepo.name2indexMap.keySet().stream().forEach(key -> this.indexRepository.createIndex(baseIndexRepo, key));
+
this.indexRepository.commit();
// save new sofa index
- if (this.mySofaRef == -1) {
+ if (this.mySofaRef == null) {
((CASImpl) cas).setSofaIndexRepository(1, this.indexRepository);
} else {
((CASImpl) cas).setSofaIndexRepository(aSofa, this.indexRepository);
@@ -575,17 +561,20 @@ public class CASImpl extends AbstractCas
private void checkInternalCodes(CASMgrSerializer ser) throws CASAdminException {
if ((ser.topTypeCode > 0)
- && (ser.topTypeCode != ((TypeImpl) this.svd.casMetadata.ts.getTopType()).getCode())) {
+ && (ser.topTypeCode != ((TypeImpl) getTypeSystemImpl().getTopType()).getCode())) {
throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
}
if (ser.featureOffsets == null) {
return;
}
- if (ser.featureOffsets.length != this.svd.casMetadata.featureOffset.length) {
- throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
- }
+// if (ser.featureOffsets.length != this.svd.casMetadata.featureOffset.length) {
+// throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
+// }
+ TypeSystemImpl tsi = getTypeSystemImpl();
for (int i = 1; i < ser.featureOffsets.length; i++) {
- if (ser.featureOffsets[i] != this.svd.casMetadata.featureOffset[i]) {
+ FeatureImpl fi = (FeatureImpl) tsi.getFeatureForCode_checked(i);
+ int adjOffset = fi.isInInt ? 0 : fi.getRangeImpl().nbrOfUsedIntDataSlots;
+ if (ser.featureOffsets[i] != (fi.getOffset() + adjOffset)) {
throw new CASAdminException(CASAdminException.DESERIALIZATION_ERROR);
}
}
@@ -596,79 +585,85 @@ public class CASImpl extends AbstractCas
}
public TypeSystem getTypeSystem() {
- final TypeSystemImpl ts = this.svd.casMetadata.ts;
- if (ts.isCommitted()) {
- return ts;
- }
- throw new CASRuntimeException(CASRuntimeException.TYPESYSTEM_NOT_LOCKED);
+ return getTypeSystemImpl();
}
+ public TypeSystemImpl getTypeSystemImpl() {
+ if (tsi == null) {
+ tsi = this.svd.tsi;
+ }
+ return this.tsi;
+ }
+
public ConstraintFactory getConstraintFactory() {
return ConstraintFactory.instance();
}
- public <T extends FeatureStructure> T createFS(Type type) {
- final int typeCode = ((TypeImpl) type).getCode();
- if (!isCreatableType(typeCode)) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.NON_CREATABLE_TYPE,
- new String[] { type.getName(), "CAS.createFS()" });
- throw e;
+ /**
+ * Create the appropriate Feature Structure Java instance
+ * - from whatever the generator for this type specifies.
+ *
+ * @param type the type to create
+ * @return a Java object representing the FeatureStructure impl in Java.
+ */
+ public <T extends TOP> T createFS(Type type) {
+ final TypeImpl ti = (TypeImpl) type;
+ if (!ti.isCreatableAndNotBuiltinArray()) {
+ throw new CASRuntimeException(CASRuntimeException.NON_CREATABLE_TYPE, type.getName(), "CAS.createFS()");
}
- return ll_getFSForRef(ll_createFSAnnotCheck(typeCode));
+ return createFSAnnotCheck(ti);
}
- public int ll_createFSAnnotCheck(int typeCode) {
- final int addr = ll_createFS(typeCode);
- final TypeSystemImpl ts = this.svd.casMetadata.ts;
- final boolean isAnnot = ts.subsumes(TypeSystemImpl.annotBaseTypeCode, typeCode);
- if (isAnnot && (this == this.getBaseCAS())) {
- CASRuntimeException e = new CASRuntimeException(
- CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS,
- new String[] { ts.ll_getTypeForCode(typeCode).getName() });
- throw e;
- }
- if (isAnnot) {
- this.setFeatureValueNotJournaled(addr, TypeSystemImpl.annotSofaFeatCode, this.getSofaRef());
+
+ private <T extends FeatureStructureImplC> T createFSAnnotCheck(TypeImpl ti) {
+ if (ti.isAnnotationBaseType() && this.isBaseCas()) {
+ throw new CASRuntimeException(CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS, ti.getName());
}
- return addr;
+ T fs = (T) (((FsGenerator)getFsGenerator(ti.getCode())).createFS(ti, this));
+ svd.cache_not_in_index = fs;
+ return fs;
+ }
+
+ public int ll_createFSAnnotCheck(int typeCode) {
+ return createFSAnnotCheck(getTypeSystemImpl().getTypeForCode(typeCode))._id;
+ }
+
+ public CommonArray createArray(int typeCode, int arrayLength) {
+ return (CommonArray) (((FsGeneratorArray)getFsGenerator(typeCode))
+ .createFS(getTypeSystemImpl().getTypeForCode(typeCode), this, arrayLength));
}
-
- // public FeatureStructure createPermFS(Type type) {
- // final int addr = createPermFS(((TypeImpl) type).getCode());
- // return getFSClassRegistry().createFS(addr, this);
- // }
public ArrayFS createArrayFS(int length) {
checkArrayPreconditions(length);
- final int addr = createTempArray(TypeSystemImpl.fsArrayTypeCode, length);
- return (ArrayFS) createFS(addr);
+ return (ArrayFS) (((FsGeneratorArray)getFsGenerator(TypeSystemImpl.fsArrayTypeCode))
+ .createFS(getTypeSystemImpl().fsArrayType, this, length));
}
public IntArrayFS createIntArrayFS(int length) {
checkArrayPreconditions(length);
- final int addr = createTempArray(TypeSystemImpl.intArrayTypeCode, length);
- return (IntArrayFS) createFS(addr);
+ return (IntArrayFS) (((FsGeneratorArray)getFsGenerator(TypeSystemImpl.intArrayTypeCode))
+ .createFS(getTypeSystemImpl().intArrayType, this, length));
}
public FloatArrayFS createFloatArrayFS(int length) {
checkArrayPreconditions(length);
- final int addr = createTempArray(TypeSystemImpl.floatArrayTypeCode, length);
- return (FloatArrayFS) createFS(addr);
+ return (FloatArrayFS) (((FsGeneratorArray)getFsGenerator(TypeSystemImpl.floatArrayTypeCode))
+ .createFS(getTypeSystemImpl().floatArrayType, this, length));
}
public StringArrayFS createStringArrayFS(int length) {
checkArrayPreconditions(length);
- final int addr = createTempArray(TypeSystemImpl.stringArrayTypeCode, length);
- return (StringArrayFS) createFS(addr);
+ return (StringArrayFS) (((FsGeneratorArray)getFsGenerator(TypeSystemImpl.stringArrayTypeCode))
+ .createFS(getTypeSystemImpl().stringArrayType, this, length));
}
-
- public final void checkArrayPreconditions(int len) throws CASRuntimeException {
- // Check array size.
- if (len < 0) {
- throw new CASRuntimeException(CASRuntimeException.ILLEGAL_ARRAY_SIZE);
- }
+
+ public JavaObjectArray createJavaObjectArrayFS(int length) {
+ checkArrayPreconditions(length);
+ return (JavaObjectArray) (((FsGeneratorArray)getFsGenerator(TypeSystemImpl.stringArrayTypeCode))
+ .createFS(getTypeSystemImpl().javaObjectArrayType, this, length));
}
+
// return true if only one sofa and it is the default text sofa
public boolean isBackwardCompatibleCas() {
// check that there is exactly one sofa
@@ -733,22 +728,33 @@ public class CASImpl extends AbstractCas
return aSofa;
}
- SofaFS createSofa(String sofaName, String mimeType) {
- final int addr = ll_createFS(TypeSystemImpl.sofaTypeCode);
- final FeatureStructure sofa = ll_getFSForRef(addr);
- addSofa(sofa, sofaName, mimeType);
- return (SofaFS) sofa;
+ Sofa createSofa(String sofaName, String mimeType) {
+ return createSofa(++this.svd.viewCount, sofaName, mimeType);
+ }
+
+ Sofa createSofa(int sofaNum, String sofaName, String mimeType) {
+ if (this.svd.sofaNameSet.contains(sofaName)) {
+ throw new CASRuntimeException(CASRuntimeException.SOFANAME_ALREADY_EXISTS, sofaName);
+ }
+
+ Sofa sofa = new Sofa(
+ getTypeSystemImpl().sofaType,
+ this,
+ sofaNum,
+ sofaName,
+ mimeType);
+
+ this.getBaseIndexRepository().addFS(sofa);
+ this.svd.sofaNameSet.add(sofaName);
+ return sofa;
}
- SofaFS createInitialSofa(String mimeType) {
- final int addr = ll_createFS(TypeSystemImpl.sofaTypeCode);
- final FeatureStructure sofa = ll_getFSForRef(addr);
- // final int llsofa = ll_getFSRef(sofa);
- ll_setIntValue(/* llsofa */addr, TypeSystemImpl.sofaNumFeatCode, 1);
- addSofa(sofa, CAS.NAME_DEFAULT_SOFA, mimeType);
+ Sofa createInitialSofa(String mimeType) {
+ Sofa sofa = createSofa(1, CAS.NAME_DEFAULT_SOFA, mimeType);
+
registerInitialSofa();
- this.mySofaRef = /* ((FeatureStructureImpl)sofa).getAddress() */addr;
- return (SofaFS) sofa;
+ this.mySofaRef = sofa;
+ return sofa;
}
void registerInitialSofa() {
@@ -759,23 +765,6 @@ public class CASImpl extends AbstractCas
return this.svd.initialSofaCreated;
}
- // Internal use only
- public void addSofa(FeatureStructure sofa, String sofaName, String mimeType) {
- if (this.svd.sofaNameSet.contains(sofaName)) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_ALREADY_EXISTS,
- new String[] { sofaName });
- throw e;
- }
- final int llsofa = ll_getFSRef(sofa);
- if (0 == ll_getIntValue(llsofa, TypeSystemImpl.sofaNumFeatCode)) {
- ll_setIntValue(llsofa, TypeSystemImpl.sofaNumFeatCode, ++this.svd.viewCount);
- }
- ll_setStringValue(llsofa, TypeSystemImpl.sofaIdFeatCode, sofaName);
- ll_setStringValue(llsofa, TypeSystemImpl.sofaMimeFeatCode, mimeType);
- this.getBaseIndexRepository().addFS(sofa);
- this.svd.sofaNameSet.add(sofaName);
- }
-
/**
* @deprecated
*/
@@ -787,17 +776,13 @@ public class CASImpl extends AbstractCas
private SofaFS getSofa(String sofaName) {
FSIterator<SofaFS> iterator = this.svd.baseCAS.getSofaIterator();
- while (iterator.isValid()) {
- SofaFS sofa = iterator.get();
- if (sofaName.equals(getStringValue(((FeatureStructureImpl) sofa).getAddress(),
- TypeSystemImpl.sofaIdFeatCode))) {
+ while (iterator.hasNext()) {
+ SofaFS sofa = iterator.next();
+ if (sofaName.equals(sofa.getSofaID())) {
return sofa;
}
- iterator.moveToNext();
}
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFANAME_NOT_FOUND,
- new String[] { sofaName });
- throw e;
+ throw new CASRuntimeException(CASRuntimeException.SOFANAME_NOT_FOUND, sofaName);
}
SofaFS getSofa(int sofaRef) {
@@ -827,129 +812,108 @@ public class CASImpl extends AbstractCas
@SuppressWarnings("unchecked")
public FSIterator<SofaFS> getSofaIterator() {
- FSIndex<SofaFS> sofaIndex = (FSIndex<SofaFS>) ( FSIndex<?>) this.svd.baseCAS.indexRepository.getIndex(CAS.SOFA_INDEX_NAME);
+ FSIndex<SofaFS> sofaIndex = this.svd.baseCAS.indexRepository.getIndex(CAS.SOFA_INDEX_NAME);
return sofaIndex.iterator();
}
// For internal use only
- public void setSofaFeat(int addr, int sofa) {
- // never an index key
- setFeatureValueNoIndexCorruptionCheck(addr, TypeSystemImpl.annotSofaFeatCode, sofa);
- }
-
- // For internal use only
- public int getSofaFeat(int addr) {
- return getFeatureValue(addr, TypeSystemImpl.annotSofaFeatCode);
- }
-
- // For internal use only
- public int getSofaRef() {
- if (this.mySofaRef == -1) {
+ public Sofa getSofaRef() {
+ if (this.mySofaRef == null) {
// create the SofaFS for _InitialView ...
// ... and reset mySofaRef to point to it
- this.mySofaRef = this.createInitialSofa(null).hashCode();
+ this.mySofaRef = this.createInitialSofa(null);
}
return this.mySofaRef;
}
// For internal use only
public InputStream getSofaDataStream(SofaFS aSofa) {
- try {
+
+ Sofa sofa = (Sofa) aSofa;
+ String sd = sofa.getLocalStringData();
- if (null != aSofa.getLocalStringData()) {
- ByteArrayInputStream bis = new ByteArrayInputStream(aSofa.getLocalStringData().getBytes(
- "UTF-8"));
- return bis;
- } else if (null != aSofa.getLocalFSData()) {
- FeatureStructureImpl fs = (FeatureStructureImpl) aSofa.getLocalFSData();
-
- int arrayStart = 0;
- int arraySize = this.ll_getArraySize(fs.getAddress());
- ByteBuffer buf = null;
- Type type = fs.getType();
- if (type.getName().equals(CAS.TYPE_NAME_STRING_ARRAY)) {
- StringBuffer sb = new StringBuffer();
- for (int i=0; i<((StringArrayFS)fs).size(); i++) {
- if (i==0) {
- sb.append( ((StringArrayFS)fs).get(i) );
- } else {
- sb.append( "\n" + ((StringArrayFS)fs).get(i) );
- }
- }
- ByteArrayInputStream bis = new ByteArrayInputStream( sb.toString().getBytes("UTF-8") );
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_INTEGER_ARRAY)) {
- arrayStart = getArrayStartAddress(fs.getAddress());
- buf = ByteBuffer.allocate(arraySize * 4);
- IntBuffer intbuf = buf.asIntBuffer();
- intbuf.put(this.getHeap().heap, arrayStart, arraySize);
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_FLOAT_ARRAY)) {
- arrayStart = getArrayStartAddress(fs.getAddress());
- buf = ByteBuffer.allocate(arraySize * 4);
- FloatBuffer floatbuf = buf.asFloatBuffer();
- float[] floatArray = new float[arraySize];
- for (int i = arrayStart; i < arrayStart + arraySize; i++) {
- floatArray[i - arrayStart] = Float.intBitsToFloat(this.getHeap().heap[i]);
- }
- floatbuf.put(floatArray);
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_BOOLEAN_ARRAY)
- || type.getName().equals(CAS.TYPE_NAME_BYTE_ARRAY)) {
- arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
- buf = ByteBuffer.allocate(arraySize);
- buf.put(this.getByteHeap().heap, arrayStart, arraySize);
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_SHORT_ARRAY)) {
- arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
- buf = ByteBuffer.allocate(arraySize * 2);
- ShortBuffer shortbuf = buf.asShortBuffer();
- shortbuf.put(this.getShortHeap().heap, arrayStart, arraySize);
-
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_LONG_ARRAY)) {
- arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
- buf = ByteBuffer.allocate(arraySize * 8);
- LongBuffer longbuf = buf.asLongBuffer();
- longbuf.put(this.getLongHeap().heap, arrayStart, arraySize);
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
- } else if (type.getName().equals(CAS.TYPE_NAME_DOUBLE_ARRAY)) {
- arrayStart = this.getHeap().heap[getArrayStartAddress(fs.getAddress())];
- buf = ByteBuffer.allocate(arraySize * 8);
- DoubleBuffer doublebuf = buf.asDoubleBuffer();
- double[] doubleArray = new double[arraySize];
- for (int i = arrayStart; i < arrayStart + arraySize; i++) {
- doubleArray[i - arrayStart] = Double.longBitsToDouble(this.getLongHeap().heap[i]);
+ if (null != sd) {
+ ByteArrayInputStream bis;
+ try {
+ bis = new ByteArrayInputStream(sd.getBytes("UTF-8"));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e); // never happen
+ }
+ return bis;
+
+ } else if (null != aSofa.getLocalFSData()) {
+ TOP fs = (TOP) sofa.getLocalFSData();
+ ByteBuffer buf = null;
+ switch(fs._getTypeCode()) {
+
+ case TypeSystemImpl.stringArrayTypeCode: {
+ StringBuilder sb = new StringBuilder();
+ final String[] theArray = ((StringArray) fs)._getTheArray();
+
+ for (int i = 0; i < theArray.length; i++) {
+ if (i != 0) {
+ sb.append('\n');
}
- doublebuf.put(doubleArray);
- ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
- return bis;
+ sb.append(theArray[i]);
+ }
+ try {
+ return new ByteArrayInputStream(sb.toString().getBytes("UTF-8") );
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e); // never happen
}
+ }
+ case TypeSystemImpl.intArrayTypeCode: {
+ final int[] theArray = ((IntegerArray) fs)._getTheArray();
+ (buf = ByteBuffer.allocate(theArray.length * 4)).asIntBuffer().put(theArray, 0, theArray.length);
+ break;
+ }
+
+ case TypeSystemImpl.floatArrayTypeCode: {
+ final float[] theArray = ((FloatArray) fs)._getTheArray();
+ (buf = ByteBuffer.allocate(theArray.length * 4)).asFloatBuffer().put(theArray, 0, theArray.length);
+ break;
+ }
+
+ case TypeSystemImpl.byteArrayTypeCode: {
+ final byte[] theArray = ((ByteArray) fs)._getTheArray();
+ buf = ByteBuffer.wrap(theArray);
+ break;
+ }
+
+ case TypeSystemImpl.shortArrayTypeCode: {
+ final short[] theArray = ((ShortArray) fs)._getTheArray();
+ (buf = ByteBuffer.allocate(theArray.length * 2)).asShortBuffer().put(theArray, 0, theArray.length);
+ break;
+ }
- } else if (null != aSofa.getSofaURI()) {
- URL url = new URL(aSofa.getSofaURI());
+ case TypeSystemImpl.longArrayTypeCode: {
+ final long[] theArray = ((LongArray) fs)._getTheArray();
+ (buf = ByteBuffer.allocate(theArray.length * 8)).asLongBuffer().put(theArray, 0, theArray.length);
+ break;
+ }
+
+ case TypeSystemImpl.doubleArrayTypeCode: {
+ final double[] theArray = ((DoubleArray) fs)._getTheArray();
+ (buf = ByteBuffer.allocate(theArray.length * 8)).asDoubleBuffer().put(theArray, 0, theArray.length);
+ break;
+ }
+
+ default:
+ assert(false);
+ }
+
+ ByteArrayInputStream bis = new ByteArrayInputStream(buf.array());
+ return bis;
+
+ } else if (null != aSofa.getSofaURI()) {
+ URL url;
+ try {
+ url = new URL(aSofa.getSofaURI());
return url.openStream();
- } else {
- return null;
+ } catch (IOException exc) {
+ throw new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR, exc.getMessage());
}
- } catch (MalformedURLException exc) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
- new String[] { exc.getMessage() });
- throw e;
- } catch (CASRuntimeException exc) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
- new String[] { exc.getMessage() });
- throw e;
- } catch (IOException exc) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.SOFADATASTREAM_ERROR,
- new String[] { exc.getMessage() });
- throw e;
- }
+ }
return null;
}
@@ -959,7 +923,7 @@ public class CASImpl extends AbstractCas
}
public void commitTypeSystem() {
- final TypeSystemImpl ts = this.svd.casMetadata.ts;
+ final TypeSystemImpl ts = getTypeSystemImpl();
// For CAS pools, the type system could have already been committed
// Skip the initFSClassReg if so, because it may have been updated to a JCas
// version by another CAS processing in the pool
@@ -970,27 +934,10 @@ public class CASImpl extends AbstractCas
// at the same time
synchronized (ts) {
if (!ts.isCommitted()) {
- this.svd.casMetadata.ts.commit();
- initFSClassRegistry();
- FSClassRegistry fscr = getFSClassRegistry();
- // save for the case of non=jcas pipeline with a jcas pear in the middle
- // - this
- // allows subsequent downstream annotators to run without jcas
- fscr.saveGeneratorsForClassLoader(this.svd.previousJCasClassLoader, fscr
- .getBaseGenerators());
+ ts.commit();
}
- }
- setLocalFsGenerators(this.svd.casMetadata.fsClassRegistry.getBaseGenerators());
- // After the type system has been committed, we can create the
- // index repository.
+ }
createIndexRepository();
- svd.annotFeatOffset_begin = getFeatureOffset(TypeSystemImpl.startFeatCode);
- svd.annotFeatOffset_end = getFeatureOffset(TypeSystemImpl.endFeatCode);
- }
-
- // internal use, public for cross class ref
- public void setLocalFsGenerators(FSGenerator<? extends FeatureStructure>[] fsGenerators) {
- this.svd.localFsGenerators = fsGenerators;
}
private void createIndexRepository() {
@@ -1026,7 +973,7 @@ public class CASImpl extends AbstractCas
* @see org.apache.uima.cas.admin.CASMgr#getTypeSystemMgr()
*/
public TypeSystemMgr getTypeSystemMgr() {
- return this.svd.casMetadata.ts;
+ return getTypeSystemImpl();
}
public void reset() {
@@ -1067,16 +1014,17 @@ public class CASImpl extends AbstractCas
public void resetNoQuestions() {
svd.casResets.incrementAndGet();
+ svd.fsIdGenerator.set(0);
if (trace) {
System.out.println("CAS Reset in thread " + Thread.currentThread().getName() +
" for CasId = " + getCasId() + ", new reset count = " + svd.casResets.get());
}
int numViews = this.getBaseSofaCount();
- // Flush indexRepository for all Sofa
+ // Flush indexRepository for all views
for (int view = 1; view <= numViews; view++) {
- CAS tcas = (view == 1) ? getInitialView() : getView(view);
+ CASImpl tcas = (CASImpl) ((view == 1) ? getInitialView() : getView(view));
if (tcas != null) {
- ((CASImpl) tcas).resetView();
+ tcas.resetView();
// mySofaRef = -1 is a flag in initial view that sofa has not been set.
// For the initial view, it is possible to not have a sofa - it is set
@@ -1084,16 +1032,10 @@ public class CASImpl extends AbstractCas
// all other views always have a sofa set. The sofaRef is set to 0,
// but will be set to the actual sofa addr in the cas when the view is
// initialized.
- ((CASImpl) tcas).mySofaRef = (1 == view) ? -1 : 0;
+
+ tcas.mySofaRef = null; // was in v2: (1 == view) ? -1 : 0;
}
}
- this.getHeap().reset(/*this.getHeap().getHeapSize() > CASImpl.resetHeapSize*/);
-
- resetStringTable();
-
- this.getByteHeap().reset();
- this.getShortHeap().reset();
- this.getLongHeap().reset();
this.indexRepository.flush(); // for base view, other views flushed above
this.svd.sofaNameSet = new HashSet<String>();
@@ -1101,16 +1043,11 @@ public class CASImpl extends AbstractCas
// always an Initial View now!!!
this.svd.viewCount = 1;
- if (null != this.svd.casMetadata.fsClassRegistry) {
- // needed only if caching non-JCas Java cover objects
- // NOTE: This code may not work - has not been maintained
- this.svd.casMetadata.fsClassRegistry.flush();
- }
if (this.jcas != null) {
JCasImpl.clearData(this);
}
clearTrackingMarks();
- this.svd.cache_not_in_index = 0;
+ this.svd.cache_not_in_index = null;
this.svd.fssTobeAddedback.clear();
this.svd.fssTobeAddedback.trimToSize();
}
@@ -1145,19 +1082,10 @@ public class CASImpl extends AbstractCas
this.svd.baseCAS.getBaseIndexRepository().addFS(sofa);
}
- void registerView(SofaFS aSofa) {
- this.mySofaRef = ((FeatureStructureImpl) aSofa).getAddress();
+ void registerView(Sofa aSofa) {
+ this.mySofaRef = aSofa;
}
- public void reinit(CASSerializer ser) {
- if (this != this.svd.baseCAS) {
- this.svd.baseCAS.reinit(ser);
- return;
- }
- this.resetNoQuestions();
- reinit(ser.getHeapMetadata(), ser.getHeapArray(), ser.getStringTable(), ser.getFSIndex(), ser
- .getByteArray(), ser.getShortArray(), ser.getLongArray());
- }
/**
* @see org.apache.uima.cas.CAS#fs2listIterator(FSIterator)
@@ -1176,97 +1104,20 @@ public class CASImpl extends AbstractCas
throw new CASAdminException(CASAdminException.MUST_COMMIT_INDEX_REPOSITORY);
}
- void resetStringTable() {
- this.getStringHeap().reset();
- }
-
// public void setFSClassRegistry(FSClassRegistry fsClassReg) {
// this.svd.casMetadata.fsClassRegistry = fsClassReg;
// }
- private void initFSClassRegistry() {
- final TypeSystemImpl ts = this.svd.casMetadata.ts;
- // System.out.println("Initializing FSClassRegistry");
- this.svd.casMetadata.fsClassRegistry.initGeneratorArray();
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.fsArrayType, new ArrayFSGenerator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.intArrayType, IntArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.floatArrayType, FloatArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.stringArrayType, StringArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.sofaType, SofaFSImpl
- .getSofaFSGenerator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotBaseType, AnnotationBaseImpl
- .getAnnotationGenerator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.annotType, AnnotationImpl
- .getAnnotationGenerator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.byteArrayType, ByteArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.booleanArrayType, BooleanArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.shortArrayType, ShortArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.longArrayType, LongArrayFSImpl
- .generator());
- this.svd.casMetadata.fsClassRegistry.addClassForType(ts.doubleArrayType, DoubleArrayFSImpl
- .generator());
-
- // assert(fsClassReg != null);
- }
-
+
// JCasGen'd cover classes use this to add their generators to the class
// registry
// Note that this now (June 2007) a no-op for JCasGen'd generators
// Also used in JCas initialization to copy-down super generators to subtypes
// as needed
- public FSClassRegistry getFSClassRegistry() // for JCas integration
- {
- return this.svd.casMetadata.fsClassRegistry;
+ public FSClassRegistry getFSClassRegistry() {
+ return getTypeSystemImpl().getFSClassRegistry();
}
- public void reinit(CASCompleteSerializer casCompSer) {
- if (this != this.svd.baseCAS) {
- this.svd.baseCAS.reinit(casCompSer);
- return;
- }
- TypeSystemImpl ts = casCompSer.getCASMgrSerializer().getTypeSystem();
- this.svd.casMetadata = ts.casMetadata;
- commitTypeSystem();
-
- // reset index repositories -- wipes out Sofa index
- this.indexRepository = casCompSer.getCASMgrSerializer().getIndexRepository(this);
- this.indexRepository.commit();
-
- // get handle to existing initial View
- CAS initialView = this.getInitialView();
-
- // throw away all other View information as the CAS definition may have
- // changed
- this.svd.sofa2indexMap.clear();
- this.svd.sofaNbr2ViewMap.clear();
- this.svd.viewCount = 0;
-
- // freshen the initial view
- ((CASImpl) initialView).refreshView(this.svd.baseCAS, null);
- setViewForSofaNbr(1, initialView);
- this.svd.viewCount = 1;
-
- // deserialize heap
- CASSerializer casSer = casCompSer.getCASSerializer();
- reinit(casSer.getHeapMetadata(), casSer.getHeapArray(), casSer.getStringTable(), casSer
- .getFSIndex(), casSer.getByteArray(), casSer.getShortArray(), casSer.getLongArray());
-
- // we also need to throw away the JCAS. A new JCAS will be created on
- // the next
- // call to getJCas(). As with the CAS, we are counting on the fact that
- // this happens only in a service, where JCAS handles are not held on
- // to.
- this.jcas = null;
- // this.sofa2jcasMap.clear();
-
- clearTrackingMarks();
- }
private void clearTrackingMarks() {
// resets all markers that might be held by things outside the Cas
@@ -1280,1108 +1131,299 @@ public class CASImpl extends AbstractCas
this.svd.trackingMark = null;
this.svd.modifiedPreexistingFSs = null;
- this.svd.modifiedFSHeapCells = null;
- this.svd.modifiedByteHeapCells = null;
- this.svd.modifiedShortHeapCells = null;
- this.svd.modifiedLongHeapCells = null;
this.svd.trackingMarkList = null;
}
- void reinit(int[] heapMetadata, int[] heapArray, String[] stringTable, int[] fsIndex,
- byte[] byteHeapArray, short[] shortHeapArray, long[] longHeapArray) {
- createStringTableFromArray(stringTable);
- this.getHeap().reinit(heapMetadata, heapArray);
- if (byteHeapArray != null) {
- this.getByteHeap().reinit(byteHeapArray);
- }
- if (shortHeapArray != null) {
- this.getShortHeap().reinit(shortHeapArray);
- }
- if (longHeapArray != null) {
- this.getLongHeap().reinit(longHeapArray);
+ /**
+ *
+ * @param fs the Feature Structure being updated
+ * @param fi the Feature of fs being updated, or null if fs is an array
+ * @param arrayIndexStart
+ * @param nbrOfConsecutive
+ */
+ private void logFSUpdate(FeatureStructureImplC fs, FeatureImpl fi, int arrayIndexStart, int nbrOfConsecutive) {
+ if (this.svd.trackingMark != null && !this.svd.trackingMark.isNew(fs.get_id())) {
+ //log the FS
+
+ //create or use last FsChange element
+ FsChange change = null;
+
+ final List<FsChange> changes = this.svd.modifiedPreexistingFSs;
+ final int nbrOfChanges = changes.size();
+ if (nbrOfChanges > 0) {
+ change = changes.get(nbrOfChanges - 1); // get last element
+ }
+
+ // only create a new FsChange element if needed
+ if (change.fs != fs) {
+ this.svd.modifiedPreexistingFSs.add(change = new FsChange(fs));
+ }
+
+ if (fi == null) {
+ if (arrayIndexStart < 0) {
+ throw new UIMARuntimeException(UIMARuntimeException.INTERNAL_ERROR);
+ }
+ change.addArrayData(arrayIndexStart, nbrOfConsecutive);
+ } else {
+ if (fi.isInInt) {
+ change.addIntData(fi.getOffset());
+ } else {
+ change.addRefData(fi.getOffset());
+ }
+ }
}
+ }
+
+ private void logFSUpdate(FeatureStructureImplC fs, FeatureImpl fi) {
+ logFSUpdate(fs, fi, -1, -1); // indicate non-array call
+ }
- reinitIndexedFSs(fsIndex);
+
+ /**
+ * This is your link from the low-level API to the high-level API. Use this
+ * method to create a FeatureStructure object from an address. Note that the
+ * reverse is not supported by public APIs (i.e., there is currently no way to
+ * get at the address of a FeatureStructure. Maybe we will need to change
+ * that.
+ *
+ * The "create" in "createFS" is a misnomer - the FS must already be created.
+ *
+ * @param id The id of the feature structure to be created.
+ * @param <T> The Java class associated with this feature structure
+ * @return A FeatureStructure object.
+ */
+ public <T extends TOP> T createFS(int id) {
+ return getFsFromId_checked(id);
+ }
+
+ public int getArraySize(CommonArrayFS fs) {
+ return fs.size();
+ }
+
+ public int ll_getArraySize(int id) {
+ return getArraySize(getFsFromId_checked(id));
+ }
+
+ /*
+ * Support code for JCas setters
+ */
+
+ public void setWithCheckAndJournal(FeatureStructureImplC fs, int featCode, Runnable setter) {
+ boolean wasRemoved = checkForInvalidFeatureSetting(fs, featCode);
+ setter.run();
+ if (wasRemoved) {
+ maybeAddback(fs);
+ }
+ maybeLogUpdate(fs, featCode);
}
+// public void setWithCheck(FeatureStructureImplC fs, FeatureImpl feat, Runnable setter) {
+// boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat);
+// setter.run();
+// if (wasRemoved) {
+// maybeAddback(fs);
+// }
+// }
+ public void setWithJournal(FeatureStructureImplC fs, FeatureImpl fi, Runnable setter) {
+ setter.run();
+ maybeLogUpdate(fs, fi);
+ }
+
/**
- * Binary Deserializaion Support
- * An instance of this class is made for every reinit operation
- *
+ *
+ * @param fs the Feature Structure being updated
+ * @param feat the feature of fs being updated, or null if fs is a primitive array
+ * @param i the index being updated
*/
- private class BinDeserSupport {
-
- private int fsStartAddr;
- private int fsEndAddr;
- /**
- * An array of all the starting indexes of the FSs on the old/prev heap
- * (below the mark, for delta CAS, plus one last one (one beyond the end)
- */
- private int[] fssAddrArray;
- private int fssIndex;
- private int lastRemovedFsAddr;
- // feature codes - there are exactly the same number as their are features
- private int[] featCodes;
- private FSsTobeAddedback tobeAddedback = FSsTobeAddedback.createSingle();
+ public void maybeLogArrayUpdate(FeatureStructureImplC fs, FeatureImpl feat, int i) {
+ if (this.svd.trackingMark != null) {
+ this.logFSUpdate(fs, feat, 1, 1);
+ }
+ }
+
+ public void maybeLogUpdate(FeatureStructureImplC fs, FeatureImpl feat) {
+ if (this.svd.trackingMark != null) {
+ this.logFSUpdate(fs, feat);
+ }
+ }
+
+ public void maybeLogUpdate(FeatureStructureImplC fs, int featCode) {
+ if (this.svd.trackingMark != null) {
+ this.logFSUpdate(fs, getTypeSystemImpl().getFeatureForCode(featCode));
+ }
}
/**
- * --------------------------------------------------------------------- see
- * Blob Format in CASSerializer
+ * Common setter code for features in Feature Structures
*
- * This reads in and deserializes CAS data from a stream. Byte swapping may be
- * needed if the blob is from C++ -- C++ blob serialization writes data in
- * native byte order.
- *
- * @param istream -
- * @return -
- * @throws CASRuntimeException wraps IOException
+ * These come in two styles: one with int values, one with Object values
+ */
+
+ /**
+ * This is the common point where all operations to set features come through
+ * It implements the check for invalid feature setting and potentially the addback.
+ *
+ * @param fs the feature structure
+ * @param feat the feature to set
+ * @param value -
*/
+
+ public void setFeatureValue(FeatureStructureImplC fs, FeatureImpl feat, int value) {
+ boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat.getCode());
+ fs._intData[feat.getAdjustedOffset()] = value;
+ if (wasRemoved) {
+ maybeAddback(fs);
+ }
+ maybeLogUpdate(fs, feat);
+ }
- public SerialFormat reinit(InputStream istream) throws CASRuntimeException {
- if (this != this.svd.baseCAS) {
- return this.svd.baseCAS.reinit(istream);
+ /**
+ * version for longs, uses two slots
+ * @param fs the feature structure
+ * @param feat the feature to set
+ * @param value -
+ */
+ public void setFeatureValue(FeatureStructureImplC fs, FeatureImpl feat, int v1, int v2) {
+ boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat.getCode());
+ int offset = feat.getAdjustedOffset();
+ fs._intData[offset] = v1;
+ fs._intData[offset + 1] = v2;
+ if (wasRemoved) {
+ maybeAddback(fs);
}
-
- final DataInputStream dis = (istream instanceof DataInputStream) ?
- (DataInputStream) istream : new DataInputStream(istream);
-
- final BinDeserSupport bds = new BinDeserSupport();
- try {
- // key
- // determine if byte swap if needed based on key
- byte[] bytebuf = new byte[4];
- bytebuf[0] = dis.readByte(); // U
- bytebuf[1] = dis.readByte(); // I
- bytebuf[2] = dis.readByte(); // M
- bytebuf[3] = dis.readByte(); // A
-
- final boolean swap = (bytebuf[0] != 85);
-
- // version
- // version bit in 2's place indicates this is in delta format.
- final int version = readInt(dis, swap);
- final boolean delta = ((version & 2) == 2);
-
- if (!delta) {
- this.resetNoQuestions();
- }
-
- if (0 != (version & 4)) {
- final int compressedVersion = readInt(dis, swap);
- if (compressedVersion == 0) {
- (new BinaryCasSerDes4(this.getTypeSystemImpl(), false)).deserialize(this, dis, delta);
- return SerialFormat.COMPRESSED;
- } else {
-// throw new CASRuntimeException(CASRuntimeException.DESERIALIZING_COMPRESSED_BINARY_UNSUPPORTED);
- // Only works for cases where the type systems match, and delta is false.
- try {
- (new BinaryCasSerDes6(this)).deserializeAfterVersion(dis, delta, AllowPreexistingFS.allow);
- } catch (ResourceInitializationException e) {
- throw new CASRuntimeException(CASRuntimeException.DESERIALIZING_COMPRESSED_BINARY_UNSUPPORTED, null, e);
- }
- return SerialFormat.COMPRESSED_FILTERED;
- }
- }
-
- // main fsheap
- final int fsheapsz = readInt(dis, swap);
-
- int startPos = 0;
- if (!delta) {
- this.getHeap().reinitSizeOnly(fsheapsz);
- } else {
- startPos = this.getHeap().getNextId();
- this.getHeap().grow(fsheapsz);
- }
-
- // add new heap slots
- for (int i = startPos; i < fsheapsz+startPos; i++) {
- this.getHeap().heap[i] = readInt(dis, swap);
- }
-
- // string heap
- int stringheapsz = readInt(dis, swap);
-
- final StringHeapDeserializationHelper shdh = new StringHeapDeserializationHelper();
-
- shdh.charHeap = new char[stringheapsz];
- for (int i = 0; i < stringheapsz; i++) {
- shdh.charHeap[i] = (char) readShort(dis, swap);
- }
- shdh.charHeapPos = stringheapsz;
-
- // word alignment
- if (stringheapsz % 2 != 0) {
- dis.readChar();
- }
-
- // string ref heap
- int refheapsz = readInt(dis, swap);
-
- refheapsz--;
- refheapsz = refheapsz / 2;
- refheapsz = refheapsz * 3;
-
- // read back into references consisting to three ints
- // --stringheap offset,length, stringlist offset
- shdh.refHeap = new int[StringHeapDeserializationHelper.FIRST_CELL_REF + refheapsz];
-
- dis.readInt(); // 0
- for (int i = shdh.refHeapPos; i < shdh.refHeap.length; i += StringHeapDeserializationHelper.REF_HEAP_CELL_SIZE) {
- shdh.refHeap[i + StringHeapDeserializationHelper.CHAR_HEAP_POINTER_OFFSET] = readInt(dis, swap);
- shdh.refHeap[i + StringHeapDeserializationHelper.CHAR_HEAP_STRLEN_OFFSET] = readInt(dis, swap);
- shdh.refHeap[i + StringHeapDeserializationHelper.STRING_LIST_ADDR_OFFSET] = 0;
- }
- shdh.refHeapPos = refheapsz + StringHeapDeserializationHelper.FIRST_CELL_REF;
-
- this.getStringHeap().reinit(shdh, delta);
-
- //if delta, handle modified fs heap cells
- if (delta) {
-
- final int heapsize = this.getHeap().getNextId();
-
- // compute table of ints which correspond to FSs in the existing heap
- // we need this because the list of modifications is just arbitrary single words on the heap
- // at arbitrary boundaries
- IntVector fss = new IntVector(Math.max(128, heapsize >> 6));
- int fsAddr;
- for (fsAddr = 1; fsAddr < heapsize; fsAddr = getNextFsHeapAddr(fsAddr)) {
- fss.add(fsAddr);
- }
- fss.add(fsAddr); // add trailing value
- bds.fssAddrArray = fss.toArray();
-
- int fsmodssz = readInt(dis, swap);
- bds.fsStartAddr = -1;
-
- // loop over all heap modifications to existing FSs
-
- // first disable auto addbacks for index corruption - this routine is handling that
- svd.fsTobeAddedbackSingleInUse = true; // sorry, a bad hack...
- try {
- for (int i = 0; i < fsmodssz; i++) {
- final int heapAddrBeingModified = readInt(dis, swap);
- maybeAddBackAndRemoveFs(heapAddrBeingModified, bds);
- this.getHeap().heap[heapAddrBeingModified] = readInt(dis, swap);
- }
- bds.tobeAddedback.addback(bds.lastRemovedFsAddr);
- bds.fssAddrArray = null; // free storage
- } finally {
- svd.fsTobeAddedbackSingleInUse = false;
- }
- }
-
- // indexed FSs
- int fsindexsz = readInt(dis, swap);
- int[] fsindexes = new int[fsindexsz];
- for (int i = 0; i < fsindexsz; i++) {
- fsindexes[i] = readInt(dis, swap);
- }
-
- // build the index
- if (delta) {
- reinitDeltaIndexedFSs(fsindexes);
- } else {
- reinitIndexedFSs(fsindexes);
- }
-
- // byte heap
- int heapsz = readInt(dis, swap);
-
- if (!delta) {
- this.getByteHeap().heap = new byte[Math.max(16, heapsz)]; // must be > 0
- dis.readFully(this.getByteHeap().heap, 0, heapsz);
- this.getByteHeap().heapPos = heapsz;
- } else {
- for (int i=0; i < heapsz; i++) {
- this.getByteHeap().addByte(dis.readByte());
- }
- }
- // word alignment
- int align = (4 - (heapsz % 4)) % 4;
- BinaryCasSerDes6.skipBytes(dis, align);
-
- // short heap
- heapsz = readInt(dis, swap);
-
- if (!delta) {
- this.getShortHeap().heap = new short[Math.max(16, heapsz)]; // must be > 0
- for (int i = 0; i < heapsz; i++) {
- this.getShortHeap().heap[i] = readShort(dis, swap);
- }
- this.getShortHeap().heapPos = heapsz;
- } else {
- for (int i = 0; i < heapsz; i++) {
- this.getShortHeap().addShort(readShort(dis, swap));
- }
- }
- // word alignment
- if (heapsz % 2 != 0) {
- dis.readShort();
- }
-
- // long heap
- heapsz = readInt(dis, swap);
-
- if (!delta) {
- this.getLongHeap().heap = new long[Math.max(16, heapsz)]; // must be > 0
- for (int i = 0; i < heapsz; i++) {
- this.getLongHeap().heap[i] = readLong(dis, swap);
- }
- this.getLongHeap().heapPos = heapsz;
- } else {
- for (int i = 0; i < heapsz; i++) {
- this.getLongHeap().addLong(readLong(dis, swap));
- }
- }
-
- if (delta) {
- //modified Byte Heap
- heapsz = readInt(dis, swap);
- if (heapsz > 0) {
- int[] heapAddrs = new int[heapsz];
- for (int i = 0; i < heapsz; i++) {
- heapAddrs[i] = readInt(dis, swap);
- }
- for (int i = 0; i < heapsz; i++) {
- this.getByteHeap().heap[heapAddrs[i]] = dis.readByte();
- }
- }
- // word alignment
- align = (4 - (heapsz % 4)) % 4;
- BinaryCasSerDes6.skipBytes(dis, align);
-
- //modified Short Heap
- heapsz = readInt(dis, swap);
- if (heapsz > 0) {
- int[] heapAddrs = new int[heapsz];
- for (int i = 0; i < heapsz; i++) {
- heapAddrs[i] = readInt(dis, swap);
- }
- for (int i = 0; i < heapsz; i++) {
- this.getShortHeap().heap[heapAddrs[i]] = readShort(dis, swap);
- }
- }
-
- // word alignment
- if (heapsz % 2 != 0) {
- dis.readShort();
- }
-
- //modified Long Heap
- heapsz = readInt(dis, swap);
- if (heapsz > 0) {
- int[] heapAddrs = new int[heapsz];
- for (int i = 0; i < heapsz; i++) {
- heapAddrs[i] = readInt(dis, swap);
- }
- for (int i = 0; i < heapsz; i++) {
- this.getLongHeap().heap[heapAddrs[i]] = readLong(dis, swap);
- }
- }
- } // of delta - modified processing
- } catch (IOException e) {
- String msg = e.getMessage();
- if (msg == null) {
- msg = e.toString();
- }
- CASRuntimeException exception = new CASRuntimeException(
- CASRuntimeException.BLOB_DESERIALIZATION, new String[] { msg });
- throw exception;
- }
- return SerialFormat.BINARY;
- }
-
- /**
- * for Deserialization of Delta, when updating existing FSs,
- * If the heap addr is for the next FS, re-add the previous one to those indexes where it was removed,
- * and then maybe remove the new one (and remember which views to re-add to).
- * @param heapAddr
- */
- private void maybeAddBackAndRemoveFs(int heapAddr, final BinDeserSupport bds) {
- if (bds.fsStartAddr == -1) {
- bds.fssIndex = -1;
- bds.lastRemovedFsAddr = -1;
- bds.tobeAddedback.clear();
- }
- findCorrespondingFs(heapAddr, bds); // sets fsStartAddr, end addr
- if (bds.lastRemovedFsAddr != bds.fsStartAddr) {
- bds.tobeAddedback.addback(bds.lastRemovedFsAddr);
- if (bds.featCodes.length == 0) {
- // is array
- final int typeCode = getTypeCode(bds.fsStartAddr);
- assert(getTypeSystemImpl().ll_isArrayType(typeCode));
- } else {
- int featCode = bds.featCodes[heapAddr - (bds.fsStartAddr + 1)];
- removeFromCorruptableIndexAnyView(bds.lastRemovedFsAddr = bds.fsStartAddr, bds.tobeAddedback, featCode);
- }
- }
- }
-
- private void findCorrespondingFs(int heapAddr, final BinDeserSupport bds) {
- if (bds.fsStartAddr < heapAddr && heapAddr < bds.fsEndAddr) {
- return;
- }
-
- // search forward by 1 before doing binary search
- bds.fssIndex ++; // incrementing dense index into fssAddrArray for start addrs
- bds.fsStartAddr = bds.fssAddrArray[bds.fssIndex]; // must exist
- if (bds.fssIndex + 1 < bds.fssAddrArray.length) { // handle edge case where prev was at the end
- bds.fsEndAddr = bds.fssAddrArray[bds.fssIndex + 1]; // must exist
- if (bds.fsStartAddr < heapAddr && heapAddr < bds.fsEndAddr) {
- bds.featCodes = getTypeSystemImpl().ll_getAppropriateFeatures(getTypeCode(bds.fsStartAddr));
- return;
- }
- }
-
- int result;
- if (heapAddr > bds.fsEndAddr) {
- // item is higher
- result = Arrays.binarySearch(bds.fssAddrArray, bds.fssIndex + 1, bds.fssAddrArray.length, heapAddr);
- } else {
- result = Arrays.binarySearch(bds.fssAddrArray, 0, bds.fssIndex - 1, heapAddr);
- }
-
- // result must be negative - should never modify a type code slot
- assert (result < 0);
- bds.fssIndex = (-result) - 2;
- bds.fsStartAddr = bds.fssAddrArray[bds.fssIndex];
- bds.fsEndAddr = bds.fssAddrArray[bds.fssIndex + 1];
- bds.featCodes = getTypeSystemImpl().ll_getAppropriateFeatures(getTypeCode(bds.fsStartAddr));
- assert(bds.fsStartAddr < heapAddr && heapAddr < bds.fsEndAddr);
- }
-
- private int getNextFsHeapAddr(int fsAddr) {
- final TypeSystemImpl tsi = getTypeSystemImpl();
- final int typeCode = getTypeCode(fsAddr);
- final Type type = tsi.ll_getTypeForCode(typeCode);
- //debug
-// if (tsi.ll_getTypeForCode(typeCode) == null) {
-// System.out.println("debug, typeCode = "+ typeCode);
-// }
- final boolean isHeapStoredArray = (typeCode == TypeSystemImpl.intArrayTypeCode) || (typeCode == TypeSystemImpl.floatArrayTypeCode)
- || (typeCode == TypeSystemImpl.fsArrayTypeCode) || (typeCode == TypeSystemImpl.stringArrayTypeCode)
- || (TypeSystemImpl.isArrayTypeNameButNotBuiltIn(type.getName()));
- if (isHeapStoredArray) {
- return fsAddr + 2 + getHeapValue(fsAddr + 1);
- } else if (type.isArray()) {
- return fsAddr + 3; // for the aux ref and the length
- } else {
- return fsAddr + this.svd.casMetadata.fsSpaceReq[typeCode];
- }
- }
-
- private long readLong(DataInputStream dis, boolean swap) throws IOException {
- long v = dis.readLong();
- return swap ? Long.reverseBytes(v) : v;
- }
-
- private int readInt(DataInputStream dis, boolean swap) throws IOException {
- int v = dis.readInt();
- return swap ? Integer.reverseBytes(v) : v;
- }
-
- private short readShort(DataInputStream dis, boolean swap) throws IOException {
- short v = dis.readShort();
- return swap ? Short.reverseBytes(v) : v;
- }
-
-// private long swap8(DataInputStream dis, byte[] buf) throws IOException {
-//
-// buf[7] = dis.readByte();
-// buf[6] = dis.readByte();
-// buf[5] = dis.readByte();
-// buf[4] = dis.readByte();
-// buf[3] = dis.readByte();
-// buf[2] = dis.readByte();
-// buf[1] = dis.readByte();
-// buf[0] = dis.readByte();
-// ByteBuffer bb = ByteBuffer.wrap(buf);
-// return bb.getLong();
-// }
-//
-// private int swap4(DataInputStream dis, byte[] buf) throws IOException {
-// buf[3] = dis.readByte();
-// buf[2] = dis.readByte();
-// buf[1] = dis.readByte();
-// buf[0] = dis.readByte();
-// ByteBuffer bb = ByteBuffer.wrap(buf);
-// return bb.getInt();
-// }
-//
-// private char swap2(DataInputStream dis, byte[] buf) throws IOException {
-// buf[1] = dis.readByte();
-// buf[0] = dis.readByte();
-// ByteBuffer bb = ByteBuffer.wrap(buf, 0, 2);
-// return bb.getChar();
-// }
-
- // assumes:
- // indexes are empty on entry
- //
- void reinitIndexedFSs(int[] fsIndex) {
- // Add FSs to index repository for base CAS
- int numViews = fsIndex[0];
- int loopLen = fsIndex[1]; // number of sofas, not necessarily the same as
- // number of views
- // because the initial view may not have a sofa
- for (int i = 2; i < loopLen + 2; i++) { // iterate over all the sofas,
- this.indexRepository.addFS(fsIndex[i]); // add to base index
- }
- int loopStart = loopLen + 2;
-
- FSIterator<SofaFS> iterator = this.svd.baseCAS.getSofaIterator();
- final Feature idFeat = getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID);
- // Add FSs to index repository for each View
- while (iterator.isValid()) {
- SofaFS sofa = iterator.get();
- String id = ll_getStringValue(((FeatureStructureImpl) sofa).getAddress(),
- ((FeatureImpl) idFeat).getCode());
- if (CAS.NAME_DEFAULT_SOFA.equals(id)) {
- this.registerInitialSofa();
- this.svd.sofaNameSet.add(id);
- }
- // next line the getView as a side effect
- // checks for dupl sofa name, and if not,
- // adds the name to the sofaNameSet
- ((CASImpl) this.getView(sofa)).registerView(sofa);
-
- iterator.moveToNext();
- }
- getInitialView(); // done for side effect of creating the initial view.
- // must be done before the next line, because it sets the
- // viewCount to 1.
- this.svd.viewCount = numViews; // total number of views
-
- for (int viewNbr = 1; viewNbr <= numViews; viewNbr++) {
- CAS view = (viewNbr == 1) ? getInitialView() : getView(viewNbr);
- if (view != null) {
- FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) getSofaIndexRepository(viewNbr);
- loopLen = fsIndex[loopStart];
- for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
- loopIndexRep.addFS(fsIndex[i]);
- }
- loopStart += loopLen + 1;
- ((CASImpl) view).updateDocumentAnnotation();
- } else {
- loopStart += 1;
- }
- }
- }
-
- /**
- * Adds the SofaFSs to the base view
- * Assumes "cas" refers to the base cas
- *
- * Processes "adds", "removes" and "reindexes" for all views
- *
- * @param fsIndex - array of fsRefs and counts, for sofas, and all views
- */
- void reinitDeltaIndexedFSs(int[] fsIndex) {
- assert(this.svd.baseCAS == this);
- // Add Sofa FSs to index repository for base CAS
- int numViews = fsIndex[0]; // total number of views
- int loopLen = fsIndex[1]; // number of sofas, not necessarily the same as number of views (initial view could be missing a Sofa)
- // add Sofa FSs to base view number of views. Should only contain new Sofas.
- for (int i = 2; i < loopLen + 2; i++) { // iterate over all the sofas,
- this.indexRepository.addFS(fsIndex[i]); // add to base index
- }
- int loopStart = loopLen + 2;
-
- FSIterator<SofaFS> iterator = this.getSofaIterator();
- final int idFeatCode = ((FeatureImpl)getTypeSystem().getFeatureByFullName(CAS.FEATURE_FULL_NAME_SOFAID)).getCode();
-
- // Register all Sofas
- while (iterator.isValid()) {
- SofaFS sofa = iterator.get();
- String id = ll_getStringValue(((FeatureStructureImpl) sofa).getAddress(), idFeatCode);
- if (CAS.NAME_DEFAULT_SOFA.equals(id)) {
- this.registerInitialSofa();
- this.svd.sofaNameSet.add(id);
- }
- // next line the getView as a side effect
- // checks for dupl sofa name, and if not,
- // adds the name to the sofaNameSet
- ((CASImpl) this.getView(sofa)).registerView(sofa);
-
- iterator.moveToNext();
- }
-
- this.svd.viewCount = numViews; // total number of views
-
- for (int viewNbr = 1; viewNbr <= numViews; viewNbr++) {
- CAS view = (viewNbr == 1) ? getInitialView() : getView(viewNbr);
- if (view != null) {
-
- // for all views
-
- FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) getSofaIndexRepository(viewNbr);
- loopLen = fsIndex[loopStart];
-
- // add FSs to index
-
- for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
- loopIndexRep.addFS(fsIndex[i]);
- }
-
- // remove FSs from indexes
-
- loopStart += loopLen + 1;
- loopLen = fsIndex[loopStart];
- for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
- loopIndexRep.removeFS(fsIndex[i]);
- }
-
- // skip the reindex - this isn't done here https://issues.apache.org/jira/browse/UIMA-4100
- // but we need to run the loop to read over the items in the input stream
- loopStart += loopLen + 1;
- loopLen = fsIndex[loopStart];
-// for (int i = loopStart + 1; i < loopStart + 1 + loopLen; i++) {
-// loopIndexRep.removeFS(fsIndex[i]);
-// loopIndexRep.addFS(fsIndex[i]);
-// }
- loopStart += loopLen + 1;
- ((CASImpl) view).updateDocumentAnnotation();
- } else {
- loopStart += 1;
- }
- }
- }
-
- // IndexedFSs format:
- // number of views
- // number of sofas
- // [sofa-1 ... sofa-n]
- // number of FS indexed in View1
- // [FS-1 ... FS-n]
- // etc.
- int[] getIndexedFSs() {
- IntVector v = new IntVector();
- int[] fsLoopIndex;
-
- int numViews = getBaseSofaCount();
- v.add(numViews);
-
- // Get indexes for base CAS
- fsLoopIndex = this.svd.baseCAS.indexRepository.getIndexedFSs();
- v.add(fsLoopIndex.length);
- v.add(fsLoopIndex, 0, fsLoopIndex.length);
-// for (int k = 0; k < fsLoopIndex.length; k++) {
-// v.add(fsLoopIndex[k]);
-// }
-
- // Get indexes for each SofaFS in the CAS
- for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) {
- FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) this.svd.baseCAS
- .getSofaIndexRepository(sofaNum);
- if (loopIndexRep != null) {
- fsLoopIndex = loopIndexRep.getIndexedFSs();
- } else {
- fsLoopIndex = INT0;
- }
- v.add(fsLoopIndex.length);
- for (int k = 0; k < fsLoopIndex.length; k++) {
- v.add(fsLoopIndex[k]);
- }
- }
- return v.toArray();
- }
-
-
-
- //Delta IndexedFSs format:
- // number of views
- // number of sofas - new
- // [sofa-1 ... sofa-n]
- // number of new FS add in View1
- // [FS-1 ... FS-n]
- // number of FS removed from View1
- // [FS-1 ... FS-n]
- //number of FS reindexed in View1
- // [FS-1 ... FS-n]
- // etc.
- int[] getDeltaIndexedFSs(MarkerImpl mark) {
- IntVector v = new IntVector();
- int[] fsLoopIndex;
- int[] fsDeletedFromIndex;
- int[] fsReindexed;
-
- int numViews = getBaseSofaCount();
- v.add(numViews);
-
- // Get indexes for base CAS
- fsLoopIndex = this.svd.baseCAS.indexRepository.getIndexedFSs();
- // Get the new Sofa FS
- IntVector newSofas = new IntVector();
- for (int k = 0; k < fsLoopIndex.length; k++) {
- if ( mark.isNew(fsLoopIndex[k]) ) {
- newSofas.add(fsLoopIndex[k]);
- }
- }
-
- v.add(newSofas.size());
- v.add(newSofas.getArray(), 0, newSofas.size());
-// for (int k = 0; k < newSofas.size(); k++) {
-// v.add(newSofas.get(k));
-// }
-
- // Get indexes for each view in the CAS
- for (int sofaNum = 1; sofaNum <= numViews; sofaNum++) {
- FSIndexRepositoryImpl loopIndexRep = (FSIndexRepositoryImpl) this.svd.baseCAS
- .getSofaIndexRepository(sofaNum);
- if (loopIndexRep != null) {
- fsLoopIndex = loopIndexRep.getAddedFSs();
- fsDeletedFromIndex = loopIndexRep.getDeletedFSs();
- fsReindexed = loopIndexRep.getReindexedFSs();
- } else {
- fsLoopIndex = INT0;
- fsDeletedFromIndex = INT0;
- fsReindexed = INT0;
- }
- v.add(fsLoopIndex.length);
- v.add(fsLoopIndex, 0, fsLoopIndex.length);
-// for (int k = 0; k < fsLoopIndex.length; k++) {
-// v.add(fsLoopIndex[k]);
-// }
- v.add(fsDeletedFromIndex.length);
- v.add(fsDeletedFromIndex, 0, fsDeletedFromIndex.length);
-// for (int k = 0; k < fsDeletedFromIndex.length; k++) {
-// v.add(fsDeletedFromIndex[k]);
-// }
- v.add(fsReindexed.length);
- v.add(fsReindexed, 0, fsReindexed.length);
-// for (int k = 0; k < fsReindexed.length; k++) {
-// v.add(fsReindexed[k]);
-// }
- }
- return v.toArray();
- }
-
- void createStringTableFromArray(String[] stringTable) {
- // why a new heap instead of reseting the old one???
- // this.stringHeap = new StringHeap();
- this.getStringHeap().reset();
- for (int i = 1; i < stringTable.length; i++) {
- this.getStringHeap().addString(stringTable[i]);
- }
- }
-
- static String mapName(String name, HashMap<String, String> map) {
- String out = map.get(name);
- if (out != null) {
- return out;
- }
- return name;
- }
-
- /**
- * This is your link from the low-level API to the high-level API. Use this
- * method to create a FeatureStructure object from an address. Not that the
- * reverse is not supported by public APIs (i.e., there is currently no way to
- * get at the address of a FeatureStructure. Maybe we will need to change
- * that.
- *
- * @param addr
- * The address of the feature structure to be created.
- * @param <T> The Java class associated with this feature structure
- * @return A FeatureStructure object. Note that no checking whatsoever is done
- * on the input address. There is really no way of finding out which
- * addresses in the valid address space actually represent feature
- * structures, and which don't.
- */
- public <T extends FeatureStructure> T createFS(int addr) {
- return ll_getFSForRef(addr);
- }
-
- public int ll_getArraySize(int arrayFsRef) {
- return this.getHeap().heap[arrayFsRef + arrayLengthFeatOffset];
- }
-
- /**
- * Get the heap address of the first cell of this array.
- *
- * @param addr
- * The address of the array.
- * @return The address where the first cell of the array is located.
- */
- public final int getArrayStartAddress(int addr) {
- return addr + arrayContentOffset;
- }
-
- /**
- * Get a specific value out of an array.
- *
- * @param addr
- * The address of the array.
- * @param index
- * The index of the value we're interested in.
- * @return The value at <code>index</code>.
- * @exception ArrayIndexOutOfBoundsException -
- */
- public int getArrayValue(int addr, int index) {
- checkArrayBounds(addr, index);
- return this.getHeap().heap[addr + arrayContentOffset + index];
- }
-
- /**
- * Set an array value.
- *
- * @param addr
- * The address of the array.
- * @param index
- * The index we want to set.
- * @param value
- * The value we want to set.
- * @exception ArrayIndexOutOfBoundsException
- */
- void setArrayValue(final int addr, final int index, final int value)
- throws ArrayIndexOutOfBoundsException {
- // Get the length of this array.
- final int arraySize = this.getHeap().heap[addr + arrayLengthFeatOffset];
- // Check for boundary violation.
- if ((index < 0) || (index >= arraySize)) {
- throw new ArrayIndexOutOfBoundsException();
- }
- this.getHeap().heap[addr + arrayContentOffset + index] = value;
- if (this.svd.trackingMark != null) {
- this.logFSUpdate(addr, addr+arrayContentOffset+index, ModifiedHeap.FSHEAP, 1);
- }
- }
-
- void setArrayValueFromString(final int addr, final int index, final String value) {
- int arrayType = this.getHeap().heap[addr];
-
- if (arrayType == TypeSystemImpl.intArrayTypeCode) {
- setArrayValue(addr, index, Integer.parseInt(value));
- } else if (arrayType == TypeSystemImpl.floatArrayTypeCode) {
- setArrayValue(addr, index, CASImpl.float2int(Float.parseFloat(value)));
- } else if (arrayType == TypeSystemImpl.stringArrayTypeCode) {
- setArrayValue(addr, index, addString(value));
- } else if (arrayType == TypeSystemImpl.booleanArrayTypeCode) {
- ll_setBooleanArrayValue(addr, index, Boolean.valueOf(value).booleanValue());
- } else if (arrayType == TypeSystemImpl.byteArrayTypeCode) {
- ll_setByteArrayValue(addr, index, Byte.parseByte(value));
- } else if (arrayType == TypeSystemImpl.shortArrayTypeCode) {
- ll_setShortArrayValue(addr, index, Short.parseShort(value));
- } else if (arrayType == TypeSystemImpl.longArrayTypeCode) {
- ll_setLongArrayValue(addr, index, Long.parseLong(value));
- } else if (arrayType == TypeSystemImpl.doubleArrayTypeCode) {
- ll_setDoubleArrayValue(addr, index, Double.parseDouble(value));
- } else if (arrayType == TypeSystemImpl.fsArrayTypeCode) {
- setArrayValue(addr, index, Integer.parseInt(value));
- }
- }
-
- /**
- * Copy the contents of an array to an externally provided array.
- *
- * @param addr
- * The address of the source array.
- * @param sourceOffset
- * The offset we want to start copying at.
- * @param dest
- * The destination array.
- * @param destOffset
- * An offset into the destination array.
- * @param length
- * The number of items to copy.
- */
- void copyToArray(int addr, int sourceOffset, int[] dest, int destOffset, int length) {
- // Get the length of this array.
- final int arraySize = this.getHeap().heap[addr + arrayLengthFeatOffset];
- // Check boundary conditions for source array. We can rely on Java to
- // complain about boundary violations for the destination array.
- if ((sourceOffset < 0) || ((length + sourceOffset) > arraySize)) {
- throw new ArrayIndexOutOfBoundsException();
- }
- // Compute the offset into the heap where the array starts.
- final int offset = addr + arrayContentOffset;
- System.arraycopy(this.getHeap().heap, offset + sourceOffset, dest, destOffset, length);
- }
+ maybeLogUpdate(fs, feat);
+ }
+
+ /**
+ * This is the common point where all operations to set features come through
+ * It implements the check for invalid feature setting and potentially the addback.
+ * (String objects may be in keys)
+ * @param fs the feature structure
+ * @param feat the feature to set
+ * @param value -
+ */
+
+ public void setFeatureValue(FeatureStructureImplC fs, FeatureImpl feat, Object value) {
+ boolean wasRemoved = checkForInvalidFeatureSetting(fs, feat.getCode());
+ fs._refData[feat.getAdjustedOffset()] = value;
+ if (wasRemoved) {
+ maybeAddback(fs);
+ }
+ maybeLogUpdate(fs, feat);
+ }
/**
- * Copy the contents of an input array into a CAS array.
- *
- * @param src
- * The array to copy from.
- * @param srcOffset
- * An offset into the source from where to start copying.
- * @param addr
- * The address of the array we're copying to.
- * @param destOffset
- * Where to start copying into the destination array.
- * @param length
- * How many elements to copy.
- */
- void copyFromArray(int[] src, int srcOffset, int addr, int destOffset, int length) {
- // Get the length of this array.
- final int arraySize = this.getHeap().heap[addr + arrayLengthFeatOffset];
- // Check boundary conditions for destination array. We can rely on Java
- // to
- // complain about boundary violations for the source array.
- if ((destOffset < 0) || ((length + destOffset) > arraySize)) {
- throw new ArrayIndexOutOfBoundsException();
- }
- // Compute the offset into the heap where the array starts.
- final int offset = addr + arrayContentOffset;
- System.arraycopy(src, srcOffset, this.getHeap().heap, offset + destOffset, length);
- if (this.svd.trackingMark != null) {
- this.logFSUpdate(addr, offset + destOffset, ModifiedHeap.FSHEAP, length);
- }
- }
-
- public int getTypeCode(int fsAddr) {
- return getHeapValue(fsAddr);
- }
-
- // not journaled, this is for a new FS only
- void copyFeatures(int trgAddr, int srcAddr) throws CASRuntimeException {
- int typeCode = getHeapValue(trgAddr);
- if (typeCode != getHeapValue(srcAddr)) {
- CASRuntimeException e = new CASRuntimeException(CASRuntimeException.INAPPROP_TYPE);
- // What's that supposed to mean? Internationalized, my foot.
- // TODO: fix exception argument.
- // e.addArgument("Type of source and target feature structures do not
- // match");
- throw (e);
- }
- // get features to copy
- int[] featcodes = getTypeSystem().getLowLevelTypeSystem().ll_getAppropriateFeatures(typeCode);
- for (int i = 0; i < featcodes.length; i++) {
-
- // get range type of this feature
- Feature feature = getTypeSystem().getLowLevelTypeSystem().ll_getFeatureForCode(featcodes[i]);
- Type rangeType = feature.getRange();
- // get feature code
- int featCode = ((FeatureImpl) feature).getCode();
- // get the value for this feature offset in src fs
- int val = getHeapValue(srcAddr + this.svd.casMetadata.featureOffset[featCode]);
- // if this is a string, create a new reference in the string
- // reference heap
- // and point to the same string as the string feature in src fs.
- setFeatureValueNotJournaled(trgAddr, featCode, isStringType(rangeType) ?
- this.getStringHeap().cloneStringReference(val) :
- getHeapValue(srcAddr + this.svd.casMetadata.featureOffset[featCode]));
- }
- }
-
- /**
- * Get the value of an address on the heap.
+ * 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 addr
- * The target address.
- * @return The value at the address.
- */
- public int getHeapValue(int addr) {
- return this.getHeap().heap[addr];
+ * @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);
}
/**
- * This is the common point where all sets of values in the heap come through
- * It implements the check for invalid feature setting and potentially the addback.
- *
- * Set the value of a feature of a FS.
- *
- * @param addr
- * The address of the FS.
- * @param feat
- * The code of the feature.
- * @param val
- * The new value for the feature.
- * @exception ArrayIndexOutOfBoundsException
- * If the feature is not a legal feature, or it is not
- * appropriate for the type at the address.
- */
- public void setFeatureValue(int addr, int feat, int val) {
- boolean wasRemoved = checkForInvalidFeatureSetting(addr, feat);
- setFeatureValueNotJournaled(addr, feat, val);
- if (wasRemoved) {
- maybeAddback(addr);
- }
- if (this.svd.trackingMark != null) {
- this.logFSUpdate(addr, addr + this.svd.casMetadata.featureOffset[feat],
[... 2995 lines stripped ...]