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:
Doron Cohen 2007-10-22 09:58:48 +00:00
parent 2f5507bfc9
commit 1df7007219
9 changed files with 75 additions and 44 deletions

View File

@ -127,6 +127,11 @@ Bug fixes
sharing an index over NFS, can be writers in quick succession. sharing an index over NFS, can be writers in quick succession.
(Patrick Kimber vis Mike McCandless) (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 New features
1. LUCENE-906: Elision filter for French. 1. LUCENE-906: Elision filter for French.

View File

@ -89,12 +89,12 @@ public class DisjunctionMaxQuery extends Query {
/* The Weight for DisjunctionMaxQuery's, used to normalize, score and explain these queries */ /* The Weight for DisjunctionMaxQuery's, used to normalize, score and explain these queries */
private class DisjunctionMaxWeight implements Weight { 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 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. */ /* Construct the Weight for this Query searched by searcher. Recursively construct subquery weights. */
public DisjunctionMaxWeight(Searcher searcher) throws IOException { public DisjunctionMaxWeight(Searcher searcher) throws IOException {
this.searcher = searcher; this.similarity = searcher.getSimilarity();
for (int i = 0; i < disjuncts.size(); i++) for (int i = 0; i < disjuncts.size(); i++)
weights.add(((Query) disjuncts.get(i)).createWeight(searcher)); 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 */ /* Create the scorer used to score our associated DisjunctionMaxQuery */
public Scorer scorer(IndexReader reader) throws IOException { 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++) { for (int i = 0 ; i < weights.size(); i++) {
Weight w = (Weight) weights.get(i); Weight w = (Weight) weights.get(i);
Scorer subScorer = w.scorer(reader); Scorer subScorer = w.scorer(reader);

View File

@ -172,13 +172,13 @@ public class CustomScoreQuery extends Query {
//=========================== W E I G H T ============================ //=========================== W E I G H T ============================
private class CustomWeight implements Weight { private class CustomWeight implements Weight {
Searcher searcher; Similarity similarity;
Weight subQueryWeight; Weight subQueryWeight;
Weight valSrcWeight; // optional Weight valSrcWeight; // optional
boolean qStrict; boolean qStrict;
public CustomWeight(Searcher searcher) throws IOException { public CustomWeight(Searcher searcher) throws IOException {
this.searcher = searcher; this.similarity = getSimilarity(searcher);
this.subQueryWeight = subQuery.weight(searcher); this.subQueryWeight = subQuery.weight(searcher);
if (valSrcQuery!=null) { if (valSrcQuery!=null) {
this.valSrcWeight = valSrcQuery.createWeight(searcher); this.valSrcWeight = valSrcQuery.createWeight(searcher);
@ -227,7 +227,7 @@ public class CustomScoreQuery extends Query {
public Scorer scorer(IndexReader reader) throws IOException { public Scorer scorer(IndexReader reader) throws IOException {
Scorer subQueryScorer = subQueryWeight.scorer(reader); Scorer subQueryScorer = subQueryWeight.scorer(reader);
Scorer valSrcScorer = (valSrcWeight==null ? null : valSrcWeight.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) */ /*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */

View File

@ -43,7 +43,6 @@ import org.apache.lucene.search.FieldCache;
*/ */
public abstract class FieldCacheSource extends ValueSource { public abstract class FieldCacheSource extends ValueSource {
private String field; private String field;
private FieldCache cache = FieldCache.DEFAULT;
/** /**
* Create a cached field source for the input field. * 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) */ /* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#getValues(org.apache.lucene.index.IndexReader) */
public final DocValues getValues(IndexReader reader) throws IOException { 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() */ /* (non-Javadoc) @see org.apache.lucene.search.function.ValueSource#description() */
@ -77,7 +76,6 @@ public abstract class FieldCacheSource extends ValueSource {
} }
FieldCacheSource other = (FieldCacheSource) o; FieldCacheSource other = (FieldCacheSource) o;
return return
this.cache == other.cache &&
this.field.equals(other.field) && this.field.equals(other.field) &&
cachedFieldSourceEquals(other); cachedFieldSourceEquals(other);
} }
@ -85,7 +83,6 @@ public abstract class FieldCacheSource extends ValueSource {
/*(non-Javadoc) @see java.lang.Object#hashCode() */ /*(non-Javadoc) @see java.lang.Object#hashCode() */
public final int hashCode() { public final int hashCode() {
return return
cache.hashCode() +
field.hashCode() + field.hashCode() +
cachedFieldSourceHashCode(); cachedFieldSourceHashCode();
} }

View File

@ -62,12 +62,12 @@ public class ValueSourceQuery extends Query {
} }
private class ValueSourceWeight implements Weight { private class ValueSourceWeight implements Weight {
Searcher searcher; Similarity similarity;
float queryNorm; float queryNorm;
float queryWeight; float queryWeight;
public ValueSourceWeight(Searcher searcher) { public ValueSourceWeight(Searcher searcher) {
this.searcher = searcher; this.similarity = getSimilarity(searcher);
} }
/*(non-Javadoc) @see org.apache.lucene.search.Weight#getQuery() */ /*(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) */ /*(non-Javadoc) @see org.apache.lucene.search.Weight#scorer(org.apache.lucene.index.IndexReader) */
public Scorer scorer(IndexReader reader) throws IOException { 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) */ /*(non-Javadoc) @see org.apache.lucene.search.Weight#explain(org.apache.lucene.index.IndexReader, int) */

View File

@ -2,7 +2,11 @@ package org.apache.lucene.search;
import junit.framework.TestCase; import junit.framework.TestCase;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException; import java.io.IOException;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
/** /**
* Copyright 2005 Apache Software Foundation * Copyright 2005 Apache Software Foundation
@ -86,12 +90,38 @@ public class QueryUtils {
checkSkipTo(q1,is); checkSkipTo(q1,is);
} }
checkExplanations(q1,s); checkExplanations(q1,s);
checkSerialization(q1,s);
} }
} catch (IOException e) { } catch (IOException e) {
throw new RuntimeException(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 /** alternate scorer skipTo(),skipTo(),next(),next(),skipTo(),skipTo(), etc
* and ensure a hitcollector receives same docs and scores * and ensure a hitcollector receives same docs and scores
*/ */

View File

@ -19,24 +19,6 @@ package org.apache.lucene.search;
import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.spans.*; 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 * TestExplanations subclass that builds up super crazy complex queries
@ -51,11 +33,16 @@ public class TestComplexExplanations extends TestExplanations {
*/ */
public void setUp() throws Exception { public void setUp() throws Exception {
super.setUp(); 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) { public float queryNorm(float sumOfSquaredWeights) {
return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights); return 1.0f; // / (float) Math.sqrt(1.0f + sumOfSquaredWeights);
} }
}); };
} }

View File

@ -17,7 +17,6 @@ package org.apache.lucene.search;
* limitations under the License. * limitations under the License.
*/ */
import junit.framework.TestCase;
import org.apache.lucene.analysis.WhitespaceAnalyzer; import org.apache.lucene.analysis.WhitespaceAnalyzer;
import org.apache.lucene.document.Document; import org.apache.lucene.document.Document;
import org.apache.lucene.document.Field; 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.index.Term;
import org.apache.lucene.search.BooleanClause.Occur; import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.store.RAMDirectory; import org.apache.lucene.store.RAMDirectory;
import org.apache.lucene.util.LuceneTestCase;
import java.util.BitSet; import java.util.BitSet;
/** /**
@ -38,7 +39,7 @@ import java.util.BitSet;
* @since 1.4 * @since 1.4
*/ */
public class TestFilteredQuery public class TestFilteredQuery
extends TestCase { extends LuceneTestCase {
private IndexSearcher searcher; private IndexSearcher searcher;
private RAMDirectory directory; private RAMDirectory directory;
@ -75,7 +76,12 @@ extends TestCase {
searcher = new IndexSearcher (directory); searcher = new IndexSearcher (directory);
query = new TermQuery (new Term ("field", "three")); 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) { public BitSet bits (IndexReader reader) {
BitSet bitset = new BitSet(5); BitSet bitset = new BitSet(5);
bitset.set (1); bitset.set (1);
@ -120,13 +126,7 @@ extends TestCase {
QueryUtils.check(filteredquery,searcher); QueryUtils.check(filteredquery,searcher);
// test boost // test boost
Filter f = new Filter() { Filter f = newStaticFilterA();
public BitSet bits (IndexReader reader) {
BitSet bitset = new BitSet(5);
bitset.set(0, 5);
return bitset;
}
};
float boost = 2.5f; float boost = 2.5f;
BooleanQuery bq1 = new BooleanQuery(); 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 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. * Tests whether the scores of the two queries are the same.
*/ */

View File

@ -192,7 +192,8 @@ public class TestBoostingTermQuery extends LuceneTestCase {
CheckHits.checkHitCollector(query, "noPayLoad", searcher, results); 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 // TODO: Remove warning after API has been finalized
public float scorePayload(byte[] payload, int offset, int length) { public float scorePayload(byte[] payload, int offset, int length) {