+++ /dev/null
-package org.apache.lucene.benchmark.byTask.utils;
-
-/**
- * Licensed to the Apache Software Foundation (ASF) under one or more
- * contributor license agreements. See the NOTICE file distributed with
- * this work for additional information regarding copyright ownership.
- * The ASF licenses this file to You under the Apache License, Version 2.0
- * (the "License"); you may not use this file except in compliance with
- * the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-import java.io.StreamTokenizer;
-import java.io.StringReader;
-import java.lang.reflect.Constructor;
-import java.util.ArrayList;
-import java.util.Arrays;
-
-import org.apache.lucene.benchmark.byTask.PerfRunData;
-import org.apache.lucene.benchmark.byTask.tasks.PerfTask;
-import org.apache.lucene.benchmark.byTask.tasks.RepSumByPrefTask;
-import org.apache.lucene.benchmark.byTask.tasks.TaskSequence;
-
-/**
- * Test algorithm, as read from file
- */
-public class Algorithm {
-
- private TaskSequence sequence;
- private final String[] taskPackages;
-
- /**
- * Read algorithm from file
- * Property examined: alt.tasks.packages == comma separated list of
- * alternate package names where tasks would be searched for, when not found
- * in the default package (that of {@link PerfTask}{@link #getClass()}).
- * If the same task class appears in more than one package, the package
- * indicated first in this list will be used.
- * @param runData perf-run-data used at running the tasks.
- * @throws Exception if errors while parsing the algorithm
- */
- @SuppressWarnings("fallthrough")
- public Algorithm (PerfRunData runData) throws Exception {
- Config config = runData.getConfig();
- taskPackages = initTasksPackages(config);
- String algTxt = config.getAlgorithmText();
- sequence = new TaskSequence(runData,null,null,false);
- TaskSequence currSequence = sequence;
- PerfTask prevTask = null;
- StreamTokenizer stok = new StreamTokenizer(new StringReader(algTxt));
- stok.commentChar('#');
- stok.eolIsSignificant(false);
- stok.ordinaryChar('"');
- stok.ordinaryChar('/');
- stok.ordinaryChar('(');
- stok.ordinaryChar(')');
- boolean colonOk = false;
- boolean isDisableCountNextTask = false; // only for primitive tasks
- currSequence.setDepth(0);
-
- while (stok.nextToken() != StreamTokenizer.TT_EOF) {
- switch(stok.ttype) {
-
- case StreamTokenizer.TT_WORD:
- String s = stok.sval;
- Constructor<? extends PerfTask> cnstr = taskClass(config,s)
- .asSubclass(PerfTask.class).getConstructor(PerfRunData.class);
- PerfTask task = cnstr.newInstance(runData);
- task.setDisableCounting(isDisableCountNextTask);
- isDisableCountNextTask = false;
- currSequence.addTask(task);
- if (task instanceof RepSumByPrefTask) {
- stok.nextToken();
- String prefix = stok.sval;
- if (prefix==null || prefix.length()==0) {
- throw new Exception("named report prefix problem - "+stok.toString());
- }
- ((RepSumByPrefTask) task).setPrefix(prefix);
- }
- // check for task param: '(' someParam ')'
- stok.nextToken();
- if (stok.ttype!='(') {
- stok.pushBack();
- } else {
- // get params, for tasks that supports them, - anything until next ')'
- StringBuilder params = new StringBuilder();
- stok.nextToken();
- while (stok.ttype!=')') {
- switch (stok.ttype) {
- case StreamTokenizer.TT_NUMBER:
- params.append(stok.nval);
- break;
- case StreamTokenizer.TT_WORD:
- params.append(stok.sval);
- break;
- case StreamTokenizer.TT_EOF:
- throw new Exception("unexpexted EOF: - "+stok.toString());
- default:
- params.append((char)stok.ttype);
- }
- stok.nextToken();
- }
- String prm = params.toString().trim();
- if (prm.length()>0) {
- task.setParams(prm);
- }
- }
-
- // ---------------------------------------
- colonOk = false; prevTask = task;
- break;
-
- default:
- char c = (char)stok.ttype;
-
- switch(c) {
-
- case ':' :
- if (!colonOk) throw new Exception("colon unexpexted: - "+stok.toString());
- colonOk = false;
- // get repetitions number
- stok.nextToken();
- if ((char)stok.ttype == '*') {
- ((TaskSequence)prevTask).setRepetitions(TaskSequence.REPEAT_EXHAUST);
- } else {
- if (stok.ttype!=StreamTokenizer.TT_NUMBER) {
- throw new Exception("expected repetitions number or XXXs: - "+stok.toString());
- } else {
- double num = stok.nval;
- stok.nextToken();
- if (stok.ttype == StreamTokenizer.TT_WORD && stok.sval.equals("s")) {
- ((TaskSequence) prevTask).setRunTime(num);
- } else {
- stok.pushBack();
- ((TaskSequence) prevTask).setRepetitions((int) num);
- }
- }
- }
- // check for rate specification (ops/min)
- stok.nextToken();
- if (stok.ttype!=':') {
- stok.pushBack();
- } else {
- // get rate number
- stok.nextToken();
- if (stok.ttype!=StreamTokenizer.TT_NUMBER) throw new Exception("expected rate number: - "+stok.toString());
- // check for unit - min or sec, sec is default
- stok.nextToken();
- if (stok.ttype!='/') {
- stok.pushBack();
- ((TaskSequence)prevTask).setRate((int)stok.nval,false); // set rate per sec
- } else {
- stok.nextToken();
- if (stok.ttype!=StreamTokenizer.TT_WORD) throw new Exception("expected rate unit: 'min' or 'sec' - "+stok.toString());
- String unit = stok.sval.toLowerCase();
- if ("min".equals(unit)) {
- ((TaskSequence)prevTask).setRate((int)stok.nval,true); // set rate per min
- } else if ("sec".equals(unit)) {
- ((TaskSequence)prevTask).setRate((int)stok.nval,false); // set rate per sec
- } else {
- throw new Exception("expected rate unit: 'min' or 'sec' - "+stok.toString());
- }
- }
- }
- colonOk = false;
- break;
-
- case '{' :
- case '[' :
- // a sequence
- // check for sequence name
- String name = null;
- stok.nextToken();
- if (stok.ttype!='"') {
- stok.pushBack();
- } else {
- stok.nextToken();
- name = stok.sval;
- stok.nextToken();
- if (stok.ttype!='"' || name==null || name.length()==0) {
- throw new Exception("sequence name problem - "+stok.toString());
- }
- }
- // start the sequence
- TaskSequence seq2 = new TaskSequence(runData, name, currSequence, c=='[');
- currSequence.addTask(seq2);
- currSequence = seq2;
- colonOk = false;
- break;
-
- case '&' :
- if (currSequence.isParallel()) {
- throw new Exception("Can only create background tasks within a serial task");
- }
- stok.nextToken();
- final int deltaPri;
- if (stok.ttype != StreamTokenizer.TT_NUMBER) {
- stok.pushBack();
- deltaPri = 0;
- } else {
- // priority
- deltaPri = (int) stok.nval;
- }
-
- if (prevTask == null) {
- throw new Exception("& was unexpected");
- } else if (prevTask.getRunInBackground()) {
- throw new Exception("double & was unexpected");
- } else {
- prevTask.setRunInBackground(deltaPri);
- }
- break;
-
- case '>' :
- currSequence.setNoChildReport(); /* intentional fallthrough */
- case '}' :
- case ']' :
- // end sequence
- colonOk = true; prevTask = currSequence;
- currSequence = currSequence.getParent();
- break;
-
- case '-' :
- isDisableCountNextTask = true;
- break;
-
- } //switch(c)
- break;
-
- } //switch(stok.ttype)
-
- }
-
- if (sequence != currSequence) {
- throw new Exception("Unmatched sequences");
- }
-
- // remove redundant top level enclosing sequences
- while (sequence.isCollapsable() && sequence.getRepetitions()==1 && sequence.getRate()==0) {
- ArrayList<PerfTask> t = sequence.getTasks();
- if (t!=null && t.size()==1) {
- PerfTask p = t.get(0);
- if (p instanceof TaskSequence) {
- sequence = (TaskSequence) p;
- continue;
- }
- }
- break;
- }
- }
-
- private String[] initTasksPackages(Config config) {
- String alts = config.get("alt.tasks.packages", null);
- String dfltPkg = PerfTask.class.getPackage().getName();
- if (alts==null) {
- return new String[]{ dfltPkg };
- }
- ArrayList<String> pkgs = new ArrayList<String>();
- pkgs.add(dfltPkg);
- for (String alt : alts.split(",")) {
- pkgs.add(alt);
- }
- return pkgs.toArray(new String[0]);
- }
-
- private Class<?> taskClass(Config config, String taskName)
- throws ClassNotFoundException {
- for (String pkg : taskPackages) {
- try {
- return Class.forName(pkg+'.'+taskName+"Task");
- } catch (ClassNotFoundException e) {
- // failed in this package, might succeed in the next one...
- }
- }
- // can only get here if failed to instantiate
- throw new ClassNotFoundException(taskName+" not found in packages "+Arrays.toString(taskPackages));
- }
-
- @Override
- public String toString() {
- String newline = System.getProperty("line.separator");
- StringBuilder sb = new StringBuilder();
- sb.append(sequence.toString());
- sb.append(newline);
- return sb.toString();
- }
-
- /**
- * Execute this algorithm
- * @throws Exception
- */
- public void execute() throws Exception {
- try {
- sequence.runAndMaybeStats(true);
- } finally {
- sequence.close();
- }
- }
-
- /**
- * Expert: for test purposes, return all tasks participating in this algorithm.
- * @return all tasks participating in this algorithm.
- */
- public ArrayList<PerfTask> extractTasks() {
- ArrayList<PerfTask> res = new ArrayList<PerfTask>();
- extractTasks(res, sequence);
- return res;
- }
- private void extractTasks (ArrayList<PerfTask> extrct, TaskSequence seq) {
- if (seq==null)
- return;
- extrct.add(seq);
- ArrayList<PerfTask> t = sequence.getTasks();
- if (t==null)
- return;
- for (final PerfTask p : t) {
- if (p instanceof TaskSequence) {
- extractTasks(extrct, (TaskSequence)p);
- } else {
- extrct.add(p);
- }
- }
- }
-
-}
-