1 package org.apache.lucene.benchmark.byTask;
4 * Licensed to the Apache Software Foundation (ASF) under one or more
5 * contributor license agreements. See the NOTICE file distributed with
6 * this work for additional information regarding copyright ownership.
7 * The ASF licenses this file to You under the Apache License, Version 2.0
8 * (the "License"); you may not use this file except in compliance with
9 * the License. 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,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
20 import java.io.Closeable;
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.Locale;
26 import org.apache.lucene.analysis.Analyzer;
27 import org.apache.lucene.benchmark.byTask.feeds.DocMaker;
28 import org.apache.lucene.benchmark.byTask.feeds.FacetSource;
29 import org.apache.lucene.benchmark.byTask.feeds.QueryMaker;
30 import org.apache.lucene.benchmark.byTask.stats.Points;
31 import org.apache.lucene.benchmark.byTask.tasks.ReadTask;
32 import org.apache.lucene.benchmark.byTask.tasks.SearchTask;
33 import org.apache.lucene.benchmark.byTask.utils.Config;
34 import org.apache.lucene.benchmark.byTask.utils.FileUtils;
35 import org.apache.lucene.benchmark.byTask.tasks.NewAnalyzerTask;
36 import org.apache.lucene.facet.taxonomy.TaxonomyReader;
37 import org.apache.lucene.facet.taxonomy.TaxonomyWriter;
38 import org.apache.lucene.index.IndexReader;
39 import org.apache.lucene.index.IndexWriter;
40 import org.apache.lucene.search.IndexSearcher;
41 import org.apache.lucene.store.Directory;
42 import org.apache.lucene.store.FSDirectory;
43 import org.apache.lucene.store.RAMDirectory;
44 import org.apache.lucene.util.IOUtils;
47 * Data maintained by a performance test run.
52 * <li>Directory, Writer, Reader.
53 * <li>Taxonomy Directory, Writer, Reader.
54 * <li>DocMaker, FacetSource and a few instances of QueryMaker.
56 * <li>Statistics data which updated during the run.
60 * <li><b>work.dir</b>=<path to root of docs and index dirs| Default: work>
61 * <li><b>analyzer</b>=<class name for analyzer| Default: StandardAnalyzer>
62 * <li><b>doc.maker</b>=<class name for doc-maker| Default: DocMaker>
63 * <li><b>facet.source</b>=<class name for facet-source| Default: RandomFacetSource>
64 * <li><b>query.maker</b>=<class name for query-maker| Default: SimpleQueryMaker>
65 * <li><b>log.queries</b>=<whether queries should be printed| Default: false>
66 * <li><b>directory</b>=<type of directory to use for the index| Default: RAMDirectory>
67 * <li><b>taxonomy.directory</b>=<type of directory for taxonomy index| Default: RAMDirectory>
70 public class PerfRunData implements Closeable {
72 private Points points;
74 // objects used during performance test run
75 // directory, analyzer, docMaker - created at startup.
76 // reader, writer, searcher - maintained by basic tasks.
77 private Directory directory;
78 private Analyzer analyzer;
79 private DocMaker docMaker;
80 private FacetSource facetSource;
81 private Locale locale;
83 private Directory taxonomyDir;
84 private TaxonomyWriter taxonomyWriter;
85 private TaxonomyReader taxonomyReader;
87 // we use separate (identical) instances for each "read" task type, so each can iterate the quries separately.
88 private HashMap<Class<? extends ReadTask>,QueryMaker> readTaskQueryMaker;
89 private Class<? extends QueryMaker> qmkrClass;
91 private IndexReader indexReader;
92 private IndexSearcher indexSearcher;
93 private IndexWriter indexWriter;
94 private Config config;
95 private long startTimeMillis;
99 public PerfRunData (Config config) throws Exception {
100 this.config = config;
101 // analyzer (default is standard analyzer)
102 analyzer = NewAnalyzerTask.createAnalyzer(config.get("analyzer",
103 "org.apache.lucene.analysis.standard.StandardAnalyzer"));
105 docMaker = Class.forName(config.get("doc.maker",
106 "org.apache.lucene.benchmark.byTask.feeds.DocMaker")).asSubclass(DocMaker.class).newInstance();
107 docMaker.setConfig(config);
109 facetSource = Class.forName(config.get("facet.source",
110 "org.apache.lucene.benchmark.byTask.feeds.RandomFacetSource")).asSubclass(FacetSource.class).newInstance();
111 facetSource.setConfig(config);
113 readTaskQueryMaker = new HashMap<Class<? extends ReadTask>,QueryMaker>();
114 qmkrClass = Class.forName(config.get("query.maker","org.apache.lucene.benchmark.byTask.feeds.SimpleQueryMaker")).asSubclass(QueryMaker.class);
120 points = new Points(config);
122 if (Boolean.valueOf(config.get("log.queries","false")).booleanValue()) {
123 System.out.println("------------> queries:");
124 System.out.println(getQueryMaker(new SearchTask(this)).printQueries());
128 public void close() throws IOException {
129 IOUtils.close(indexWriter, indexReader, indexSearcher, directory,
130 taxonomyWriter, taxonomyReader, taxonomyDir,
131 docMaker, facetSource);
134 // clean old stuff, reopen
135 public void reinit(boolean eraseIndex) throws Exception {
138 IOUtils.close(indexWriter, indexReader, directory);
142 IOUtils.close(taxonomyWriter, taxonomyReader, taxonomyDir);
143 taxonomyWriter = null;
144 taxonomyReader = null;
146 // directory (default is ram-dir).
147 directory = createDirectory(eraseIndex, "index", "directory");
148 taxonomyDir = createDirectory(eraseIndex, "taxo", "taxonomy.directory");
153 // release unused stuff
154 System.runFinalization();
158 setStartTimeMillis();
161 private Directory createDirectory(boolean eraseIndex, String dirName,
162 String dirParam) throws IOException {
163 if ("FSDirectory".equals(config.get(dirParam,"RAMDirectory"))) {
164 File workDir = new File(config.get("work.dir","work"));
165 File indexDir = new File(workDir,dirName);
166 if (eraseIndex && indexDir.exists()) {
167 FileUtils.fullyDelete(indexDir);
170 return FSDirectory.open(indexDir);
173 return new RAMDirectory();
176 public long setStartTimeMillis() {
177 startTimeMillis = System.currentTimeMillis();
178 return startTimeMillis;
182 * @return Start time in milliseconds
184 public long getStartTimeMillis() {
185 return startTimeMillis;
189 * @return Returns the points.
191 public Points getPoints() {
196 * @return Returns the directory.
198 public Directory getDirectory() {
203 * @param directory The directory to set.
205 public void setDirectory(Directory directory) {
206 this.directory = directory;
210 * @return Returns the taxonomy directory
212 public Directory getTaxonomyDir() {
217 * Set the taxonomy reader. Takes ownership of that taxonomy reader, that is,
218 * internally performs taxoReader.incRef() (If caller no longer needs that
219 * reader it should decRef()/close() it after calling this method, otherwise,
220 * the reader will remain open).
221 * @param taxoReader The taxonomy reader to set.
223 public synchronized void setTaxonomyReader(TaxonomyReader taxoReader) throws IOException {
224 if (taxoReader == this.taxonomyReader) {
227 if (taxonomyReader != null) {
228 taxonomyReader.decRef();
231 if (taxoReader != null) {
234 this.taxonomyReader = taxoReader;
238 * @return Returns the taxonomyReader. NOTE: this returns a
239 * reference. You must call TaxonomyReader.decRef() when
242 public synchronized TaxonomyReader getTaxonomyReader() {
243 if (taxonomyReader != null) {
244 taxonomyReader.incRef();
246 return taxonomyReader;
250 * @param taxoWriter The taxonomy writer to set.
252 public void setTaxonomyWriter(TaxonomyWriter taxoWriter) {
253 this.taxonomyWriter = taxoWriter;
256 public TaxonomyWriter getTaxonomyWriter() {
257 return taxonomyWriter;
261 * @return Returns the indexReader. NOTE: this returns a
262 * reference. You must call IndexReader.decRef() when
265 public synchronized IndexReader getIndexReader() {
266 if (indexReader != null) {
267 indexReader.incRef();
273 * @return Returns the indexSearcher. NOTE: this returns
274 * a reference to the underlying IndexReader. You must
275 * call IndexReader.decRef() when you're done.
277 public synchronized IndexSearcher getIndexSearcher() {
278 if (indexReader != null) {
279 indexReader.incRef();
281 return indexSearcher;
285 * Set the index reader. Takes ownership of that index reader, that is,
286 * internally performs indexReader.incRef() (If caller no longer needs that
287 * reader it should decRef()/close() it after calling this method, otherwise,
288 * the reader will remain open).
289 * @param indexReader The indexReader to set.
291 public synchronized void setIndexReader(IndexReader indexReader) throws IOException {
292 if (indexReader == this.indexReader) {
296 if (this.indexReader != null) {
297 // Release current IR
298 this.indexReader.decRef();
301 this.indexReader = indexReader;
302 if (indexReader != null) {
303 // Hold reference to new IR
304 indexReader.incRef();
305 indexSearcher = new IndexSearcher(indexReader);
307 indexSearcher = null;
312 * @return Returns the indexWriter.
314 public IndexWriter getIndexWriter() {
319 * @param indexWriter The indexWriter to set.
321 public void setIndexWriter(IndexWriter indexWriter) {
322 this.indexWriter = indexWriter;
326 * @return Returns the anlyzer.
328 public Analyzer getAnalyzer() {
333 public void setAnalyzer(Analyzer analyzer) {
334 this.analyzer = analyzer;
337 /** Returns the docMaker. */
338 public DocMaker getDocMaker() {
342 /** Returns the facet source. */
343 public FacetSource getFacetSource() {
350 public Locale getLocale() {
355 * @param locale the locale to set
357 public void setLocale(Locale locale) {
358 this.locale = locale;
362 * @return Returns the config.
364 public Config getConfig() {
368 public void resetInputs() throws IOException {
369 docMaker.resetInputs();
370 facetSource.resetInputs();
371 for (final QueryMaker queryMaker : readTaskQueryMaker.values()) {
372 queryMaker.resetInputs();
377 * @return Returns the queryMaker by read task type (class)
379 synchronized public QueryMaker getQueryMaker(ReadTask readTask) {
380 // mapping the query maker by task class allows extending/adding new search/read tasks
381 // without needing to modify this class.
382 Class<? extends ReadTask> readTaskClass = readTask.getClass();
383 QueryMaker qm = readTaskQueryMaker.get(readTaskClass);
386 qm = qmkrClass.newInstance();
387 qm.setConfig(config);
388 } catch (Exception e) {
389 throw new RuntimeException(e);
391 readTaskQueryMaker.put(readTaskClass,qm);