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 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;
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:
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
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).
45 public abstract class PerfTask implements Cloneable {
47 static final int DEFAULT_LOG_STEP = 1000;
49 private PerfRunData runData;
51 // propeties that all tasks have
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;
60 private boolean runInBackground;
63 protected static final String NEW_LINE = System.getProperty("line.separator");
65 /** Should not be used externally */
67 name = getClass().getSimpleName();
68 if (name.endsWith("Task")) {
69 name = name.substring(0, name.length() - 4);
73 public void setRunInBackground(int deltaPri) {
74 runInBackground = true;
75 this.deltaPri = deltaPri;
78 public boolean getRunInBackground() {
79 return runInBackground;
82 public int getBackgroundDeltaPriority() {
86 protected volatile boolean stopNow;
88 public void stopNow() {
92 public PerfTask(PerfRunData runData) {
94 this.runData = runData;
95 Config config = runData.getConfig();
96 this.maxDepthLogStart = config.get("task.max.depth.log",0);
98 String logStepAtt = "log.step";
99 String taskLogStepAtt = "log.step." + name;
100 if (config.get(taskLogStepAtt, null) != null) {
101 logStepAtt = taskLogStepAtt;
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.
109 logStep = Integer.MAX_VALUE;
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();
120 public void close() throws Exception {
124 * Run the task, record statistics.
125 * @return number of work items done by this task.
127 public final int runAndMaybeStats(boolean reportStats) throws Exception {
128 if (!reportStats || shouldNotRecordStats()) {
130 int count = doLogic();
131 count = disableCounting ? 0 : count;
135 if (reportStats && depth <= maxDepthLogStart && !shouldNeverLogAtStart()) {
136 System.out.println("------------> starting task: " + getName());
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);
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.
155 public abstract int doLogic() throws Exception;
158 * @return Returns the name.
160 public String getName() {
164 return new StringBuilder(name).append('(').append(params).append(')').toString();
168 * @param name The name to set.
170 protected void setName(String name) {
175 * @return Returns the run data.
177 public PerfRunData getRunData() {
182 * @return Returns the depth.
184 public int getDepth() {
189 * @param depth The depth to set.
191 public void setDepth(int depth) {
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);
203 * @see java.lang.Object#toString()
206 public String toString() {
207 String padd = getPadding();
208 StringBuilder sb = new StringBuilder(padd);
209 if (disableCounting) {
212 sb.append(getName());
213 if (getRunInBackground()) {
215 int x = getBackgroundDeltaPriority();
220 return sb.toString();
224 * @return Returns the maxDepthLogStart.
226 int getMaxDepthLogStart() {
227 return maxDepthLogStart;
230 protected String getLogMessage(int recsCount) {
231 return "processed " + recsCount + " records";
235 * Tasks that should never log at start can override this.
236 * @return true if this task should never log when it start.
238 protected boolean shouldNeverLogAtStart () {
243 * Tasks that should not record statistics can override this.
244 * @return true if this task should never record its statistics.
246 protected boolean shouldNotRecordStats () {
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.
258 public void setup () throws Exception {
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.
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));
277 * Sub classes that supports parameters must override this method to return true.
278 * @return true iff this task supports command line params.
280 public boolean supportsParams () {
285 * Set the params of this task.
286 * @exception UnsupportedOperationException for tasks supporting command line parameters.
288 public void setParams(String params) {
289 if (!supportsParams()) {
290 throw new UnsupportedOperationException(getName()+" does not support command line parameters.");
292 this.params = params;
296 * @return Returns the Params.
298 public String getParams() {
303 * Return true if counting is disabled for this task.
305 public boolean isDisableCounting() {
306 return disableCounting;
310 * See {@link #isDisableCounting()}
312 public void setDisableCounting(boolean disableCounting) {
313 this.disableCounting = disableCounting;