add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / misc / src / test / org / apache / lucene / index / TestFieldNormModifier.java
1 package org.apache.lucene.index;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements.  See the NOTICE file distributed with
6  * this work for additional information regarding copyright ownership.
7  * The ASF licenses this file to You under the Apache License, Version 2.0
8  * (the "License"); you may not use this file except in compliance with
9  * the License.  You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19
20 import java.io.IOException;
21 import java.util.Arrays;
22
23 import org.apache.lucene.analysis.MockAnalyzer;
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.lucene.search.Collector;
27 import org.apache.lucene.search.DefaultSimilarity;
28 import org.apache.lucene.search.IndexSearcher;
29 import org.apache.lucene.search.Scorer;
30 import org.apache.lucene.search.Similarity;
31 import org.apache.lucene.search.TermQuery;
32 import org.apache.lucene.store.Directory;
33 import org.apache.lucene.util.LuceneTestCase;
34
35 /**
36  * Tests changing of field norms with a custom similarity and with fake norms.
37  */
38 public class TestFieldNormModifier extends LuceneTestCase {
39   public static int NUM_DOCS = 5;
40   
41   public Directory store;
42   
43   /** inverts the normal notion of lengthNorm */
44   public static Similarity s = new DefaultSimilarity() {
45     @Override
46     public float computeNorm(String fieldName, FieldInvertState state) {
47       return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
48     }
49   };
50   
51   @Override
52   public void setUp() throws Exception {
53     super.setUp();
54     store = newDirectory();
55     IndexWriter writer = new IndexWriter(store, newIndexWriterConfig(
56                                                                      TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
57     
58     for (int i = 0; i < NUM_DOCS; i++) {
59       Document d = new Document();
60       d.add(newField("field", "word", Field.Store.YES, Field.Index.ANALYZED));
61       d.add(newField("nonorm", "word", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
62       d.add(newField("untokfield", "20061212 20071212", Field.Store.YES, Field.Index.ANALYZED));
63       
64       for (int j = 1; j <= i; j++) {
65         d.add(newField("field", "crap", Field.Store.YES, Field.Index.ANALYZED));
66         d.add(newField("nonorm", "more words", Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
67       }
68       writer.addDocument(d);
69     }
70     writer.close();
71   }
72   
73   @Override
74   public void tearDown() throws Exception {
75     store.close();
76     super.tearDown();
77   }
78   
79   public void testMissingField() throws Exception {
80     FieldNormModifier fnm = new FieldNormModifier(store, s);
81     try {
82       fnm.reSetNorms("nobodyherebutuschickens");
83     } catch (IllegalStateException e) {
84       // expected
85     }
86   }
87   
88   public void testFieldWithNoNorm() throws Exception {
89     
90     IndexReader r = IndexReader.open(store, false);
91     byte[] norms = r.norms("nonorm");
92     
93     // sanity check, norms should all be 1
94     assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
95     assertNull(norms);
96     
97     r.close();
98     
99     FieldNormModifier fnm = new FieldNormModifier(store, s);
100     try {
101       fnm.reSetNorms("nonorm");
102     } catch (IllegalStateException e) {
103       // expected
104     }
105     
106     // nothing should have changed
107     r = IndexReader.open(store, false);
108     
109     norms = r.norms("nonorm");
110     assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
111     assertNull(norms);
112
113     r.close();
114   }
115   
116   
117   public void testGoodCases() throws Exception {
118     
119     IndexSearcher searcher = new IndexSearcher(store, true);
120     final float[] scores = new float[NUM_DOCS];
121     float lastScore = 0.0f;
122     
123     // default similarity should put docs with shorter length first
124     searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
125       private int docBase = 0;
126       private Scorer scorer;
127       
128       @Override
129       public final void collect(int doc) throws IOException {
130         scores[doc + docBase] = scorer.score();
131       }
132       @Override
133       public void setNextReader(IndexReader reader, int docBase) {
134         this.docBase = docBase;
135       }
136       @Override
137       public void setScorer(Scorer scorer) throws IOException {
138         this.scorer = scorer;
139       }
140       @Override
141       public boolean acceptsDocsOutOfOrder() {
142         return true;
143       }
144     });
145     searcher.close();
146     
147     lastScore = Float.MAX_VALUE;
148     for (int i = 0; i < NUM_DOCS; i++) {
149       String msg = "i=" + i + ", " + scores[i] + " <= " + lastScore;
150       assertTrue(msg, scores[i] <= lastScore);
151       //System.out.println(msg);
152       lastScore = scores[i];
153     }
154
155     FieldNormModifier fnm = new FieldNormModifier(store, s);
156     fnm.reSetNorms("field");
157     
158     // new norm (with default similarity) should put longer docs first
159     searcher = new IndexSearcher(store, true);
160     searcher.search(new TermQuery(new Term("field", "word")),  new Collector() {
161       private int docBase = 0;
162       private Scorer scorer;
163       @Override
164       public final void collect(int doc) throws IOException {
165         scores[doc + docBase] = scorer.score();
166       }
167       @Override
168       public void setNextReader(IndexReader reader, int docBase) {
169         this.docBase = docBase;
170       }
171       @Override
172       public void setScorer(Scorer scorer) throws IOException {
173         this.scorer = scorer;
174       }
175       @Override
176       public boolean acceptsDocsOutOfOrder() {
177         return true;
178       }
179     });
180     searcher.close();
181     
182     lastScore = 0.0f;
183     for (int i = 0; i < NUM_DOCS; i++) {
184       String msg = "i=" + i + ", " + scores[i] + " >= " + lastScore;
185       assertTrue(msg, scores[i] >= lastScore);
186       //System.out.println(msg);
187       lastScore = scores[i];
188     }
189   }
190
191   public void testNormKiller() throws IOException {
192
193     IndexReader r = IndexReader.open(store, false);
194     byte[] oldNorms = r.norms("untokfield");    
195     r.close();
196     
197     FieldNormModifier fnm = new FieldNormModifier(store, s);
198     fnm.reSetNorms("untokfield");
199
200     r = IndexReader.open(store, false);
201     byte[] newNorms = r.norms("untokfield");
202     r.close();
203     assertFalse(Arrays.equals(oldNorms, newNorms));    
204
205     
206     // verify that we still get documents in the same order as originally
207     IndexSearcher searcher = new IndexSearcher(store, true);
208     final float[] scores = new float[NUM_DOCS];
209     float lastScore = 0.0f;
210     
211     // default similarity should return the same score for all documents for this query
212     searcher.search(new TermQuery(new Term("untokfield", "20061212")), new Collector() {
213       private int docBase = 0;
214       private Scorer scorer;
215       @Override
216       public final void collect(int doc) throws IOException {
217         scores[doc + docBase] = scorer.score();
218       }
219       @Override
220       public void setNextReader(IndexReader reader, int docBase) {
221         this.docBase = docBase;
222       }
223       @Override
224       public void setScorer(Scorer scorer) throws IOException {
225         this.scorer = scorer;
226       }
227       @Override
228       public boolean acceptsDocsOutOfOrder() {
229         return true;
230       }
231     });
232     searcher.close();
233     
234     lastScore = scores[0];
235     for (int i = 0; i < NUM_DOCS; i++) {
236       String msg = "i=" + i + ", " + scores[i] + " == " + lastScore;
237       assertTrue(msg, scores[i] == lastScore);
238       //System.out.println(msg);
239       lastScore = scores[i];
240     }
241   }
242 }