LUCENE-6309: disable coord when scores are not needed, or the scoring fn does not use it

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1662964 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2015-02-28 16:43:54 +00:00
parent f5e8447d8c
commit 99a16fc2dc
2 changed files with 23 additions and 14 deletions

View File

@ -42,13 +42,13 @@ public class BooleanWeight extends Weight {
protected int maxCoord; // num optional + num required
private final boolean disableCoord;
private final boolean needsScores;
private final float coords[];
public BooleanWeight(BooleanQuery query, IndexSearcher searcher, boolean needsScores, boolean disableCoord) throws IOException {
super(query);
this.query = query;
this.needsScores = needsScores;
this.similarity = searcher.getSimilarity();
this.disableCoord = disableCoord;
weights = new ArrayList<>(query.clauses().size());
for (int i = 0 ; i < query.clauses().size(); i++) {
BooleanClause c = query.clauses().get(i);
@ -58,6 +58,23 @@ public class BooleanWeight extends Weight {
maxCoord++;
}
}
// precompute coords (0..N, N).
// set disableCoord when its explicit, scores are not needed, no scoring clauses, or the sim doesn't use it.
coords = new float[maxCoord+1];
Arrays.fill(coords, 1F);
coords[0] = 0f;
if (maxCoord > 0 && needsScores && disableCoord == false) {
// compute coords from the similarity, look for any actual ones.
boolean seenActualCoord = false;
for (int i = 1; i < coords.length; i++) {
coords[i] = coord(i, maxCoord);
seenActualCoord |= (coords[i] != 1F);
}
this.disableCoord = seenActualCoord == false;
} else {
this.disableCoord = true;
}
}
@Override
@ -346,9 +363,9 @@ public class BooleanWeight extends Weight {
}
} else {
if (minShouldMatch > 0) {
return new BooleanTopLevelScorers.CoordinatingConjunctionScorer(this, coords(), req, requiredScoring.size(), opt);
return new BooleanTopLevelScorers.CoordinatingConjunctionScorer(this, coords, req, requiredScoring.size(), opt);
} else {
return new BooleanTopLevelScorers.ReqMultiOptScorer(req, opt, requiredScoring.size(), coords());
return new BooleanTopLevelScorers.ReqMultiOptScorer(req, opt, requiredScoring.size(), coords);
}
}
}
@ -395,10 +412,11 @@ public class BooleanWeight extends Weight {
} else {
float coords[];
if (disableCoord) {
// sneaky: when we do a mixed conjunction/disjunction, we need a fake for the disjunction part.
coords = new float[optional.size()+1];
Arrays.fill(coords, 1F);
} else {
coords = coords();
coords = this.coords;
}
if (minShouldMatch > 1) {
return new MinShouldMatchSumScorer(this, optional, minShouldMatch, coords);
@ -407,13 +425,4 @@ public class BooleanWeight extends Weight {
}
}
}
private float[] coords() {
float[] coords = new float[maxCoord+1];
coords[0] = 0F;
for (int i = 1; i < coords.length; i++) {
coords[i] = coord(i, maxCoord);
}
return coords;
}
}

View File

@ -674,7 +674,7 @@ public class TestBooleanQuery extends LuceneTestCase {
final Weight weight = searcher.createNormalizedWeight(q, random().nextBoolean());
final Scorer scorer = weight.scorer(reader.leaves().get(0), null);
assertTrue(scorer instanceof BoostedScorer);
assertTrue(scorer instanceof BoostedScorer || scorer instanceof ExactPhraseScorer);
assertNotNull(scorer.asTwoPhaseIterator());
reader.close();