001: package org.apache.lucene;
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.util.*;
021: import org.apache.lucene.store.*;
022: import org.apache.lucene.document.*;
023: import org.apache.lucene.analysis.*;
024: import org.apache.lucene.index.*;
025: import org.apache.lucene.search.*;
026: import org.apache.lucene.queryParser.*;
027:
028: import java.util.Random;
029: import java.io.File;
030:
031: class ThreadSafetyTest {
032: private static final Analyzer ANALYZER = new SimpleAnalyzer();
033: private static final Random RANDOM = new Random();
034: private static Searcher SEARCHER;
035:
036: private static int ITERATIONS = 1;
037:
038: private static int random(int i) { // for JDK 1.1 compatibility
039: int r = RANDOM.nextInt();
040: if (r < 0)
041: r = -r;
042: return r % i;
043: }
044:
045: private static class IndexerThread extends Thread {
046: private final int reopenInterval = 30 + random(60);
047: IndexWriter writer;
048:
049: public IndexerThread(IndexWriter writer) {
050: this .writer = writer;
051: }
052:
053: public void run() {
054: try {
055: boolean useCompoundFiles = false;
056:
057: for (int i = 0; i < 1024 * ITERATIONS; i++) {
058: Document d = new Document();
059: int n = RANDOM.nextInt();
060: d.add(new Field("id", Integer.toString(n),
061: Field.Store.YES, Field.Index.UN_TOKENIZED));
062: d.add(new Field("contents",
063: English.intToEnglish(n), Field.Store.NO,
064: Field.Index.TOKENIZED));
065: System.out.println("Adding " + n);
066:
067: // Switch between single and multiple file segments
068: useCompoundFiles = Math.random() < 0.5;
069: writer.setUseCompoundFile(useCompoundFiles);
070:
071: writer.addDocument(d);
072:
073: if (i % reopenInterval == 0) {
074: writer.close();
075: writer = new IndexWriter("index", ANALYZER,
076: false);
077: }
078: }
079:
080: writer.close();
081:
082: } catch (Exception e) {
083: System.out.println(e.toString());
084: e.printStackTrace();
085: System.exit(0);
086: }
087: }
088: }
089:
090: private static class SearcherThread extends Thread {
091: private IndexSearcher searcher;
092: private final int reopenInterval = 10 + random(20);
093:
094: public SearcherThread(boolean useGlobal)
095: throws java.io.IOException {
096: if (!useGlobal)
097: this .searcher = new IndexSearcher("index");
098: }
099:
100: public void run() {
101: try {
102: for (int i = 0; i < 512 * ITERATIONS; i++) {
103: searchFor(RANDOM.nextInt(),
104: (searcher == null) ? SEARCHER : searcher);
105: if (i % reopenInterval == 0) {
106: if (searcher == null) {
107: SEARCHER = new IndexSearcher("index");
108: } else {
109: searcher.close();
110: searcher = new IndexSearcher("index");
111: }
112: }
113: }
114: } catch (Exception e) {
115: System.out.println(e.toString());
116: e.printStackTrace();
117: System.exit(0);
118: }
119: }
120:
121: private void searchFor(int n, Searcher searcher)
122: throws Exception {
123: System.out.println("Searching for " + n);
124: QueryParser parser = new QueryParser("contents", ANALYZER);
125: Hits hits = searcher.search(parser.parse(English
126: .intToEnglish(n)));
127: System.out.println("Search for " + n + ": total="
128: + hits.length());
129: for (int j = 0; j < Math.min(3, hits.length()); j++) {
130: System.out.println("Hit for " + n + ": "
131: + hits.doc(j).get("id"));
132: }
133: }
134: }
135:
136: public static void main(String[] args) throws Exception {
137:
138: boolean readOnly = false;
139: boolean add = false;
140:
141: for (int i = 0; i < args.length; i++) {
142: if ("-ro".equals(args[i]))
143: readOnly = true;
144: if ("-add".equals(args[i]))
145: add = true;
146: }
147:
148: File indexDir = new File("index");
149: if (!indexDir.exists())
150: indexDir.mkdirs();
151:
152: IndexReader.unlock(FSDirectory.getDirectory(indexDir));
153:
154: if (!readOnly) {
155: IndexWriter writer = new IndexWriter(indexDir, ANALYZER,
156: !add);
157:
158: Thread indexerThread = new IndexerThread(writer);
159: indexerThread.start();
160:
161: Thread.sleep(1000);
162: }
163:
164: SearcherThread searcherThread1 = new SearcherThread(false);
165: searcherThread1.start();
166:
167: SEARCHER = new IndexSearcher(indexDir.toString());
168:
169: SearcherThread searcherThread2 = new SearcherThread(true);
170: searcherThread2.start();
171:
172: SearcherThread searcherThread3 = new SearcherThread(true);
173: searcherThread3.start();
174: }
175: }
|