blob: c95afcc012e8d0f9c95769b39c50477538d0a3f2 [file] [log] [blame]
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;
}
}