1 package org.apache.lucene.index;
3 * Copyright 2006 The Apache Software Foundation
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
9 * http://www.apache.org/licenses/LICENSE-2.0
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.
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;
28 import java.io.IOException;
29 import java.util.Random;
32 public class TestIndexWriterMerging extends LuceneTestCase
36 * Tests that index merging (specifically addIndexes(Directory...)) doesn't
37 * change the index order of documents.
39 public void testLucene() throws IOException {
42 Directory indexA = newDirectory();
43 Directory indexB = newDirectory();
45 fillIndex(random, indexA, 0, num);
46 boolean fail = verifyIndex(indexA, 0);
49 fail("Index a is invalid");
52 fillIndex(random, indexB, num, num);
53 fail = verifyIndex(indexB, num);
56 fail("Index b is invalid");
59 Directory merged = newDirectory();
61 IndexWriter writer = new IndexWriter(
63 newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
64 setMergePolicy(newLogMergePolicy(2))
66 writer.setInfoStream(VERBOSE ? System.out : null);
67 writer.addIndexes(new Directory[]{indexA, indexB});
71 fail = verifyIndex(merged, 0);
73 assertFalse("The merged index is invalid", fail);
79 private boolean verifyIndex(Directory directory, int startAt) throws IOException
82 IndexReader reader = IndexReader.open(directory, true);
84 int max = reader.maxDoc();
85 for (int i = 0; i < max; i++)
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) + ""))
93 System.out.println("Document " + (i + startAt) + " is returning document " + temp.getField("count").stringValue());
100 private void fillIndex(Random random, Directory dir, int start, int numDocs) throws IOException {
102 IndexWriter writer = new IndexWriter(
104 newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
105 setOpenMode(OpenMode.CREATE).
106 setMaxBufferedDocs(2).
107 setMergePolicy(newLogMergePolicy(2))
110 for (int i = start; i < (start + numDocs); i++)
112 Document temp = new Document();
113 temp.add(newField("count", (""+i), Field.Store.YES, Field.Index.NOT_ANALYZED));
115 writer.addDocument(temp);
120 // LUCENE-325: test forceMergeDeletes, when 2 singular merges
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();
131 document = new Document();
132 Field storedField = newField("stored", "stored", Field.Store.YES,
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);
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());
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());
157 ir = IndexReader.open(dir, true);
158 assertEquals(8, ir.maxDoc());
159 assertEquals(8, ir.numDocs());
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(
169 newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
170 setMaxBufferedDocs(2).
171 setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH).
172 setMergePolicy(newLogMergePolicy(50))
175 Document document = new Document();
177 document = new Document();
178 Field storedField = newField("stored", "stored", Store.YES,
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);
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());
197 writer = new IndexWriter(
199 newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
200 setMergePolicy(newLogMergePolicy(3))
202 assertEquals(49, writer.numDocs());
203 writer.forceMergeDeletes();
205 ir = IndexReader.open(dir, true);
206 assertEquals(49, ir.maxDoc());
207 assertEquals(49, ir.numDocs());
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(
218 newIndexWriterConfig(TEST_VERSION_CURRENT, new MockAnalyzer(random)).
219 setMaxBufferedDocs(2).
220 setRAMBufferSizeMB(IndexWriterConfig.DISABLE_AUTO_FLUSH).
221 setMergePolicy(newLogMergePolicy(50))
224 Document document = new Document();
226 document = new Document();
227 Field storedField = newField("stored", "stored", Field.Store.YES,
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);
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());
246 writer = new IndexWriter(
248 newIndexWriterConfig( TEST_VERSION_CURRENT, new MockAnalyzer(random)).
249 setMergePolicy(newLogMergePolicy(3))
251 writer.forceMergeDeletes(false);
253 ir = IndexReader.open(dir, true);
254 assertEquals(49, ir.maxDoc());
255 assertEquals(49, ir.numDocs());
260 // Just intercepts all merges & verifies that we are never
261 // merging a segment with >= 20 (maxMergeDocs) docs
262 private class MyMergeScheduler extends MergeScheduler {
264 synchronized public void merge(IndexWriter writer)
265 throws CorruptIndexException, IOException {
268 MergePolicy.OneMerge merge = writer.getNextMerge();
272 for(int i=0;i<merge.segments.size();i++) {
273 assert merge.segments.get(i).docCount < 20;
280 public void close() {}
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);