001: package org.apache.lucene.benchmark.byTask.utils;
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 java.io.StreamTokenizer;
021: import java.io.StringReader;
022: import java.lang.reflect.Constructor;
023: import java.util.ArrayList;
024:
025: import org.apache.lucene.benchmark.byTask.PerfRunData;
026: import org.apache.lucene.benchmark.byTask.tasks.PerfTask;
027: import org.apache.lucene.benchmark.byTask.tasks.RepSumByPrefTask;
028: import org.apache.lucene.benchmark.byTask.tasks.TaskSequence;
029:
030: /**
031: * Test algorithm, as read from file
032: */
033: public class Algorithm {
034:
035: private TaskSequence sequence;
036:
037: /**
038: * Read algorithm from file
039: * @param runData perf-run-data used at running the tasks.
040: * @throws Exception if errors while parsing the algorithm
041: */
042: public Algorithm(PerfRunData runData) throws Exception {
043: String algTxt = runData.getConfig().getAlgorithmText();
044: sequence = new TaskSequence(runData, null, null, false);
045: TaskSequence currSequence = sequence;
046: PerfTask prevTask = null;
047: StreamTokenizer stok = new StreamTokenizer(new StringReader(
048: algTxt));
049: stok.commentChar('#');
050: stok.eolIsSignificant(false);
051: stok.ordinaryChar('"');
052: stok.ordinaryChar('/');
053: stok.ordinaryChar('(');
054: stok.ordinaryChar(')');
055: boolean colonOk = false;
056: currSequence.setDepth(0);
057: String taskPackage = PerfTask.class.getPackage().getName()
058: + ".";
059:
060: Class paramClass[] = { PerfRunData.class };
061: PerfRunData paramObj[] = { runData };
062:
063: while (stok.nextToken() != StreamTokenizer.TT_EOF) {
064: switch (stok.ttype) {
065:
066: case StreamTokenizer.TT_WORD:
067: String s = stok.sval;
068: Constructor cnstr = Class.forName(
069: taskPackage + s + "Task").getConstructor(
070: paramClass);
071: PerfTask task = (PerfTask) cnstr.newInstance(paramObj);
072: currSequence.addTask(task);
073: if (task instanceof RepSumByPrefTask) {
074: stok.nextToken();
075: String prefix = stok.sval;
076: if (prefix == null || prefix.length() == 0) {
077: throw new Exception(
078: "named report prefix problem - "
079: + stok.toString());
080: }
081: ((RepSumByPrefTask) task).setPrefix(prefix);
082: }
083: // check for task param: '(' someParam ')'
084: stok.nextToken();
085: if (stok.ttype != '(') {
086: stok.pushBack();
087: } else {
088: // get params, for tasks that supports them, - anything until next ')'
089: StringBuffer params = new StringBuffer();
090: stok.nextToken();
091: while (stok.ttype != ')') {
092: switch (stok.ttype) {
093: case StreamTokenizer.TT_NUMBER:
094: params.append(stok.nval);
095: break;
096: case StreamTokenizer.TT_WORD:
097: params.append(stok.sval);
098: break;
099: case StreamTokenizer.TT_EOF:
100: throw new Exception("unexpexted EOF: - "
101: + stok.toString());
102: default:
103: params.append((char) stok.ttype);
104: }
105: stok.nextToken();
106: }
107: String prm = params.toString().trim();
108: if (prm.length() > 0) {
109: task.setParams(prm);
110: }
111: }
112:
113: // ---------------------------------------
114: colonOk = false;
115: prevTask = task;
116: break;
117:
118: default:
119: char c = (char) stok.ttype;
120:
121: switch (c) {
122:
123: case ':':
124: if (!colonOk)
125: throw new Exception("colon unexpexted: - "
126: + stok.toString());
127: colonOk = false;
128: // get repetitions number
129: stok.nextToken();
130: if ((char) stok.ttype == '*') {
131: ((TaskSequence) prevTask)
132: .setRepetitions(TaskSequence.REPEAT_EXHAUST);
133: } else {
134: if (stok.ttype != StreamTokenizer.TT_NUMBER)
135: throw new Exception(
136: "expexted repetitions number: - "
137: + stok.toString());
138: ((TaskSequence) prevTask)
139: .setRepetitions((int) stok.nval);
140: }
141: // check for rate specification (ops/min)
142: stok.nextToken();
143: if (stok.ttype != ':') {
144: stok.pushBack();
145: } else {
146: // get rate number
147: stok.nextToken();
148: if (stok.ttype != StreamTokenizer.TT_NUMBER)
149: throw new Exception(
150: "expexted rate number: - "
151: + stok.toString());
152: // check for unit - min or sec, sec is default
153: stok.nextToken();
154: if (stok.ttype != '/') {
155: stok.pushBack();
156: ((TaskSequence) prevTask).setRate(
157: (int) stok.nval, false); // set rate per sec
158: } else {
159: stok.nextToken();
160: if (stok.ttype != StreamTokenizer.TT_WORD)
161: throw new Exception(
162: "expexted rate unit: 'min' or 'sec' - "
163: + stok.toString());
164: String unit = stok.sval.toLowerCase();
165: if ("min".equals(unit)) {
166: ((TaskSequence) prevTask).setRate(
167: (int) stok.nval, true); // set rate per min
168: } else if ("sec".equals(unit)) {
169: ((TaskSequence) prevTask).setRate(
170: (int) stok.nval, false); // set rate per sec
171: } else {
172: throw new Exception(
173: "expexted rate unit: 'min' or 'sec' - "
174: + stok.toString());
175: }
176: }
177: }
178: colonOk = false;
179: break;
180:
181: case '{':
182: case '[':
183: // a sequence
184: // check for sequence name
185: String name = null;
186: stok.nextToken();
187: if (stok.ttype != '"') {
188: stok.pushBack();
189: } else {
190: stok.nextToken();
191: name = stok.sval;
192: stok.nextToken();
193: if (stok.ttype != '"' || name == null
194: || name.length() == 0) {
195: throw new Exception(
196: "sequence name problem - "
197: + stok.toString());
198: }
199: }
200: // start the sequence
201: TaskSequence seq2 = new TaskSequence(runData, name,
202: currSequence, c == '[');
203: currSequence.addTask(seq2);
204: currSequence = seq2;
205: colonOk = false;
206: break;
207:
208: case '>':
209: currSequence.setNoChildReport();
210: case '}':
211: case ']':
212: // end sequence
213: colonOk = true;
214: prevTask = currSequence;
215: currSequence = currSequence.getParent();
216: break;
217:
218: } //switch(c)
219: break;
220:
221: } //switch(stok.ttype)
222:
223: }
224:
225: if (sequence != currSequence) {
226: throw new Exception("Unmatched sequences");
227: }
228:
229: // remove redundant top level enclosing sequences
230: while (sequence.getRepetitions() == 1
231: && sequence.getRate() == 0) {
232: ArrayList t = sequence.getTasks();
233: if (t != null && t.size() == 1) {
234: PerfTask p = (PerfTask) t.get(0);
235: if (p instanceof TaskSequence) {
236: sequence = (TaskSequence) p;
237: continue;
238: }
239: }
240: break;
241: }
242: }
243:
244: /* (non-Javadoc)
245: * @see java.lang.Object#toString()
246: */
247: public String toString() {
248: String newline = System.getProperty("line.separator");
249: StringBuffer sb = new StringBuffer();
250: sb.append(sequence.toString());
251: sb.append(newline);
252: return sb.toString();
253: }
254:
255: /**
256: * Execute this algorithm
257: * @throws Exception
258: */
259: public void execute() throws Exception {
260: sequence.doLogic();
261: }
262:
263: /**
264: * Expert: for test purposes, return all tasks participating in this algorithm.
265: * @return all tasks participating in this algorithm.
266: */
267: public ArrayList extractTasks() {
268: ArrayList res = new ArrayList();
269: extractTasks(res, sequence);
270: return res;
271: }
272:
273: private void extractTasks(ArrayList extrct, TaskSequence seq) {
274: if (seq == null)
275: return;
276: extrct.add(seq);
277: ArrayList t = sequence.getTasks();
278: if (t == null)
279: return;
280: for (int i = 0; i < t.size(); i++) {
281: PerfTask p = (PerfTask) t.get(0);
282: if (p instanceof TaskSequence) {
283: extractTasks(extrct, (TaskSequence) p);
284: } else {
285: extrct.add(p);
286: }
287: }
288: }
289:
290: }
|