pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / test / org / apache / lucene / index / TestStressIndexing.java
1 package org.apache.lucene.index;
2
3 /**
4  * Copyright 2004 The Apache Software Foundation
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 import org.apache.lucene.util.*;
20 import org.apache.lucene.store.*;
21 import org.apache.lucene.analysis.MockAnalyzer;
22 import org.apache.lucene.document.*;
23 import org.apache.lucene.index.IndexWriterConfig.OpenMode;
24 import org.apache.lucene.search.*;
25
26 public class TestStressIndexing extends LuceneTestCase {
27   private static abstract class TimedThread extends Thread {
28     volatile boolean failed;
29     int count;
30     private static int RUN_TIME_MSEC = atLeast(1000);
31     private TimedThread[] allThreads;
32
33     abstract public void doWork() throws Throwable;
34
35     TimedThread(TimedThread[] threads) {
36       this.allThreads = threads;
37     }
38
39     @Override
40     public void run() {
41       final long stopTime = System.currentTimeMillis() + RUN_TIME_MSEC;
42
43       count = 0;
44
45       try {
46         do {
47           if (anyErrors()) break;
48           doWork();
49           count++;
50         } while(System.currentTimeMillis() < stopTime);
51       } catch (Throwable e) {
52         System.out.println(Thread.currentThread() + ": exc");
53         e.printStackTrace(System.out);
54         failed = true;
55       }
56     }
57
58     private boolean anyErrors() {
59       for(int i=0;i<allThreads.length;i++)
60         if (allThreads[i] != null && allThreads[i].failed)
61           return true;
62       return false;
63     }
64   }
65
66   private class IndexerThread extends TimedThread {
67     IndexWriter writer;
68     int nextID;
69
70     public IndexerThread(IndexWriter writer, TimedThread[] threads) {
71       super(threads);
72       this.writer = writer;
73     }
74
75     @Override
76     public void doWork() throws Exception {
77       // Add 10 docs:
78       for(int j=0; j<10; j++) {
79         Document d = new Document();
80         int n = random.nextInt();
81         d.add(newField("id", Integer.toString(nextID++), Field.Store.YES, Field.Index.NOT_ANALYZED));
82         d.add(newField("contents", English.intToEnglish(n), Field.Store.NO, Field.Index.ANALYZED));
83         writer.addDocument(d);
84       }
85
86       // Delete 5 docs:
87       int deleteID = nextID-1;
88       for(int j=0; j<5; j++) {
89         writer.deleteDocuments(new Term("id", ""+deleteID));
90         deleteID -= 2;
91       }
92     }
93   }
94
95   private static class SearcherThread extends TimedThread {
96     private Directory directory;
97
98     public SearcherThread(Directory directory, TimedThread[] threads) {
99       super(threads);
100       this.directory = directory;
101     }
102
103     @Override
104     public void doWork() throws Throwable {
105       for (int i=0; i<100; i++) {
106         IndexReader ir = IndexReader.open(directory, true);
107         IndexSearcher is = new IndexSearcher(ir);
108         is.close();
109         ir.close();
110       }
111       count += 100;
112     }
113   }
114
115   /*
116     Run one indexer and 2 searchers against single index as
117     stress test.
118   */
119   public void runStressTest(Directory directory, MergeScheduler mergeScheduler) throws Exception {
120     IndexWriter modifier = new IndexWriter(directory, newIndexWriterConfig(
121         TEST_VERSION_CURRENT, new MockAnalyzer(random))
122         .setOpenMode(OpenMode.CREATE).setMaxBufferedDocs(10).setMergeScheduler(
123             mergeScheduler));
124     modifier.commit();
125     
126     TimedThread[] threads = new TimedThread[4];
127     int numThread = 0;
128
129
130     // One modifier that writes 10 docs then removes 5, over
131     // and over:
132     IndexerThread indexerThread = new IndexerThread(modifier, threads);
133     threads[numThread++] = indexerThread;
134     indexerThread.start();
135     
136     IndexerThread indexerThread2 = new IndexerThread(modifier, threads);
137     threads[numThread++] = indexerThread2;
138     indexerThread2.start();
139       
140     // Two searchers that constantly just re-instantiate the
141     // searcher:
142     SearcherThread searcherThread1 = new SearcherThread(directory, threads);
143     threads[numThread++] = searcherThread1;
144     searcherThread1.start();
145
146     SearcherThread searcherThread2 = new SearcherThread(directory, threads);
147     threads[numThread++] = searcherThread2;
148     searcherThread2.start();
149
150     for(int i=0;i<numThread;i++)
151       threads[i].join();
152
153     modifier.close();
154
155     for(int i=0;i<numThread;i++)
156       assertTrue(! threads[i].failed);
157
158     //System.out.println("    Writer: " + indexerThread.count + " iterations");
159     //System.out.println("Searcher 1: " + searcherThread1.count + " searchers created");
160     //System.out.println("Searcher 2: " + searcherThread2.count + " searchers created");
161   }
162
163   /*
164     Run above stress test against RAMDirectory and then
165     FSDirectory.
166   */
167   public void testStressIndexAndSearching() throws Exception {
168     Directory directory = newDirectory();
169     runStressTest(directory, new ConcurrentMergeScheduler());
170     directory.close();
171   }
172 }