You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by si...@apache.org on 2012/07/19 03:13:59 UTC
svn commit: r1363198 [1/2] - in /lucene/dev/branches/LUCENE-2878/lucene:
core/src/java/org/apache/lucene/search/
core/src/java/org/apache/lucene/search/payloads/
core/src/java/org/apache/lucene/search/positions/
core/src/java/org/apache/lucene/search/s...
Author: simonw
Date: Thu Jul 19 01:13:58 2012
New Revision: 1363198
URL: http://svn.apache.org/viewvc?rev=1363198&view=rev
Log:
LUCENE-2878: Added Brouwerian operator, several testcases and introduced matchDistance on position iterators for filtering
Added:
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianIntervalIterator.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianQuery.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionQuery.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/TermIntervalIterator.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinOrderedFilter.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestBrouwerianQuery.java (with props)
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestPositionFilterQueries.java (with props)
Removed:
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/MockSpanQuery.java
Modified:
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/Scorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BlockPositionIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/ConjunctionPositionIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/DisjunctionPositionIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueue.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueAnd.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueOr.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/MaxLengthPositionIntervalIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionPositionIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionFilterQuery.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionIntervalIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/RangePositionsIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinPositionIterator.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestSimplePositions.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestNearSpansOrdered.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestPayloadSpans.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpanFirstQuery.java
lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/spans/TestSpans.java
lucene/dev/branches/LUCENE-2878/lucene/highlighter/src/java/org/apache/lucene/search/poshighlight/PositionIntervalArrayIterator.java
lucene/dev/branches/LUCENE-2878/lucene/highlighter/src/test/org/apache/lucene/search/poshighlight/PosHighlighterTest.java
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionScorer.java Thu Jul 19 01:13:58 2012
@@ -17,15 +17,15 @@ package org.apache.lucene.search;
* limitations under the License.
*/
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Comparator;
+
import org.apache.lucene.search.positions.BooleanPositionIterator;
import org.apache.lucene.search.positions.ConjunctionPositionIterator;
import org.apache.lucene.search.positions.PositionIntervalIterator;
import org.apache.lucene.util.ArrayUtil;
-import java.io.IOException;
-import java.util.Collection;
-import java.util.Comparator;
-
/** Scorer for conjunctions, sets of queries, all of which are required. */
class ConjunctionScorer extends Scorer {
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ConjunctionTermScorer.java Thu Jul 19 01:13:58 2012
@@ -17,17 +17,17 @@ package org.apache.lucene.search;
* limitations under the License.
*/
+import java.io.IOException;
+import java.util.Comparator;
+
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.search.TermQuery.TermDocsEnumFactory;
-import org.apache.lucene.search.TermScorer.TermPositions;
import org.apache.lucene.search.positions.ConjunctionPositionIterator;
import org.apache.lucene.search.positions.PositionIntervalIterator;
+import org.apache.lucene.search.positions.TermIntervalIterator;
import org.apache.lucene.search.similarities.Similarity.ExactSimScorer;
import org.apache.lucene.util.ArrayUtil;
-import java.io.IOException;
-import java.util.Comparator;
-
/** Scorer for conjunctions, sets of terms, all of which are required. */
class ConjunctionTermScorer extends Scorer {
@@ -123,10 +123,10 @@ class ConjunctionTermScorer extends Scor
@Override
public PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException {
- TermPositions[] positionIters = new TermPositions[origDocsAndFreqs.length];
+ TermIntervalIterator[] positionIters = new TermIntervalIterator[origDocsAndFreqs.length];
for (int i = 0; i < positionIters.length; i++) {
DocsAndFreqs d = origDocsAndFreqs[i];
- positionIters[i] = new TermPositions(this, d.factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
+ positionIters[i] = new TermIntervalIterator(this, d.factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
}
return new ConjunctionPositionIterator(this, collectPositions, positionIters);
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/ExactPhraseScorer.java Thu Jul 19 01:13:58 2012
@@ -20,6 +20,7 @@ package org.apache.lucene.search;
import org.apache.lucene.index.DocsAndPositionsEnum;
import org.apache.lucene.search.positions.BlockPositionIterator;
import org.apache.lucene.search.positions.PositionIntervalIterator;
+import org.apache.lucene.search.positions.TermIntervalIterator;
import org.apache.lucene.search.similarities.Similarity;
import java.io.IOException;
@@ -326,9 +327,9 @@ final class ExactPhraseScorer extends Sc
@Override
public PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException {
- TermScorer.TermPositions[] posIters = new TermScorer.TermPositions[chunkStates.length];
+ TermIntervalIterator[] posIters = new TermIntervalIterator[chunkStates.length];
for (int i = 0; i < chunkStates.length; i++) {
- posIters[i] = new TermScorer.TermPositions(this, chunkStates[i].factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
+ posIters[i] = new TermIntervalIterator(this, chunkStates[i].factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
}
return new BlockPositionIterator(this, collectPositions, posIters);
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/Scorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/Scorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/Scorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/Scorer.java Thu Jul 19 01:13:58 2012
@@ -63,6 +63,7 @@ public abstract class Scorer extends Doc
}
}
+ //nocommit javadocs
public abstract PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException;
/**
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/SloppyPhraseScorer.java Thu Jul 19 01:13:58 2012
@@ -33,6 +33,7 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.search.positions.ConjunctionPositionIterator;
import org.apache.lucene.search.positions.MaxLengthPositionIntervalIterator;
import org.apache.lucene.search.positions.PositionIntervalIterator;
+import org.apache.lucene.search.positions.TermIntervalIterator;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.OpenBitSet;
@@ -559,7 +560,7 @@ final class SloppyPhraseScorer extends P
if (!map.containsKey(term)) {
DocsAndPositionsEnum docsAndPosEnum = postings[i].factory
.docsAndPositionsEnum(needsOffsets);
- iterAndOffset = new IterAndOffsets(new TermScorer.TermPositions(this, docsAndPosEnum, needsPayloads,
+ iterAndOffset = new IterAndOffsets(new TermIntervalIterator(this, docsAndPosEnum, needsPayloads,
collectPositions));
map.put(term, iterAndOffset);
} else {
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/TermScorer.java Thu Jul 19 01:13:58 2012
@@ -23,6 +23,7 @@ import org.apache.lucene.index.DocsAndPo
import org.apache.lucene.index.DocsEnum;
import org.apache.lucene.search.TermQuery.TermDocsEnumFactory;
import org.apache.lucene.search.positions.PositionIntervalIterator;
+import org.apache.lucene.search.positions.TermIntervalIterator;
import org.apache.lucene.search.positions.PositionIntervalIterator.PositionInterval;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.BytesRef;
@@ -98,100 +99,6 @@ final class TermScorer extends Scorer {
@Override
public PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException {
- return new TermPositions(this, factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
- }
-
- static final class TermPositions extends PositionIntervalIterator {
- private final PositionInterval interval;
- int positionsPending;
- private final DocsAndPositionsEnum docsAndPos;
- private int docID = -1;
-
- public TermPositions(Scorer scorer, DocsAndPositionsEnum docsAndPos, boolean doPayloads, boolean collectPositions) {
- super(scorer, collectPositions);
- this.docsAndPos = docsAndPos;
- this.interval = doPayloads ? new PayloadPosInterval(docsAndPos, this)
- : new PositionInterval();
- }
-
- @Override
- public PositionInterval next() throws IOException {
- if (--positionsPending >= 0) {
- interval.begin = interval.end = docsAndPos.nextPosition();
- interval.offsetBegin = docsAndPos.startOffset();
- interval.offsetEnd = docsAndPos.endOffset();
- return interval;
- }
- positionsPending = 0;
- return null;
- }
-
- @Override
- public int docID() {
- return docID;
- }
-
- @Override
- public PositionIntervalIterator[] subs(boolean inOrder) {
- return EMPTY;
- }
-
- @Override
- public void collect(PositionCollector collector) {
- collector.collectLeafPosition(scorer, interval, docID);
- }
-
- @Override
- public int advanceTo(int docId) throws IOException {
- int advance = docsAndPos.advance(docId);
- if (advance != NO_MORE_DOCS) {
- positionsPending = docsAndPos.freq();
- }
- interval.reset();
- return docID = docsAndPos.docID();
- }
-
- @Override
- public String toString() {
- return "TermPositions [interval=" + interval + ", positionsPending="
- + positionsPending + ", docID=" + docID + "]";
- }
- }
-
- private static final class PayloadPosInterval extends PositionInterval {
- private int pos = -1;
- private final DocsAndPositionsEnum payloads;
- private final TermPositions termPos;
-
- public PayloadPosInterval(DocsAndPositionsEnum payloads, TermPositions pos) {
- this.payloads = payloads;
- this.termPos = pos;
- }
-
- @Override
- public boolean payloadAvailable() {
- return payloads.hasPayload();
- }
-
- @Override
- public boolean nextPayload(BytesRef ref) throws IOException {
- if (pos == termPos.positionsPending) {
- return false;
- } else {
- pos = termPos.positionsPending;
- final BytesRef payload = payloads.getPayload();
- ref.bytes = payload.bytes;
- ref.length = payload.length;
- ref.offset = payload.offset;
- return true;
- }
- }
-
- @Override
- public void reset() {
- super.reset();
- pos = -1;
- }
-
+ return new TermIntervalIterator(this, factory.docsAndPositionsEnum(needsOffsets), needsPayloads, collectPositions);
}
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/payloads/PayloadTermQuery.java Thu Jul 19 01:13:58 2012
@@ -19,15 +19,19 @@ package org.apache.lucene.search.payload
import org.apache.lucene.index.AtomicReaderContext;
import org.apache.lucene.index.Term;
-import org.apache.lucene.search.*;
-import org.apache.lucene.search.positions.PositionIntervalIterator.PositionInterval;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.ComplexExplanation;
import org.apache.lucene.search.similarities.DefaultSimilarity;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.search.similarities.Similarity.SloppySimScorer;
-import org.apache.lucene.search.spans.SpanScorer;
+import org.apache.lucene.search.spans.TermSpans;
import org.apache.lucene.search.spans.SpanTermQuery;
import org.apache.lucene.search.spans.SpanWeight;
-import org.apache.lucene.search.spans.SpansScorerWrapper;
+import org.apache.lucene.search.spans.SpanScorer;
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.BytesRef;
@@ -76,17 +80,17 @@ public class PayloadTermQuery extends Sp
@Override
public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder,
boolean topScorer, Bits acceptDocs) throws IOException {
- return new PayloadTermSpanScorer((SpansScorerWrapper) query.getSpans(context, acceptDocs, termContexts),
+ return new PayloadTermSpanScorer((TermSpans) query.getSpans(context, acceptDocs, termContexts),
this, similarity.sloppySimScorer(stats, context));
}
protected class PayloadTermSpanScorer extends SpanScorer {
- protected BytesRef payload = new BytesRef();
+ protected BytesRef payload;
protected float payloadScore;
protected int payloadsSeen;
- private final SpansScorerWrapper termSpans;
+ private final TermSpans termSpans;
- public PayloadTermSpanScorer(SpansScorerWrapper spans, Weight weight, Similarity.SloppySimScorer docScorer) throws IOException {
+ public PayloadTermSpanScorer(TermSpans spans, Weight weight, Similarity.SloppySimScorer docScorer) throws IOException {
super(spans, weight, docScorer);
termSpans = spans;
}
@@ -113,19 +117,19 @@ public class PayloadTermQuery extends Sp
}
protected void processPayload(Similarity similarity) throws IOException {
- if (termSpans.isPayloadAvailable()) {
-
- final PositionInterval current = termSpans.current();
- if (current.nextPayload(payload) && payload.length != 0) {
+ final DocsAndPositionsEnum postings = termSpans.getPostings();
+ if (postings.hasPayload()) {
+ payload = postings.getPayload();
+ if (payload != null) {
payloadScore = function.currentScore(doc, term.field(),
- spans.start(), spans.end(), payloadsSeen, payloadScore,
- docScorer.computePayloadFactor(doc, spans.start(), spans.end(), payload));
+ spans.start(), spans.end(), payloadsSeen, payloadScore,
+ docScorer.computePayloadFactor(doc, spans.start(), spans.end(), payload));
} else {
payloadScore = function.currentScore(doc, term.field(),
- spans.start(), spans.end(), payloadsSeen, payloadScore, 1F);
+ spans.start(), spans.end(), payloadsSeen, payloadScore, 1F);
}
payloadsSeen++;
-
+
} else {
// zero out the payload?
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BlockPositionIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BlockPositionIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BlockPositionIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BlockPositionIterator.java Thu Jul 19 01:13:58 2012
@@ -16,12 +16,11 @@ package org.apache.lucene.search.positio
* See the License for the specific language governing permissions and
* limitations under the License.
*/
-import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.positions.PositionIntervalIterator.PositionCollector;
-
import java.io.IOException;
import java.util.Arrays;
+import org.apache.lucene.search.Scorer;
+
/**
*
* @lucene.experimental
@@ -153,4 +152,9 @@ public final class BlockPositionIterator
Arrays.fill(intervals, INFINITE_INTERVAL);
return currentDoc = docId;
}
+
+ @Override
+ public int matchDistance() {
+ return intervals[lastIter].begin - intervals[0].end;
+ }
}
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianIntervalIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianIntervalIterator.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianIntervalIterator.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianIntervalIterator.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,81 @@
+package org.apache.lucene.search.positions;
+
+import java.io.IOException;
+
+import org.apache.lucene.search.Scorer;
+
+/*
+ * 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.
+ */
+
+public class BrouwerianIntervalIterator extends PositionIntervalIterator {
+
+ private final PositionIntervalIterator minuted;
+ private final PositionIntervalIterator subtracted;
+ private PositionInterval subtractedInterval = new PositionInterval();
+ private PositionInterval currentInterval = new PositionInterval();
+ private int secondDoc = -1;
+
+ public BrouwerianIntervalIterator(Scorer scorer, boolean collectPositions, PositionIntervalIterator minuted, PositionIntervalIterator subtracted) {
+ super(scorer, collectPositions);
+ this.minuted = minuted;
+ this.subtracted = subtracted;
+ }
+
+
+ @Override
+ public int advanceTo(int docId) throws IOException {
+ currentDoc = minuted.advanceTo(docId);
+ secondDoc = subtracted.advanceTo(docId);
+ subtractedInterval.reset();
+ return currentDoc;
+ }
+
+ @Override
+ public PositionInterval next() throws IOException {
+ if (secondDoc != currentDoc) {
+ return currentInterval = minuted.next();
+ }
+ while ((currentInterval = minuted.next()) != null) {
+ while(subtractedInterval.lessThan(currentInterval) && (subtractedInterval = subtracted.next()) != null) {
+ }
+ if (subtractedInterval == null || subtractedInterval.greaterThan(currentInterval)) {
+ return currentInterval;
+ }
+ }
+ return currentInterval;
+ }
+
+ @Override
+ public void collect(PositionCollector collector) {
+ assert collectPositions;
+ collector.collectComposite(scorer, currentInterval, currentDoc);
+ minuted.collect(collector);
+
+ }
+
+ @Override
+ public PositionIntervalIterator[] subs(boolean inOrder) {
+ return new PositionIntervalIterator[] {minuted, subtracted};
+ }
+
+
+ @Override
+ public int matchDistance() {
+ return minuted.matchDistance();
+ }
+
+}
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianQuery.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianQuery.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/BrouwerianQuery.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,215 @@
+package org.apache.lucene.search.positions;
+
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+import java.util.Set;
+
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.Explanation;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.util.Bits;
+
+/**
+ *
+ * @lucene.experimental
+ */ // nocommit - javadoc
+public final class BrouwerianQuery extends Query implements Cloneable {
+
+ private Query minuted;
+ private Query subtracted;
+
+
+ public BrouwerianQuery(Query minuted, Query subtracted) {
+ this.minuted = minuted;
+ this.subtracted = subtracted;
+ }
+
+ @Override
+ public void extractTerms(Set<Term> terms) {
+ minuted.extractTerms(terms);
+ subtracted.extractTerms(terms);
+ }
+
+ @Override
+ public Query rewrite(IndexReader reader) throws IOException {
+ BrouwerianQuery clone = null;
+
+ Query rewritten = minuted.rewrite(reader);
+ Query subRewritten = subtracted.rewrite(reader);
+ if (rewritten != minuted || subRewritten != subtracted) {
+ clone = (BrouwerianQuery) this.clone();
+ clone.minuted = rewritten;
+ clone.subtracted = subRewritten;
+ }
+
+ if (clone != null) {
+ return clone; // some clauses rewrote
+ } else {
+ return this; // no clauses rewrote
+ }
+ }
+
+ @Override
+ public Weight createWeight(IndexSearcher searcher) throws IOException {
+ return new BrouwerianQueryWeight(minuted.createWeight(searcher), subtracted.createWeight(searcher));
+ }
+
+ class BrouwerianQueryWeight extends Weight {
+
+ private final Weight minuted;
+ private final Weight subtracted;
+
+ public BrouwerianQueryWeight(Weight minuted, Weight subtracted) {
+ this.minuted = minuted;
+ this.subtracted = subtracted;
+ }
+
+ @Override
+ public Explanation explain(AtomicReaderContext context, int doc)
+ throws IOException {
+ return minuted.explain(context, doc);
+ }
+
+ @Override
+ public Scorer scorer(AtomicReaderContext context, boolean scoreDocsInOrder,
+ boolean topScorer, Bits acceptDocs) throws IOException {
+ final Scorer scorer = minuted.scorer(context, scoreDocsInOrder, topScorer, acceptDocs);
+ final Scorer subScorer = subtracted.scorer(context, scoreDocsInOrder, topScorer, acceptDocs);
+ if (subScorer == null) {
+ return scorer;
+ }
+ return scorer == null ? null : new PositionFilterScorer(this, scorer, subScorer);
+ }
+
+ @Override
+ public Query getQuery() {
+ return BrouwerianQuery.this;
+ }
+
+ @Override
+ public float getValueForNormalization() throws IOException {
+ return minuted.getValueForNormalization();
+ }
+
+ @Override
+ public void normalize(float norm, float topLevelBoost) {
+ minuted.normalize(norm, topLevelBoost);
+ }
+ }
+
+ class PositionFilterScorer extends Scorer {
+
+ private final Scorer other;
+ private PositionIntervalIterator filter;
+ private final Scorer substracted;
+
+ public PositionFilterScorer(Weight weight, Scorer other, Scorer substacted) throws IOException {
+ super(weight);
+ this.other = other;
+ this.substracted = substacted;
+ this.filter = new BrouwerianIntervalIterator(other, false, other.positions(false, false, false), substacted.positions(false, false, false));
+ }
+
+ @Override
+ public float score() throws IOException {
+ return other.score();
+ }
+
+ @Override
+ public PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException {
+ return new BrouwerianIntervalIterator(other, collectPositions, other.positions(needsPayloads, needsOffsets, collectPositions), substracted.positions(needsPayloads, needsOffsets, collectPositions));
+ }
+
+ @Override
+ public int docID() {
+ return other.docID();
+ }
+
+ @Override
+ public int nextDoc() throws IOException {
+ int docId = -1;
+ while ((docId = other.nextDoc()) != Scorer.NO_MORE_DOCS) {
+ filter.advanceTo(docId);
+ if (filter.next() != null) { // just check if there is a position that matches!
+ return other.docID();
+ }
+ }
+ return Scorer.NO_MORE_DOCS;
+ }
+
+ @Override
+ public int advance(int target) throws IOException {
+ int docId = other.advance(target);
+ if (docId == Scorer.NO_MORE_DOCS) {
+ return NO_MORE_DOCS;
+ }
+ do {
+ filter.advanceTo(docId);
+ if (filter.next() != null) {
+ return other.docID();
+ }
+ } while ((docId = other.nextDoc()) != Scorer.NO_MORE_DOCS);
+ return NO_MORE_DOCS;
+ }
+
+ }
+
+ @Override
+ public String toString(String field) {
+ //nocommit TODO
+ return minuted.toString();
+ }
+
+ /*
+ *
+ */
+ @Override
+ public int hashCode() {
+ final int prime = 31;
+ int result = super.hashCode();
+ result = prime * result + ((minuted == null) ? 0 : minuted.hashCode());
+ result = prime * result
+ + ((subtracted == null) ? 0 : subtracted.hashCode());
+ return result;
+ }
+
+ /*
+ *
+ */
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) return true;
+ if (!super.equals(obj)) return false;
+ if (getClass() != obj.getClass()) return false;
+ BrouwerianQuery other = (BrouwerianQuery) obj;
+ if (minuted == null) {
+ if (other.minuted != null) return false;
+ } else if (!minuted.equals(other.minuted)) return false;
+ if (subtracted == null) {
+ if (other.subtracted != null) return false;
+ } else if (!subtracted.equals(other.subtracted)) return false;
+ return true;
+ }
+
+}
\ No newline at end of file
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/ConjunctionPositionIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/ConjunctionPositionIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/ConjunctionPositionIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/ConjunctionPositionIterator.java Thu Jul 19 01:13:58 2012
@@ -38,6 +38,8 @@ public final class ConjunctionPositionIt
private final IntervalQueueAnd queue;
private final int nrMustMatch;
private SnapshotPositionCollector snapshot;
+ private int rightExtremeBegin;
+
public ConjunctionPositionIterator(Scorer scorer, boolean collectPositions,
PositionIntervalIterator... iterators) throws IOException {
@@ -58,7 +60,7 @@ public final class ConjunctionPositionIt
PositionInterval interval = null;
if ((interval = iterators[top.index].next()) != null) {
top.interval = interval;
- queue.updateRightExtreme(interval);
+ queue.updateRightExtreme(top);
queue.updateTop();
} else {
queue.pop();
@@ -86,7 +88,7 @@ public final class ConjunctionPositionIt
&& queue.currentCandidate.end == top.end) {
return queue.currentCandidate;
}
-
+ rightExtremeBegin = queue.rightExtremeBegin;
advance();
if (queue.size() < nrMustMatch) {
break;
@@ -97,21 +99,31 @@ public final class ConjunctionPositionIt
@Override
- public int advanceTo(int docId) throws IOException {
- queue.reset();
- int advancedTo = -1;
- for (int i = 0; i < iterators.length; i++) {
- currentDoc = iterators[i].advanceTo(docId);
- assert advancedTo == -1 || advancedTo == currentDoc;
-
- final PositionInterval interval = iterators[i].next();
- if (interval != null) {
- IntervalRef intervalRef = new IntervalRef(interval, i); // TODO maybe reuse?
- queue.updateRightExtreme(intervalRef.interval);
- queue.add(intervalRef);
+ public int advanceTo(final int docId) throws IOException {
+ int advancedTo = docId;
+ while (true) {
+ queue.reset();
+ for (int i = 0; i < iterators.length; i++) {
+ currentDoc = iterators[i].advanceTo(advancedTo);
+ if (currentDoc == NO_MORE_DOCS) {
+ return NO_MORE_DOCS;
+ }
+
+ if (i != 0 && currentDoc != advancedTo) {
+ advancedTo = currentDoc;
+ continue;
+ }
+ advancedTo = currentDoc;
+ final PositionInterval interval = iterators[i].next();
+ if (interval != null) {
+ IntervalRef intervalRef = new IntervalRef(interval, i); // TODO maybe
+ // reuse?
+ queue.updateRightExtreme(intervalRef);
+ queue.add(intervalRef);
+ }
}
+ return currentDoc;
}
- return currentDoc;
}
@@ -227,4 +239,9 @@ public final class ConjunctionPositionIt
}
}
+
+ @Override
+ public int matchDistance() {
+ return (rightExtremeBegin) - (queue.currentTopEnd) -1; // align the match if pos are adjacent
+ }
}
\ No newline at end of file
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/DisjunctionPositionIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/DisjunctionPositionIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/DisjunctionPositionIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/DisjunctionPositionIterator.java Thu Jul 19 01:13:58 2012
@@ -20,7 +20,6 @@ import java.io.IOException;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.positions.IntervalQueue.IntervalRef;
-import org.apache.lucene.search.positions.PositionIntervalIterator.PositionCollector;
/**
* DisjunctionPositionIterator based on minimal interval semantics for OR
@@ -53,7 +52,7 @@ public final class DisjunctionPositionIt
@Override
public PositionInterval next() throws IOException {
- while (queue.size() > 0 && queue.topContainsQueueInterval()) {
+ while (queue.size() > 0 && queue.top().interval.begin <= queue.currentCandidate.begin) {
advance();
}
if (queue.size() == 0) {
@@ -77,7 +76,7 @@ public final class DisjunctionPositionIt
@Override
public int advanceTo(int docId) throws IOException {
- queue.clear();
+ queue.reset();
int minAdvance = NO_MORE_DOCS;
for (int i = 0; i < iterators.length; i++) {
if (iterators[i].docID() < docId) {
@@ -97,4 +96,9 @@ public final class DisjunctionPositionIt
return currentDoc = minAdvance;
}
+ @Override
+ public int matchDistance() {
+ return iterators[queue.top().index].matchDistance();
+ }
+
}
\ No newline at end of file
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueue.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueue.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueue.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueue.java Thu Jul 19 01:13:58 2012
@@ -31,6 +31,10 @@ abstract class IntervalQueue extends Pri
public void reset() {
clear();
+ currentCandidate.begin = Integer.MIN_VALUE;
+ currentCandidate.end = Integer.MIN_VALUE;
+ currentCandidate.offsetBegin = -1;
+ currentCandidate.offsetEnd = -1;
}
abstract public boolean topContainsQueueInterval();
@@ -43,7 +47,6 @@ abstract class IntervalQueue extends Pri
final static class IntervalRef {
PositionInterval interval;
- int ord;
int index;
IntervalRef(PositionInterval interval, int index) {
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueAnd.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueAnd.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueAnd.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueAnd.java Thu Jul 19 01:13:58 2012
@@ -25,6 +25,9 @@ final class IntervalQueueAnd extends Int
int rightExtreme = Integer.MIN_VALUE;
int rightExtremeOffset = Integer.MIN_VALUE;
+ int rightExtremeBegin;
+ int currentTopEnd;
+
public IntervalQueueAnd(int size) {
super(size);
@@ -32,15 +35,17 @@ final class IntervalQueueAnd extends Int
public void reset () {
super.reset();
- currentCandidate.begin = Integer.MIN_VALUE;
- currentCandidate.end = Integer.MIN_VALUE;
rightExtreme = Integer.MIN_VALUE;
rightExtremeOffset = Integer.MIN_VALUE;
}
- public void updateRightExtreme(PositionInterval interval) {
- rightExtreme = Math.max(rightExtreme, interval.end);
- rightExtremeOffset = Math.max(rightExtremeOffset, interval.offsetEnd);
+ public void updateRightExtreme(IntervalRef intervalRef) {
+ final PositionInterval interval = intervalRef.interval;
+ if (rightExtreme <= interval.end) {
+ rightExtreme = interval.end;
+ rightExtremeOffset = interval.offsetEnd;
+ rightExtremeBegin = interval.begin;
+ }
}
public boolean topContainsQueueInterval() {
@@ -50,11 +55,14 @@ final class IntervalQueueAnd extends Int
}
public void updateCurrentCandidate() {
- PositionInterval interval = top().interval;
+ final IntervalRef top = top();
+ PositionInterval interval = top.interval;
currentCandidate.begin = interval.begin;
currentCandidate.offsetBegin = interval.offsetBegin;
currentCandidate.end = rightExtreme;
currentCandidate.offsetEnd = rightExtremeOffset;
+ currentTopEnd = interval.end;
+
}
@Override
@@ -63,4 +71,5 @@ final class IntervalQueueAnd extends Int
final PositionInterval b = right.interval;
return a.begin < b.begin || (a.begin == b.begin && a.end > b.end) || a.offsetBegin < b.offsetBegin;
}
+
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueOr.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueOr.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueOr.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/IntervalQueueOr.java Thu Jul 19 01:13:58 2012
@@ -26,10 +26,6 @@ final class IntervalQueueOr extends Inte
super(size);
}
- public void reset() {
- clear();
- }
-
public boolean topContainsQueueInterval() {
PositionInterval interval = top().interval;
return interval.begin <= currentCandidate.begin
@@ -44,7 +40,7 @@ final class IntervalQueueOr extends Inte
protected boolean lessThan(IntervalRef left, IntervalRef right) {
final PositionInterval a = left.interval;
final PositionInterval b = right.interval;
- return a.end < b.end|| (a.end == b.end && a.begin >= b.begin);
+ return a.end < b.end || (a.end == b.end && a.begin >= b.begin);
}
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/MaxLengthPositionIntervalIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/MaxLengthPositionIntervalIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/MaxLengthPositionIntervalIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/MaxLengthPositionIntervalIterator.java Thu Jul 19 01:13:58 2012
@@ -19,13 +19,12 @@ package org.apache.lucene.search.positio
import java.io.IOException;
import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.positions.IntervalQueue.IntervalRef;
/**
* An interval iterator that has the semantics of sloppy phrase query.
*/
public class MaxLengthPositionIntervalIterator extends PositionIntervalIterator {
-
+ //TODO rename to sloppy iter?
private final int maxLen;
private int matchDistance;
private final PositionIntervalIterator iterator;
@@ -60,7 +59,7 @@ public class MaxLengthPositionIntervalIt
return currentDoc = iterator.advanceTo(docId);
}
- public int matchLength() {
+ public int matchDistance() {
return matchDistance;
}
@@ -114,6 +113,11 @@ public class MaxLengthPositionIntervalIt
public PositionIntervalIterator[] subs(boolean inOrder) {
return null;
}
+
+ @Override
+ public int matchDistance() {
+ return sloppyInterval.end - sloppyInterval.begin;
+ }
}
@@ -201,6 +205,11 @@ public class MaxLengthPositionIntervalIt
public PositionIntervalIterator[] subs(boolean inOrder) {
return new PositionIntervalIterator[] {groupIterator};
}
+
+ @Override
+ public int matchDistance() {
+ return sloppyGroupInterval.end - sloppyGroupInterval.begin;
+ }
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionPositionIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionPositionIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionPositionIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionPositionIterator.java Thu Jul 19 01:13:58 2012
@@ -34,7 +34,10 @@ public final class OrderedConjunctionPos
private final PositionInterval interval = new PositionInterval(
Integer.MAX_VALUE, Integer.MAX_VALUE, -1, -1);
private int index = 1;
-
+ private int lastTopEnd;
+ private int lastEndBegin;
+
+
public OrderedConjunctionPositionIterator(boolean collectPositions, PositionIntervalIterator other) {
super(other.scorer, collectPositions);
assert other.subs(true) != null;
@@ -85,6 +88,8 @@ public final class OrderedConjunctionPos
interval.end = intervals[lastIter].end;
interval.offsetBegin = intervals[0].offsetBegin;
interval.offsetEnd = intervals[lastIter].offsetEnd;
+ lastTopEnd = intervals[0].end;
+ lastEndBegin = intervals[lastIter].begin;
b = intervals[lastIter].begin;
index = 1;
intervals[0] = iterators[0].next();
@@ -124,4 +129,9 @@ public final class OrderedConjunctionPos
return currentDoc = docId;
}
+ @Override
+ public int matchDistance() {
+ return (lastEndBegin-lastIter) - lastTopEnd;
+ }
+
}
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionQuery.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionQuery.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/OrderedConjunctionQuery.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,38 @@
+package org.apache.lucene.search.positions;
+
+/*
+ * 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.
+ */
+
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Query;
+
+public class OrderedConjunctionQuery extends PositionFilterQuery {
+
+ public OrderedConjunctionQuery(int slop, Query... queries) {
+ super(buildBooleanQuery(queries), new WithinOrderedFilter(slop + queries.length - 1));
+ }
+
+ private static BooleanQuery buildBooleanQuery(Query... queries) {
+ BooleanQuery bq = new BooleanQuery();
+ for (Query q : queries) {
+ bq.add(q, BooleanClause.Occur.MUST);
+ }
+ return bq;
+ }
+
+}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionFilterQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionFilterQuery.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionFilterQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionFilterQuery.java Thu Jul 19 01:13:58 2012
@@ -80,7 +80,16 @@ public class PositionFilterQuery extends
@Override
public Explanation explain(AtomicReaderContext context, int doc)
throws IOException {
- return other.explain(context, doc);
+ Scorer scorer = scorer(context, true, false, context.reader()
+ .getLiveDocs());
+ if (scorer != null) {
+ int newDoc = scorer.advance(doc);
+ if (newDoc == doc) {
+ return other.explain(context, doc);
+ }
+ }
+ return new ComplexExplanation(false, 0.0f,
+ "No matching term within position filter");
}
@Override
@@ -110,7 +119,6 @@ public class PositionFilterQuery extends
private final Scorer other;
private PositionIntervalIterator filter;
- private final FilteredPositions filtered;
public PositionFilterScorer(Weight weight, Scorer other) throws IOException {
super(weight);
@@ -119,7 +127,6 @@ public class PositionFilterQuery extends
this.filter = PositionFilterQuery.this.filter != null
? PositionFilterQuery.this.filter.filter(other.positions(false, false, false))
: other.positions(false, false, false);
- filtered = new FilteredPositions(this, filter);
}
@Override
@@ -143,7 +150,7 @@ public class PositionFilterQuery extends
int docId = -1;
while ((docId = other.nextDoc()) != Scorer.NO_MORE_DOCS) {
filter.advanceTo(docId);
- if ((filtered.interval = filter.next()) != null) { // just check if there is a position that matches!
+ if (filter.next() != null) { // just check if there is a position that matches!
return other.docID();
}
}
@@ -158,7 +165,7 @@ public class PositionFilterQuery extends
}
do {
filter.advanceTo(docId);
- if ((filtered.interval = filter.next()) != null) {
+ if (filter.next() != null) {
return other.docID();
}
} while ((docId = other.nextDoc()) != Scorer.NO_MORE_DOCS);
@@ -169,42 +176,9 @@ public class PositionFilterQuery extends
@Override
public String toString(String field) {
- return inner.toString();
+ return filter.toString() + "(" + inner.toString() + ")";
}
- private final class FilteredPositions extends PositionIntervalIterator {
- public FilteredPositions(Scorer scorer, PositionIntervalIterator other) {
- super(scorer, other.collectPositions);
- this.other = other;
- }
-
- private final PositionIntervalIterator other;
- PositionInterval interval;
- @Override
- public int advanceTo(int docId) throws IOException {
- return currentDoc = other.docID();
- }
-
- @Override
- public PositionInterval next() throws IOException {
- PositionInterval current = this.interval;
- this.interval = null;
- return current;
- }
-
- @Override
- public void collect(PositionCollector collector) {
- assert this.collectPositions;
- other.collect(collector);
-
- }
- @Override
- public PositionIntervalIterator[] subs(boolean inOrder) {
- return EMPTY;
- }
-
- }
-
@Override
public int hashCode() {
final int prime = 31;
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionIntervalIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionIntervalIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionIntervalIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/PositionIntervalIterator.java Thu Jul 19 01:13:58 2012
@@ -24,30 +24,34 @@ import java.io.IOException;
/**
*
* @lucene.experimental
- */ // nocommit - javadoc
+ */
+// nocommit - javadoc
public abstract class PositionIntervalIterator {
-
+
public static final PositionIntervalIterator[] EMPTY = new PositionIntervalIterator[0];
public static final PositionIntervalIterator NO_MORE_POSITIONS = new NoPositionsIntervalIterator();
public static final int NO_MORE_DOCS = Integer.MAX_VALUE;
-
+
protected int currentDoc = -1;
protected final Scorer scorer;
protected final boolean collectPositions;
-
+
public PositionIntervalIterator(Scorer scorer, boolean collectPositions) {
this.scorer = scorer;
this.collectPositions = collectPositions;
}
-
+
public abstract int advanceTo(int docId) throws IOException;
-
+
public abstract PositionInterval next() throws IOException;
-
+
public abstract void collect(PositionCollector collector);
-
+
public abstract PositionIntervalIterator[] subs(boolean inOrder);
+
+ public abstract int matchDistance();
+
public int docID() {
return currentDoc;
}
@@ -55,28 +59,48 @@ public abstract class PositionIntervalIt
public Scorer getScorer() {
return scorer;
}
-
+
public static interface PositionIntervalFilter {
public abstract PositionIntervalIterator filter(
PositionIntervalIterator iter);
}
-
+
public static class PositionInterval implements Cloneable {
-
+
public int begin;
public int end;
public int offsetBegin;
public int offsetEnd;
-
+
public PositionInterval(int begin, int end, int offsetBegin, int offsetEnd) {
this.begin = begin;
this.end = end;
this.offsetBegin = offsetBegin;
this.offsetEnd = offsetEnd;
}
-
+
public PositionInterval() {
- this(0, 0, -1, -1);
+ this(Integer.MIN_VALUE, Integer.MIN_VALUE, -1, -1);
+ }
+
+ public boolean lessThanExclusive(PositionInterval other) {
+ return begin < other.begin && end < other.end;
+ }
+
+ public boolean lessThan(PositionInterval other) {
+ return begin <= other.begin && end <= other.end;
+ }
+
+ public boolean greaterThanExclusive(PositionInterval other) {
+ return begin > other.begin && end > other.end;
+ }
+
+ public boolean greaterThan(PositionInterval other) {
+ return begin >= other.begin && end >= other.end;
+ }
+
+ public boolean contains(PositionInterval other) {
+ return begin <= other.begin && other.end <= end;
}
public void copy(PositionInterval other) {
@@ -85,19 +109,20 @@ public abstract class PositionIntervalIt
offsetBegin = other.offsetBegin;
offsetEnd = other.offsetEnd;
}
-
+
public boolean nextPayload(BytesRef ref) throws IOException {
return false;
}
-
+
public boolean payloadAvailable() {
return false;
}
-
+
public void reset() {
- offsetBegin = offsetEnd = begin = end = -1;
+ offsetBegin = offsetEnd = -1;
+ begin = end = Integer.MIN_VALUE;
}
-
+
@Override
public Object clone() {
try {
@@ -106,45 +131,54 @@ public abstract class PositionIntervalIt
throw new RuntimeException(); // should not happen
}
}
-
+
@Override
public String toString() {
- return "PositionInterval [begin=" + begin + "(" + offsetBegin + "), end=" + end + "(" + offsetEnd + ")]";
+ return "PositionInterval [begin=" + begin + "(" + offsetBegin + "), end="
+ + end + "(" + offsetEnd + ")]";
}
-
+
}
-
+
public static interface PositionCollector {
- public void collectLeafPosition(Scorer scorer, PositionInterval interval, int docID);
- public void collectComposite(Scorer scorer, PositionInterval interval, int docID);
-
+ public void collectLeafPosition(Scorer scorer, PositionInterval interval,
+ int docID);
+
+ public void collectComposite(Scorer scorer, PositionInterval interval,
+ int docID);
+
}
private static final class NoPositionsIntervalIterator extends
- PositionIntervalIterator {
-
+ PositionIntervalIterator {
+
public NoPositionsIntervalIterator() {
super(null, false);
}
-
+
@Override
public int advanceTo(int docId) throws IOException {
return PositionIntervalIterator.NO_MORE_DOCS;
}
-
+
@Override
public PositionInterval next() throws IOException {
return null;
}
-
+
@Override
public void collect(PositionCollector collectoc) {}
-
+
@Override
public PositionIntervalIterator[] subs(boolean inOrder) {
return EMPTY;
}
+
+ @Override
+ public int matchDistance() {
+ return Integer.MAX_VALUE;
+ }
}
-
+
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/RangePositionsIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/RangePositionsIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/RangePositionsIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/RangePositionsIterator.java Thu Jul 19 01:13:58 2012
@@ -18,7 +18,6 @@ package org.apache.lucene.search.positio
import java.io.IOException;
-import org.apache.lucene.search.positions.PositionIntervalIterator.PositionCollector;
import org.apache.lucene.search.positions.PositionIntervalIterator.PositionIntervalFilter;
/**
@@ -76,6 +75,11 @@ public class RangePositionsIterator exte
public int advanceTo(int docId) throws IOException {
return currentDoc = iterator.advanceTo(docId);
}
+
+ @Override
+ public int matchDistance() {
+ return iterator.matchDistance();
+ }
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/TermIntervalIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/TermIntervalIterator.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/TermIntervalIterator.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/TermIntervalIterator.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,127 @@
+package org.apache.lucene.search.positions;
+/*
+ * 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.
+ */
+
+import java.io.IOException;
+
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.util.BytesRef;
+
+
+/**
+ *
+ */
+//nocommmit javadocs
+public final class TermIntervalIterator extends PositionIntervalIterator {
+ private final PositionInterval interval;
+ int positionsPending;
+ private final DocsAndPositionsEnum docsAndPos;
+ private int docID = -1;
+
+ public TermIntervalIterator(Scorer scorer, DocsAndPositionsEnum docsAndPos, boolean doPayloads, boolean collectPositions) {
+ super(scorer, collectPositions);
+ this.docsAndPos = docsAndPos;
+ this.interval = doPayloads ? new PayloadPosInterval(docsAndPos, this)
+ : new PositionInterval();
+ }
+
+ @Override
+ public PositionInterval next() throws IOException {
+ if (--positionsPending >= 0) {
+ interval.begin = interval.end = docsAndPos.nextPosition();
+ interval.offsetBegin = docsAndPos.startOffset();
+ interval.offsetEnd = docsAndPos.endOffset();
+ return interval;
+ }
+ positionsPending = 0;
+ return null;
+ }
+
+ @Override
+ public int docID() {
+ return docID;
+ }
+
+ @Override
+ public PositionIntervalIterator[] subs(boolean inOrder) {
+ return EMPTY;
+ }
+
+ @Override
+ public void collect(PositionCollector collector) {
+ collector.collectLeafPosition(scorer, interval, docID);
+ }
+
+ @Override
+ public int advanceTo(int docId) throws IOException {
+ int advance = docsAndPos.advance(docId);
+ if (advance != NO_MORE_DOCS) {
+ positionsPending = docsAndPos.freq();
+ }
+ interval.reset();
+ return docID = docsAndPos.docID();
+ }
+
+ @Override
+ public String toString() {
+ return "TermPositions [interval=" + interval + ", positionsPending="
+ + positionsPending + ", docID=" + docID + "]";
+ }
+
+ @Override
+ public int matchDistance() {
+ return 0;
+ }
+
+ private static final class PayloadPosInterval extends PositionInterval {
+ private int pos = -1;
+ private final DocsAndPositionsEnum payloads;
+ private final TermIntervalIterator termPos;
+
+ public PayloadPosInterval(DocsAndPositionsEnum payloads, TermIntervalIterator pos) {
+ this.payloads = payloads;
+ this.termPos = pos;
+ }
+
+ @Override
+ public boolean payloadAvailable() {
+ return payloads.hasPayload();
+ }
+
+ @Override
+ public boolean nextPayload(BytesRef ref) throws IOException {
+ if (pos == termPos.positionsPending) {
+ return false;
+ } else {
+ pos = termPos.positionsPending;
+ final BytesRef payload = payloads.getPayload();
+ ref.bytes = payload.bytes;
+ ref.length = payload.length;
+ ref.offset = payload.offset;
+ return true;
+ }
+ }
+
+ @Override
+ public void reset() {
+ super.reset();
+ pos = -1;
+ }
+
+ }
+}
\ No newline at end of file
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinOrderedFilter.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinOrderedFilter.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinOrderedFilter.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinOrderedFilter.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,39 @@
+package org.apache.lucene.search.positions;
+
+/*
+ * 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.
+ */
+
+public class WithinOrderedFilter implements PositionIntervalIterator.PositionIntervalFilter {
+
+ private int slop;
+
+ public WithinOrderedFilter(int slop) {
+ this.slop = slop;
+ }
+
+ @Override
+ public PositionIntervalIterator filter(PositionIntervalIterator iter) {
+ return new WithinPositionIterator(slop,
+ new OrderedConjunctionPositionIterator(false, iter));
+ }
+
+ @Override
+ public String toString() {
+ return "WithinOrderedFilter[" + slop + "]";
+ }
+
+}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinPositionIterator.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinPositionIterator.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinPositionIterator.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/positions/WithinPositionIterator.java Thu Jul 19 01:13:58 2012
@@ -17,7 +17,6 @@ package org.apache.lucene.search.positio
*/
import java.io.IOException;
-import org.apache.lucene.search.positions.PositionIntervalIterator.PositionCollector;
import org.apache.lucene.search.positions.PositionIntervalIterator.PositionIntervalFilter;
@@ -41,7 +40,7 @@ public class WithinPositionIterator exte
@Override
public PositionInterval next() throws IOException {
while ((interval = iterator.next()) != null) {
- if((interval.end - interval.begin) <= howMany){
+ if((iterator.matchDistance()) <= howMany){
return interval;
}
}
@@ -69,4 +68,9 @@ public class WithinPositionIterator exte
return currentDoc = iterator.advanceTo(docId);
}
+ @Override
+ public int matchDistance() {
+ return iterator.matchDistance();
+ }
+
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java Thu Jul 19 01:13:58 2012
@@ -17,13 +17,13 @@ package org.apache.lucene.search.spans;
* limitations under the License.
*/
-import org.apache.lucene.search.Scorer;
+import java.io.IOException;
+
import org.apache.lucene.search.Weight;
+import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.positions.PositionIntervalIterator;
import org.apache.lucene.search.similarities.Similarity;
-import java.io.IOException;
-
/**
* Public for extension only.
*/
@@ -100,7 +100,8 @@ public class SpanScorer extends Scorer {
}
@Override
- public PositionIntervalIterator positions(boolean needsPayloads, boolean needsOffsets, boolean collectPositions) throws IOException {
+ public PositionIntervalIterator positions(boolean needsPayloads,
+ boolean needsOffsets, boolean collectPositions) throws IOException {
return null;
}
}
Modified: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java?rev=1363198&r1=1363197&r2=1363198&view=diff
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java (original)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java Thu Jul 19 01:13:58 2012
@@ -1,6 +1,6 @@
package org.apache.lucene.search.spans;
-/**
+/*
* 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.
@@ -17,40 +17,51 @@ package org.apache.lucene.search.spans;
* limitations under the License.
*/
-import java.util.Set;
-
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.Fields;
import org.apache.lucene.index.Term;
-import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.index.TermContext;
+import org.apache.lucene.index.TermState;
+import org.apache.lucene.index.Terms;
+import org.apache.lucene.index.TermsEnum;
+import org.apache.lucene.util.Bits;
+import org.apache.lucene.util.ToStringUtils;
+
+import java.io.IOException;
+import java.util.Map;
+import java.util.Set;
/** Matches spans containing a term. */
-public class SpanTermQuery extends MockSpanQuery {
+public class SpanTermQuery extends SpanQuery {
protected Term term;
/** Construct a SpanTermQuery matching the named term's spans. */
- public SpanTermQuery(Term term) {
- this(term, true);
- }
-
- public SpanTermQuery(Term term, boolean needsPayloads) {
- this(term, new TermQuery(term), needsPayloads);
- }
-
- private SpanTermQuery(Term term, TermQuery query, boolean needsPayloads) {
- super(query, needsPayloads, term.field(), null);
- this.term = term;
- }
+ public SpanTermQuery(Term term) { this.term = term; }
/** Return the term whose spans are matched. */
- public Term getTerm() {
- return term;
- }
+ public Term getTerm() { return term; }
@Override
+ public String getField() { return term.field(); }
+
+ @Override
public void extractTerms(Set<Term> terms) {
terms.add(term);
}
@Override
+ public String toString(String field) {
+ StringBuilder buffer = new StringBuilder();
+ if (term.field().equals(field))
+ buffer.append(term.text());
+ else
+ buffer.append(term.toString());
+ buffer.append(ToStringUtils.boost(getBoost()));
+ return buffer.toString();
+ }
+
+ @Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
@@ -60,14 +71,62 @@ public class SpanTermQuery extends MockS
@Override
public boolean equals(Object obj) {
- if (this == obj) return true;
- if (!super.equals(obj)) return false;
- if (getClass() != obj.getClass()) return false;
+ if (this == obj)
+ return true;
+ if (!super.equals(obj))
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
SpanTermQuery other = (SpanTermQuery) obj;
if (term == null) {
- if (other.term != null) return false;
- } else if (!term.equals(other.term)) return false;
+ if (other.term != null)
+ return false;
+ } else if (!term.equals(other.term))
+ return false;
return true;
}
+ @Override
+ public Spans getSpans(final AtomicReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException {
+ TermContext termContext = termContexts.get(term);
+ final TermState state;
+ if (termContext == null) {
+ // this happens with span-not query, as it doesn't include the NOT side in extractTerms()
+ // so we seek to the term now in this segment..., this sucks because its ugly mostly!
+ final Fields fields = context.reader().fields();
+ if (fields != null) {
+ final Terms terms = fields.terms(term.field());
+ if (terms != null) {
+ final TermsEnum termsEnum = terms.iterator(null);
+ if (termsEnum.seekExact(term.bytes(), true)) {
+ state = termsEnum.termState();
+ } else {
+ state = null;
+ }
+ } else {
+ state = null;
+ }
+ } else {
+ state = null;
+ }
+ } else {
+ state = termContext.get(context.ord);
+ }
+
+ if (state == null) { // term is not present in that reader
+ return TermSpans.EMPTY_TERM_SPANS;
+ }
+
+ final TermsEnum termsEnum = context.reader().terms(term.field()).iterator(null);
+ termsEnum.seekExact(term.bytes(), state);
+
+ final DocsAndPositionsEnum postings = termsEnum.docsAndPositions(acceptDocs, null, false);
+
+ if (postings != null) {
+ return new TermSpans(postings, term);
+ } else {
+ // term does exist, but has no positions
+ throw new IllegalStateException("field \"" + term.field() + "\" was indexed without position data; cannot run SpanTermQuery (term=" + term.text() + ")");
+ }
+ }
}
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,169 @@
+package org.apache.lucene.search.spans;
+/**
+ * Copyright 2005 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+
+import org.apache.lucene.index.Term;
+import org.apache.lucene.index.DocsAndPositionsEnum;
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.util.BytesRef;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Collection;
+
+/**
+ * Expert:
+ * Public for extension only
+ */
+public class TermSpans extends Spans {
+ protected final DocsAndPositionsEnum postings;
+ protected final Term term;
+ protected int doc;
+ protected int freq;
+ protected int count;
+ protected int position;
+
+ public TermSpans(DocsAndPositionsEnum postings, Term term) {
+ this.postings = postings;
+ this.term = term;
+ doc = -1;
+ }
+
+ // only for EmptyTermSpans (below)
+ TermSpans() {
+ term = null;
+ postings = null;
+ }
+
+ @Override
+ public boolean next() throws IOException {
+ if (count == freq) {
+ if (postings == null) {
+ return false;
+ }
+ doc = postings.nextDoc();
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
+ return false;
+ }
+ freq = postings.freq();
+ count = 0;
+ }
+ position = postings.nextPosition();
+ count++;
+ return true;
+ }
+
+ @Override
+ public boolean skipTo(int target) throws IOException {
+ doc = postings.advance(target);
+ if (doc == DocIdSetIterator.NO_MORE_DOCS) {
+ return false;
+ }
+
+ freq = postings.freq();
+ count = 0;
+ position = postings.nextPosition();
+ count++;
+
+ return true;
+ }
+
+ @Override
+ public int doc() {
+ return doc;
+ }
+
+ @Override
+ public int start() {
+ return position;
+ }
+
+ @Override
+ public int end() {
+ return position + 1;
+ }
+
+ // TODO: Remove warning after API has been finalized
+ @Override
+ public Collection<byte[]> getPayload() throws IOException {
+ final BytesRef payload = postings.getPayload();
+ final byte[] bytes;
+ if (payload != null) {
+ bytes = new byte[payload.length];
+ System.arraycopy(payload.bytes, payload.offset, bytes, 0, payload.length);
+ } else {
+ bytes = null;
+ }
+ return Collections.singletonList(bytes);
+ }
+
+ // TODO: Remove warning after API has been finalized
+ @Override
+ public boolean isPayloadAvailable() {
+ return postings.hasPayload();
+ }
+
+ @Override
+ public String toString() {
+ return "spans(" + term.toString() + ")@" +
+ (doc == -1 ? "START" : (doc == Integer.MAX_VALUE) ? "END" : doc + "-" + position);
+ }
+
+ public DocsAndPositionsEnum getPostings() {
+ return postings;
+ }
+
+ private static final class EmptyTermSpans extends TermSpans {
+
+ @Override
+ public boolean next() {
+ return false;
+ }
+
+ @Override
+ public boolean skipTo(int target) {
+ return false;
+ }
+
+ @Override
+ public int doc() {
+ return DocIdSetIterator.NO_MORE_DOCS;
+ }
+
+ @Override
+ public int start() {
+ return -1;
+ }
+
+ @Override
+ public int end() {
+ return -1;
+ }
+
+ @Override
+ public Collection<byte[]> getPayload() {
+ return null;
+ }
+
+ @Override
+ public boolean isPayloadAvailable() {
+ return false;
+ }
+ }
+
+ public static final TermSpans EMPTY_TERM_SPANS = new EmptyTermSpans();
+}
Added: lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestBrouwerianQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestBrouwerianQuery.java?rev=1363198&view=auto
==============================================================================
--- lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestBrouwerianQuery.java (added)
+++ lucene/dev/branches/LUCENE-2878/lucene/core/src/test/org/apache/lucene/search/positions/TestBrouwerianQuery.java Thu Jul 19 01:13:58 2012
@@ -0,0 +1,159 @@
+package org.apache.lucene.search.positions;
+/**
+ * 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.
+ */
+import java.io.IOException;
+import java.util.List;
+
+import org.apache.lucene.analysis.MockAnalyzer;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.TextField;
+import org.apache.lucene.index.AtomicReaderContext;
+import org.apache.lucene.index.CorruptIndexException;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.IndexReaderContext;
+import org.apache.lucene.index.RandomIndexWriter;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanClause.Occur;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.ScoreDoc;
+import org.apache.lucene.search.Scorer;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.TopDocs;
+import org.apache.lucene.search.Weight;
+import org.apache.lucene.search.positions.PositionIntervalIterator.PositionInterval;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.util.LuceneTestCase;
+
+public class TestBrouwerianQuery extends LuceneTestCase {
+
+ private static final void addDocs(RandomIndexWriter writer) throws CorruptIndexException, IOException {
+ {
+ Document doc = new Document();
+ doc.add(newField(
+ "field",
+ "The quick brown fox jumps over the lazy dog",
+ TextField.TYPE_STORED));
+ writer.addDocument(doc);
+ }
+
+ {
+ Document doc = new Document();
+ doc.add(newField(
+ "field",
+ "The quick brown duck jumps over the lazy dog with the quick brown fox",
+ TextField.TYPE_STORED));
+ writer.addDocument(doc);
+ }
+ }
+
+ public void testBrouwerianBooleanQuery() throws IOException {
+ Directory directory = newDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
+ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())));
+ addDocs(writer);
+
+ IndexReader reader = writer.getReader();
+ IndexSearcher searcher = new IndexSearcher(reader);
+ writer.close();
+ BooleanQuery query = new BooleanQuery();
+ query.add(new BooleanClause(new TermQuery(new Term("field", "the")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "quick")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "jumps")), Occur.MUST));
+ BooleanQuery sub = new BooleanQuery();
+ sub.add(new BooleanClause(new TermQuery(new Term("field", "fox")), Occur.MUST));
+ BrouwerianQuery q = new BrouwerianQuery(query, sub);
+ TopDocs search = searcher.search(q, 10);
+ ScoreDoc[] scoreDocs = search.scoreDocs;
+ assertEquals(1, search.totalHits);
+ assertEquals(1, scoreDocs[0].doc);
+
+ reader.close();
+ directory.close();
+ }
+
+ public void testBrouwerianBooleanQueryExcludedDoesNotExist() throws IOException {
+ Directory directory = newDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
+ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())));
+ addDocs(writer);
+
+ IndexReader reader = writer.getReader();
+ IndexSearcher searcher = new IndexSearcher(reader);
+ writer.close();
+ BooleanQuery query = new BooleanQuery();
+ query.add(new BooleanClause(new TermQuery(new Term("field", "the")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "quick")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "jumps")), Occur.MUST));
+ BooleanQuery sub = new BooleanQuery();
+ sub.add(new BooleanClause(new TermQuery(new Term("field", "blox")), Occur.MUST));
+ BrouwerianQuery q = new BrouwerianQuery(query, sub);
+ TopDocs search = searcher.search(q, 10);
+ ScoreDoc[] scoreDocs = search.scoreDocs;
+ assertEquals(2, search.totalHits);
+ assertEquals(0, scoreDocs[0].doc);
+ assertEquals(1, scoreDocs[1].doc);
+
+
+ reader.close();
+ directory.close();
+ }
+
+ public void testPositions() throws IOException {
+ Directory directory = newDirectory();
+ RandomIndexWriter writer = new RandomIndexWriter(random(), directory,
+ newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random())));
+ addDocs(writer);
+
+ IndexReader reader = writer.getReader();
+ IndexSearcher searcher = new IndexSearcher(reader);
+ writer.close();
+ BooleanQuery query = new BooleanQuery();
+ query.add(new BooleanClause(new TermQuery(new Term("field", "the")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "quick")), Occur.MUST));
+ query.add(new BooleanClause(new TermQuery(new Term("field", "jumps")), Occur.MUST));
+ BooleanQuery sub = new BooleanQuery();
+ sub.add(new BooleanClause(new TermQuery(new Term("field", "fox")), Occur.MUST));
+ BrouwerianQuery q = new BrouwerianQuery(query, sub);
+ Weight weight = q.createWeight(searcher);
+ IndexReaderContext topReaderContext = searcher.getTopReaderContext();
+ List<AtomicReaderContext> leaves = topReaderContext.leaves();
+ assertEquals(1, leaves.size());
+ for (AtomicReaderContext atomicReaderContext : leaves) {
+ Scorer scorer = weight.scorer(atomicReaderContext, true, true, atomicReaderContext.reader().getLiveDocs());
+ int nextDoc = scorer.nextDoc();
+ assertEquals(1, nextDoc);
+ PositionIntervalIterator positions = scorer.positions(false, false, false);
+ assertEquals(1, positions.advanceTo(nextDoc));
+ PositionInterval interval = null;
+ int[] start = new int[] {0, 1, 4};
+ int[] end = new int[] {4, 6, 11};
+ for (int j = 0; j < end.length; j++) {
+ interval = positions.next();
+ assertNotNull("" + j, interval);
+ assertEquals(start[j], interval.begin);
+ assertEquals(end[j], interval.end);
+ }
+ assertNull(positions.next());
+ assertEquals(Scorer.NO_MORE_DOCS, scorer.nextDoc());
+ reader.close();
+ directory.close();
+ }
+
+ }
+}