LUCENE-1776: Add an option to not collect payloads for an ordered SpanNearQuery. Payloads were not lazily loaded in this case as the javadocs implied. If you have payloads and want to use an ordered SpanNearQuery that does not need to use the payloads, you can disable loading them with a new constructor switch.

git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@800393 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Mark Robert Miller 2009-08-03 14:12:15 +00:00
parent 457c29d31e
commit 6a47cbb5f9
4 changed files with 35 additions and 11 deletions

View File

@ -647,6 +647,12 @@ New features
3.0 and will then replace the current core QueryParser, which 3.0 and will then replace the current core QueryParser, which
has been deprecated with this patch. has been deprecated with this patch.
(Luis Alves and Adriano Campos via Michael Busch) (Luis Alves and Adriano Campos via Michael Busch)
36. LUCENE-1776: Add an option to not collect payloads for an ordered
SpanNearQuery. Payloads were not lazily loaded in this case as
the javadocs implied. If you have payloads and want to use an ordered
SpanNearQuery that does not need to use the payloads, you can
disable loading them with a new constructor switch. (Mark Miller)
Optimizations Optimizations

View File

@ -72,13 +72,19 @@ class NearSpansOrdered implements PayloadSpans {
}; };
private SpanNearQuery query; private SpanNearQuery query;
private boolean collectPayloads = true;
public NearSpansOrdered(SpanNearQuery spanNearQuery, IndexReader reader) throws IOException {
this(spanNearQuery, reader, true);
}
public NearSpansOrdered(SpanNearQuery spanNearQuery, IndexReader reader) public NearSpansOrdered(SpanNearQuery spanNearQuery, IndexReader reader, boolean collectPayloads)
throws IOException { throws IOException {
if (spanNearQuery.getClauses().length < 2) { if (spanNearQuery.getClauses().length < 2) {
throw new IllegalArgumentException("Less than 2 clauses: " throw new IllegalArgumentException("Less than 2 clauses: "
+ spanNearQuery); + spanNearQuery);
} }
this.collectPayloads = collectPayloads;
allowedSlop = spanNearQuery.getSlop(); allowedSlop = spanNearQuery.getSlop();
SpanQuery[] clauses = spanNearQuery.getClauses(); SpanQuery[] clauses = spanNearQuery.getClauses();
subSpans = new PayloadSpans[clauses.length]; subSpans = new PayloadSpans[clauses.length];
@ -101,6 +107,7 @@ class NearSpansOrdered implements PayloadSpans {
public int end() { return matchEnd; } public int end() { return matchEnd; }
// TODO: Remove warning after API has been finalized // TODO: Remove warning after API has been finalized
// TODO: Would be nice to be able to lazy load payloads
public Collection/*<byte[]>*/ getPayload() throws IOException { public Collection/*<byte[]>*/ getPayload() throws IOException {
return matchPayload; return matchPayload;
} }
@ -122,7 +129,9 @@ class NearSpansOrdered implements PayloadSpans {
} }
more = true; more = true;
} }
matchPayload.clear(); if(collectPayloads) {
matchPayload.clear();
}
return advanceAfterOrdered(); return advanceAfterOrdered();
} }
@ -145,7 +154,9 @@ class NearSpansOrdered implements PayloadSpans {
return false; return false;
} }
} }
matchPayload.clear(); if(collectPayloads) {
matchPayload.clear();
}
return advanceAfterOrdered(); return advanceAfterOrdered();
} }
@ -250,7 +261,7 @@ class NearSpansOrdered implements PayloadSpans {
int lastEnd = matchEnd; int lastEnd = matchEnd;
for (int i = subSpans.length - 2; i >= 0; i--) { for (int i = subSpans.length - 2; i >= 0; i--) {
PayloadSpans prevSpans = subSpans[i]; PayloadSpans prevSpans = subSpans[i];
if (prevSpans.isPayloadAvailable()) { if (collectPayloads && prevSpans.isPayloadAvailable()) {
Collection payload = prevSpans.getPayload(); Collection payload = prevSpans.getPayload();
possiblePayload = new ArrayList(payload.size()); possiblePayload = new ArrayList(payload.size());
possiblePayload.addAll(payload); possiblePayload.addAll(payload);
@ -274,7 +285,7 @@ class NearSpansOrdered implements PayloadSpans {
} else { // prevSpans still before (lastStart, lastEnd) } else { // prevSpans still before (lastStart, lastEnd)
prevStart = ppStart; prevStart = ppStart;
prevEnd = ppEnd; prevEnd = ppEnd;
if (prevSpans.isPayloadAvailable()) { if (collectPayloads && prevSpans.isPayloadAvailable()) {
Collection payload = prevSpans.getPayload(); Collection payload = prevSpans.getPayload();
possiblePayload = new ArrayList(payload.size()); possiblePayload = new ArrayList(payload.size());
possiblePayload.addAll(payload); possiblePayload.addAll(payload);
@ -283,7 +294,7 @@ class NearSpansOrdered implements PayloadSpans {
} }
} }
if (possiblePayload != null) { if (collectPayloads && possiblePayload != null) {
possibleMatchPayloads.addAll(possiblePayload); possibleMatchPayloads.addAll(possiblePayload);
} }
@ -302,7 +313,7 @@ class NearSpansOrdered implements PayloadSpans {
boolean match = matchSlop <= allowedSlop; boolean match = matchSlop <= allowedSlop;
if(match && possibleMatchPayloads.size() > 0) { if(collectPayloads && match && possibleMatchPayloads.size() > 0) {
matchPayload.addAll(possibleMatchPayloads); matchPayload.addAll(possibleMatchPayloads);
} }

View File

@ -33,9 +33,11 @@ public interface PayloadSpans extends Spans{
* This is invalid until {@link #next()} is called for * This is invalid until {@link #next()} is called for
* the first time. * the first time.
* This method must not be called more than once after each call * This method must not be called more than once after each call
* of {@link #next()}. However, payloads are loaded lazily, * of {@link #next()}. However, most SpanQuerys load payloads lazily,
* so if the payload data for the current position is not needed, * so if the payload data for the current position is not needed,
* this method may not be called at all for performance reasons.<br> * this method may not be called at all for performance reasons.
* The ordered case of SpanNearQuery does not load lazily and has
* an option to turn off payload loading.<br>
* <br> * <br>
* Note that the return type is a collection, thus the ordering should not be relied upon. * Note that the return type is a collection, thus the ordering should not be relied upon.
* <br/> * <br/>

View File

@ -39,12 +39,17 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
private boolean inOrder; private boolean inOrder;
private String field; private String field;
private boolean collectPayloads;
/** Construct a SpanNearQuery. Matches spans matching a span from each /** Construct a SpanNearQuery. Matches spans matching a span from each
* clause, with up to <code>slop</code> total unmatched positions between * clause, with up to <code>slop</code> total unmatched positions between
* them. * When <code>inOrder</code> is true, the spans from each clause * them. * When <code>inOrder</code> is true, the spans from each clause
* must be * ordered as in <code>clauses</code>. */ * must be * ordered as in <code>clauses</code>. */
public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) { public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder) {
this(clauses, slop, inOrder, true);
}
public SpanNearQuery(SpanQuery[] clauses, int slop, boolean inOrder, boolean collectPayloads) {
// copy clauses array into an ArrayList // copy clauses array into an ArrayList
this.clauses = new ArrayList(clauses.length); this.clauses = new ArrayList(clauses.length);
@ -57,7 +62,7 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
} }
this.clauses.add(clause); this.clauses.add(clause);
} }
this.collectPayloads = collectPayloads;
this.slop = slop; this.slop = slop;
this.inOrder = inOrder; this.inOrder = inOrder;
} }
@ -126,7 +131,7 @@ public class SpanNearQuery extends SpanQuery implements Cloneable {
return ((SpanQuery)clauses.get(0)).getPayloadSpans(reader); return ((SpanQuery)clauses.get(0)).getPayloadSpans(reader);
return inOrder return inOrder
? (PayloadSpans) new NearSpansOrdered(this, reader) ? (PayloadSpans) new NearSpansOrdered(this, reader, collectPayloads)
: (PayloadSpans) new NearSpansUnordered(this, reader); : (PayloadSpans) new NearSpansUnordered(this, reader);
} }