MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Driver.cpp
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 #include <iostream>
21 #include <sstream>
22 #include <fstream>
23 #include <string>
24 #include <vector>
25 #include <cassert>
26 #include <ctime>
27 
28 #include "helpers.hpp"
29 #include "string_helpers.hpp"
30 
31 #include "Driver.hpp"
32 
33 using std::cout;
34 using std::flush;
35 using std::endl;
36 using std::ios_base;
37 using std::ofstream;
38 using std::ostringstream;
39 using std::string;
40 using std::wstring;
41 using std::vector;
42 
43 using utils::Properties;
44 using utils::toBool;
45 using utils::toInt;
46 using utils::toString;
47 
48 //---------------------------------------------------------------------------
49 
50 vector< string > Driver::propFileNames;
51 string Driver::logFileName;
52 
53 void
54 Driver::exitUsage()
55 {
56  cout << "usage: [options]" << endl
57  << " [-p <file name>]... properties file name" << endl
58  << " [-l <file name>] log file name for data output" << endl
59  << " [-h|--help] print usage message and exit" << endl
60  << endl;
61  exit(1); // return an error code
62 }
63 
64 void
65 Driver::parseArguments(int argc, const char* argv[])
66 {
67  for (int i = 1; i < argc; i++) {
68  const string arg = argv[i];
69  if (arg.compare("-p") == 0) {
70  if (i >= argc) {
71  exitUsage();
72  }
73  propFileNames.push_back(argv[++i]);
74  } else if (arg.compare("-l") == 0) {
75  if (i >= argc) {
76  exitUsage();
77  }
78  logFileName = argv[++i];
79  } else if (arg.compare("-h") == 0 || arg.compare("--help") == 0) {
80  exitUsage();
81  } else {
82  cout << "unknown option: " << arg << endl;
83  exitUsage();
84  }
85  }
86 
87  if (propFileNames.size() == 0) {
88  propFileNames.push_back("run.properties");
89  }
90 
91  if (logFileName.empty()) {
92  logFileName = "log_";
93 
94  // format, destination strings (static size)
95  const char format[] = "%Y%m%d_%H%M%S";
96  const int size = sizeof("yyyymmdd_HHMMSS");
97  char dest[size];
98 
99  // get time, convert to timeinfo (statically allocated) then to string
100  const time_t now = time(0);
101  const int nchars = strftime(dest, size, format, localtime(&now));
102  assert(nchars == size-1);
103  (void)nchars;
104 
105  logFileName += dest;
106  logFileName += ".txt";
107  }
108  //cout << "logFileName='" << logFileName << "'" << endl;
109 }
110 
111 // ----------------------------------------------------------------------
112 
113 void
115  init();
116 
117  if (nRuns > 0) {
118  cout << endl
119  << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl
120  << "hot runs ..." << endl
121  << "++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++" << endl;
122 
123  for (int i = 0; i < nRuns; i++) {
124  runTests();
125  }
126 
127  // write log buffers
128  if (logRealTime) {
129  log << descr << ", rtime[ms]"
130  << header.rdbuf()->str() << endl
131  << rtimes.rdbuf()->str() << endl << endl << endl;
132  }
133  if (logCpuTime) {
134  log << descr << ", ctime[ms]"
135  << header.rdbuf()->str() << endl
136  << ctimes.rdbuf()->str() << endl << endl << endl;
137  }
138  }
139 
140  close();
141 }
142 
143 void
144 Driver::init() {
145  loadProperties();
146  initProperties();
147  printProperties();
148  openLogFile();
149 
150  // clear log buffers
151  logHeader = true;
152  header.rdbuf()->str("");
153  rtimes.rdbuf()->str("");
154 }
155 
156 void
157 Driver::close() {
158  // clear log buffers
159  header.rdbuf()->str("");
160  rtimes.rdbuf()->str("");
161 
162  closeLogFile();
163 }
164 
165 void
166 Driver::loadProperties() {
167  cout << endl;
168  for (vector<string>::const_iterator i = propFileNames.begin();
169  i != propFileNames.end(); ++i) {
170  cout << "reading properties file: " << *i << endl;
171  props.load(i->c_str());
172  //cout << "props = {" << endl << props << "}" << endl;
173  }
174 }
175 
176 void
177 Driver::initProperties() {
178  cout << "setting driver properties ..." << flush;
179 
180  ostringstream msg;
181 
182  logRealTime = toBool(props[L"logRealTime"], true);
183  logCpuTime = toBool(props[L"logCpuTime"], false);
184 
185  nRuns = toInt(props[L"nRuns"], 1, -1);
186  if (nRuns < 0) {
187  msg << "[ignored] nRuns: '"
188  << toString(props[L"nRuns"]) << "'" << endl;
189  nRuns = 1;
190  }
191 
192  //if (msg.tellp() == 0) // netbeans reports amibuities
193  if (msg.str().empty()) {
194  cout << " [ok]" << endl;
195  } else {
196  cout << endl << msg.str() << endl;
197  }
198 }
199 
200 void
201 Driver::printProperties() {
202  const ios_base::fmtflags f = cout.flags();
203  // no effect calling manipulator function, not sure why
204  //cout << ios_base::boolalpha;
205  cout.flags(ios_base::boolalpha);
206 
207  cout << endl << "driver settings ..." << endl;
208  cout << "logRealTime: " << logRealTime << endl;
209  cout << "logCpuTime: " << logCpuTime << endl;
210  cout << "nRuns: " << nRuns << endl;
211 
212  cout.flags(f);
213 }
214 
215 void
216 Driver::openLogFile() {
217  cout << endl
218  << "opening results file:" << flush;
219  log.open(logFileName.c_str(), ios_base::out | ios_base::trunc);
220  assert(log.good());
221  cout << " [ok: " << logFileName << "]" << endl;
222 }
223 
224 void
225 Driver::closeLogFile() {
226  cout << endl
227  << "closing results file:" << flush;
228  log.close();
229  cout << " [ok: " << logFileName << "]" << endl;
230 }
231 
232 // ----------------------------------------------------------------------
233 
234 void
235 Driver::begin(const string& name) {
236  cout << endl;
237  cout << name << endl;
238 
239  if (logRealTime && logCpuTime) {
240  s0 = hrt_tnow(&t0);
241  } else if (logRealTime) {
242  s0 = hrt_rtnow(&t0.rtstamp);
243  } else if (logCpuTime) {
244  s0 = hrt_ctnow(&t0.ctstamp);
245  }
246 }
247 
248 void
249 Driver::commit(const string& name) {
250  if (logRealTime && logCpuTime) {
251  s1 = hrt_tnow(&t1);
252  } else if (logRealTime) {
253  s1 = hrt_rtnow(&t1.rtstamp);
254  } else if (logCpuTime) {
255  s1 = hrt_ctnow(&t1.ctstamp);
256  }
257 
258  if (logRealTime) {
259  if (s0 | s1) {
260  cout << "ERROR: failed to get the system's real time.";
261  rtimes << "\tERROR";
262  } else {
263  long t = long(hrt_rtmicros(&t1.rtstamp, &t0.rtstamp)/1000);
264  cout << "tx real time: " << t
265  << "\tms" << endl;
266  rtimes << "\t" << t;
267  rta += t;
268  }
269  }
270 
271  if (logCpuTime) {
272  if (s0 | s1) {
273  cout << "ERROR: failed to get this process's cpu time.";
274  ctimes << "\tERROR";
275  } else {
276  long t = long(hrt_ctmicros(&t1.ctstamp, &t0.ctstamp)/1000);
277  cout << "tx cpu time: " << t
278  << "\tms" << endl;
279  ctimes << "\t" << t;
280  cta += t;
281  }
282  }
283 
284  if (logHeader)
285  header << "\t" << name;
286 }
287 
288 //---------------------------------------------------------------------------