~slub.team/goobi-indexserver/3.x

« back to all changes in this revision

Viewing changes to lucene/src/test/org/apache/lucene/index/TestNorms.java

  • Committer: Sebastian Meyer
  • Date: 2012-08-03 09:12:40 UTC
  • Revision ID: sebastian.meyer@slub-dresden.de-20120803091240-x6861b0vabq1xror
Remove Lucene and Solr source code and add patches instead
Fix Bug #985487: Auto-suggestion for the search interface

Show diffs side-by-side

added added

removed removed

Lines of Context:
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.ArrayList;
22
 
import java.util.Random;
23
 
 
24
 
import org.apache.lucene.analysis.Analyzer;
25
 
import org.apache.lucene.analysis.MockAnalyzer;
26
 
import org.apache.lucene.document.Document;
27
 
import org.apache.lucene.document.Field;
28
 
import org.apache.lucene.document.Field.Index;
29
 
import org.apache.lucene.document.Field.Store;
30
 
import org.apache.lucene.index.IndexWriterConfig.OpenMode;
31
 
import org.apache.lucene.search.DefaultSimilarity;
32
 
import org.apache.lucene.search.Similarity;
33
 
import org.apache.lucene.store.Directory;
34
 
import org.apache.lucene.util.LuceneTestCase;
35
 
 
36
 
/**
37
 
 * Test that norms info is preserved during index life - including
38
 
 * separate norms, addDocument, addIndexes, forceMerge.
39
 
 */
40
 
public class TestNorms extends LuceneTestCase {
41
 
 
42
 
  private class SimilarityOne extends DefaultSimilarity {
43
 
    @Override
44
 
    public float computeNorm(String fieldName, FieldInvertState state) {
45
 
      // Disable length norm
46
 
      return state.getBoost();
47
 
    }
48
 
  }
49
 
 
50
 
  private static final int NUM_FIELDS = 10;
51
 
  
52
 
  private Similarity similarityOne;
53
 
  private Analyzer anlzr;
54
 
  private int numDocNorms;
55
 
  private ArrayList<Float> norms; 
56
 
  private ArrayList<Float> modifiedNorms; 
57
 
  private float lastNorm = 0;
58
 
  private float normDelta = (float) 0.001;
59
 
 
60
 
  @Override
61
 
  public void setUp() throws Exception {
62
 
    super.setUp();
63
 
    similarityOne = new SimilarityOne();
64
 
    anlzr = new MockAnalyzer(random);
65
 
  }
66
 
 
67
 
  /**
68
 
   * Test that norms values are preserved as the index is maintained.
69
 
   * Including separate norms.
70
 
   * Including merging indexes with seprate norms. 
71
 
   * Including forceMerge. 
72
 
   */
73
 
  public void testNorms() throws IOException {
74
 
    Directory dir1 = newDirectory();
75
 
 
76
 
    norms = new ArrayList<Float>();
77
 
    modifiedNorms = new ArrayList<Float>();
78
 
 
79
 
    createIndex(random, dir1);
80
 
    doTestNorms(random, dir1);
81
 
 
82
 
    // test with a single index: index2
83
 
    ArrayList<Float> norms1 = norms;
84
 
    ArrayList<Float> modifiedNorms1 = modifiedNorms;
85
 
    int numDocNorms1 = numDocNorms;
86
 
 
87
 
    norms = new ArrayList<Float>();
88
 
    modifiedNorms = new ArrayList<Float>();
89
 
    numDocNorms = 0;
90
 
    
91
 
    Directory dir2 = newDirectory();
92
 
 
93
 
    createIndex(random, dir2);
94
 
    doTestNorms(random, dir2);
95
 
 
96
 
    // add index1 and index2 to a third index: index3
97
 
    Directory dir3 = newDirectory();
98
 
 
99
 
    createIndex(random, dir3);
100
 
    IndexWriter iw = new IndexWriter(dir3, newIndexWriterConfig(
101
 
        TEST_VERSION_CURRENT, anlzr).setOpenMode(OpenMode.APPEND)
102
 
                                     .setMaxBufferedDocs(5).setMergePolicy(newLogMergePolicy(3)));
103
 
    iw.addIndexes(new Directory[]{dir1,dir2});
104
 
    iw.forceMerge(1);
105
 
    iw.close();
106
 
    
107
 
    norms1.addAll(norms);
108
 
    norms = norms1;
109
 
    modifiedNorms1.addAll(modifiedNorms);
110
 
    modifiedNorms = modifiedNorms1;
111
 
    numDocNorms += numDocNorms1;
112
 
 
113
 
    // test with index3
114
 
    verifyIndex(dir3);
115
 
    doTestNorms(random, dir3);
116
 
    
117
 
    // now with single segment
118
 
    iw = new IndexWriter(dir3, newIndexWriterConfig( TEST_VERSION_CURRENT,
119
 
        anlzr).setOpenMode(OpenMode.APPEND).setMaxBufferedDocs(5).setMergePolicy(newLogMergePolicy(3)));
120
 
    iw.forceMerge(1);
121
 
    iw.close();
122
 
    verifyIndex(dir3);
123
 
    
124
 
    dir1.close();
125
 
    dir2.close();
126
 
    dir3.close();
127
 
  }
128
 
 
129
 
  private void doTestNorms(Random random, Directory dir) throws IOException {
130
 
    int num = atLeast(1);
131
 
    for (int i=0; i<num; i++) {
132
 
      addDocs(random, dir,12,true);
133
 
      verifyIndex(dir);
134
 
      modifyNormsForF1(dir);
135
 
      verifyIndex(dir);
136
 
      addDocs(random, dir,12,false);
137
 
      verifyIndex(dir);
138
 
      modifyNormsForF1(dir);
139
 
      verifyIndex(dir);
140
 
    }
141
 
  }
142
 
 
143
 
  private void createIndex(Random random, Directory dir) throws IOException {
144
 
    IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(
145
 
        TEST_VERSION_CURRENT, anlzr).setOpenMode(OpenMode.CREATE)
146
 
        .setMaxBufferedDocs(5).setSimilarity(similarityOne).setMergePolicy(newLogMergePolicy()));
147
 
    LogMergePolicy lmp = (LogMergePolicy) iw.getConfig().getMergePolicy();
148
 
    lmp.setMergeFactor(3);
149
 
    lmp.setUseCompoundFile(true);
150
 
    iw.close();
151
 
  }
152
 
 
153
 
  private void modifyNormsForF1(Directory dir) throws IOException {
154
 
    IndexReader ir = IndexReader.open(dir, false);
155
 
    int n = ir.maxDoc();
156
 
    for (int i = 0; i < n; i+=3) { // modify for every third doc
157
 
      int k = (i*3) % modifiedNorms.size();
158
 
      float origNorm = modifiedNorms.get(i).floatValue();
159
 
      float newNorm = modifiedNorms.get(k).floatValue();
160
 
      //System.out.println("Modifying: for "+i+" from "+origNorm+" to "+newNorm);
161
 
      //System.out.println("      and: for "+k+" from "+newNorm+" to "+origNorm);
162
 
      modifiedNorms.set(i, Float.valueOf(newNorm));
163
 
      modifiedNorms.set(k, Float.valueOf(origNorm));
164
 
      ir.setNorm(i, "f"+1, newNorm); 
165
 
      ir.setNorm(k, "f"+1, origNorm); 
166
 
    }
167
 
    ir.close();
168
 
  }
169
 
 
170
 
 
171
 
  private void verifyIndex(Directory dir) throws IOException {
172
 
    IndexReader ir = IndexReader.open(dir, false);
173
 
    for (int i = 0; i < NUM_FIELDS; i++) {
174
 
      String field = "f"+i;
175
 
      byte b[] = ir.norms(field);
176
 
      assertEquals("number of norms mismatches",numDocNorms,b.length);
177
 
      ArrayList<Float> storedNorms = (i==1 ? modifiedNorms : norms);
178
 
      for (int j = 0; j < b.length; j++) {
179
 
        float norm = similarityOne.decodeNormValue(b[j]);
180
 
        float norm1 = storedNorms.get(j).floatValue();
181
 
        assertEquals("stored norm value of "+field+" for doc "+j+" is "+norm+" - a mismatch!", norm, norm1, 0.000001);
182
 
      }
183
 
    }
184
 
    ir.close();
185
 
  }
186
 
 
187
 
  private void addDocs(Random random, Directory dir, int ndocs, boolean compound) throws IOException {
188
 
    IndexWriter iw = new IndexWriter(dir, newIndexWriterConfig(
189
 
        TEST_VERSION_CURRENT, anlzr).setOpenMode(OpenMode.APPEND)
190
 
        .setMaxBufferedDocs(5).setSimilarity(similarityOne).setMergePolicy(newLogMergePolicy()));
191
 
    LogMergePolicy lmp = (LogMergePolicy) iw.getConfig().getMergePolicy();
192
 
    lmp.setMergeFactor(3);
193
 
    lmp.setUseCompoundFile(compound);
194
 
    for (int i = 0; i < ndocs; i++) {
195
 
      iw.addDocument(newDoc());
196
 
    }
197
 
    iw.close();
198
 
  }
199
 
 
200
 
  // create the next document
201
 
  private Document newDoc() {
202
 
    Document d = new Document();
203
 
    float boost = nextNorm();
204
 
    for (int i = 0; i < 10; i++) {
205
 
      Field f = newField("f"+i,"v"+i,Store.NO,Index.NOT_ANALYZED);
206
 
      f.setBoost(boost);
207
 
      d.add(f);
208
 
    }
209
 
    return d;
210
 
  }
211
 
 
212
 
  // return unique norm values that are unchanged by encoding/decoding
213
 
  private float nextNorm() {
214
 
    float norm = lastNorm + normDelta;
215
 
    do {
216
 
      float norm1 = similarityOne.decodeNormValue(similarityOne.encodeNormValue(norm));
217
 
      if (norm1 > lastNorm) {
218
 
        //System.out.println(norm1+" > "+lastNorm);
219
 
        norm = norm1;
220
 
        break;
221
 
      }
222
 
      norm += normDelta;
223
 
    } while (true);
224
 
    norms.add(numDocNorms, Float.valueOf(norm));
225
 
    modifiedNorms.add(numDocNorms, Float.valueOf(norm));
226
 
    //System.out.println("creating norm("+numDocNorms+"): "+norm);
227
 
    numDocNorms ++;
228
 
    lastNorm = (norm>10 ? 0 : norm); //there's a limit to how many distinct values can be stored in a ingle byte
229
 
    return norm;
230
 
  }
231
 
  
232
 
  class CustomNormEncodingSimilarity extends DefaultSimilarity {
233
 
    @Override
234
 
    public byte encodeNormValue(float f) {
235
 
      return (byte) f;
236
 
    }
237
 
    
238
 
    @Override
239
 
    public float decodeNormValue(byte b) {
240
 
      return (float) b;
241
 
    }
242
 
 
243
 
    @Override
244
 
    public float computeNorm(String field, FieldInvertState state) {
245
 
      return (float) state.getLength();
246
 
    }
247
 
  }
248
 
  
249
 
  // LUCENE-1260
250
 
  public void testCustomEncoder() throws Exception {
251
 
    Directory dir = newDirectory();
252
 
    IndexWriterConfig config = newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random));
253
 
    config.setSimilarity(new CustomNormEncodingSimilarity());
254
 
    RandomIndexWriter writer = new RandomIndexWriter(random, dir, config);
255
 
    Document doc = new Document();
256
 
    Field foo = newField("foo", "", Field.Store.NO, Field.Index.ANALYZED);
257
 
    Field bar = newField("bar", "", Field.Store.NO, Field.Index.ANALYZED);
258
 
    doc.add(foo);
259
 
    doc.add(bar);
260
 
    
261
 
    for (int i = 0; i < 100; i++) {
262
 
      bar.setValue("singleton");
263
 
      writer.addDocument(doc);
264
 
    }
265
 
    
266
 
    IndexReader reader = writer.getReader();
267
 
    writer.close();
268
 
    
269
 
    byte fooNorms[] = reader.norms("foo");
270
 
    for (int i = 0; i < reader.maxDoc(); i++)
271
 
      assertEquals(0, fooNorms[i]);
272
 
    
273
 
    byte barNorms[] = reader.norms("bar");
274
 
    for (int i = 0; i < reader.maxDoc(); i++)
275
 
      assertEquals(1, barNorms[i]);
276
 
    
277
 
    reader.close();
278
 
    dir.close();
279
 
  }
280
 
}