http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs new file mode 100644 index 0000000..eeb8f8c --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReopenReaderTask.cs @@ -0,0 +1,45 @@ +using Lucene.Net.Index; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Reopens <see cref="IndexReader"/> and closes old <see cref="IndexReader"/>. + /// </summary> + public class ReopenReaderTask : PerfTask + { + public ReopenReaderTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + DirectoryReader r = RunData.GetIndexReader(); + DirectoryReader nr = DirectoryReader.OpenIfChanged(r); + if (nr != null) + { + RunData.SetIndexReader(nr); + nr.DecRef(); + } + r.DecRef(); + return 1; + } + } +}
http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs new file mode 100644 index 0000000..e382605 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepAllTask.cs @@ -0,0 +1,83 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System.Collections.Generic; +using System.Text; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report all statistics with no aggregations. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepAllTask : ReportTask + { + public RepAllTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + Report rp = ReportAll(RunData.Points.TaskStats); + + SystemConsole.WriteLine(); + SystemConsole.WriteLine("------------> Report All (" + rp.Count + " out of " + rp.OutOf + ")"); + SystemConsole.WriteLine(rp.Text); + SystemConsole.WriteLine(); + return 0; + } + + /// <summary> + /// Report detailed statistics as a string. + /// </summary> + /// <param name="taskStats"></param> + /// <returns>The report.</returns> + protected virtual Report ReportAll(IList<TaskStats> taskStats) + { + string longestOp = LongestOp(taskStats); + bool first = true; + StringBuilder sb = new StringBuilder(); + sb.Append(TableTitle(longestOp)); + sb.Append(newline); + int reported = 0; + foreach (TaskStats stat in taskStats) + { + if (stat.Elapsed >= 0) + { // consider only tasks that ended + if (!first) + { + sb.Append(newline); + } + first = false; + string line = TaskReportLine(longestOp, stat); + reported++; + if (taskStats.Count > 2 && reported % 2 == 0) + { + line = line.Replace(" ", " - "); + } + sb.Append(line); + } + } + string reptxt = (reported == 0 ? "No Matching Entries Were Found!" : sb.ToString()); + return new Report(reptxt, reported, reported, taskStats.Count); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs new file mode 100644 index 0000000..16aac93 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSelectByPrefTask.cs @@ -0,0 +1,81 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report by-name-prefix statistics with no aggregations. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepSelectByPrefTask : RepSumByPrefTask + { + public RepSelectByPrefTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + Report rp = ReportSelectByPrefix(RunData.Points.TaskStats); + + SystemConsole.WriteLine(); + SystemConsole.WriteLine("------------> Report Select By Prefix (" + m_prefix + ") (" + + rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + ")"); + SystemConsole.WriteLine(rp.Text); + SystemConsole.WriteLine(); + + return 0; + } + + protected virtual Report ReportSelectByPrefix(IList<TaskStats> taskStats) + { + string longestOp = LongestOp(taskStats); + bool first = true; + StringBuilder sb = new StringBuilder(); + sb.Append(TableTitle(longestOp)); + sb.Append(newline); + int reported = 0; + foreach (TaskStats stat in taskStats) + { + if (stat.Elapsed >= 0 && stat.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal)) + { // only ended tasks with proper name + reported++; + if (!first) + { + sb.Append(newline); + } + first = false; + string line = TaskReportLine(longestOp, stat); + if (taskStats.Count > 2 && reported % 2 == 0) + { + line = line.Replace(" ", " - "); + } + sb.Append(line); + } + } + string reptxt = (reported == 0 ? "No Matching Entries Were Found!" : sb.ToString()); + return new Report(reptxt, reported, reported, taskStats.Count); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs new file mode 100644 index 0000000..bce47ca --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameRoundTask.cs @@ -0,0 +1,83 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System.Collections.Generic; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report all statistics grouped/aggregated by name and round. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepSumByNameRoundTask : ReportTask + { + public RepSumByNameRoundTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + Report rp = ReportSumByNameRound(RunData.Points.TaskStats); + + SystemConsole.WriteLine(); + SystemConsole.WriteLine("------------> Report Sum By (any) Name and Round (" + + rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + ")"); + SystemConsole.WriteLine(rp.Text); + SystemConsole.WriteLine(); + + return 0; + } + + /// <summary> + /// Report statistics as a string, aggregate for tasks named the same, and from the same round. + /// </summary> + /// <param name="taskStats"></param> + /// <returns>The report.</returns> + protected virtual Report ReportSumByNameRound(IList<TaskStats> taskStats) + { + // aggregate by task name and round + LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, TaskStats>(); + int reported = 0; + foreach (TaskStats stat1 in taskStats) + { + if (stat1.Elapsed >= 0) + { // consider only tasks that ended + reported++; + string name = stat1.Task.GetName(); + string rname = stat1.Round + "." + name; // group by round + TaskStats stat2; + if (!p2.TryGetValue(rname, out stat2) || stat2 == null) + { + stat2 = (TaskStats)stat1.Clone(); + + p2[rname] = stat2; + } + else + { + stat2.Add(stat1); + } + } + } + // now generate report from secondary list p2 + return GenPartialReport(reported, p2, taskStats.Count); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs new file mode 100644 index 0000000..30d9878 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByNameTask.cs @@ -0,0 +1,81 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System.Collections.Generic; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report all statistics aggregated by name. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepSumByNameTask : ReportTask + { + public RepSumByNameTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + Report rp = ReportSumByName(RunData.Points.TaskStats); + + SystemConsole.WriteLine(); + SystemConsole.WriteLine("------------> Report Sum By (any) Name (" + + rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + ")"); + SystemConsole.WriteLine(rp.Text); + SystemConsole.WriteLine(); + + return 0; + } + + /// <summary> + /// Report statistics as a string, aggregate for tasks named the same. + /// </summary> + /// <param name="taskStats"></param> + /// <returns>The report.</returns> + protected virtual Report ReportSumByName(IList<TaskStats> taskStats) + { + // aggregate by task name + int reported = 0; + LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, TaskStats>(); + foreach (TaskStats stat1 in taskStats) + { + if (stat1.Elapsed >= 0) + { // consider only tasks that ended + reported++; + string name = stat1.Task.GetName(); + TaskStats stat2; + if (!p2.TryGetValue(name, out stat2) || stat2 == null) + { + stat2 = (TaskStats)stat1.Clone(); + p2[name] = stat2; + } + else + { + stat2.Add(stat1); + } + } + } + // now generate report from secondary list p2 + return GenPartialReport(reported, p2, taskStats.Count); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs new file mode 100644 index 0000000..ce977a0 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefRoundTask.cs @@ -0,0 +1,79 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report all prefix matching statistics grouped/aggregated by name and round. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepSumByPrefRoundTask : RepSumByPrefTask + { + public RepSumByPrefRoundTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + Report rp = ReportSumByPrefixRound(RunData.Points.TaskStats); + + Console.Out.WriteLine(); + Console.Out.WriteLine("------------> Report sum by Prefix (" + m_prefix + ") and Round (" + + rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + ")"); + Console.Out.WriteLine(rp.Text); + Console.Out.WriteLine(); + + return 0; + } + + protected virtual Report ReportSumByPrefixRound(IList<TaskStats> taskStats) + { + // aggregate by task name and by round + int reported = 0; + LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, TaskStats>(); + foreach (TaskStats stat1 in taskStats) + { + if (stat1.Elapsed >= 0 && stat1.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal)) + { // only ended tasks with proper name + reported++; + string name = stat1.Task.GetName(); + string rname = stat1.Round + "." + name; // group by round + TaskStats stat2; + if (!p2.TryGetValue(rname, out stat2) || stat2 == null) + { + stat2 = (TaskStats)stat1.Clone(); + + p2[rname] = stat2; + } + else + { + stat2.Add(stat1); + } + } + } + // now generate report from secondary list p2 + return GenPartialReport(reported, p2, taskStats.Count); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs new file mode 100644 index 0000000..732e902 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RepSumByPrefTask.cs @@ -0,0 +1,91 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report by-name-prefix statistics aggregated by name. + /// <para/> + /// Other side effects: None. + /// </summary> + public class RepSumByPrefTask : ReportTask + { + public RepSumByPrefTask(PerfRunData runData) + : base(runData) + { + } + + protected string m_prefix; + + public override int DoLogic() + { + Report rp = ReportSumByPrefix(RunData.Points.TaskStats); + + SystemConsole.WriteLine(); + SystemConsole.WriteLine("------------> Report Sum By Prefix (" + m_prefix + ") (" + + rp.Count + " about " + rp.Reported + " out of " + rp.OutOf + ")"); + SystemConsole.WriteLine(rp.Text); + SystemConsole.WriteLine(); + + return 0; + } + + protected virtual Report ReportSumByPrefix(IList<TaskStats> taskStats) + { + // aggregate by task name + int reported = 0; + LinkedHashMap<string, TaskStats> p2 = new LinkedHashMap<string, TaskStats>(); + foreach (TaskStats stat1 in taskStats) + { + if (stat1.Elapsed >= 0 && stat1.Task.GetName().StartsWith(m_prefix, StringComparison.Ordinal)) + { // only ended tasks with proper name + reported++; + string name = stat1.Task.GetName(); + TaskStats stat2; + if (!p2.TryGetValue(name, out stat2) || stat2 == null) + { + stat2 = (TaskStats)stat1.Clone(); + p2[name] = stat2; + } + else + { + stat2.Add(stat1); + } + } + } + // now generate report from secondary list p2 + return GenPartialReport(reported, p2, taskStats.Count); + } + + + public virtual void SetPrefix(string prefix) + { + this.m_prefix = prefix; + } + + /// <seealso cref="PerfTask.ToString()"/> + public override string ToString() + { + return base.ToString() + " " + m_prefix; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs new file mode 100644 index 0000000..0e83471 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ReportTask.cs @@ -0,0 +1,189 @@ +using Lucene.Net.Benchmarks.ByTask.Stats; +using Lucene.Net.Benchmarks.ByTask.Utils; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; +using System.Text; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Report (abstract) task - all report tasks extend this task. + /// </summary> + public abstract class ReportTask : PerfTask + { + public ReportTask(PerfRunData runData) + : base(runData) + { + } + + /// <seealso cref="PerfTask.ShouldNeverLogAtStart"/> + protected override bool ShouldNeverLogAtStart + { + get { return true; } + } + + /// <seealso cref="PerfTask.ShouldNotRecordStats"/> + protected override bool ShouldNotRecordStats + { + get { return true; } + } + + /// <summary> + /// From here start the code used to generate the reports. + /// Subclasses would use this part to generate reports. + /// </summary> + protected static readonly string newline = Environment.NewLine; + + /// <summary> + /// Get a textual summary of the benchmark results, average from all test runs. + /// </summary> + protected static readonly string OP = "Operation "; + protected static readonly string ROUND = " round"; + protected static readonly string RUNCNT = " runCnt"; + protected static readonly string RECCNT = " recsPerRun"; + protected static readonly string RECSEC = " rec/s"; + protected static readonly string ELAPSED = " elapsedSec"; + protected static readonly string USEDMEM = " avgUsedMem"; + protected static readonly string TOTMEM = " avgTotalMem"; + protected static readonly string[] COLS = { + RUNCNT, + RECCNT, + RECSEC, + ELAPSED, + USEDMEM, + TOTMEM + }; + + /// <summary> + /// Compute a title line for a report table. + /// </summary> + /// <param name="longestOp">Size of longest op name in the table.</param> + /// <returns>The table title line.</returns> + protected virtual string TableTitle(string longestOp) + { + StringBuilder sb = new StringBuilder(); + sb.Append(Formatter.Format(OP, longestOp)); + sb.Append(ROUND); + sb.Append(RunData.Config.GetColsNamesForValsByRound()); + for (int i = 0; i < COLS.Length; i++) + { + sb.Append(COLS[i]); + } + return sb.ToString(); + } + + /// <summary> + /// Find the longest op name out of completed tasks. + /// </summary> + /// <param name="taskStats">Completed tasks to be considered.</param> + /// <returns>The longest op name out of completed tasks.</returns> + protected virtual string LongestOp(IEnumerable<TaskStats> taskStats) + { + string longest = OP; + foreach (TaskStats stat in taskStats) + { + if (stat.Elapsed >= 0) + { // consider only tasks that ended + string name = stat.Task.GetName(); + if (name.Length > longest.Length) + { + longest = name; + } + } + } + return longest; + } + + /// <summary> + /// Compute a report line for the given task stat. + /// </summary> + /// <param name="longestOp">Size of longest op name in the table.</param> + /// <param name="stat">Task stat to be printed.</param> + /// <returns>The report line.</returns> + protected virtual string TaskReportLine(string longestOp, TaskStats stat) + { + PerfTask task = stat.Task; + StringBuilder sb = new StringBuilder(); + sb.Append(Formatter.Format(task.GetName(), longestOp)); + string round = (stat.Round >= 0 ? "" + stat.Round : "-"); + sb.Append(Formatter.FormatPaddLeft(round, ROUND)); + sb.Append(RunData.Config.GetColsValuesForValsByRound(stat.Round)); + sb.Append(Formatter.Format(stat.NumRuns, RUNCNT)); + sb.Append(Formatter.Format(stat.Count / stat.NumRuns, RECCNT)); + long elapsed = (stat.Elapsed > 0 ? stat.Elapsed : 1); // assume at least 1ms + sb.Append(Formatter.Format(2, (float)(stat.Count * 1000.0 / elapsed), RECSEC)); + sb.Append(Formatter.Format(2, (float)stat.Elapsed / 1000, ELAPSED)); + sb.Append(Formatter.Format(0, (float)stat.MaxUsedMem / stat.NumRuns, USEDMEM)); + sb.Append(Formatter.Format(0, (float)stat.MaxTotMem / stat.NumRuns, TOTMEM)); + return sb.ToString(); + } + + protected virtual Report GenPartialReport(int reported, LinkedHashMap<string, TaskStats> partOfTasks, int totalSize) + { + string longetOp = LongestOp(partOfTasks.Values); + bool first = true; + StringBuilder sb = new StringBuilder(); + sb.Append(TableTitle(longetOp)); + sb.Append(newline); + int lineNum = 0; + foreach (TaskStats stat in partOfTasks.Values) + { + if (!first) + { + sb.Append(newline); + } + first = false; + string line = TaskReportLine(longetOp, stat); + lineNum++; + if (partOfTasks.Count > 2 && lineNum % 2 == 0) + { + line = line.Replace(" ", " - "); + } + sb.Append(line); + int[] byTime = stat.GetCountsByTime(); + if (byTime != null) + { + sb.Append(newline); + int end = -1; + for (int i = byTime.Length - 1; i >= 0; i--) + { + if (byTime[i] != 0) + { + end = i; + break; + } + } + if (end != -1) + { + sb.Append(" by time:"); + for (int i = 0; i < end; i++) + { + sb.Append(' ').Append(byTime[i]); + } + } + } + } + + string reptxt = (reported == 0 ? "No Matching Entries Were Found!" : sb.ToString()); + return new Report(reptxt, partOfTasks.Count, reported, totalSize); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs new file mode 100644 index 0000000..ed6261f --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetInputsTask.cs @@ -0,0 +1,43 @@ +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Reset inputs so that the test run would behave, input wise, + /// as if it just started. This affects e.g. the generation of docs and queries. + /// </summary> + public class ResetInputsTask : PerfTask + { + public ResetInputsTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + RunData.ResetInputs(); + return 0; + } + + /// <seealso cref="PerfTask.ShouldNotRecordStats"/> + protected override bool ShouldNotRecordStats + { + get { return true; } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs new file mode 100644 index 0000000..b8e854a --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemEraseTask.cs @@ -0,0 +1,42 @@ +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Reset all index and input data and call gc, erase index and dir, does NOT clear statistics. + /// <para/> + /// This contains ResetInputs. + /// <para/> + /// Other side effects: writers/readers nullified, deleted, closed. + /// Index is erased. + /// Directory is erased. + /// </summary> + public class ResetSystemEraseTask : ResetSystemSoftTask + { + public ResetSystemEraseTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + RunData.Reinit(true); + return 0; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs new file mode 100644 index 0000000..5d2d4f5 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/ResetSystemSoftTask.cs @@ -0,0 +1,41 @@ +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Reset all index and input data and call gc, does NOT erase index/dir, does NOT clear statistics. + /// This contains ResetInputs. + /// <para/> + /// Other side effects: writers/readers nullified, closed. + /// Index is NOT erased. + /// Directory is NOT erased. + /// </summary> + public class ResetSystemSoftTask : ResetInputsTask + { + public ResetSystemSoftTask(PerfRunData runData) + : base(runData) + { + } + + public override int DoLogic() + { + RunData.Reinit(false); + return 0; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs new file mode 100644 index 0000000..c189b93 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/RollbackIndexTask.cs @@ -0,0 +1,52 @@ +using Lucene.Net.Index; +using Lucene.Net.Util; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Rollback the index writer. + /// </summary> + public class RollbackIndexTask : PerfTask + { + public RollbackIndexTask(PerfRunData runData) + : base(runData) + { + } + + //bool doWait = true; // LUCENENET: Not used + + public override int DoLogic() + { + IndexWriter iw = RunData.IndexWriter; + if (iw != null) + { + // If infoStream was set to output to a file, close it. + InfoStream infoStream = iw.Config.InfoStream; + if (infoStream != null) + { + infoStream.Dispose(); + } + iw.Rollback(); + RunData.IndexWriter = null; + } + return 1; + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs new file mode 100644 index 0000000..f7dd4b7 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTask.cs @@ -0,0 +1,60 @@ +using Lucene.Net.Benchmarks.ByTask.Feeds; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search task. + /// <para/> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// </summary> + public class SearchTask : ReadTask + { + public SearchTask(PerfRunData runData) + : base(runData) + { + } + + public override bool WithRetrieve + { + get { return false; } + } + + public override bool WithSearch + { + get { return true; } + } + + public override bool WithTraverse + { + get { return false; } + } + + public override bool WithWarm + { + get { return false; } + } + + public override IQueryMaker GetQueryMaker() + { + return RunData.GetQueryMaker(this); + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs new file mode 100644 index 0000000..2d623b1 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetHighlightTask.cs @@ -0,0 +1,188 @@ +using Lucene.Net.Analysis; +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Search.Highlight; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search and Traverse and Retrieve docs task. Highlight the fields in the retrieved documents. + /// </summary> + /// <remarks> + /// Uses the <see cref="SimpleHTMLFormatter"/> for formatting. + /// <para/> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// <para/> + /// Takes optional multivalued, comma separated param string as: + /// <code> + /// size[<traversal size>],highlight[<int>],maxFrags[<int>],mergeContiguous[<boolean>],fields[name1;name2;...] + /// </code> + /// <list type="table"> + /// <item><term>traversal size</term><description>The number of hits to traverse, otherwise all will be traversed.</description></item> + /// <item><term>highlight</term><description>The number of the hits to highlight. Will always be less than or equal to traversal size. Default is <see cref="int.MaxValue"/> (i.e. hits.Length).</description></item> + /// <item><term>maxFrags</term><description>The maximum number of fragments to score by the highlighter.</description></item> + /// <item><term>mergeContiguous</term><description><c>true</c> if contiguous fragments should be merged.</description></item> + /// <item><term>fields</term><description>The fields to highlight. If not specified all fields will be highlighted (or at least attempted).</description></item> + /// </list> + /// <para/> + /// Example: + /// <code> + /// "SearchHlgtSameRdr" SearchTravRetHighlight(size[10],highlight[10],mergeContiguous[true],maxFrags[3],fields[body]) > : 1000 + /// </code> + /// <para/> + /// Documents must be stored in order for this task to work. Additionally, term vector positions can be used as well. + /// <para/> + /// Other side effects: counts additional 1 (record) for each traversed hit, + /// and 1 more for each retrieved (non null) document and 1 for each fragment returned. + /// </remarks> + public class SearchTravRetHighlightTask : SearchTravTask + { + protected int m_numToHighlight = int.MaxValue; + protected bool m_mergeContiguous; + protected int m_maxFrags = 2; + protected ISet<string> m_paramFields = new HashSet<string>(); + protected Highlighter m_highlighter; + protected int m_maxDocCharsToAnalyze; + + public SearchTravRetHighlightTask(PerfRunData runData) + : base(runData) + { + } + + public override void Setup() + { + base.Setup(); + //check to make sure either the doc is being stored + PerfRunData data = RunData; + if (data.Config.Get("doc.stored", false) == false) + { + throw new Exception("doc.stored must be set to true"); + } + m_maxDocCharsToAnalyze = data.Config.Get("highlighter.maxDocCharsToAnalyze", Highlighter.DEFAULT_MAX_CHARS_TO_ANALYZE); + } + + public override bool WithRetrieve + { + get { return true; } + } + + public override int NumToHighlight + { + get { return m_numToHighlight; } + } + + protected override BenchmarkHighlighter GetBenchmarkHighlighter(Query q) + { + m_highlighter = new Highlighter(new SimpleHTMLFormatter(), new QueryScorer(q)); + m_highlighter.MaxDocCharsToAnalyze = m_maxDocCharsToAnalyze; + return new BenchmarkHighlighterAnonymousHelper(this, m_highlighter); + } + + private class BenchmarkHighlighterAnonymousHelper : BenchmarkHighlighter + { + private readonly SearchTravRetHighlightTask outerInstance; + private readonly Highlighter highlighter; + + public BenchmarkHighlighterAnonymousHelper(SearchTravRetHighlightTask outerInstance, Highlighter highlighter) + { + this.outerInstance = outerInstance; + this.highlighter = highlighter; + } + public override int DoHighlight(IndexReader reader, int doc, string field, Document document, Analyzer analyzer, string text) + { + TokenStream ts = TokenSources.GetAnyTokenStream(reader, doc, field, document, analyzer); + TextFragment[] + frag = highlighter.GetBestTextFragments(ts, text, outerInstance.m_mergeContiguous, outerInstance.m_maxFrags); + return frag != null ? frag.Length : 0; + } + } + + protected override ICollection<string> GetFieldsToHighlight(Document document) + { + ICollection<string> result = base.GetFieldsToHighlight(document); + //if stored is false, then result will be empty, in which case just get all the param fields + if (m_paramFields.Count > 0 && result.Count > 0) + { + //result.RetainAll(paramFields); + var toRemove = new List<string>(); + foreach (var e in result) + { + if (!m_paramFields.Contains(e)) + toRemove.Add(e); + } + result.RemoveAll(toRemove); + } + else + { + result = m_paramFields; + } + return result; + } + + public override void SetParams(string @params) + { + // can't call super because super doesn't understand our + // params syntax + this.m_params = @params; + string[] splits = @params.Split(',').TrimEnd(); + for (int i = 0; i < splits.Length; i++) + { + if (splits[i].StartsWith("size[", StringComparison.Ordinal) == true) + { + int len = "size[".Length; + m_traversalSize = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("highlight[", StringComparison.Ordinal) == true) + { + int len = "highlight[".Length; + m_numToHighlight = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("maxFrags[", StringComparison.Ordinal) == true) + { + int len = "maxFrags[".Length; + m_maxFrags = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("mergeContiguous[", StringComparison.Ordinal) == true) + { + int len = "mergeContiguous[".Length; + m_mergeContiguous = bool.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len)); + } + else if (splits[i].StartsWith("fields[", StringComparison.Ordinal) == true) + { + m_paramFields = new HashSet<string>(); + int len = "fields[".Length; + string fieldNames = splits[i].Substring(len, (splits[i].Length - 1) - len); + string[] fieldSplits = fieldNames.Split(';').TrimEnd(); + for (int j = 0; j < fieldSplits.Length; j++) + { + m_paramFields.Add(fieldSplits[j]); + } + + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs new file mode 100644 index 0000000..169a330 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetLoadFieldSelectorTask.cs @@ -0,0 +1,85 @@ +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Support; +using System.Collections.Generic; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search and Traverse and Retrieve docs task using a + /// FieldVisitor loading only the requested fields. + /// </summary> + /// <remarks> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// <para/> + /// Takes optional param: comma separated list of Fields to load. + /// <para/> + /// Other side effects: counts additional 1 (record) for each traversed hit, + /// and 1 more for each retrieved (non null) document. + /// </remarks> + public class SearchTravRetLoadFieldSelectorTask : SearchTravTask + { + protected ISet<string> m_fieldsToLoad; + + public SearchTravRetLoadFieldSelectorTask(PerfRunData runData) + : base(runData) + { + } + + public override bool WithRetrieve + { + get { return true; } + } + + + protected override Document RetrieveDoc(IndexReader ir, int id) + { + if (m_fieldsToLoad == null) + { + return ir.Document(id); + } + else + { + DocumentStoredFieldVisitor visitor = new DocumentStoredFieldVisitor(m_fieldsToLoad); + ir.Document(id, visitor); + return visitor.Document; + } + } + + public override void SetParams(string @params) + { + this.m_params = @params; // cannot just call super.setParams(), b/c it's params differ. + m_fieldsToLoad = new HashSet<string>(); + for (StringTokenizer tokenizer = new StringTokenizer(@params, ","); tokenizer.HasMoreTokens();) + { + string s = tokenizer.NextToken(); + m_fieldsToLoad.Add(s); + } + } + + + /// <seealso cref="PerfTask.SupportsParams"/> + public override bool SupportsParams + { + get { return true; } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs new file mode 100644 index 0000000..61d1436 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetTask.cs @@ -0,0 +1,44 @@ +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search and Traverse and Retrieve docs task. + /// </summary> + /// <remarks> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// <para/> + /// Takes optional param: traversal size (otherwise all results are traversed). + /// <para/> + /// Other side effects: counts additional 1 (record) for each traversed hit, + /// and 1 more for each retrieved (non null) document. + /// </remarks> + public class SearchTravRetTask : SearchTravTask + { + public SearchTravRetTask(PerfRunData runData) + : base(runData) + { + } + + public override bool WithRetrieve + { + get { return true; } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs new file mode 100644 index 0000000..0725c65 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravRetVectorHighlightTask.cs @@ -0,0 +1,191 @@ +using Lucene.Net.Analysis; +using Lucene.Net.Documents; +using Lucene.Net.Index; +using Lucene.Net.Search; +using Lucene.Net.Search.VectorHighlight; +using Lucene.Net.Support; +using System; +using System.Collections.Generic; +using System.Globalization; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search and Traverse and Retrieve docs task. Highlight the fields in the retrieved documents by using <see cref="FastVectorHighlighter"/>. + /// </summary> + /// <remarks> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// <para/> + /// Takes optional multivalued, comma separated param string as: + /// <code> + /// size[<traversal size>],highlight[<int>],maxFrags[<int>],mergeContiguous[<boolean>],fields[name1;name2;...] + /// </code> + /// <list type="bullet"> + /// <item><term>traversal size</term><description>The number of hits to traverse, otherwise all will be traversed.</description></item> + /// <item><term>highlight</term><description>The number of the hits to highlight. Will always be less than or equal to traversal size. Default is <see cref="int.MaxValue"/> (i.e. hits.Length).</description></item> + /// <item><term>maxFrags</term><description>The maximum number of fragments to score by the highlighter.</description></item> + /// <item><term>fragSize</term><description>The length of fragments.</description></item> + /// <item><term>fields</term><description>The fields to highlight. If not specified all fields will be highlighted (or at least attempted).</description></item> + /// </list> + /// <para/> + /// Example: + /// <code> + /// "SearchVecHlgtSameRdr" SearchTravRetVectorHighlight(size[10],highlight[10],maxFrags[3],fields[body]) > : 1000 + /// </code> + /// <para/> + /// Fields must be stored and term vector offsets and positions in order must be true for this task to work. + /// <para/> + /// Other side effects: counts additional 1 (record) for each traversed hit, + /// and 1 more for each retrieved (non null) document and 1 for each fragment returned. + /// </remarks> + public class SearchTravRetVectorHighlightTask : SearchTravTask + { + protected int m_numToHighlight = int.MaxValue; + protected int m_maxFrags = 2; + protected int m_fragSize = 100; + protected ISet<string> m_paramFields = new HashSet<string>(); + protected FastVectorHighlighter m_highlighter; + + public SearchTravRetVectorHighlightTask(PerfRunData runData) + : base(runData) + { + } + + public override void Setup() + { + base.Setup(); + //check to make sure either the doc is being stored + PerfRunData data = RunData; + if (data.Config.Get("doc.stored", false) == false) + { + throw new Exception("doc.stored must be set to true"); + } + if (data.Config.Get("doc.term.vector.offsets", false) == false) + { + throw new Exception("doc.term.vector.offsets must be set to true"); + } + if (data.Config.Get("doc.term.vector.positions", false) == false) + { + throw new Exception("doc.term.vector.positions must be set to true"); + } + } + + public override bool WithRetrieve + { + get { return true; } + } + + public override int NumToHighlight + { + get { return m_numToHighlight; } + } + + protected override BenchmarkHighlighter GetBenchmarkHighlighter(Query q) + { + m_highlighter = new FastVectorHighlighter(false, false); + Query myq = q; + return new BenchmarkHighlighterAnonymousHelper(this, m_highlighter, myq); + } + + private class BenchmarkHighlighterAnonymousHelper : BenchmarkHighlighter + { + private readonly SearchTravRetVectorHighlightTask outerInstance; + private readonly FastVectorHighlighter highlighter; + private readonly Query myq; + public BenchmarkHighlighterAnonymousHelper(SearchTravRetVectorHighlightTask outerInstance, FastVectorHighlighter highlighter, Query myq) + { + this.outerInstance = outerInstance; + this.highlighter = highlighter; + this.myq = myq; + } + public override int DoHighlight(IndexReader reader, int doc, string field, Document document, Analyzer analyzer, string text) + { + FieldQuery fq = highlighter.GetFieldQuery(myq, reader); + string[] fragments = highlighter.GetBestFragments(fq, reader, doc, field, outerInstance.m_fragSize, outerInstance.m_maxFrags); + return fragments != null ? fragments.Length : 0; + } + } + + protected override ICollection<string> GetFieldsToHighlight(Document document) + { + ICollection<string> result = base.GetFieldsToHighlight(document); + //if stored is false, then result will be empty, in which case just get all the param fields + if (m_paramFields.Count > 0 && result.Count > 0) + { + //result.RetainAll(paramFields); + var toRemove = new List<string>(); + foreach (var e in result) + { + if (!m_paramFields.Contains(e)) + toRemove.Add(e); + } + result.RemoveAll(toRemove); + } + else + { + result = m_paramFields; + } + return result; + } + + public override void SetParams(string @params) + { + // can't call super because super doesn't understand our + // params syntax + string[] splits = @params.Split(',').TrimEnd(); + for (int i = 0; i < splits.Length; i++) + { + if (splits[i].StartsWith("size[", StringComparison.Ordinal) == true) + { + int len = "size[".Length; + m_traversalSize = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("highlight[", StringComparison.Ordinal) == true) + { + int len = "highlight[".Length; + m_numToHighlight = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("maxFrags[", StringComparison.Ordinal) == true) + { + int len = "maxFrags[".Length; + m_maxFrags = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("fragSize[", StringComparison.Ordinal) == true) + { + int len = "fragSize[".Length; + m_fragSize = (int)float.Parse(splits[i].Substring(len, (splits[i].Length - 1) - len), CultureInfo.InvariantCulture); + } + else if (splits[i].StartsWith("fields[", StringComparison.Ordinal) == true) + { + m_paramFields = new HashSet<string>(); + int len = "fields[".Length; + string fieldNames = splits[i].Substring(len, (splits[i].Length - 1) - len); + string[] fieldSplits = fieldNames.Split(';').TrimEnd(); + for (int j = 0; j < fieldSplits.Length; j++) + { + m_paramFields.Add(fieldSplits[j]); + } + + } + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs new file mode 100644 index 0000000..a514411 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchTravTask.cs @@ -0,0 +1,87 @@ +using Lucene.Net.Benchmarks.ByTask.Feeds; +using System.Globalization; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Search and Traverse task. + /// </summary> + /// <remarks> + /// Note: This task reuses the reader if it is already open. + /// Otherwise a reader is opened at start and closed at the end. + /// <para/> + /// Takes optional param: traversal size (otherwise all results are traversed). + /// <para/> + /// Other side effects: counts additional 1 (record) for each traversed hit. + /// </remarks> + public class SearchTravTask : ReadTask + { + protected int m_traversalSize = int.MaxValue; + + public SearchTravTask(PerfRunData runData) + : base(runData) + { + } + + public override bool WithRetrieve + { + get { return false; } + } + + + public override bool WithSearch + { + get { return true; } + } + + public override bool WithTraverse + { + get { return true; } + } + + public override bool WithWarm + { + get { return false; } + } + + + public override IQueryMaker GetQueryMaker() + { + return RunData.GetQueryMaker(this); + } + + public override int TraversalSize + { + get { return m_traversalSize; } + } + + public override void SetParams(string @params) + { + base.SetParams(@params); + m_traversalSize = (int)float.Parse(@params, CultureInfo.InvariantCulture); + } + + /// <seealso cref="PerfTask.SupportsParams"/> + public override bool SupportsParams + { + get { return true; } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs new file mode 100644 index 0000000..b767b44 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithCollectorTask.cs @@ -0,0 +1,99 @@ +using Lucene.Net.Benchmarks.ByTask.Feeds; +using Lucene.Net.Benchmarks.ByTask.Utils; +using Lucene.Net.Search; +using System; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Does search w/ a custom collector + /// </summary> + public class SearchWithCollectorTask : SearchTask + { + protected string m_clnName; + + public SearchWithCollectorTask(PerfRunData runData) + : base(runData) + { + } + + public override void Setup() + { + base.Setup(); + //check to make sure either the doc is being stored + PerfRunData runData = RunData; + Config config = runData.Config; + m_clnName = config.Get("collector.class", ""); + } + + public override bool WithCollector + { + get { return true; } + } + + protected override ICollector CreateCollector() + { + ICollector collector = null; + if (m_clnName.Equals("topScoreDocOrdered", StringComparison.OrdinalIgnoreCase) == true) + { + collector = TopScoreDocCollector.Create(NumHits, true); + } + else if (m_clnName.Equals("topScoreDocUnOrdered", StringComparison.OrdinalIgnoreCase) == true) + { + collector = TopScoreDocCollector.Create(NumHits, false); + } + else if (m_clnName.Length > 0) + { + collector = (ICollector)Activator.CreateInstance(Type.GetType(m_clnName)); + + } + else + { + collector = base.CreateCollector(); + } + return collector; + } + + public override IQueryMaker GetQueryMaker() + { + return RunData.GetQueryMaker(this); + } + + public override bool WithRetrieve + { + get { return false; } + } + + public override bool WithSearch + { + get { return true; } + } + + public override bool WithTraverse + { + get { return false; } + } + + public override bool WithWarm + { + get { return false; } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs new file mode 100644 index 0000000..634f048 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SearchWithSortTask.cs @@ -0,0 +1,157 @@ +using Lucene.Net.Benchmarks.ByTask.Feeds; +using Lucene.Net.Search; +using Lucene.Net.Support; +using System; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Does sort search on specified field. + /// </summary> + public class SearchWithSortTask : ReadTask + { + private bool doScore = true; + private bool doMaxScore = true; + private Sort sort; + + public SearchWithSortTask(PerfRunData runData) + : base(runData) + { + } + + /// <summary> + /// SortFields: field:type,field:type[,noscore][,nomaxscore] + /// <para/> + /// If noscore is present, then we turn off score tracking + /// in <see cref="TopFieldCollector"/>. + /// If nomaxscore is present, then we turn off maxScore tracking + /// in <see cref="TopFieldCollector"/>. + /// <para/> + /// name:string,page:int,subject:string + /// </summary> + public override void SetParams(string sortField) + { + base.SetParams(sortField); + string[] fields = sortField.Split(',').TrimEnd(); + SortField[] sortFields = new SortField[fields.Length]; + int upto = 0; + for (int i = 0; i < fields.Length; i++) + { + string field = fields[i]; + SortField sortField0; + if (field.Equals("doc", StringComparison.Ordinal)) + { + sortField0 = SortField.FIELD_DOC; + } + else if (field.Equals("score", StringComparison.Ordinal)) + { + sortField0 = SortField.FIELD_SCORE; + } + else if (field.Equals("noscore", StringComparison.Ordinal)) + { + doScore = false; + continue; + } + else if (field.Equals("nomaxscore", StringComparison.Ordinal)) + { + doMaxScore = false; + continue; + } + else + { + int index = field.LastIndexOf(':'); + string fieldName; + string typeString; + if (index != -1) + { + fieldName = field.Substring(0, index - 0); + typeString = field.Substring(1 + index, field.Length - (1 + index)); + } + else + { + throw new Exception("You must specify the sort type ie page:int,subject:string"); + } + sortField0 = new SortField(fieldName, (SortFieldType)Enum.Parse(typeof(SortFieldType), typeString, true)); + } + sortFields[upto++] = sortField0; + } + + if (upto < sortFields.Length) + { + SortField[] newSortFields = new SortField[upto]; + System.Array.Copy(sortFields, 0, newSortFields, 0, upto); + sortFields = newSortFields; + } + this.sort = new Sort(sortFields); + } + + public override bool SupportsParams + { + get { return true; } + } + + public override IQueryMaker GetQueryMaker() + { + return RunData.GetQueryMaker(this); + } + + public override bool WithRetrieve + { + get { return false; } + } + + public override bool WithSearch + { + get { return true; } + } + + public override bool WithTraverse + { + get { return false; } + } + + public override bool WithWarm + { + get { return false; } + } + + public override bool WithScore + { + get { return doScore; } + } + + public override bool WithMaxScore + { + get { return doMaxScore; } + } + + public override Sort Sort + { + get + { + if (sort == null) + { + throw new InvalidOperationException("No sort field was set"); + } + return sort; + } + } + } +} http://git-wip-us.apache.org/repos/asf/lucenenet/blob/b515271d/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs ---------------------------------------------------------------------- diff --git a/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs b/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs new file mode 100644 index 0000000..abb66d2 --- /dev/null +++ b/src/Lucene.Net.Benchmark/ByTask/Tasks/SetPropTask.cs @@ -0,0 +1,71 @@ +using System; + +namespace Lucene.Net.Benchmarks.ByTask.Tasks +{ + /* + * 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. + */ + + /// <summary> + /// Set a performance test configuration property. + /// A property may have a single value, or a sequence of values, separated by ":". + /// If a sequence of values is specified, each time a new round starts, + /// the next (cyclic) value is taken. + /// <para/> + /// Other side effects: none. + /// <para/> + /// Takes mandatory param: "name,value" pair. + /// </summary> + /// <seealso cref="NewRoundTask"/> + public class SetPropTask : PerfTask + { + public SetPropTask(PerfRunData runData) + : base(runData) + { + } + + private string name; + private string value; + + public override int DoLogic() + { + if (name == null || value == null) + { + throw new Exception(GetName() + " - undefined name or value: name=" + name + " value=" + value); + } + RunData.Config.Set(name, value); + return 0; + } + + /// <summary> + /// Set the params (property name and value). + /// </summary> + /// <param name="params">Property name and value separated by ','.</param> + public override void SetParams(string @params) + { + base.SetParams(@params); + int k = @params.IndexOf(","); + name = @params.Substring(0, k - 0).Trim(); + value = @params.Substring(k + 1).Trim(); + } + + /// <seealso cref="PerfTask.SupportsParams"/> + public override bool SupportsParams + { + get { return true; } + } + } +}
