| package de.ids_mannheim.korap.query.spans; |
| |
| import java.io.IOException; |
| import java.util.Map; |
| |
| import org.apache.lucene.index.AtomicReaderContext; |
| import org.apache.lucene.index.Term; |
| import org.apache.lucene.index.TermContext; |
| import org.apache.lucene.util.Bits; |
| |
| import de.ids_mannheim.korap.query.SpanSubspanQuery; |
| |
| /** |
| * Enumeration of SubSpans, which are parts of another Spans. The |
| * SubSpans are specified with a start offset relative to the original |
| * span and a length. If the length is unspecified or 0, the end |
| * position of the subspans is the same as that of the original spans. |
| * |
| * @author margaretha |
| * |
| */ |
| public class SubSpans extends SimpleSpans { |
| |
| private int startOffset, length; |
| |
| /** |
| * Constructs SubSpans for the given {@link SpanSubspanQuery} |
| * specifiying the start offset and the length of the subspans. |
| * |
| * @param subspanQuery |
| * a SpanSubspanQuery |
| * @param context |
| * @param acceptDocs |
| * @param termContexts |
| * @throws IOException |
| */ |
| public SubSpans (SpanSubspanQuery subspanQuery, |
| AtomicReaderContext context, Bits acceptDocs, |
| Map<Term, TermContext> termContexts) throws IOException { |
| super(subspanQuery, context, acceptDocs, termContexts); |
| this.startOffset = subspanQuery.getStartOffset(); |
| this.length = subspanQuery.getLength(); |
| hasMoreSpans = firstSpans.next(); |
| } |
| |
| @Override |
| public boolean next() throws IOException { |
| isStartEnumeration = false; |
| return advance(); |
| } |
| |
| /** |
| * Advances the SubSpans to the next match. |
| * |
| * @return <code>true</code> if a match is found, |
| * <code>false</code> otherwise. |
| * @throws IOException |
| */ |
| private boolean advance() throws IOException { |
| while (hasMoreSpans) { |
| if (findMatch()) { |
| hasMoreSpans = firstSpans.next(); |
| return true; |
| } |
| hasMoreSpans = firstSpans.next(); |
| } |
| return false; |
| } |
| |
| /** |
| * Sets the properties of the current match/subspan. |
| * |
| * @throws IOException |
| */ |
| public boolean findMatch() throws IOException { |
| if (this.startOffset < 0) { |
| matchStartPosition = firstSpans.end() + startOffset; |
| if (matchStartPosition < firstSpans.start()) { |
| matchStartPosition = firstSpans.start(); |
| } |
| } |
| else { |
| matchStartPosition = firstSpans.start() + startOffset; |
| if (matchStartPosition >= firstSpans.end()) { |
| return false; |
| } |
| } |
| |
| if (this.length > 0) { |
| matchEndPosition = matchStartPosition + this.length; |
| if (matchEndPosition > firstSpans.end()) { |
| matchEndPosition = firstSpans.end(); |
| } |
| } |
| else { |
| matchEndPosition = firstSpans.end(); |
| } |
| matchPayload = firstSpans.getPayload(); |
| matchDocNumber = firstSpans.doc(); |
| return true; |
| } |
| |
| @Override |
| public boolean skipTo(int target) throws IOException { |
| if (hasMoreSpans && (firstSpans.doc() < target)) { |
| if (!firstSpans.skipTo(target)) { |
| hasMoreSpans = false; |
| return false; |
| } |
| } |
| matchPayload.clear(); |
| return advance(); |
| } |
| |
| @Override |
| public long cost() { |
| return firstSpans.cost() + 1; |
| } |
| |
| } |