pylucene 3.5.0-3
[pylucene.git] / lucene-java-3.5.0 / lucene / contrib / benchmark / src / java / org / apache / lucene / benchmark / byTask / tasks / PerfTask.java
1 package org.apache.lucene.benchmark.byTask.tasks;
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 org.apache.lucene.benchmark.byTask.PerfRunData;
21 import org.apache.lucene.benchmark.byTask.stats.Points;
22 import org.apache.lucene.benchmark.byTask.stats.TaskStats;
23 import org.apache.lucene.benchmark.byTask.utils.Config;
24
25 /**
26  * An abstract task to be tested for performance. <br>
27  * Every performance task extends this class, and provides its own
28  * {@link #doLogic()} method, which performs the actual task. <br>
29  * Tasks performing some work that should be measured for the task, can override
30  * {@link #setup()} and/or {@link #tearDown()} and place that work there. <br>
31  * Relevant properties: <code>task.max.depth.log</code>.<br>
32  * Also supports the following logging attributes:
33  * <ul>
34  * <li>log.step - specifies how often to log messages about the current running
35  * task. Default is 1000 {@link #doLogic()} invocations. Set to -1 to disable
36  * logging.
37  * <li>log.step.[class Task Name] - specifies the same as 'log.step', only for a
38  * particular task name. For example, log.step.AddDoc will be applied only for
39  * {@link AddDocTask}, but not for {@link DeleteDocTask}. It's a way to control
40  * per task logging settings. If you want to omit logging for any other task,
41  * include log.step=-1. The syntax is "log.step." together with the Task's
42  * 'short' name (i.e., without the 'Task' part).
43  * </ul>
44  */
45 public abstract class PerfTask implements Cloneable {
46
47   static final int DEFAULT_LOG_STEP = 1000;
48   
49   private PerfRunData runData;
50   
51   // propeties that all tasks have
52   private String name;
53   private int depth = 0;
54   protected int logStep;
55   private int logStepCount = 0;
56   private int maxDepthLogStart = 0;
57   private boolean disableCounting = false;
58   protected String params = null;
59
60   private boolean runInBackground;
61   private int deltaPri;
62
63   protected static final String NEW_LINE = System.getProperty("line.separator");
64
65   /** Should not be used externally */
66   private PerfTask() {
67     name = getClass().getSimpleName();
68     if (name.endsWith("Task")) {
69       name = name.substring(0, name.length() - 4);
70     }
71   }
72
73   public void setRunInBackground(int deltaPri) {
74     runInBackground = true;
75     this.deltaPri = deltaPri;
76   }
77
78   public boolean getRunInBackground() {
79     return runInBackground;
80   }
81
82   public int getBackgroundDeltaPriority() {
83     return deltaPri;
84   }
85
86   protected volatile boolean stopNow;
87
88   public void stopNow() {
89     stopNow = true;
90   }
91
92   public PerfTask(PerfRunData runData) {
93     this();
94     this.runData = runData;
95     Config config = runData.getConfig();
96     this.maxDepthLogStart = config.get("task.max.depth.log",0);
97
98     String logStepAtt = "log.step";
99     String taskLogStepAtt = "log.step." + name;
100     if (config.get(taskLogStepAtt, null) != null) {
101       logStepAtt = taskLogStepAtt;
102     }
103
104     // It's important to read this from Config, to support vals-by-round.
105     logStep = config.get(logStepAtt, DEFAULT_LOG_STEP);
106     // To avoid the check 'if (logStep > 0)' in tearDown(). This effectively
107     // turns logging off.
108     if (logStep <= 0) {
109       logStep = Integer.MAX_VALUE;
110     }
111   }
112   
113   @Override
114   protected Object clone() throws CloneNotSupportedException {
115     // tasks having non primitive data structures should override this.
116     // otherwise parallel running of a task sequence might not run correctly. 
117     return super.clone();
118   }
119
120   public void close() throws Exception {
121   }
122
123   /**
124    * Run the task, record statistics.
125    * @return number of work items done by this task.
126    */
127   public final int runAndMaybeStats(boolean reportStats) throws Exception {
128     if (!reportStats || shouldNotRecordStats()) {
129       setup();
130       int count = doLogic();
131       count = disableCounting ? 0 : count;
132       tearDown();
133       return count;
134     }
135     if (reportStats && depth <= maxDepthLogStart && !shouldNeverLogAtStart()) {
136       System.out.println("------------> starting task: " + getName());
137     }
138     setup();
139     Points pnts = runData.getPoints();
140     TaskStats ts = pnts.markTaskStart(this, runData.getConfig().getRoundNumber());
141     int count = doLogic();
142     count = disableCounting ? 0 : count;
143     pnts.markTaskEnd(ts, count);
144     tearDown();
145     return count;
146   }
147
148   /**
149    * Perform the task once (ignoring repetitions specification)
150    * Return number of work items done by this task.
151    * For indexing that can be number of docs added.
152    * For warming that can be number of scanned items, etc.
153    * @return number of work items done by this task.
154    */
155   public abstract int doLogic() throws Exception;
156   
157   /**
158    * @return Returns the name.
159    */
160   public String getName() {
161     if (params==null) {
162       return name;
163     } 
164     return new StringBuilder(name).append('(').append(params).append(')').toString();
165   }
166
167   /**
168    * @param name The name to set.
169    */
170   protected void setName(String name) {
171     this.name = name;
172   }
173
174   /**
175    * @return Returns the run data.
176    */
177   public PerfRunData getRunData() {
178     return runData;
179   }
180
181   /**
182    * @return Returns the depth.
183    */
184   public int getDepth() {
185     return depth;
186   }
187
188   /**
189    * @param depth The depth to set.
190    */
191   public void setDepth(int depth) {
192     this.depth = depth;
193   }
194   
195   // compute a blank string padding for printing this task indented by its depth  
196   String getPadding () {
197     char c[] = new char[4*getDepth()];
198     for (int i = 0; i < c.length; i++) c[i] = ' ';
199     return new String(c);
200   }
201   
202   /* (non-Javadoc)
203    * @see java.lang.Object#toString()
204    */
205   @Override
206   public String toString() {
207     String padd = getPadding();
208     StringBuilder sb = new StringBuilder(padd);
209     if (disableCounting) {
210       sb.append('-');
211     }
212     sb.append(getName());
213     if (getRunInBackground()) {
214       sb.append(" &");
215       int x = getBackgroundDeltaPriority();
216       if (x != 0) {
217         sb.append(x);
218       }
219     }
220     return sb.toString();
221   }
222
223   /**
224    * @return Returns the maxDepthLogStart.
225    */
226   int getMaxDepthLogStart() {
227     return maxDepthLogStart;
228   }
229
230   protected String getLogMessage(int recsCount) {
231     return "processed " + recsCount + " records";
232   }
233   
234   /**
235    * Tasks that should never log at start can override this.  
236    * @return true if this task should never log when it start.
237    */
238   protected boolean shouldNeverLogAtStart () {
239     return false;
240   }
241   
242   /**
243    * Tasks that should not record statistics can override this.  
244    * @return true if this task should never record its statistics.
245    */
246   protected boolean shouldNotRecordStats () {
247     return false;
248   }
249
250   /**
251    * Task setup work that should not be measured for that specific task.
252    * By default it does nothing, but tasks can implement this, moving work from 
253    * doLogic() to this method. Only the work done in doLogicis measured for this task.
254    * Notice that higher level (sequence) tasks containing this task would then 
255    * measure larger time than the sum of their contained tasks.
256    * @throws Exception 
257    */
258   public void setup () throws Exception {
259   }
260   
261   /**
262    * Task tearDown work that should not be measured for that specific task.
263    * By default it does nothing, but tasks can implement this, moving work from 
264    * doLogic() to this method. Only the work done in doLogicis measured for this task.
265    * Notice that higher level (sequence) tasks containing this task would then 
266    * measure larger time than the sum of their contained tasks.
267    */
268   public void tearDown() throws Exception {
269     if (++logStepCount % logStep == 0) {
270       double time = (System.currentTimeMillis() - runData.getStartTimeMillis()) / 1000.0;
271       System.out.println(String.format("%7.2f",time) + " sec --> "
272           + Thread.currentThread().getName() + " " + getLogMessage(logStepCount));
273     }
274   }
275
276   /**
277    * Sub classes that supports parameters must override this method to return true.
278    * @return true iff this task supports command line params.
279    */
280   public boolean supportsParams () {
281     return false;
282   }
283   
284   /**
285    * Set the params of this task.
286    * @exception UnsupportedOperationException for tasks supporting command line parameters.
287    */
288   public void setParams(String params) {
289     if (!supportsParams()) {
290       throw new UnsupportedOperationException(getName()+" does not support command line parameters.");
291     }
292     this.params = params;
293   }
294   
295   /**
296    * @return Returns the Params.
297    */
298   public String getParams() {
299     return params;
300   }
301
302   /**
303    * Return true if counting is disabled for this task.
304    */
305   public boolean isDisableCounting() {
306     return disableCounting;
307   }
308
309   /**
310    * See {@link #isDisableCounting()}
311    */
312   public void setDisableCounting(boolean disableCounting) {
313     this.disableCounting = disableCounting;
314   }
315
316 }