This is an automated email from the ASF dual-hosted git repository. rec pushed a commit to branch bugfix/345-Certain-select-operations-deplete-FS-ID-pool in repository https://gitbox.apache.org/repos/asf/uima-uimaj.git
commit 3d35bfeb24faa0d63eed108e6c4141ddbe6737a6 Author: Richard Eckart de Castilho <r...@apache.org> AuthorDate: Wed Sep 20 20:52:50 2023 +0200 Issue #345: Certain select operations deplete FS ID pool - Introduce an internal flag and guard to temporarily disable ID assignment to annotatons while creating temporary annotations. --- .../java/org/apache/uima/cas/impl/CASImpl.java | 9 +++--- .../uima/cas/impl/FeatureStructureImplC.java | 36 ++++++++++++++++++---- .../org/apache/uima/cas/impl/SelectFSs_impl.java | 16 ++-------- .../java/org/apache/uima/cas/impl/Subiterator.java | 4 +-- .../org/apache/uima/jcas/cas/AnnotationBase.java | 24 ++++++++------- .../main/java/org/apache/uima/jcas/cas/TOP.java | 12 +++++++- .../java/org/apache/uima/jcas/tcas/Annotation.java | 33 +++++++++++++++++--- .../org/apache/uima/cas/impl/SubiteratorTest.java | 4 +-- 8 files changed, 94 insertions(+), 44 deletions(-) diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java index 14d568c6e..a65b9fc2f 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/CASImpl.java @@ -1250,8 +1250,7 @@ public class CASImpl extends AbstractCas_ImplBase mySofaRef = (Sofa) aSofa; // get the indexRepository for this Sofa - indexRepository = (mySofaRef == null) - ? (FSIndexRepositoryImpl) cas.getSofaIndexRepository(1) + indexRepository = (mySofaRef == null) ? (FSIndexRepositoryImpl) cas.getSofaIndexRepository(1) : (FSIndexRepositoryImpl) cas.getSofaIndexRepository(aSofa); if (null == indexRepository) { // create the indexRepository for this CAS @@ -1703,9 +1702,9 @@ public class CASImpl extends AbstractCas_ImplBase } Sofa sofa = new Sofa(getTypeSystemImpl().sofaType, getBaseCAS(), // view for a sofa is the - // base cas to correspond - // to where it gets - // indexed + // base cas to correspond + // to where it gets + // indexed sofaNum, sofaName, mimeType); getBaseIndexRepository().addFS(sofa); diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java index 3aa568f7a..cc91fffb3 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/FeatureStructureImplC.java @@ -187,15 +187,11 @@ public class FeatureStructureImplC implements FeatureStructureImpl { /** * For non-JCas use, Internal Use Only, called by cas.createFS via generators - * - * @param casView - * - - * @param type - * - */ protected FeatureStructureImplC(TypeImpl type, CASImpl casView) { _casView = casView; _typeImpl = type; + _id = casView.getNextFsId((TOP) this); if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) { @@ -226,7 +222,6 @@ public class FeatureStructureImplC implements FeatureStructureImpl { * @param jcasImpl * - the view this is being created in */ - protected FeatureStructureImplC(JCasImpl jcasImpl) { _casView = jcasImpl.getCasImpl(); _typeImpl = _casView.getTypeSystemImpl().getJCasRegisteredType(getTypeIndexID()); @@ -264,6 +259,35 @@ public class FeatureStructureImplC implements FeatureStructureImpl { // } } + /** + * For temporary marker annotations. Does not assign an ID from the CAS ID generator and never + * retains the annotation. We also do not trace this annotation. + */ + protected FeatureStructureImplC(JCasImpl jcasImpl, int aId) { + _casView = jcasImpl.getCasImpl(); + _typeImpl = _casView.getTypeSystemImpl().getJCasRegisteredType(getTypeIndexID()); + _id = aId; + + if (null == _typeImpl) { + throw new CASRuntimeException(CASRuntimeException.JCAS_TYPE_NOT_IN_CAS, + this.getClass().getName()); + } + + if (_casView.maybeMakeBaseVersionForPear(this, _typeImpl)) { + _setPearTrampoline(); + } + + FeatureStructureImplC baseFs = _casView.pearBaseFs; + if (null != baseFs) { + _intData = baseFs._intData; + _refData = baseFs._refData; + _casView.pearBaseFs = null; + } else { + _intData = _allocIntData(); + _refData = _allocRefData(); + } + } + private int[] _allocIntData() { final int c = _typeImpl.nbrOfUsedIntDataSlots; if (c != 0) { diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java index cf1a71aca..69d793e81 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/SelectFSs_impl.java @@ -19,6 +19,7 @@ package org.apache.uima.cas.impl; import static org.apache.uima.cas.impl.Subiterator.BoundsUse.notBounded; +import static org.apache.uima.jcas.tcas.Annotation._createMarkerAnnotation; import java.lang.reflect.Array; import java.util.ArrayList; @@ -56,7 +57,6 @@ import org.apache.uima.cas.impl.Subiterator.BoundsUse; import org.apache.uima.cas.text.AnnotationFS; import org.apache.uima.cas.text.AnnotationIndex; import org.apache.uima.cas.text.AnnotationPredicates; -import org.apache.uima.jcas.JCas; import org.apache.uima.jcas.cas.EmptyFSList; import org.apache.uima.jcas.cas.FSArray; import org.apache.uima.jcas.cas.FSList; @@ -64,7 +64,6 @@ import org.apache.uima.jcas.cas.NonEmptyFSList; import org.apache.uima.jcas.cas.TOP; import org.apache.uima.jcas.impl.JCasImpl; import org.apache.uima.jcas.tcas.Annotation; -import org.apache.uima.util.AutoCloseableNoException; // @formatter:off /** @@ -1019,19 +1018,10 @@ public class SelectFSs_impl<T extends FeatureStructure> implements SelectFSs<T> // } private Annotation makePosAnnot(int begin, int end) { - return makePosAnnot(jcas, begin, end); + return _createMarkerAnnotation(jcas, begin, end); } - static Annotation makePosAnnot(JCas jcas, int begin, int end) { - if (end < begin) { - throw new IllegalArgumentException("End value must be >= Begin value"); - } - try (AutoCloseableNoException c = ((CASImpl) jcas.getCas()).ll_forceEnableV2IdRefs(false)) { - return new Annotation(jcas, begin, end); - } - } - -//@formatter:off + //@formatter:off /** * Iterator respects backwards * diff --git a/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java b/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java index bce76f870..4cb1b4f56 100644 --- a/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java +++ b/uimaj-core/src/main/java/org/apache/uima/cas/impl/Subiterator.java @@ -365,7 +365,7 @@ public class Subiterator<T extends AnnotationFS> implements LowLevelIterator<T> if (begin < 0) { begin = 0; } - coveringStartPos = SelectFSs_impl.makePosAnnot(jcas, begin, Integer.MAX_VALUE); + coveringStartPos = Annotation._createMarkerAnnotation(jcas, begin, Integer.MAX_VALUE); } else { coveringStartPos = null; } @@ -759,7 +759,7 @@ public class Subiterator<T extends AnnotationFS> implements LowLevelIterator<T> */ private void moveToJustPastBoundsAndBackup(int begin, int end, Predicate<Annotation> continue_going_backwards) { - it.moveToNoReinit(SelectFSs_impl.makePosAnnot(jcas, begin, end)); + it.moveToNoReinit(Annotation._createMarkerAnnotation(jcas, begin, end)); if (!it.isValid()) { it.moveToLastNoReinit(); diff --git a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java index 4c5efd192..383f48d9f 100644 --- a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java +++ b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/AnnotationBase.java @@ -82,11 +82,6 @@ public class AnnotationBase extends TOP implements AnnotationBaseImpl { protected AnnotationBase() { } - // /* Internal - Constructor used by generator */ - // public AnnotationBase(int addr, TOP_Type type) { - // super(addr, type); - // } - public AnnotationBase(JCas jcas) { super(jcas); if (_casView.isBaseCas()) { @@ -98,14 +93,21 @@ public class AnnotationBase extends TOP implements AnnotationBaseImpl { } /** - * used by generator Make a new AnnotationBase - * - * @param c - * - - * @param t - * - + * Used to create temporary marker annotations. */ + protected AnnotationBase(JCas jcas, int aId) { + super(jcas, 0); + if (_casView.isBaseCas()) { + throw new CASRuntimeException(CASRuntimeException.DISALLOW_CREATE_ANNOTATION_IN_BASE_CAS, + this.getClass().getName()); + } + // no journaling, no index corruption checking + _setRefValueCommon(wrapGetIntCatchException(_FH_sofa), _casView.getSofaRef()); + } + /** + * used by generator Make a new AnnotationBase + */ public AnnotationBase(TypeImpl t, CASImpl c) { super(t, c); if (_casView.isBaseCas()) { diff --git a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/TOP.java b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/TOP.java index 60ef838c5..7dc694339 100644 --- a/uimaj-core/src/main/java/org/apache/uima/jcas/cas/TOP.java +++ b/uimaj-core/src/main/java/org/apache/uima/jcas/cas/TOP.java @@ -66,7 +66,7 @@ public class TOP extends FeatureStructureImplC { * @param id * - */ - private TOP(int id) { + TOP(int id) { super(id); } @@ -93,6 +93,16 @@ public class TOP extends FeatureStructureImplC { super((JCasImpl) jcas); } + /** + * Internal. Used to create marker annotations. + * + * @param jcas + * - + */ + TOP(JCas jcas, int aId) { + super((JCasImpl) jcas, aId); + } + public static TOP _createSearchKey(int id) { return new TOP(id); // special super class, does nothing except create this TOP instance } diff --git a/uimaj-core/src/main/java/org/apache/uima/jcas/tcas/Annotation.java b/uimaj-core/src/main/java/org/apache/uima/jcas/tcas/Annotation.java index 7f2baa3c5..47cb64ec0 100644 --- a/uimaj-core/src/main/java/org/apache/uima/jcas/tcas/Annotation.java +++ b/uimaj-core/src/main/java/org/apache/uima/jcas/tcas/Annotation.java @@ -27,6 +27,7 @@ import org.apache.uima.cas.CAS; import org.apache.uima.cas.admin.LinearTypeOrder; import org.apache.uima.cas.impl.AnnotationImpl; import org.apache.uima.cas.impl.CASImpl; +import org.apache.uima.cas.impl.SelectFSs_impl; import org.apache.uima.cas.impl.TypeImpl; import org.apache.uima.cas.impl.TypeSystemImpl; import org.apache.uima.jcas.JCas; @@ -176,6 +177,15 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { setEnd(end); } + /** + * Used to create temporary marker annotations. + */ + private Annotation(JCas jcas, int begin, int end, int aId) { + super(jcas, aId); // forward to constructor + setBegin(begin); + setEnd(end); + } + /** * @see org.apache.uima.cas.text.AnnotationFS#getCoveredText() * @return - @@ -212,8 +222,9 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { int result = Integer.compare(_getIntValueNc(b), other._getIntValueNc(b)); // int result = Integer.compare(_getIntValueNc(BEGIN_OFFSET), // other._getIntValueNc(BEGIN_OFFSET)); - if (result != 0) + if (result != 0) { return result; + } final int e = (int) _FH_end.invokeExact(); result = Integer.compare(_getIntValueNc(e), other._getIntValueNc(e)); @@ -235,8 +246,9 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { */ public final int compareAnnotation(Annotation other, LinearTypeOrder lto) { int result = compareAnnotation(other); - if (result != 0) + if (result != 0) { return result; + } return lto.compare(this, other); } @@ -250,8 +262,9 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { */ public final int compareAnnotationWithId(Annotation other) { int result = compareAnnotation(other); - if (result != 0) + if (result != 0) { return result; + } return Integer.compare(_id, other._id); } @@ -266,8 +279,9 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { */ public final int compareAnnotationWithId(Annotation other, LinearTypeOrder lto) { int result = compareAnnotation(other, lto); - if (result != 0) + if (result != 0) { return result; + } return Integer.compare(_id, other._id); } @@ -309,4 +323,15 @@ public class Annotation extends AnnotationBase implements AnnotationImpl { }); } } + + /** + * For internal use by {@link SelectFSs_impl} + */ + public static Annotation _createMarkerAnnotation(JCas aJCas, int aBegin, int aEnd) { + if (aEnd < aBegin) { + throw new IllegalArgumentException("End value must be >= Begin value"); + } + + return new Annotation(aJCas, aBegin, aEnd, 0); + } } diff --git a/uimaj-core/src/test/java/org/apache/uima/cas/impl/SubiteratorTest.java b/uimaj-core/src/test/java/org/apache/uima/cas/impl/SubiteratorTest.java index 7f3cd95ab..8c069b524 100644 --- a/uimaj-core/src/test/java/org/apache/uima/cas/impl/SubiteratorTest.java +++ b/uimaj-core/src/test/java/org/apache/uima/cas/impl/SubiteratorTest.java @@ -99,9 +99,9 @@ public class SubiteratorTest { .containsOnly(CAS.TYPE_NAME_SOFA, CAS.TYPE_NAME_DOCUMENT_ANNOTATION, Sentence._TypeName, Token._TypeName); - // The +1 here accounts for the temporary Annotation that was created. + // The temporary annotation should not have been assigned an ID var t = new Token(jcas); - assertThat(t._id).isEqualTo(maxId + 2 + 1); + assertThat(t._id).isEqualTo(maxId + 1); } }