1 package org.apache.lucene.index;
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
11 * http://www.apache.org/licenses/LICENSE-2.0
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
19 import java.io.IOException;
20 import java.util.Random;
21 import java.util.concurrent.CountDownLatch;
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;
30 public class TestIndexWriterNRTIsCurrent extends LuceneTestCase {
32 public static class ReaderHolder {
33 volatile IndexReader reader;
34 volatile boolean stop = false;
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);
44 writer.setInfoStream(System.out);
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);
58 boolean failed = writerThread.failed != null;
60 writerThread.failed.printStackTrace();
61 for (int i = 0; i < threads.length; i++) {
63 if (threads[i].failed != null) {
64 threads[i].failed.printStackTrace();
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;
83 WriterThread(ReaderHolder holder, IndexWriter writer, int numOps,
84 Random random, CountDownLatch latch) {
94 IndexReader currentReader = null;
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();
105 writer.updateDocument(term, doc);
106 } else if (nextOp < 0.5) {
107 writer.addDocument(doc);
110 writer.deleteDocuments(term);
112 if (holder.reader != currentReader) {
113 holder.reader = currentReader;
119 if (random.nextBoolean()) {
121 final IndexReader newReader = IndexReader
122 .openIfChanged(currentReader);
123 if (newReader != null) {
124 currentReader.decRef();
125 currentReader = newReader;
127 if (currentReader.numDocs() == 0) {
128 writer.addDocument(doc);
132 } catch (Throwable e) {
135 holder.reader = null;
139 if (currentReader != null) {
141 currentReader.decRef();
142 } catch (IOException e) {
147 System.out.println("writer stopped - forced by reader: " + holder.stop);
153 public static final class ReaderThread extends Thread {
154 private final ReaderHolder holder;
155 private final CountDownLatch latch;
158 ReaderThread(ReaderHolder holder, CountDownLatch latch) {
160 this.holder = holder;
167 } catch (InterruptedException e) {
172 while ((reader = holder.reader) != null) {
173 if (reader.tryIncRef()) {
175 boolean current = reader.isCurrent();
177 System.out.println("Thread: " + Thread.currentThread() + " Reader: " + reader + " isCurrent:" + current);
180 assertFalse(current);
181 } catch (Throwable e) {
183 System.out.println("FAILED Thread: " + Thread.currentThread() + " Reader: " + reader + " isCurrent: false");
191 } catch (IOException e) {
192 if (failed == null) {