LUCENE-2757: Fix hackish max clause count handling in trunk

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1035173 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Uwe Schindler 2010-11-15 08:22:13 +00:00
parent 63555ce48d
commit 1d0515124e
2 changed files with 19 additions and 11 deletions

View File

@ -68,6 +68,12 @@ public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewr
topLevel.add(tq, BooleanClause.Occur.SHOULD); topLevel.add(tq, BooleanClause.Occur.SHOULD);
} }
@Override
protected void checkMaxClauseCount(int count) {
if (count > BooleanQuery.getMaxClauseCount())
throw new BooleanQuery.TooManyClauses();
}
// Make sure we are still a singleton even after deserializing // Make sure we are still a singleton even after deserializing
protected Object readResolve() { protected Object readResolve() {
return SCORING_BOOLEAN_QUERY_REWRITE; return SCORING_BOOLEAN_QUERY_REWRITE;
@ -104,10 +110,14 @@ public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewr
} }
}; };
/** This method is called after every new term to check if the number of max clauses
* (e.g. in BooleanQuery) is not exceeded. Throws the corresponding {@link RuntimeException}. */
protected abstract void checkMaxClauseCount(int count) throws IOException;
@Override @Override
public final Q rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException { public final Q rewrite(final IndexReader reader, final MultiTermQuery query) throws IOException {
final Q result = getTopLevelQuery(); final Q result = getTopLevelQuery();
final ParallelArraysTermCollector col = new ParallelArraysTermCollector(result instanceof BooleanQuery); final ParallelArraysTermCollector col = new ParallelArraysTermCollector();
collectTerms(reader, query, col); collectTerms(reader, query, col);
final Term placeholderTerm = new Term(query.field); final Term placeholderTerm = new Term(query.field);
@ -127,18 +137,13 @@ public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewr
return result; return result;
} }
static final class ParallelArraysTermCollector extends TermCollector { final class ParallelArraysTermCollector extends TermCollector {
private final boolean checkMaxClauseCount;
final TermFreqBoostByteStart array = new TermFreqBoostByteStart(16); final TermFreqBoostByteStart array = new TermFreqBoostByteStart(16);
final BytesRefHash terms = new BytesRefHash(new ByteBlockPool(new ByteBlockPool.DirectAllocator()), 16, array); final BytesRefHash terms = new BytesRefHash(new ByteBlockPool(new ByteBlockPool.DirectAllocator()), 16, array);
TermsEnum termsEnum; TermsEnum termsEnum;
private BoostAttribute boostAtt; private BoostAttribute boostAtt;
public ParallelArraysTermCollector(boolean checkMaxClauseCount) {
this.checkMaxClauseCount = checkMaxClauseCount;
}
@Override @Override
public void setNextEnum(TermsEnum termsEnum) throws IOException { public void setNextEnum(TermsEnum termsEnum) throws IOException {
this.termsEnum = termsEnum; this.termsEnum = termsEnum;
@ -146,7 +151,7 @@ public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewr
} }
@Override @Override
public boolean collect(BytesRef bytes) { public boolean collect(BytesRef bytes) throws IOException {
final int e = terms.add(bytes); final int e = terms.add(bytes);
if (e < 0 ) { if (e < 0 ) {
// duplicate term: update docFreq // duplicate term: update docFreq
@ -157,10 +162,8 @@ public abstract class ScoringRewrite<Q extends Query> extends TermCollectingRewr
// new entry: we populate the entry initially // new entry: we populate the entry initially
array.docFreq[e] = termsEnum.docFreq(); array.docFreq[e] = termsEnum.docFreq();
array.boost[e] = boostAtt.getBoost(); array.boost[e] = boostAtt.getBoost();
ScoringRewrite.this.checkMaxClauseCount(terms.size());
} }
// if the new entry reaches the max clause count, we exit early
if (checkMaxClauseCount && e >= BooleanQuery.getMaxClauseCount())
throw new BooleanQuery.TooManyClauses();
return true; return true;
} }
} }

View File

@ -147,6 +147,11 @@ public class SpanMultiTermQueryWrapper<Q extends MultiTermQuery> extends SpanQue
return new SpanOrQuery(); return new SpanOrQuery();
} }
@Override
protected void checkMaxClauseCount(int count) {
// we accept all terms as SpanOrQuery has no limits
}
@Override @Override
protected void addClause(SpanOrQuery topLevel, Term term, int docCount, float boost) { protected void addClause(SpanOrQuery topLevel, Term term, int docCount, float boost) {
final SpanTermQuery q = new SpanTermQuery(term); final SpanTermQuery q = new SpanTermQuery(term);