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.
(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.

View File

@ -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);

View File

@ -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) */

View File

@ -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();
}

View File

@ -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) */

View File

@ -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
*/

View File

@ -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);
}
});
};
}

View File

@ -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.
*/

View File

@ -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) {