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