001: package org.apache.lucene.index;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.analysis.SimpleAnalyzer;
021: import org.apache.lucene.analysis.Analyzer;
022: import org.apache.lucene.store.Directory;
023: import org.apache.lucene.store.FSDirectory;
024: import org.apache.lucene.store.MockRAMDirectory;
025: import org.apache.lucene.document.Document;
026: import org.apache.lucene.document.Field;
027: import org.apache.lucene.util._TestUtil;
028: import org.apache.lucene.util.English;
029:
030: import org.apache.lucene.util.LuceneTestCase;
031:
032: import java.io.IOException;
033: import java.io.File;
034:
035: public class TestThreadedOptimize extends LuceneTestCase {
036:
037: private static final Analyzer ANALYZER = new SimpleAnalyzer();
038:
039: private final static int NUM_THREADS = 3;
040: //private final static int NUM_THREADS = 5;
041:
042: private final static int NUM_ITER = 2;
043: //private final static int NUM_ITER = 10;
044:
045: private final static int NUM_ITER2 = 2;
046: //private final static int NUM_ITER2 = 5;
047:
048: private boolean failed;
049:
050: private void setFailed() {
051: failed = true;
052: }
053:
054: public void runTest(Directory directory, boolean autoCommit,
055: MergeScheduler merger) throws Exception {
056:
057: IndexWriter writer = new IndexWriter(directory, autoCommit,
058: ANALYZER, true);
059: writer.setMaxBufferedDocs(2);
060: if (merger != null)
061: writer.setMergeScheduler(merger);
062:
063: for (int iter = 0; iter < NUM_ITER; iter++) {
064: final int iterFinal = iter;
065:
066: writer.setMergeFactor(1000);
067:
068: for (int i = 0; i < 200; i++) {
069: Document d = new Document();
070: d.add(new Field("id", Integer.toString(i),
071: Field.Store.YES, Field.Index.UN_TOKENIZED));
072: d.add(new Field("contents", English.intToEnglish(i),
073: Field.Store.NO, Field.Index.TOKENIZED));
074: writer.addDocument(d);
075: }
076:
077: writer.setMergeFactor(4);
078: //writer.setInfoStream(System.out);
079:
080: final int docCount = writer.docCount();
081:
082: Thread[] threads = new Thread[NUM_THREADS];
083:
084: for (int i = 0; i < NUM_THREADS; i++) {
085: final int iFinal = i;
086: final IndexWriter writerFinal = writer;
087: threads[i] = new Thread() {
088: public void run() {
089: try {
090: for (int j = 0; j < NUM_ITER2; j++) {
091: writerFinal.optimize(false);
092: for (int k = 0; k < 17 * (1 + iFinal); k++) {
093: Document d = new Document();
094: d.add(new Field("id", iterFinal
095: + "_" + iFinal + "_" + j
096: + "_" + k, Field.Store.YES,
097: Field.Index.UN_TOKENIZED));
098: d.add(new Field("contents", English
099: .intToEnglish(iFinal + k),
100: Field.Store.NO,
101: Field.Index.TOKENIZED));
102: writerFinal.addDocument(d);
103: }
104: for (int k = 0; k < 9 * (1 + iFinal); k++)
105: writerFinal
106: .deleteDocuments(new Term(
107: "id", iterFinal
108: + "_"
109: + iFinal
110: + "_" + j
111: + "_" + k));
112: writerFinal.optimize();
113: }
114: } catch (Throwable t) {
115: setFailed();
116: System.out.println(Thread.currentThread()
117: .getName()
118: + ": hit exception");
119: t.printStackTrace(System.out);
120: }
121: }
122: };
123: }
124:
125: for (int i = 0; i < NUM_THREADS; i++)
126: threads[i].start();
127:
128: for (int i = 0; i < NUM_THREADS; i++)
129: threads[i].join();
130:
131: assertTrue(!failed);
132:
133: final int expectedDocCount = (int) ((1 + iter) * (200 + 8
134: * NUM_ITER2 * (NUM_THREADS / 2.0)
135: * (1 + NUM_THREADS)));
136:
137: // System.out.println("TEST: now index=" + writer.segString());
138:
139: assertEquals(expectedDocCount, writer.docCount());
140:
141: if (!autoCommit) {
142: writer.close();
143: writer = new IndexWriter(directory, autoCommit,
144: ANALYZER, false);
145: writer.setMaxBufferedDocs(2);
146: }
147:
148: IndexReader reader = IndexReader.open(directory);
149: assertTrue(reader.isOptimized());
150: assertEquals(expectedDocCount, reader.numDocs());
151: reader.close();
152: }
153: writer.close();
154: }
155:
156: /*
157: Run above stress test against RAMDirectory and then
158: FSDirectory.
159: */
160: public void testThreadedOptimize() throws Exception {
161: Directory directory = new MockRAMDirectory();
162: runTest(directory, false, null);
163: runTest(directory, true, null);
164: runTest(directory, false, new ConcurrentMergeScheduler());
165: runTest(directory, true, new ConcurrentMergeScheduler());
166: directory.close();
167:
168: String tempDir = System.getProperty("tempDir");
169: if (tempDir == null)
170: throw new IOException("tempDir undefined, cannot run test");
171:
172: String dirName = tempDir + "/luceneTestThreadedOptimize";
173: directory = FSDirectory.getDirectory(dirName);
174: runTest(directory, false, null);
175: runTest(directory, true, null);
176: runTest(directory, false, new ConcurrentMergeScheduler());
177: runTest(directory, true, new ConcurrentMergeScheduler());
178: directory.close();
179: _TestUtil.rmDir(dirName);
180: }
181: }
|