You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@lucene.apache.org by rm...@apache.org on 2015/04/01 03:10:13 UTC
svn commit: r1670533 [2/4] - in /lucene/dev/branches/lucene6271: ./
dev-tools/ lucene/ lucene/analysis/ lucene/analysis/common/
lucene/backward-codecs/ lucene/benchmark/ lucene/classification/
lucene/codecs/ lucene/core/ lucene/core/src/java/org/apache...
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanNotQuery.java Wed Apr 1 01:10:11 2015
@@ -30,9 +30,11 @@ import java.util.ArrayList;
import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import java.util.Objects;
-/** Removes matches which overlap with another SpanQuery or
- * within a x tokens before or y tokens after another SpanQuery. */
+/** Removes matches which overlap with another SpanQuery or which are
+ * within x tokens before or y tokens after another SpanQuery.
+ */
public class SpanNotQuery extends SpanQuery implements Cloneable {
private SpanQuery include;
private SpanQuery exclude;
@@ -45,20 +47,20 @@ public class SpanNotQuery extends SpanQu
this(include, exclude, 0, 0);
}
-
+
/** Construct a SpanNotQuery matching spans from <code>include</code> which
- * have no overlap with spans from <code>exclude</code> within
+ * have no overlap with spans from <code>exclude</code> within
* <code>dist</code> tokens of <code>include</code>. */
public SpanNotQuery(SpanQuery include, SpanQuery exclude, int dist) {
this(include, exclude, dist, dist);
}
-
+
/** Construct a SpanNotQuery matching spans from <code>include</code> which
- * have no overlap with spans from <code>exclude</code> within
+ * have no overlap with spans from <code>exclude</code> within
* <code>pre</code> tokens before or <code>post</code> tokens of <code>include</code>. */
public SpanNotQuery(SpanQuery include, SpanQuery exclude, int pre, int post) {
- this.include = include;
- this.exclude = exclude;
+ this.include = Objects.requireNonNull(include);
+ this.exclude = Objects.requireNonNull(exclude);
this.pre = (pre >=0) ? pre : 0;
this.post = (post >= 0) ? post : 0;
@@ -96,81 +98,153 @@ public class SpanNotQuery extends SpanQu
@Override
public SpanNotQuery clone() {
- SpanNotQuery spanNotQuery = new SpanNotQuery((SpanQuery)include.clone(),
- (SpanQuery) exclude.clone(), pre, post);
+ SpanNotQuery spanNotQuery = new SpanNotQuery((SpanQuery) include.clone(),
+ (SpanQuery) exclude.clone(), pre, post);
spanNotQuery.setBoost(getBoost());
- return spanNotQuery;
+ return spanNotQuery;
}
@Override
public Spans getSpans(final LeafReaderContext context, final Bits acceptDocs, final Map<Term,TermContext> termContexts) throws IOException {
- return new Spans() {
- private Spans includeSpans = include.getSpans(context, acceptDocs, termContexts);
- private boolean moreInclude = true;
+ Spans includeSpans = include.getSpans(context, acceptDocs, termContexts);
+ if (includeSpans == null) {
+ return null;
+ }
- private Spans excludeSpans = exclude.getSpans(context, acceptDocs, termContexts);
- private boolean moreExclude = excludeSpans.next();
+ Spans excludeSpans = exclude.getSpans(context, acceptDocs, termContexts);
+ if (excludeSpans == null) {
+ return includeSpans;
+ }
- @Override
- public boolean next() throws IOException {
- if (moreInclude) // move to next include
- moreInclude = includeSpans.next();
-
- while (moreInclude && moreExclude) {
-
- if (includeSpans.doc() > excludeSpans.doc()) // skip exclude
- moreExclude = excludeSpans.skipTo(includeSpans.doc());
-
- while (moreExclude // while exclude is before
- && includeSpans.doc() == excludeSpans.doc()
- && excludeSpans.end() <= includeSpans.start() - pre) {
- moreExclude = excludeSpans.next(); // increment exclude
- }
+ return new Spans() {
+ private boolean moreInclude = true;
+ private int includeStart = -1;
+ private int includeEnd = -1;
+ private boolean atFirstInCurrentDoc = false;
+
+ private boolean moreExclude = excludeSpans.nextDoc() != NO_MORE_DOCS;
+ private int excludeStart = moreExclude ? excludeSpans.nextStartPosition() : NO_MORE_POSITIONS;
- if (!moreExclude // if no intersection
- || includeSpans.doc() != excludeSpans.doc()
- || includeSpans.end()+post <= excludeSpans.start())
- break; // we found a match
- moreInclude = includeSpans.next(); // intersected: keep scanning
+ @Override
+ public int nextDoc() throws IOException {
+ if (moreInclude) {
+ moreInclude = includeSpans.nextDoc() != NO_MORE_DOCS;
+ if (moreInclude) {
+ atFirstInCurrentDoc = true;
+ includeStart = includeSpans.nextStartPosition();
+ assert includeStart != NO_MORE_POSITIONS;
}
- return moreInclude;
}
+ toNextIncluded();
+ int res = moreInclude ? includeSpans.docID() : NO_MORE_DOCS;
+ return res;
+ }
- @Override
- public boolean skipTo(int target) throws IOException {
- if (moreInclude) // skip include
- moreInclude = includeSpans.skipTo(target);
+ private void toNextIncluded() throws IOException {
+ while (moreInclude && moreExclude) {
+ if (includeSpans.docID() > excludeSpans.docID()) {
+ moreExclude = excludeSpans.advance(includeSpans.docID()) != NO_MORE_DOCS;
+ if (moreExclude) {
+ excludeStart = -1; // only use exclude positions at same doc
+ }
+ }
+ if (excludeForwardInCurrentDocAndAtMatch()) {
+ break; // at match.
+ }
- if (!moreInclude)
- return false;
+ // else intersected: keep scanning, to next doc if needed
+ includeStart = includeSpans.nextStartPosition();
+ if (includeStart == NO_MORE_POSITIONS) {
+ moreInclude = includeSpans.nextDoc() != NO_MORE_DOCS;
+ if (moreInclude) {
+ atFirstInCurrentDoc = true;
+ includeStart = includeSpans.nextStartPosition();
+ assert includeStart != NO_MORE_POSITIONS;
+ }
+ }
+ }
+ }
- if (moreExclude // skip exclude
- && includeSpans.doc() > excludeSpans.doc())
- moreExclude = excludeSpans.skipTo(includeSpans.doc());
+ private boolean excludeForwardInCurrentDocAndAtMatch() throws IOException {
+ assert moreInclude;
+ assert includeStart != NO_MORE_POSITIONS;
+ if (! moreExclude) {
+ return true;
+ }
+ if (includeSpans.docID() != excludeSpans.docID()) {
+ return true;
+ }
+ // at same doc
+ if (excludeStart == -1) { // init exclude start position if needed
+ excludeStart = excludeSpans.nextStartPosition();
+ assert excludeStart != NO_MORE_POSITIONS;
+ }
+ while (excludeSpans.endPosition() <= includeStart - pre) {
+ // exclude end position is before a possible exclusion
+ excludeStart = excludeSpans.nextStartPosition();
+ if (excludeStart == NO_MORE_POSITIONS) {
+ return true; // no more exclude at current doc.
+ }
+ }
+ // exclude end position far enough in current doc, check start position:
+ boolean res = includeSpans.endPosition() + post <= excludeStart;
+ return res;
+ }
- while (moreExclude // while exclude is before
- && includeSpans.doc() == excludeSpans.doc()
- && excludeSpans.end() <= includeSpans.start()-pre) {
- moreExclude = excludeSpans.next(); // increment exclude
+ @Override
+ public int advance(int target) throws IOException {
+ if (moreInclude) {
+ assert target > includeSpans.docID() : "target="+target+", includeSpans.docID()="+includeSpans.docID();
+ moreInclude = includeSpans.advance(target) != NO_MORE_DOCS;
+ if (moreInclude) {
+ atFirstInCurrentDoc = true;
+ includeStart = includeSpans.nextStartPosition();
+ assert includeStart != NO_MORE_POSITIONS;
}
+ }
+ toNextIncluded();
+ int res = moreInclude ? includeSpans.docID() : NO_MORE_DOCS;
+ return res;
+ }
- if (!moreExclude // if no intersection
- || includeSpans.doc() != excludeSpans.doc()
- || includeSpans.end()+post <= excludeSpans.start())
- return true; // we found a match
+ @Override
+ public int docID() {
+ int res = includeSpans.docID();
+ return res;
+ }
+
+ @Override
+ public int nextStartPosition() throws IOException {
+ assert moreInclude;
- return next(); // scan to next match
+ if (atFirstInCurrentDoc) {
+ atFirstInCurrentDoc = false;
+ assert includeStart != NO_MORE_POSITIONS;
+ return includeStart;
}
- @Override
- public int doc() { return includeSpans.doc(); }
- @Override
- public int start() { return includeSpans.start(); }
- @Override
- public int end() { return includeSpans.end(); }
+ includeStart = includeSpans.nextStartPosition();
+ while ((includeStart != NO_MORE_POSITIONS)
+ && (! excludeForwardInCurrentDocAndAtMatch()))
+ {
+ includeStart = includeSpans.nextStartPosition();
+ }
+
+ return includeStart;
+ }
+
+ @Override
+ public int startPosition() {
+ assert includeStart == includeSpans.startPosition();
+ return atFirstInCurrentDoc ? -1 : includeStart;
+ }
+
+ @Override
+ public int endPosition() {
+ return atFirstInCurrentDoc ? -1 : includeSpans.endPosition();
+ }
- // TODO: Remove warning after API has been finalized
@Override
public Collection<byte[]> getPayload() throws IOException {
ArrayList<byte[]> result = null;
@@ -180,7 +254,6 @@ public class SpanNotQuery extends SpanQu
return result;
}
- // TODO: Remove warning after API has been finalized
@Override
public boolean isPayloadAvailable() throws IOException {
return includeSpans.isPayloadAvailable();
@@ -193,10 +266,9 @@ public class SpanNotQuery extends SpanQu
@Override
public String toString() {
- return "spans(" + SpanNotQuery.this.toString() + ")";
- }
-
- };
+ return "spans(" + SpanNotQuery.this.toString() + ")";
+ }
+ };
}
@Override
@@ -230,7 +302,7 @@ public class SpanNotQuery extends SpanQu
SpanNotQuery other = (SpanNotQuery)o;
return this.include.equals(other.include)
&& this.exclude.equals(other.exclude)
- && this.pre == other.pre
+ && this.pre == other.pre
&& this.post == other.post;
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanOrQuery.java Wed Apr 1 01:10:11 2015
@@ -35,18 +35,19 @@ import org.apache.lucene.util.PriorityQu
import org.apache.lucene.util.ToStringUtils;
import org.apache.lucene.search.Query;
-/** Matches the union of its clauses.*/
+/** Matches the union of its clauses.
+ */
public class SpanOrQuery extends SpanQuery implements Cloneable {
private List<SpanQuery> clauses;
private String field;
- /** Construct a SpanOrQuery merging the provided clauses. */
+ /** Construct a SpanOrQuery merging the provided clauses.
+ * All clauses must have the same field.
+ */
public SpanOrQuery(SpanQuery... clauses) {
-
- // copy clauses array into an ArrayList
this.clauses = new ArrayList<>(clauses.length);
- for (int i = 0; i < clauses.length; i++) {
- addClause(clauses[i]);
+ for (SpanQuery seq : clauses) {
+ addClause(seq);
}
}
@@ -59,7 +60,7 @@ public class SpanOrQuery extends SpanQue
}
this.clauses.add(clause);
}
-
+
/** Return the clauses whose spans are matched. */
public SpanQuery[] getClauses() {
return clauses.toArray(new SpanQuery[clauses.size()]);
@@ -74,7 +75,7 @@ public class SpanOrQuery extends SpanQue
clause.extractTerms(terms);
}
}
-
+
@Override
public SpanOrQuery clone() {
int sz = clauses.size();
@@ -152,90 +153,120 @@ public class SpanOrQuery extends SpanQue
@Override
protected final boolean lessThan(Spans spans1, Spans spans2) {
- if (spans1.doc() == spans2.doc()) {
- if (spans1.start() == spans2.start()) {
- return spans1.end() < spans2.end();
+ if (spans1.docID() == spans2.docID()) {
+ if (spans1.startPosition() == spans2.startPosition()) {
+ return spans1.endPosition() < spans2.endPosition();
} else {
- return spans1.start() < spans2.start();
+ return spans1.startPosition() < spans2.startPosition();
}
} else {
- return spans1.doc() < spans2.doc();
+ return spans1.docID() < spans2.docID();
}
}
}
@Override
- public Spans getSpans(final LeafReaderContext context, final Bits acceptDocs, final Map<Term,TermContext> termContexts) throws IOException {
- if (clauses.size() == 1) // optimize 1-clause case
- return (clauses.get(0)).getSpans(context, acceptDocs, termContexts);
+ public Spans getSpans(final LeafReaderContext context, final Bits acceptDocs, final Map<Term,TermContext> termContexts)
+ throws IOException {
+
+ ArrayList<Spans> subSpans = new ArrayList<>(clauses.size());
+
+ for (SpanQuery seq : clauses) {
+ Spans subSpan = seq.getSpans(context, acceptDocs, termContexts);
+ if (subSpan != null) {
+ subSpans.add(subSpan);
+ }
+ }
+
+ if (subSpans.size() == 0) {
+ return null;
+ } else if (subSpans.size() == 1) {
+ return subSpans.get(0);
+ }
+
+ SpanQueue queue = new SpanQueue(clauses.size());
+ for (Spans spans : subSpans) {
+ queue.add(spans);
+ }
return new Spans() {
- private SpanQueue queue = null;
- private long cost;
- private boolean initSpanQueue(int target) throws IOException {
- queue = new SpanQueue(clauses.size());
- Iterator<SpanQuery> i = clauses.iterator();
- while (i.hasNext()) {
- Spans spans = i.next().getSpans(context, acceptDocs, termContexts);
- cost += spans.cost();
- if ( ((target == -1) && spans.next())
- || ((target != -1) && spans.skipTo(target))) {
- queue.add(spans);
- }
- }
- return queue.size() != 0;
+ @Override
+ public int nextDoc() throws IOException {
+ if (queue.size() == 0) { // all done
+ return NO_MORE_DOCS;
}
- @Override
- public boolean next() throws IOException {
- if (queue == null) {
- return initSpanQueue(-1);
- }
+ int currentDoc = top().docID();
- if (queue.size() == 0) { // all done
- return false;
- }
+ if (currentDoc == -1) { // initially
+ return advance(0);
+ }
- if (top().next()) { // move to next
+ do {
+ if (top().nextDoc() != NO_MORE_DOCS) { // move top to next doc
queue.updateTop();
- return true;
+ } else {
+ queue.pop(); // exhausted a clause
+ if (queue.size() == 0) {
+ return NO_MORE_DOCS;
+ }
}
+ // assert queue.size() > 0;
+ int doc = top().docID();
+ if (doc > currentDoc) {
+ return doc;
+ }
+ } while (true);
+ }
- queue.pop(); // exhausted a clause
- return queue.size() != 0;
- }
+ private Spans top() {
+ return queue.top();
+ }
- private Spans top() { return queue.top(); }
+ @Override
+ public int advance(int target) throws IOException {
- @Override
- public boolean skipTo(int target) throws IOException {
- if (queue == null) {
- return initSpanQueue(target);
- }
-
- boolean skipCalled = false;
- while (queue.size() != 0 && top().doc() < target) {
- if (top().skipTo(target)) {
- queue.updateTop();
- } else {
- queue.pop();
- }
- skipCalled = true;
- }
-
- if (skipCalled) {
- return queue.size() != 0;
+ while ((queue.size() > 0) && (top().docID() < target)) {
+ if (top().advance(target) != NO_MORE_DOCS) {
+ queue.updateTop();
+ } else {
+ queue.pop();
}
- return next();
}
- @Override
- public int doc() { return top().doc(); }
- @Override
- public int start() { return top().start(); }
- @Override
- public int end() { return top().end(); }
+ return (queue.size() > 0) ? top().docID() : NO_MORE_DOCS;
+ }
+
+ @Override
+ public int docID() {
+ return (queue == null) ? -1
+ : (queue.size() > 0) ? top().docID()
+ : NO_MORE_DOCS;
+ }
+
+ @Override
+ public int nextStartPosition() throws IOException {
+ top().nextStartPosition();
+ queue.updateTop();
+ int startPos = top().startPosition();
+ while (startPos == -1) { // initially at this doc
+ top().nextStartPosition();
+ queue.updateTop();
+ startPos = top().startPosition();
+ }
+ return startPos;
+ }
+
+ @Override
+ public int startPosition() {
+ return top().startPosition();
+ }
+
+ @Override
+ public int endPosition() {
+ return top().endPosition();
+ }
@Override
public Collection<byte[]> getPayload() throws IOException {
@@ -257,15 +288,23 @@ public class SpanOrQuery extends SpanQue
public String toString() {
return "spans("+SpanOrQuery.this+")@"+
((queue == null)?"START"
- :(queue.size()>0?(doc()+":"+start()+"-"+end()):"END"));
- }
+ :(queue.size()>0?(docID()+": "+top().startPosition()+" - "+top().endPosition()):"END"));
+ }
+
+ private long cost = -1;
@Override
public long cost() {
+ if (cost == -1) {
+ cost = 0;
+ for (Spans spans : subSpans) {
+ cost += spans.cost();
+ }
+ }
return cost;
}
-
- };
+
+ };
}
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPayloadCheckQuery.java Wed Apr 1 01:10:11 2015
@@ -28,15 +28,14 @@ import java.util.Iterator;
* Only return those matches that have a specific payload at
* the given position.
* <p>
- * Do not use this with an SpanQuery that contains a {@link org.apache.lucene.search.spans.SpanNearQuery}. Instead, use
- * {@link SpanNearPayloadCheckQuery} since it properly handles the fact that payloads
+ * Do not use this with a SpanQuery that contains a {@link org.apache.lucene.search.spans.SpanNearQuery}.
+ * Instead, use {@link SpanNearPayloadCheckQuery} since it properly handles the fact that payloads
* aren't ordered by {@link org.apache.lucene.search.spans.SpanNearQuery}.
*/
-public class SpanPayloadCheckQuery extends SpanPositionCheckQuery{
+public class SpanPayloadCheckQuery extends SpanPositionCheckQuery {
protected final Collection<byte[]> payloadToMatch;
/**
- *
* @param match The underlying {@link org.apache.lucene.search.spans.SpanQuery} to check
* @param payloadToMatch The {@link java.util.Collection} of payloads to match
*/
@@ -71,7 +70,7 @@ public class SpanPayloadCheckQuery exten
}
}
return AcceptStatus.YES;
- }
+ }
@Override
public String toString(String field) {
@@ -108,7 +107,7 @@ public class SpanPayloadCheckQuery exten
@Override
public int hashCode() {
- int h = match.hashCode();
+ int h = match.hashCode() ^ getClass().hashCode();
h ^= (h << 8) | (h >>> 25); // reversible
//TODO: is this right?
h ^= payloadToMatch.hashCode();
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionCheckQuery.java Wed Apr 1 01:10:11 2015
@@ -25,10 +25,9 @@ import org.apache.lucene.search.Query;
import org.apache.lucene.util.Bits;
import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import java.util.Objects;
/**
@@ -37,9 +36,8 @@ import java.util.Set;
public abstract class SpanPositionCheckQuery extends SpanQuery implements Cloneable {
protected SpanQuery match;
-
public SpanPositionCheckQuery(SpanQuery match) {
- this.match = match;
+ this.match = Objects.requireNonNull(match);
}
/**
@@ -60,42 +58,44 @@ public abstract class SpanPositionCheckQ
match.extractTerms(terms);
}
- /**
+ /**
* Return value for {@link SpanPositionCheckQuery#acceptPosition(Spans)}.
*/
protected static enum AcceptStatus {
/** Indicates the match should be accepted */
YES,
-
+
/** Indicates the match should be rejected */
NO,
-
- /**
- * Indicates the match should be rejected, and the enumeration should advance
- * to the next document.
+
+ /**
+ * Indicates the match should be rejected, and the enumeration may continue
+ * with the next document.
*/
- NO_AND_ADVANCE
+ NO_MORE_IN_CURRENT_DOC
};
-
+
/**
* Implementing classes are required to return whether the current position is a match for the passed in
- * "match" {@link org.apache.lucene.search.spans.SpanQuery}.
+ * "match" {@link SpanQuery}.
+ *
+ * This is only called if the underlying last {@link Spans#nextStartPosition()} for the
+ * match indicated a valid start position.
*
- * This is only called if the underlying {@link org.apache.lucene.search.spans.Spans#next()} for the
- * match is successful
*
+ * @param spans The {@link Spans} instance, positioned at the spot to check
*
- * @param spans The {@link org.apache.lucene.search.spans.Spans} instance, positioned at the spot to check
* @return whether the match is accepted, rejected, or rejected and should move to the next doc.
*
- * @see org.apache.lucene.search.spans.Spans#next()
+ * @see Spans#nextDoc()
*
*/
protected abstract AcceptStatus acceptPosition(Spans spans) throws IOException;
@Override
public Spans getSpans(final LeafReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException {
- return new PositionCheckSpan(context, acceptDocs, termContexts);
+ Spans matchSpans = match.getSpans(context, acceptDocs, termContexts);
+ return (matchSpans == null) ? null : new PositionCheckSpans(matchSpans);
}
@@ -116,79 +116,110 @@ public abstract class SpanPositionCheckQ
}
}
- protected class PositionCheckSpan extends Spans {
- private Spans spans;
+ protected class PositionCheckSpans extends FilterSpans {
+
+ private boolean atFirstInCurrentDoc = false;
+ private int startPos = -1;
- public PositionCheckSpan(LeafReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException {
- spans = match.getSpans(context, acceptDocs, termContexts);
+ public PositionCheckSpans(Spans matchSpans) throws IOException {
+ super(matchSpans);
}
@Override
- public boolean next() throws IOException {
- if (!spans.next())
- return false;
-
- return doNext();
+ public int nextDoc() throws IOException {
+ if (in.nextDoc() == NO_MORE_DOCS)
+ return NO_MORE_DOCS;
+
+ return toNextDocWithAllowedPosition();
}
@Override
- public boolean skipTo(int target) throws IOException {
- if (!spans.skipTo(target))
- return false;
+ public int advance(int target) throws IOException {
+ if (in.advance(target) == NO_MORE_DOCS)
+ return NO_MORE_DOCS;
- return doNext();
+ return toNextDocWithAllowedPosition();
}
-
- protected boolean doNext() throws IOException {
+
+ @SuppressWarnings("fallthrough")
+ protected int toNextDocWithAllowedPosition() throws IOException {
+ startPos = in.nextStartPosition();
+ assert startPos != NO_MORE_POSITIONS;
for (;;) {
switch(acceptPosition(this)) {
- case YES: return true;
- case NO:
- if (!spans.next())
- return false;
- break;
- case NO_AND_ADVANCE:
- if (!spans.skipTo(spans.doc()+1))
- return false;
+ case YES:
+ atFirstInCurrentDoc = true;
+ return in.docID();
+ case NO:
+ startPos = in.nextStartPosition();
+ if (startPos != NO_MORE_POSITIONS) {
+ break;
+ }
+ // else fallthrough
+ case NO_MORE_IN_CURRENT_DOC:
+ if (in.nextDoc() == NO_MORE_DOCS) {
+ startPos = -1;
+ return NO_MORE_DOCS;
+ }
+ startPos = in.nextStartPosition();
+ assert startPos != NO_MORE_POSITIONS : "no start position at doc="+in.docID();
break;
}
}
}
@Override
- public int doc() { return spans.doc(); }
-
- @Override
- public int start() { return spans.start(); }
-
- @Override
- public int end() { return spans.end(); }
- // TODO: Remove warning after API has been finalized
+ public int nextStartPosition() throws IOException {
+ if (atFirstInCurrentDoc) {
+ atFirstInCurrentDoc = false;
+ return startPos;
+ }
- @Override
- public Collection<byte[]> getPayload() throws IOException {
- ArrayList<byte[]> result = null;
- if (spans.isPayloadAvailable()) {
- result = new ArrayList<>(spans.getPayload());
+ for (;;) {
+ startPos = in.nextStartPosition();
+ if (startPos == NO_MORE_POSITIONS) {
+ return NO_MORE_POSITIONS;
+ }
+ switch(acceptPosition(this)) {
+ case YES:
+ return startPos;
+ case NO:
+ break;
+ case NO_MORE_IN_CURRENT_DOC:
+ return startPos = NO_MORE_POSITIONS; // startPos ahead for the current doc.
+ }
}
- return result;//TODO: any way to avoid the new construction?
}
- // TODO: Remove warning after API has been finalized
@Override
- public boolean isPayloadAvailable() throws IOException {
- return spans.isPayloadAvailable();
+ public int startPosition() {
+ return atFirstInCurrentDoc ? -1 : startPos;
}
@Override
- public long cost() {
- return spans.cost();
+ public int endPosition() {
+ return atFirstInCurrentDoc ? -1
+ : (startPos != NO_MORE_POSITIONS) ? in.endPosition() : NO_MORE_POSITIONS;
}
@Override
public String toString() {
- return "spans(" + SpanPositionCheckQuery.this.toString() + ")";
- }
+ return "spans(" + SpanPositionCheckQuery.this.toString() + ")";
+ }
+ }
+ /** Returns true iff <code>o</code> is equal to this. */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) return true;
+ if (o == null) return false;
+ if (getClass() != o.getClass()) return false;
+ final SpanPositionCheckQuery spcq = (SpanPositionCheckQuery) o;
+ return match.equals(spcq.match);
+ }
+
+ @Override
+ public int hashCode() {
+ return match.hashCode() ^ getClass().hashCode();
}
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanPositionRangeQuery.java Wed Apr 1 01:10:11 2015
@@ -25,10 +25,10 @@ import java.io.IOException;
/**
* Checks to see if the {@link #getMatch()} lies between a start and end position
*
- * @see org.apache.lucene.search.spans.SpanFirstQuery for a derivation that is optimized for the case where start position is 0
+ * See {@link SpanFirstQuery} for a derivation that is optimized for the case where start position is 0.
*/
public class SpanPositionRangeQuery extends SpanPositionCheckQuery {
- protected int start = 0;
+ protected int start;
protected int end;
public SpanPositionRangeQuery(SpanQuery match, int start, int end) {
@@ -40,13 +40,12 @@ public class SpanPositionRangeQuery exte
@Override
protected AcceptStatus acceptPosition(Spans spans) throws IOException {
- assert spans.start() != spans.end();
- if (spans.start() >= end)
- return AcceptStatus.NO_AND_ADVANCE;
- else if (spans.start() >= start && spans.end() <= end)
- return AcceptStatus.YES;
- else
- return AcceptStatus.NO;
+ assert spans.startPosition() != spans.endPosition();
+ AcceptStatus res = (spans.startPosition() >= end)
+ ? AcceptStatus.NO_MORE_IN_CURRENT_DOC
+ : (spans.startPosition() >= start && spans.endPosition() <= end)
+ ? AcceptStatus.YES : AcceptStatus.NO;
+ return res;
}
@@ -96,7 +95,7 @@ public class SpanPositionRangeQuery exte
@Override
public int hashCode() {
- int h = match.hashCode();
+ int h = match.hashCode() ^ getClass().hashCode();
h ^= (h << 8) | (h >>> 25); // reversible
h ^= Float.floatToRawIntBits(getBoost()) ^ end ^ start;
return h;
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanQuery.java Wed Apr 1 01:10:11 2015
@@ -25,16 +25,17 @@ import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Weight;
import org.apache.lucene.util.Bits;
/** Base class for span-based queries. */
public abstract class SpanQuery extends Query {
- /** Expert: Returns the matches for this query in an index. Used internally
- * to search for spans. */
+ /** Expert: Returns the matches for this query in an index.
+ * Used internally to search for spans.
+ * This may return null to indicate that the SpanQuery has no results.
+ */
public abstract Spans getSpans(LeafReaderContext context, Bits acceptDocs, Map<Term,TermContext> termContexts) throws IOException;
- /**
+ /**
* Returns the name of the field matched by this query.
* <p>
* Note that this may return null if the query matches no terms.
@@ -42,7 +43,7 @@ public abstract class SpanQuery extends
public abstract String getField();
@Override
- public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
+ public SpanWeight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
return new SpanWeight(this, searcher);
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanScorer.java Wed Apr 1 01:10:11 2015
@@ -18,9 +18,9 @@ package org.apache.lucene.search.spans;
*/
import java.io.IOException;
+import java.util.Objects;
import org.apache.lucene.search.Scorer;
-import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.Similarity;
/**
@@ -29,58 +29,68 @@ import org.apache.lucene.search.similari
public class SpanScorer extends Scorer {
protected Spans spans;
- protected boolean more = true;
-
protected int doc;
protected float freq;
protected int numMatches;
protected final Similarity.SimScorer docScorer;
-
- protected SpanScorer(Spans spans, Weight weight, Similarity.SimScorer docScorer)
+
+ protected SpanScorer(Spans spans, SpanWeight weight, Similarity.SimScorer docScorer)
throws IOException {
super(weight);
- this.docScorer = docScorer;
- this.spans = spans;
-
- doc = -1;
- more = spans.next();
+ this.docScorer = Objects.requireNonNull(docScorer);
+ this.spans = Objects.requireNonNull(spans);
+ this.doc = -1;
}
@Override
public int nextDoc() throws IOException {
- if (!setFreqCurrentDoc()) {
- doc = NO_MORE_DOCS;
+ int prevDoc = doc;
+ doc = spans.nextDoc();
+ if (doc != NO_MORE_DOCS) {
+ setFreqCurrentDoc();
}
return doc;
}
@Override
public int advance(int target) throws IOException {
- if (!more) {
- return doc = NO_MORE_DOCS;
- }
- if (spans.doc() < target) { // setFreqCurrentDoc() leaves spans.doc() ahead
- more = spans.skipTo(target);
- }
- if (!setFreqCurrentDoc()) {
- doc = NO_MORE_DOCS;
+ int prevDoc = doc;
+ doc = spans.advance(target);
+ if (doc != NO_MORE_DOCS) {
+ setFreqCurrentDoc();
}
return doc;
}
-
+
protected boolean setFreqCurrentDoc() throws IOException {
- if (!more) {
- return false;
- }
- doc = spans.doc();
freq = 0.0f;
numMatches = 0;
+
+ assert spans.startPosition() == -1 : "incorrect initial start position, spans="+spans;
+ assert spans.endPosition() == -1 : "incorrect initial end position, spans="+spans;
+ int prevStartPos = -1;
+ int prevEndPos = -1;
+
+ int startPos = spans.nextStartPosition();
+ assert startPos != Spans.NO_MORE_POSITIONS : "initial startPos NO_MORE_POSITIONS, spans="+spans;
do {
- int matchLength = spans.end() - spans.start();
- freq += docScorer.computeSlopFactor(matchLength);
+ assert startPos >= prevStartPos;
+ int endPos = spans.endPosition();
+ assert endPos != Spans.NO_MORE_POSITIONS;
+ // This assertion can fail for Or spans on the same term:
+ // assert (startPos != prevStartPos) || (endPos > prevEndPos) : "non increased endPos="+endPos;
+ assert (startPos != prevStartPos) || (endPos >= prevEndPos) : "decreased endPos="+endPos;
numMatches++;
- more = spans.next();
- } while (more && (doc == spans.doc()));
+ int matchLength = endPos - startPos;
+ freq += docScorer.computeSlopFactor(matchLength);
+ prevStartPos = startPos;
+ prevEndPos = endPos;
+ startPos = spans.nextStartPosition();
+ } while (startPos != Spans.NO_MORE_POSITIONS);
+
+ assert spans.startPosition() == Spans.NO_MORE_POSITIONS : "incorrect final start position, spans="+spans;
+ assert spans.endPosition() == Spans.NO_MORE_POSITIONS : "incorrect final end position, spans="+spans;
+
return true;
}
@@ -89,15 +99,16 @@ public class SpanScorer extends Scorer {
@Override
public float score() throws IOException {
- return docScorer.score(doc, freq);
+ float s = docScorer.score(doc, freq);
+ return s;
}
-
+
@Override
public int freq() throws IOException {
return numMatches;
}
- /** Returns the intermediate "sloppy freq" adjusted for edit distance
+ /** Returns the intermediate "sloppy freq" adjusted for edit distance
* @lucene.internal */
// only public so .payloads can see it.
public float sloppyFreq() throws IOException {
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanTermQuery.java Wed Apr 1 01:10:11 2015
@@ -20,6 +20,7 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import java.util.Map;
import java.util.Set;
+import java.util.Objects;
import org.apache.lucene.index.PostingsEnum;
import org.apache.lucene.index.LeafReaderContext;
@@ -31,19 +32,23 @@ import org.apache.lucene.index.TermsEnum
import org.apache.lucene.util.Bits;
import org.apache.lucene.util.ToStringUtils;
-/** Matches spans containing a term. */
+/** Matches spans containing a term.
+ * This should not be used for terms that are indexed at position Integer.MAX_VALUE.
+ */
public class SpanTermQuery extends SpanQuery {
protected Term term;
/** Construct a SpanTermQuery matching the named term's spans. */
- public SpanTermQuery(Term term) { this.term = term; }
+ public SpanTermQuery(Term term) {
+ this.term = Objects.requireNonNull(term);
+ }
/** Return the term whose spans are matched. */
public Term getTerm() { return term; }
@Override
public String getField() { return term.field(); }
-
+
@Override
public void extractTerms(Set<Term> terms) {
terms.add(term);
@@ -64,7 +69,7 @@ public class SpanTermQuery extends SpanQ
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
- result = prime * result + ((term == null) ? 0 : term.hashCode());
+ result = prime * result + term.hashCode();
return result;
}
@@ -77,12 +82,7 @@ public class SpanTermQuery extends SpanQ
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;
- return true;
+ return term.equals(other.term);
}
@Override
@@ -99,7 +99,7 @@ public class SpanTermQuery extends SpanQ
}
final TermsEnum termsEnum = terms.iterator(null);
- if (termsEnum.seekExact(term.bytes())) {
+ if (termsEnum.seekExact(term.bytes())) {
state = termsEnum.termState();
} else {
state = null;
@@ -110,14 +110,14 @@ public class SpanTermQuery extends SpanQ
} else {
state = termContext.get(context.ord);
}
-
+
if (state == null) { // term is not present in that reader
- return TermSpans.EMPTY_TERM_SPANS;
+ return null;
}
-
+
final TermsEnum termsEnum = context.reader().terms(term.field()).iterator(null);
termsEnum.seekExact(term.bytes(), state);
-
+
final PostingsEnum postings = termsEnum.postings(acceptDocs, null, PostingsEnum.PAYLOADS);
return new TermSpans(postings, term);
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/SpanWeight.java Wed Apr 1 01:10:11 2015
@@ -51,7 +51,7 @@ public class SpanWeight extends Weight {
super(query);
this.similarity = searcher.getSimilarity();
this.query = query;
-
+
termContexts = new HashMap<>();
TreeSet<Term> terms = new TreeSet<>();
query.extractTerms(terms);
@@ -66,8 +66,8 @@ public class SpanWeight extends Weight {
}
final String field = query.getField();
if (field != null) {
- stats = similarity.computeWeight(query.getBoost(),
- searcher.collectionStatistics(query.getField()),
+ stats = similarity.computeWeight(query.getBoost(),
+ searcher.collectionStatistics(query.getField()),
termStats);
}
}
@@ -88,9 +88,9 @@ public class SpanWeight extends Weight {
public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
if (stats == null) {
return null;
- } else {
- return new SpanScorer(query.getSpans(context, acceptDocs, termContexts), this, similarity.simScorer(stats, context));
}
+ Spans spans = query.getSpans(context, acceptDocs, termContexts);
+ return (spans == null) ? null : new SpanScorer(spans, this, similarity.simScorer(stats, context));
}
@Override
@@ -106,11 +106,11 @@ public class SpanWeight extends Weight {
Explanation scoreExplanation = docScorer.explain(doc, new Explanation(freq, "phraseFreq=" + freq));
result.addDetail(scoreExplanation);
result.setValue(scoreExplanation.getValue());
- result.setMatch(true);
+ result.setMatch(true);
return result;
}
}
-
+
return new ComplexExplanation(false, 0.0f, "no matching term");
}
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/Spans.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/Spans.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/Spans.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/Spans.java Wed Apr 1 01:10:11 2015
@@ -20,54 +20,44 @@ package org.apache.lucene.search.spans;
import java.io.IOException;
import java.util.Collection;
-/** Expert: an enumeration of span matches. Used to implement span searching.
- * Each span represents a range of term positions within a document. Matches
- * are enumerated in order, by increasing document number, within that by
- * increasing start position and finally by increasing end position. */
-public abstract class Spans {
- /** Move to the next match, returning true iff any such exists. */
- public abstract boolean next() throws IOException;
-
- /** Skips to the first match beyond the current, whose document number is
- * greater than or equal to <i>target</i>.
- * <p>The behavior of this method is <b>undefined</b> when called with
- * <code> target ≤ current</code>, or after the iterator has exhausted.
- * Both cases may result in unpredicted behavior.
- * <p>Returns true iff there is such
- * a match. <p>Behaves as if written:
- * <pre class="prettyprint">
- * boolean skipTo(int target) {
- * do {
- * if (!next())
- * return false;
- * } while (target > doc());
- * return true;
- * }
- * </pre>
- * Most implementations are considerably more efficient than that.
- */
- public abstract boolean skipTo(int target) throws IOException;
-
- /** Returns the document number of the current match. Initially invalid. */
- public abstract int doc();
-
- /** Returns the start position of the current match. Initially invalid. */
- public abstract int start();
-
- /** Returns the end position of the current match. Initially invalid. */
- public abstract int end();
-
- /**
- * Returns the payload data for the current span.
- * This is invalid until {@link #next()} is called for
- * the first time.
+import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.TwoPhaseIterator;
+
+/** Iterates through combinations of start/end positions per-doc.
+ * Each start/end position represents a range of term positions within the current document.
+ * These are enumerated in order, by increasing document number, within that by
+ * increasing start position and finally by increasing end position.
+ */
+public abstract class Spans extends DocIdSetIterator {
+ public static final int NO_MORE_POSITIONS = Integer.MAX_VALUE;
+
+ /**
+ * Returns the next start position for the current doc.
+ * There is always at least one start/end position per doc.
+ * After the last start/end position at the current doc this returns {@link #NO_MORE_POSITIONS}.
+ */
+ public abstract int nextStartPosition() throws IOException;
+
+ /**
+ * Returns the start position in the current doc, or -1 when {@link #nextStartPosition} was not yet called on the current doc.
+ * After the last start/end position at the current doc this returns {@link #NO_MORE_POSITIONS}.
+ */
+ public abstract int startPosition();
+
+ /**
+ * Returns the end position for the current start position, or -1 when {@link #nextStartPosition} was not yet called on the current doc.
+ * After the last start/end position at the current doc this returns {@link #NO_MORE_POSITIONS}.
+ */
+ public abstract int endPosition();
+
+ /**
+ * Returns the payload data for the current start/end position.
+ * This is only valid after {@link #nextStartPosition()}
+ * returned an available start position.
* This method must not be called more than once after each call
- * of {@link #next()}. However, most payloads are loaded lazily,
+ * of {@link #nextStartPosition()}. However, most payloads are loaded lazily,
* so if the payload data for the current position is not needed,
- * this method may not be called at all for performance reasons. An ordered
- * SpanQuery does not lazy load, so if you have payloads in your index and
- * you do not want ordered SpanNearQuerys to collect payloads, you can
- * disable collection with a constructor option.<br>
+ * this method may not be called at all for performance reasons.
* <br>
* Note that the return type is a collection, thus the ordering should not be relied upon.
* <br>
@@ -76,25 +66,35 @@ public abstract class Spans {
* @return a List of byte arrays containing the data of this payload, otherwise null if isPayloadAvailable is false
* @throws IOException if there is a low-level I/O error
*/
- // TODO: Remove warning after API has been finalized
public abstract Collection<byte[]> getPayload() throws IOException;
/**
- * Checks if a payload can be loaded at this position.
+ * Checks if a payload can be loaded at the current start/end position.
* <p>
* Payloads can only be loaded once per call to
- * {@link #next()}.
+ * {@link #nextStartPosition()}.
*
- * @return true if there is a payload available at this position that can be loaded
+ * @return true if there is a payload available at this start/end position
+ * that can be loaded
*/
public abstract boolean isPayloadAvailable() throws IOException;
-
+
/**
- * Returns the estimated cost of this spans.
- * <p>
- * This is generally an upper bound of the number of documents this iterator
- * might match, but may be a rough heuristic, hardcoded value, or otherwise
- * completely inaccurate.
+ * Optional method: Return a {@link TwoPhaseIterator} view of this
+ * {@link Spans}. A return value of {@code null} indicates that
+ * two-phase iteration is not supported.
+ *
+ * Note that the returned {@link TwoPhaseIterator}'s
+ * {@link TwoPhaseIterator#approximation() approximation} must
+ * advance synchronously with this iterator: advancing the approximation must
+ * advance this iterator and vice-versa.
+ *
+ * Implementing this method is typically useful on {@link Spans}s
+ * that have a high per-document overhead in order to confirm matches.
+ *
+ * The default implementation returns {@code null}.
*/
- public abstract long cost();
+ public TwoPhaseIterator asTwoPhaseIterator() {
+ return null;
+ }
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/TermSpans.java Wed Apr 1 01:10:11 2015
@@ -24,10 +24,12 @@ import org.apache.lucene.util.BytesRef;
import java.io.IOException;
import java.util.Collections;
import java.util.Collection;
+import java.util.Objects;
/**
* Expert:
- * Public for extension only
+ * Public for extension only.
+ * This does not work correctly for terms that indexed at position Integer.MAX_VALUE.
*/
public class TermSpans extends Spans {
protected final PostingsEnum postings;
@@ -39,65 +41,67 @@ public class TermSpans extends Spans {
protected boolean readPayload;
public TermSpans(PostingsEnum postings, Term term) {
- this.postings = postings;
- this.term = term;
- doc = -1;
- }
-
- // only for EmptyTermSpans (below)
- TermSpans() {
- term = null;
- postings = null;
+ this.postings = Objects.requireNonNull(postings);
+ this.term = Objects.requireNonNull(term);
+ this.doc = -1;
+ this.position = -1;
}
@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;
- }
+ public int nextDoc() throws IOException {
+ doc = postings.nextDoc();
+ if (doc != DocIdSetIterator.NO_MORE_DOCS) {
freq = postings.freq();
+ assert freq >= 1;
count = 0;
}
- position = postings.nextPosition();
- count++;
- readPayload = false;
- return true;
+ position = -1;
+ return doc;
}
@Override
- public boolean skipTo(int target) throws IOException {
+ public int advance(int target) throws IOException {
assert target > doc;
doc = postings.advance(target);
- if (doc == DocIdSetIterator.NO_MORE_DOCS) {
- return false;
+ if (doc != DocIdSetIterator.NO_MORE_DOCS) {
+ freq = postings.freq();
+ assert freq >= 1;
+ count = 0;
}
-
- freq = postings.freq();
- count = 0;
- position = postings.nextPosition();
- count++;
- readPayload = false;
- return true;
+ position = -1;
+ return doc;
}
@Override
- public int doc() {
+ public int docID() {
return doc;
}
@Override
- public int start() {
+ public int nextStartPosition() throws IOException {
+ if (count == freq) {
+ assert position != NO_MORE_POSITIONS;
+ return position = NO_MORE_POSITIONS;
+ }
+ int prevPosition = position;
+ position = postings.nextPosition();
+ assert position >= prevPosition : "prevPosition="+prevPosition+" > position="+position;
+ assert position != NO_MORE_POSITIONS; // int endPosition not possible
+ count++;
+ readPayload = false;
+ return position;
+ }
+
+ @Override
+ public int startPosition() {
return position;
}
@Override
- public int end() {
- return position + 1;
+ public int endPosition() {
+ return (position == -1) ? -1
+ : (position != NO_MORE_POSITIONS) ? position + 1
+ : NO_MORE_POSITIONS;
}
@Override
@@ -105,7 +109,6 @@ public class TermSpans extends Spans {
return postings.cost();
}
- // TODO: Remove warning after API has been finalized
@Override
public Collection<byte[]> getPayload() throws IOException {
final BytesRef payload = postings.getPayload();
@@ -120,7 +123,6 @@ public class TermSpans extends Spans {
return Collections.singletonList(bytes);
}
- // TODO: Remove warning after API has been finalized
@Override
public boolean isPayloadAvailable() throws IOException {
return readPayload == false && postings.getPayload() != null;
@@ -129,55 +131,12 @@ public class TermSpans extends Spans {
@Override
public String toString() {
return "spans(" + term.toString() + ")@" +
- (doc == -1 ? "START" : (doc == Integer.MAX_VALUE) ? "END" : doc + "-" + position);
+ (doc == -1 ? "START" : (doc == NO_MORE_DOCS) ? "ENDDOC"
+ : doc + " - " + (position == NO_MORE_POSITIONS ? "ENDPOS" : position));
}
public PostingsEnum 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;
- }
-
- @Override
- public long cost() {
- return 0;
- }
- }
-
- public static final TermSpans EMPTY_TERM_SPANS = new EmptyTermSpans();
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/package-info.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/package-info.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/package-info.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/search/spans/package-info.java Wed Apr 1 01:10:11 2015
@@ -18,14 +18,18 @@
/**
* The calculus of spans.
*
- * <p>A span is a <code><doc,startPosition,endPosition></code> tuple.</p>
+ * <p>A span is a <code><doc,startPosition,endPosition></code> tuple that is enumerated by
+ * class {@link org.apache.lucene.search.spans.Spans Spans}.
+ * </p>
*
* <p>The following span query operators are implemented:
*
* <ul>
*
* <li>A {@link org.apache.lucene.search.spans.SpanTermQuery SpanTermQuery} matches all spans
- * containing a particular {@link org.apache.lucene.index.Term Term}.</li>
+ * containing a particular {@link org.apache.lucene.index.Term Term}.
+ * This should not be used for terms that are indexed at position Integer.MAX_VALUE.
+ * </li>
*
* <li> A {@link org.apache.lucene.search.spans.SpanNearQuery SpanNearQuery} matches spans
* which occur near one another, and can be used to implement things like
Modified: lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/util/Version.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/util/Version.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/util/Version.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/java/org/apache/lucene/util/Version.java Wed Apr 1 01:10:11 2015
@@ -46,6 +46,13 @@ public final class Version {
@Deprecated
public static final Version LUCENE_5_1_0 = new Version(5, 1, 0);
+ /**
+ * Match settings and bugs in Lucene's 5.2.0 release.
+ * @deprecated Use latest
+ */
+ @Deprecated
+ public static final Version LUCENE_5_2_0 = new Version(5, 2, 0);
+
/** Match settings and bugs in Lucene's 6.0 release.
* <p>
* Use this to get the latest & greatest settings, bug
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestConcurrentMergeScheduler.java Wed Apr 1 01:10:11 2015
@@ -217,6 +217,9 @@ public class TestConcurrentMergeSchedule
public void testNoWaitClose() throws IOException {
Directory directory = newDirectory();
+ if (directory instanceof MockDirectoryWrapper) {
+ ((MockDirectoryWrapper) directory).setPreventDoubleWrite(false);
+ }
Document doc = new Document();
Field idField = newStringField("id", "", Field.Store.YES);
doc.add(idField);
@@ -248,7 +251,6 @@ public class TestConcurrentMergeSchedule
// stress out aborting them on close:
((LogMergePolicy) writer.getConfig().getMergePolicy()).setMergeFactor(3);
writer.addDocument(doc);
- writer.commit();
try {
writer.commit();
@@ -267,7 +269,8 @@ public class TestConcurrentMergeSchedule
setOpenMode(OpenMode.APPEND).
setMergePolicy(newLogMergePolicy(100)).
// Force excessive merging:
- setMaxBufferedDocs(2)
+ setMaxBufferedDocs(2).
+ setCommitOnClose(false)
);
}
writer.close();
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/index/TestFieldsReader.java Wed Apr 1 01:10:11 2015
@@ -172,7 +172,7 @@ public class TestFieldsReader extends Lu
try {
i.seek(getFilePointer());
} catch (IOException e) {
- throw new RuntimeException();
+ throw new RuntimeException(e);
}
return i;
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/TestPositionIncrement.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/TestPositionIncrement.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/TestPositionIncrement.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/TestPositionIncrement.java Wed Apr 1 01:10:11 2015
@@ -238,18 +238,20 @@ public class TestPositionIncrement exten
if (VERBOSE) {
System.out.println("\ngetPayloadSpans test");
}
- Spans pspans = MultiSpansWrapper.wrap(is.getTopReaderContext(), snq);
- while (pspans.next()) {
- if (VERBOSE) {
- System.out.println("doc " + pspans.doc() + ": span " + pspans.start()
- + " to " + pspans.end());
- }
- Collection<byte[]> payloads = pspans.getPayload();
- sawZero |= pspans.start() == 0;
- for (byte[] bytes : payloads) {
- count++;
+ Spans pspans = MultiSpansWrapper.wrap(is.getIndexReader(), snq);
+ while (pspans.nextDoc() != Spans.NO_MORE_DOCS) {
+ while (pspans.nextStartPosition() != Spans.NO_MORE_POSITIONS) {
if (VERBOSE) {
- System.out.println(" payload: " + new String(bytes, StandardCharsets.UTF_8));
+ System.out.println("doc " + pspans.docID() + ": span " + pspans.startPosition()
+ + " to " + pspans.endPosition());
+ }
+ Collection<byte[]> payloads = pspans.getPayload();
+ sawZero |= pspans.startPosition() == 0;
+ for (byte[] bytes : payloads) {
+ count++;
+ if (VERBOSE) {
+ System.out.println(" payload: " + new String(bytes, StandardCharsets.UTF_8));
+ }
}
}
}
@@ -257,20 +259,20 @@ public class TestPositionIncrement exten
assertEquals(5, count);
// System.out.println("\ngetSpans test");
- Spans spans = MultiSpansWrapper.wrap(is.getTopReaderContext(), snq);
+ Spans spans = MultiSpansWrapper.wrap(is.getIndexReader(), snq);
count = 0;
sawZero = false;
- while (spans.next()) {
- count++;
- sawZero |= spans.start() == 0;
- // System.out.println(spans.doc() + " - " + spans.start() + " - " +
- // spans.end());
+ while (spans.nextDoc() != Spans.NO_MORE_DOCS) {
+ while (spans.nextStartPosition() != Spans.NO_MORE_POSITIONS) {
+ count++;
+ sawZero |= spans.startPosition() == 0;
+ // System.out.println(spans.doc() + " - " + spans.start() + " - " +
+ // spans.end());
+ }
}
assertEquals(4, count);
assertTrue(sawZero);
- // System.out.println("\nPayloadSpanUtil test");
-
sawZero = false;
PayloadSpanUtil psu = new PayloadSpanUtil(is.getTopReaderContext());
Collection<byte[]> pls = psu.getPayloadsForQuery(snq);
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/payloads/TestPayloadTermQuery.java Wed Apr 1 01:10:11 2015
@@ -160,7 +160,7 @@ public class TestPayloadTermQuery extend
assertTrue(doc.score + " does not equal: " + 1, doc.score == 1);
}
CheckHits.checkExplanations(query, PayloadHelper.FIELD, searcher, true);
- Spans spans = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), query);
+ Spans spans = MultiSpansWrapper.wrap(searcher.getIndexReader(), query);
assertTrue("spans is null and it shouldn't be", spans != null);
/*float score = hits.score(0);
for (int i =1; i < hits.length(); i++)
@@ -211,13 +211,15 @@ public class TestPayloadTermQuery extend
}
assertTrue(numTens + " does not equal: " + 10, numTens == 10);
CheckHits.checkExplanations(query, "field", searcher, true);
- Spans spans = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), query);
+ Spans spans = MultiSpansWrapper.wrap(searcher.getIndexReader(), query);
assertTrue("spans is null and it shouldn't be", spans != null);
//should be two matches per document
int count = 0;
//100 hits times 2 matches per hit, we should have 200 in count
- while (spans.next()) {
- count++;
+ while (spans.nextDoc() != Spans.NO_MORE_DOCS) {
+ while (spans.nextStartPosition() != Spans.NO_MORE_POSITIONS) {
+ count++;
+ }
}
assertTrue(count + " does not equal: " + 200, count == 200);
}
@@ -253,13 +255,15 @@ public class TestPayloadTermQuery extend
}
assertTrue(numTens + " does not equal: " + 10, numTens == 10);
CheckHits.checkExplanations(query, "field", searcher, true);
- Spans spans = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), query);
+ Spans spans = MultiSpansWrapper.wrap(searcher.getIndexReader(), query);
assertTrue("spans is null and it shouldn't be", spans != null);
//should be two matches per document
int count = 0;
//100 hits times 2 matches per hit, we should have 200 in count
- while (spans.next()) {
- count++;
+ while (spans.nextDoc() != Spans.NO_MORE_DOCS) {
+ while (spans.nextStartPosition() != Spans.NO_MORE_POSITIONS) {
+ count++;
+ }
}
reader.close();
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/JustCompileSearchSpans.java Wed Apr 1 01:10:11 2015
@@ -24,7 +24,6 @@ import java.util.Map;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
-import org.apache.lucene.search.Weight;
import org.apache.lucene.search.similarities.Similarity;
import org.apache.lucene.util.Bits;
@@ -42,27 +41,32 @@ final class JustCompileSearchSpans {
static final class JustCompileSpans extends Spans {
@Override
- public int doc() {
+ public int docID() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public int end() {
+ public int nextDoc() throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public boolean next() {
+ public int advance(int target) throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
-
+
@Override
- public boolean skipTo(int target) {
+ public int startPosition() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public int start() {
+ public int endPosition() {
+ throw new UnsupportedOperationException(UNSUPPORTED_MSG);
+ }
+
+ @Override
+ public int nextStartPosition() throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@@ -104,37 +108,42 @@ final class JustCompileSearchSpans {
static final class JustCompilePayloadSpans extends Spans {
@Override
- public Collection<byte[]> getPayload() {
+ public int docID() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public boolean isPayloadAvailable() {
+ public int nextDoc() throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public int doc() {
+ public int advance(int target) throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public int end() {
+ public int startPosition() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public boolean next() {
+ public int endPosition() {
+ throw new UnsupportedOperationException(UNSUPPORTED_MSG);
+ }
+
+ @Override
+ public int nextStartPosition() throws IOException {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public boolean skipTo(int target) {
+ public Collection<byte[]> getPayload() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@Override
- public int start() {
+ public boolean isPayloadAvailable() {
throw new UnsupportedOperationException(UNSUPPORTED_MSG);
}
@@ -147,7 +156,7 @@ final class JustCompileSearchSpans {
static final class JustCompileSpanScorer extends SpanScorer {
- protected JustCompileSpanScorer(Spans spans, Weight weight,
+ protected JustCompileSpanScorer(Spans spans, SpanWeight weight,
Similarity.SimScorer docScorer) throws IOException {
super(spans, weight, docScorer);
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/MultiSpansWrapper.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/MultiSpansWrapper.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/MultiSpansWrapper.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/MultiSpansWrapper.java Wed Apr 1 01:10:11 2015
@@ -18,19 +18,18 @@ package org.apache.lucene.search.spans;
*/
import java.io.IOException;
-import java.util.Collection;
-import java.util.Collections;
import java.util.HashMap;
-import java.util.List;
+import java.util.HashSet;
import java.util.Map;
-import java.util.TreeSet;
+import org.apache.lucene.index.IndexReader;
+import org.apache.lucene.index.LeafReader;
import org.apache.lucene.index.LeafReaderContext;
-import org.apache.lucene.index.IndexReaderContext;
-import org.apache.lucene.index.ReaderUtil;
+import org.apache.lucene.index.SlowCompositeReaderWrapper;
import org.apache.lucene.index.Term;
import org.apache.lucene.index.TermContext;
-import org.apache.lucene.search.DocIdSetIterator;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.util.Bits;
/**
*
@@ -39,141 +38,20 @@ import org.apache.lucene.search.DocIdSet
* NOTE: This should be used for testing purposes only
* @lucene.internal
*/
-public class MultiSpansWrapper extends Spans { // can't be package private due to payloads
+public class MultiSpansWrapper {
- private SpanQuery query;
- private List<LeafReaderContext> leaves;
- private int leafOrd = 0;
- private Spans current;
- private Map<Term,TermContext> termContexts;
- private final int numLeaves;
-
- private MultiSpansWrapper(List<LeafReaderContext> leaves, SpanQuery query, Map<Term,TermContext> termContexts) {
- this.query = query;
- this.leaves = leaves;
- this.numLeaves = leaves.size();
- this.termContexts = termContexts;
- }
-
- public static Spans wrap(IndexReaderContext topLevelReaderContext, SpanQuery query) throws IOException {
+ public static Spans wrap(IndexReader reader, SpanQuery spanQuery) throws IOException {
+ LeafReader lr = SlowCompositeReaderWrapper.wrap(reader); // slow, but ok for testing
+ LeafReaderContext lrContext = lr.getContext();
+ Query rewrittenQuery = spanQuery.rewrite(lr); // get the term contexts so getSpans can be called directly
+ HashSet<Term> termSet = new HashSet<>();
+ rewrittenQuery.extractTerms(termSet);
Map<Term,TermContext> termContexts = new HashMap<>();
- TreeSet<Term> terms = new TreeSet<>();
- query.extractTerms(terms);
- for (Term term : terms) {
- termContexts.put(term, TermContext.build(topLevelReaderContext, term));
- }
- final List<LeafReaderContext> leaves = topLevelReaderContext.leaves();
- if(leaves.size() == 1) {
- final LeafReaderContext ctx = leaves.get(0);
- return query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
+ for (Term term: termSet) {
+ TermContext termContext = TermContext.build(lrContext, term);
+ termContexts.put(term, termContext);
}
- return new MultiSpansWrapper(leaves, query, termContexts);
+ Spans actSpans = spanQuery.getSpans(lrContext, new Bits.MatchAllBits(lr.numDocs()), termContexts);
+ return actSpans;
}
-
- @Override
- public boolean next() throws IOException {
- if (leafOrd >= numLeaves) {
- return false;
- }
- if (current == null) {
- final LeafReaderContext ctx = leaves.get(leafOrd);
- current = query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
- }
- while(true) {
- if (current.next()) {
- return true;
- }
- if (++leafOrd < numLeaves) {
- final LeafReaderContext ctx = leaves.get(leafOrd);
- current = query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
- } else {
- current = null;
- break;
- }
- }
- return false;
- }
-
- @Override
- public boolean skipTo(int target) throws IOException {
- if (leafOrd >= numLeaves) {
- return false;
- }
-
- int subIndex = ReaderUtil.subIndex(target, leaves);
- assert subIndex >= leafOrd;
- if (subIndex != leafOrd) {
- final LeafReaderContext ctx = leaves.get(subIndex);
- current = query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
- leafOrd = subIndex;
- } else if (current == null) {
- final LeafReaderContext ctx = leaves.get(leafOrd);
- current = query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
- }
- while (true) {
- if (target < leaves.get(leafOrd).docBase) {
- // target was in the previous slice
- if (current.next()) {
- return true;
- }
- } else if (current.skipTo(target - leaves.get(leafOrd).docBase)) {
- return true;
- }
- if (++leafOrd < numLeaves) {
- final LeafReaderContext ctx = leaves.get(leafOrd);
- current = query.getSpans(ctx, ctx.reader().getLiveDocs(), termContexts);
- } else {
- current = null;
- break;
- }
- }
-
- return false;
- }
-
- @Override
- public int doc() {
- if (current == null) {
- return DocIdSetIterator.NO_MORE_DOCS;
- }
- return current.doc() + leaves.get(leafOrd).docBase;
- }
-
- @Override
- public int start() {
- if (current == null) {
- return DocIdSetIterator.NO_MORE_DOCS;
- }
- return current.start();
- }
-
- @Override
- public int end() {
- if (current == null) {
- return DocIdSetIterator.NO_MORE_DOCS;
- }
- return current.end();
- }
-
- @Override
- public Collection<byte[]> getPayload() throws IOException {
- if (current == null) {
- return Collections.emptyList();
- }
- return current.getPayload();
- }
-
- @Override
- public boolean isPayloadAvailable() throws IOException {
- if (current == null) {
- return false;
- }
- return current.isPayloadAvailable();
- }
-
- @Override
- public long cost() {
- return Integer.MAX_VALUE; // just for tests
- }
-
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestBasics.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestBasics.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestBasics.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestBasics.java Wed Apr 1 01:10:11 2015
@@ -651,47 +651,6 @@ public class TestBasics extends LuceneTe
1746, 1747, 1756, 1757, 1766, 1767, 1776, 1777, 1786, 1787, 1796, 1797});
}
- @Test
- public void testSpansSkipTo() throws Exception {
- SpanTermQuery t1 = new SpanTermQuery(new Term("field", "seventy"));
- SpanTermQuery t2 = new SpanTermQuery(new Term("field", "seventy"));
- Spans s1 = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), t1);
- Spans s2 = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), t2);
-
- assertTrue(s1.next());
- assertTrue(s2.next());
-
- boolean hasMore = true;
-
- do {
- hasMore = skipToAccordingToJavaDocs(s1, s1.doc() + 1);
- assertEquals(hasMore, s2.skipTo(s2.doc() + 1));
- assertEquals(s1.doc(), s2.doc());
- } while (hasMore);
- }
-
- /** Skips to the first match beyond the current, whose document number is
- * greater than or equal to <i>target</i>. <p>Returns true iff there is such
- * a match. <p>Behaves as if written: <pre>
- * boolean skipTo(int target) {
- * do {
- * if (!next())
- * return false;
- * } while (target > doc());
- * return true;
- * }
- * </pre>
- */
- private boolean skipToAccordingToJavaDocs(Spans s, int target)
- throws Exception {
- do {
- if (!s.next())
- return false;
- } while (target > s.doc());
- return true;
-
- }
-
private void checkHits(Query query, int[] results) throws IOException {
CheckHits.checkHits(random(), query, "field", searcher, results);
}
Modified: lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java
URL: http://svn.apache.org/viewvc/lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java?rev=1670533&r1=1670532&r2=1670533&view=diff
==============================================================================
--- lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java (original)
+++ lucene/dev/branches/lucene6271/lucene/core/src/test/org/apache/lucene/search/spans/TestFieldMaskingSpanQuery.java Wed Apr 1 01:10:11 2015
@@ -258,37 +258,19 @@ public class TestFieldMaskingSpanQuery e
SpanQuery q2 = new SpanTermQuery(new Term("first", "james"));
SpanQuery q = new SpanOrQuery(q1, new FieldMaskingSpanQuery(q2, "gender"));
check(q, new int[] { 0, 1, 2, 3, 4 });
-
- Spans span = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), q);
-
- assertEquals(true, span.next());
- assertEquals(s(0,0,1), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(1,0,1), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(1,1,2), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(2,0,1), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(2,1,2), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(2,2,3), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(3,0,1), s(span));
- assertEquals(true, span.next());
- assertEquals(s(4,0,1), s(span));
+ Spans span = MultiSpansWrapper.wrap(searcher.getIndexReader(), q);
- assertEquals(true, span.next());
- assertEquals(s(4,1,2), s(span));
-
- assertEquals(false, span.next());
+ TestSpans.tstNextSpans(span, 0,0,1);
+ TestSpans.tstNextSpans(span, 1,0,1);
+ TestSpans.tstNextSpans(span, 1,1,2);
+ TestSpans.tstNextSpans(span, 2,0,1);
+ TestSpans.tstNextSpans(span, 2,1,2);
+ TestSpans.tstNextSpans(span, 2,2,3);
+ TestSpans.tstNextSpans(span, 3,0,1);
+ TestSpans.tstNextSpans(span, 4,0,1);
+ TestSpans.tstNextSpans(span, 4,1,2);
+ TestSpans.tstEndSpans(span);
}
public void testSpans1() throws Exception {
@@ -300,19 +282,22 @@ public class TestFieldMaskingSpanQuery e
check(qA, new int[] { 0, 1, 2, 4 });
check(qB, new int[] { 0, 1, 2, 4 });
- Spans spanA = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), qA);
- Spans spanB = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), qB);
+ Spans spanA = MultiSpansWrapper.wrap(searcher.getIndexReader(), qA);
+ Spans spanB = MultiSpansWrapper.wrap(searcher.getIndexReader(), qB);
- while (spanA.next()) {
- assertTrue("spanB not still going", spanB.next());
- assertEquals("spanA not equal spanB", s(spanA), s(spanB));
+ while (spanA.nextDoc() != Spans.NO_MORE_DOCS) {
+ assertNotSame("spanB not still going", Spans.NO_MORE_DOCS, spanB.nextDoc());
+ while (spanA.nextStartPosition() != Spans.NO_MORE_POSITIONS) {
+ assertEquals("spanB start position", spanA.startPosition(), spanB.nextStartPosition());
+ assertEquals("spanB end position", spanA.endPosition(), spanB.endPosition());
+ }
+ assertEquals("spanB start position", Spans.NO_MORE_POSITIONS, spanB.nextStartPosition());
}
- assertTrue("spanB still going even tough spanA is done", !(spanB.next()));
-
+ assertEquals("spanB end doc", Spans.NO_MORE_DOCS, spanB.nextDoc());
}
public void testSpans2() throws Exception {
- assumeTrue("Broken scoring: LUCENE-3723",
+ assumeTrue("Broken scoring: LUCENE-3723",
searcher.getSimilarity() instanceof TFIDFSimilarity);
SpanQuery qA1 = new SpanTermQuery(new Term("gender", "female"));
SpanQuery qA2 = new SpanTermQuery(new Term("first", "james"));
@@ -322,30 +307,17 @@ public class TestFieldMaskingSpanQuery e
{ new FieldMaskingSpanQuery(qA, "id"),
new FieldMaskingSpanQuery(qB, "id") }, -1, false );
check(q, new int[] { 0, 1, 2, 3 });
-
- Spans span = MultiSpansWrapper.wrap(searcher.getTopReaderContext(), q);
-
- assertEquals(true, span.next());
- assertEquals(s(0,0,1), s(span));
- assertEquals(true, span.next());
- assertEquals(s(1,1,2), s(span));
+ Spans span = MultiSpansWrapper.wrap(searcher.getIndexReader(), q);
- assertEquals(true, span.next());
- assertEquals(s(2,0,1), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(2,2,3), s(span));
-
- assertEquals(true, span.next());
- assertEquals(s(3,0,1), s(span));
-
- assertEquals(false, span.next());
+ TestSpans.tstNextSpans(span, 0,0,1);
+ TestSpans.tstNextSpans(span, 1,1,2);
+ TestSpans.tstNextSpans(span, 2,0,1);
+ TestSpans.tstNextSpans(span, 2,2,3);
+ TestSpans.tstNextSpans(span, 3,0,1);
+ TestSpans.tstEndSpans(span);
}
- public String s(Spans span) {
- return s(span.doc(), span.start(), span.end());
- }
public String s(int doc, int start, int end) {
return "s(" + doc + "," + start + "," + end +")";
}