add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / contrib / misc / src / test / org / apache / lucene / misc / TestLengthNormModifier.java
1 package org.apache.lucene.misc;
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
22 import org.apache.lucene.analysis.MockAnalyzer;
23 import org.apache.lucene.document.Document;
24 import org.apache.lucene.document.Field;
25 import org.apache.lucene.index.FieldInvertState;
26 import org.apache.lucene.index.FieldNormModifier;
27 import org.apache.lucene.index.IndexReader;
28 import org.apache.lucene.index.IndexWriter;
29 import org.apache.lucene.index.Term;
30 import org.apache.lucene.search.Collector;
31 import org.apache.lucene.search.DefaultSimilarity;
32 import org.apache.lucene.search.IndexSearcher;
33 import org.apache.lucene.search.Scorer;
34 import org.apache.lucene.search.Similarity;
35 import org.apache.lucene.search.TermQuery;
36 import org.apache.lucene.store.Directory;
37 import org.apache.lucene.util.LuceneTestCase;
38
39 /**
40  * Tests changing the norms after changing the simularity
41  */
42 public class TestLengthNormModifier extends LuceneTestCase {
43     public static int NUM_DOCS = 5;
44
45     public Directory store;
46
47     /** inverts the normal notion of lengthNorm */
48     public static Similarity s = new DefaultSimilarity() {
49         @Override
50         public float computeNorm(String fieldName, FieldInvertState state) {
51           return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
52         }
53       };
54     
55     @Override
56     public void setUp() throws Exception {
57       super.setUp();
58       store = newDirectory();
59         IndexWriter writer = new IndexWriter(store, newIndexWriterConfig(
60                                                                          TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
61         
62         for (int i = 0; i < NUM_DOCS; i++) {
63             Document d = new Document();
64             d.add(newField("field", "word",
65                             Field.Store.YES, Field.Index.ANALYZED));
66             d.add(newField("nonorm", "word",
67                             Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
68                 
69             for (int j = 1; j <= i; j++) {
70                 d.add(newField("field", "crap",
71                                 Field.Store.YES, Field.Index.ANALYZED));
72                 d.add(newField("nonorm", "more words",
73                                 Field.Store.YES, Field.Index.NOT_ANALYZED_NO_NORMS));
74             }
75             writer.addDocument(d);
76         }
77         writer.close();
78     }
79     
80     @Override
81     public void tearDown() throws Exception {
82       store.close();
83       super.tearDown();
84     }
85     
86     public void testMissingField() throws Exception {
87         FieldNormModifier fnm = new FieldNormModifier(store, s);
88         try {
89             fnm.reSetNorms("nobodyherebutuschickens");
90         } catch (IllegalStateException e) {
91             // expected
92         }
93     }
94         
95     public void testFieldWithNoNorm() throws Exception {
96
97         IndexReader r = IndexReader.open(store, false);
98         byte[] norms = r.norms("nonorm");
99
100         // sanity check, norms should all be 1
101         assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
102         assertNull(norms);
103
104         r.close();
105         
106         FieldNormModifier fnm = new FieldNormModifier(store, s);
107         try {
108             fnm.reSetNorms("nonorm");
109         } catch (IllegalStateException e) {
110           // expected
111         }
112
113         // nothing should have changed
114         r = IndexReader.open(store, false);
115         
116         norms = r.norms("nonorm");
117         assertTrue("Whoops we have norms?", !r.hasNorms("nonorm"));
118   assertNull(norms);
119
120         r.close();
121         
122     }
123         
124     
125     public void testGoodCases() throws Exception {
126         
127         IndexSearcher searcher;
128         final float[] scores = new float[NUM_DOCS];
129         float lastScore = 0.0f;
130         
131         // default similarity should put docs with shorter length first
132   searcher = new IndexSearcher(store, false);
133   searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
134     private int docBase = 0;
135     private Scorer scorer;
136     @Override
137     public final void collect(int doc) throws IOException {
138       scores[doc + docBase] = scorer.score();
139     }
140     @Override
141     public void setNextReader(IndexReader reader, int docBase) {
142       this.docBase = docBase;
143     }
144     @Override
145     public void setScorer(Scorer scorer) throws IOException {
146       this.scorer = scorer;
147     }
148     @Override
149     public boolean acceptsDocsOutOfOrder() {
150       return true;
151     }
152   });
153   searcher.close();
154         
155         lastScore = Float.MAX_VALUE;
156         for (int i = 0; i < NUM_DOCS; i++) {
157             String msg = "i=" + i + ", "+scores[i]+" <= "+lastScore;
158             assertTrue(msg, scores[i] <= lastScore);
159             //System.out.println(msg);
160             lastScore = scores[i];
161         }
162
163         // override the norms to be inverted
164         Similarity s = new DefaultSimilarity() {
165             @Override
166             public float computeNorm(String fieldName, FieldInvertState state) {
167               return state.getBoost() * (discountOverlaps ? state.getLength() - state.getNumOverlap() : state.getLength());
168             }
169           };
170         FieldNormModifier fnm = new FieldNormModifier(store, s);
171         fnm.reSetNorms("field");
172
173         // new norm (with default similarity) should put longer docs first
174         searcher = new IndexSearcher(store, false);
175         searcher.search(new TermQuery(new Term("field", "word")), new Collector() {
176       private int docBase = 0;
177       private Scorer scorer;
178       @Override
179       public final void collect(int doc) throws IOException {
180         scores[doc + docBase] = scorer.score();
181       }
182       @Override
183       public void setNextReader(IndexReader reader, int docBase) {
184         this.docBase = docBase;
185       }
186       @Override
187       public void setScorer(Scorer scorer) throws IOException {
188         this.scorer = scorer;
189       }
190       @Override
191       public boolean acceptsDocsOutOfOrder() {
192         return true;
193       }
194     });
195     searcher.close();
196         
197         lastScore = 0.0f;
198         for (int i = 0; i < NUM_DOCS; i++) {
199             String msg = "i=" + i + ", "+scores[i]+" >= "+lastScore;
200             assertTrue(msg, scores[i] >= lastScore);
201             //System.out.println(msg);
202             lastScore = scores[i];
203         }
204         
205     }
206 }