Index: contrib/benchmark/conf/basicNRT.alg =================================================================== --- contrib/benchmark/conf/basicNRT.alg (revision 0) +++ contrib/benchmark/conf/basicNRT.alg (revision 0) @@ -0,0 +1,67 @@ +#/** +# * Licensed to the Apache Software Foundation (ASF) under one or more +# * contributor license agreements. See the NOTICE file distributed with +# * this work for additional information regarding copyright ownership. +# * The ASF licenses this file to You 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. +# */ +# ------------------------------------------------------------------------------------- +# multi val params are iterated by NewRound's, added to reports, start with column name. +# +# based on micro-standard +# +# modified to use wikipedia sources and index entire docs +# currently just used to measure ingest rate + +analyzer=org.apache.lucene.analysis.standard.StandardAnalyzer +directory=FSDirectory + +work.dir = /x/lucene/wiki.nrt.5M + +doc.stored=true +doc.body.stored=false +doc.tokenized=false +doc.body.tokenized=true +doc.term.vector=false +log.step.AddDoc=100 +log.step.Search = 100 + +content.source=org.apache.lucene.benchmark.byTask.feeds.LineDocSource +content.source.forever = false +file.query.maker.file = queries.txt + +query.maker=org.apache.lucene.benchmark.byTask.feeds.FileBasedQueryMaker +docs.file = /x/lucene/enwiki-20090306-lines-1k-fixed.txt + +# task at this depth or less would print when they start +task.max.depth.log=2 + +log.queries=true + +# ------------------------------------------------------------------------------------- + +OpenIndex +{ + NearRealtimeReader(5.0) & + # Warm + Search + { "Index1" AddDoc > : * : 100/sec & + [ { "Search" Search > : * ] : 4 & + Wait(30.0) +} +CloseReader + +# Don't keep any changes, so we can re-test on the same index again +RollbackIndex + +RepSumByName + Index: contrib/benchmark/CHANGES.txt =================================================================== --- contrib/benchmark/CHANGES.txt (revision 834565) +++ contrib/benchmark/CHANGES.txt (working copy) @@ -4,6 +4,16 @@ $Id:$ +11/10/2009 + LUCENE-2050: Added ability to run tasks within a serial sequence in + the background, by appending "&". The tasks are stopped & joined at + the end of the sequence. Also added Wait and RollbackIndex tasks. + Genericized NearRealTimeReaderTask to only reopen the reader + (previously it spawned its own thread, and also did searching). + Also changed the API of PerfRunData.getIndexReader: it now returns a + reference, and it's your job to decRef the reader when you're done + using it. (Mike McCandless) + 11/08/2009 LUCENE-2044: Added delete.percent.rand.seed to seed the Random instance used by DeleteByPercentTask. (Mike McCandless) Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java (working copy) @@ -186,6 +186,19 @@ currSequence = seq2; colonOk = false; break; + + case '&' : + if (currSequence.isParallel()) { + throw new Exception("Can only create background tasks within a serial task"); + } + if (prevTask == null) { + throw new Exception("& was unexpected"); + } else if (prevTask.getRunInBackground()) { + throw new Exception("double & was unexpected"); + } else { + prevTask.setRunInBackground(); + } + break; case '>' : currSequence.setNoChildReport(); Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CommitIndexTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CommitIndexTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CommitIndexTask.java (working copy) @@ -54,6 +54,7 @@ IndexReader r = getRunData().getIndexReader(); if (r != null) { r.commit(commitUserData); + r.decRef(); } else { throw new IllegalStateException("neither IndexWriter nor IndexReader is currently open"); } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/RollbackIndexTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/RollbackIndexTask.java (revision 0) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/RollbackIndexTask.java (revision 0) @@ -0,0 +1,52 @@ +package org.apache.lucene.benchmark.byTask.tasks; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +import java.io.IOException; +import java.io.PrintStream; + +import org.apache.lucene.benchmark.byTask.PerfRunData; +import org.apache.lucene.index.IndexWriter; + +/** + * Rollback the index writer. + */ +public class RollbackIndexTask extends PerfTask { + + public RollbackIndexTask(PerfRunData runData) { + super(runData); + } + + boolean doWait = true; + + @Override + public int doLogic() throws IOException { + IndexWriter iw = getRunData().getIndexWriter(); + if (iw != null) { + // If infoStream was set to output to a file, close it. + PrintStream infoStream = iw.getInfoStream(); + if (infoStream != null && infoStream != System.out + && infoStream != System.err) { + infoStream.close(); + } + iw.rollback(); + getRunData().setIndexWriter(null); + } + return 1; + } +} Property changes on: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/RollbackIndexTask.java ___________________________________________________________________ Added: svn:eol-style + native Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/NearRealtimeReaderTask.java (working copy) @@ -17,18 +17,9 @@ * limitations under the License. */ -import java.io.IOException; - import org.apache.lucene.benchmark.byTask.PerfRunData; import org.apache.lucene.index.IndexReader; import org.apache.lucene.index.IndexWriter; -import org.apache.lucene.search.Query; -import org.apache.lucene.search.TermQuery; -import org.apache.lucene.search.Sort; -import org.apache.lucene.search.SortField; -import org.apache.lucene.search.IndexSearcher; -import org.apache.lucene.search.TopFieldDocs; -import org.apache.lucene.index.Term; /** * Spawns a BG thread that periodically (defaults to 3.0 @@ -43,97 +34,63 @@ */ public class NearRealtimeReaderTask extends PerfTask { - ReopenThread t; - float pauseSec = 3.0f; + long pauseMSec = 3000L; - private static class ReopenThread extends Thread { + public NearRealtimeReaderTask(PerfRunData runData) { + super(runData); + } - final IndexWriter writer; - final int pauseMsec; + @Override + public int doLogic() throws Exception { - public volatile boolean done; + final PerfRunData runData = getRunData(); - ReopenThread(IndexWriter writer, float pauseSec) { - this.writer = writer; - this.pauseMsec = (int) (1000*pauseSec); - setDaemon(true); + // Get initial reader + IndexWriter w = runData.getIndexWriter(); + if (w == null) { + throw new RuntimeException("please open the writer before invoking NearRealtimeReader"); } - @Override - public void run() { + if (runData.getIndexReader() != null) { + throw new RuntimeException("please close the existing reader before invoking NearRealtimeReader"); + } + + long t = System.currentTimeMillis(); + IndexReader r = w.getReader(); + runData.setIndexReader(r); + // Transfer our reference to runData + r.decRef(); - IndexReader reader = null; + // nocommit -- gather metrics for reporting - final Query query = new TermQuery(new Term("body", "1")); - final SortField sf = new SortField("docdate", SortField.LONG); - final Sort sort = new Sort(sf); + // Parent sequence sets stopNow + while(!stopNow) { + long waitForMsec = (long) (pauseMSec - (System.currentTimeMillis() - t)); + if (waitForMsec > 0) { + Thread.sleep(waitForMsec); + } - try { - while(!done) { - final long t0 = System.currentTimeMillis(); - if (reader == null) { - reader = writer.getReader(); - } else { - final IndexReader newReader = reader.reopen(); - if (reader != newReader) { - reader.close(); - reader = newReader; - } - } - - final long t1 = System.currentTimeMillis(); - final TopFieldDocs hits = new IndexSearcher(reader).search(query, null, 10, sort); - final long t2 = System.currentTimeMillis(); - System.out.println("nrt: open " + (t1-t0) + " msec; search " + (t2-t1) + " msec, " + hits.totalHits + - " results; " + reader.numDocs() + " docs"); - - final long t4 = System.currentTimeMillis(); - final int delay = (int) (pauseMsec - (t4-t0)); - if (delay > 0) { - try { - Thread.sleep(delay); - } catch (InterruptedException ie) { - throw new RuntimeException(ie); - } - } - } - } catch (Exception e) { - throw new RuntimeException(e); + t = System.currentTimeMillis(); + final IndexReader newReader = r.reopen(); + if (r != newReader) { + runData.setIndexReader(newReader); + // Transfer our reference to runData + newReader.decRef(); + r = newReader; } } - } - public NearRealtimeReaderTask(PerfRunData runData) { - super(runData); - } - - @Override - public int doLogic() throws IOException { - if (t == null) { - IndexWriter w = getRunData().getIndexWriter(); - t = new ReopenThread(w, pauseSec); - t.start(); - } return 1; } @Override public void setParams(String params) { super.setParams(params); - pauseSec = Float.parseFloat(params); + pauseMSec = (long) (1000.0*Float.parseFloat(params)); } @Override public boolean supportsParams() { return true; } - - // Close the thread - @Override - public void close() throws InterruptedException { - if (t != null) { - t.done = true; - t.join(); - } - } } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java (working copy) @@ -59,7 +59,9 @@ private int maxDepthLogStart = 0; private boolean disableCounting = false; protected String params = null; - + + private boolean runInBackground; + protected static final String NEW_LINE = System.getProperty("line.separator"); /** Should not be used externally */ @@ -70,6 +72,20 @@ } } + public void setRunInBackground() { + runInBackground = true; + } + + public boolean getRunInBackground() { + return runInBackground; + } + + protected volatile boolean stopNow; + + public void stopNow() { + stopNow = true; + } + /** * @deprecated will be removed in 3.0. checks if there are any obsolete * settings, like doc.add.log.step and doc.delete.log.step and @@ -131,6 +147,8 @@ * Run the task, record statistics. * @return number of work items done by this task. */ + // nocommit -- this is rather heavyweight, for the leaf + // tasks (AddDoc, Search) -- allow them to override & cut? public final int runAndMaybeStats(boolean reportStats) throws Exception { if (reportStats && depth <= maxDepthLogStart && !shouldNeverLogAtStart()) { System.out.println("------------> starting task: " + getName()); Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WaitTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WaitTask.java (revision 0) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WaitTask.java (revision 0) @@ -0,0 +1,68 @@ +package org.apache.lucene.benchmark.byTask.tasks; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ + +import org.apache.lucene.benchmark.byTask.PerfRunData; + +/** + nocommit + */ +public class WaitTask extends PerfTask { + + private double waitTimeSec; + + public WaitTask(PerfRunData runData) { + super(runData); + } + + @Override + public void setParams(String params) { + super.setParams(params); + if (params != null) { + int multiplier; + if (params.endsWith("s")) { + multiplier = 1; + params = params.substring(0, params.length()-1); + } else if (params.endsWith("m")) { + multiplier = 60; + params = params.substring(0, params.length()-1); + } else if (params.endsWith("h")) { + multiplier = 3600; + params = params.substring(0, params.length()-1); + } else { + // Assume seconds + multiplier = 1; + } + + waitTimeSec = Double.parseDouble(params) * multiplier; + } else { + throw new IllegalArgumentException("you must specify the wait time, eg: 10.0s, 4.5m, 2h"); + } + } + + @Override + public int doLogic() throws Exception { + Thread.sleep((long) (1000*waitTimeSec)); + return 0; + } + + @Override + public boolean supportsParams() { + return true; + } +} Property changes on: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/WaitTask.java ___________________________________________________________________ Added: svn:eol-style + native Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReopenReaderTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReopenReaderTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReopenReaderTask.java (working copy) @@ -33,13 +33,13 @@ @Override public int doLogic() throws IOException { - IndexReader ir = getRunData().getIndexReader(); - IndexReader or = ir; - IndexReader nr = ir.reopen(); - if(nr != or) { + IndexReader r = getRunData().getIndexReader(); + IndexReader nr = r.reopen(); + if (nr != r) { getRunData().setIndexReader(nr); - or.close(); + nr.decRef(); } + r.decRef(); return 1; } } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteByPercentTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteByPercentTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteByPercentTask.java (working copy) @@ -88,6 +88,7 @@ termDocs.close(); } System.out.println("--> processed (delete) " + numDeleted + " docs"); + r.decRef(); return numDeleted; } } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java (working copy) @@ -54,6 +54,8 @@ r = IndexReader.open(dir, indexDeletionPolicy, readOnly); } getRunData().setIndexReader(r); + // We transfer reference to the run data + r.decRef(); return 1; } @@ -72,7 +74,9 @@ break; } } - if (r == null) throw new IOException("cannot find commitPoint userData:"+userData); + if (r == null) { + throw new IOException("cannot find commitPoint userData:"+userData); + } return r; } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java (working copy) @@ -18,6 +18,7 @@ */ import org.apache.lucene.benchmark.byTask.PerfRunData; +import org.apache.lucene.index.IndexReader; /** * Delete a document by docid. If no docid param is supplied, deletes doc with @@ -42,8 +43,10 @@ @Override public int doLogic() throws Exception { - getRunData().getIndexReader().deleteDocument(docid); + IndexReader r = getRunData().getIndexReader(); + r.deleteDocument(docid); lastDeleted = docid; + r.decRef(); return 1; // one work item done here } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java (working copy) @@ -35,11 +35,12 @@ @Override public int doLogic() throws IOException { - IndexReader reader= getRunData().getIndexReader(); - if (reader!=null) { - reader.close(); + IndexReader reader = getRunData().getIndexReader(); + getRunData().setIndexReader(null); + if (reader.getRefCount() != 1) { + System.out.println("WARNING: CloseReader: reference count is currently " + reader.getRefCount()); } - getRunData().setIndexReader(null); + reader.decRef(); return 1; } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/FlushReaderTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/FlushReaderTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/FlushReaderTask.java (working copy) @@ -52,6 +52,7 @@ } else { reader.flush(); } + reader.decRef(); return 1; } } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/TaskSequence.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/TaskSequence.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/TaskSequence.java (working copy) @@ -18,6 +18,7 @@ */ import java.util.ArrayList; +import java.util.List; import java.text.NumberFormat; import org.apache.lucene.benchmark.byTask.PerfRunData; @@ -131,6 +132,34 @@ return ( parallel ? doParallelTasks() : doSerialTasks()); } + private static class RunBackgroundTask extends Thread { + private final PerfTask task; + private final boolean letChildReport; + private volatile int count; + + public RunBackgroundTask(PerfTask task, boolean letChildReport) { + this.task = task; + this.letChildReport = letChildReport; + } + + public void stopNow() throws InterruptedException { + task.stopNow(); + join(); + } + + public int getCount() { + return count; + } + + public void run() { + try { + count = task.runAndMaybeStats(letChildReport); + } catch (Exception e) { + throw new RuntimeException(e); + } + } + } + private int doSerialTasks() throws Exception { if (rate > 0) { return doSerialTasksWithRate(); @@ -142,22 +171,43 @@ final long t0 = System.currentTimeMillis(); final long runTime = (long) (runTimeSec*1000); + List bgTasks = null; for (int k=0; fixedTime || (repetitions==REPEAT_EXHAUST && !exhausted) || k(); + } + RunBackgroundTask bgTask = new RunBackgroundTask(task, letChildReport); + bgTask.start(); + bgTasks.add(bgTask); + } else { + try { + count += task.runAndMaybeStats(letChildReport); + if (anyExhaustibleTasks) + updateExhausted(task); + } catch (NoMoreDataException e) { + exhausted = true; + } } + } if (fixedTime && System.currentTimeMillis()-t0 > runTime) { repetitions = k+1; break; } } + + if (bgTasks != null) { + for(RunBackgroundTask bgTask : bgTasks) { + bgTask.stopNow(); + count += bgTask.getCount(); + } + } return count; } @@ -167,6 +217,9 @@ long nextStartTime = System.currentTimeMillis(); int count = 0; for (int k=0; (repetitions==REPEAT_EXHAUST && !exhausted) || k 0) { startlThreadsWithRate(t); return; @@ -254,7 +332,7 @@ } // run threads with rate - private void startlThreadsWithRate(Thread[] t) throws InterruptedException { + private void startlThreadsWithRate(ParallelTask[] t) throws InterruptedException { long delayStep = (perMin ? 60000 : 1000) /rate; long nextStartTime = System.currentTimeMillis(); for (int i = 0; i < t.length; i++) { Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (working copy) @@ -66,15 +66,16 @@ @Override public int doLogic() throws Exception { int res = 0; - boolean closeReader = false; // open reader or use existing one IndexReader ir = getRunData().getIndexReader(); + boolean closeReader; if (ir == null) { Directory dir = getRunData().getDirectory(); ir = IndexReader.open(dir, true); closeReader = true; - //res++; //this is confusing, comment it out + } else { + closeReader = false; } // optionally warm and add num docs traversed to count @@ -115,22 +116,19 @@ final String printHitsField = getRunData().getConfig().get("print.hits.field", null); if (printHitsField != null && printHitsField.length() > 0) { - final IndexReader r = searcher.getIndexReader(); if (q instanceof MultiTermQuery) { System.out.println("MultiTermQuery term count = " + ((MultiTermQuery) q).getTotalNumberOfTerms()); } System.out.println("totalHits = " + hits.totalHits); - System.out.println("maxDoc() = " + r.maxDoc()); - System.out.println("numDocs() = " + r.numDocs()); + System.out.println("maxDoc() = " + ir.maxDoc()); + System.out.println("numDocs() = " + ir.numDocs()); for(int i=0;i 0; + ir.decRef(); } return res; } Index: contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java =================================================================== --- contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java (revision 834565) +++ contrib/benchmark/src/java/org/apache/lucene/benchmark/byTask/PerfRunData.java (working copy) @@ -173,25 +173,39 @@ } /** - * @return Returns the indexReader. + * @return Returns the indexReader. NOTE: this returns a + * reference. You must call IndexReader.decRef() when + * you're done. */ - public IndexReader getIndexReader() { + public synchronized IndexReader getIndexReader() { + if (indexReader != null) { + indexReader.incRef(); + } return indexReader; } /** - * @return Returns the indexSearcher. + * @return Returns the indexSearcher. NOTE: this returns + * a reference to the underlying IndexReader. You must + * call IndexReader.decRef() when you're done. */ public IndexSearcher getIndexSearcher() { + if (indexReader != null) { + indexReader.incRef(); + } return indexSearcher; } /** * @param indexReader The indexReader to set. */ - public void setIndexReader(IndexReader indexReader) { + public synchronized void setIndexReader(IndexReader indexReader) throws IOException { + if (this.indexReader != null) { + this.indexReader.decRef(); + } this.indexReader = indexReader; if (indexReader != null) { + indexReader.incRef(); indexSearcher = new IndexSearcher(indexReader); } else { indexSearcher = null;