mirror of https://github.com/apache/lucene.git
LUCENE-1028: Fixed Weight serialization for few queries.
git-svn-id: https://svn.apache.org/repos/asf/lucene/java/trunk@587050 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
parent
2f5507bfc9
commit
1df7007219
|
@ -127,6 +127,11 @@ Bug fixes
|
|||
sharing an index over NFS, can be writers in quick succession.
|
||||
(Patrick Kimber vis Mike McCandless)
|
||||
|
||||
21. LUCENE-1028: Fixed Weight serialization for few queries:
|
||||
DisjunctionMaxQuery, ValueSourceQuery, CustomScoreQuery.
|
||||
Serialization check added for all queries.
|
||||
(Kyle Maxwell via Doron Cohen)
|
||||
|
||||
New features
|
||||
|
||||
1. LUCENE-906: Elision filter for French.
|
||||
|
|
|
@ -89,12 +89,12 @@ public class DisjunctionMaxQuery extends Query {
|
|||
/* The Weight for DisjunctionMaxQuery's, used to normalize, score and explain these queries */
|
||||
private class DisjunctionMaxWeight implements Weight {
|
||||
|
||||
private Searcher searcher; // The searcher with which we are associated.
|
||||
private Similarity similarity; // The similarity which we are associated.
|
||||
private ArrayList weights = new ArrayList(); // The Weight's for our subqueries, in 1-1 correspondence with disjuncts
|
||||
|
||||
/* Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. */
|
||||
public DisjunctionMaxWeight(Searcher searcher) throws IOException {
|
||||
this.searcher = searcher;
|
||||
this.similarity = searcher.getSimilarity();
|
||||
for (int i = 0; i < disjuncts.size(); i++)
|
||||
weights.add(((Query) disjuncts.get(i)).createWeight(searcher));
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ public class DisjunctionMaxQuery extends Query {
|
|||
|
||||
/* Create the scorer used to score our associated DisjunctionMaxQuery */
|
||||
public Scorer scorer(IndexReader reader) throws IOException {
|
||||
DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, getSimilarity(searcher));
|
||||
DisjunctionMaxScorer result = new DisjunctionMaxScorer(tieBreakerMultiplier, similarity);
|
||||
for (int i = 0 ; i < weights.size(); i++) {
|
||||
Weight w = (Weight) weights.get(i);
|
||||
Scorer subScorer = w.scorer(reader);
|
||||
|
|
|
@ -172,13 +172,13 @@ public class CustomScoreQuery extends Query {
|
|||
//=========================== W E I G H T ============================
|
||||
|
||||
private class CustomWeight implements Weight {
|
||||
Searcher searcher;
|
||||
Similarity similarity;
|
||||
Weight subQueryWeight;
|
||||
Weight valSrcWeight; // optional
|
||||
boolean qStrict;
|
||||
|
||||
public CustomWeight(Searcher searcher) throws IOException {
|
||||
this.searcher = searcher;
|
||||
this.similarity = getSimilarity(searcher);
|
||||
this.subQueryWeight = subQuery.weight(searcher);
|
||||
if (valSrcQuery!=null) {
|
||||
this.valSrcWeight = valSrcQuery.createWeight(searcher);
|
||||
|
@ -227,7 +227,7 @@ public class CustomScoreQuery extends Query {
|
|||
public Scorer scorer(IndexReader reader) throws IOException {
|
||||
Scorer subQueryScorer = subQueryWeight.scorer(reader);
|
||||
Scorer valSrcScorer = (valSrcWeight==null ? null : valSrcWeight.scorer(reader));
|
||||
return new CustomScorer(getSimilarity(searcher), reader, this, subQueryScorer, valSrcScorer);
|
||||
return new CustomScorer(similarity, reader, this, subQueryScorer, valSrcScorer);
|
||||
}
|
||||
|
||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
||||
|
|
|
@ -43,7 +43,6 @@ import org.apache.lucene.search.FieldCache;
|
|||
*/
|
||||
public abstract class FieldCacheSource extends ValueSource {
|
||||
private String field;
|
||||
private FieldCache cache = FieldCache.DEFAULT;
|
||||
|
||||
/**
|
||||
* Create a cached field source for the input field.
|
||||
|
@ -54,7 +53,7 @@ public abstract class FieldCacheSource extends ValueSource {
|
|||
|
||||
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#getValues(org.apache.lucene.index.IndexReader) */
|
||||
public final DocValues getValues(IndexReader reader) throws IOException {
|
||||
return getCachedFieldValues(cache, field, reader);
|
||||
return getCachedFieldValues(FieldCache.DEFAULT, field, reader);
|
||||
}
|
||||
|
||||
/* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#description() */
|
||||
|
@ -77,7 +76,6 @@ public abstract class FieldCacheSource extends ValueSource {
|
|||
}
|
||||
FieldCacheSource other = (FieldCacheSource) o;
|
||||
return
|
||||
this.cache == other.cache &&
|
||||
this.field.equals(other.field) &&
|
||||
cachedFieldSourceEquals(other);
|
||||
}
|
||||
|
@ -85,7 +83,6 @@ public abstract class FieldCacheSource extends ValueSource {
|
|||
/*(non-Javadoc) @see java.lang.Object#hashCode() */
|
||||
public final int hashCode() {
|
||||
return
|
||||
cache.hashCode() +
|
||||
field.hashCode() +
|
||||
cachedFieldSourceHashCode();
|
||||
}
|
||||
|
|
|
@ -62,12 +62,12 @@ public class ValueSourceQuery extends Query {
|
|||
}
|
||||
|
||||
private class ValueSourceWeight implements Weight {
|
||||
Searcher searcher;
|
||||
Similarity similarity;
|
||||
float queryNorm;
|
||||
float queryWeight;
|
||||
|
||||
public ValueSourceWeight(Searcher searcher) {
|
||||
this.searcher = searcher;
|
||||
this.similarity = getSimilarity(searcher);
|
||||
}
|
||||
|
||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */
|
||||
|
@ -94,7 +94,7 @@ public class ValueSourceQuery extends Query {
|
|||
|
||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */
|
||||
public Scorer scorer(IndexReader reader) throws IOException {
|
||||
return new ValueSourceScorer(getSimilarity(searcher), reader, this);
|
||||
return new ValueSourceScorer(similarity, reader, this);
|
||||
}
|
||||
|
||||
/*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */
|
||||
|
|
|
@ -2,7 +2,11 @@ package org.apache.lucene.search;
|
|||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.ObjectInputStream;
|
||||
import java.io.ObjectOutputStream;
|
||||
|
||||
/**
|
||||
* Copyright 2005 Apache Software Foundation
|
||||
|
@ -86,12 +90,38 @@ public class QueryUtils {
|
|||
checkSkipTo(q1,is);
|
||||
}
|
||||
checkExplanations(q1,s);
|
||||
checkSerialization(q1,s);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new RuntimeException(e);
|
||||
}
|
||||
}
|
||||
|
||||
/** check that the query weight is serializable.
|
||||
* @throws IOException if serialization check fail.
|
||||
*/
|
||||
private static void checkSerialization(Query q, Searcher s) throws IOException {
|
||||
Weight w = q.weight(s);
|
||||
try {
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
ObjectOutputStream oos = new ObjectOutputStream(bos);
|
||||
oos.writeObject(w);
|
||||
oos.close();
|
||||
ObjectInputStream ois = new ObjectInputStream(new ByteArrayInputStream(bos.toByteArray()));
|
||||
Weight w2 = (Weight) ois.readObject();
|
||||
ois.close();
|
||||
|
||||
//skip rquals() test for now - most weights don't overide equals() and we won't add this just for the tests.
|
||||
//TestCase.assertEquals("writeObject(w) != w. ("+w+")",w2,w);
|
||||
|
||||
} catch (Exception e) {
|
||||
IOException e2 = new IOException("Serialization failed for "+w);
|
||||
e2.initCause(e);
|
||||
throw e2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc
|
||||
* and ensure a hitcollector receives same docs and scores
|
||||
*/
|
||||
|
|
|
@ -19,24 +19,6 @@ package org.apache.lucene.search;
|
|||
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.search.spans.*;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
|
||||
import org.apache.lucene.index.IndexWriter;
|
||||
import org.apache.lucene.index.IndexReader;
|
||||
import org.apache.lucene.index.Term;
|
||||
|
||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
|
||||
import org.apache.lucene.queryParser.QueryParser;
|
||||
import org.apache.lucene.queryParser.ParseException;
|
||||
|
||||
import junit.framework.TestCase;
|
||||
|
||||
import java.util.Random;
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
* TestExplanations subclass that builds up super crazy complex queries
|
||||
|
@ -51,11 +33,16 @@ public class TestComplexExplanations extends TestExplanations {
|
|||
*/
|
||||
public void setUp() throws Exception {
|
||||
super.setUp();
|
||||
searcher.setSimilarity(new DefaultSimilarity() {
|
||||
searcher.setSimilarity(createQnorm1Similarity());
|
||||
}
|
||||
|
||||
// must be static for weight serialization tests
|
||||
private static DefaultSimilarity createQnorm1Similarity() {
|
||||
return new DefaultSimilarity() {
|
||||
public float queryNorm(float sumOfSquaredWeights) {
|
||||
return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
|
||||
}
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -17,7 +17,6 @@ package org.apache.lucene.search;
|
|||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import junit.framework.TestCase;
|
||||
import org.apache.lucene.analysis.WhitespaceAnalyzer;
|
||||
import org.apache.lucene.document.Document;
|
||||
import org.apache.lucene.document.Field;
|
||||
|
@ -26,6 +25,8 @@ import org.apache.lucene.index.IndexReader;
|
|||
import org.apache.lucene.index.Term;
|
||||
import org.apache.lucene.search.BooleanClause.Occur;
|
||||
import org.apache.lucene.store.RAMDirectory;
|
||||
import org.apache.lucene.util.LuceneTestCase;
|
||||
|
||||
import java.util.BitSet;
|
||||
|
||||
/**
|
||||
|
@ -38,7 +39,7 @@ import java.util.BitSet;
|
|||
* @since 1.4
|
||||
*/
|
||||
public class TestFilteredQuery
|
||||
extends TestCase {
|
||||
extends LuceneTestCase {
|
||||
|
||||
private IndexSearcher searcher;
|
||||
private RAMDirectory directory;
|
||||
|
@ -75,7 +76,12 @@ extends TestCase {
|
|||
|
||||
searcher = new IndexSearcher (directory);
|
||||
query = new TermQuery (new Term ("field", "three"));
|
||||
filter = new Filter() {
|
||||
filter = newStaticFilterB();
|
||||
}
|
||||
|
||||
// must be static for serialization tests
|
||||
private static Filter newStaticFilterB() {
|
||||
return new Filter() {
|
||||
public BitSet bits (IndexReader reader) {
|
||||
BitSet bitset = new BitSet(5);
|
||||
bitset.set (1);
|
||||
|
@ -120,13 +126,7 @@ extends TestCase {
|
|||
QueryUtils.check(filteredquery,searcher);
|
||||
|
||||
// test boost
|
||||
Filter f = new Filter() {
|
||||
public BitSet bits (IndexReader reader) {
|
||||
BitSet bitset = new BitSet(5);
|
||||
bitset.set(0, 5);
|
||||
return bitset;
|
||||
}
|
||||
};
|
||||
Filter f = newStaticFilterA();
|
||||
|
||||
float boost = 2.5f;
|
||||
BooleanQuery bq1 = new BooleanQuery();
|
||||
|
@ -147,6 +147,17 @@ extends TestCase {
|
|||
assertEquals(1.0f, tq.getBoost(), 0); // the boost value of the underlying query shouldn't have changed
|
||||
}
|
||||
|
||||
// must be static for serialization tests
|
||||
private static Filter newStaticFilterA() {
|
||||
return new Filter() {
|
||||
public BitSet bits (IndexReader reader) {
|
||||
BitSet bitset = new BitSet(5);
|
||||
bitset.set(0, 5);
|
||||
return bitset;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* Tests whether the scores of the two queries are the same.
|
||||
*/
|
||||
|
|
|
@ -192,7 +192,8 @@ public class TestBoostingTermQuery extends LuceneTestCase {
|
|||
CheckHits.checkHitCollector(query, "noPayLoad", searcher, results);
|
||||
}
|
||||
|
||||
class BoostingSimilarity extends DefaultSimilarity {
|
||||
// must be static for weight serialization tests
|
||||
static class BoostingSimilarity extends DefaultSimilarity {
|
||||
|
||||
// TODO: Remove warning after API has been finalized
|
||||
public float scorePayload(byte[] payload, int offset, int length) {
|
||||
|
|
Loading…
Reference in New Issue