LUCENE-4236: move all crazies into one place

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/branches/lucene4236@1596442 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Robert Muir 2014-05-21 02:37:25 +00:00
parent f12abad10f
commit f3ecdd337a
5 changed files with 141 additions and 124 deletions

View File

@ -420,18 +420,17 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
} else {
float coordReq = coord(required.size(), maxCoord);
float coordBoth = coord(required.size() + 1, maxCoord);
return new ReqOptSumScorer.ReqSingleOptScorer(req, opt, coordReq, coordBoth);
return new BooleanTopLevelScorers.ReqSingleOptScorer(req, opt, coordReq, coordBoth);
}
} else {
if (minShouldMatch > 0) {
return new ConjunctionScorer.CoordinatingConjunctionScorer(this, coords(), req, required.size(), opt);
return new BooleanTopLevelScorers.CoordinatingConjunctionScorer(this, coords(), req, required.size(), opt);
} else {
return new ReqOptSumScorer.ReqMultiOptScorer(req, opt, required.size(), coords());
return new BooleanTopLevelScorers.ReqMultiOptScorer(req, opt, required.size(), coords());
}
}
}
// nocommit: double-check all this
@Override
public boolean scoresDocsOutOfOrder() {
if (minNrShouldMatch > 1) {
@ -460,7 +459,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
if (required.size() == 1) {
Scorer req = required.get(0);
if (!disableCoord && maxCoord > 1) {
return new BoostedScorer(req, coord(1, maxCoord));
return new BooleanTopLevelScorers.BoostedScorer(req, coord(1, maxCoord));
} else {
return req;
}
@ -491,7 +490,7 @@ public class BooleanQuery extends Query implements Iterable<BooleanClause> {
if (optional.size() == 1) {
Scorer opt = optional.get(0);
if (!disableCoord && maxCoord > 1) {
return new BoostedScorer(opt, coord(1, maxCoord));
return new BooleanTopLevelScorers.BoostedScorer(opt, coord(1, maxCoord));
} else {
return opt;
}

View File

@ -0,0 +1,136 @@
package org.apache.lucene.search;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
/** Internal document-at-a-time scorers used to deal with stupid coord() computation */
class BooleanTopLevelScorers {
/**
* Used when there is more than one scorer in a query, but a segment
* only had one non-null scorer. This just wraps that scorer directly
* to factor in coord().
*/
static class BoostedScorer extends FilterScorer {
private final float boost;
BoostedScorer(Scorer in, float boost) {
super(in);
this.boost = boost;
}
@Override
public float score() throws IOException {
return in.score() * boost;
}
}
/**
* Used when there are both mandatory and optional clauses, but minShouldMatch
* dictates that some of the optional clauses must match. The query is a conjunction,
* but must compute coord based on how many optional subscorers matched (freq).
*/
static class CoordinatingConjunctionScorer extends ConjunctionScorer {
private final float coords[];
private final int reqCount;
private final Scorer req;
private final Scorer opt;
CoordinatingConjunctionScorer(Weight weight, float coords[], Scorer req, int reqCount, Scorer opt) {
super(weight, new Scorer[] { req, opt });
this.coords = coords;
this.req = req;
this.reqCount = reqCount;
this.opt = opt;
}
@Override
public float score() throws IOException {
return (req.score() + opt.score()) * coords[reqCount + opt.freq()];
}
}
/**
* Used when there are mandatory clauses with one optional clause: we compute
* coord based on whether the optional clause matched or not.
*/
static class ReqSingleOptScorer extends ReqOptSumScorer {
// coord factor if just the required part matches
private final float coordReq;
// coord factor if both required and optional part matches
private final float coordBoth;
public ReqSingleOptScorer(Scorer reqScorer, Scorer optScorer, float coordReq, float coordBoth) {
super(reqScorer, optScorer);
this.coordReq = coordReq;
this.coordBoth = coordBoth;
}
@Override
public float score() throws IOException {
int curDoc = reqScorer.docID();
float reqScore = reqScorer.score();
if (optScorer == null) {
return reqScore * coordReq;
}
int optScorerDoc = optScorer.docID();
if (optScorerDoc < curDoc && (optScorerDoc = optScorer.advance(curDoc)) == NO_MORE_DOCS) {
optScorer = null;
return reqScore * coordReq;
}
return optScorerDoc == curDoc ? (reqScore + optScorer.score()) * coordBoth : reqScore * coordReq;
}
}
/**
* Used when there are mandatory clauses with optional clauses: we compute
* coord based on how many optional subscorers matched (freq).
*/
static class ReqMultiOptScorer extends ReqOptSumScorer {
private final int requiredCount;
private final float coords[];
private final Scorer disjunction;
public ReqMultiOptScorer(Scorer reqScorer, Scorer optScorer, int requiredCount, float coords[]) {
super(reqScorer, optScorer);
this.requiredCount = requiredCount;
this.coords = coords;
this.disjunction = optScorer;
}
@Override
public float score() throws IOException {
int curDoc = reqScorer.docID();
float reqScore = reqScorer.score();
if (optScorer == null) {
return reqScore * coords[requiredCount];
}
int optScorerDoc = optScorer.docID();
if (optScorerDoc < curDoc && (optScorerDoc = optScorer.advance(curDoc)) == NO_MORE_DOCS) {
optScorer = null;
return reqScore * coords[requiredCount];
}
return optScorerDoc == curDoc ? (reqScore + optScorer.score()) * coords[requiredCount + disjunction.freq()] : reqScore * coords[requiredCount];
}
}
}

View File

@ -1,35 +0,0 @@
package org.apache.lucene.search;
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import java.io.IOException;
// nocommit: WTF?
final class BoostedScorer extends FilterScorer {
private final float boost;
BoostedScorer(Scorer in, float boost) {
super(in);
this.boost = boost;
}
@Override
public float score() throws IOException {
return in.score() * boost;
}
}

View File

@ -139,25 +139,4 @@ class ConjunctionScorer extends Scorer {
this.cost = scorer.cost();
}
}
// nocommit: WTF?
static class CoordinatingConjunctionScorer extends ConjunctionScorer {
private final float coords[];
private final int reqCount;
private final Scorer req;
private final Scorer opt;
CoordinatingConjunctionScorer(Weight weight, float coords[], Scorer req, int reqCount, Scorer opt) {
super(weight, new Scorer[] { req, opt });
this.coords = coords;
this.req = req;
this.reqCount = reqCount;
this.opt = opt;
}
@Override
public float score() throws IOException {
return (req.score() + opt.score()) * coords[reqCount + opt.freq()];
}
}
}

View File

@ -104,67 +104,5 @@ class ReqOptSumScorer extends Scorer {
public long cost() {
return reqScorer.cost();
}
// nocommit: WTF?
static class ReqSingleOptScorer extends ReqOptSumScorer {
// coord factor if just the required part matches
private final float coordReq;
// coord factor if both required and optional part matches
private final float coordBoth;
public ReqSingleOptScorer(Scorer reqScorer, Scorer optScorer, float coordReq, float coordBoth) {
super(reqScorer, optScorer);
this.coordReq = coordReq;
this.coordBoth = coordBoth;
}
@Override
public float score() throws IOException {
int curDoc = reqScorer.docID();
float reqScore = reqScorer.score();
if (optScorer == null) {
return reqScore * coordReq;
}
int optScorerDoc = optScorer.docID();
if (optScorerDoc < curDoc && (optScorerDoc = optScorer.advance(curDoc)) == NO_MORE_DOCS) {
optScorer = null;
return reqScore * coordReq;
}
return optScorerDoc == curDoc ? (reqScore + optScorer.score()) * coordBoth : reqScore * coordReq;
}
}
// nocommit: WTF?
static class ReqMultiOptScorer extends ReqOptSumScorer {
private final int requiredCount;
private final float coords[];
private final Scorer disjunction;
public ReqMultiOptScorer(Scorer reqScorer, Scorer optScorer, int requiredCount, float coords[]) {
super(reqScorer, optScorer);
this.requiredCount = requiredCount;
this.coords = coords;
this.disjunction = optScorer;
}
@Override
public float score() throws IOException {
int curDoc = reqScorer.docID();
float reqScore = reqScorer.score();
if (optScorer == null) {
return reqScore * coords[requiredCount];
}
int optScorerDoc = optScorer.docID();
if (optScorerDoc < curDoc && (optScorerDoc = optScorer.advance(curDoc)) == NO_MORE_DOCS) {
optScorer = null;
return reqScore * coords[requiredCount];
}
return optScorerDoc == curDoc ? (reqScore + optScorer.score()) * coords[requiredCount + disjunction.freq()] : reqScore * coords[requiredCount];
}
}
}