MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Driver.java
1 /* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2  * vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
3  *
4  * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
5  *
6  * This program is free software; you can redistribute it and/or modify
7  * it under the terms of the GNU General Public License as published by
8  * the Free Software Foundation; version 2 of the License.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18  */
19 
20 package com.mysql.cluster.crund;
21 
22 import java.util.Properties;
23 import java.util.List;
24 import java.util.ArrayList;
25 import java.util.Date;
26 import java.text.SimpleDateFormat;
27 
28 import java.io.File;
29 import java.io.FileInputStream;
30 import java.io.FileNotFoundException;
31 import java.io.FileOutputStream;
32 import java.io.FileWriter;
33 import java.io.IOException;
34 import java.io.OutputStream;
35 import java.io.PrintWriter;
36 import java.io.InputStream;
37 
38 
58 abstract public class Driver {
59 
60  // console
61  static protected final PrintWriter out = new PrintWriter(System.out, true);
62  static protected final PrintWriter err = new PrintWriter(System.err, true);
63 
64  // shortcuts
65  static protected final String endl = System.getProperty("line.separator");
66  static protected final Runtime rt = Runtime.getRuntime();
67 
68  // driver command-line arguments
69  static private final List<String> propFileNames = new ArrayList<String>();
70  static private String logFileName;
71 
72  // driver settings
73  protected final Properties props = new Properties();
74  protected boolean logRealTime;
75  protected boolean logMemUsage;
76  protected boolean includeFullGC;
77  protected int nRuns;
78 
79  // driver resources
80  protected PrintWriter log;
81  protected String descr = "";
82  protected boolean logHeader;
83  protected StringBuilder header;
84  protected StringBuilder rtimes;
85  protected StringBuilder musage;
86  protected long t0 = 0, t1 = 0, ta = 0;
87  protected long m0 = 0, m1 = 0, ma = 0;
88 
89  // ----------------------------------------------------------------------
90  // driver usage
91  // ----------------------------------------------------------------------
92 
96  static protected void exitUsage() {
97  out.println("usage: [options]");
98  out.println(" [-p <file name>]... a properties file name");
99  out.println(" [-l <file name>] log file name for data output");
100  out.println(" [-h|--help] print usage message and exit");
101  out.println();
102  System.exit(1); // return an error code
103  }
104 
108  static public void parseArguments(String[] args) {
109  for (int i = 0; i < args.length; i++) {
110  final String arg = args[i];
111  if (arg.equals("-p")) {
112  if (i >= args.length) {
113  exitUsage();
114  }
115  propFileNames.add(args[++i]);
116  } else if (arg.equals("-l")) {
117  if (i >= args.length) {
118  exitUsage();
119  }
120  logFileName = args[++i];
121  } else if (arg.equals("-h") || arg.equals("--help")) {
122  exitUsage();
123  } else {
124  out.println("unknown option: " + arg);
125  exitUsage();
126  }
127  }
128 
129  if (propFileNames.size() == 0) {
130  propFileNames.add("run.properties");
131  }
132 
133  if (logFileName == null) {
134  SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd_HHMMss");
135  logFileName = ("log_" + sdf.format(new Date()) + ".txt");
136  }
137  }
138 
142  public Driver() {}
143 
147  public void run() {
148  try {
149  init();
150  runTests();
151  close();
152  } catch (Exception ex) {
153  // end the program regardless of threads
154  out.println("caught " + ex);
155  ex.printStackTrace();
156  System.exit(2); // return an error code
157  }
158  }
159 
160  // ----------------------------------------------------------------------
161  // driver intializers/finalizers
162  // ----------------------------------------------------------------------
163 
164  // loads a dynamically linked system library and reports any failures
165  static protected void loadSystemLibrary(String name) {
166  out.print("loading libary ...");
167  out.flush();
168  try {
169  System.loadLibrary(name);
170  } catch (UnsatisfiedLinkError e) {
171  String path;
172  try {
173  path = System.getProperty("java.library.path");
174  } catch (Exception ex) {
175  path = "<exception caught: " + ex.getMessage() + ">";
176  }
177  err.println("NdbBase: failed loading library '"
178  + name + "'; java.library.path='" + path + "'");
179  throw e;
180  } catch (SecurityException e) {
181  err.println("NdbBase: failed loading library '"
182  + name + "'; caught exception: " + e);
183  throw e;
184  }
185  out.println(" [" + name + "]");
186  }
187 
188  // attempts to run the JVM's Garbage Collector
189  static private void gc() {
190  // empirically determined limit after which no further
191  // reduction in memory usage has been observed
192  //final int nFullGCs = 5;
193  final int nFullGCs = 10;
194  for (int i = 0; i < nFullGCs; i++) {
195  //out.print("gc: ");
196  long oldfree;
197  long newfree = rt.freeMemory();
198  do {
199  oldfree = newfree;
200  rt.runFinalization();
201  rt.gc();
202  newfree = rt.freeMemory();
203  //out.print('.');
204  } while (newfree > oldfree);
205  //out.println();
206  }
207  }
208 
209  // initializes the driver's resources.
210  protected void init() throws Exception {
211  loadProperties();
212  initProperties();
213  printProperties();
214  writeProperties("logging.properties");
215  // setting this property allows implementations under test to use java.util.logging
216  System.setProperty("java.util.logging.config.file", "logging.properties");
217  openLogFile();
218  clearLogBuffers();
219  }
220 
221  // releases the driver's resources.
222  protected void close() throws Exception {
223  // release log buffers
224  logHeader = false;
225  header = null;
226  rtimes = null;
227  musage = null;
228 
229  closeLogFile();
230  props.clear();
231  }
232 
233  // loads the benchmark's properties from properties files
234  private void loadProperties() throws IOException {
235  out.println();
236  for (String fn : propFileNames) {
237  out.println("reading properties file: " + fn);
238  InputStream is = null;
239  try {
240  is = new FileInputStream(fn);
241  props.load(is);
242  } finally {
243  if (is != null)
244  is.close();
245  }
246  }
247  }
248 
249  // retrieves a property's value and parses it as a boolean
250  protected boolean parseBoolean(String k, boolean vdefault) {
251  final String v = props.getProperty(k);
252  return (v == null ? vdefault : Boolean.parseBoolean(v));
253  }
254 
255  // retrieves a property's value and parses it as a signed decimal integer
256  protected int parseInt(String k, int vdefault) {
257  final String v = props.getProperty(k);
258  try {
259  return (v == null ? vdefault : Integer.parseInt(v));
260  } catch (NumberFormatException e) {
261  final NumberFormatException nfe = new NumberFormatException(
262  "invalid value of benchmark property ('" + k + "', '"
263  + v + "').");
264  nfe.initCause(e);
265  throw nfe;
266  }
267  }
268 
269  // initializes the benchmark properties
270  protected void initProperties() {
271  //props.list(out);
272  out.print("setting driver properties ...");
273  out.flush();
274 
275  final StringBuilder msg = new StringBuilder();
276  final String eol = System.getProperty("line.separator");
277 
278  logRealTime = parseBoolean("logRealTime", true);
279  logMemUsage = parseBoolean("logMemUsage", false);
280  includeFullGC = parseBoolean("includeFullGC", false);
281 
282  nRuns = parseInt("nRuns", 1);
283  if (nRuns < 1) {
284  msg.append("[ignored] nRuns: " + nRuns + eol);
285  nRuns = 1;
286  }
287 
288  if (msg.length() == 0) {
289  out.println(" [ok]");
290  } else {
291  out.println();
292  out.print(msg.toString());
293  }
294  }
295 
296  // prints the benchmark's properties
297  protected void printProperties() {
298  out.println();
299  out.println("driver settings ...");
300  out.println("logRealTime: " + logRealTime);
301  out.println("logMemUsage: " + logMemUsage);
302  out.println("includeFullGC: " + includeFullGC);
303  out.println("nRuns: " + nRuns);
304  }
305 
306  protected void writeProperties(String fileName) {
307  File logger = new File(fileName);
308  OutputStream out;
309  try {
310  if (!logger.exists()) {
311  logger.createNewFile();
312  }
313  out = new FileOutputStream(logger);
314  props.store(out, "**** WARNING: DO NOT EDIT THIS FILE; IT IS GENERATED EACH RUN.");
315  } catch (FileNotFoundException e) {
316  throw new RuntimeException("Unexpected exception opening file logger.properties.", e);
317  } catch (IOException e) {
318  throw new RuntimeException("Unexpected exception writing file logger.properties.", e);
319  }
320  }
321  // opens the benchmark's data log file
322  private void openLogFile() throws IOException {
323  out.println();
324  out.println("writing results to file: " + logFileName);
325  log = new PrintWriter(new FileWriter(logFileName, false));
326  }
327 
328  // closes the benchmark's data log file
329  private void closeLogFile() throws IOException {
330  out.println();
331  out.print("closing files ...");
332  out.flush();
333  if (log != null) {
334  log.close();
335  log = null;
336  }
337  out.println(" [ok]");
338  }
339 
340  // ----------------------------------------------------------------------
341  // benchmark operations
342  // ----------------------------------------------------------------------
343 
344  abstract protected void runTests() throws Exception;
345 
346  protected void clearLogBuffers() {
347  logHeader = true;
348  header = new StringBuilder();
349  if (logRealTime) {
350  rtimes = new StringBuilder();
351  }
352  if (logMemUsage) {
353  musage = new StringBuilder();
354  }
355  }
356 
357  protected void writeLogBuffers(String descr) {
358  if (logRealTime) {
359  log.println(descr + ", rtime[ms]"
360  + header.toString() + endl
361  + rtimes.toString() + endl);
362  }
363  if (logMemUsage) {
364  log.println(descr + ", net musage[KiB]"
365  + header.toString() + endl
366  + musage.toString() + endl);
367  }
368  }
369 
370  protected void begin(String name) {
371  out.println();
372  out.println(name);
373 
374  // attempt max GC, before tx
375  gc();
376 
377  if (logMemUsage) {
378  m0 = rt.totalMemory() - rt.freeMemory();
379  }
380 
381  if (logRealTime) {
382  //t0 = System.currentTimeMillis();
383  t0 = System.nanoTime() / 1000000;
384  }
385  }
386 
387  protected void finish(String name) {
388  // attempt one full GC, before timing tx end
389  if (includeFullGC) {
390  rt.gc();
391  }
392 
393  if (logRealTime) {
394  //t1 = System.currentTimeMillis();
395  t1 = System.nanoTime() / 1000000;
396  final long t = t1 - t0;
397  out.println("tx real time " + t
398  + "\tms");
399  //rtimes.append("\t" + (Math.round(t / 100.0) / 10.0));
400  rtimes.append("\t" + t);
401  ta += t;
402  }
403 
404  if (logMemUsage) {
405  // attempt max GC, after tx
406  gc();
407  m1 = rt.totalMemory() - rt.freeMemory();
408  final long m0K = (m0 / 1024);
409  final long m1K = (m1 / 1024);
410  final long mK = m1K - m0K;
411  out.println("net mem usage "
412  + (mK >= 0 ? "+" : "") + mK
413  + "\tKiB [" + m0K + "K->" + m1K + "K]");
414  musage.append("\t" + mK);
415  ma += mK;
416  }
417 
418  if (logHeader)
419  header.append("\t" + name);
420  }
421 }