| /* | |
| * Copyright 2004 The Apache Software Foundation | |
| * | |
| * Licensed under the Apache License, Version 2.0 (the "License"); | |
| * you may not use this file except in compliance with the License. | |
| * You may obtain a copy of the License at | |
| * | |
| * http://www.apache.org/licenses/LICENSE-2.0 | |
| * | |
| * Unless required by applicable law or agreed to in writing, software | |
| * distributed under the License is distributed on an "AS IS" BASIS, | |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
| * See the License for the specific language governing permissions and | |
| * limitations under the License. | |
| */ | |
| using System; | |
| using Lucene.Net.Analysis; | |
| using Lucene.Net.Documents; | |
| using Lucene.Net.Index; | |
| using Lucene.Net.QueryParsers; | |
| using Lucene.Net.Search; | |
| using Searchable = Lucene.Net.Search.Searchable; | |
| using Lucene.Net.Store; | |
| using Lucene.Net.Util; | |
| namespace Lucene.Net | |
| { | |
| class ThreadSafetyTest | |
| { | |
| private static readonly Analyzer ANALYZER = new SimpleAnalyzer(); | |
| private static readonly System.Random RANDOM = new System.Random(); | |
| private static Searcher SEARCHER; | |
| private static int ITERATIONS = 1; | |
| private static int Random(int i) | |
| { | |
| // for JDK 1.1 compatibility | |
| int r = RANDOM.Next(); | |
| if (r < 0) | |
| r = - r; | |
| return r % i; | |
| } | |
| private class IndexerThread:SupportClass.ThreadClass | |
| { | |
| private void InitBlock() | |
| { | |
| reopenInterval = 30 + Lucene.Net.ThreadSafetyTest.Random(60); | |
| } | |
| private int reopenInterval; | |
| internal IndexWriter writer; | |
| public IndexerThread(IndexWriter writer) | |
| { | |
| this.writer = writer; | |
| } | |
| override public void Run() | |
| { | |
| try | |
| { | |
| bool useCompoundFiles = false; | |
| for (int i = 0; i < 1024 * Lucene.Net.ThreadSafetyTest.ITERATIONS; i++) | |
| { | |
| Lucene.Net.Documents.Document d = new Lucene.Net.Documents.Document(); | |
| int n = Lucene.Net.ThreadSafetyTest.RANDOM.Next(); | |
| d.Add(new Field("id", System.Convert.ToString(n), Field.Store.YES, Field.Index.UN_TOKENIZED)); | |
| d.Add(new Field("contents", English.IntToEnglish(n), Field.Store.NO, Field.Index.TOKENIZED)); | |
| System.Console.Out.WriteLine("Adding " + n); | |
| // Switch between single and multiple file segments | |
| useCompoundFiles = (new System.Random()).NextDouble() < 0.5; | |
| writer.SetUseCompoundFile(useCompoundFiles); | |
| writer.AddDocument(d); | |
| if (i % reopenInterval == 0) | |
| { | |
| writer.Close(); | |
| writer = new IndexWriter("index", Lucene.Net.ThreadSafetyTest.ANALYZER, false); | |
| } | |
| } | |
| writer.Close(); | |
| } | |
| catch (System.Exception e) | |
| { | |
| System.Console.Out.WriteLine(e.ToString()); | |
| System.Console.Error.WriteLine(e.StackTrace); | |
| System.Environment.Exit(0); | |
| } | |
| } | |
| } | |
| private class SearcherThread:SupportClass.ThreadClass | |
| { | |
| private void InitBlock() | |
| { | |
| reopenInterval = 10 + Lucene.Net.ThreadSafetyTest.Random(20); | |
| } | |
| private IndexSearcher searcher; | |
| private int reopenInterval; | |
| public SearcherThread(bool useGlobal) | |
| { | |
| if (!useGlobal) | |
| this.searcher = new IndexSearcher("index"); | |
| } | |
| override public void Run() | |
| { | |
| try | |
| { | |
| for (int i = 0; i < 512 * Lucene.Net.ThreadSafetyTest.ITERATIONS; i++) | |
| { | |
| searchFor(Lucene.Net.ThreadSafetyTest.RANDOM.Next(), (searcher == null)?Lucene.Net.ThreadSafetyTest.SEARCHER:searcher); | |
| if (i % reopenInterval == 0) | |
| { | |
| if (searcher == null) | |
| { | |
| Lucene.Net.ThreadSafetyTest.SEARCHER = new IndexSearcher("index"); | |
| } | |
| else | |
| { | |
| searcher.Close(); | |
| searcher = new IndexSearcher("index"); | |
| } | |
| } | |
| } | |
| } | |
| catch (System.Exception e) | |
| { | |
| System.Console.Out.WriteLine(e.ToString()); | |
| System.Console.Error.WriteLine(e.StackTrace); | |
| System.Environment.Exit(0); | |
| } | |
| } | |
| private void searchFor(int n, Searcher searcher) | |
| { | |
| System.Console.Out.WriteLine("Searching for " + n); | |
| Hits hits = searcher.Search(Lucene.Net.QueryParsers.QueryParser.Parse(English.IntToEnglish(n), "contents", Lucene.Net.ThreadSafetyTest.ANALYZER)); | |
| System.Console.Out.WriteLine("Search for " + n + ": total=" + hits.Length()); | |
| for (int j = 0; j < System.Math.Min(3, hits.Length()); j++) | |
| { | |
| System.Console.Out.WriteLine("Hit for " + n + ": " + hits.Doc(j).Get("id")); | |
| } | |
| } | |
| } | |
| [STAThread] | |
| public static void Main(System.String[] args) | |
| { | |
| bool readOnly = false; | |
| bool add = false; | |
| for (int i = 0; i < args.Length; i++) | |
| { | |
| if ("-ro".Equals(args[i])) | |
| readOnly = true; | |
| if ("-add".Equals(args[i])) | |
| add = true; | |
| } | |
| System.IO.FileInfo indexDir = new System.IO.FileInfo("index"); | |
| bool tmpBool; | |
| if (System.IO.File.Exists(indexDir.FullName)) | |
| tmpBool = true; | |
| else | |
| tmpBool = System.IO.Directory.Exists(indexDir.FullName); | |
| if (!tmpBool) | |
| { | |
| System.IO.Directory.CreateDirectory(indexDir.FullName); | |
| } | |
| IndexReader.Unlock(FSDirectory.GetDirectory(indexDir, false)); | |
| if (!readOnly) | |
| { | |
| IndexWriter writer = new IndexWriter(indexDir, ANALYZER, !add); | |
| SupportClass.ThreadClass indexerThread = new IndexerThread(writer); | |
| indexerThread.Start(); | |
| System.Threading.Thread.Sleep(new System.TimeSpan((System.Int64) 10000 * 1000)); | |
| } | |
| SearcherThread searcherThread1 = new SearcherThread(false); | |
| searcherThread1.Start(); | |
| SEARCHER = new IndexSearcher(indexDir.ToString()); | |
| SearcherThread searcherThread2 = new SearcherThread(true); | |
| searcherThread2.Start(); | |
| SearcherThread searcherThread3 = new SearcherThread(true); | |
| searcherThread3.Start(); | |
| } | |
| } | |
| } |