1 /* -*- mode: java; c-basic-offset: 4; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=4:tabstop=4:smarttab:
3 *
4 * Copyright (c) 2010, 2011, 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, version 2.0,
8 * as published by the Free Software Foundation.
9 *
10 * This program is also distributed with certain software (including
11 * but not limited to OpenSSL) that is licensed under separate terms,
12 * as designated in a particular file or component or in included license
13 * documentation. The authors of MySQL hereby grant you an additional
14 * permission to link the program and your derivative works with the
15 * separately licensed software that they have included with MySQL.
16 *
17 * This program is distributed in the hope that it will be useful,
18 * but WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 * GNU General Public License, version 2.0, for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, write to the Free Software
24 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
25 */
26
27 #include <iostream>
28 #include <sstream>
29 #include <string>
30 #include <cassert>
31
32 #include "helpers.hpp"
33 #include "string_helpers.hpp"
34
35 #include "CrundDriver.hpp"
36
37 using std::cout;
38 using std::flush;
39 using std::endl;
40 using std::ios_base;
41 using std::ostringstream;
42 using std::string;
43 using std::wstring;
44
45 using utils::toBool;
46 using utils::toInt;
47 using utils::toString;
48
49 // ----------------------------------------------------------------------
50
51 void
init()52 CrundDriver::init() {
53 Driver::init();
54 // do work here
55 }
56
57 void
close()58 CrundDriver::close() {
59 // do work here
60 Driver::close();
61 }
62
63 void
initProperties()64 CrundDriver::initProperties() {
65 Driver::initProperties();
66
67 cout << "setting crund properties ..." << flush;
68
69 ostringstream msg;
70
71 renewConnection = toBool(props[L"renewConnection"], false);
72 renewOperations = toBool(props[L"renewOperations"], false);
73
74 string lm = toString(props[L"lockMode"]);
75 if (lm.empty()) {
76 lockMode = READ_COMMITTED;
77 } else if (lm.compare("READ_COMMITTED") == 0) {
78 lockMode = READ_COMMITTED;
79 } else if (lm.compare("SHARED") == 0) {
80 lockMode = SHARED;
81 } else if (lm.compare("EXCLUSIVE") == 0) {
82 lockMode = EXCLUSIVE;
83 } else {
84 msg << "[ignored] lockMode: '" << lm << "'" << endl;
85 lockMode = READ_COMMITTED;
86 }
87
88 logSumOfOps = toBool(props[L"logSumOfOps"], true);
89 //allowExtendedPC = toBool(props[L"allowExtendedPC"], false); // not used
90
91 nOpsStart = toInt(props[L"nOpsStart"], 256, 0);
92 if (nOpsStart < 1) {
93 msg << "[ignored] nOpsStart: '"
94 << toString(props[L"nOpsStart"]) << "'" << endl;
95 nOpsStart = 256;
96 }
97 nOpsEnd = toInt(props[L"nOpsEnd"], nOpsStart, 0);
98 if (nOpsEnd < nOpsStart) {
99 msg << "[ignored] nOpsEnd: '"
100 << toString(props[L"nOpsEnd"]) << "'" << endl;
101 nOpsEnd = nOpsStart;
102 }
103 nOpsScale = toInt(props[L"nOpsScale"], 2, 0);
104 if (nOpsScale < 2) {
105 msg << "[ignored] nOpsScale: '"
106 << toString(props[L"nOpsScale"]) << "'" << endl;
107 nOpsScale = 2;
108 }
109
110 maxVarbinaryBytes = toInt(props[L"maxVarbinaryBytes"], 100, 0);
111 if (maxVarbinaryBytes < 1) {
112 msg << "[ignored] maxVarbinaryBytes: '"
113 << toString(props[L"maxVarbinaryBytes"]) << "'" << endl;
114 maxVarbinaryBytes = 100;
115 }
116 maxVarcharChars = toInt(props[L"maxVarcharChars"], 100, 0);
117 if (maxVarcharChars < 1) {
118 msg << "[ignored] maxVarcharChars: '"
119 << toString(props[L"maxVarcharChars"]) << "'" << endl;
120 maxVarcharChars = 100;
121 }
122
123 maxBlobBytes = toInt(props[L"maxBlobBytes"], 1000, 0);
124 if (maxBlobBytes < 1) {
125 msg << "[ignored] maxBlobBytes: '"
126 << toString(props[L"maxBlobBytes"]) << "'" << endl;
127 maxBlobBytes = 1000;
128 }
129 maxTextChars = toInt(props[L"maxTextChars"], 1000, 0);
130 if (maxTextChars < 1) {
131 msg << "[ignored] maxTextChars: '"
132 << toString(props[L"maxTextChars"]) << "'" << endl;
133 maxTextChars = 1000;
134 }
135
136 // initialize exclude set
137 const wstring& estr = props[L"exclude"];
138 //cout << "estr='" << toString(estr) << "'" << endl;
139 const size_t len = estr.length();
140 size_t beg = 0, next;
141 while (beg < len
142 && ((next = estr.find_first_of(L",", beg)) != wstring::npos)) {
143 // add substring if not empty
144 if (beg < next) {
145 const wstring& s = estr.substr(beg, next - beg);
146 exclude.insert(toString(s));
147 }
148 beg = next + 1;
149 }
150 // add last substring if any
151 if (beg < len) {
152 const wstring& s = estr.substr(beg, len - beg);
153 exclude.insert(toString(s));
154 }
155
156 if (!msg.tellp()) {
157 cout << " [ok: "
158 << "nOps=" << nOpsStart << ".." << nOpsEnd << "]" << endl;
159 } else {
160 cout << endl << msg.str() << endl;
161 }
162 }
163
164 void
printProperties()165 CrundDriver::printProperties() {
166 Driver::printProperties();
167
168 const ios_base::fmtflags f = cout.flags();
169 // no effect calling manipulator function, not sure why
170 //cout << ios_base::boolalpha;
171 cout.flags(ios_base::boolalpha);
172
173 cout << endl << "crund settings ..." << endl;
174 cout << "renewConnection: " << renewConnection << endl;
175 cout << "renewOperations: " << renewOperations << endl;
176 cout << "lockMode: " << toStr(lockMode) << endl;
177 cout << "logSumOfOps: " << logSumOfOps << endl;
178 //cout << "allowExtendedPC: " << allowExtendedPC << endl;
179 cout << "nOpsStart: " << nOpsStart << endl;
180 cout << "nOpsEnd: " << nOpsEnd << endl;
181 cout << "nOpsScale: " << nOpsScale << endl;
182 cout << "maxVarbinaryBytes: " << maxVarbinaryBytes << endl;
183 cout << "maxVarcharChars: " << maxVarcharChars << endl;
184 cout << "maxBlobBytes: " << maxBlobBytes << endl;
185 cout << "maxTextChars: " << maxTextChars << endl;
186 cout << "exclude: " << toString(exclude) << endl;
187
188 cout.flags(f);
189 }
190
191 // ----------------------------------------------------------------------
192
193 void
runTests()194 CrundDriver::runTests() {
195 cout << endl;
196 initConnection();
197 initOperations();
198
199 assert(nOpsStart <= nOpsEnd && nOpsScale > 1);
200 for (int i = nOpsStart; i <= nOpsEnd; i *= nOpsScale) {
201 runLoads(i);
202 }
203
204 cout << endl
205 << "------------------------------------------------------------" << endl
206 << endl;
207 clearData();
208 closeOperations();
209 closeConnection();
210 }
211
212 void
runLoads(int nOps)213 CrundDriver::runLoads(int nOps) {
214 cout << endl
215 << "------------------------------------------------------------" << endl;
216
217 cout << "running operations ..."
218 << " [nOps=" << nOps << "]" << endl;
219
220 // log buffers
221 if (logRealTime) {
222 rtimes << nOps;
223 rta = 0L;
224 }
225 if (logCpuTime) {
226 ctimes << nOps;
227 cta = 0L;
228 }
229
230 // pre-run cleanup
231 if (renewConnection) {
232 closeOperations();
233 closeConnection();
234 initConnection();
235 initOperations();
236 } else if (renewOperations) {
237 closeOperations();
238 initOperations();
239 }
240 clearData();
241
242 runOperations(nOps);
243
244 if (logSumOfOps) {
245 cout << endl
246 << "total" << endl;
247 if (logRealTime) {
248 cout << "tx real time " << rta
249 << "\tms" << endl;
250 }
251 if (logSumOfOps) {
252 cout << "tx cpu time " << cta
253 << "\tms" << endl;
254 }
255 }
256
257 // log buffers
258 if (logHeader) {
259 if (logSumOfOps) {
260 header << "\ttotal";
261 }
262 logHeader = false;
263 }
264 if (logRealTime) {
265 if (logSumOfOps) {
266 rtimes << "\t" << rta;
267 }
268 rtimes << endl;
269 }
270 if (logCpuTime) {
271 if (logSumOfOps) {
272 ctimes << "\t" << cta;
273 }
274 ctimes << endl;
275 }
276 }
277
278 void
runOperations(int nOps)279 CrundDriver::runOperations(int nOps) {
280 for (Operations::const_iterator i = operations.begin();
281 i != operations.end(); ++i) {
282 // no need for pre-tx cleanup with NDBAPI-based loads
283 //if (!allowExtendedPC) {
284 // // effectively prevent caching beyond Tx scope by clearing
285 // // any data/result caches before the next transaction
286 // clearPersistenceContext();
287 //}
288 runOp(**i, nOps);
289 }
290 }
291
292 void
runOp(const Op & op,int nOps)293 CrundDriver::runOp(const Op& op, int nOps) {
294 const string& name = op.name;
295 if (exclude.find(name) == exclude.end()) {
296 begin(name);
297 op.run(nOps);
298 commit(name);
299 }
300 }
301
302 const char*
toStr(XMode mode)303 CrundDriver::toStr(XMode mode) {
304 switch (mode) {
305 case SINGLE:
306 return "single";
307 case BULK:
308 return "bulk";
309 case BATCH:
310 return "batch";
311 default:
312 assert(false);
313 return "<invalid value>";
314 };
315 }
316
317 const char*
toStr(LockMode mode)318 CrundDriver::toStr(LockMode mode) {
319 switch (mode) {
320 case SINGLE:
321 return "read_committed";
322 case SHARED:
323 return "shared";
324 case EXCLUSIVE:
325 return "exclusive";
326 default:
327 assert(false);
328 return "<invalid value>";
329 };
330 }
331
332 //---------------------------------------------------------------------------
333