22 package com.mysql.cluster.crund;
24 import java.util.Properties;
25 import java.util.List;
26 import java.util.ArrayList;
27 import java.text.ParseException;
28 import java.text.DecimalFormat;
30 import java.io.FileInputStream;
31 import java.io.FileReader;
32 import java.io.BufferedReader;
33 import java.io.IOException;
34 import java.io.PrintWriter;
35 import java.io.InputStream;
69 static public class SimpleResultReporter
implements ResultReporter {
70 static protected final DecimalFormat df =
new DecimalFormat(
"#.##");
75 public void report(
String tag,
83 out.println(
"tag = " + tag);
84 out.println(
"nRuns = " + nRuns);
85 out.println(
"nTxOps = " + nTxOps);
89 final double thres = 10.0;
90 final List<String> problematic =
new ArrayList<String>();
92 for (
int i = 0;
i < op.length;
i++) {
93 out.println(
"op = " + op[
i]);
94 out.println(
"avg = " + df.format(avg[i]));
95 out.println(
"sdev = " + df.format(sdev[i]));
96 out.println(
"rsdev = " + df.format(rsdev[i]) +
"%");
99 if (rsdev[i] > thres) {
100 problematic.add(df.format(rsdev[i]) +
"%\t" + op[
i]);
104 if (problematic.size() > 1) {
105 out.println(
"operations with large deviations:");
106 for (
String p : problematic) {
107 out.println(
" " + p);
114 static protected final PrintWriter out =
new PrintWriter(System.out,
true);
115 static protected final PrintWriter err =
new PrintWriter(System.err,
true);
118 static protected final String endl = System.getProperty(
"line.separator");
121 static private final List<String> propFileNames =
new ArrayList<String>();
122 static private final List<String> ilogFileNames =
new ArrayList<String>();
126 protected int nWarmupRuns;
129 protected ResultReporter reporter;
130 protected String[] header;
131 protected int nTxOps;
133 protected double[] ravg;
134 protected double[] rdev;
144 out.println(
"usage: [options] <log file>...");
145 out.println(
" [-p <file name>]... a properties file name");
146 out.println(
" [-h|--help] print usage message and exit");
155 for (
int i = 0; i < args.length; i++) {
157 if (arg.equals(
"-p")) {
158 if (i >= args.length) {
161 propFileNames.add(args[++i]);
162 }
else if (arg.equals(
"-h") || arg.equals(
"--help")) {
164 }
else if (arg.startsWith(
"-")) {
165 out.println(
"unknown option: " + arg);
168 ilogFileNames.add(args[i]);
172 if (propFileNames.size() == 0) {
173 propFileNames.add(
"crundResult.properties");
176 if (ilogFileNames.size() == 0) {
177 out.println(
"missing input files");
196 for (
String fn : ilogFileNames) {
198 out.println(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
199 out.println(
"reading log file: " + fn);
200 out.println(
"++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++");
202 BufferedReader ilog = null;
204 ilog =
new BufferedReader(
new FileReader(fn));
213 }
catch (Exception ex) {
215 out.println(
"caught " + ex);
216 ex.printStackTrace();
222 protected void process(BufferedReader ilog)
223 throws IOException, ParseException {
227 int nIgnored = nWarmupRuns;
229 line = ilog.readLine();
237 if (line.startsWith(
"#")) {
242 if (line.equals(
"")) {
243 if (header != null) {
254 if (header == null) {
255 header = line.split(
"\\t");
256 assert (header.length > 0);
260 ravg =
new double[header.length];
261 rdev =
new double[header.length];
266 final String[] values = line.split(
"\\t");
267 if (values.length != header.length) {
269 +
": wrong number of tokens; "
270 +
"expected: " + header.length
271 +
", found: " + values.length);
272 throw new ParseException(msg, 0);
279 n = Integer.valueOf(values[0]);
280 }
catch (NumberFormatException e) {
283 throw new ParseException(msg, 0);
287 }
else if (nTxOps != n) {
289 +
": unexpected nTxOps; "
290 +
"expected: " + nTxOps
292 throw new ParseException(msg, 0);
296 if (nRuns <= nIgnored) {
303 for (
int i = 1; i < values.length; i++) {
306 l = Long.valueOf(values[i]);
307 }
catch (NumberFormatException e) {
310 throw new ParseException(msg, i);
315 final double oavg = ravg[
i];
316 final double navg = oavg + (v - oavg) / nRuns;
317 final double odev = rdev[
i];
318 final double ndev = odev + (v - oavg) * (v - navg);
325 protected void report() {
327 final int nops = header.length - 1;
329 final double[] avg =
new double[nops];
330 final double[] sdev =
new double[nops];
331 final double[] rsdev =
new double[nops];
334 for (
int i = 1; i <= nops; i++) {
337 sdev[i-1] = Math.sqrt(rdev[i] / nRuns);
338 rsdev[i-1] = (sdev[i-1] * 100.0) / avg[i-1];
340 final String tag = header[0];
342 reporter.
report(tag, nRuns, nTxOps, op, avg, sdev, rsdev);
350 protected void init() throws Exception {
354 reporter =
new SimpleResultReporter();
358 protected void close() throws Exception {
364 private void loadProperties() throws IOException {
366 for (
String fn : propFileNames) {
367 out.println(
"reading properties file: " + fn);
380 protected boolean parseBoolean(
String k,
boolean vdefault) {
381 final String v = props.getProperty(k);
382 return (v == null ? vdefault : Boolean.parseBoolean(v));
386 protected int parseInt(
String k,
int vdefault) {
387 final String v = props.getProperty(k);
389 return (v == null ? vdefault : Integer.parseInt(v));
390 }
catch (NumberFormatException e) {
391 final NumberFormatException nfe =
new NumberFormatException(
392 "invalid value of property ('" + k +
"', '"
400 protected void initProperties() {
402 out.print(
"setting properties ...");
405 final StringBuilder
msg =
new StringBuilder();
406 final String eol = System.getProperty(
"line.separator");
408 nWarmupRuns = parseInt(
"nWarmupRuns", 0);
409 if (nWarmupRuns < 0) {
410 msg.append(
"[ignored] nWarmupRuns: " + nWarmupRuns + eol);
414 if (msg.length() == 0) {
415 out.println(
" [ok]");
418 out.print(msg.toString());
423 protected void printProperties() {
425 out.println(
"result processor settings ...");
426 out.println(
"nWarmupRuns: " + nWarmupRuns);
431 static public void main(
String[] args) {
432 System.out.println(
"ResultProcessor.main()");
435 System.out.println();
436 System.out.println(
"ResultProcessor.main(): done.");