blob: f3c8c9aab03eea4dc567fd2bee81cf02db8e1812 [file] [log] [blame]
/*
* 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.Collection;
import java.util.List;
import org.apache.uima.cas.FSIterator;
import org.apache.uima.cas.FeatureStructure;
import org.apache.uima.cas.Type;
import org.apache.uima.cas.admin.FSIndexComparator;
import org.apache.uima.internal.util.CopyOnWriteObjHashSet;
import org.apache.uima.internal.util.ObjHashSet;
import org.apache.uima.jcas.cas.TOP;
/**
* Used for UIMA FS Bag Indexes
* Uses ObjHashSet to hold instances of FeatureStructures
* @param <T> the Java cover class type for this index, passed along to (wrapped) iterators producing Java cover classes
* NOTE: V3 doesn't support ALLOW_DUP_ADD_TO_INDEXES
*/
public class FsIndex_bag<T extends FeatureStructure> extends FsIndex_singletype<T> {
// // package private
// final static boolean USE_POSITIVE_INT_SET = !FSIndexRepositoryImpl.IS_ALLOW_DUP_ADD_2_INDEXES;
// The index
final private ObjHashSet<TOP> index;
// /**
// * Copy on write, initially null
// * Iterator creation initializes (if not null).
// * Modification to index:
// * call cow.makeCopy();
// * set cow = null
// * do the modification
// * index clear/flush - set to null;
// */
// private WeakReference<CopyOnWriteObjHashSet<TOP>> cow = null;
FsIndex_bag(CASImpl cas, Type type, int initialSize, int indexType, FSIndexComparator comparatorForIndexSpecs) {
super(cas, type, indexType, cleanUpComparator(comparatorForIndexSpecs, cas));
this.index = new ObjHashSet<TOP>(initialSize, TOP.class, TOP._singleton);
}
/**
* Substitutes an empty comparator if one is specified - may not be needed
* @see org.apache.uima.cas.impl.FSLeafIndexImpl#init(org.apache.uima.cas.admin.FSIndexComparator)
*/
private static FSIndexComparator cleanUpComparator(FSIndexComparator comp, CASImpl casImpl) {
// The comparator for a bag index must be empty, except for the type. If
// it isn't, we create an empty one.
FSIndexComparator newComp;
if (comp.getNumberOfKeys() > 0) {
newComp = new FSIndexComparatorImpl();
newComp.setType(comp.getType());
} else {
newComp = comp;
}
return newComp;
}
@Override
public void flush() {
super.flush();
index.clear();
}
@Override
public final void insert(T fs) {
maybeCopy();
index.add((TOP) fs);
}
// @SuppressWarnings("unchecked") // unused 1/2016
// public final boolean insert(int fs) {
// return insert((T) casImpl.getFsFromId_checked(fs));
// }
/**
* Override the super impl which uses comparators.
* For bag indexes, compare equal only if identical addresses
*/
@Override
public int compare(FeatureStructure fs1, FeatureStructure fs2) {
return (fs1 == fs2) ? 0 : (fs1._id() < fs2._id()) ? -1 : 1;
}
/*
* // Do binary search on index.
* private final int binarySearch(int [] array, int ele, int start, int end) {
* --end; // Make end a legal value.
* int i; // Current position
* int comp; // Compare value
* while (start <= end) {
* i = (start + end) / 2;
* comp = compare(ele, array[i]);
* if (comp == 0) {
* return i;
* }
* if (start == end) {
* if (comp < 0) {
* return (-i)-1;
* } else { // comp > 0
* return (-i)-2; // (-(i+1))-1
* }
* }
* if (comp < 0) {
* end = i-1;
* } else { // comp > 0
* start = i+1;
* }
* } //This means that the input span is empty.
* return (-start)-1;
* }
*/
// public FsIterator_bag<T>SIteratorSingleType_ImplBase<T> createFSIterator(int[] detectIllegalIndexUpdates, int typeCode) {
// return new FsIterator_bag<T>(this, detectIllegalIndexUpdates, typeCode);
// }
/**
* @see org.apache.uima.cas.FSIndex#contains(FeatureStructure)
* @param fs A Feature Structure used a template to match for equality with the
* FSs in the index.
* @return <code>true</code> if the index contains such an element.
*/
@Override
public boolean contains(FeatureStructure fs) {
return this.index.contains(fs);
}
boolean ll_contains(int fsAddr) {
return contains(casImpl.getFsFromId_checked(fsAddr));
}
/**
* This is a silly method for bag indexes in V3, since dupl add to indexes is not allowed.
* @param fs -
* @return null or the original fs if the fs is in the index
*/
@Override
public T find(FeatureStructure fs) {
final int resultAddr = this.index.find((TOP) fs);
if (resultAddr >= 0) {
return (T) fs;
}
// Not found.
return null;
}
/**
* @see org.apache.uima.cas.FSIndex#size()
*/
@Override
public int size() {
return this.index.size();
}
/**
* only for backwards compatibility
*
*/
@Override
public boolean deleteFS(T fs) {
maybeCopy();
return this.index.remove(fs);
}
// @Override
// public boolean remove(int fsRef) {
// return deleteFS((T) casImpl.getFsFromId_checked(fsRef));
// }
@Override
public int hashCode() {
throw new UnsupportedOperationException();
}
@Override
protected void bulkAddTo(List<T> fss) {
fss.addAll((Collection<? extends T>) this.index);
}
/* (non-Javadoc)
* @see org.apache.uima.cas.FSIndex#iterator()
*/
@Override
public FSIterator<T> iterator() {
setupIteratorCopyOnWrite();
return casImpl.inPearContext()
? new FsIterator_bag_pear<>(this, type)
: new FsIterator_bag <>(this, type);
}
@Override
protected CopyOnWriteIndexPart createCopyOnWriteIndexPart() {
if (CASImpl.traceCow) {
this.casImpl.traceCowCopy(this);
}
return new CopyOnWriteObjHashSet<TOP>(index);
}
@Override
public int ll_maxAnnotSpan() {
return Integer.MAX_VALUE;
}
// ObjHashSet<TOP> getObjHashSet() {
// return index;
// }
// private void maybeCopy() {
// if (cow != null) {
// CopyOnWriteObjHashSet<TOP> v = cow.get();
// if (v != null) {
// v.makeCopy();
// }
// cow = null;
// }
// }
// /**
// * Called when iterator created, and when a reset concur mod happens
// * @return cow to use in iterator
// */
// public CopyOnWriteObjHashSet<TOP> getNonNullCow() {
// if (cow != null) {
// CopyOnWriteObjHashSet<TOP> n = cow.get();
// if (n != null) {
// return n;
// }
// }
//
// // null means index updated since iterator was created, need to make new cow and use it
// CopyOnWriteObjHashSet<TOP> n = new CopyOnWriteObjHashSet<TOP>(index);
// cow = new WeakReference<>(n);
// return n;
// }
}