pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / src / test / org / apache / lucene / index / TestIndexWriterNRTIsCurrent.java
1 package org.apache.lucene.index;
2
3 /**
4  * Licensed to the Apache Software Foundation (ASF) under one or more
5  * contributor license agreements. See the NOTICE file distributed with this
6  * work for additional information regarding copyright ownership. The ASF
7  * licenses this file to You under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  * 
11  * http://www.apache.org/licenses/LICENSE-2.0
12  * 
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15  * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
16  * License for the specific language governing permissions and limitations under
17  * the License.
18  */
19 import java.io.IOException;
20 import java.util.Random;
21 import java.util.concurrent.CountDownLatch;
22
23 import org.apache.lucene.analysis.MockAnalyzer;
24 import org.apache.lucene.document.Document;
25 import org.apache.lucene.document.Field;
26 import org.apache.lucene.store.Directory;
27 import org.apache.lucene.store.LockObtainFailedException;
28 import org.apache.lucene.util.LuceneTestCase;
29
30 public class TestIndexWriterNRTIsCurrent extends LuceneTestCase {
31
32   public static class ReaderHolder {
33     volatile IndexReader reader;
34     volatile boolean stop = false;
35   }
36
37   public void testIsCurrentWithThreads() throws CorruptIndexException,
38       LockObtainFailedException, IOException, InterruptedException {
39     Directory dir = newDirectory();
40     IndexWriterConfig conf = newIndexWriterConfig(TEST_VERSION_CURRENT,
41         new MockAnalyzer(random));
42     IndexWriter writer = new IndexWriter(dir, conf);
43     if (VERBOSE) {
44       writer.setInfoStream(System.out);
45     }
46     ReaderHolder holder = new ReaderHolder();
47     ReaderThread[] threads = new ReaderThread[atLeast(3)];
48     final CountDownLatch latch = new CountDownLatch(1);
49     WriterThread writerThread = new WriterThread(holder, writer,
50         atLeast(500), random, latch);
51     for (int i = 0; i < threads.length; i++) {
52       threads[i] = new ReaderThread(holder, latch);
53       threads[i].start();
54     }
55     writerThread.start();
56
57     writerThread.join();
58     boolean failed = writerThread.failed != null;
59     if (failed)
60       writerThread.failed.printStackTrace();
61     for (int i = 0; i < threads.length; i++) {
62       threads[i].join();
63       if (threads[i].failed != null) {
64         threads[i].failed.printStackTrace();
65         failed = true;
66       }
67     }
68     assertFalse(failed);
69     writer.close();
70     dir.close();
71
72   }
73
74   public static class WriterThread extends Thread {
75     private final ReaderHolder holder;
76     private final IndexWriter writer;
77     private final int numOps;
78     private final Random random;
79     private boolean countdown = true;
80     private final CountDownLatch latch;
81     Throwable failed;
82
83     WriterThread(ReaderHolder holder, IndexWriter writer, int numOps,
84         Random random, CountDownLatch latch) {
85       super();
86       this.holder = holder;
87       this.writer = writer;
88       this.numOps = numOps;
89       this.random = random;
90       this.latch = latch;
91     }
92
93     public void run() {
94       IndexReader currentReader = null;
95       try {
96         Document doc = new Document();
97         doc.add(new Field("id", "1", Field.Store.NO, Field.Index.ANALYZED));
98         writer.addDocument(doc);
99         holder.reader = currentReader = writer.getReader(true);
100         Term term = new Term("id");
101         for (int i = 0; i < numOps && !holder.stop; i++) {
102           float nextOp = random.nextFloat();
103           if (nextOp < 0.3) {
104             term.set("id", "1");
105             writer.updateDocument(term, doc);
106           } else if (nextOp < 0.5) {
107             writer.addDocument(doc);
108           } else {
109             term.set("id", "1");
110             writer.deleteDocuments(term);
111           }
112           if (holder.reader != currentReader) {
113             holder.reader = currentReader;
114             if (countdown) {
115               countdown = false;
116               latch.countDown();
117             }
118           }
119           if (random.nextBoolean()) {
120             writer.commit();
121             final IndexReader newReader = IndexReader
122                 .openIfChanged(currentReader);
123             if (newReader != null) { 
124               currentReader.decRef();
125               currentReader = newReader;
126             }
127             if (currentReader.numDocs() == 0) {
128               writer.addDocument(doc);
129             }
130           }
131         }
132       } catch (Throwable e) {
133         failed = e;
134       } finally {
135         holder.reader = null;
136         if (countdown) {
137           latch.countDown();
138         }
139         if (currentReader != null) {
140           try {
141             currentReader.decRef();
142           } catch (IOException e) {
143           }
144         }
145       }
146       if (VERBOSE) {
147         System.out.println("writer stopped - forced by reader: " + holder.stop);
148       }
149     }
150     
151   }
152
153   public static final class ReaderThread extends Thread {
154     private final ReaderHolder holder;
155     private final CountDownLatch latch;
156     Throwable failed;
157
158     ReaderThread(ReaderHolder holder, CountDownLatch latch) {
159       super();
160       this.holder = holder;
161       this.latch = latch;
162     }
163
164     public void run() {
165       try {
166         latch.await();
167       } catch (InterruptedException e) {
168         failed = e;
169         return;
170       }
171       IndexReader reader;
172       while ((reader = holder.reader) != null) {
173         if (reader.tryIncRef()) {
174           try {
175             boolean current = reader.isCurrent();
176             if (VERBOSE) {
177               System.out.println("Thread: " + Thread.currentThread() + " Reader: " + reader + " isCurrent:" + current);
178             }
179
180             assertFalse(current);
181           } catch (Throwable e) {
182             if (VERBOSE) {
183               System.out.println("FAILED Thread: " + Thread.currentThread() + " Reader: " + reader + " isCurrent: false");
184             }
185             failed = e;
186             holder.stop = true;
187             return;
188           } finally {
189             try {
190               reader.decRef();
191             } catch (IOException e) {
192               if (failed == null) {
193                 failed = e;
194               }
195               return;
196             }
197           }
198         }
199       }
200     }
201   }
202 }