You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@uima.apache.org by sc...@apache.org on 2015/11/01 14:11:17 UTC
svn commit: r1711750 [2/2] -
/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
Modified: uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java
URL: http://svn.apache.org/viewvc/uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java?rev=1711750&r1=1711749&r2=1711750&view=diff
==============================================================================
--- uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java (original)
+++ uima/uimaj/branches/experiment-v3-jcas/uimaj-core/src/main/java/org/apache/uima/cas/impl/FSIndexRepositoryImpl.java Sun Nov 1 13:11:17 2015
@@ -24,12 +24,11 @@ import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.Comparator;
-import java.util.ConcurrentModificationException;
import java.util.HashMap;
+import java.util.IdentityHashMap;
import java.util.Iterator;
import java.util.List;
-import java.util.NoSuchElementException;
-import java.util.Set;
+import java.util.Map;
import java.util.Vector;
import org.apache.uima.UIMARuntimeException;
@@ -39,23 +38,18 @@ import org.apache.uima.cas.CASRuntimeExc
import org.apache.uima.cas.FSIndex;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.FeatureStructure;
-import org.apache.uima.cas.SofaFS;
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.FSIndexComparator;
import org.apache.uima.cas.admin.FSIndexRepositoryMgr;
import org.apache.uima.cas.admin.LinearTypeOrder;
import org.apache.uima.cas.admin.LinearTypeOrderBuilder;
-import org.apache.uima.cas.impl.FSIndexFlat.FSIteratorFlat;
import org.apache.uima.cas.text.AnnotationFS;
-import org.apache.uima.internal.util.ComparableIntPointerIterator;
-import org.apache.uima.internal.util.Int2IntArrayMapFixedSize;
-import org.apache.uima.internal.util.IntComparator;
-import org.apache.uima.internal.util.IntPointerIterator;
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.internal.util.ObjHashSet;
+import org.apache.uima.jcas.cas.AnnotationBase;
+import org.apache.uima.jcas.cas.Sofa;
+import org.apache.uima.jcas.tcas.Annotation;
import org.apache.uima.util.Misc;
/**
@@ -64,20 +58,16 @@ import org.apache.uima.util.Misc;
* Some parts of the data here are shared between all views of a CAS.
*
* Many things refer to specific types, and their associated Java Cover classes.
- * There are 2 kinds of cover classes:
- * If JCas is not being used, or if there is no JCas cover class defined for a type, then
- * the Java class FeatureStructureImplC is used as the cover class.
+ * Java impl classes are always used for each type;
+ * If there is no JCas cover class defined for a type, then
+ * the most specific superclass which has a JCas defined class is used;
+ * this is the class TOP or one of its subclasses.
*
- * If the JCas is being used, then the JCas cover type (a subtype of TOP) is used as the cover class.
- *
- * Both of these classes inherit from FeatureStructureImpl (an abstract class)
- *
- * Both of these classes implement the common interface FeatureStructure.
*
* Generic typing:
* User facing APIs can make use of the (JCas) Java cover types, for indexes and iterators over them
* The general generic type used is typically written here as T extends FeatureStructure, where
- * FeatureStructure is the super interface of all cover types (JCas and non-JCas).
+ * FeatureStructure is the super interface of all JCas types.
*
* APIs having no reference to Java cover types (i.e., low level iterators) are not generic, unless they
* are needed to be to pass along the associated type to other APIs.
@@ -85,1685 +75,82 @@ import org.apache.uima.util.Misc;
public class FSIndexRepositoryImpl implements FSIndexRepositoryMgr, LowLevelIndexRepository {
private final static boolean DEBUG = false;
+
+ public final static boolean ITEM_ADDED_TO_INDEX = true;
+ public final static boolean ITEM_REMOVED_FROM_INDEX = false;
/**
* The default size of an index.
*/
public static final int DEFAULT_INDEX_SIZE = 16;
-
+ /**
+ * flag used when removing FSs due to corruption avoidance
+ */
+ public static final boolean SKIP_BAG_INDEXES = true;
+ public static final boolean INCLUDE_BAG_INDEXES = false;
+
/**
* Define this JVM property to allow adding the same identical FS to Set and Sorted indexes more than once.
*/
-
public static final String ALLOW_DUP_ADD_TO_INDEXES = "uima.allow_duplicate_add_to_indexes";
-
- // accessed by FSIntArrayIndex and tests
- public static final boolean IS_ALLOW_DUP_ADD_2_INDEXES = Misc.getNoValueSystemProperty(ALLOW_DUP_ADD_TO_INDEXES);
+ static {
+ if (Misc.getNoValueSystemProperty(ALLOW_DUP_ADD_TO_INDEXES)) {
+ throw new CASAdminException(CASAdminException.INDEX_DUPLICATES_NOT_SUPPORTED);
+ }
+ }
public static final String DISABLE_ENHANCED_WRONG_INDEX = "uima.disable_enhanced_check_wrong_add_to_index";
private static final boolean IS_DISABLE_ENHANCED_WRONG_INDEX_CHECK = Misc.getNoValueSystemProperty(DISABLE_ENHANCED_WRONG_INDEX);
-
- /**
- * Kinds of extra functions for iterators
- */
- public enum IteratorExtraFunction {
- SNAPSHOT, // snapshot iterators
- UNORDERED, // unordered iterators - means unordered among subtypes, but each subtype may have an order
- }
-
- private static final FSIterator emptyFSIterator = new FSIteratorImplBase<FeatureStructure>() {
-
- @Override
- public boolean isValid() {return false;}
-
- @Override
- public FeatureStructure get() throws NoSuchElementException { throw new NoSuchElementException(); }
-
- @Override
- public void moveToNext() {}
-
- @Override
- public void moveToPrevious() {}
-
- @Override
- public void moveToFirst() {}
-
- @Override
- public void moveToLast() {}
-
- @Override
- public void moveTo(FeatureStructure fs) {}
-
- @Override
- public FSIterator<FeatureStructure> copy() {
- return this;
- }
- @Override
- <TT extends AnnotationFS> void moveTo(int begin, int end) {}
- };
-
- private static final LowLevelIterator emptyLlIterator = new FSIntIteratorImplBase<FeatureStructure>(null, null) {
-
- @Override
- public boolean isValid() { return false; }
-
- @Override
- public int get() { throw new NoSuchElementException(); }
-
- @Override
- public void moveTo(int i) {}
-
- @Override
- public void moveToFirst() {}
-
- @Override
- public void moveToLast() {}
-
- @Override
- public Object copy() { return this; }
-
- @Override
- public void moveToNext() {}
-
- @Override
- public void moveToPrevious() {}
-
- @Override
- public int ll_indexSize() { return 0; }
-
- };
+
// Implementation note: the use of equals() here is pretty hairy and
// should probably be fixed. We rely on the fact that when two
// FSIndexComparators are compared, the type of the comparators is
// ignored! A fix for this would be to split the FSIndexComparator
// class into two classes, one for the key-comparator pairs, and one
// for the combination of the two. Note also that we compare two
- // IndexIteratorCachePairs by comparing their
+ // FsIndex_iicps by comparing their
// index.getComparator()s.
- /**
- * IndexIteratorCachePair (iicp)
- *
- * A pair of an leaf index and an iterator cache. An iterator cache is the set of all leaf-indexes necessary
- * to create an iterator for the type of the index.
- *
- * The cache includes the index for the type of this index, as well as all subtypes.
- *
- * compareTo() is based on types and the comparator of the index.
- *
- * T is the Java cover class of the top type (root) in the index set
- *
- * Also includes a lazily initialized reference to a corresponding FSIndexFlat instance.
- *
- * This class is package private to share with FSIndexFlat
- * For Internal Use
- */
- class IndexIteratorCachePair<T extends FeatureStructure>
- implements Comparable<IndexIteratorCachePair<? extends FeatureStructure>> {
-
- /**
- * The "root" index, i.e., index of the type of the iterator.
- * default visibility to make it accessable by FSIndexFlat
- */
- final private FSLeafIndexImpl<T> fsLeafIndex;
-
- FSLeafIndexImpl<T> getFsLeafIndex() {
- return fsLeafIndex;
- }
-
- /**
- * A list of indexes (the sub-indexes that we need for an iterator).
- * I.e., one index for each type that's subsumed by the iterator's type;
- * includes the iterator's type leaf index too.
- */
- private ArrayList<FSLeafIndexImpl<? extends T>> cachedSubFsLeafIndexes = null;
-
- // VOLATILE to permit double-checked locking technique
- private volatile boolean isIteratorCacheSetup = false;
-
- /**
- * Link to associated flattened information, set up lazily, only if this level has an iterator
- */
- private FSIndexFlat<T> flatIndex = null;
-
- /**
- * The type codes corresponding to the cachedSubFsLeafIndexes, set up lazily
- */
- int[] sortedTypeCodes;
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder("IndexIteratorCachePair, index=");
- sb.append(fsLeafIndex).append('\n');
- if (!isIteratorCacheSetup) {
- sb.append(" cache not set up yet");
- } else {
- int len = Math.min(3, cachedSubFsLeafIndexes.size());
- for (int i = 0; i < len; i++) {
- FSLeafIndexImpl<? extends T> lii = cachedSubFsLeafIndexes.get(i);
- sb.append(" cache ").append(i++);
- sb.append(" ").append(lii).append('\n');
- }
- if (cachedSubFsLeafIndexes.size() > 3) {
- sb.append(" ... and " + (cachedSubFsLeafIndexes.size() - 3) + " more\n");
- }
- }
- return sb.toString();
- }
-
- private IndexIteratorCachePair(FSLeafIndexImpl<T> fsLeafIndex) {
- this.fsLeafIndex = fsLeafIndex;
-// setAndTestMask = FSIndexRepositoryImpl.this.cas.getTypeSystemImpl().getSetAndTestMasks(fsLeafIndex.getTypeCode());
- }
-
- // Two IICPs are equal iff their index comparators are equal AND their
- // indexing strategy is the same.
- // Equal is used when creating the index iterator cache to select
- // from the set of all IndexIteratorCachePairs for a particular type,
- // the one that goes with the same index definition
- @Override
- public boolean equals(Object o) {
- if (!(o instanceof IndexIteratorCachePair)) {
- return false;
- }
- @SuppressWarnings("rawtypes")
- final IndexIteratorCachePair iicp = (IndexIteratorCachePair) o;
- return this.fsLeafIndex.getComparator().equals(iicp.fsLeafIndex.getComparator())
- && (this.fsLeafIndex.getIndexingStrategy() == iicp.fsLeafIndex.getIndexingStrategy());
- }
-
-// if this throws, then the Eclipse debugger fails to show the object saying
-// com.sun.jdi.InvocationException occurred invoking method.
- @Override
- public int hashCode() {
- final int prime = 31;
- int result = 1;
- result = prime * result + this.fsLeafIndex.getComparator().hashCode();
- result = prime * result + this.fsLeafIndex.getIndexingStrategy();
- return result;
- }
-
- // Populate the cache.
- // For read-only CASes, this may be called on multiple threads, so do some synchronization
-
- @SuppressWarnings("unchecked")
- private void createIndexIteratorCache() {
- // using double-checked sync - see http://en.wikipedia.org/wiki/Double-checked_locking#Usage_in_Java
- if (isIteratorCacheSetup) {
- return;
- }
- synchronized (this) {
- if (isIteratorCacheSetup) {
- return;
- }
- final Type rootType = this.fsLeafIndex.getComparator().getType();
- final int indexKind = this.fsLeafIndex.getIndexingStrategy();
- ArrayList<Type> allTypes = null;
- if (indexKind == FSIndex.DEFAULT_BAG_INDEX) {
- allTypes = new ArrayList<Type>();
- allTypes.add(rootType);
- } else {
- // includes the original type as element 0
- allTypes = getAllSubsumedTypes(rootType, FSIndexRepositoryImpl.this.sii.tsi);
- }
-
- final ArrayList<FSLeafIndexImpl<? extends T>> tempSubIndexCache = new ArrayList<FSLeafIndexImpl<? extends T>>();
- final int len = allTypes.size();
- if (indexKind == FSIndex.SORTED_INDEX) {
- sortedTypeCodes = new int[len];
- }
-
- for (int i = 0; i < len; i++) {
- final int typeCode = ((TypeImpl) allTypes.get(i)).getCode();
- final ArrayList<IndexIteratorCachePair<?>> indexList = FSIndexRepositoryImpl.this.indexArray[typeCode];
- final int indexPos = indexList.indexOf(this);
- FSLeafIndexImpl<? extends T> leafIndex = (FSLeafIndexImpl<? extends T>) indexList.get(indexPos).fsLeafIndex;
- if (indexPos >= 0) { // is always true???
- tempSubIndexCache.add(leafIndex);
- } else {
- throw new RuntimeException("never happen");
- }
- if (indexKind == FSIndex.SORTED_INDEX) {
- sortedTypeCodes[i] = leafIndex.getTypeCode();
- }
- }
- this.cachedSubFsLeafIndexes = tempSubIndexCache;
- if (this.fsLeafIndex.getIndexingStrategy() == FSIndex.SORTED_INDEX) {
- Arrays.sort(sortedTypeCodes);
- this.flatIndex = FSIndexFlat.enabled ? new FSIndexFlat<>(this) : null; // must follow cachedSubFsLeafIndexes setup
- }
- // assign to "volatile" at end, after all initialization is complete
- this.isIteratorCacheSetup = true;
- } // end of synchronized block
- }
-
-
- /**
- * Maybe not used 3/2015
- *
- * Compares first using the type code of the main types
- * If those are equal,
- * Compares using the comparator objects
- * @see java.lang.Comparable#compareTo(Object)
- *
- */
- public int compareTo(IndexIteratorCachePair<? extends FeatureStructure> cp) {
- final int typeCode1 = ((TypeImpl) this.fsLeafIndex.getType()).getCode();
- final int typeCode2 = ((TypeImpl) cp.fsLeafIndex.getType()).getCode();
- if (typeCode1 < typeCode2) {
- return -1;
- } else if (typeCode1 > typeCode2) {
- return 1;
- } else { // types are equal
- return this.fsLeafIndex.getComparator().compareTo(cp.fsLeafIndex.getComparator());
- }
- }
-
- /**
- *
- * @return the sum of the sizes of the indexes of the type + all subtypes
- */
- int size() {
- int size = 0;
- createIndexIteratorCache(); // does nothing if already created
- final ArrayList<FSLeafIndexImpl<? extends T>> localIc = this.cachedSubFsLeafIndexes;
- final int len = localIc.size();
- for (int i = 0; i < len; i++) {
- size += localIc.get(i).size();
- }
- return size;
- }
-
- boolean has1OrMoreEntries() {
- createIndexIteratorCache(); // does nothing if already created
- final ArrayList<FSLeafIndexImpl<? extends T>> localIc = this.cachedSubFsLeafIndexes;
- final int len = localIc.size();
- for (int i = 0; i < len; i++) {
- if (localIc.get(i).size() > 0) {
- return true;
- };
- }
- return false;
- }
-
- /**
- * A faster version of size() when there are lots of subtypes
- * The cache must be already set up
- *
- * Guess by adding the sizes of up to the first 3 type/subtypes,
- * then add 1 more for each subtype in addition.
- *
- * @return a guess at the size, done quickly
- */
- int guessedSize() {
- final ArrayList<FSLeafIndexImpl<? extends T>> localIc = this.cachedSubFsLeafIndexes;
- final int len = localIc.size();
- final int lim = Math.min(3, len);
- int size = 0;
- for (int i = 0; i < lim; i++) {
- size += localIc.get(i).size();
- }
- size += len - lim;
- return size;
- }
-
- /**
- * Flat array filled, ordered
- * @param flatArray the array to fill
- */
- public void fillFlatArray(FeatureStructure[] flatArray) {
- LowLevelIterator it = (LowLevelIterator) createPointerIterator(this);
- int i = 0;
- while (it.isValid()) {
- if (i >= flatArray.length) {
- throw new ConcurrentModificationException();
- }
- flatArray[i++] = cas.createFS(it.ll_get());
- if (DEBUG) {
- int tc1 = fsLeafIndex.getTypeCode();
- int tc2 = ((TypeImpl)(flatArray[i-1].getType())).getCode();
- if (!subsumes(tc1, tc2)) {
- throw new RuntimeException(String.format("FillFlatArray for element %,d produced a non-subtype, tc1 = %d, tc2 = %d%n"
- + "iicp = %s%nfs = %s%n",
- tc1, tc2,
- i-1,
- this,
- flatArray[i-1]));
- }
- }
- it.moveToNext();
- }
- if (i != flatArray.length) {
-// System.out.println("Debug - got iterator invalid before all items filled, i = " + i + ", size = " + flatArray.length);
- throw new ConcurrentModificationException();
- }
- }
-
- Int2IntArrayMapFixedSize createIndexUpdateCountsAtReset() {
- Int2IntArrayMapFixedSize m = new Int2IntArrayMapFixedSize(sortedTypeCodes.length);
- captureIndexUpdateCounts(m);
- return m;
- }
-
- void captureIndexUpdateCounts() {
- captureIndexUpdateCounts(this.flatIndex.indexUpdateCountsResetValues);
- }
-
- private void captureIndexUpdateCounts(Int2IntArrayMapFixedSize m) {
- final int[] localSortedTypeCodes = sortedTypeCodes;
- for (int i = 0; i < localSortedTypeCodes.length; i++) {
- m.putAtIndex(i, detectIllegalIndexUpdates[localSortedTypeCodes[i]]);
- }
- }
-
- boolean isUpdateFreeSinceLastCounterReset() {
- final Int2IntArrayMapFixedSize typeCode2updateCount = this.flatIndex.indexUpdateCountsResetValues;
- final int[] localSortedTypeCodes = sortedTypeCodes;
- for (int i = 0; i < localSortedTypeCodes.length; i++) {
- if (typeCode2updateCount.getAtIndex(i) != detectIllegalIndexUpdates[localSortedTypeCodes[i]]) {
- return false;
- }
- }
- return true;
- }
-
- boolean isUpdateFreeSinceLastCounterReset(final int typeCode) {
- return this.flatIndex.indexUpdateCountsResetValues.get(typeCode, sortedTypeCodes) ==
- detectIllegalIndexUpdates[typeCode];
- }
-
- boolean subsumes(int superType, int subType) {
- return cas.getTypeSystemImpl().subsumes(superType, subType);
- }
-
- // debug
- CASImpl getCASImpl() {
- return cas;
- }
-
- void addToIteratedSortedIndexes() {
- iteratedSortedIndexes.add(this);
- }
-
- // flatIndex is null except for sorted indexes
- private boolean hasFlatIndex() {
- if (! FSIndexFlat.enabled) {
- return false;
- } else {
- return isIteratorCacheSetup && (flatIndex != null) && flatIndex.hasFlatIndex();
- }
- }
-
- } // end of class definition for IndexIteratorCachePair
-
-
- /* ============================================================================================================*/
- /* Pointer Iterators
- /* ============================================================================================================*/
- /**
- * Create an "ordered" (e.g. one that maintains iicp sort order for sorted index) pointer iterator over an iicp
- * @param iicp - the index plus its subtype list of indexes
- * @return an int iterator
- */
- IntPointerIterator createPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp) {
- return createPointerIterator(iicp, false);
- }
-
-
- /**
- * Create an ordered or iicp-unordered pointer iterator over an iicp
- *
- * Note that flattened index iterators are not int style; and they're created higher up...
- *
- * @param iicp - the index plus its subtype list of indexes
- * @param is_unordered true if ordering among subtypes not needed
- * @return an int iterator
- */
- <T extends FeatureStructure> IntPointerIterator createPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp, boolean is_unordered) {
- iicp.createIndexIteratorCache();
- if (iicp.cachedSubFsLeafIndexes.size() > 1) {
- final int strat = iicp.fsLeafIndex.getIndexingStrategy();
- if (strat == FSIndex.BAG_INDEX ||
- strat == FSIndex.SET_INDEX || // because set indexes do not enforce ordering
- is_unordered) {
- return new PointerIteratorUnordered(iicp);
- } else {
- return new PointerIterator(iicp);
- }
- }
- return createLeafPointerIterator(iicp);
- }
-
- <T extends FeatureStructure> IntPointerIterator createPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp, int fs) {
- return createPointerIterator(iicp, false, fs);
- }
-
- <T extends FeatureStructure> IntPointerIterator createPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp, boolean is_unordered, int fs) {
- IntPointerIterator it = createPointerIterator(iicp, is_unordered);
- it.moveTo(fs);
- return it;
- }
-
- private <T extends FeatureStructure> IntPointerIterator createLeafPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp) {
- FSLeafIndexImpl<T> leafIndex = (FSLeafIndexImpl<T>) iicp.fsLeafIndex;
- return leafIndex.pointerIterator(leafIndex, this.detectIllegalIndexUpdates, leafIndex.getTypeCode());
- }
-
- /**
- * The next 3 classes (PointerIterator, PointerIteratorUnordered and LeafPointerIterator)
- * implement iterators for particular indexes.
- *
- * PointerIteratorUnordered is used for bag and things like all indexed fs where order is not important.
- * It uses the same impl as PointerIterator, except it works by sequentially iterating over each of the
- * iterator pieces.
- *
- * This class handles the concepts involved with iterating over a type and
- * all of its subtypes, keeping the ordering among the subtypes.
- *
- * The LeafPointerIterator handles just iterating over a particular type or subtype
- * (the one that this class picks).
- *
- * The iterator implementation for indexes. Tricky because the iterator needs to be able to move
- * backwards as well as forwards.
- */
- private class PointerIterator implements IntPointerIterator, LowLevelIterator {
-
- /**
- * The number of elements to keep in order before the binary heap starts. This section helps the
- * performance in cases where a couple of types dominate the index.
- */
- static final int SORTED_SECTION = 3;
-
- // The IICP
- final private IndexIteratorCachePair<? extends FeatureStructure> iicp;
-
- protected IndexIteratorCachePair<? extends FeatureStructure> getIicp() {
- return iicp;
- }
-
- // An array of ComparableIntPointerIterators, one for each subtype.
- // Each instance of these has a Class.this kind of ref to a particular variety of FSLeafIndex (bag, set, sorted) corresponding to 1 type
- // This array has the indexes for all the subtypes that were non-empty at the time of iterator creation
- protected ComparableIntPointerIterator[] iterators;
-
- int lastValidIndex;
-
- // snapshot to detectIllegalIndexUpdates
- // need to move this to ComparableIntPointerIterator so it can be tested
-
- // currentIndex is always 0
-
- // The iterator works in two modes:
- // Forward and backward processing. This flag tells which mode we're in.
- // The iterator heap needs to be reconstructed when we switch direction.
- protected boolean wentForward;
-
- // Comparator that is used to compare FS addresses for the purposes of
- // iteration.
- final private IntComparator iteratorComparator;
-
- // skip including iterators for empty indexes
- // The concurrent modification exception notification doesn't occur when subsequent "adds" are done, but
- // that is the same as current:
- // where the move to first would mark the iterator "invalid" (because it was initially empty) and it would be
- // subsequently ignored - same effect
- private ComparableIntPointerIterator[] initPointerIterator() {
- // Note to maintainers: Make sure the iterator cache exists on all paths calling this
- final ArrayList<?> cachedSubIndexes = iicp.cachedSubFsLeafIndexes;
- final int length = cachedSubIndexes.size();
-
- final ArrayList<ComparableIntPointerIterator> pia = new ArrayList<ComparableIntPointerIterator>(cachedSubIndexes.size());
-
- // put all non-empty leaf iterators into the iteration, and if all are empty, put the last one in
- // (to avoid handling 0 as a special case)
- for (int i = 0; i < length; i++) {
- final FSLeafIndexImpl<?> leafIndex = (FSLeafIndexImpl<?>) cachedSubIndexes.get(i);
- if ((leafIndex.size() > 0) ||
- ((i == length -1) && // this logic puts in the last one if all are empty
- (0 == pia.size()))) {
- pia.add(leafIndex.pointerIterator(
- this.iteratorComparator,
- FSIndexRepositoryImpl.this.detectIllegalIndexUpdates,
- ((TypeImpl) leafIndex.getType()).getCode()));
- }
- }
-
- ComparableIntPointerIterator[] piaa = new ComparableIntPointerIterator[pia.size()];
- return pia.toArray(piaa);
- }
-
- private PointerIterator(final IndexIteratorCachePair<? extends FeatureStructure> iicp) {
- // next 3 are final so aren't done in the common init
- this.iicp = iicp;
- this.iteratorComparator = iicp.cachedSubFsLeafIndexes.get(0);
- this.iterators = initPointerIterator();
- moveToFirst();
- }
-
- private PointerIterator(final IndexIteratorCachePair<? extends FeatureStructure> iicp, int fs) {
- // next 3 are final so aren't done in the common init
- this.iicp = iicp;
- this.iteratorComparator = iicp.cachedSubFsLeafIndexes.get(0);
- this.iterators = initPointerIterator();
- moveTo(fs);
- }
-
- public boolean isValid() {
- // We're valid as long as at least one index is.
- return (this.lastValidIndex >= 0 );
- }
-
- protected ComparableIntPointerIterator<?> checkConcurrentModification(int i) {
- final FSIntIteratorImplBase<?> cipi = (FSIntIteratorImplBase<?>) this.iterators[i];
- cipi.checkConcurrentModification(); // throws if concurrentModification
- return cipi;
- }
-
- /**
- * Test the order with which the two iterators should be used. Introduces arbitrary ordering for
- * equivalent FSs. Only called with valid iterators.
- *
- * @param l
- * @param r
- * @param dir
- * Direction of movement, 1 for forward, -1 for backward
- * @return true if the left iterator needs to be used before the right one.
- */
- private boolean is_before(ComparableIntPointerIterator l, ComparableIntPointerIterator r,
- int dir) {
- final int il = l.get();
- final int ir = r.get();
- int d = this.iteratorComparator.compare(il, ir);
-
- // If two FSs are identical wrt the comparator of the index,
- // we still need to be able to distinguish them to be able to have a
- // well-defined sequence. In that case, we arbitrarily order FSs by
- // their
- // addresses. We need to do this in order to be able to ensure that a
- // reverse iterator produces the reverse order of the forward iterator.
- if (d == 0) {
- d = il - ir;
- }
-
- return d * dir < 0;
- }
-
- /**
- * Move the idx'th element up in the heap until it finds its proper position.
- *
- * @param it
- * indexes[idx]
- * @param idx
- * Element to move
- * @param dir
- * Direction of iterator movement, 1 for forward, -1 for backward
- */
- private void heapify_up(ComparableIntPointerIterator it, int idx, int dir) {
- FSIndexFlat<? extends FeatureStructure> flatIndexInfo = iicp.flatIndex;
- if (null != flatIndexInfo) {
- flatIndexInfo.incrementReorderingCount();
- }
- int nidx;
-
- while (idx > SORTED_SECTION) {
- nidx = (idx + SORTED_SECTION - 1) >> 1;
- if (!is_before(it, this.iterators[nidx], dir)) {
- this.iterators[idx] = it;
- return;
- }
- this.iterators[idx] = this.iterators[nidx];
- idx = nidx;
- }
-
- while (idx > 0) {
- nidx = idx - 1;
- if (!is_before(it, this.iterators[nidx], dir)) {
- this.iterators[idx] = it;
- return;
- }
- this.iterators[idx] = this.iterators[nidx];
- idx = nidx;
- }
-
- this.iterators[idx] = it;
- }
-
- /**
- * Move the top element down in the heap until it finds its proper position.
- *
- * @param it
- * indexes[0]
- * @param dir
- * Direction of iterator movement, 1 for forward, -1 for backward
- */
- private void heapify_down(ComparableIntPointerIterator it, int dir) {
- FSIndexFlat<? extends FeatureStructure> flatIndexInfo = iicp.flatIndex;
- if (null != flatIndexInfo) {
- flatIndexInfo.incrementReorderingCount();
- }
-
- if (!it.isValid()) {
- final ComparableIntPointerIterator itl = checkConcurrentModification(this.lastValidIndex);
- this.iterators[this.lastValidIndex] = it;
- this.iterators[0] = itl;
- --this.lastValidIndex;
- it = itl;
- }
-
- final int num = this.lastValidIndex;
- if ((num < 1) || !is_before(checkConcurrentModification(1), it, dir)) {
- return;
- }
-
- int idx = 1;
- this.iterators[0] = this.iterators[1];
- final int end = Math.min(num, SORTED_SECTION);
- int nidx = idx + 1;
-
- // make sure we don't leave the iterator in a completely invalid state
- // (i.e. one it can't recover from using moveTo/moveToFirst/moveToLast)
- // in case of a concurrent modification
- try {
- while (nidx <= end) {
- if (!is_before(checkConcurrentModification(nidx), it, dir)) {
- return; // passes through finally
- }
-
- this.iterators[idx] = this.iterators[nidx];
- idx = nidx;
- nidx = idx + 1;
- }
-
- nidx = SORTED_SECTION + 1;
- while (nidx <= num) {
- if ((nidx < num)
- && is_before(checkConcurrentModification(nidx + 1),
- checkConcurrentModification(nidx), dir)) {
- ++nidx;
- }
-
- if (!is_before(this.iterators[nidx], it, dir)) {
- return;
- }
-
- this.iterators[idx] = this.iterators[nidx];
- idx = nidx;
- nidx = (nidx << 1) - (SORTED_SECTION - 1);
- }
- } finally {
- this.iterators[idx] = it;
- }
- }
-
- public void moveToFirst() {
- int lvi = this.iterators.length - 1;
- // Need to consider all iterators.
- // Set all iterators to insertion point.
- int i = 0;
- while (i <= lvi) {
- final FSIntIteratorImplBase<?> it = (FSIntIteratorImplBase<?>) this.iterators[i];
- it.resetConcurrentModification();
- it.moveToFirst();
- if (it.isValid()) {
- heapify_up(it, i, 1);
- ++i;
- } else {
- // swap this iterator with the last possibly valid one
- // lvi might be equal to i, this will not be a problem
- this.iterators[i] = this.iterators[lvi];
- this.iterators[lvi] = it;
- --lvi;
- }
- }
- // configured to continue with forward iterations
- this.wentForward = true;
- this.lastValidIndex = lvi;
- }
-
- public void moveToLast() {
- int lvi = this.iterators.length - 1;
- // Need to consider all iterators.
- // Set all iterators to insertion point.
- int i = 0;
- while (i <= lvi) {
- final FSIntIteratorImplBase<?> it = (FSIntIteratorImplBase<?>) this.iterators[i];
- it.resetConcurrentModification();
- it.moveToLast();
- if (it.isValid()) {
- heapify_up(it, i, -1);
- ++i;
- } else {
- // swap this iterator with the last possibly valid one
- // lvi might be equal to i, this will not be a problem
- this.iterators[i] = this.iterators[lvi];
- this.iterators[lvi] = it;
- --lvi;
- }
- }
- // configured to continue with backward iterations
- this.wentForward = false;
- this.lastValidIndex = lvi;
- }
-
- public void moveToNext() {
- if (!isValid()) {
- return;
- }
-
- final ComparableIntPointerIterator it0 = checkConcurrentModification(0);
-
- if (this.wentForward) {
- it0.inc();
- heapify_down(it0, 1);
- } else {
- // We need to increment everything.
- int lvi = this.iterators.length - 1;
- int i = 1;
- while (i <= lvi) {
- // Any iterator other than the current one needs to be
- // incremented until it's pointing at something that's
- // greater than the current element.
- final ComparableIntPointerIterator it = checkConcurrentModification(i);
- // If the iterator we're considering is not valid, we
- // set it to the first element. This should be it for this iterator...
- if (!it.isValid()) {
- it.moveToFirst();
- }
- // Increment the iterator while it is valid and pointing
- // at something smaller than the current element.
- while (it.isValid() && is_before(it, it0, 1)) {
- it.inc();
- }
-
- // find placement
- if (it.isValid()) {
- heapify_up(it, i, 1);
- ++i;
- } else {
- // swap this iterator with the last possibly valid one
- // lvi might be equal to i, this will not be a problem
- this.iterators[i] = this.iterators[lvi];
- this.iterators[lvi] = it;
- --lvi;
- }
- }
-
- this.lastValidIndex = lvi;
- this.wentForward = true;
-
- it0.inc();
- heapify_down(it0, 1);
- }
- }
-
- public void moveToPrevious() {
- if (!isValid()) {
- return;
- }
-
- final ComparableIntPointerIterator it0 = checkConcurrentModification(0);
- if (!this.wentForward) {
- it0.dec();
- // this also takes care of invalid iterators
- heapify_down(it0, -1);
- } else {
- // We need to decrement everything.
- int lvi = this.iterators.length - 1;
- int i = 1;
- while (i <= lvi) {
- // Any iterator other than the current one needs to be
- // decremented until it's pointing at something that's
- // smaller than the current element.
- final ComparableIntPointerIterator it = checkConcurrentModification(i);
- // If the iterator we're considering is not valid, we
- // set it to the last element. This should be it for this iterator...
- if (!it.isValid()) {
- it.moveToLast();
- }
- // Decrement the iterator while it is valid and pointing
- // at something greater than the current element.
- while (it.isValid() && is_before(it, it0, -1)) {
- it.dec();
- }
-
- // find placement
- if (it.isValid()) {
- heapify_up(it, i, -1);
- ++i;
- } else {
- // swap this iterator with the last possibly valid one
- // lvi might be equal to i, this will not be a problem
- this.iterators[i] = this.iterators[lvi];
- this.iterators[lvi] = it;
- --lvi;
- }
- }
-
- this.lastValidIndex = lvi;
- this.wentForward = false;
-
- it0.dec();
- heapify_down(it0, -1);
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIterator#ll_get()
- */
- public int get() throws NoSuchElementException {
- return ll_get();
- }
-
- public int ll_get() {
- if (!isValid()) {
- throw new NoSuchElementException();
- }
- return checkConcurrentModification(0).get();
- }
-
- public Object copy() {
- // If this.isValid(), return a copy pointing to the same element.
- if (this.isValid()) {
- PointerIterator it = new PointerIterator(this.iicp);
- moveTo(this.get());
- return it;
- }
- // Else, create a copy that is also not valid.
- final PointerIterator pi = new PointerIterator(this.iicp);
- pi.moveToFirst();
- pi.moveToPrevious();
- return pi;
- }
-
- /**
- * @see org.apache.uima.internal.util.IntPointerIterator#moveTo(int)
- */
- public void moveTo(int fs) {
- moveTo(fs, false);
- }
- /**
- * @param fs the FS to move to
- * @param isExact if true, move to this exact one (must be present),
- * if false, move to the left-most element that is equal to fs
- * using the comparator for the index or if none is equal,
- * move to the next element that is greater than this fs
- * or invalid position of all are less than this fs
- */
- void moveTo(int fs, boolean isExact) {
- int lvi = this.iterators.length - 1;
- // Need to consider all iterators.
- // Set all iterators to insertion point.
- int i = 0;
- while (i <= lvi) {
- final FSIntIteratorImplBase<?> it = (FSIntIteratorImplBase<?>) this.iterators[i];
- it.moveTo(fs, isExact);
- if (it.isValid()) {
- heapify_up(it, i, 1);
- ++i;
- } else {
- // swap this iterator with the last possibly valid one
- // lvi might be equal to i, this will not be a problem
- this.iterators[i] = this.iterators[lvi];
- this.iterators[lvi] = it;
- --lvi;
- }
- }
- // configured to continue with forward iterations
- this.wentForward = true;
- this.lastValidIndex = lvi;
-
- // moved to leaf iterator
-// if (!isValid()) {
-// // this means the moveTo found the insert point at the end of the index
-// // so just return invalid, since there's no way to return an insert point for a position
-// // that satisfies the FS at that position is greater than fs
-// return;
-// }
-// // Go back until we find a FS that is really smaller
-// while (true) {
-// moveToPrevious();
-// if (isValid()) {
-// int prev = get();
-// if (this.iicp.index.compare(prev, fs) != 0) {
-// moveToNext();
-// break;
-// }
-// } else {
-// moveToFirst();
-// break;
-// }
-// }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIterator#moveToNext()
- */
- public void inc() {
- moveToNext();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIterator#moveToPrevious()
- */
- public void dec() {
- moveToPrevious();
- }
-
- public int ll_indexSize() {
- return this.iicp.size();
- }
-
- public LowLevelIndex ll_getIndex() {
- return (LowLevelIndex) this.iicp.fsLeafIndex;
- }
-
- @Override
- public String toString() {
- StringBuilder sb = new StringBuilder(this.getClass().getSimpleName() + " [iicp=" + iicp + ", indexes=\n");
- int i = 0;
- for (ComparableIntPointerIterator item : iterators) {
- sb.append(" ").append(i++).append(" ").append(item).append('\n');
- if (i > 4) {
- break;
- }
- }
- if (i < iterators.length) {
- sb.append(" and ").append(iterators.length - i).append(" more.\n");
- }
- sb.append(" lastValidIndex="
- + lastValidIndex + ", wentForward=" + wentForward + ", iteratorComparator=" + iteratorComparator + "]");
- return sb.toString();
- }
-
- } // end of class PointerIterator
-
- /**
- * Version of pointer iterator for unordered uses (bags and getAllIndexedFSs
- * Since bags have no order, simplify the iteration by just going thru sequentially
- * all the subtypes
- *
- */
- private class PointerIteratorUnordered extends PointerIterator {
-
- private PointerIteratorUnordered(final IndexIteratorCachePair<? extends FeatureStructure> iicp) {
- super(iicp);
- }
-
- private PointerIteratorUnordered(final IndexIteratorCachePair<? extends FeatureStructure> iicp, int fs) {
- super(iicp);
- moveTo(fs);
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#isValid()
- */
- @Override
- public boolean isValid() {
- return (lastValidIndex >= 0) && (lastValidIndex < iterators.length);
- }
-
-
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#ll_get()
- */
- @Override
- public int ll_get() {
- if (!isValid()) {
- throw new NoSuchElementException();
- }
- return checkConcurrentModification(lastValidIndex).get();
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#moveToFirst()
- */
- @Override
- public void moveToFirst() {
- for (int i = 0; i < iterators.length; i++) {
- FSIntIteratorImplBase<?> it = (FSIntIteratorImplBase<?>) iterators[i];
- it.moveToFirst();
- it.resetConcurrentModification();
- if (it.isValid()) {
- lastValidIndex = i;
- return;
- }
- }
- lastValidIndex = -1; // no valid index
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#moveToLast()
- */
- @Override
- public void moveToLast() {
- for (int i = iterators.length -1; i >= 0; i--) {
- FSIntIteratorImplBase<?> it = (FSIntIteratorImplBase<?>) iterators[i];
- it.moveToLast();
- it.resetConcurrentModification();
- if (it.isValid()) {
- lastValidIndex = i;
- return;
- }
- }
- lastValidIndex = -1;
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#moveToNext()
- */
- @Override
- public void moveToNext() {
- if (!isValid()) {
- return;
- }
-
- ComparableIntPointerIterator it = checkConcurrentModification(lastValidIndex);
-
- it.inc();
-
- while (!it.isValid()) {
- // loop until find valid index, or end
- lastValidIndex ++;
- if (lastValidIndex == iterators.length) {
- return; // all subsequent indices are invalid
- }
- it = iterators[lastValidIndex];
- it.moveToFirst();
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#moveToPrevious()
- */
- @Override
- public void moveToPrevious() {
- if (!isValid()) {
- return;
- }
-
- ComparableIntPointerIterator it = checkConcurrentModification(lastValidIndex);
-
- it.dec();
-
- while (!it.isValid()) {
- // loop until find valid index or end
- lastValidIndex --;
- if (lastValidIndex < 0) {
- return;
- }
- it = iterators[lastValidIndex];
- it.moveToLast();
- }
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#copy()
- */
- @Override
- public Object copy() {
- // If this.isValid(), return a copy pointing to the same element.
- if (this.isValid()) {
- return new PointerIteratorUnordered(getIicp(), get());
- }
- // Else, create a copy that is also not valid.
- final PointerIteratorUnordered pi = new PointerIteratorUnordered(getIicp());
- pi.moveToFirst();
- pi.moveToPrevious();
- return pi;
- }
-
- /* (non-Javadoc)
- * @see org.apache.uima.cas.impl.FSIndexRepositoryImpl.PointerIterator#moveTo(int)
- *
- * moveTo is used internally in the contains and find methods of FSIndexes
- * The unordered version is only called on for bags and sets having subtypes
- * There, the logic needs to iterate over all the iterators, looking for an equal (for set) or eq one (for bags)
- * If not found, its more useful to make the iterator not-valid
- *
- * Should not be called if sorted, but do something reasonable:
- * stop on first one found equal. This will be the left-most
- * equal one in cas there are multiples of this particular type
- * if none found equal on one subType, go to next subType
- * if none found equal on any subType, mark iterator invalid
- * (NOTE: not really the contract for moveTo, but
- * as stated in the beginning, probably not called for unordered)
- */
- @Override
- public void moveTo(int fs) {
- moveTo(fs, false);
- }
-
- void moveTo(int fs, boolean isExact) {
- IndexIteratorCachePair<? extends FeatureStructure> iicp = getIicp();
- int kind = iicp.fsLeafIndex.getIndexingStrategy();
- for (int i = 0; i < iterators.length; i++) {
- if (kind == FSIndex.SORTED_INDEX) {
- // case: sorted index being used in unordered mode, eg. for getAllIndexedFSs
- FSIntArrayIndex<? extends FeatureStructure> sortedIndex =
- (FSIntArrayIndex<? extends FeatureStructure>) ((FSIntIteratorImplBase) iterators[i]).getFSLeafIndexImpl();
- if ((isExact ? sortedIndex.findEq(fs) :sortedIndex.findLeftmost(fs)) < 0) {
- continue; // fs not found in the index of this subtype
- }
- }
- // if sorted index, fs is in this leaf index
- // if it is not sorted, we're in some type/subtype of the index
- FSIntIteratorImplBase<?> li = (FSIntIteratorImplBase<?>) iterators[i];
- li.moveTo(fs);
- if (li.isValid() && (0 == iicp.fsLeafIndex.compare(fs, li.get()))) {
- lastValidIndex = i;
- li.resetConcurrentModification();
- return;
- }
- // if get here, iterate to the next subtype
- }
- // if get here, nothing found that was equal or eq for bag
- // make iterator invalid
- moveToFirst();
- moveToPrevious();
- }
- }
/**
- * This class and the previous ones (PointerIterator, PointerIteratorUnordered, and LeafPointerIterator)
- * implement iterators for particular indexes.
+ * The index repository holds instances of defined and built-in indexes.
*
- * PointerIterator and PointerIteratorUnordered handles the concepts involved with iterating over a type and
- * all of its subtypes
+ * Indexes implement Java's NavigableSet ( *** do this later ??? may be a bit of work to make work over subtypes )
*
- * This class handles just iterating over a particular type or subtype
- * (the one that the previous class picks).
-
- * The iterator implementation for indexes. Tricky because the iterator needs to be able to move
- * backwards as well as forwards.
- */
-
- // removed 4/2015 - was an extra wrapper, needed maintenance, and the wrapper provided no purpose.
-// private class LeafPointerIterator implements IntPointerIterator, LowLevelIterator {
-//
-// // The IICP
-// final private IndexIteratorCachePair<? extends FeatureStructure> iicp;
-//
-// // The underlying iterator
-// final private ComparableIntPointerIterator iter;
-//
-//
-// @Override
-// public String toString() {
-// return "LeafPointerIterator [iicp=" + iicp + ", index=" + iter + "]";
-// }
-//
-// private LeafPointerIterator(final IndexIteratorCachePair<? extends FeatureStructure> iicp) {
-// this.iicp = iicp;
-// // Make sure the iterator cache exists.
-// final ArrayList<?> iteratorCache = iicp.cachedSubFsLeafIndexes;
-// final FSLeafIndexImpl<?> leafIndex = (FSLeafIndexImpl<?>) iteratorCache.get(0);
-// this.iter = leafIndex.pointerIterator(leafIndex,
-// FSIndexRepositoryImpl.this.detectIllegalIndexUpdates,
-// ((TypeImpl) leafIndex.getType()).getCode());
-// }
-//
-// private LeafPointerIterator(IndexIteratorCachePair<? extends FeatureStructure> iicp, int fs) {
-// this(iicp);
-// moveTo(fs);
-// }
-//
-// private ComparableIntPointerIterator checkConcurrentModification() {
-// if (this.iter.isConcurrentModification()) {
-// throw new ConcurrentModificationException();
-// }
-// return this.iter;
-// }
-//
-// public boolean isValid() {
-// return this.iter.isValid();
-// }
-//
-// public void moveToLast() {
-// this.iter.resetConcurrentModification();
-// this.iter.moveToLast();
-// }
-//
-// public void moveToFirst() {
-// this.iter.resetConcurrentModification();
-// this.iter.moveToFirst();
-// }
-//
-// public void moveToNext() {
-// checkConcurrentModification().inc();
-// }
-//
-// public void moveToPrevious() {
-// checkConcurrentModification().dec();
-// }
-//
-// public int get() throws NoSuchElementException {
-// return ll_get();
-// }
-//
-// public int ll_get() {
-// if (!isValid()) {
-// throw new NoSuchElementException();
-// }
-// return checkConcurrentModification().get();
-// }
-//
-// public Object copy() {
-// // If this.isValid(), return a copy pointing to the same element.
-// if (this.isValid()) {
-// return new LeafPointerIterator(this.iicp, this.get());
-// }
-// // Else, create a copy that is also not valid.
-// final LeafPointerIterator pi = new LeafPointerIterator(this.iicp);
-// pi.moveToFirst();
-// pi.moveToPrevious();
-// return pi;
-// }
-//
-// /**
-// * @see org.apache.uima.internal.util.IntPointerIterator#moveTo(int)
-// */
-// public void moveTo(int fs) {
-// this.iter.resetConcurrentModification();
-// this.iter.moveTo(fs);
-// }
-//
-// /*
-// * (non-Javadoc)
-// *
-// * @see org.apache.uima.cas.impl.LowLevelIterator#moveToNext()
-// */
-// public void inc() {
-// checkConcurrentModification().inc();
-// }
-//
-// /*
-// * (non-Javadoc)
-// *
-// * @see org.apache.uima.cas.impl.LowLevelIterator#moveToPrevious()
-// */
-// public void dec() {
-// checkConcurrentModification().dec();
-// }
-//
-// public int ll_indexSize() {
-// return this.iicp.size();
-// }
-//
-// public LowLevelIndex ll_getIndex() {
-// return (LowLevelIndex) this.iicp.fsLeafIndex;
-// }
-//
-// } // end of LeafPointerIterator
-
- /**
- * This implementation creates a pseudo index that is
- * flattened and
- * copied (so it is a snapshot), and
- * returns an iterator over that
- *
- */
- private class SnapshotPointerIterator<T extends FeatureStructure> implements IntPointerIterator, LowLevelIterator {
-
- final private FSIntArrayIndex<T> sortedLeafIndex;
- final private int[] snapshot;
- final private int size; // can't get from snapshot.length - that might have extra space https://issues.apache.org/jira/browse/UIMA-4248
- private int pos = 0;
-
- @Override
- public String toString() {
- return "SnapshotPointerIterator[size: " + snapshot.length + ", position: " + pos + "]";
- }
-
- private SnapshotPointerIterator(IndexIteratorCachePair<T> iicp0) {
- this(iicp0, false);
- }
-
- private SnapshotPointerIterator(IndexIteratorCachePair<T> iicp0, boolean isRootOnly) {
- FSLeafIndexImpl<T> leafIndex = iicp0.fsLeafIndex;
- FSIndexComparator comp = leafIndex.getComparator();
-
- final int size = iicp0.size(); // adds up all the sizes of the indexes
- sortedLeafIndex = (FSIntArrayIndex<T>) FSIndexRepositoryImpl.this.<T>addNewIndexCore(comp, size, FSIndex.SORTED_INDEX);
- snapshot = sortedLeafIndex.getVector().getArray();
- this.size = size;
- flattenCopy(iicp0, isRootOnly);
- sortedLeafIndex.getVector().setSize(size);
- moveToFirst();
- }
-
- private SnapshotPointerIterator(IndexIteratorCachePair<T> iicp0, int fs) {
- this(iicp0);
- moveTo(fs);
- }
-
- private void flattenCopy(IndexIteratorCachePair<T> iicp0, boolean isRootOnly) {
-
-
-// if (iicp0.iteratorCache.size() > 1) {
-// if (indexKind == FSIndex.BAG_INDEX) {
-// // have a set of bag indexes, just copy them into the snapshot in bulk
-// } else {
-// // for sorted or set, extract the elements
-//
-// }
- LowLevelIterator it = (LowLevelIterator)
- (isRootOnly ?
- createLeafPointerIterator(iicp0) :
- createPointerIterator(iicp0));
- int i = 0;
- while (it.isValid()) {
- snapshot[i++] = it.ll_get();
- it.moveToNext();
- }
- }
-
- public boolean isValid() {
- return (0 <= pos) && (pos < size);
- }
-
- public void moveToLast() {
- pos = size - 1;
- }
-
- public void moveToFirst() {
- pos = 0;
- }
-
- public void moveToNext() {
- pos ++;
- }
-
- public void moveToPrevious() {
- pos --;
- }
-
- public int get() throws NoSuchElementException {
- return ll_get();
- }
-
- public int ll_get() {
- if (!isValid()) {
- throw new NoSuchElementException();
- }
- return snapshot[pos]; // no concurrent mod test
- }
-
- /**
- * @see org.apache.uima.internal.util.IntPointerIterator#moveTo(int)
- */
- public void moveTo(int fs) {
- moveTo(fs, false);
- }
-
- void moveTo(int fs, boolean isExact) {
- if (sortedLeafIndex.getComparator().getNumberOfKeys() == 0) {
- // use identity, search from beginning to get "left-most"
- int i = 0;
- for (; i < size; i++) {
- if (fs == snapshot[i]) {
- break;
- }
- }
- pos = i;
- } else {
- int position = isExact ? sortedLeafIndex.findEq(fs) : sortedLeafIndex.findLeftmost(fs);
- if (position >= 0) {
- pos = position;
- } else {
- if (isExact) {
- throw new UIMARuntimeException(); // Internal error
- }
- pos = -(position + 1);
- }
- }
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIterator#moveToNext()
- */
- public void inc() {
- pos ++; // no concurrent mod check
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIterator#moveToPrevious()
- */
- public void dec() {
- pos --; // no concurrent mod check
- }
-
- public int ll_indexSize() {
- return size;
- }
-
- public Object copy() {
- // If this.isValid(), return a copy pointing to the same element.
- IndexIteratorCachePair<T> iicp = new IndexIteratorCachePair<T>(sortedLeafIndex);
- if (this.isValid()) {
- SnapshotPointerIterator<T> it = new SnapshotPointerIterator<T>(iicp);
- it.moveTo(this.get(), true); // move to exact match
- return it;
- }
- // Else, create a copy that is also not valid.
- SnapshotPointerIterator<T> pi = new SnapshotPointerIterator<T>(iicp);
- pi.pos = -1;
- return pi;
- }
-
- public LowLevelIndex ll_getIndex() {
- return (LowLevelIndex) sortedLeafIndex;
- }
-
- } // end of SnapshotPointerIterator
-
- /**
- * Implementation of a particular index for a particular Type (and its subtypes)
- *
- * @param <T> - the particular type (and it subtypes) this particular index is associated with
+ * There are various kinds of iterators that can be obtained:
+ * Iterator - plain Java iterator - goes forward only
+ * FSIterator - an extension that can go in either direction, and can locate a position via an FS
+ *
+ * Low-level iterators return internal "ints" representing FS ids; these are only for backwards compatibility
+ * IntPointerIterator - for backwards compatibility - a wrapper around FSIterator, plus inc() dec()
+ * - may be dropped if only internally used
+ * LowLevelIterator - for backwards compatibility - a wrapper around FSIterator, plus ll_get, ll_indexSize, ll_getIndex
+ *
+ * To obtain normal iterators, use the FSIndex methods
+ * iterator
+ * iterator(FeatureStructure) - to initially position to the FS)
+ * index.withSnapshotIterators() - to get snapshot versions of the indexes to iterate over
+ *
+ * To get the low level iterators,
+ * get a low-level indexrepository (CAS -> getLowLevelCAS -> get low-level index repository), and from there
+ * get a low-level index
+ * get a low-level iterator
*/
- // needs default visibility
- class IndexImpl<T extends FeatureStructure> implements FSIndex<T>, FSIndexImpl {
-
- private final IndexIteratorCachePair<T> iicp;
-
- private final boolean is_with_snapshot_iterators;
-
- private final boolean is_unordered; //Set for getAllIndexedFSs
-
- private IndexImpl(IndexIteratorCachePair<T> iicp) {
- this.iicp = iicp;
- is_with_snapshot_iterators = false;
- is_unordered = false;
- }
-
- private IndexImpl(IndexIteratorCachePair<T> iicp, IteratorExtraFunction extraFn) {
- this.iicp = iicp;
- is_with_snapshot_iterators = (extraFn == IteratorExtraFunction.SNAPSHOT);
- is_unordered = (extraFn == IteratorExtraFunction.UNORDERED);
- }
-
- public int ll_compare(int ref1, int ref2) {
- return this.iicp.fsLeafIndex.ll_compare(ref1, ref2);
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#getIndexingStrategy()
- */
- @Override
- public int getIndexingStrategy() {
- return this.iicp.fsLeafIndex.getIndexingStrategy();
- }
-
- /**
- * @see org.apache.uima.cas.FSIndexImpl#getComparator()
- */
- @Override
- public FSIndexComparator getComparator() {
- return this.iicp.fsLeafIndex.getComparator();
- }
-
- // never used 3/2015
-// protected IntComparator getIntComparator() {
-// return this.iicp.fsLeafIndex.getIntComparator();
-// }
-
- // probably never called 3/15/2015
- public void flush() {
- this.iicp.fsLeafIndex.flush();
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#compare(FeatureStructure, FeatureStructure)
- */
- @Override
- public int compare(FeatureStructure fs1, FeatureStructure fs2) {
- return this.iicp.fsLeafIndex.compare(fs1, fs2);
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#contains(FeatureStructure)
- */
- @Override
- public boolean contains(FeatureStructure fs) {
- FeatureStructureImpl fsi = (FeatureStructureImpl) fs;
- IntPointerIterator it = createPointerIterator(this.iicp);
- it.moveTo(fsi.getAddress());
- return it.isValid() && (0 == this.iicp.fsLeafIndex.ll_compare(fsi.getAddress(), it.get()));
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#find(FeatureStructure)
- */
- @Override
- public FeatureStructure find(FeatureStructure fs) {
- FeatureStructureImpl fsi = (FeatureStructureImpl) fs;
- IntPointerIterator it = createPointerIterator(this.iicp);
- it.moveTo(fsi.getAddress());
- if (it.isValid()) {
- int v = it.get();
- return (0 == this.iicp.fsLeafIndex.ll_compare(fsi.getAddress(), v)) ?
- this.iicp.getCASImpl().createFS(v) :
- null;
- }
- return null;
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#getType()
- */
- @Override
- public Type getType() {
- return this.iicp.fsLeafIndex.getType();
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#iterator()
- */
- @Override
- public FSIterator<T> iterator() {
- return iterator(null);
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#iterator(FeatureStructure)
- */
- @Override
- public FSIterator<T> iterator(FeatureStructure fs) {
- if (this.iicp.flatIndex != null) {
- FSIteratorFlat<T> flatIterator = this.iicp.flatIndex.iterator(fs);
- if (flatIterator != null) {
- if (DEBUG) {
- // this stuff - the flat iterator will have been created by other means, and could be ordered,
- // so don't force unordering
- return new FSIteratorWrapperDoubleCheck<T>(nonFlatIterator(fs, false), flatIterator);
- }
- return flatIterator;
- }
- }
- return nonFlatIterator(fs, true);
- }
-
- private FSIterator<T> nonFlatIterator(FeatureStructure fs, boolean respectUnordered) {
- if (null != fs) {
- final int fsAddr = ((FeatureStructureImpl) fs).getAddress();
- return new FSIteratorWrapper<T>(
- is_with_snapshot_iterators ?
- new SnapshotPointerIterator<T>(iicp, fsAddr) :
- createPointerIterator(this.iicp, fsAddr),
- FSIndexRepositoryImpl.this.cas);
- } else {
- return new FSIteratorWrapper<T>(
- is_with_snapshot_iterators ?
- new SnapshotPointerIterator<T>(iicp) :
- createPointerIterator(this.iicp, respectUnordered && is_unordered),
- FSIndexRepositoryImpl.this.cas);
- }
- }
-
- // probably never called 3/15/2015
- public IntPointerIterator getIntIterator() {
- return createPointerIterator(this.iicp, is_unordered);
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#size()
- */
- @Override
- public int size() {
- return this.iicp.size();
- }
-
- /*
- * (non-Javadoc)
- *
- * @see org.apache.uima.cas.impl.LowLevelIndex#ll_iterator()
- */
- public LowLevelIterator ll_iterator() {
- return (LowLevelIterator)
- (is_with_snapshot_iterators ?
- new SnapshotPointerIterator<T>(iicp) :
- createPointerIterator(this.iicp, is_unordered));
- }
-
- public LowLevelIterator ll_rootIterator() {
- this.iicp.createIndexIteratorCache();
- return (LowLevelIterator) (is_with_snapshot_iterators ?
- new SnapshotPointerIterator<T>(iicp, true) :
- createLeafPointerIterator(this.iicp));
- }
-
- public LowLevelIterator ll_iterator(boolean ambiguous) {
- if (ambiguous) {
- return this.ll_iterator();
- }
- return new LLUnambiguousIteratorImpl(this.ll_iterator(), this.iicp.fsLeafIndex.lowLevelCAS);
- }
-
- /**
- * @see org.apache.uima.cas.FSIndex#withSnapshotIterators()
- */
- @Override
- public FSIndex<T> withSnapshotIterators() {
- return new IndexImpl<T>(this.iicp, IteratorExtraFunction.SNAPSHOT);
- }
-
- FSIndexRepositoryImpl getFsRepositoryImpl() {
- return iicp.getCASImpl().indexRepository;
- }
- } // end of class IndexImpl
+ /**
+ * General FSIterator creation
+ *
+ * There are some alternatives
+ * If the index has subtypes, then
+ * - the iterator may be ordered/unordered.
+ * - Ordered ones select among the subtypes as needed.
+ * - Unordered ones return all elements from each subtype and then switch to the next subtype.
+ * This is for efficiency.
+ * - (currently disabled) flattened indexes may be created and used
+ * If the index says to use snapshots, then each call makes a snapshot of the index, and iterates over that.
+ * - these don't throw ConcurrentModificationExceptions.
+ */
/*************************************************************
* Information about indexes that is shared across all views *
@@ -1783,11 +170,6 @@ public class FSIndexRepositoryImpl imple
private Comparator<AnnotationFS> annotationFsComparator = null;
/**
- * lazily created comparator using the built-in annotation index, but for ints
- */
- private IntComparator annotationComparator = null;
-
- /**
* optimization only - bypasses some shared (among views) initialization if already done
*/
private boolean isSetUpFromBaseCAS = false;
@@ -1797,14 +179,62 @@ public class FSIndexRepositoryImpl imple
}
}
+ /**
+ * For processing index updates in batch mode when deserializing from a remote service;
+ * lists of FSs that were added, removed, or reindexed
+ *
+ * only used when processing updates in batch mode
+ */
private static class ProcessedIndexInfo {
- final private PositiveIntSet fsAddedToIndex = new PositiveIntSet_impl(); // only used when processing updates in batch mode
-
- final private PositiveIntSet fsDeletedFromIndex = new PositiveIntSet_impl(); // only used when processing updates in batch mode
-
- final private PositiveIntSet fsReindexed = new PositiveIntSet_impl(); // only used when processing updates in batch mode
+ final private ObjHashSet<FeatureStructureImplC> fsAddedToIndex = new ObjHashSet<>(FeatureStructureImplC.class);
+ final private ObjHashSet<FeatureStructureImplC> fsDeletedFromIndex = new ObjHashSet<>(FeatureStructureImplC.class);
+ final private ObjHashSet<FeatureStructureImplC> fsReindexed = new ObjHashSet<>(FeatureStructureImplC.class);
}
+ /**
+ * Information about all the indexes for a single type. This is kept in an
+ * List, with the key being the type code.
+ */
+ static class IndexesForType {
+ /**
+ * true if one or more of the indexes is a set index
+ */
+ boolean hasSetIndex;
+ /**
+ * index of any sorted index or -1 if no sorted index
+ */
+ int aSortedIndex = -1; // -1 or the position of an arbitrary sorted index
+ int aBagIndex = -1; // -1 or the position of an arbitrary bag index
+ ArrayList<FsIndex_iicp<FeatureStructure>> indexesForType = new ArrayList<>(1);
+
+ FsIndex_iicp<FeatureStructure> getNonSetIndex() {
+ if (aSortedIndex < 0 && aBagIndex < 0) { // index is empty!
+ return null;
+ }
+ return indexesForType.get((aBagIndex >= 0) ? aBagIndex : aSortedIndex);
+ }
+
+ void add(FsIndex_iicp<FeatureStructure> iicp) {
+ final int kind = iicp.fsIndex_singletype.getIndexingStrategy();
+ int i = indexesForType.size();
+ switch (kind) {
+ case FSIndex.BAG_INDEX:
+ aBagIndex = i;
+ break;
+ case FSIndex.DEFAULT_BAG_INDEX:
+ if (aBagIndex == -1) { // real bag indexes have priority
+ aBagIndex = i;
+ }
+ break;
+ case FSIndex.SORTED_INDEX:
+ aSortedIndex = i;
+ break;
+ }
+ indexesForType.add(iicp);
+ }
+
+
+ }
/***** I N S T A N C E V A R I A B L E S *****/
/***** Replicated per view *****/
@@ -1815,15 +245,17 @@ public class FSIndexRepositoryImpl imple
private boolean locked = false;
/**
- * An array of ArrayLists, one for each type in the type hierarchy.
- * The ArrayLists are unordered lists of IndexIteratorCachePairs for
- * that type, corresponding to the different index definitions over that type.
- * This list includes iicps for subtypes of defined and default indexes over some type
+ * An array of information about defined indexes, one for each type in the type hierarchy.
+ * - includes for each type, an unordered list of FsIndex_iicps for
+ * that type, corresponding to the different index definitions over that type.
+ *
+ * The key is the typecode of the type.
*/
- final private ArrayList<IndexIteratorCachePair<? extends FeatureStructure>>[] indexArray;
- <T extends FeatureStructure> ArrayList<IndexIteratorCachePair<T>> getIndexesForType(int typeCode) {
- return (ArrayList<IndexIteratorCachePair<T>>) (Object) indexArray[typeCode];
+ final IndexesForType[] indexArray;
+
+ IndexesForType getIndexesForType(int typeCode) {
+ return indexArray[typeCode];
}
/**
@@ -1835,15 +267,21 @@ public class FSIndexRepositoryImpl imple
final int[] detectIllegalIndexUpdates;
/**
- * A map from names to IndexIteratorCachePairs, which represent the index at the
+ * A map from names to FsIndex_iicps, which represent the index at the
* top-most type declared in the index specification.
* Different names may map to the same iicp.
* The keys are the same across all views, but the values are different, per view
*/
- final private HashMap<String, IndexIteratorCachePair<? extends FeatureStructure>> name2indexMap;
-
+ final HashMap<String, FsIndex_iicp<FeatureStructure>> name2indexMap;
+
+ /**
+ * speedup for annotation index accessing by type, lazily initialized
+ */
+ final private Map<TypeImpl, FsIndex_annotation<Annotation>> annotationIndexes =
+ new IdentityHashMap<TypeImpl, FsIndex_annotation<Annotation>>();
+
// the next are for journaling updates to indexes
- final private IntVector indexUpdates;
+ final private List<FeatureStructure> indexUpdates;
final private BitSet indexUpdateOperation;
@@ -1858,8 +296,8 @@ public class FSIndexRepositoryImpl imple
final private boolean[] isUsed;
// Monitor which indexes are iterated over, to allow resetting flatIndexes
- final private List<IndexIteratorCachePair<? extends FeatureStructure>> iteratedSortedIndexes =
- Collections.synchronizedList(new ArrayList<IndexIteratorCachePair<? extends FeatureStructure>>());
+ final private List<FsIndex_iicp<? extends FeatureStructure>> iteratedSortedIndexes =
+ Collections.synchronizedList(new ArrayList<FsIndex_iicp<? extends FeatureStructure>>());
private final SharedIndexInfo sii;
@@ -1931,18 +369,18 @@ public class FSIndexRepositoryImpl imple
final int numTypes = ts.getNumberOfTypes() + 1;
this.detectIllegalIndexUpdates = new int[numTypes];
// this.flattenedIndexValid = new ConcurrentBits(numTypes);
- this.name2indexMap = new HashMap<String, IndexIteratorCachePair<? extends FeatureStructure>>();
- this.indexUpdates = new IntVector();
+ this.name2indexMap = new HashMap<String, FsIndex_iicp<FeatureStructure>>();
+ this.indexUpdates = new ArrayList<>();
this.indexUpdateOperation = new BitSet();
this.logProcessed = false;
- this.indexArray = new ArrayList[this.sii.tsi.getNumberOfTypes() + 1];
+ this.indexArray = new IndexesForType[this.sii.tsi.getNumberOfTypes() + 1];
this.usedIndexes = new IntVector();
this.isUsed = new boolean[numTypes];
init();
}
/**
- * Constructor for views.
+ * Constructor for additional views.
*
* @param cas
* @param baseIndexRepository
@@ -1959,50 +397,119 @@ public class FSIndexRepositoryImpl imple
this.detectIllegalIndexUpdates = new int[numTypes];
// this.flattenedIndexValid = new ConcurrentBits(numTypes);
- this.name2indexMap = new HashMap<String, IndexIteratorCachePair<? extends FeatureStructure>>();
- this.indexUpdates = new IntVector();
+ this.name2indexMap = new HashMap<String, FsIndex_iicp<FeatureStructure>>();
+ this.indexUpdates = new ArrayList<>();
this.indexUpdateOperation = new BitSet();
this.logProcessed = false;
- this.indexArray = new ArrayList[numTypes];
+ this.indexArray = new IndexesForType[numTypes];
this.usedIndexes = new IntVector();
this.isUsed = new boolean[numTypes];
init();
- final Set<String> keys = baseIndexRepo.name2indexMap.keySet();
- if (!keys.isEmpty()) {
- final Iterator<String> keysIter = keys.iterator();
- while (keysIter.hasNext()) {
- final String key = keysIter.next();
- final IndexIteratorCachePair<? extends FeatureStructure> iicp = baseIndexRepo.name2indexMap.get(key);
- createIndexNoQuestionsAsked(iicp.fsLeafIndex.getComparator(), key,
-
- iicp.fsLeafIndex.getIndexingStrategy());
- }
- }
+ // cant do this here because need to have the CAS's ref to this instance set before this is done.
+// baseIndexRepo.name2indexMap.keySet().stream().forEach(key -> createIndex(baseIndexRepo, key));
}
/**
- * Initialize data. Called from the constructor.
+ * Initialize data. Common initialization called from the constructors.
*/
private void init() {
final TypeSystemImpl ts = this.sii.tsi;
- // Type counting starts at 1.
- final int numTypes = ts.getNumberOfTypes() + 1;
- // Can't instantiate arrays of generic types.
+
+ /* **********************************************
+ * for each type in the TypeSystem,
+ * create a list of iicp's
+ * each one corresponding to a defined index
+ * **********************************************/
+ final int numTypes = ts.getNumberOfTypes() + 1; // Type counting starts at 1.
+ // Can't instantiate arrays of generic types, but this is ok for ArrayList.
for (int i = 1; i < numTypes; i++) {
- this.indexArray[i] = new ArrayList<IndexIteratorCachePair<? extends FeatureStructure>>();
+ this.indexArray[i] = new IndexesForType();
}
- resetDetectIllegalIndexUpdates();
+
+ Arrays.fill(detectIllegalIndexUpdates, Integer.MIN_VALUE);
mPii = new ProcessedIndexInfo();
-// this.fsAddedToIndex = new PositiveIntSet_impl();
-// this.fsDeletedFromIndex = new PositiveIntSet_impl();
-// this.fsReindexed = new PositiveIntSet_impl();
}
-
- private void resetDetectIllegalIndexUpdates() {
- for (int i = 0; i < detectIllegalIndexUpdates.length; i++) {
- detectIllegalIndexUpdates[i] = Integer.MIN_VALUE;
+
+ /* ***************
+ * Create indexes
+ * ***************/
+
+ <T extends FeatureStructure>
+ void createIndex(FSIndexRepositoryImpl baseIndexRepo, String key) {
+ final FsIndex_singletype<FeatureStructure> fsIndex = baseIndexRepo.name2indexMap.get(key).fsIndex_singletype;
+ createIndexNoQuestionsAsked(fsIndex.getComparatorForIndexSpecs(), key, fsIndex.getIndexingStrategy());
+ }
+
+ /**
+ * @see org.apache.uima.cas.admin.FSIndexRepositoryMgr#createIndex(FSIndexComparator, String)
+ */
+ @Override
+ public boolean createIndex(FSIndexComparator comp, String label, int indexType) throws CASAdminException {
+ if (this.locked) {
+ throw new CASAdminException(CASAdminException.REPOSITORY_LOCKED);
+ }
+ return createIndexNoQuestionsAsked(comp, label, indexType);
+ }
+
+ /**
+ * This is public only until the xml specifier format supports specifying index kinds (set, bag
+ * etc.).
+ *
+ * @param comp -
+ * @param label -
+ * @param indexType -
+ * @return -
+ */
+ public <T extends FeatureStructure>
+ boolean createIndexNoQuestionsAsked(final FSIndexComparator comp, String label, int indexType) {
+
+ FsIndex_iicp<FeatureStructure> cp = this.name2indexMap.get(label);
+
+
+ if (cp == null) {
+ // Create new index
+ cp = this.addNewIndexRecursive(comp, indexType);
+
+ // create a set of feature codes that are in one or more index definitions,
+ // only once for all cas views
+ if (!sii.isSetUpFromBaseCAS) {
+ for (int i = 0, nKeys = comp.getNumberOfKeys(); i < nKeys; i++) {
+ if (comp.getKeyType(i) == FSIndexComparator.FEATURE_KEY) {
+ cas.featureCodesInIndexKeysAdd(comp.getKeyFeature(i).getCode());
+ }
+ }
+ }
+
+ this.name2indexMap.put(label, cp);
+ return true;
}
+
+ // For now, just return false if the label already exists.
+ return false;
+ // // An index has previously been registered for this name. We need to
+ // // compare the types to see if the new addition is compatible with the
+ // // pre-existing one. There are three cases: the new type can be a sub-type
+ // // of the old one, in which case we don't need to do anything; or, the
+ // // new type is a super-type of the old one, in which case we add the new
+ // // index while keeping the old one; or, there is no subsumption relation,
+ // // in which case we can't add the index.
+ // Type oldType = cp.index.getType(); // Get old type from the index.
+ // Type newType = comp.getType(); // Get new type from comparator.
+ // if (this.sii.typeSystem.subsumes(oldType, newType)) {
+ // // We don't need to do anything.
+ // return true;
+ // } else if (this.sii.typeSystem.subsumes(newType, oldType)) {
+ // // Add the index, subsuming the old one.
+ // cp = this.addIndexRecursive(comp);
+ // // Replace the old index with the new one in the map.
+ // this.name2indexMap.put(label, cp);
+ // return true;
+ // } else {
+ // // Can't add index under that name.
+ // return false;
+ // }
+ // }
}
/**
@@ -2020,16 +527,13 @@ public class FSIndexRepositoryImpl imple
if (this.usedIndexes.size() == 0) {
return;
}
-
- for (int i = 0; i < this.usedIndexes.size(); i++) {
- this.isUsed[this.usedIndexes.get(i)] = false;
- ArrayList<IndexIteratorCachePair<? extends FeatureStructure>> v =
- this.indexArray[this.usedIndexes.get(i)];
- int max = v.size();
- for (int j = 0; j < max; j++) {
- IndexIteratorCachePair<? extends FeatureStructure> iicp = v.get(j);
- iicp.fsLeafIndex.flush();
- }
+
+ annotationIndexes.clear();
+
+ for (int i = 0; i < usedIndexes.size(); i++) {
+ int used = this.usedIndexes.get(i);
+ isUsed[used] = false;
+ indexArray[used].indexesForType.stream().forEach(iicp -> iicp.fsIndex_singletype.flush());
}
clearIteratedSortedIndexes();
@@ -2037,7 +541,7 @@ public class FSIndexRepositoryImpl imple
// reset the index update trackers
// resetDetectIllegalIndexUpdates();
- this.indexUpdates.removeAllElements();
+ this.indexUpdates.clear();
this.indexUpdateOperation.clear();
mPii = new ProcessedIndexInfo();
// this.fsAddedToIndex = new IntSet();
@@ -2047,212 +551,195 @@ public class FSIndexRepositoryImpl imple
this.usedIndexes.removeAllElements();
}
+ // for now, with flattened index optimization disabled, this should be a no-op
private void clearIteratedSortedIndexes() {
int sz = iteratedSortedIndexes.size();
if (DEBUG) {
System.out.println("Index Flush flatIndex, size = " + sz);
}
+
+// iteratedSortedIndexes.stream().forEach(iicp -> iicp.flatIndex.flush());
- for (IndexIteratorCachePair<? extends FeatureStructure> iicp : iteratedSortedIndexes) {
- iicp.flatIndex.flush();
- }
- if (iteratedSortedIndexes.size() != sz) {
- throw new RuntimeException(
- "Index Flush flatIndex, size not the same, before = " +
- sz + ", after = " + iteratedSortedIndexes.size());
+ if (DEBUG) {
+ if (iteratedSortedIndexes.size() != sz) {
+ throw new RuntimeException(
+ "Index Flush flatIndex, size not the same, before = " +
+ sz + ", after = " + iteratedSortedIndexes.size());
+ }
}
iteratedSortedIndexes.clear();
}
- public void addFS(int fsRef) {
- ll_addFS(fsRef);
- }
-
- private IndexIteratorCachePair<? extends FeatureStructure> addNewIndex(FSIndexComparator comparator, int indexType) {
+ /* *****************************************
+ * Adding indexes to the index repository
+ *******************************************/
+
+ private FsIndex_iicp<FeatureStructure> addNewIndex(FSIndexComparator comparator, int indexType) {
return addNewIndex(comparator, DEFAULT_INDEX_SIZE, indexType);
}
/**
* This is where the actual index gets created.
*/
- private <T extends FeatureStructure> IndexIteratorCachePair<T> addNewIndex(final FSIndexComparator comparator, int initialSize,
- int indexType) {
-
- FSLeafIndexImpl<T> fsLeafIndex = addNewIndexCore(comparator, initialSize, indexType);
- IndexIteratorCachePair<T> iicp = new IndexIteratorCachePair<T>(fsLeafIndex);
-// iicp.fsLeafIndex = addNewIndexCore(comparator, initialSize, indexType);
- final Type type = comparator.getType();
- final int typeCode = ((TypeImpl) type).getCode();
- // add indexes so that sorted ones are first, to benefit getAllIndexedFSs
- if (indexType == FSIndex.SORTED_INDEX) {
- this.indexArray[typeCode].add(0, iicp);
+ private <T extends FeatureStructure> FsIndex_iicp<T> addNewIndex(final FSIndexComparator comparator, int initialSize, int indexType) {
+ FsIndex_iicp<T> iicp = null;
+ if (isAnnotationIndex(comparator, indexType)) {
+ FsIndex_singletype<Annotation> index = addNewIndexCore(comparator, initialSize, indexType);
+ iicp = (FsIndex_iicp<T>) new FsIndex_annotation<Annotation>(index);
} else {
- this.indexArray[typeCode].add(iicp);
+ FsIndex_singletype<FeatureStructure> index = addNewIndexCore(comparator, initialSize, indexType);
+ iicp = (FsIndex_iicp<T>) new FsIndex_iicp<FeatureStructure>(index);
}
+ final Type type = comparator.getType();
+ final int typeCode = ((TypeImpl) type).getCode();
+
+// add indexes so that sorted ones are first, to benefit getAllIndexedFSs
+// if (indexType == FSIndex.SORTED_INDEX) {
+// this.indexArray[typeCode].add(0, iicp); // shifts rest down
+// } else
+ this.indexArray[typeCode].add((FsIndex_iicp<FeatureStructure>) iicp);
+// }
return iicp;
}
- private <T extends FeatureStructure> FSLeafIndexImpl<T> addNewIndexCore(
- final FSIndexComparator comparator,
+ private boolean isAnnotationIndex(FSIndexComparator c, int indexKind) {
+ TypeSystemImpl tsi = getTypeSystemImpl();
+ return indexKind == FSIndex.SORTED_INDEX &&
+ getTypeSystemImpl().annotType.subsumes((TypeImpl) c.getType()) &&
+ c.getNumberOfKeys() == 3 &&
+
+ c.getKeyType(0) == FSIndexComparator.FEATURE_KEY &&
+ c.getKeyComparator(0) == FSIndexComparator.STANDARD_COMPARE &&
+ c.getKeyFeature(0) == tsi.startFeat &&
+
+ c.getKeyType(1) == FSIndexComparator.FEATURE_KEY &&
+ c.getKeyComparator(1) == FSIndexComparator.REVERSE_STANDARD_COMPARE &&
+ c.getKeyFeature(1) == tsi.endFeat &&
+
+ c.getKeyType(2) == FSIndexComparator.TYPE_ORDER_KEY;
+ }
+
+ /**
+ * @param comparatorForIndexSpecs -
+ * @param initialSize -
+ * @param indexType -
+ * @return -
+ */
+ <T extends FeatureStructure> FsIndex_singletype<T> addNewIndexCore(
+ final FSIndexComparator comparatorForIndexSpecs,
int initialSize,
int indexType) {
- final Type type = comparator.getType();
+ final Type type = comparatorForIndexSpecs.getType();
// final int vecLen = indexVector.size();
- FSLeafIndexImpl<T> ind;
+ FsIndex_singletype<T> ind;
switch (indexType) {
- case FSIndex.SET_INDEX: {
- ind = new FSRBTSetIndex<T>(this.cas, type, indexType);
+
+ case FSIndex.SET_INDEX:
+ ind = new FsIndex_set_sorted<T>(this.cas, type, indexType, false); // false = is set
break;
- }
+
+// case FSIndex.FLAT_INDEX:
+// // this index is only created from another existing index
+// throw new UIMARuntimeException(UIMARuntimeException.INTERNAL_ERROR);
+
case FSIndex.BAG_INDEX:
- case FSIndex.DEFAULT_BAG_INDEX: {
- ind = new FSBagIndex<T>(this.cas, type, initialSize, indexType);
+ case FSIndex.DEFAULT_BAG_INDEX:
+ ind = new FsIndex_bag<T>(this.cas, type, initialSize, indexType);
break;
- }
- default: {
- // SORTED_INDEX is the default. We don't throw any errors, if the
- // code is unknown, we just create a sorted index (with duplicates).
- // ind = new FSRBTIndex(this.cas, type, FSIndex.SORTED_INDEX);
-
- ind = new FSIntArrayIndex<T>(this.cas, type, initialSize, FSIndex.SORTED_INDEX, isAnnotationIndex(type, comparator));
+
+ default:
+ // SORTED_INDEX is the default. We don't throw any errors, if the code is unknown, we just create a sorted index.
+ ind = new FsIndex_set_sorted<T>(this.cas, type, FSIndex.SORTED_INDEX, true); // true = is sorted
break;
+
}
- }
- // ind = new FSRBTIndex(this.cas, type);
- // ind = new FSVectorIndex(this.cas, initialSize);
- ind.init(comparator);
+ ind.init(comparatorForIndexSpecs);
return ind;
}
- private boolean isAnnotationIndex(Type type, FSIndexComparator comp) {
- TypeSystemImpl tsi = cas.getTypeSystemImpl();
+ private boolean isAnnotationIndex(Type type, FSIndexComparator compForIndexSpecs) {
+ TypeSystemImpl tsi = this.sii.tsi;
return
(type == tsi.annotType) &&
- (comp.getNumberOfKeys() == 3) &&
- (comp.getKeyType(0) == FSIndexComparator.FEATURE_KEY) &&
- (comp.getKeyType(1) == FSIndexComparator.FEATURE_KEY) &&
- (comp.getKeyType(2) == FSIndexComparator.TYPE_ORDER_KEY) &&
- (comp.getKeyComparator(0) == FSIndexComparator.STANDARD_COMPARE) &&
- (comp.getKeyComparator(1) == FSIndexComparator.REVERSE_STANDARD_COMPARE) &&
- (comp.getKeyComparator(2) == FSIndexComparator.STANDARD_COMPARE) &&
- (comp.getKeyFeature(0) == tsi.startFeat) &&
- (comp.getKeyFeature(1) == tsi.endFeat);
+ (compForIndexSpecs.getNumberOfKeys() == 3) &&
+ (compForIndexSpecs.getKeyType(0) == FSIndexComparator.FEATURE_KEY) &&
+ (compForIndexSpecs.getKeyType(1) == FSIndexComparator.FEATURE_KEY) &&
+ (compForIndexSpecs.getKeyType(2) == FSIndexComparator.TYPE_ORDER_KEY) &&
+ (compForIndexSpecs.getKeyComparator(0) == FSIndexComparator.STANDARD_COMPARE) &&
+ (compForIndexSpecs.getKeyComparator(1) == FSIndexComparator.REVERSE_STANDARD_COMPARE) &&
+ (compForIndexSpecs.getKeyComparator(2) == FSIndexComparator.STANDARD_COMPARE) &&
+ (compForIndexSpecs.getKeyFeature(0) == tsi.startFeat) &&
+ (compForIndexSpecs.getKeyFeature(1) == tsi.endFeat);
}
-
- /*
- * private IndexIteratorCachePair addIndex( FSIndexComparator comparator, int initialSize) { final
- * Type type = comparator.getType(); final int typeCode = ((TypeImpl) type).getCode(); final
- * Vector indexVector = this.indexArray[typeCode]; final int vecLen = indexVector.size();
- * FSLeafIndexImpl ind;
- *
- * for (int i = 0; i < vecLen; i++) { ind = ((IndexIteratorCachePair) indexVector.get(i)).index;
- * if (comparator.equals(ind.getComparator())) { return null; } }
- *
- * ind = new FSRBTIndex(this.cas, type); // ind = new FSVectorIndex(this.cas, initialSize);
- * ind.init(comparator); IndexIteratorCachePair iicp = new IndexIteratorCachePair(); iicp.index =
- * ind; indexVector.add(iicp); return iicp; }
- */
- // private IndexIteratorCachePair addIndexRecursive(FSIndexComparator
- // comparator) {
- // final FSIndexComparatorImpl compCopy =
- // ((FSIndexComparatorImpl) comparator).copy();
- // return addIndexRec(compCopy);
- // }
-
+
/**
* Top level call to add the indexes for a particular index definition
- * @param comparator
+ * @param compForIndexSpecs
* @param indexType
* @return the iicp for the top new index
*/
- private IndexIteratorCachePair<? extends FeatureStructure> addNewIndexRecursive(FSIndexComparator comparator, int indexType) {
- final FSIndexComparatorImpl compCopy = ((FSIndexComparatorImpl) comparator).copy();
+ private FsIndex_iicp<FeatureStructure> addNewIndexRecursive(FSIndexComparator compForIndexSpecs, int indexType) {
+ final FSIndexComparatorImpl compCopy = ((FSIndexComparatorImpl)compForIndexSpecs).copy();
return addNewIndexRec(compCopy, indexType);
}
- /**
- * Finds an index among iicp's for all defined indexes of a type, such that
- * the type of the index (SET, BAG, SORTED) is the same and
- * the comparator (the keys) are the same
- * @param indexes
- * @param comp
- * @param indexType
- * @return the index in the set of iicps for this type for the matching index
- */
- private static final <T extends FeatureStructure> int findIndex(ArrayList<IndexIteratorCachePair<T>> indexes,
- FSIndexComparator comp,
- int indexType) {
- FSIndexComparator indexComp;
- final int max = indexes.size();
- for (int i = 0; i < max; i++) {
- FSLeafIndexImpl<? extends FeatureStructure> index = indexes.get(i).fsLeafIndex;
- if (index.getIndexingStrategy() != indexType) {
- continue;
- }
- indexComp = index.getComparator();
- if (comp.equals(indexComp)) {
- return i;
- }
- }
- return -1;
- }
- /*
[... 1465 lines stripped ...]