pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / benchmark / src / java / org / apache / lucene / benchmark / byTask / PerfRunData.java
1 package org.apache.lucene.benchmark.byTask;
2
3 /**
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
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  */
19
20 import java.io.Closeable;
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.HashMap;
24 import java.util.Locale;
25
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;
45
46 /**
47  * Data maintained by a performance test run.
48  * <p>
49  * Data includes:
50  * <ul>
51  *  <li>Configuration.
52  *  <li>Directory, Writer, Reader.
53  *  <li>Taxonomy Directory, Writer, Reader.
54  *  <li>DocMaker, FacetSource and a few instances of QueryMaker.
55  *  <li>Analyzer.
56  *  <li>Statistics data which updated during the run.
57  * </ul>
58  * Config properties:
59  * <ul>
60  *  <li><b>work.dir</b>=&lt;path to root of docs and index dirs| Default: work&gt;
61  *  <li><b>analyzer</b>=&lt;class name for analyzer| Default: StandardAnalyzer&gt;
62  *  <li><b>doc.maker</b>=&lt;class name for doc-maker| Default: DocMaker&gt;
63  *  <li><b>facet.source</b>=&lt;class name for facet-source| Default: RandomFacetSource&gt;
64  *  <li><b>query.maker</b>=&lt;class name for query-maker| Default: SimpleQueryMaker&gt;
65  *  <li><b>log.queries</b>=&lt;whether queries should be printed| Default: false&gt;
66  *  <li><b>directory</b>=&lt;type of directory to use for the index| Default: RAMDirectory&gt;
67  *  <li><b>taxonomy.directory</b>=&lt;type of directory for taxonomy index| Default: RAMDirectory&gt;
68  * </ul>
69  */
70 public class PerfRunData implements Closeable {
71
72   private Points points;
73   
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;
82
83   private Directory taxonomyDir;
84   private TaxonomyWriter taxonomyWriter;
85   private TaxonomyReader taxonomyReader;
86   
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;
90
91   private IndexReader indexReader;
92   private IndexSearcher indexSearcher;
93   private IndexWriter indexWriter;
94   private Config config;
95   private long startTimeMillis;
96
97   
98   // constructor
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"));
104     // doc maker
105     docMaker = Class.forName(config.get("doc.maker",
106         "org.apache.lucene.benchmark.byTask.feeds.DocMaker")).asSubclass(DocMaker.class).newInstance();
107     docMaker.setConfig(config);
108     // facet source
109     facetSource = Class.forName(config.get("facet.source",
110         "org.apache.lucene.benchmark.byTask.feeds.RandomFacetSource")).asSubclass(FacetSource.class).newInstance();
111     facetSource.setConfig(config);
112     // query makers
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);
115
116     // index stuff
117     reinit(false);
118     
119     // statistic points
120     points = new Points(config);
121     
122     if (Boolean.valueOf(config.get("log.queries","false")).booleanValue()) {
123       System.out.println("------------> queries:");
124       System.out.println(getQueryMaker(new SearchTask(this)).printQueries());
125     }
126   }
127   
128   public void close() throws IOException {
129     IOUtils.close(indexWriter, indexReader, indexSearcher, directory, 
130                   taxonomyWriter, taxonomyReader, taxonomyDir, 
131                   docMaker, facetSource);
132   }
133
134   // clean old stuff, reopen 
135   public void reinit(boolean eraseIndex) throws Exception {
136
137     // cleanup index
138     IOUtils.close(indexWriter, indexReader, directory);
139     indexWriter = null;
140     indexReader = null;
141
142     IOUtils.close(taxonomyWriter, taxonomyReader, taxonomyDir);
143     taxonomyWriter = null;
144     taxonomyReader = null;
145     
146     // directory (default is ram-dir).
147     directory = createDirectory(eraseIndex, "index", "directory");
148     taxonomyDir = createDirectory(eraseIndex, "taxo", "taxonomy.directory");
149
150     // inputs
151     resetInputs();
152     
153     // release unused stuff
154     System.runFinalization();
155     System.gc();
156
157     // Re-init clock
158     setStartTimeMillis();
159   }
160
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);
168       }
169       indexDir.mkdirs();
170       return FSDirectory.open(indexDir);
171     } 
172
173     return new RAMDirectory();
174   }
175   
176   public long setStartTimeMillis() {
177     startTimeMillis = System.currentTimeMillis();
178     return startTimeMillis;
179   }
180
181   /**
182    * @return Start time in milliseconds
183    */
184   public long getStartTimeMillis() {
185     return startTimeMillis;
186   }
187
188   /**
189    * @return Returns the points.
190    */
191   public Points getPoints() {
192     return points;
193   }
194
195   /**
196    * @return Returns the directory.
197    */
198   public Directory getDirectory() {
199     return directory;
200   }
201
202   /**
203    * @param directory The directory to set.
204    */
205   public void setDirectory(Directory directory) {
206     this.directory = directory;
207   }
208
209   /**
210    * @return Returns the taxonomy directory
211    */
212   public Directory getTaxonomyDir() {
213     return taxonomyDir;
214   }
215   
216   /**
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.
222    */
223   public synchronized void setTaxonomyReader(TaxonomyReader taxoReader) throws IOException {
224     if (taxoReader == this.taxonomyReader) {
225       return;
226     }
227     if (taxonomyReader != null) {
228       taxonomyReader.decRef();
229     }
230     
231     if (taxoReader != null) {
232       taxoReader.incRef();
233     }
234     this.taxonomyReader = taxoReader;
235   }
236   
237   /**
238    * @return Returns the taxonomyReader.  NOTE: this returns a
239    * reference.  You must call TaxonomyReader.decRef() when
240    * you're done.
241    */
242   public synchronized TaxonomyReader getTaxonomyReader() {
243     if (taxonomyReader != null) {
244       taxonomyReader.incRef();
245     }
246     return taxonomyReader;
247   }
248   
249   /**
250    * @param taxoWriter The taxonomy writer to set.
251    */
252   public void setTaxonomyWriter(TaxonomyWriter taxoWriter) {
253     this.taxonomyWriter = taxoWriter;
254   }
255   
256   public TaxonomyWriter getTaxonomyWriter() {
257     return taxonomyWriter;
258   }
259   
260   /**
261    * @return Returns the indexReader.  NOTE: this returns a
262    * reference.  You must call IndexReader.decRef() when
263    * you're done.
264    */
265   public synchronized IndexReader getIndexReader() {
266     if (indexReader != null) {
267       indexReader.incRef();
268     }
269     return indexReader;
270   }
271
272   /**
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.
276    */
277   public synchronized IndexSearcher getIndexSearcher() {
278     if (indexReader != null) {
279       indexReader.incRef();
280     }
281     return indexSearcher;
282   }
283
284   /**
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.
290    */
291   public synchronized void setIndexReader(IndexReader indexReader) throws IOException {
292     if (indexReader == this.indexReader) {
293       return;
294     }
295     
296     if (this.indexReader != null) {
297       // Release current IR
298       this.indexReader.decRef();
299     }
300
301     this.indexReader = indexReader;
302     if (indexReader != null) {
303       // Hold reference to new IR
304       indexReader.incRef();
305       indexSearcher = new IndexSearcher(indexReader);
306     } else {
307       indexSearcher = null;
308     }
309   }
310
311   /**
312    * @return Returns the indexWriter.
313    */
314   public IndexWriter getIndexWriter() {
315     return indexWriter;
316   }
317
318   /**
319    * @param indexWriter The indexWriter to set.
320    */
321   public void setIndexWriter(IndexWriter indexWriter) {
322     this.indexWriter = indexWriter;
323   }
324
325   /**
326    * @return Returns the anlyzer.
327    */
328   public Analyzer getAnalyzer() {
329     return analyzer;
330   }
331
332
333   public void setAnalyzer(Analyzer analyzer) {
334     this.analyzer = analyzer;
335   }
336
337   /** Returns the docMaker. */
338   public DocMaker getDocMaker() {
339     return docMaker;
340   }
341
342   /** Returns the facet source. */
343   public FacetSource getFacetSource() {
344     return facetSource;
345   }
346
347   /**
348    * @return the locale
349    */
350   public Locale getLocale() {
351     return locale;
352   }
353
354   /**
355    * @param locale the locale to set
356    */
357   public void setLocale(Locale locale) {
358     this.locale = locale;
359   }
360
361   /**
362    * @return Returns the config.
363    */
364   public Config getConfig() {
365     return config;
366   }
367
368   public void resetInputs() throws IOException {
369     docMaker.resetInputs();
370     facetSource.resetInputs();
371     for (final QueryMaker queryMaker : readTaskQueryMaker.values()) {
372       queryMaker.resetInputs();
373     }
374   }
375
376   /**
377    * @return Returns the queryMaker by read task type (class)
378    */
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);
384     if (qm == null) {
385       try {
386         qm = qmkrClass.newInstance();
387         qm.setConfig(config);
388       } catch (Exception e) {
389         throw new RuntimeException(e);
390       }
391       readTaskQueryMaker.put(readTaskClass,qm);
392     }
393     return qm;
394   }
395
396 }