Fix RandomApproximationQuery to not share Random instances across threads.

git-svn-id: https://svn.apache.org/repos/asf/lucene/dev/trunk@1660415 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Adrien Grand 2015-02-17 15:31:34 +00:00
parent 0c483c6cd5
commit 456187051b
1 changed files with 92 additions and 71 deletions

View File

@ -76,91 +76,112 @@ public class RandomApproximationQuery extends Query {
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores) throws IOException {
final Weight weight = query.createWeight(searcher, needsScores);
return new Weight(RandomApproximationQuery.this) {
return new RandomApproximationWeight(weight, new Random(random.nextLong()));
}
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return weight.explain(context, doc);
private static class RandomApproximationWeight extends Weight {
private final Weight weight;
private final Random random;
RandomApproximationWeight(Weight weight, Random random) {
super(weight.getQuery());
this.weight = weight;
this.random = random;
}
@Override
public Explanation explain(LeafReaderContext context, int doc) throws IOException {
return weight.explain(context, doc);
}
@Override
public float getValueForNormalization() throws IOException {
return weight.getValueForNormalization();
}
@Override
public void normalize(float norm, float topLevelBoost) {
weight.normalize(norm, topLevelBoost);
}
@Override
public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
final Scorer scorer = weight.scorer(context, acceptDocs);
if (scorer == null) {
return null;
}
return new RandomApproximationScorer(scorer, new Random(random.nextLong()));
}
@Override
public float getValueForNormalization() throws IOException {
return weight.getValueForNormalization();
}
}
@Override
public void normalize(float norm, float topLevelBoost) {
weight.normalize(norm, topLevelBoost);
}
private static class RandomApproximationScorer extends Scorer {
@Override
public Scorer scorer(LeafReaderContext context, Bits acceptDocs) throws IOException {
final Scorer scorer = weight.scorer(context, acceptDocs);
if (scorer == null) {
return null;
}
final RandomTwoPhaseView twoPhaseView = new RandomTwoPhaseView(random, scorer);
return new Scorer(this) {
private final Scorer scorer;
private final RandomTwoPhaseView twoPhaseView;
@Override
public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
return twoPhaseView;
}
RandomApproximationScorer(Scorer scorer, Random random) {
super(scorer.getWeight());
this.scorer = scorer;
this.twoPhaseView = new RandomTwoPhaseView(random, scorer);
}
@Override
public float score() throws IOException {
return scorer.score();
}
@Override
public TwoPhaseDocIdSetIterator asTwoPhaseIterator() {
return twoPhaseView;
}
@Override
public int freq() throws IOException {
return scorer.freq();
}
@Override
public float score() throws IOException {
return scorer.score();
}
@Override
public int nextPosition() throws IOException {
return scorer.nextPosition();
}
@Override
public int freq() throws IOException {
return scorer.freq();
}
@Override
public int startOffset() throws IOException {
return scorer.startOffset();
}
@Override
public int nextPosition() throws IOException {
return scorer.nextPosition();
}
@Override
public int endOffset() throws IOException {
return scorer.endOffset();
}
@Override
public int startOffset() throws IOException {
return scorer.startOffset();
}
@Override
public BytesRef getPayload() throws IOException {
return scorer.getPayload();
}
@Override
public int endOffset() throws IOException {
return scorer.endOffset();
}
@Override
public int docID() {
return scorer.docID();
}
@Override
public BytesRef getPayload() throws IOException {
return scorer.getPayload();
}
@Override
public int nextDoc() throws IOException {
return scorer.nextDoc();
}
@Override
public int docID() {
return scorer.docID();
}
@Override
public int advance(int target) throws IOException {
return scorer.advance(target);
}
@Override
public int nextDoc() throws IOException {
return scorer.nextDoc();
}
@Override
public long cost() {
return scorer.cost();
}
};
}
@Override
public int advance(int target) throws IOException {
return scorer.advance(target);
}
@Override
public long cost() {
return scorer.cost();
}
};
}
private static class RandomTwoPhaseView extends TwoPhaseDocIdSetIterator {
@ -182,7 +203,7 @@ public class RandomApproximationQuery extends Query {
public boolean matches() throws IOException {
return approximation.doc == disi.docID();
}
}
private static class RandomApproximation extends DocIdSetIterator {
@ -191,7 +212,7 @@ public class RandomApproximationQuery extends Query {
private final DocIdSetIterator disi;
int doc = -1;
public RandomApproximation(Random random, DocIdSetIterator disi) {
this.random = random;
this.disi = disi;
@ -201,7 +222,7 @@ public class RandomApproximationQuery extends Query {
public int docID() {
return doc;
}
@Override
public int nextDoc() throws IOException {
return advance(doc + 1);