pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / test / org / apache / lucene / index / TestIndexWriterMerging.java
1 package org.apache.lucene.index;
2 /**
3  * Copyright 2006 The Apache Software Foundation
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17
18 import org.apache.lucene.store.Directory;
19 import org.apache.lucene.analysis.MockAnalyzer;
20 import org.apache.lucene.document.Document;
21 import org.apache.lucene.document.Field;
22 import org.apache.lucene.document.Field.Index;
23 import org.apache.lucene.document.Field.Store;
24 import org.apache.lucene.document.Field.TermVector;
25 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
26 import org.apache.lucene.util.LuceneTestCase;
27
28 import java.io.IOException;
29 import java.util.Random;
30
31
32 public class TestIndexWriterMerging extends LuceneTestCase
33 {
34
35   /**
36    * Tests that index merging (specifically addIndexes(Directory...)) doesn't
37    * change the index order of documents.
38    */
39   public void testLucene() throws IOException {
40     int num=100;
41
42     Directory indexA = newDirectory();
43     Directory indexB = newDirectory();
44
45     fillIndex(random, indexA, 0, num);
46     boolean fail = verifyIndex(indexA, 0);
47     if (fail)
48     {
49       fail("Index a is invalid");
50     }
51
52     fillIndex(random, indexB, num, num);
53     fail = verifyIndex(indexB, num);
54     if (fail)
55     {
56       fail("Index b is invalid");
57     }
58
59     Directory merged = newDirectory();
60
61     IndexWriter writer = new IndexWriter(
62         merged,
63         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
64             setMergePolicy(newLogMergePolicy(2))
65     );
66     writer.setInfoStream(VERBOSE ? System.out : null);
67     writer.addIndexes(new Directory[]{indexA, indexB});
68     writer.forceMerge(1);
69     writer.close();
70
71     fail = verifyIndex(merged, 0);
72
73     assertFalse("The merged index is invalid", fail);
74     indexA.close();
75     indexB.close();
76     merged.close();
77   }
78
79   private boolean verifyIndex(Directory directory, int startAt) throws IOException
80   {
81     boolean fail = false;
82     IndexReader reader = IndexReader.open(directory, true);
83
84     int max = reader.maxDoc();
85     for (int i = 0; i < max; i++)
86     {
87       Document temp = reader.document(i);
88       //System.out.println("doc "+i+"="+temp.getField("count").stringValue());
89       //compare the index doc number to the value that it should be
90       if (!temp.getField("count").stringValue().equals((i + startAt) + ""))
91       {
92         fail = true;
93         System.out.println("Document " + (i + startAt) + " is returning document " + temp.getField("count").stringValue());
94       }
95     }
96     reader.close();
97     return fail;
98   }
99
100   private void fillIndex(Random random, Directory dir, int start, int numDocs) throws IOException {
101
102     IndexWriter writer = new IndexWriter(
103         dir,
104         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
105             setOpenMode(OpenMode.CREATE).
106             setMaxBufferedDocs(2).
107             setMergePolicy(newLogMergePolicy(2))
108     );
109
110     for (int i = start; i < (start + numDocs); i++)
111     {
112       Document temp = new Document();
113       temp.add(newField("count", (""+i), Field.Store.YES, Field.Index.NOT_ANALYZED));
114
115       writer.addDocument(temp);
116     }
117     writer.close();
118   }
119   
120   // LUCENE-325: test forceMergeDeletes, when 2 singular merges
121   // are required
122   public void testForceMergeDeletes() throws IOException {
123     Directory dir = newDirectory();
124     IndexWriter writer = new IndexWriter(dir, newIndexWriterConfig(
125         TEST_VERSION_CURRENT, new MockAnalyzer(random))
126         .setMaxBufferedDocs(2).setRAMBufferSizeMB(
127                                                   IndexWriterConfig.DISABLE_AUTO_FLUSH));
128     writer.setInfoStream(VERBOSE ? System.out : null);
129     Document document = new Document();
130
131     document = new Document();
132     Field storedField = newField("stored", "stored", Field.Store.YES,
133                                   Field.Index.NO);
134     document.add(storedField);
135     Field termVectorField = newField("termVector", "termVector",
136                                       Field.Store.NO, Field.Index.NOT_ANALYZED,
137                                       Field.TermVector.WITH_POSITIONS_OFFSETS);
138     document.add(termVectorField);
139     for(int i=0;i<10;i++)
140       writer.addDocument(document);
141     writer.close();
142
143     IndexReader ir = IndexReader.open(dir, false);
144     assertEquals(10, ir.maxDoc());
145     assertEquals(10, ir.numDocs());
146     ir.deleteDocument(0);
147     ir.deleteDocument(7);
148     assertEquals(8, ir.numDocs());
149     ir.close();
150
151     writer = new IndexWriter(dir, newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).setMergePolicy(newLogMergePolicy()));
152     assertEquals(8, writer.numDocs());
153     assertEquals(10, writer.maxDoc());
154     writer.forceMergeDeletes();
155     assertEquals(8, writer.numDocs());
156     writer.close();
157     ir = IndexReader.open(dir, true);
158     assertEquals(8, ir.maxDoc());
159     assertEquals(8, ir.numDocs());
160     ir.close();
161     dir.close();
162   }
163
164   // LUCENE-325: test forceMergeDeletes, when many adjacent merges are required
165   public void testForceMergeDeletes2() throws IOException {
166     Directory dir = newDirectory();
167     IndexWriter writer = new IndexWriter(
168         dir,
169         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
170             setMaxBufferedDocs(2).
171             setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH).
172             setMergePolicy(newLogMergePolicy(50))
173     );
174
175     Document document = new Document();
176
177     document = new Document();
178     Field storedField = newField("stored", "stored", Store.YES,
179                                   Index.NO);
180     document.add(storedField);
181     Field termVectorField = newField("termVector", "termVector",
182                                       Store.NO, Index.NOT_ANALYZED,
183                                       TermVector.WITH_POSITIONS_OFFSETS);
184     document.add(termVectorField);
185     for(int i=0;i<98;i++)
186       writer.addDocument(document);
187     writer.close();
188
189     IndexReader ir = IndexReader.open(dir, false);
190     assertEquals(98, ir.maxDoc());
191     assertEquals(98, ir.numDocs());
192     for(int i=0;i<98;i+=2)
193       ir.deleteDocument(i);
194     assertEquals(49, ir.numDocs());
195     ir.close();
196
197     writer = new IndexWriter(
198         dir,
199         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
200             setMergePolicy(newLogMergePolicy(3))
201     );
202     assertEquals(49, writer.numDocs());
203     writer.forceMergeDeletes();
204     writer.close();
205     ir = IndexReader.open(dir, true);
206     assertEquals(49, ir.maxDoc());
207     assertEquals(49, ir.numDocs());
208     ir.close();
209     dir.close();
210   }
211
212   // LUCENE-325: test forceMergeDeletes without waiting, when
213   // many adjacent merges are required
214   public void testForceMergeDeletes3() throws IOException {
215     Directory dir = newDirectory();
216     IndexWriter writer = new IndexWriter(
217         dir,
218         newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
219             setMaxBufferedDocs(2).
220             setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH).
221             setMergePolicy(newLogMergePolicy(50))
222     );
223
224     Document document = new Document();
225
226     document = new Document();
227     Field storedField = newField("stored", "stored", Field.Store.YES,
228                                   Field.Index.NO);
229     document.add(storedField);
230     Field termVectorField = newField("termVector", "termVector",
231                                       Field.Store.NO, Field.Index.NOT_ANALYZED,
232                                       Field.TermVector.WITH_POSITIONS_OFFSETS);
233     document.add(termVectorField);
234     for(int i=0;i<98;i++)
235       writer.addDocument(document);
236     writer.close();
237
238     IndexReader ir = IndexReader.open(dir, false);
239     assertEquals(98, ir.maxDoc());
240     assertEquals(98, ir.numDocs());
241     for(int i=0;i<98;i+=2)
242       ir.deleteDocument(i);
243     assertEquals(49, ir.numDocs());
244     ir.close();
245
246     writer = new IndexWriter(
247         dir,
248         newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).
249             setMergePolicy(newLogMergePolicy(3))
250     );
251     writer.forceMergeDeletes(false);
252     writer.close();
253     ir = IndexReader.open(dir, true);
254     assertEquals(49, ir.maxDoc());
255     assertEquals(49, ir.numDocs());
256     ir.close();
257     dir.close();
258   }
259   
260   // Just intercepts all merges & verifies that we are never
261   // merging a segment with >= 20 (maxMergeDocs) docs
262   private class MyMergeScheduler extends MergeScheduler {
263     @Override
264     synchronized public void merge(IndexWriter writer)
265       throws CorruptIndexException, IOException {
266
267       while(true) {
268         MergePolicy.OneMerge merge = writer.getNextMerge();
269         if (merge == null) {
270           break;
271         }
272         for(int i=0;i<merge.segments.size();i++) {
273           assert merge.segments.get(i).docCount < 20;
274         }
275         writer.merge(merge);
276       }
277     }
278
279     @Override
280     public void close() {}
281   }
282
283   // LUCENE-1013
284   public void testSetMaxMergeDocs() throws IOException {
285     Directory dir = newDirectory();
286     IndexWriterConfig conf = newIndexWriterConfig(
287         TEST_VERSION_CURRENT, new MockAnalyzer(random))
288       .setMergeScheduler(new MyMergeScheduler()).setMaxBufferedDocs(2).setMergePolicy(newLogMergePolicy());
289     LogMergePolicy lmp = (LogMergePolicy) conf.getMergePolicy();
290     lmp.setMaxMergeDocs(20);
291     lmp.setMergeFactor(2);
292     IndexWriter iw = new IndexWriter(dir, conf);
293     iw.setInfoStream(VERBOSE ? System.out : null);
294     Document document = new Document();
295     document.add(newField("tvtest", "a b c", Field.Store.NO, Field.Index.ANALYZED,
296                            Field.TermVector.YES));
297     for(int i=0;i<177;i++)
298       iw.addDocument(document);
299     iw.close();
300     dir.close();
301   }
302 }