| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| package org.apache.uima.cas.impl; |
| |
| import java.util.Comparator; |
| |
| import org.apache.uima.cas.FeatureStructure; |
| import org.apache.uima.internal.util.CopyOnWriteOrderedFsSet_array; |
| import org.apache.uima.internal.util.Misc; |
| import org.apache.uima.jcas.cas.TOP; |
| |
| /** |
| * An iterator for a single type for a set or sorted index |
| * |
| * NOTE: This is the version used for set/sorted iterators It is built directly on top of a |
| * CopyOnWrite wrapper for OrderedFsSet_array It uses the version of OrdereFsSet_array that has no |
| * embedded nulls |
| * |
| * @param <T> |
| * the type of FSs being returned from the iterator, supplied by the calling context |
| */ |
| class FsIterator_set_sorted2<T extends FeatureStructure> extends FsIterator_singletype<T> { |
| |
| // not final, because on moveToFirst/Last/FS, the semantics dictate that |
| // if the underlying index was updated, this should iterate over that. |
| protected CopyOnWriteOrderedFsSet_array ofsa; // orderedFsSet_array; |
| |
| protected int pos; |
| |
| protected final FsIndex_set_sorted<T> ll_index; |
| |
| /** |
| * if the iterator is configured to ignore TypeOrdering, then the comparator omits the type (if |
| * the index has a type order key) |
| */ |
| protected final Comparator<TOP> comparatorMaybeNoTypeWithoutID; |
| |
| public FsIterator_set_sorted2(FsIndex_set_sorted<T> ll_index, CopyOnWriteIndexPart cow_wrapper, |
| Comparator<TOP> comparatorMaybeNoTypeWithoutID) { |
| super((TypeImpl) ll_index.getType()); |
| this.comparatorMaybeNoTypeWithoutID = comparatorMaybeNoTypeWithoutID; |
| |
| this.ll_index = ll_index; |
| ofsa = (CopyOnWriteOrderedFsSet_array) cow_wrapper; |
| pos = ofsa.a_firstUsedslot; |
| // incrToSkipOverNulls(); |
| // if (MEASURE) { |
| // int s = ofsa.a_nextFreeslot - ofsa.a_firstUsedslot; |
| // iterPctEmptySkip[(s - ofsa.size()) * 10 / s] ++; |
| // } |
| } |
| |
| @Override |
| public boolean maybeReinitIterator() { |
| if (!ofsa.isOriginal()) { |
| // can't share this copy with other iterators - they may have not done a moveToFirst, etc. |
| // and need to continue with the previous view |
| ofsa = (CopyOnWriteOrderedFsSet_array) ll_index.getNonNullCow(); |
| return true; |
| } |
| return false; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.FSIterator#isValid() |
| */ |
| @Override |
| public boolean isValid() { |
| return pos >= ofsa.a_firstUsedslot && pos < ofsa.a_nextFreeslot; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.FSIterator#getNvc() |
| */ |
| @Override |
| public T getNvc() { |
| return (T) ofsa.a[pos]; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.FSIterator#moveToNextNvc() |
| */ |
| @Override |
| public void moveToNextNvc() { |
| pos++; |
| // incrToSkipOverNulls(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.FSIterator#moveToPreviousNvc() |
| */ |
| @Override |
| public void moveToPreviousNvc() { |
| pos--; |
| // decrToSkipOverNulls(); |
| } |
| |
| // Internal use |
| @Override |
| public void moveToFirstNoReinit() { |
| pos = ofsa.a_firstUsedslot; |
| } |
| |
| // Internal use |
| @Override |
| public void moveToLastNoReinit() { |
| pos = ofsa.a_nextFreeslot - 1; |
| } |
| |
| // Internal use |
| @Override |
| public void moveToNoReinit(FeatureStructure fs) { |
| pos = ofsa.getOfsa().find((TOP) fs, comparatorMaybeNoTypeWithoutID); |
| |
| if (pos < 0) { |
| pos = (-pos) - 1; // insertion point, one above |
| return; |
| } |
| |
| int savedPos = pos; |
| |
| // pos is the equal-with-id item |
| |
| moveToPreviousNvc(); |
| if (isValid()) { |
| if (0 == comparatorMaybeNoTypeWithoutID.compare((TOP) get(), (TOP) fs)) { |
| moveToLeftMost(fs); |
| } else { |
| // did not compare equal, so previous was the right position |
| pos = savedPos; |
| } |
| } else { |
| // went one before start, restore to start |
| pos = savedPos; |
| } |
| |
| return; |
| } |
| |
| // // Internal use |
| // public void moveToExactNoReinit(FeatureStructure fs) { |
| // pos = ofsa.getOfsa().find((TOP) fs); // find == find with ID |
| // // if not found, this will be negative marking iterator invalid |
| // } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.FSIterator#copy() |
| */ |
| @Override |
| public FsIterator_singletype<T> copy() { |
| FsIterator_set_sorted2<T> r = new FsIterator_set_sorted2<>(ll_index, ofsa, |
| comparatorMaybeNoTypeWithoutID); |
| copyCommonSetup(r); |
| return r; |
| } |
| |
| protected void copyCommonSetup(FsIterator_set_sorted2<T> copy) { |
| copy.pos = pos; |
| } |
| |
| // /* (non-Javadoc) |
| // * @see org.apache.uima.cas.FSIterator#getType() |
| // */ |
| // @Override |
| // public Type getType() { |
| // // TODO Auto-generated method stub |
| // return LowLevelIterator.super.getType(); |
| // } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.LowLevelIterator#ll_indexSize() |
| */ |
| @Override |
| public int ll_indexSizeMaybeNotCurrent() { |
| return ofsa.size(); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.LowLevelIterator#ll_getIndex() |
| */ |
| @Override |
| public LowLevelIndex<T> ll_getIndex() { |
| return ll_index; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.LowLevelIterator#ll_maxAnnotSpan() |
| */ |
| @Override |
| public int ll_maxAnnotSpan() { |
| FsIndex_set_sorted<T> ss_idx = ll_index; |
| return ss_idx.isAnnotIdx ? ss_idx.ll_maxAnnotSpan() : Integer.MAX_VALUE; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.LowLevelIterator#isIndexesHaveBeenUpdated() This is local to this |
| * class because it references the ofsa |
| */ |
| @Override |
| public boolean isIndexesHaveBeenUpdated() { |
| return ofsa != ll_index.getCopyOnWriteIndexPart(); |
| } |
| |
| // private void incrToSkipOverNulls() { |
| // while (pos < ofsa.a_nextFreeslot) { |
| // if (ofsa.a[pos] != null) { |
| // break; |
| // } |
| // pos ++; |
| // } |
| // } |
| // |
| // private void decrToSkipOverNulls() { |
| // while (pos >= ofsa.a_firstUsedslot) { |
| // if (ofsa.a[pos] != null) { |
| // break; |
| // } |
| // pos --; |
| // } |
| // } |
| |
| /** |
| * Starting at a position where the item is equal to fs using the compare without id, move to the |
| * leftmost one |
| * |
| * search opportunistically, starting at 1 before, 2, 4, 8, 16, etc. then doing binary search in |
| * the opposite dir |
| * |
| * These methods are in this class because they manipulate "pos" |
| * |
| * @param fs |
| * - |
| */ |
| private void moveToLeftMost(FeatureStructure fs) { |
| |
| // adjust to move to left-most equal item |
| boolean comparedEqual = false; |
| int origPos = pos; |
| int span = 1; |
| while (isValid()) { |
| int upperValidPos = pos; |
| pos = origPos - span; |
| pos = Math.max(-1, pos); |
| // decrToSkipOverNulls(); |
| if (!isValid()) { |
| moveToLeftMostUp(fs, upperValidPos); |
| return; |
| } |
| comparedEqual = (0 == comparatorMaybeNoTypeWithoutID.compare((TOP) get(), (TOP) fs)); |
| if (!comparedEqual) { |
| moveToLeftMostUp(fs, upperValidPos); |
| return; |
| } |
| span = span << 1; |
| } |
| } |
| |
| /** |
| * Must be possible to leave the pos == to upperValidPos. Starts searching from next above current |
| * pos |
| * |
| * @param fs |
| * @param upperValidPos |
| */ |
| private void moveToLeftMostUp(FeatureStructure fs, int upperValidPos) { |
| if (pos < ofsa.a_firstUsedslot) { |
| moveToFirst(); |
| } else { |
| moveToNext(); |
| } |
| // binary search between pos (inclusive) and upperValidPos (exclusive) |
| if (!isValid()) { |
| Misc.internalError(); |
| } |
| if (pos == upperValidPos) { |
| return; |
| } |
| pos = ofsa.getOfsa().binarySearchLeftMostEqual((TOP) fs, pos, upperValidPos, |
| comparatorMaybeNoTypeWithoutID); |
| } |
| |
| @Override |
| public Comparator<TOP> getComparator() { |
| return comparatorMaybeNoTypeWithoutID; |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see org.apache.uima.cas.impl.LowLevelIterator#moveToSupported() |
| */ |
| @Override |
| public boolean isMoveToSupported() { |
| return this.ll_getIndex().isSorted(); |
| } |
| |
| @Override |
| public int size() { |
| return ofsa.size(); |
| } |
| |
| // @Override |
| // protected int getModificationCountFromIndex() { |
| // return ofsa.getModificationCount(); |
| // } |
| |
| // /** |
| // * Never returns an index to a "null" (deleted) item. |
| // * If all items are LT key, returns - size - 1 |
| // * @param fs the key |
| // * @return the lowest position whose item is equal to or greater than fs; |
| // * if not equal, the item's position is returned as -insertionPoint - 1. |
| // * If the key is greater than all elements, return -size - 1). |
| // */ |
| // private int find(TOP fs) { |
| // return ofsa.getOfsa().find(fs); |
| // } |
| |
| } |