Index: conf/micro-standard.alg =================================================================== --- conf/micro-standard.alg (revision 519567) +++ conf/micro-standard.alg (working copy) @@ -64,9 +64,9 @@ { "SrchNewRdr" Search > : 500 - { "SrchTrvNewRdr" SearchTrav > : 300 + { "SrchTrvNewRdr" SearchTrav(1000) > : 300 - { "SrchTrvRetNewRdr" SearchTravRet > : 100 + { "SrchTrvRetNewRdr" SearchTravRet(2000) > : 100 NewRound Index: CHANGES.txt =================================================================== --- CHANGES.txt (revision 519567) +++ CHANGES.txt (working copy) @@ -4,6 +4,16 @@ $Id:$ +3/19/07 + +1. Introduced an AbstractQueryMaker to hold common QueryMaker code. (GSI) +2. Added traversalSize parameter to SearchTravRetTask and SearchTravTask. Changed SearchTravRetTask to extend SearchTravTask. (GSI) +3. Added FileBasedQueryMaker to run queries from a File or resource. (GSI) +4. Modified query-maker generation for read related tasks to make further read tasks addition simpler and safer. (DC) +5. Changed Taks' setParams() to throw UnsupportedOperationException if that task does not suppot command line param. (DC) +6. Improved javadoc to specify all properties command line params currently supported. (DC) +7. Refactored ReportTasks so that it is easy/possible now to create new report tasks. (DC) + 01/09/07 1. Committed Doron Cohen's benchmarking contribution, which provides an easily expandable task based approach to benchmarking. See the javadocs for information. (Doron Cohen via Grant Ingersoll) Index: src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksLogic.java =================================================================== --- src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksLogic.java (revision 0) +++ src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksLogic.java (revision 0) @@ -0,0 +1,100 @@ +/** + * 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. + */ + +package org.apache.lucene.benchmark.byTask; + +import java.io.StringReader; + +import org.apache.lucene.benchmark.byTask.Benchmark; +import org.apache.lucene.benchmark.byTask.tasks.CountingSearchTestTask; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.IndexWriter; + +import junit.framework.TestCase; + +/** + * Test very simply that perf tasks - simple algorithms - are doing what they should. + */ +public class TestPerfTasksLogic extends TestCase { + + private static final boolean DEBUG = true; + static final String NEW_LINE = System.getProperty("line.separator"); + + // properties in effect in all tests here + static final String propLines [] = { + "directory=RAMDirectory", + "print.props=false", + }; + + /** + * @param name test name + */ + public TestPerfTasksLogic(String name) { + super(name); + } + + /** + * Test index creation logic + */ + public void testPopulateIndex() throws Exception { + String algLines[] = { + "ResetSystemErase", + "CreateIndex", + "{ AddDoc } : 1000", + "Optimize", + "CloseIndex", + "OpenReader", + "{ CountingSearchTest } : 200", + "CloseReader", + "[ CountingSearchTest > : 70", + "[ CountingSearchTest > : 9", + }; + String algText = algLinesToText(algLines); + logTstLogic(algText); + Benchmark benchmark = new Benchmark(new StringReader(algText)); + CountingSearchTestTask.numSearches = 0; + benchmark.execute(); + assertEquals("TestSearchTask was supposed to be called!",279,CountingSearchTestTask.numSearches); + assertTrue("Index does not exist?...!", IndexReader.indexExists(benchmark.getRunData().getDirectory())); + // now we should be able to open the index for write. + IndexWriter iw = new IndexWriter(benchmark.getRunData().getDirectory(),null,false); + iw.close(); + IndexReader ir = IndexReader.open(benchmark.getRunData().getDirectory()); + assertEquals("1000 docs were added to the index, this is what we expect to find!",1000,ir.numDocs()); + } + + // catenate alg lines to make the alg text + private String algLinesToText(String[] algLines) { + String indent = " "; + StringBuffer sb = new StringBuffer(); + for (int i = 0; i < propLines.length; i++) { + sb.append(indent).append(propLines[i]).append(NEW_LINE); + } + for (int i = 0; i < algLines.length; i++) { + sb.append(indent).append(algLines[i]).append(NEW_LINE); + } + return sb.toString(); + } + + private void logTstLogic (String txt) { + if (!DEBUG) + return; + System.out.println("Test logic of:"); + System.out.println(txt); + } + +} Property changes on: src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksLogic.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Index: src/test/org/apache/lucene/benchmark/byTask/tasks/CountingSearchTestTask.java =================================================================== --- src/test/org/apache/lucene/benchmark/byTask/tasks/CountingSearchTestTask.java (revision 0) +++ src/test/org/apache/lucene/benchmark/byTask/tasks/CountingSearchTestTask.java (revision 0) @@ -0,0 +1,43 @@ +/** + * 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. + */ + +package org.apache.lucene.benchmark.byTask.tasks; + +import org.apache.lucene.benchmark.byTask.PerfRunData; + +/** + * Test Search task which counts number of searches. + */ +public class CountingSearchTestTask extends SearchTask { + + public static int numSearches = 0; + + public CountingSearchTestTask(PerfRunData runData) { + super(runData); + } + + public int doLogic() throws Exception { + int res = super.doLogic(); + incrNumSearches(); + return res; + } + + private static synchronized void incrNumSearches() { + numSearches++; + } + +} Property changes on: src/test/org/apache/lucene/benchmark/byTask/tasks/CountingSearchTestTask.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Index: src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksParse.java =================================================================== --- src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksParse.java (revision 0) +++ src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksParse.java (revision 0) @@ -0,0 +1,204 @@ +/** + * 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. + */ + +package org.apache.lucene.benchmark.byTask; + +import java.io.StringReader; +import java.util.ArrayList; +import java.util.Iterator; + +import org.apache.lucene.benchmark.byTask.tasks.PerfTask; +import org.apache.lucene.benchmark.byTask.tasks.TaskSequence; +import org.apache.lucene.benchmark.byTask.utils.Algorithm; + +import junit.framework.TestCase; + +/** + * Test very simply that perf tasks are parses as expected. + */ +public class TestPerfTasksParse extends TestCase { + + private static final boolean DEBUG = true; + static final String NEW_LINE = System.getProperty("line.separator"); + + /* + * All known tasks. + * As new tasks are added, add them here. + * It would be nice to do that automatically, unfortunately + * Java does not provide a "get all classes in package" or + * "get all sub-classes" functionality. + */ + static String singleTaskAlgs [] = { + " AddDoc ", + " AddDoc(1000.0) ", // for numeruc params use double form, just for this test. + " ClearStats ", + " CloseIndex ", + " CloseReader ", + " CreateIndex ", + " DeleteDoc ", + " DeleteDoc(500.0) ", + " NewRound ", + " OpenIndex ", + " OpenReader ", + " Optimize ", + //" Perf ", // not a usable task + //" Read ", // not a usable task + " RepAll ", + " RepSelectByPref prefix ", + " RepSumByNameRound ", + " RepSumByName ", + " RepSumByPrefRound prefix ", + " RepSumByPref prefix ", + //" Report ", // not a usable task + " ResetInputs ", + " ResetSystemErase ", + " ResetSystemSoft ", + " Search ", + " SearchTravRet ", + " SearchTravRet(100.0) ", + " SearchTrav ", + " SearchTrav(50.0) ", + " SetProp ", + " SetProp(name,value) ", + //" TaskSequence.java ", // not an explicitely usable task + " Warm ", + }; + + + /** + * @param name test name + */ + public TestPerfTasksParse(String name) { + super(name); + } + + /** + * Test the parsing of very simple tasks, for all tasks + */ + public void testAllTasksSimpleParse() { + doTestAllTasksSimpleParse(false,false); + } + + /** + * Test the parsing of simple sequential sequences, for all tasks + */ + public void testAllTasksSimpleParseSequntial() { + doTestAllTasksSimpleParse(true,false); + } + + /** + * Test the parsing of simple parallel sequences, for all tasks + */ + public void testAllTasksSimpleParseParallel() { + doTestAllTasksSimpleParse(true,true); + } + + // utility for simple parsing testing of all tasks. + private void doTestAllTasksSimpleParse(boolean parOrSeq, boolean par) { + String propline = "print.props=false" + NEW_LINE; + for (int i = 0; i < singleTaskAlgs.length; i++) { + String testedTask = singleTaskAlgs[i]; + if (parOrSeq) { + if (par) { + testedTask = "[ " + testedTask + " ] : 2"; + } else { + testedTask = "{ " + testedTask + " } : 3"; + } + } + try { + log(testedTask); + Benchmark benchmark = new Benchmark(new StringReader(propline+testedTask)); + Algorithm alg = benchmark.getAlgorithm(); + ArrayList algTasks = alg.extractTasks(); + // must find a task with this name in the algorithm + boolean foundName = false; + boolean foundPar = false; + String theTask = singleTaskAlgs[i].replaceAll(" +"," ").trim(); + for (Iterator iter = algTasks.iterator(); iter.hasNext();) { + PerfTask task = (PerfTask) iter.next(); + foundName |= (task.toString().indexOf(theTask)>=0); + foundPar |= (task instanceof TaskSequence && ((TaskSequence)task).isParallel()); + } + assertTrue("Task "+testedTask+" was not found in "+alg.toString(),foundName); + if (parOrSeq) { + if (par) { + assertTrue("Task "+testedTask+" was supposed to be parallel in "+alg.toString(),foundPar); + } else { + assertFalse("Task "+testedTask+" was not supposed to be parallel in "+alg.toString(),foundPar); + } + } + } catch (Exception e) { + System.out.flush(); + e.printStackTrace(); + fail(e.getMessage()); + } + } + } + + /** + * Test the repetiotion parsing for parallel tasks + */ + public void testParseParallelTaskSequenceRepetition() throws Exception { + String propline = "print.props=false" + NEW_LINE; + String taskStr = "AddDoc"; + String parsedTasks = "[ "+taskStr+" ] : 1000"; + Benchmark benchmark = new Benchmark(new StringReader(propline+parsedTasks)); + Algorithm alg = benchmark.getAlgorithm(); + ArrayList algTasks = alg.extractTasks(); + boolean foundAdd = false; + for (Iterator iter = algTasks.iterator(); iter.hasNext();) { + PerfTask task = (PerfTask) iter.next(); + if (task.toString().indexOf(taskStr)>=0) { + foundAdd = true; + } + if (task instanceof TaskSequence) { + assertEquals("repetions should be 1000 for "+parsedTasks, 1000, ((TaskSequence) task).getRepetitions()); + assertTrue("sequence for "+parsedTasks+" should be parallel!", ((TaskSequence) task).isParallel()); + } + assertTrue("Task "+taskStr+" was not found in "+alg.toString(),foundAdd); + } + } + + /** + * Test the repetiotion parsing for sequential tasks + */ + public void testParseTaskSequenceRepetition() throws Exception { + String propline = "print.props=false" + NEW_LINE; + String taskStr = "AddDoc"; + String parsedTasks = "{ "+taskStr+" } : 1000"; + Benchmark benchmark = new Benchmark(new StringReader(propline+parsedTasks)); + Algorithm alg = benchmark.getAlgorithm(); + ArrayList algTasks = alg.extractTasks(); + boolean foundAdd = false; + for (Iterator iter = algTasks.iterator(); iter.hasNext();) { + PerfTask task = (PerfTask) iter.next(); + if (task.toString().indexOf(taskStr)>=0) { + foundAdd = true; + } + if (task instanceof TaskSequence) { + assertEquals("repetions should be 1000 for "+parsedTasks, 1000, ((TaskSequence) task).getRepetitions()); + assertFalse("sequence for "+parsedTasks+" should be sequential!", ((TaskSequence) task).isParallel()); + } + assertTrue("Task "+taskStr+" was not found in "+alg.toString(),foundAdd); + } + } + + private void log (String txt) { + if (DEBUG) System.out.println("Test parsing of: "+txt); + } + +} Property changes on: src/test/org/apache/lucene/benchmark/byTask/TestPerfTasksParse.java ___________________________________________________________________ Name: svn:executable + * Name: svn:eol-style + native Index: src/java/org/apache/lucene/benchmark/byTask/utils/Config.java =================================================================== --- src/java/org/apache/lucene/benchmark/byTask/utils/Config.java (revision 519567) +++ src/java/org/apache/lucene/benchmark/byTask/utils/Config.java (working copy) @@ -19,9 +19,8 @@ import java.io.BufferedReader; import java.io.ByteArrayInputStream; -import java.io.File; -import java.io.FileReader; import java.io.IOException; +import java.io.Reader; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; @@ -49,10 +48,10 @@ * @param algFile file containing both algorithm and config properties. * @throws IOException */ - public Config (File algFile) throws IOException { + public Config (Reader algReader) throws IOException { // read alg file to array of lines ArrayList lines = new ArrayList(); - BufferedReader r = new BufferedReader(new FileReader(algFile)); + BufferedReader r = new BufferedReader(algReader); int lastConfigLine=0; for (String line = r.readLine(); line!=null; line=r.readLine()) { lines.add(line); Index: src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java =================================================================== --- src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java (revision 519567) +++ src/java/org/apache/lucene/benchmark/byTask/utils/Algorithm.java (working copy) @@ -223,7 +223,32 @@ public void execute() throws Exception { sequence.doLogic(); } + + /** + * Expert: for test purposes, return all tasks participating in this algorithm. + * @return all tasks participating in this algorithm. + */ + public ArrayList extractTasks() { + ArrayList res = new ArrayList(); + extractTasks(res, sequence); + return res; + } + private void extractTasks (ArrayList extrct, TaskSequence seq) { + if (seq==null) + return; + extrct.add(seq); + ArrayList t = sequence.getTasks(); + if (t==null) + return; + for (int i = 0; i < t.size(); i++) { + PerfTask p = (PerfTask) t.get(0); + if (p instanceof TaskSequence) { + extractTasks(extrct, (TaskSequence)p); + } else { + extrct.add(p); + } + } + } - } Index: src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetTask.java =================================================================== --- src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetTask.java (revision 519567) +++ src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravRetTask.java (working copy) @@ -18,15 +18,16 @@ */ import org.apache.lucene.benchmark.byTask.PerfRunData; -import org.apache.lucene.benchmark.byTask.feeds.QueryMaker; /** * Search and Travrese and Retrieve docs task. * *
Note: This task reuses the reader if it is already open.
* Otherwise a reader is opened at start and closed at the end.
+ *
+ * Takes optional param: traversal size (otherwise all results are traversed).
*/
-public class SearchTravRetTask extends ReadTask {
+public class SearchTravRetTask extends SearchTravTask {
public SearchTravRetTask(PerfRunData runData) {
super(runData);
@@ -36,21 +37,4 @@
return true;
}
- public boolean withSearch() {
- return true;
- }
-
- public boolean withTraverse() {
- return true;
- }
-
- public boolean withWarm() {
- return false;
- }
-
- public QueryMaker getQueryMaker() {
- return getRunData().getSearchTravQueryMaker();
- }
-
-
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/AddDocTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/AddDocTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/AddDocTask.java (working copy)
@@ -23,11 +23,19 @@
/**
- * Add a document, optionally with of a cetrain size.
- * Other side effects: none.
+ * Add a document, optionally with of a certain size.
+ * Note: This task reuses the reader if it is already open.
* Otherwise a reader is opened at start and closed at the end.
+ *
Other side effects: none.
+ *
Relevant properties: doc.add.log.step.
+ *
Takes optional param: document size.
*/
public class AddDocTask extends PerfTask {
+ /**
+ * Default value for property doc.add.log.step - indicating how often
+ * an "added N docs" message should be logged.
+ */
+ public static final int DEFAULT_ADD_DOC_LOG_STEP = 500;
+
public AddDocTask(PerfRunData runData) {
super(runData);
}
@@ -70,10 +78,10 @@
private void log (int count) {
if (logStep<0) {
// avoid sync although race possible here
- logStep = getRunData().getConfig().get("doc.add.log.step",500);
+ logStep = getRunData().getConfig().get("doc.add.log.step",DEFAULT_ADD_DOC_LOG_STEP);
}
if (logStep>0 && (count%logStep)==0) {
- System.out.println("--> processed "+count+" docs");
+ System.out.println("--> processed (add) "+count+" docs");
}
}
@@ -85,4 +93,12 @@
super.setParams(params);
docSize = (int) Float.parseFloat(params);
}
+
+ /* (non-Javadoc)
+ * @see org.apache.lucene.benchmark.byTask.tasks.PerfTask#supportsParams()
+ */
+ public boolean supportsParams() {
+ return true;
+ }
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameRoundTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameRoundTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameRoundTask.java (working copy)
@@ -17,12 +17,17 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report all statistics grouped/aggregated by name and round.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepSumByNameRoundTask extends ReportTask {
@@ -31,7 +36,7 @@
}
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportSumByNameRound();
+ Report rp = reportSumByNameRound(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report Sum By (any) Name and Round ("+
@@ -42,4 +47,35 @@
return 0;
}
+ /**
+ * Report statistics as a string, aggregate for tasks named the same, and from the same round.
+ * @return the report
+ */
+ protected Report reportSumByNameRound(List taskStats) {
+ // aggregate by task name and round
+ LinkedHashMap p2 = new LinkedHashMap();
+ int reported = 0;
+ for (Iterator it = taskStats.iterator(); it.hasNext();) {
+ TaskStats stat1 = (TaskStats) it.next();
+ if (stat1.getElapsed()>=0) { // consider only tasks that ended
+ reported++;
+ String name = stat1.getTask().getName();
+ String rname = stat1.getRound()+"."+name; // group by round
+ TaskStats stat2 = (TaskStats) p2.get(rname);
+ if (stat2 == null) {
+ try {
+ stat2 = (TaskStats) stat1.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ p2.put(rname,stat2);
+ } else {
+ stat2.add(stat1);
+ }
+ }
+ }
+ // now generate report from secondary list p2
+ return genPartialReport(reported, p2, taskStats.size());
+ }
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepAllTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepAllTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepAllTask.java (working copy)
@@ -17,12 +17,16 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report all statistics with no aggregations.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepAllTask extends ReportTask {
@@ -31,7 +35,7 @@
}
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportAll();
+ Report rp = reportAll(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report All ("+rp.getSize()+" out of "+rp.getOutOf()+")");
@@ -39,5 +43,36 @@
System.out.println();
return 0;
}
+
+ /**
+ * Report detailed statistics as a string
+ * @return the report
+ */
+ protected Report reportAll(List taskStats) {
+ String longestOp = longestOp(taskStats.iterator());
+ boolean first = true;
+ StringBuffer sb = new StringBuffer();
+ sb.append(tableTitle(longestOp));
+ sb.append(newline);
+ int reported = 0;
+ Iterator it = taskStats.iterator();
+ while (it.hasNext()) {
+ TaskStats stat = (TaskStats) it.next();
+ if (stat.getElapsed()>=0) { // consider only tasks that ended
+ if (!first) {
+ sb.append(newline);
+ }
+ first = false;
+ String line = taskReportLine(longestOp, stat);
+ reported++;
+ if (taskStats.size()>2 && reported%2==0) {
+ line = line.replaceAll(" "," - ");
+ }
+ sb.append(line);
+ }
+ }
+ String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
+ return new Report(reptxt,reported,reported,taskStats.size());
+ }
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefTask.java (working copy)
@@ -17,12 +17,17 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report by-name-prefix statistics aggregated by name.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepSumByPrefTask extends ReportTask {
@@ -33,7 +38,7 @@
protected String prefix;
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportSumByPrefix(prefix);
+ Report rp = reportSumByPrefix(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report Sum By Prefix ("+prefix+") ("+
@@ -44,6 +49,33 @@
return 0;
}
+ protected Report reportSumByPrefix (List taskStats) {
+ // aggregate by task name
+ int reported = 0;
+ LinkedHashMap p2 = new LinkedHashMap();
+ for (Iterator it = taskStats.iterator(); it.hasNext();) {
+ TaskStats stat1 = (TaskStats) it.next();
+ if (stat1.getElapsed()>=0 && stat1.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
+ reported++;
+ String name = stat1.getTask().getName();
+ TaskStats stat2 = (TaskStats) p2.get(name);
+ if (stat2 == null) {
+ try {
+ stat2 = (TaskStats) stat1.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ p2.put(name,stat2);
+ } else {
+ stat2.add(stat1);
+ }
+ }
+ }
+ // now generate report from secondary list p2
+ return genPartialReport(reported, p2, taskStats.size());
+ }
+
+
public void setPrefix(String prefix) {
this.prefix = prefix;
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemSoftTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemSoftTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemSoftTask.java (working copy)
@@ -24,7 +24,7 @@
/**
* Reset all index and input data and call gc, does NOT erase index/dir, does NOT clear statistics.
* This contains ResetInputs.
- * Other side effects: writers/readers nulified, closed.
+ *
Other side effects: writers/readers nulified, closed.
* Index is NOT erased.
* Directory is NOT erased.
*/
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/OpenReaderTask.java (working copy)
@@ -25,7 +25,7 @@
/**
* Open an index reader.
- * Other side effects: index redaer object in perfRunData is set.
+ *
Other side effects: index redaer object in perfRunData is set.
*/
public class OpenReaderTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/DeleteDocTask.java (working copy)
@@ -21,10 +21,24 @@
/**
* Delete a document by docid.
- * Other side effects: none.
+ *
Other side effects: none.
+ *
Relevant properties: doc.delete.log.step , doc.delete.step.
+ *
If no docid param is supplied, deletes doc with id = last-deleted-doc + doc.delete.step.
+ *
Takes optional param: document id.
*/
public class DeleteDocTask extends PerfTask {
+ /**
+ * Gap between ids of deleted docs, applies when no docid param is provided.
+ */
+ public static final int DEFAULT_DOC_DELETE_STEP = 8;
+
+ /**
+ * Default value for property doc.delete.log.step - indicating how often
+ * an "deleted N docs" message should be logged.
+ */
+ public static final int DEFAULT_DELETE_DOC_LOG_STEP = 500;
+
public DeleteDocTask(PerfRunData runData) {
super(runData);
}
@@ -50,10 +64,10 @@
super.setup();
// one time static initializations
if (logStep<0) {
- logStep = getRunData().getConfig().get("doc.delete.log.step",500);
+ logStep = getRunData().getConfig().get("doc.delete.log.step",DEFAULT_DELETE_DOC_LOG_STEP);
}
if (deleteStep<0) {
- deleteStep = getRunData().getConfig().get("doc.delete.step",8);
+ deleteStep = getRunData().getConfig().get("doc.delete.step",DEFAULT_DOC_DELETE_STEP);
}
// set the docid to be deleted
docid = (byStep ? lastDeleted + deleteStep : docid);
@@ -69,7 +83,7 @@
private void log (int count) {
if (logStep>0 && (count%logStep)==0) {
- System.out.println("--> processed "+count+" docs, last deleted: "+lastDeleted);
+ System.out.println("--> processed (delete) "+count+" docs, last deleted: "+lastDeleted);
}
}
@@ -82,5 +96,12 @@
docid = (int) Float.parseFloat(params);
byStep = (docid < 0);
}
+
+ /* (non-Javadoc)
+ * @see org.apache.lucene.benchmark.byTask.tasks.PerfTask#supportsParams()
+ */
+ public boolean supportsParams() {
+ return true;
+ }
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/CloseReaderTask.java (working copy)
@@ -24,8 +24,8 @@
/**
* Close index reader.
- * Other side effects: index reader in perfRunData is nullified.
- * This would cause read related tasks to reopen their own reader.
+ *
Other side effects: index reader in perfRunData is nullified.
+ *
This would cause read related tasks to reopen their own reader.
*/
public class CloseReaderTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/OpenIndexTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/OpenIndexTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/OpenIndexTask.java (working copy)
@@ -28,10 +28,14 @@
/**
* Open an index writer.
- * Other side effects: index writer object in perfRunData is set.
+ *
Other side effects: index writer object in perfRunData is set.
+ *
Relevant properties: merge.factor , max.buffered.
*/
public class OpenIndexTask extends PerfTask {
+ public static final int DEFAULT_MAX_BUFFERED = 10;
+ public static final int DEFAULT_MERGE_PFACTOR = 10;
+
public OpenIndexTask(PerfRunData runData) {
super(runData);
}
@@ -44,8 +48,8 @@
Config config = getRunData().getConfig();
boolean cmpnd = config.get("compound",true);
- int mrgf = config.get("merge.factor",10);
- int mxbf = config.get("max.buffered",10);
+ int mrgf = config.get("merge.factor",DEFAULT_MERGE_PFACTOR);
+ int mxbf = config.get("max.buffered",DEFAULT_MAX_BUFFERED);
// must update params for newly opened writer
writer.setMaxBufferedDocs(mxbf);
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/CreateIndexTask.java (working copy)
@@ -28,7 +28,8 @@
/**
* Create an index.
- * Other side effects: index writer object in perfRunData is set.
+ *
Other side effects: index writer object in perfRunData is set.
+ *
Relevant properties: merge.factor , max.buffered.
*/
public class CreateIndexTask extends PerfTask {
@@ -45,8 +46,8 @@
Config config = getRunData().getConfig();
boolean cmpnd = config.get("compound",true);
- int mrgf = config.get("merge.factor",10);
- int mxbf = config.get("max.buffered",10);
+ int mrgf = config.get("merge.factor",OpenIndexTask.DEFAULT_MERGE_PFACTOR);
+ int mxbf = config.get("max.buffered",OpenIndexTask.DEFAULT_MAX_BUFFERED);
iw.setUseCompoundFile(cmpnd);
iw.setMergeFactor(mrgf);
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefRoundTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefRoundTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByPrefRoundTask.java (working copy)
@@ -17,12 +17,17 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report all prefix matching statistics grouped/aggregated by name and round.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepSumByPrefRoundTask extends RepSumByPrefTask {
@@ -31,7 +36,7 @@
}
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportSumByPrefixRound(prefix);
+ Report rp = reportSumByPrefixRound(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report sum by Prefix ("+prefix+") and Round ("+
@@ -42,4 +47,32 @@
return 0;
}
+ protected Report reportSumByPrefixRound(List taskStats) {
+ // aggregate by task name and by round
+ int reported = 0;
+ LinkedHashMap p2 = new LinkedHashMap();
+ for (Iterator it = taskStats.iterator(); it.hasNext();) {
+ TaskStats stat1 = (TaskStats) it.next();
+ if (stat1.getElapsed()>=0 && stat1.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
+ reported++;
+ String name = stat1.getTask().getName();
+ String rname = stat1.getRound()+"."+name; // group by round
+ TaskStats stat2 = (TaskStats) p2.get(rname);
+ if (stat2 == null) {
+ try {
+ stat2 = (TaskStats) stat1.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ p2.put(rname,stat2);
+ } else {
+ stat2.add(stat1);
+ }
+ }
+ }
+ // now generate report from secondary list p2
+ return genPartialReport(reported, p2, taskStats.size());
+ }
+
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/PerfTask.java (working copy)
@@ -30,6 +30,8 @@
*
* Tasks performing some work that should be measured for the task, can overide setup() and/or tearDown() and
* placed that work there.
+ *
+ * Relevant properties: task.max.depth.log.
*/
public abstract class PerfTask implements Cloneable {
@@ -39,7 +41,7 @@
private String name;
private int depth = 0;
private int maxDepthLogStart = 0;
- protected String params = null;
+ private String params = null;
protected static final String NEW_LINE = System.getProperty("line.separator");
@@ -200,13 +202,24 @@
}
/**
+ * Sub classes that supports parameters must overide this method to return true.
+ * @return true iff this task supports command line params.
+ */
+ public boolean supportsParams () {
+ return false;
+ }
+
+ /**
* Set the params of this task.
- * Sub classes that supports parameters may overide this method for fetching/processing the params.
+ * @exception UnsupportedOperationException for tasks supporting command line parameters.
*/
public void setParams(String params) {
+ if (!supportsParams()) {
+ throw new UnsupportedOperationException(getName()+" does not support command line parameters.");
+ }
this.params = params;
}
-
+
/**
* @return Returns the Params.
*/
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/SetPropTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/SetPropTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/SetPropTask.java (working copy)
@@ -24,7 +24,8 @@
* A property may have a single value, or a sequence of values, seprated by ":".
* If a sequence of values is specified, each time a new round starts,
* the next (cyclic) value is taken.
- * Other side effects: none.
+ *
Other side effects: none.
+ *
Takes mandatory param: "name,value" pair.
* @see org.apache.lucene.benchmark.byTask.tasks.NewRoundTask
*/
public class SetPropTask extends PerfTask {
@@ -55,4 +56,11 @@
value = params.substring(k+1).trim();
}
+ /* (non-Javadoc)
+ * @see org.apache.lucene.benchmark.byTask.tasks.PerfTask#supportsParams()
+ */
+ public boolean supportsParams() {
+ return true;
+ }
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/CloseIndexTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/CloseIndexTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/CloseIndexTask.java (working copy)
@@ -24,7 +24,7 @@
/**
* Close index writer.
- * Other side effects: index writer object in perfRunData is nullified.
+ *
Other side effects: index writer object in perfRunData is nullified.
*/
public class CloseIndexTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepSelectByPrefTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepSelectByPrefTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepSelectByPrefTask.java (working copy)
@@ -17,12 +17,16 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report by-name-prefix statistics with no aggregations.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepSelectByPrefTask extends RepSumByPrefTask {
@@ -31,7 +35,7 @@
}
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportSelectByPrefix(prefix);
+ Report rp = reportSelectByPrefix(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report Select By Prefix ("+prefix+") ("+
@@ -41,4 +45,31 @@
return 0;
}
+
+ protected Report reportSelectByPrefix(List taskStats) {
+ String longestOp = longestOp(taskStats.iterator());
+ boolean first = true;
+ StringBuffer sb = new StringBuffer();
+ sb.append(tableTitle(longestOp));
+ sb.append(newline);
+ int reported = 0;
+ for (Iterator it = taskStats.iterator(); it.hasNext();) {
+ TaskStats stat = (TaskStats) it.next();
+ if (stat.getElapsed()>=0 && stat.getTask().getName().startsWith(prefix)) { // only ended tasks with proper name
+ reported++;
+ if (!first) {
+ sb.append(newline);
+ }
+ first = false;
+ String line = taskReportLine(longestOp,stat);
+ if (taskStats.size()>2 && reported%2==0) {
+ line = line.replaceAll(" "," - ");
+ }
+ sb.append(line);
+ }
+ }
+ String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
+ return new Report(reptxt,reported,reported, taskStats.size());
+ }
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/OptimizeTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/OptimizeTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/OptimizeTask.java (working copy)
@@ -22,7 +22,7 @@
/**
* Optimize the index.
- * Other side effects: none.
+ *
Other side effects: none.
*/
public class OptimizeTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/NewRoundTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/NewRoundTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/NewRoundTask.java (working copy)
@@ -22,7 +22,7 @@
/**
* Increment the counter for properties maintained by Round Number.
- * Other side effects: if there are props by round number, log value change.
+ *
Other side effects: if there are props by round number, log value change.
*/
public class NewRoundTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTravTask.java (working copy)
@@ -25,8 +25,12 @@
*
*
Other side effects: None.
*/
public class ClearStatsTask extends PerfTask {
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/SearchTask.java (working copy)
@@ -49,7 +49,7 @@
}
public QueryMaker getQueryMaker() {
- return getRunData().getSearchQueryMaker();
+ return getRunData().getQueryMaker(this);
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/RepSumByNameTask.java (working copy)
@@ -17,12 +17,17 @@
* limitations under the License.
*/
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+import java.util.List;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
/**
* Report all statistics aggregated by name.
- * Other side effects: None.
+ *
Other side effects: None.
*/
public class RepSumByNameTask extends ReportTask {
@@ -31,7 +36,7 @@
}
public int doLogic() throws Exception {
- Report rp = getRunData().getPoints().reportSumByName();
+ Report rp = reportSumByName(getRunData().getPoints().taskStats());
System.out.println();
System.out.println("------------> Report Sum By (any) Name ("+
@@ -42,4 +47,35 @@
return 0;
}
+ /**
+ * Report statistics as a string, aggregate for tasks named the same.
+ * @return the report
+ */
+ protected Report reportSumByName(List taskStats) {
+ // aggregate by task name
+ int reported = 0;
+ LinkedHashMap p2 = new LinkedHashMap();
+ for (Iterator it = taskStats.iterator(); it.hasNext();) {
+ TaskStats stat1 = (TaskStats) it.next();
+ if (stat1.getElapsed()>=0) { // consider only tasks that ended
+ reported++;
+ String name = stat1.getTask().getName();
+ TaskStats stat2 = (TaskStats) p2.get(name);
+ if (stat2 == null) {
+ try {
+ stat2 = (TaskStats) stat1.clone();
+ } catch (CloneNotSupportedException e) {
+ throw new RuntimeException(e);
+ }
+ p2.put(name,stat2);
+ } else {
+ stat2.add(stat1);
+ }
+ }
+ }
+ // now generate report from secondary list p2
+ return genPartialReport(reported, p2, taskStats.size());
+ }
+
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemEraseTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemEraseTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/ResetSystemEraseTask.java (working copy)
@@ -23,8 +23,8 @@
/**
* Reset all index and input data and call gc, erase index and dir, does NOT clear statistics.
- * This contains ResetInputs.
- * Other side effects: writers/readers nulified, deleted, closed.
+ *
This contains ResetInputs.
+ *
Other side effects: writers/readers nulified, deleted, closed.
* Index is erased.
* Directory is erased.
*/
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/ReadTask.java (working copy)
@@ -76,9 +76,10 @@
Hits hits = searcher.search(q);
//System.out.println("searched: "+q);
- if (withTraverse()) {
+ if (withTraverse() && hits!=null) {
Document doc = null;
- if (hits != null && hits.length() > 0) {
+ int traversalSize = Math.min(hits.length(), traversalSize());
+ if (traversalSize > 0) {
for (int m = 0; m < hits.length(); m++) {
int id = hits.id(m);
res++;
@@ -121,6 +122,18 @@
public abstract boolean withTraverse ();
/**
+ * Specify the number of hits to traverse. Tasks should override this if they want to restrict the number
+ * of hits that are traversed when {@link #withTraverse()} is true. Must be greater than 0.
+ *
+ * Read task calculates the traversal as: Math.min(hits.length(), traversalSize())
+ * @return Integer.MAX_VALUE
+ */
+ public int traversalSize()
+ {
+ return Integer.MAX_VALUE;
+ }
+
+ /**
* Return true if, with search & results traversing, docs should be retrieved.
*/
public abstract boolean withRetrieve ();
Index: src/java/org/apache/lucene/benchmark/byTask/tasks/ReportTask.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/tasks/ReportTask.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/tasks/ReportTask.java (working copy)
@@ -1,6 +1,12 @@
package org.apache.lucene.benchmark.byTask.tasks;
+import java.util.Iterator;
+import java.util.LinkedHashMap;
+
import org.apache.lucene.benchmark.byTask.PerfRunData;
+import org.apache.lucene.benchmark.byTask.stats.Report;
+import org.apache.lucene.benchmark.byTask.stats.TaskStats;
+import org.apache.lucene.benchmark.byTask.utils.Format;
/**
* Licensed to the Apache Software Foundation (ASF) under one or more
@@ -41,4 +47,116 @@
protected boolean shouldNotRecordStats() {
return true;
}
+
+ /*
+ * From here start the code used to generate the reports.
+ * Subclasses would use this part to generate reports.
+ */
+
+ protected static final String newline = System.getProperty("line.separator");
+
+ /**
+ * Get a textual summary of the benchmark results, average from all test runs.
+ */
+ protected static final String OP = "Operation ";
+ protected static final String ROUND = " round";
+ protected static final String RUNCNT = " runCnt";
+ protected static final String RECCNT = " recsPerRun";
+ protected static final String RECSEC = " rec/s";
+ protected static final String ELAPSED = " elapsedSec";
+ protected static final String USEDMEM = " avgUsedMem";
+ protected static final String TOTMEM = " avgTotalMem";
+ protected static final String COLS[] = {
+ RUNCNT,
+ RECCNT,
+ RECSEC,
+ ELAPSED,
+ USEDMEM,
+ TOTMEM
+ };
+
+ /**
+ * Compute a title line for a report table
+ * @param longestOp size of longest op name in the table
+ * @return the table title line.
+ */
+ protected String tableTitle (String longestOp) {
+ StringBuffer sb = new StringBuffer();
+ sb.append(Format.format(OP,longestOp));
+ sb.append(ROUND);
+ sb.append(getRunData().getConfig().getColsNamesForValsByRound());
+ for (int i = 0; i < COLS.length; i++) {
+ sb.append(COLS[i]);
+ }
+ return sb.toString();
+ }
+
+ /**
+ * find the longest op name out of completed tasks.
+ * @param taskStats completed tasks to be considered.
+ * @return the longest op name out of completed tasks.
+ */
+ protected String longestOp(Iterator taskStats) {
+ String longest = OP;
+ while (taskStats.hasNext()) {
+ TaskStats stat = (TaskStats) taskStats.next();
+ if (stat.getElapsed()>=0) { // consider only tasks that ended
+ String name = stat.getTask().getName();
+ if (name.length() > longest.length()) {
+ longest = name;
+ }
+ }
+ }
+ return longest;
+ }
+
+ /**
+ * Compute a report line for the given task stat.
+ * @param longestOp size of longest op name in the table.
+ * @param stat task stat to be printed.
+ * @return the report line.
+ */
+ protected String taskReportLine(String longestOp, TaskStats stat) {
+ PerfTask task = stat.getTask();
+ StringBuffer sb = new StringBuffer();
+ sb.append(Format.format(task.getName(), longestOp));
+ String round = (stat.getRound()>=0 ? ""+stat.getRound() : "-");
+ sb.append(Format.formatPaddLeft(round, ROUND));
+ sb.append(getRunData().getConfig().getColsValuesForValsByRound(stat.getRound()));
+ sb.append(Format.format(stat.getNumRuns(), RUNCNT));
+ sb.append(Format.format(stat.getCount() / stat.getNumRuns(), RECCNT));
+ long elapsed = (stat.getElapsed()>0 ? stat.getElapsed() : 1); // assume at least 1ms
+ sb.append(Format.format(1,(float) (stat.getCount() * 1000.0 / elapsed), RECSEC));
+ sb.append(Format.format(2, (float) stat.getElapsed() / 1000, ELAPSED));
+ sb.append(Format.format(0, (float) stat.getMaxUsedMem() / stat.getNumRuns(), USEDMEM));
+ sb.append(Format.format(0, (float) stat.getMaxTotMem() / stat.getNumRuns(), TOTMEM));
+ return sb.toString();
+ }
+
+ protected Report genPartialReport(int reported, LinkedHashMap partOfTasks, int totalSize) {
+ String longetOp = longestOp(partOfTasks.values().iterator());
+ boolean first = true;
+ StringBuffer sb = new StringBuffer();
+ sb.append(tableTitle(longetOp));
+ sb.append(newline);
+ int lineNum = 0;
+ for (Iterator it = partOfTasks.values().iterator(); it.hasNext();) {
+ TaskStats stat = (TaskStats) it.next();
+ if (!first) {
+ sb.append(newline);
+ }
+ first = false;
+ String line = taskReportLine(longetOp,stat);
+ lineNum++;
+ if (partOfTasks.size()>2 && lineNum%2==0) {
+ line = line.replaceAll(" "," - ");
+ }
+ sb.append(line);
+ }
+ String reptxt = (reported==0 ? "No Matching Entries Were Found!" : sb.toString());
+ return new Report(reptxt,partOfTasks.size(),reported,totalSize);
+ }
+
+
+
}
Index: src/java/org/apache/lucene/benchmark/byTask/feeds/ReutersQueryMaker.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/feeds/ReutersQueryMaker.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/feeds/ReutersQueryMaker.java (working copy)
@@ -17,10 +17,6 @@
* limitations under the License.
*/
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
import org.apache.lucene.analysis.Analyzer;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
@@ -30,20 +26,18 @@
import org.apache.lucene.search.spans.SpanNearQuery;
import org.apache.lucene.search.spans.SpanQuery;
import org.apache.lucene.search.spans.SpanTermQuery;
-import org.apache.lucene.benchmark.byTask.utils.Config;
-import org.apache.lucene.benchmark.byTask.utils.Format;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
/**
* A QueryMaker that makes queries devised manually (by Grant Ingersoll) for
* searching in the Reuters collection.
*/
-public class ReutersQueryMaker implements QueryMaker {
-
- private int qnum = 0;
- private Query queries[];
- private Config config;
-
+public class ReutersQueryMaker extends AbstractQueryMaker implements QueryMaker {
+
private static String [] STANDARD_QUERIES = {
//Start with some short queries
"Salomon", "Comex", "night trading", "Japan Sony",
@@ -106,7 +100,7 @@
return (Query[]) queries.toArray(new Query[0]);
}
- private void prepareQueries() throws Exception {
+ protected Query[] prepareQueries() throws Exception {
// analyzer (default is standard analyzer)
Analyzer anlzr= (Analyzer) Class.forName(config.get("analyzer",
"org.apache.lucene.analysis.standard.StandardAnalyzer")).newInstance();
@@ -114,47 +108,10 @@
List queryList = new ArrayList(20);
queryList.addAll(Arrays.asList(STANDARD_QUERIES));
queryList.addAll(Arrays.asList(getPrebuiltQueries("body")));
- queries = createQueries(queryList, anlzr);
+ return createQueries(queryList, anlzr);
}
+
+
- public Query makeQuery() throws Exception {
- return queries[nextQnum()];
- }
-
- public void setConfig(Config config) throws Exception {
- this.config = config;
- prepareQueries();
- }
-
- public void resetInputs() {
- qnum = 0;
- }
-
- // return next qnum
- private synchronized int nextQnum() {
- int res = qnum;
- qnum = (qnum+1) % queries.length;
- return res;
- }
-
- public String printQueries() {
- String newline = System.getProperty("line.separator");
- StringBuffer sb = new StringBuffer();
- if (queries != null) {
- for (int i = 0; i < queries.length; i++) {
- sb.append(i+". "+Format.simpleName(queries[i].getClass())+" - "+queries[i].toString());
- sb.append(newline);
- }
- }
- return sb.toString();
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.lucene.benchmark.byTask.feeds.QueryMaker#makeQuery(int)
- */
- public Query makeQuery(int size) throws Exception {
- throw new Exception(this+".makeQuery(int size) is not supported!");
- }
}
Index: src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleQueryMaker.java (working copy)
@@ -17,28 +17,23 @@
* limitations under the License.
*/
-import java.util.ArrayList;
-
import org.apache.lucene.analysis.Analyzer;
-import org.apache.lucene.benchmark.byTask.utils.Config;
-import org.apache.lucene.benchmark.byTask.utils.Format;
import org.apache.lucene.index.Term;
import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.search.BooleanClause.Occur;
import org.apache.lucene.search.BooleanQuery;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.BooleanClause.Occur;
+import java.util.ArrayList;
+
/**
* A QueryMaker that makes queries for a collection created
* using {@link org.apache.lucene.benchmark.byTask.feeds.SimpleDocMaker}.
*/
-public class SimpleQueryMaker implements QueryMaker {
+public class SimpleQueryMaker extends AbstractQueryMaker implements QueryMaker {
- private int qnum = 0;
- private Query queries[];
- private Config config;
-
+
/**
* Prepare the queries for this test.
* Extending classes can overide this method for preparing different queries.
@@ -70,44 +65,4 @@
return (Query []) qq.toArray(new Query[0]);
}
- public Query makeQuery() throws Exception {
- return queries[nextQnum()];
- }
-
- public void setConfig(Config config) throws Exception {
- this.config = config;
- queries = prepareQueries();
- }
-
- public void resetInputs() {
- qnum = 0;
- }
-
- // return next qnum
- private synchronized int nextQnum() {
- int res = qnum;
- qnum = (qnum+1) % queries.length;
- return res;
- }
-
- public String printQueries() {
- String newline = System.getProperty("line.separator");
- StringBuffer sb = new StringBuffer();
- if (queries != null) {
- for (int i = 0; i < queries.length; i++) {
- sb.append(i+". "+Format.simpleName(queries[i].getClass())+" - "+queries[i].toString());
- sb.append(newline);
- }
- }
- return sb.toString();
- }
-
- /*
- * (non-Javadoc)
- * @see org.apache.lucene.benchmark.byTask.feeds.QueryMaker#makeQuery(int)
- */
- public Query makeQuery(int size) throws Exception {
- throw new Exception(this+".makeQuery(int size) is not supported!");
- }
-
}
Index: src/java/org/apache/lucene/benchmark/byTask/feeds/FileBasedQueryMaker.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/feeds/FileBasedQueryMaker.java (revision 0)
+++ src/java/org/apache/lucene/benchmark/byTask/feeds/FileBasedQueryMaker.java (revision 0)
@@ -0,0 +1,94 @@
+package org.apache.lucene.benchmark.byTask.feeds;
+
+import org.apache.lucene.analysis.Analyzer;
+import org.apache.lucene.queryParser.QueryParser;
+import org.apache.lucene.queryParser.ParseException;
+import org.apache.lucene.search.Query;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed 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.
+ */
+
+/**
+ * Create queries from a FileReader. One per line, pass them through the
+ * QueryParser. Lines beginning with # are treated as comments
+ *
+ * File can be specified as a absolute, relative or resource.
+ * Two properties can be set:
+ * file.query.maker.file=<Full path to file containing queries>
+ *
+ * file.query.maker.default.field=<Name of default field - Default value is "body">
+ *
+ * Example:
+ * file.query.maker.file=c:/myqueries.txt
+ * file.query.maker.default.field=body
+ */
+public class FileBasedQueryMaker extends AbstractQueryMaker implements QueryMaker{
+
+
+ protected Query[] prepareQueries() throws Exception {
+
+ Analyzer anlzr = (Analyzer) Class.forName(config.get("analyzer",
+ "org.apache.lucene.analysis.standard.StandardAnalyzer")).newInstance();
+ String defaultField = config.get("file.query.maker.default.field", "body");
+ QueryParser qp = new QueryParser(defaultField, anlzr);
+
+ List qq = new ArrayList();
+ String fileName = config.get("file.query.maker.file", null);
+ if (fileName != null)
+ {
+ File file = new File(fileName);
+ Reader reader = null;
+ if (file != null && file.exists())
+ {
+ reader = new FileReader(file);
+ } else {
+ //see if we can find it as a resource
+ InputStream asStream = FileBasedQueryMaker.class.getClassLoader().getResourceAsStream(fileName);
+ if (asStream != null) {
+ reader = new InputStreamReader(asStream);
+ }
+ }
+ if (reader != null) {
+ BufferedReader buffered = new BufferedReader(reader);
+ String line = null;
+ int lineNum = 0;
+ while ((line = buffered.readLine()) != null)
+ {
+ line = line.trim();
+ if (!line.equals("") && !line.startsWith("#"))
+ {
+ Query query = null;
+ try {
+ query = qp.parse(line);
+ } catch (ParseException e) {
+ System.err.println("Exception: " + e.getMessage() + " occurred while parsing line: " + lineNum + " Text: " + line);
+ }
+ qq.add(query);
+ }
+ lineNum++;
+ }
+ } else {
+ System.err.println("No Reader available for: " + fileName);
+ }
+ }
+ Query [] result = (Query[]) qq.toArray(new Query[qq.size()]) ;
+ return result;
+ }
+}
Property changes on: src/java/org/apache/lucene/benchmark/byTask/feeds/FileBasedQueryMaker.java
___________________________________________________________________
Name: svn:executable
+ *
Name: svn:eol-style
+ native
Index: src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleSloppyPhraseQueryMaker.java
===================================================================
--- src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleSloppyPhraseQueryMaker.java (revision 519567)
+++ src/java/org/apache/lucene/benchmark/byTask/feeds/SimpleSloppyPhraseQueryMaker.java (working copy)
@@ -36,7 +36,7 @@
q.setSlop(slop);
int wind = wd;
for (int i=0; i
-A benchmark is composed of some predefined tasks, allowing for creating an index, adding documents, -optimizing, searching, generating reports, and more. A benchmark run takes an "algorithm" file -that contains a description of the sequence of tasks making up the run, and some properties defining a few +A benchmark is composed of some predefined tasks, allowing for creating an +index, adding documents, +optimizing, searching, generating reports, and more. A benchmark run takes an +"algorithm" file +that contains a description of the sequence of tasks making up the run, and some +properties defining a few additional characteristics of the benchmark run.
@@ -95,28 +99,30 @@your perf test "algorithm".
-You may find existing tasks sufficient for defining the benchmark you need, -otherwise, you can extend the framework to meet your needs, as explained herein. +You may find existing tasks sufficient for defining the benchmark you +need, otherwise, you can extend the framework to meet your needs, as explained +herein.
-Each benchmark run has a DocMaker and a QueryMaker. These two should usually match, so -that "meaningful" queries are used for a certain collection. -Properties set at the header of the alg file define which "makers" should be used. -You can also specify your own makers, implementing the DocMaker and QureyMaker interfaces. +Each benchmark run has a DocMaker and a QueryMaker. These two should usually +match, so that "meaningful" queries are used for a certain collection. +Properties set at the header of the alg file define which "makers" should be +used. You can also specify your own makers, implementing the DocMaker and +QureyMaker interfaces.
-Benchmark .alg file contains the benchmark "algorithm". The syntax is described below. -Within the algorithm, you can specify groups of commands, assign them names, -specify commands that should be repeated, +Benchmark .alg file contains the benchmark "algorithm". The syntax is described +below. Within the algorithm, you can specify groups of commands, assign them +names, specify commands that should be repeated, do commands in serial or in parallel, and also control the speed of "firing" the commands.
@@ -151,8 +157,10 @@doc.delete.step property.
+ @@ -351,12 +441,13 @@
-For additional defined properties see the *.alg files under conf. +Here is a list of currently defined properties:
++For sample use of these properties see the *.alg files under conf. +
+