001: package org.apache.lucene.benchmark.byTask.tasks;
002:
003: /**
004: * Licensed to the Apache Software Foundation (ASF) under one or more
005: * contributor license agreements. See the NOTICE file distributed with
006: * this work for additional information regarding copyright ownership.
007: * The ASF licenses this file to You under the Apache License, Version 2.0
008: * (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: *
011: * http://www.apache.org/licenses/LICENSE-2.0
012: *
013: * Unless required by applicable law or agreed to in writing, software
014: * distributed under the License is distributed on an "AS IS" BASIS,
015: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
016: * See the License for the specific language governing permissions and
017: * limitations under the License.
018: */
019:
020: import org.apache.lucene.benchmark.byTask.PerfRunData;
021: import org.apache.lucene.benchmark.byTask.stats.Points;
022: import org.apache.lucene.benchmark.byTask.stats.TaskStats;
023: import org.apache.lucene.benchmark.byTask.utils.Format;
024:
025: /**
026: * A (abstract) task to be tested for performance.
027: * <br>
028: * Every performance task extends this class, and provides its own doLogic() method,
029: * which performss the actual task.
030: * <br>
031: * Tasks performing some work that should be measured for the task, can overide setup() and/or tearDown() and
032: * placed that work there.
033: * <br>
034: * Relevant properties: <code>task.max.depth.log</code>.
035: */
036: public abstract class PerfTask implements Cloneable {
037:
038: private PerfRunData runData;
039:
040: // propeties that all tasks have
041: private String name;
042: private int depth = 0;
043: private int maxDepthLogStart = 0;
044: protected String params = null;
045:
046: protected static final String NEW_LINE = System
047: .getProperty("line.separator");
048:
049: /**
050: * Should not be used externally
051: */
052: private PerfTask() {
053: name = Format.simpleName(getClass());
054: if (name.endsWith("Task")) {
055: name = name.substring(0, name.length() - 4);
056: }
057: }
058:
059: public PerfTask(PerfRunData runData) {
060: this ();
061: this .runData = runData;
062: this .maxDepthLogStart = runData.getConfig().get(
063: "task.max.depth.log", 0);
064: }
065:
066: /* (non-Javadoc)
067: * @see java.lang.Object#clone()
068: */
069: protected Object clone() throws CloneNotSupportedException {
070: // tasks having non primitive data structures should overide this.
071: // otherwise parallel running of a task sequence might not run crrectly.
072: return super .clone();
073: }
074:
075: /**
076: * Run the task, record statistics.
077: * @return number of work items done by this task.
078: */
079: public final int runAndMaybeStats(boolean reportStats)
080: throws Exception {
081: if (reportStats && depth <= maxDepthLogStart
082: && !shouldNeverLogAtStart()) {
083: System.out.println("------------> starting task: "
084: + getName());
085: }
086: if (!reportStats || shouldNotRecordStats()) {
087: setup();
088: int count = doLogic();
089: tearDown();
090: return count;
091: }
092: setup();
093: Points pnts = runData.getPoints();
094: TaskStats ts = pnts.markTaskStart(this , runData.getConfig()
095: .getRoundNumber());
096: int count = doLogic();
097: pnts.markTaskEnd(ts, count);
098: tearDown();
099: return count;
100: }
101:
102: /**
103: * Perform the task once (ignoring repetions specification)
104: * Return number of work items done by this task.
105: * For indexing that can be number of docs added.
106: * For warming that can be number of scanned items, etc.
107: * @return number of work items done by this task.
108: */
109: public abstract int doLogic() throws Exception;
110:
111: /**
112: * @return Returns the name.
113: */
114: public String getName() {
115: if (params == null) {
116: return name;
117: }
118: return new StringBuffer(name).append('(').append(params)
119: .append(')').toString();
120: }
121:
122: /**
123: * @param name The name to set.
124: */
125: protected void setName(String name) {
126: this .name = name;
127: }
128:
129: /**
130: * @return Returns the run data.
131: */
132: public PerfRunData getRunData() {
133: return runData;
134: }
135:
136: /**
137: * @return Returns the depth.
138: */
139: public int getDepth() {
140: return depth;
141: }
142:
143: /**
144: * @param depth The depth to set.
145: */
146: public void setDepth(int depth) {
147: this .depth = depth;
148: }
149:
150: // compute a blank string padding for printing this task indented by its depth
151: String getPadding() {
152: char c[] = new char[4 * getDepth()];
153: for (int i = 0; i < c.length; i++)
154: c[i] = ' ';
155: return new String(c);
156: }
157:
158: /* (non-Javadoc)
159: * @see java.lang.Object#toString()
160: */
161: public String toString() {
162: String padd = getPadding();
163: StringBuffer sb = new StringBuffer(padd);
164: sb.append(getName());
165: return sb.toString();
166: }
167:
168: /**
169: * @return Returns the maxDepthLogStart.
170: */
171: int getMaxDepthLogStart() {
172: return maxDepthLogStart;
173: }
174:
175: /**
176: * Tasks that should never log at start can overide this.
177: * @return true if this task should never log when it start.
178: */
179: protected boolean shouldNeverLogAtStart() {
180: return false;
181: }
182:
183: /**
184: * Tasks that should not record statistics can overide this.
185: * @return true if this task should never record its statistics.
186: */
187: protected boolean shouldNotRecordStats() {
188: return false;
189: }
190:
191: /**
192: * Task setup work that should not be measured for that specific task.
193: * By default it does nothing, but tasks can implement this, moving work from
194: * doLogic() to this method. Only the work done in doLogicis measured for this task.
195: * Notice that higher level (sequence) tasks containing this task would then
196: * measure larger time than the sum of their contained tasks.
197: * @throws Exception
198: */
199: public void setup() throws Exception {
200: }
201:
202: /**
203: * Task tearDown work that should not be measured for that specific task.
204: * By default it does nothing, but tasks can implement this, moving work from
205: * doLogic() to this method. Only the work done in doLogicis measured for this task.
206: * Notice that higher level (sequence) tasks containing this task would then
207: * measure larger time than the sum of their contained tasks.
208: */
209: public void tearDown() throws Exception {
210: }
211:
212: /**
213: * Sub classes that supports parameters must overide this method to return true.
214: * @return true iff this task supports command line params.
215: */
216: public boolean supportsParams() {
217: return false;
218: }
219:
220: /**
221: * Set the params of this task.
222: * @exception UnsupportedOperationException for tasks supporting command line parameters.
223: */
224: public void setParams(String params) {
225: if (!supportsParams()) {
226: throw new UnsupportedOperationException(getName()
227: + " does not support command line parameters.");
228: }
229: this .params = params;
230: }
231:
232: /**
233: * @return Returns the Params.
234: */
235: public String getParams() {
236: return params;
237: }
238:
239: }
|