| package de.ids_mannheim.korap.query.spans; |
| |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.List; |
| 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.SpanDistanceQuery; |
| |
| /** Enumeration of token-based distance span matches. |
| * Each match consists of two specified spans having an actual distance |
| * in the range of the min and max distance parameters given in the query. |
| * |
| * @author margaretha |
| * */ |
| public class TokenDistanceSpans extends OrderedDistanceSpans{ |
| |
| public TokenDistanceSpans(SpanDistanceQuery query, |
| AtomicReaderContext context, Bits acceptDocs, |
| Map<Term, TermContext> termContexts) throws IOException { |
| super(query, context, acceptDocs, termContexts); |
| hasMoreSpans = hasMoreFirstSpans; |
| } |
| |
| @Override |
| protected void setCandidateList() throws IOException{ |
| if (candidateListDocNum == secondSpans.doc()){ |
| copyPossibleCandidates(); |
| addNewCandidates(); |
| candidateListIndex = -1; |
| } |
| else { |
| candidateList.clear(); |
| if (hasMoreFirstSpans && ensureSameDoc(firstSpans,secondSpans)){ |
| candidateListDocNum = firstSpans.doc(); |
| addNewCandidates(); |
| candidateListIndex = -1; |
| } |
| } |
| } |
| |
| /** Copy candidate spans which are still possible to create a match, |
| * from the candidate list prepared for the previous second spans. |
| * */ |
| private void copyPossibleCandidates(){ |
| List<CandidateSpan> temp = new ArrayList<>(); |
| for (CandidateSpan cs : candidateList){ |
| if (cs.getEnd()+maxDistance > secondSpans.start()) |
| temp.add(cs); |
| } |
| candidateList = temp; |
| } |
| |
| /** Add new possible candidates for the current secondspan. |
| * */ |
| private void addNewCandidates() throws IOException{ |
| while ( hasMoreFirstSpans && |
| firstSpans.doc() == candidateListDocNum && |
| firstSpans.start() < secondSpans.end()){ |
| |
| if (firstSpans.end()+maxDistance > secondSpans.start()) |
| candidateList.add(new CandidateSpan(firstSpans)); |
| |
| hasMoreFirstSpans = firstSpans.next(); |
| } |
| } |
| |
| @Override |
| protected boolean findMatch() throws IOException { |
| CandidateSpan candidateSpan = candidateList.get(candidateListIndex); |
| if (minDistance == 0 && |
| // intersection |
| candidateSpan.getStart() < secondSpans.end() && |
| secondSpans.start() < candidateSpan.getEnd()){ |
| |
| setMatchProperties(candidateSpan, true); |
| return true; |
| } |
| |
| int actualDistance = secondSpans.start() - candidateSpan.getEnd() +1; |
| if (candidateSpan.getStart() < secondSpans.start() && |
| minDistance <= actualDistance && |
| actualDistance <= maxDistance){ |
| |
| setMatchProperties(candidateSpan, false); |
| return true; |
| } |
| return false; |
| } |
| |
| @Override |
| public long cost() { |
| CandidateSpan candidateSpan = candidateList.get(candidateListIndex); |
| return candidateSpan.getCost() + secondSpans.cost(); |
| } |
| |
| @Override |
| protected boolean isSecondSpanValid() throws IOException { |
| return true; |
| } |
| } |