add --shared
[pylucene.git] / lucene-java-3.4.0 / lucene / backwards / 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         (new IndexSearcher(directory, true)).close();
107       count += 100;
108     }
109   }
110
111   /*
112     Run one indexer and 2 searchers against single index as
113     stress test.
114   */
115   public void runStressTest(Directory directory, MergeScheduler mergeScheduler) throws Exception {
116     IndexWriter modifier = new IndexWriter(directory, newIndexWriterConfig(
117         TEST_VERSION_CURRENT, new MockAnalyzer(random))
118         .setOpenMode(OpenMode.CREATE).setMaxBufferedDocs(10).setMergeScheduler(
119             mergeScheduler));
120     modifier.commit();
121     
122     TimedThread[] threads = new TimedThread[4];
123     int numThread = 0;
124
125
126     // One modifier that writes 10 docs then removes 5, over
127     // and over:
128     IndexerThread indexerThread = new IndexerThread(modifier, threads);
129     threads[numThread++] = indexerThread;
130     indexerThread.start();
131     
132     IndexerThread indexerThread2 = new IndexerThread(modifier, threads);
133     threads[numThread++] = indexerThread2;
134     indexerThread2.start();
135       
136     // Two searchers that constantly just re-instantiate the
137     // searcher:
138     SearcherThread searcherThread1 = new SearcherThread(directory, threads);
139     threads[numThread++] = searcherThread1;
140     searcherThread1.start();
141
142     SearcherThread searcherThread2 = new SearcherThread(directory, threads);
143     threads[numThread++] = searcherThread2;
144     searcherThread2.start();
145
146     for(int i=0;i<numThread;i++)
147       threads[i].join();
148
149     modifier.close();
150
151     for(int i=0;i<numThread;i++)
152       assertTrue(! threads[i].failed);
153
154     //System.out.println("    Writer: " + indexerThread.count + " iterations");
155     //System.out.println("Searcher 1: " + searcherThread1.count + " searchers created");
156     //System.out.println("Searcher 2: " + searcherThread2.count + " searchers created");
157   }
158
159   /*
160     Run above stress test against RAMDirectory and then
161     FSDirectory.
162   */
163   public void testStressIndexAndSearching() throws Exception {
164     Directory directory = newDirectory();
165     runStressTest(directory, new ConcurrentMergeScheduler());
166     directory.close();
167   }
168 }