1 package org.apache.lucene.benchmark.byTask.tasks;
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.text.NumberFormat;
22 import org.apache.lucene.benchmark.byTask.PerfRunData;
23 import org.apache.lucene.benchmark.byTask.stats.Points;
24 import org.apache.lucene.benchmark.byTask.stats.TaskStats;
25 import org.apache.lucene.benchmark.byTask.utils.Config;
28 * An abstract task to be tested for performance. <br>
29 * Every performance task extends this class, and provides its own
30 * {@link #doLogic()} method, which performs the actual task. <br>
31 * Tasks performing some work that should be measured for the task, can override
32 * {@link #setup()} and/or {@link #tearDown()} and place that work there. <br>
33 * Relevant properties: <code>task.max.depth.log</code>.<br>
34 * Also supports the following logging attributes:
36 * <li>log.step - specifies how often to log messages about the current running
37 * task. Default is 1000 {@link #doLogic()} invocations. Set to -1 to disable
39 * <li>log.step.[class Task Name] - specifies the same as 'log.step', only for a
40 * particular task name. For example, log.step.AddDoc will be applied only for
41 * {@link AddDocTask}, but not for {@link DeleteDocTask}. It's a way to control
42 * per task logging settings. If you want to omit logging for any other task,
43 * include log.step=-1. The syntax is "log.step." together with the Task's
44 * 'short' name (i.e., without the 'Task' part).
47 public abstract class PerfTask implements Cloneable {
49 static final int DEFAULT_LOG_STEP = 1000;
51 private PerfRunData runData;
53 // propeties that all tasks have
55 private int depth = 0;
56 protected int logStep;
57 private int logStepCount = 0;
58 private int maxDepthLogStart = 0;
59 private boolean disableCounting = false;
60 protected String params = null;
62 private boolean runInBackground;
65 protected static final String NEW_LINE = System.getProperty("line.separator");
67 /** Should not be used externally */
69 name = getClass().getSimpleName();
70 if (name.endsWith("Task")) {
71 name = name.substring(0, name.length() - 4);
75 public void setRunInBackground(int deltaPri) {
76 runInBackground = true;
77 this.deltaPri = deltaPri;
80 public boolean getRunInBackground() {
81 return runInBackground;
84 public int getBackgroundDeltaPriority() {
88 protected volatile boolean stopNow;
90 public void stopNow() {
94 public PerfTask(PerfRunData runData) {
96 this.runData = runData;
97 Config config = runData.getConfig();
98 this.maxDepthLogStart = config.get("task.max.depth.log",0);
100 String logStepAtt = "log.step";
101 String taskLogStepAtt = "log.step." + name;
102 if (config.get(taskLogStepAtt, null) != null) {
103 logStepAtt = taskLogStepAtt;
106 // It's important to read this from Config, to support vals-by-round.
107 logStep = config.get(logStepAtt, DEFAULT_LOG_STEP);
108 // To avoid the check 'if (logStep > 0)' in tearDown(). This effectively
109 // turns logging off.
111 logStep = Integer.MAX_VALUE;
116 protected Object clone() throws CloneNotSupportedException {
117 // tasks having non primitive data structures should override this.
118 // otherwise parallel running of a task sequence might not run correctly.
119 return super.clone();
122 public void close() throws Exception {
126 * Run the task, record statistics.
127 * @return number of work items done by this task.
129 public final int runAndMaybeStats(boolean reportStats) throws Exception {
130 if (!reportStats || shouldNotRecordStats()) {
132 int count = doLogic();
133 count = disableCounting ? 0 : count;
137 if (reportStats && depth <= maxDepthLogStart && !shouldNeverLogAtStart()) {
138 System.out.println("------------> starting task: " + getName());
141 Points pnts = runData.getPoints();
142 TaskStats ts = pnts.markTaskStart(this, runData.getConfig().getRoundNumber());
143 int count = doLogic();
144 count = disableCounting ? 0 : count;
145 pnts.markTaskEnd(ts, count);
151 * Perform the task once (ignoring repetitions specification)
152 * Return number of work items done by this task.
153 * For indexing that can be number of docs added.
154 * For warming that can be number of scanned items, etc.
155 * @return number of work items done by this task.
157 public abstract int doLogic() throws Exception;
160 * @return Returns the name.
162 public String getName() {
166 return new StringBuilder(name).append('(').append(params).append(')').toString();
170 * @param name The name to set.
172 protected void setName(String name) {
177 * @return Returns the run data.
179 public PerfRunData getRunData() {
184 * @return Returns the depth.
186 public int getDepth() {
191 * @param depth The depth to set.
193 public void setDepth(int depth) {
197 // compute a blank string padding for printing this task indented by its depth
198 String getPadding () {
199 char c[] = new char[4*getDepth()];
200 for (int i = 0; i < c.length; i++) c[i] = ' ';
201 return new String(c);
205 * @see java.lang.Object#toString()
208 public String toString() {
209 String padd = getPadding();
210 StringBuilder sb = new StringBuilder(padd);
211 if (disableCounting) {
214 sb.append(getName());
215 if (getRunInBackground()) {
217 int x = getBackgroundDeltaPriority();
222 return sb.toString();
226 * @return Returns the maxDepthLogStart.
228 int getMaxDepthLogStart() {
229 return maxDepthLogStart;
232 protected String getLogMessage(int recsCount) {
233 return "processed " + recsCount + " records";
237 * Tasks that should never log at start can override this.
238 * @return true if this task should never log when it start.
240 protected boolean shouldNeverLogAtStart () {
245 * Tasks that should not record statistics can override this.
246 * @return true if this task should never record its statistics.
248 protected boolean shouldNotRecordStats () {
253 * Task setup work that should not be measured for that specific task.
254 * By default it does nothing, but tasks can implement this, moving work from
255 * doLogic() to this method. Only the work done in doLogicis measured for this task.
256 * Notice that higher level (sequence) tasks containing this task would then
257 * measure larger time than the sum of their contained tasks.
260 public void setup () throws Exception {
264 * Task tearDown work that should not be measured for that specific task.
265 * By default it does nothing, but tasks can implement this, moving work from
266 * doLogic() to this method. Only the work done in doLogicis measured for this task.
267 * Notice that higher level (sequence) tasks containing this task would then
268 * measure larger time than the sum of their contained tasks.
270 public void tearDown() throws Exception {
271 if (++logStepCount % logStep == 0) {
272 double time = (System.currentTimeMillis() - runData.getStartTimeMillis()) / 1000.0;
273 NumberFormat nf = NumberFormat.getInstance();
274 nf.setMaximumFractionDigits(2);
275 System.out.println(nf.format(time) + " sec --> "
276 + Thread.currentThread().getName() + " " + getLogMessage(logStepCount));
281 * Sub classes that supports parameters must override this method to return true.
282 * @return true iff this task supports command line params.
284 public boolean supportsParams () {
289 * Set the params of this task.
290 * @exception UnsupportedOperationException for tasks supporting command line parameters.
292 public void setParams(String params) {
293 if (!supportsParams()) {
294 throw new UnsupportedOperationException(getName()+" does not support command line parameters.");
296 this.params = params;
300 * @return Returns the Params.
302 public String getParams() {
307 * Return true if counting is disabled for this task.
309 public boolean isDisableCounting() {
310 return disableCounting;
314 * See {@link #isDisableCounting()}
316 public void setDisableCounting(boolean disableCounting) {
317 this.disableCounting = disableCounting;