Merge lp:~stewart/percona-server/5.5-update-handlersocket into lp:percona-server/5.5
- 5.5-update-handlersocket
- Merge into 5.5
Proposed by
Stewart Smith
Status: | Work in progress |
---|---|
Proposed branch: | lp:~stewart/percona-server/5.5-update-handlersocket |
Merge into: | lp:percona-server/5.5 |
Diff against target: | 81747 lines |
To merge this branch: | bzr merge lp:~stewart/percona-server/5.5-update-handlersocket |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Laurynas Biveinis (community) | Needs Fixing | ||
Review via email: mp+111767@code.launchpad.net |
Commit message
Description of the change
Update HandlerSocket to 1.1.0 from a git branch (imported with bzr-git). This should make it easier to keep up to date in the future.
http://
To post a comment you must log in.
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
review:
Needs Information
Revision history for this message
Laurynas Biveinis (laurynas-biveinis) wrote : | # |
Setting to WiP as will need to be redone the same way 5.1 was after the bzr bug breaking trunk.
review:
Needs Fixing
Unmerged revisions
- 266. By Stewart Smith
-
update HandlerSocket to 1.1.0 (by removing old HandlerSocket tree and replacing with a 'bzr join'ed one)
Preview Diff
[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1 | === added directory 'HandlerSocket-Plugin-for-MySQL' |
2 | === removed directory 'HandlerSocket-Plugin-for-MySQL' |
3 | === added file 'HandlerSocket-Plugin-for-MySQL/.gitignore' |
4 | --- HandlerSocket-Plugin-for-MySQL/.gitignore 1970-01-01 00:00:00 +0000 |
5 | +++ HandlerSocket-Plugin-for-MySQL/.gitignore 2012-06-25 04:42:22 +0000 |
6 | @@ -0,0 +1,35 @@ |
7 | +configure |
8 | +Makefile.in |
9 | +Makefile |
10 | +.deps |
11 | +*.lo |
12 | +*.o |
13 | +INSTALL |
14 | +m4 |
15 | +stamp-h1 |
16 | +libtool |
17 | +ltmain.sh |
18 | +missing |
19 | +install-sh |
20 | +autom4te.cache |
21 | +config.h* |
22 | +config.status |
23 | +config.guess |
24 | +config.sub |
25 | +config.log |
26 | +depcomp |
27 | +TAGS |
28 | +aclocal.m4 |
29 | +.libs |
30 | +ltmain.sh |
31 | +*.la |
32 | +handlersocket/Makefile.plain |
33 | +handlersocket/*.spec |
34 | +libhsclient/*.spec |
35 | +client/hstest |
36 | +client/hsclient |
37 | +perl-Net-HandlerSocket/*.spec |
38 | +regtest/*/*.log |
39 | +regtest/*/*.log2 |
40 | +regtest/*/DONE |
41 | +dist/* |
42 | |
43 | === added file 'HandlerSocket-Plugin-for-MySQL/AUTHORS' |
44 | --- HandlerSocket-Plugin-for-MySQL/AUTHORS 1970-01-01 00:00:00 +0000 |
45 | +++ HandlerSocket-Plugin-for-MySQL/AUTHORS 2012-06-25 04:42:22 +0000 |
46 | @@ -0,0 +1,22 @@ |
47 | +Akira Higuchi (https://github.com/ahiguti) |
48 | + - developed HanderSocket plugin, libhsclient, and perl-Net-HandlerSocket |
49 | + |
50 | +Yoshinori Matsunobu (https://github.com/yoshinorim) |
51 | + - introduced autotools, added support for MySQL 5.5.6, added statistics |
52 | + variables |
53 | + |
54 | +Jeff Hodges (https://github.com/jmhodges) |
55 | + - fixed some autotools scripts |
56 | + |
57 | +Toru Yamaguchi (https://github.com/zigorou) |
58 | + - ported to MacOS X |
59 | + |
60 | +Moriyoshi Koizumi (https://github.com/moriyoshi) |
61 | + - fixed some autotools scripts |
62 | + |
63 | +takeda-at (https://github.com/takada-at) |
64 | + - added simple authorization function |
65 | + |
66 | +WheresWardy (https://github.com/WheresWardy) |
67 | + - added authentication functions to libhsclient |
68 | + |
69 | |
70 | === removed file 'HandlerSocket-Plugin-for-MySQL/AUTHORS' |
71 | --- HandlerSocket-Plugin-for-MySQL/AUTHORS 2011-01-10 13:39:35 +0000 |
72 | +++ HandlerSocket-Plugin-for-MySQL/AUTHORS 1970-01-01 00:00:00 +0000 |
73 | @@ -1,19 +0,0 @@ |
74 | -Akira Higuchi (https://github.com/ahiguti) |
75 | - - developed HanderSocket plugin, libhsclient, and perl-Net-HandlerSocket |
76 | - |
77 | -Yoshinori Matsunobu (https://github.com/yoshinorim) |
78 | - - introduced autotools, added support for MySQL 5.5.6, added statistics |
79 | - variables |
80 | - |
81 | -Jeff Hodges (https://github.com/jmhodges) |
82 | - - fixed some autotools scripts |
83 | - |
84 | -Toru Yamaguchi (https://github.com/zigorou) |
85 | - - ported to MacOS X |
86 | - |
87 | -Moriyoshi Koizumi (https://github.com/moriyoshi) |
88 | - - fixed some autotools scripts |
89 | - |
90 | -takeda-at (https://github.com/takada-at) |
91 | - - added simple authorization function |
92 | - |
93 | |
94 | === added file 'HandlerSocket-Plugin-for-MySQL/COPYING' |
95 | --- HandlerSocket-Plugin-for-MySQL/COPYING 1970-01-01 00:00:00 +0000 |
96 | +++ HandlerSocket-Plugin-for-MySQL/COPYING 2012-06-25 04:42:22 +0000 |
97 | @@ -0,0 +1,30 @@ |
98 | +----------------------------------------------------------------------------- |
99 | +HandlerSocket plugin for MySQL |
100 | + |
101 | + Copyright (c) 2010 DeNA Co.,Ltd. |
102 | + All rights reserved. |
103 | + |
104 | + Redistribution and use in source and binary forms, with or without |
105 | + modification, are permitted provided that the following conditions are met: |
106 | + |
107 | + * Redistributions of source code must retain the above copyright |
108 | + notice, this list of conditions and the following disclaimer. |
109 | + * Redistributions in binary form must reproduce the above copyright |
110 | + notice, this list of conditions and the following disclaimer in the |
111 | + documentation and/or other materials provided with the distribution. |
112 | + * Neither the name of DeNA Co.,Ltd. nor the names of its contributors |
113 | + may be used to endorse or promote products derived from this software |
114 | + without specific prior written permission. |
115 | + |
116 | + THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "AS IS" AND ANY EXPRESS OR |
117 | + IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
118 | + MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
119 | + EVENT SHALL DeNA Co.,Ltd. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
120 | + SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
121 | + PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
122 | + OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
123 | + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
124 | + OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
125 | + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
126 | + |
127 | + |
128 | |
129 | === removed file 'HandlerSocket-Plugin-for-MySQL/COPYING' |
130 | --- HandlerSocket-Plugin-for-MySQL/COPYING 2011-01-10 13:39:35 +0000 |
131 | +++ HandlerSocket-Plugin-for-MySQL/COPYING 1970-01-01 00:00:00 +0000 |
132 | @@ -1,30 +0,0 @@ |
133 | ------------------------------------------------------------------------------ |
134 | -HandlerSocket plugin for MySQL |
135 | - |
136 | - Copyright (c) 2010 DeNA Co.,Ltd. |
137 | - All rights reserved. |
138 | - |
139 | - Redistribution and use in source and binary forms, with or without |
140 | - modification, are permitted provided that the following conditions are met: |
141 | - |
142 | - * Redistributions of source code must retain the above copyright |
143 | - notice, this list of conditions and the following disclaimer. |
144 | - * Redistributions in binary form must reproduce the above copyright |
145 | - notice, this list of conditions and the following disclaimer in the |
146 | - documentation and/or other materials provided with the distribution. |
147 | - * Neither the name of DeNA Co.,Ltd. nor the names of its contributors |
148 | - may be used to endorse or promote products derived from this software |
149 | - without specific prior written permission. |
150 | - |
151 | - THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "AS IS" AND ANY EXPRESS OR |
152 | - IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
153 | - MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
154 | - EVENT SHALL DeNA Co.,Ltd. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
155 | - SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
156 | - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
157 | - OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
158 | - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
159 | - OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
160 | - ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
161 | - |
162 | - |
163 | |
164 | === added file 'HandlerSocket-Plugin-for-MySQL/ChangeLog' |
165 | --- HandlerSocket-Plugin-for-MySQL/ChangeLog 1970-01-01 00:00:00 +0000 |
166 | +++ HandlerSocket-Plugin-for-MySQL/ChangeLog 2012-06-25 04:42:22 +0000 |
167 | @@ -0,0 +1,15 @@ |
168 | +1.1.0 - 2011-12-29 |
169 | + * 1.1.0 |
170 | + |
171 | +1.0.6 - 2010-10-29 |
172 | + * Changed build instruction (autoreconf/configure/make), removed auto-generated files (Contributed by jmhodges) |
173 | + * |
174 | + |
175 | +1.0.5 - 2010-10-18 |
176 | + * Changed build procedures (using typical configure/make) |
177 | + * Supported 5.5.6 |
178 | + * Added status variables |
179 | + |
180 | +1.0.4 - 2010-08-15 |
181 | + * Initial public release |
182 | + |
183 | |
184 | === removed file 'HandlerSocket-Plugin-for-MySQL/ChangeLog' |
185 | --- HandlerSocket-Plugin-for-MySQL/ChangeLog 2011-01-10 13:39:35 +0000 |
186 | +++ HandlerSocket-Plugin-for-MySQL/ChangeLog 1970-01-01 00:00:00 +0000 |
187 | @@ -1,12 +0,0 @@ |
188 | -1.0.6 - 2010-10-29 |
189 | - * Changed build instruction (autoreconf/configure/make), removed auto-generated files (Contributed by jmhodges) |
190 | - * |
191 | - |
192 | -1.0.5 - 2010-10-18 |
193 | - * Changed build procedures (using typical configure/make) |
194 | - * Supported 5.5.6 |
195 | - * Added status variables |
196 | - |
197 | -1.0.4 - 2010-08-15 |
198 | - * Initial public release |
199 | - |
200 | |
201 | === added file 'HandlerSocket-Plugin-for-MySQL/Makefile.am' |
202 | --- HandlerSocket-Plugin-for-MySQL/Makefile.am 1970-01-01 00:00:00 +0000 |
203 | +++ HandlerSocket-Plugin-for-MySQL/Makefile.am 2012-06-25 04:42:22 +0000 |
204 | @@ -0,0 +1,87 @@ |
205 | + |
206 | +ACLOCAL_AMFLAGS = -I m4 |
207 | + |
208 | +SUBDIRS = @HANDLERSOCKET_SUBDIRS@ |
209 | + |
210 | +perl: |
211 | + cd perl-Net-HandlerSocket && perl Makefile.PL && make |
212 | + |
213 | +install_perl: |
214 | + cd perl-Net-HandlerSocket && make install |
215 | + |
216 | +rpms: rpm_cli rpm_perl rpm_c |
217 | + |
218 | +rpm_dir: |
219 | + - mkdir dist |
220 | + - mkdir dist/BUILD dist/RPMS dist/SOURCES dist/SPECS dist/SRPMS |
221 | + |
222 | +rpm_cli: clean_cli rpm_dir |
223 | + sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
224 | + libhsclient/libhsclient.spec.template \ |
225 | + > libhsclient/libhsclient.spec |
226 | + tar cvfz dist/libhsclient.tar.gz libhsclient |
227 | + rpmbuild --define "_topdir `pwd`/dist" -ta \ |
228 | + dist/libhsclient.tar.gz |
229 | + |
230 | +rpm_perl: clean_perl rpm_dir |
231 | + sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
232 | + perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template \ |
233 | + > perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec |
234 | + cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \ |
235 | + rm -f Makefile.old |
236 | + tar cvfz dist/perl-Net-HandlerSocket.tar.gz perl-Net-HandlerSocket |
237 | + rpmbuild --define "_topdir `pwd`/dist" -ta \ |
238 | + dist/perl-Net-HandlerSocket.tar.gz |
239 | + |
240 | +rpm_c: clean_c rpm_dir |
241 | + sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
242 | + handlersocket/handlersocket.spec.template \ |
243 | + > handlersocket/handlersocket.spec |
244 | + sed -e "s|HANDLERSOCKET_MYSQL_INC|$(MYSQL_CFLAGS) $(MYSQL_INC)|" \ |
245 | + -e "s|HANDLERSOCKET_MYSQL_LIB|$(MYSQL_LIB)|" \ |
246 | + handlersocket/Makefile.plain.template \ |
247 | + > handlersocket/Makefile.plain |
248 | + tar cvfz dist/handlersocket.tar.gz handlersocket |
249 | + rpmbuild --define "_topdir `pwd`/dist" -ta \ |
250 | + dist/handlersocket.tar.gz |
251 | + |
252 | +install_rpm_pl: |
253 | + - sudo rpm -e perl-Net-HandlerSocket |
254 | + - sudo rpm -e perl-Net-HandlerSocket-debuginfo |
255 | + make clean |
256 | + make rpm_perl |
257 | + - sudo rpm -U dist/RPMS/*/perl*.rpm |
258 | + |
259 | +installrpms: |
260 | + - sudo rpm -e handlersocket |
261 | + - sudo rpm -e handlersocket-debuginfo |
262 | + - sudo rpm -e perl-Net-HandlerSocket |
263 | + - sudo rpm -e perl-Net-HandlerSocket-debuginfo |
264 | + - sudo rpm -e libhsclient |
265 | + - sudo rpm -e libhsclient-debuginfo |
266 | + make clean |
267 | + make rpm_cli |
268 | + - sudo rpm -U dist/RPMS/*/libhsclient*.rpm |
269 | + make clean |
270 | + make rpm_perl |
271 | + - sudo rpm -U dist/RPMS/*/perl*.rpm |
272 | + make clean |
273 | + make rpm_c |
274 | + - sudo rpm -U dist/RPMS/*/handlersocket*.rpm |
275 | + |
276 | +clean_cli: |
277 | + cd libhsclient && make clean |
278 | + cd client && make clean |
279 | + |
280 | +clean_perl: |
281 | + cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \ |
282 | + rm -f Makefile.old |
283 | + |
284 | +clean_c: |
285 | + cd handlersocket && make clean |
286 | + |
287 | +clean_all: clean_cli clean_perl clean_c |
288 | + cd regtest && make clean |
289 | + rm -rf dist/*/* |
290 | + rm -f dist/*.tar.gz |
291 | + |
292 | |
293 | === removed file 'HandlerSocket-Plugin-for-MySQL/Makefile.am' |
294 | --- HandlerSocket-Plugin-for-MySQL/Makefile.am 2011-01-10 13:39:35 +0000 |
295 | +++ HandlerSocket-Plugin-for-MySQL/Makefile.am 1970-01-01 00:00:00 +0000 |
296 | @@ -1,87 +0,0 @@ |
297 | - |
298 | -ACLOCAL_AMFLAGS = -I m4 |
299 | - |
300 | -SUBDIRS = @HANDLERSOCKET_SUBDIRS@ |
301 | - |
302 | -perl: |
303 | - cd perl-Net-HandlerSocket && perl Makefile.PL && make |
304 | - |
305 | -install_perl: |
306 | - cd perl-Net-HandlerSocket && make install |
307 | - |
308 | -rpms: rpm_cli rpm_perl rpm_c |
309 | - |
310 | -rpm_dir: |
311 | - - mkdir dist |
312 | - - mkdir dist/BUILD dist/RPMS dist/SOURCES dist/SPECS dist/SRPMS |
313 | - |
314 | -rpm_cli: clean_cli rpm_dir |
315 | - sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
316 | - libhsclient/libhsclient.spec.template \ |
317 | - > libhsclient/libhsclient.spec |
318 | - tar cvfz dist/libhsclient.tar.gz libhsclient |
319 | - rpmbuild --define "_topdir `pwd`/dist" -ta \ |
320 | - dist/libhsclient.tar.gz |
321 | - |
322 | -rpm_perl: clean_perl rpm_dir |
323 | - sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
324 | - perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec.template \ |
325 | - > perl-Net-HandlerSocket/perl-Net-HandlerSocket.spec |
326 | - cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \ |
327 | - rm -f Makefile.old |
328 | - tar cvfz dist/perl-Net-HandlerSocket.tar.gz perl-Net-HandlerSocket |
329 | - rpmbuild --define "_topdir `pwd`/dist" -ta \ |
330 | - dist/perl-Net-HandlerSocket.tar.gz |
331 | - |
332 | -rpm_c: clean_c rpm_dir |
333 | - sed -e "s/HANDLERSOCKET_VERSION/$(VERSION)/" \ |
334 | - handlersocket/handlersocket.spec.template \ |
335 | - > handlersocket/handlersocket.spec |
336 | - sed -e "s|HANDLERSOCKET_MYSQL_INC|$(MYSQL_CFLAGS) $(MYSQL_INC)|" \ |
337 | - -e "s|HANDLERSOCKET_MYSQL_LIB|$(MYSQL_LIB)|" \ |
338 | - handlersocket/Makefile.plain.template \ |
339 | - > handlersocket/Makefile.plain |
340 | - tar cvfz dist/handlersocket.tar.gz handlersocket |
341 | - rpmbuild --define "_topdir `pwd`/dist" -ta \ |
342 | - dist/handlersocket.tar.gz |
343 | - |
344 | -install_rpm_pl: |
345 | - - sudo rpm -e perl-Net-HandlerSocket |
346 | - - sudo rpm -e perl-Net-HandlerSocket-debuginfo |
347 | - make clean |
348 | - make rpm_perl |
349 | - - sudo rpm -U dist/RPMS/*/perl*.rpm |
350 | - |
351 | -installrpms: |
352 | - - sudo rpm -e handlersocket |
353 | - - sudo rpm -e handlersocket-debuginfo |
354 | - - sudo rpm -e perl-Net-HandlerSocket |
355 | - - sudo rpm -e perl-Net-HandlerSocket-debuginfo |
356 | - - sudo rpm -e libhsclient |
357 | - - sudo rpm -e libhsclient-debuginfo |
358 | - make clean |
359 | - make rpm_cli |
360 | - - sudo rpm -U dist/RPMS/*/libhsclient*.rpm |
361 | - make clean |
362 | - make rpm_perl |
363 | - - sudo rpm -U dist/RPMS/*/perl*.rpm |
364 | - make clean |
365 | - make rpm_c |
366 | - - sudo rpm -U dist/RPMS/*/handlersocket*.rpm |
367 | - |
368 | -clean_cli: |
369 | - cd libhsclient && make clean |
370 | - cd client && make clean |
371 | - |
372 | -clean_perl: |
373 | - cd perl-Net-HandlerSocket && perl Makefile.PL && make clean && \ |
374 | - rm -f Makefile.old |
375 | - |
376 | -clean_c: |
377 | - cd handlersocket && make clean |
378 | - |
379 | -clean_all: clean_cli clean_perl clean_c |
380 | - cd regtest && make clean |
381 | - rm -rf dist/*/* |
382 | - rm -f dist/*.tar.gz |
383 | - |
384 | |
385 | === added file 'HandlerSocket-Plugin-for-MySQL/README' |
386 | --- HandlerSocket-Plugin-for-MySQL/README 1970-01-01 00:00:00 +0000 |
387 | +++ HandlerSocket-Plugin-for-MySQL/README 2012-06-25 04:42:22 +0000 |
388 | @@ -0,0 +1,78 @@ |
389 | + |
390 | +----------------------------------------------------------------------------- |
391 | +HandlerSocket plugin for MySQL |
392 | + |
393 | +Copyright (c) 2010 DeNA Co.,Ltd. |
394 | +All rights reserved. |
395 | + |
396 | +Redistribution and use in source and binary forms, with or without |
397 | +modification, are permitted provided that the following conditions are met: |
398 | + |
399 | + * Redistributions of source code must retain the above copyright |
400 | + notice, this list of conditions and the following disclaimer. |
401 | + * Redistributions in binary form must reproduce the above copyright |
402 | + notice, this list of conditions and the following disclaimer in the |
403 | + documentation and/or other materials provided with the distribution. |
404 | + * Neither the name of DeNA Co.,Ltd. nor the names of its contributors |
405 | + may be used to endorse or promote products derived from this software |
406 | + without specific prior written permission. |
407 | + |
408 | +THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "AS IS" AND ANY EXPRESS OR |
409 | +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
410 | +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
411 | +EVENT SHALL DeNA Co.,Ltd. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
412 | +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
413 | +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
414 | +OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
415 | +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
416 | +OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
417 | +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
418 | + |
419 | + |
420 | +----------------------------------------------------------------------------- |
421 | +About HandlerSocket |
422 | + |
423 | +HandlerSocket is a NoSQL plugin for MySQL. It works as a daemon inside the |
424 | +mysqld process, accept tcp connections, and execute requests from clients. |
425 | +HandlerSocket does not support SQL queries. Instead, it supports simple CRUD |
426 | +operations on tables. |
427 | + |
428 | +Because of the following reasons, HandlerSocket is much faster than the |
429 | +mysqld/libmysql pair in some circumstances: |
430 | + |
431 | + - HandlerSocket manipulates data without parsing SQL, which causes less |
432 | + CPU usage. |
433 | + - HandlerSocket reads many requests from clients and executes their |
434 | + requests in bulk, which causes less CPU and disk usage. |
435 | + - HandlerSocket client/server protocol is more compact than the |
436 | + mysql/libmysql pair, which causes less network usage. |
437 | + |
438 | +The current version of HandlerSocket only works with GNU/Linux. The source |
439 | +archive of HandlerSocket includes a C++ and a Perl client libraries. |
440 | +Here is a list of client libraries for other languages: |
441 | + |
442 | + - PHP |
443 | + http://openpear.org/package/Net_HandlerSocket |
444 | + http://github.com/tz-lom/HSPHP |
445 | + http://code.google.com/p/php-handlersocket/ |
446 | + - Java |
447 | + http://code.google.com/p/hs4j/ |
448 | + http://code.google.com/p/handlersocketforjava/ |
449 | + - Python |
450 | + http://pypi.python.org/pypi/python-handler-socket |
451 | + https://code.launchpad.net/~songofacandy/+junk/pyhandlersocket |
452 | + - Ruby |
453 | + https://github.com/winebarrel/ruby-handlersocket |
454 | + https://github.com/miyucy/handlersocket |
455 | + - JavaScript |
456 | + https://github.com/koichik/node-handlersocket |
457 | + - Scala |
458 | + https://github.com/fujohnwang/hs2client |
459 | + - Haskell |
460 | + https://github.com/wuxb45/HandlerSocket-Haskell-Client |
461 | + |
462 | +The home of HandlerSocket is here: |
463 | + https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL |
464 | + |
465 | +More documents are available in docs-en/ and docs-ja/ directories. |
466 | + |
467 | |
468 | === removed file 'HandlerSocket-Plugin-for-MySQL/README' |
469 | --- HandlerSocket-Plugin-for-MySQL/README 2011-01-10 13:39:35 +0000 |
470 | +++ HandlerSocket-Plugin-for-MySQL/README 1970-01-01 00:00:00 +0000 |
471 | @@ -1,76 +0,0 @@ |
472 | - |
473 | ------------------------------------------------------------------------------ |
474 | -HandlerSocket plugin for MySQL |
475 | - |
476 | -Copyright (c) 2010 DeNA Co.,Ltd. |
477 | -All rights reserved. |
478 | - |
479 | -Redistribution and use in source and binary forms, with or without |
480 | -modification, are permitted provided that the following conditions are met: |
481 | - |
482 | - * Redistributions of source code must retain the above copyright |
483 | - notice, this list of conditions and the following disclaimer. |
484 | - * Redistributions in binary form must reproduce the above copyright |
485 | - notice, this list of conditions and the following disclaimer in the |
486 | - documentation and/or other materials provided with the distribution. |
487 | - * Neither the name of DeNA Co.,Ltd. nor the names of its contributors |
488 | - may be used to endorse or promote products derived from this software |
489 | - without specific prior written permission. |
490 | - |
491 | -THIS SOFTWARE IS PROVIDED BY DeNA Co.,Ltd. "AS IS" AND ANY EXPRESS OR |
492 | -IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF |
493 | -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO |
494 | -EVENT SHALL DeNA Co.,Ltd. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
495 | -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
496 | -PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; |
497 | -OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, |
498 | -WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR |
499 | -OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF |
500 | -ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
501 | - |
502 | - |
503 | ------------------------------------------------------------------------------ |
504 | -About HandlerSocket |
505 | - |
506 | -HandlerSocket is a NoSQL plugin for MySQL. It works as a daemon inside the |
507 | -mysqld process, accept tcp connections, and execute requests from clients. |
508 | -HandlerSocket does not support SQL queries. Instead, it supports simple CRUD |
509 | -operations on tables. |
510 | - |
511 | -Because of the following reasons, HandlerSocket is much faster than the |
512 | -mysqld/libmysql pair in some circumstances: |
513 | - |
514 | - - HandlerSocket manipulates data without parsing SQL, which causes less |
515 | - CPU usage. |
516 | - - HandlerSocket reads many requests from clients and executes their |
517 | - requests in bulk, which causes less CPU and disk usage. |
518 | - - HandlerSocket client/server protocol is more compact than the |
519 | - mysql/libmysql pair, which causes less network usage. |
520 | - |
521 | -The current version of HandlerSocket only works with GNU/Linux. The source |
522 | -archive of HandlerSocket includes a C++ and a Perl client libraries. |
523 | -Here is a list of client libraries for other languages: |
524 | - |
525 | - - PHP |
526 | - http://openpear.org/package/Net_HandlerSocket |
527 | - http://github.com/tz-lom/HSPHP |
528 | - http://code.google.com/p/php-handlersocket/ |
529 | - - Java |
530 | - http://code.google.com/p/hs4j/ |
531 | - http://code.google.com/p/handlersocketforjava/ |
532 | - - Python |
533 | - http://pypi.python.org/pypi/python-handler-socket |
534 | - https://code.launchpad.net/~songofacandy/+junk/pyhandlersocket |
535 | - - Ruby |
536 | - https://github.com/winebarrel/ruby-handlersocket |
537 | - https://github.com/miyucy/handlersocket |
538 | - - JavaScript |
539 | - https://github.com/koichik/node-handlersocket |
540 | - - Scala |
541 | - https://github.com/fujohnwang/hs2client |
542 | - |
543 | -The home of HandlerSocket is here: |
544 | - https://github.com/ahiguti/HandlerSocket-Plugin-for-MySQL |
545 | - |
546 | -More documents are available in docs-en/ and docs-ja/ directories. |
547 | - |
548 | |
549 | === added file 'HandlerSocket-Plugin-for-MySQL/autogen.sh' |
550 | --- HandlerSocket-Plugin-for-MySQL/autogen.sh 1970-01-01 00:00:00 +0000 |
551 | +++ HandlerSocket-Plugin-for-MySQL/autogen.sh 2012-06-25 04:42:22 +0000 |
552 | @@ -0,0 +1,117 @@ |
553 | +#!/bin/sh |
554 | + |
555 | +warn() { |
556 | +echo -e "\tWARNING: $@" 1>&2 |
557 | +} |
558 | + |
559 | +# init |
560 | + |
561 | +LIBTOOLIZE=libtoolize |
562 | +ACLOCAL=aclocal |
563 | +AUTOCONF=autoconf |
564 | +AUTOHEADER=autoheader |
565 | +AUTOMAKE=automake |
566 | + |
567 | +case `uname -s` in |
568 | +Darwin) |
569 | +LIBTOOLIZE=glibtoolize |
570 | +;; |
571 | +FreeBSD) |
572 | +ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/" |
573 | +;; |
574 | +esac |
575 | + |
576 | + |
577 | +# libtoolize |
578 | +echo "Searching libtoolize..." |
579 | +if [ `which $LIBTOOLIZE` ] ; then |
580 | +echo -e "\tFOUND: libtoolize -> $LIBTOOLIZE" |
581 | +else |
582 | +warn "Cannot Found libtoolize... input libtool command" |
583 | + read LIBTOOLIZE |
584 | + LIBTOOLIZE=`which $LIBTOOLIZE` |
585 | + if [ `which $LIBTOOLIZE` ] ; then |
586 | +echo -e "\tSET: libtoolize -> $LIBTOOLIZE" |
587 | + else |
588 | +warn "$LIBTOOLIZE: Command not found." |
589 | + exit 1; |
590 | + fi |
591 | +fi |
592 | + |
593 | +# aclocal |
594 | +echo "Searching aclocal..." |
595 | +if [ `which $ACLOCAL` ] ; then |
596 | +echo -e "\tFOUND: aclocal -> $ACLOCAL" |
597 | +else |
598 | +warn "Cannot Found aclocal... input aclocal command" |
599 | + read ACLOCAL |
600 | + ACLOCAL=`which $ACLOCAL` |
601 | + if [ `which $ACLOCAL` ] ; then |
602 | +echo -e "\tSET: aclocal -> $ACLOCAL" |
603 | + else |
604 | +warn "$ACLOCAL: Command not found." |
605 | + exit 1; |
606 | + fi |
607 | +fi |
608 | + |
609 | +# automake |
610 | +echo "Searching automake..." |
611 | +if [ `which $AUTOMAKE` ] ; then |
612 | +echo -e "\tFOUND: automake -> $AUTOMAKE" |
613 | +else |
614 | +warn "Cannot Found automake... input automake command" |
615 | + read AUTOMAKE |
616 | + ACLOCAL=`which $AUTOMAKE` |
617 | + if [ `which $AUTOMAKE` ] ; then |
618 | +echo -e "\tSET: automake -> $AUTOMAKE" |
619 | + else |
620 | +warn "$AUTOMAKE: Command not found." |
621 | + exit 1; |
622 | + fi |
623 | +fi |
624 | + |
625 | +# autoheader |
626 | +echo "Searching autoheader..." |
627 | +if [ `which $AUTOHEADER` ] ; then |
628 | +echo -e "\tFOUND: autoheader -> $AUTOHEADER" |
629 | +else |
630 | +warn "Cannot Found autoheader... input autoheader command" |
631 | + read AUTOHEADER |
632 | + ACLOCAL=`which $AUTOHEADER` |
633 | + if [ `which $AUTOHEADER` ] ; then |
634 | +echo -e "\tSET: autoheader -> $AUTOHEADER" |
635 | + else |
636 | +warn "$AUTOHEADER: Command not found." |
637 | + exit 1; |
638 | + fi |
639 | +fi |
640 | + |
641 | +# autoconf |
642 | +echo "Searching autoconf..." |
643 | +if [ `which $AUTOCONF` ] ; then |
644 | +echo -e "\tFOUND: autoconf -> $AUTOCONF" |
645 | +else |
646 | +warn "Cannot Found autoconf... input autoconf command" |
647 | + read AUTOCONF |
648 | + ACLOCAL=`which $AUTOCONF` |
649 | + if [ `which $AUTOCONF` ] ; then |
650 | +echo -e "\tSET: autoconf -> $AUTOCONF" |
651 | + else |
652 | +warn "$AUTOCONF: Command not found." |
653 | + exit 1; |
654 | + fi |
655 | +fi |
656 | + |
657 | +echo "Running libtoolize ..." |
658 | +$LIBTOOLIZE --force --copy |
659 | +echo "Running aclocal ..." |
660 | +$ACLOCAL ${ACLOCAL_ARGS} -I . |
661 | +echo "Running autoheader..." |
662 | +$AUTOHEADER |
663 | +echo "Running automake ..." |
664 | +$AUTOMAKE --add-missing --copy |
665 | +echo "Running autoconf ..." |
666 | +$AUTOCONF |
667 | + |
668 | +mkdir -p m4 |
669 | + |
670 | |
671 | === removed file 'HandlerSocket-Plugin-for-MySQL/autogen.sh' |
672 | --- HandlerSocket-Plugin-for-MySQL/autogen.sh 2011-04-19 12:57:00 +0000 |
673 | +++ HandlerSocket-Plugin-for-MySQL/autogen.sh 1970-01-01 00:00:00 +0000 |
674 | @@ -1,117 +0,0 @@ |
675 | -#!/bin/sh |
676 | - |
677 | -warn() { |
678 | -echo -e "\tWARNING: $@" 1>&2 |
679 | -} |
680 | - |
681 | -# init |
682 | - |
683 | -LIBTOOLIZE=libtoolize |
684 | -ACLOCAL=aclocal |
685 | -AUTOCONF=autoconf |
686 | -AUTOHEADER=autoheader |
687 | -AUTOMAKE=automake |
688 | - |
689 | -case `uname -s` in |
690 | -Darwin) |
691 | -LIBTOOLIZE=glibtoolize |
692 | -;; |
693 | -FreeBSD) |
694 | -ACLOCAL_ARGS="$ACLOCAL_ARGS -I /usr/local/share/aclocal/" |
695 | -;; |
696 | -esac |
697 | - |
698 | - |
699 | -# libtoolize |
700 | -echo "Searching libtoolize..." |
701 | -if [ `which $LIBTOOLIZE` ] ; then |
702 | -echo -e "\tFOUND: libtoolize -> $LIBTOOLIZE" |
703 | -else |
704 | -warn "Cannot Found libtoolize... input libtool command" |
705 | - read LIBTOOLIZE |
706 | - LIBTOOLIZE=`which $LIBTOOLIZE` |
707 | - if [ `which $LIBTOOLIZE` ] ; then |
708 | -echo -e "\tSET: libtoolize -> $LIBTOOLIZE" |
709 | - else |
710 | -warn "$LIBTOOLIZE: Command not found." |
711 | - exit 1; |
712 | - fi |
713 | -fi |
714 | - |
715 | -# aclocal |
716 | -echo "Searching aclocal..." |
717 | -if [ `which $ACLOCAL` ] ; then |
718 | -echo -e "\tFOUND: aclocal -> $ACLOCAL" |
719 | -else |
720 | -warn "Cannot Found aclocal... input aclocal command" |
721 | - read ACLOCAL |
722 | - ACLOCAL=`which $ACLOCAL` |
723 | - if [ `which $ACLOCAL` ] ; then |
724 | -echo -e "\tSET: aclocal -> $ACLOCAL" |
725 | - else |
726 | -warn "$ACLOCAL: Command not found." |
727 | - exit 1; |
728 | - fi |
729 | -fi |
730 | - |
731 | -# automake |
732 | -echo "Searching automake..." |
733 | -if [ `which $AUTOMAKE` ] ; then |
734 | -echo -e "\tFOUND: automake -> $AUTOMAKE" |
735 | -else |
736 | -warn "Cannot Found automake... input automake command" |
737 | - read AUTOMAKE |
738 | - ACLOCAL=`which $AUTOMAKE` |
739 | - if [ `which $AUTOMAKE` ] ; then |
740 | -echo -e "\tSET: automake -> $AUTOMAKE" |
741 | - else |
742 | -warn "$AUTOMAKE: Command not found." |
743 | - exit 1; |
744 | - fi |
745 | -fi |
746 | - |
747 | -# autoheader |
748 | -echo "Searching autoheader..." |
749 | -if [ `which $AUTOHEADER` ] ; then |
750 | -echo -e "\tFOUND: autoheader -> $AUTOHEADER" |
751 | -else |
752 | -warn "Cannot Found autoheader... input autoheader command" |
753 | - read AUTOHEADER |
754 | - ACLOCAL=`which $AUTOHEADER` |
755 | - if [ `which $AUTOHEADER` ] ; then |
756 | -echo -e "\tSET: autoheader -> $AUTOHEADER" |
757 | - else |
758 | -warn "$AUTOHEADER: Command not found." |
759 | - exit 1; |
760 | - fi |
761 | -fi |
762 | - |
763 | -# autoconf |
764 | -echo "Searching autoconf..." |
765 | -if [ `which $AUTOCONF` ] ; then |
766 | -echo -e "\tFOUND: autoconf -> $AUTOCONF" |
767 | -else |
768 | -warn "Cannot Found autoconf... input autoconf command" |
769 | - read AUTOCONF |
770 | - ACLOCAL=`which $AUTOCONF` |
771 | - if [ `which $AUTOCONF` ] ; then |
772 | -echo -e "\tSET: autoconf -> $AUTOCONF" |
773 | - else |
774 | -warn "$AUTOCONF: Command not found." |
775 | - exit 1; |
776 | - fi |
777 | -fi |
778 | - |
779 | -echo "Running libtoolize ..." |
780 | -$LIBTOOLIZE --force --copy |
781 | -echo "Running aclocal ..." |
782 | -$ACLOCAL ${ACLOCAL_ARGS} -I . |
783 | -echo "Running autoheader..." |
784 | -$AUTOHEADER |
785 | -echo "Running automake ..." |
786 | -$AUTOMAKE --add-missing --copy |
787 | -echo "Running autoconf ..." |
788 | -$AUTOCONF |
789 | - |
790 | -mkdir -p m4 |
791 | - |
792 | |
793 | === added directory 'HandlerSocket-Plugin-for-MySQL/client' |
794 | === removed directory 'HandlerSocket-Plugin-for-MySQL/client' |
795 | === added file 'HandlerSocket-Plugin-for-MySQL/client/Makefile.am' |
796 | --- HandlerSocket-Plugin-for-MySQL/client/Makefile.am 1970-01-01 00:00:00 +0000 |
797 | +++ HandlerSocket-Plugin-for-MySQL/client/Makefile.am 2012-06-25 04:42:22 +0000 |
798 | @@ -0,0 +1,24 @@ |
799 | +AM_INCLUDES= -I../libhsclient |
800 | +bin_PROGRAMS=hsclient |
801 | +hsclient_SOURCES= hsclient.cpp |
802 | +hsclient_LDFLAGS= -static -L../libhsclient -lhsclient |
803 | +hsclient_CXXFLAGS= $(AM_INCLUDES) |
804 | + |
805 | +hstest: hstest.o |
806 | + $(CXX) $(CXXFLAGS) $(LFLAGS) hstest.o \ |
807 | + -L../libhsclient/.libs -lhsclient $$(mysql_config --libs_r) \ |
808 | + -o hstest |
809 | + |
810 | +hstest.o: hstest.cpp |
811 | + $(CXX) $(CXXFLAGS) $(AM_INCLUDES) $$(mysql_config --include) \ |
812 | + -c hstest.cpp |
813 | + |
814 | +hslongrun: hslongrun.o |
815 | + $(CXX) $(CXXFLAGS) $(LFLAGS) hslongrun.o \ |
816 | + -L../libhsclient/.libs -lhsclient $$(mysql_config --libs_r) \ |
817 | + -o hslongrun |
818 | + |
819 | +hslongrun.o: hslongrun.cpp |
820 | + $(CXX) $(CXXFLAGS) $(AM_INCLUDES) $$(mysql_config --include) \ |
821 | + -c hslongrun.cpp |
822 | + |
823 | |
824 | === removed file 'HandlerSocket-Plugin-for-MySQL/client/Makefile.am' |
825 | --- HandlerSocket-Plugin-for-MySQL/client/Makefile.am 2011-04-19 12:57:00 +0000 |
826 | +++ HandlerSocket-Plugin-for-MySQL/client/Makefile.am 1970-01-01 00:00:00 +0000 |
827 | @@ -1,24 +0,0 @@ |
828 | -AM_INCLUDES= -I../libhsclient |
829 | -bin_PROGRAMS=hsclient |
830 | -hsclient_SOURCES= hsclient.cpp |
831 | -hsclient_LDFLAGS= -static -L../libhsclient -lhsclient |
832 | -hsclient_CXXFLAGS= $(AM_INCLUDES) |
833 | - |
834 | -hstest: hstest.o |
835 | - $(CXX) $(CXXFLAGS) $(LFLAGS) hstest.o \ |
836 | - -L../libhsclient/.libs -lhsclient $$(mysql_config --libs_r) \ |
837 | - -o hstest |
838 | - |
839 | -hstest.o: hstest.cpp |
840 | - $(CXX) $(CXXFLAGS) $(AM_INCLUDES) $$(mysql_config --include) \ |
841 | - -c hstest.cpp |
842 | - |
843 | -hslongrun: hslongrun.o |
844 | - $(CXX) $(CXXFLAGS) $(LFLAGS) hslongrun.o \ |
845 | - -L../libhsclient/.libs -lhsclient $$(mysql_config --libs_r) \ |
846 | - -o hslongrun |
847 | - |
848 | -hslongrun.o: hslongrun.cpp |
849 | - $(CXX) $(CXXFLAGS) $(AM_INCLUDES) $$(mysql_config --include) \ |
850 | - -c hslongrun.cpp |
851 | - |
852 | |
853 | === added file 'HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp' |
854 | --- HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp 1970-01-01 00:00:00 +0000 |
855 | +++ HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp 2012-06-25 04:42:22 +0000 |
856 | @@ -0,0 +1,88 @@ |
857 | + |
858 | +// vim:sw=2:ai |
859 | + |
860 | +#include "hstcpcli.hpp" |
861 | +#include "string_util.hpp" |
862 | + |
863 | +namespace dena { |
864 | + |
865 | +int |
866 | +hstcpcli_main(int argc, char **argv) |
867 | +{ |
868 | + config conf; |
869 | + parse_args(argc, argv, conf); |
870 | + socket_args sockargs; |
871 | + sockargs.set(conf); |
872 | + hstcpcli_ptr cli = hstcpcli_i::create(sockargs); |
873 | + const std::string dbname = conf.get_str("dbname", "hstest"); |
874 | + const std::string table = conf.get_str("table", "hstest_table1"); |
875 | + const std::string index = conf.get_str("index", "PRIMARY"); |
876 | + const std::string fields = conf.get_str("fields", "k,v"); |
877 | + const int limit = conf.get_int("limit", 0); |
878 | + const int skip = conf.get_int("skip", 0); |
879 | + std::vector<std::string> keys; |
880 | + std::vector<string_ref> keyrefs; |
881 | + size_t num_keys = 0; |
882 | + while (true) { |
883 | + const std::string conf_key = std::string("k") + to_stdstring(num_keys); |
884 | + const std::string k = conf.get_str(conf_key, ""); |
885 | + const std::string kx = conf.get_str(conf_key, "x"); |
886 | + if (k.empty() && kx == "x") { |
887 | + break; |
888 | + } |
889 | + ++num_keys; |
890 | + keys.push_back(k); |
891 | + } |
892 | + for (size_t i = 0; i < keys.size(); ++i) { |
893 | + const string_ref ref(keys[i].data(), keys[i].size()); |
894 | + keyrefs.push_back(ref); |
895 | + } |
896 | + const std::string op = conf.get_str("op", "="); |
897 | + const string_ref op_ref(op.data(), op.size()); |
898 | + cli->request_buf_open_index(0, dbname.c_str(), table.c_str(), |
899 | + index.c_str(), fields.c_str()); |
900 | + cli->request_buf_exec_generic(0, op_ref, num_keys == 0 ? 0 : &keyrefs[0], |
901 | + num_keys, limit, skip, string_ref(), 0, 0); |
902 | + int code = 0; |
903 | + size_t numflds = 0; |
904 | + do { |
905 | + if (cli->request_send() != 0) { |
906 | + fprintf(stderr, "request_send: %s\n", cli->get_error().c_str()); |
907 | + break; |
908 | + } |
909 | + if ((code = cli->response_recv(numflds)) != 0) { |
910 | + fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str()); |
911 | + break; |
912 | + } |
913 | + } while (false); |
914 | + cli->response_buf_remove(); |
915 | + do { |
916 | + if ((code = cli->response_recv(numflds)) != 0) { |
917 | + fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str()); |
918 | + break; |
919 | + } |
920 | + while (true) { |
921 | + const string_ref *const row = cli->get_next_row(); |
922 | + if (row == 0) { |
923 | + break; |
924 | + } |
925 | + printf("REC:"); |
926 | + for (size_t i = 0; i < numflds; ++i) { |
927 | + const std::string val(row[i].begin(), row[i].size()); |
928 | + printf(" %s", val.c_str()); |
929 | + } |
930 | + printf("\n"); |
931 | + } |
932 | + } while (false); |
933 | + cli->response_buf_remove(); |
934 | + return 0; |
935 | +} |
936 | + |
937 | +}; |
938 | + |
939 | +int |
940 | +main(int argc, char **argv) |
941 | +{ |
942 | + return dena::hstcpcli_main(argc, argv); |
943 | +} |
944 | + |
945 | |
946 | === removed file 'HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp' |
947 | --- HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp 2011-01-10 13:39:35 +0000 |
948 | +++ HandlerSocket-Plugin-for-MySQL/client/hsclient.cpp 1970-01-01 00:00:00 +0000 |
949 | @@ -1,88 +0,0 @@ |
950 | - |
951 | -// vim:sw=2:ai |
952 | - |
953 | -#include "hstcpcli.hpp" |
954 | -#include "string_util.hpp" |
955 | - |
956 | -namespace dena { |
957 | - |
958 | -int |
959 | -hstcpcli_main(int argc, char **argv) |
960 | -{ |
961 | - config conf; |
962 | - parse_args(argc, argv, conf); |
963 | - socket_args sockargs; |
964 | - sockargs.set(conf); |
965 | - hstcpcli_ptr cli = hstcpcli_i::create(sockargs); |
966 | - const std::string dbname = conf.get_str("dbname", "hstest"); |
967 | - const std::string table = conf.get_str("table", "hstest_table1"); |
968 | - const std::string index = conf.get_str("index", "PRIMARY"); |
969 | - const std::string fields = conf.get_str("fields", "k,v"); |
970 | - const int limit = conf.get_int("limit", 0); |
971 | - const int skip = conf.get_int("skip", 0); |
972 | - std::vector<std::string> keys; |
973 | - std::vector<string_ref> keyrefs; |
974 | - size_t num_keys = 0; |
975 | - while (true) { |
976 | - const std::string conf_key = std::string("k") + to_stdstring(num_keys); |
977 | - const std::string k = conf.get_str(conf_key, ""); |
978 | - const std::string kx = conf.get_str(conf_key, "x"); |
979 | - if (k.empty() && kx == "x") { |
980 | - break; |
981 | - } |
982 | - ++num_keys; |
983 | - keys.push_back(k); |
984 | - } |
985 | - for (size_t i = 0; i < keys.size(); ++i) { |
986 | - const string_ref ref(keys[i].data(), keys[i].size()); |
987 | - keyrefs.push_back(ref); |
988 | - } |
989 | - const std::string op = conf.get_str("op", "="); |
990 | - const string_ref op_ref(op.data(), op.size()); |
991 | - cli->request_buf_open_index(0, dbname.c_str(), table.c_str(), |
992 | - index.c_str(), fields.c_str()); |
993 | - cli->request_buf_exec_generic(0, op_ref, num_keys == 0 ? 0 : &keyrefs[0], |
994 | - num_keys, limit, skip, string_ref(), 0, 0); |
995 | - int code = 0; |
996 | - size_t numflds = 0; |
997 | - do { |
998 | - if (cli->request_send() != 0) { |
999 | - fprintf(stderr, "request_send: %s\n", cli->get_error().c_str()); |
1000 | - break; |
1001 | - } |
1002 | - if ((code = cli->response_recv(numflds)) != 0) { |
1003 | - fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str()); |
1004 | - break; |
1005 | - } |
1006 | - } while (false); |
1007 | - cli->response_buf_remove(); |
1008 | - do { |
1009 | - if ((code = cli->response_recv(numflds)) != 0) { |
1010 | - fprintf(stderr, "response_recv: %s\n", cli->get_error().c_str()); |
1011 | - break; |
1012 | - } |
1013 | - while (true) { |
1014 | - const string_ref *const row = cli->get_next_row(); |
1015 | - if (row == 0) { |
1016 | - break; |
1017 | - } |
1018 | - printf("REC:"); |
1019 | - for (size_t i = 0; i < numflds; ++i) { |
1020 | - const std::string val(row[i].begin(), row[i].size()); |
1021 | - printf(" %s", val.c_str()); |
1022 | - } |
1023 | - printf("\n"); |
1024 | - } |
1025 | - } while (false); |
1026 | - cli->response_buf_remove(); |
1027 | - return 0; |
1028 | -} |
1029 | - |
1030 | -}; |
1031 | - |
1032 | -int |
1033 | -main(int argc, char **argv) |
1034 | -{ |
1035 | - return dena::hstcpcli_main(argc, argv); |
1036 | -} |
1037 | - |
1038 | |
1039 | === added file 'HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp' |
1040 | --- HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp 1970-01-01 00:00:00 +0000 |
1041 | +++ HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp 2012-06-25 04:42:22 +0000 |
1042 | @@ -0,0 +1,1041 @@ |
1043 | + |
1044 | +// vim:sw=2:ai |
1045 | + |
1046 | +#include <signal.h> |
1047 | +#include <sys/time.h> |
1048 | +#include <stdio.h> |
1049 | +#include <string.h> |
1050 | +#include <vector> |
1051 | +#include <map> |
1052 | +#include <stdlib.h> |
1053 | +#include <memory> |
1054 | +#include <errno.h> |
1055 | +#include <mysql.h> |
1056 | +#include <time.h> |
1057 | +#include <sys/types.h> |
1058 | +#include <sys/stat.h> |
1059 | +#include <fcntl.h> |
1060 | + |
1061 | +#include "util.hpp" |
1062 | +#include "auto_ptrcontainer.hpp" |
1063 | +#include "socket.hpp" |
1064 | +#include "hstcpcli.hpp" |
1065 | +#include "string_util.hpp" |
1066 | +#include "mutex.hpp" |
1067 | + |
1068 | +namespace dena { |
1069 | + |
1070 | +struct auto_mysql : private noncopyable { |
1071 | + auto_mysql() : db(0) { |
1072 | + reset(); |
1073 | + } |
1074 | + ~auto_mysql() { |
1075 | + if (db) { |
1076 | + mysql_close(db); |
1077 | + } |
1078 | + } |
1079 | + void reset() { |
1080 | + if (db) { |
1081 | + mysql_close(db); |
1082 | + } |
1083 | + if ((db = mysql_init(0)) == 0) { |
1084 | + fatal_exit("failed to initialize mysql client"); |
1085 | + } |
1086 | + } |
1087 | + operator MYSQL *() const { return db; } |
1088 | + private: |
1089 | + MYSQL *db; |
1090 | +}; |
1091 | + |
1092 | +struct auto_mysql_res : private noncopyable { |
1093 | + auto_mysql_res(MYSQL *db) { |
1094 | + res = mysql_store_result(db); |
1095 | + } |
1096 | + ~auto_mysql_res() { |
1097 | + if (res) { |
1098 | + mysql_free_result(res); |
1099 | + } |
1100 | + } |
1101 | + operator MYSQL_RES *() const { return res; } |
1102 | + private: |
1103 | + MYSQL_RES *res; |
1104 | +}; |
1105 | + |
1106 | +struct auto_mysql_stmt : private noncopyable { |
1107 | + auto_mysql_stmt(MYSQL *db) { |
1108 | + stmt = mysql_stmt_init(db); |
1109 | + } |
1110 | + ~auto_mysql_stmt() { |
1111 | + if (stmt) { |
1112 | + mysql_stmt_close(stmt); |
1113 | + } |
1114 | + } |
1115 | + operator MYSQL_STMT *() const { return stmt; } |
1116 | + private: |
1117 | + MYSQL_STMT *stmt; |
1118 | +}; |
1119 | + |
1120 | +double |
1121 | +gettimeofday_double() |
1122 | +{ |
1123 | + struct timeval tv = { }; |
1124 | + if (gettimeofday(&tv, 0) != 0) { |
1125 | + fatal_abort("gettimeofday"); |
1126 | + } |
1127 | + return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec; |
1128 | +} |
1129 | + |
1130 | +struct record_value { |
1131 | + mutex lock; |
1132 | + bool deleted; |
1133 | + bool unknown_state; |
1134 | + std::string key; |
1135 | + std::vector<std::string> values; |
1136 | + record_value() : deleted(true), unknown_state(false) { } |
1137 | +}; |
1138 | + |
1139 | +struct hs_longrun_shared { |
1140 | + config conf; |
1141 | + socket_args arg; |
1142 | + int verbose; |
1143 | + long num_threads; |
1144 | + int usleep; |
1145 | + volatile mutable int running; |
1146 | + auto_ptrcontainer< std::vector<record_value *> > records; |
1147 | + hs_longrun_shared() : verbose(0), num_threads(0), usleep(0), running(1) { } |
1148 | +}; |
1149 | + |
1150 | +struct thread_base { |
1151 | + thread_base() : need_join(false), stack_size(256 * 1024) { } |
1152 | + virtual ~thread_base() { |
1153 | + join(); |
1154 | + } |
1155 | + virtual void run() = 0; |
1156 | + void start() { |
1157 | + if (!start_nothrow()) { |
1158 | + fatal_abort("thread::start"); |
1159 | + } |
1160 | + } |
1161 | + bool start_nothrow() { |
1162 | + if (need_join) { |
1163 | + return need_join; /* true */ |
1164 | + } |
1165 | + void *const arg = this; |
1166 | + pthread_attr_t attr; |
1167 | + if (pthread_attr_init(&attr) != 0) { |
1168 | + fatal_abort("pthread_attr_init"); |
1169 | + } |
1170 | + if (pthread_attr_setstacksize(&attr, stack_size) != 0) { |
1171 | + fatal_abort("pthread_attr_setstacksize"); |
1172 | + } |
1173 | + const int r = pthread_create(&thr, &attr, thread_main, arg); |
1174 | + if (pthread_attr_destroy(&attr) != 0) { |
1175 | + fatal_abort("pthread_attr_destroy"); |
1176 | + } |
1177 | + if (r != 0) { |
1178 | + return need_join; /* false */ |
1179 | + } |
1180 | + need_join = true; |
1181 | + return need_join; /* true */ |
1182 | + } |
1183 | + void join() { |
1184 | + if (!need_join) { |
1185 | + return; |
1186 | + } |
1187 | + int e = 0; |
1188 | + if ((e = pthread_join(thr, 0)) != 0) { |
1189 | + fatal_abort("pthread_join"); |
1190 | + } |
1191 | + need_join = false; |
1192 | + } |
1193 | + private: |
1194 | + static void *thread_main(void *arg) { |
1195 | + thread_base *p = static_cast<thread_base *>(arg); |
1196 | + p->run(); |
1197 | + return 0; |
1198 | + } |
1199 | + private: |
1200 | + pthread_t thr; |
1201 | + bool need_join; |
1202 | + size_t stack_size; |
1203 | +}; |
1204 | + |
1205 | +struct hs_longrun_stat { |
1206 | + unsigned long long verify_error_count; |
1207 | + unsigned long long runtime_error_count; |
1208 | + unsigned long long unknown_count; |
1209 | + unsigned long long success_count; |
1210 | + hs_longrun_stat() |
1211 | + : verify_error_count(0), runtime_error_count(0), |
1212 | + unknown_count(0), success_count(0) { } |
1213 | + void add(const hs_longrun_stat& x) { |
1214 | + verify_error_count += x.verify_error_count; |
1215 | + runtime_error_count += x.runtime_error_count; |
1216 | + unknown_count += x.unknown_count; |
1217 | + success_count += x.success_count; |
1218 | + } |
1219 | +}; |
1220 | + |
1221 | +struct hs_longrun_thread_base : public thread_base { |
1222 | + struct arg_type { |
1223 | + int id; |
1224 | + std::string worker_type; |
1225 | + char op; |
1226 | + int lock_flag; |
1227 | + const hs_longrun_shared& sh; |
1228 | + arg_type(int id, const std::string& worker_type, char op, int lock_flag, |
1229 | + const hs_longrun_shared& sh) |
1230 | + : id(id), worker_type(worker_type), op(op), lock_flag(lock_flag), |
1231 | + sh(sh) { } |
1232 | + }; |
1233 | + arg_type arg; |
1234 | + hs_longrun_stat stat; |
1235 | + drand48_data randbuf; |
1236 | + unsigned int seed; |
1237 | + hs_longrun_thread_base(const arg_type& arg) |
1238 | + : arg(arg), seed(0) { |
1239 | + seed = time(0) + arg.id + 1; |
1240 | + srand48_r(seed, &randbuf); |
1241 | + } |
1242 | + virtual ~hs_longrun_thread_base() { } |
1243 | + virtual void run() = 0; |
1244 | + size_t rand_record() { |
1245 | + double v = 0; |
1246 | + drand48_r(&randbuf, &v); |
1247 | + const size_t sz = arg.sh.records.size(); |
1248 | + size_t r = size_t(v * sz); |
1249 | + if (r >= sz) { |
1250 | + r = 0; |
1251 | + } |
1252 | + return r; |
1253 | + } |
1254 | + int verify_update(const std::string& k, const std::string& v1, |
1255 | + const std::string& v2, const std::string& v3, record_value& rec, |
1256 | + uint32_t num_rows, bool cur_unknown_state); |
1257 | + int verify_read(const std::string& k, uint32_t num_rows, uint32_t num_flds, |
1258 | + const std::string rrec[4], record_value& rec); |
1259 | + int verify_readnolock(const std::string& k, uint32_t num_rows, |
1260 | + uint32_t num_flds, const std::string rrec[4]); |
1261 | +}; |
1262 | + |
1263 | +int |
1264 | +hs_longrun_thread_base::verify_update(const std::string& k, |
1265 | + const std::string& v1, const std::string& v2, const std::string& v3, |
1266 | + record_value& rec, uint32_t num_rows, bool cur_unknown_state) |
1267 | +{ |
1268 | + const bool op_success = num_rows == 1; |
1269 | + int ret = 0; |
1270 | + if (!rec.unknown_state) { |
1271 | + if (!rec.deleted && !op_success) { |
1272 | + ++stat.verify_error_count; |
1273 | + if (arg.sh.verbose > 0) { |
1274 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1275 | + "unexpected_update_failure\n", |
1276 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1277 | + } |
1278 | + ret = 1; |
1279 | + } else if (rec.deleted && op_success) { |
1280 | + ++stat.verify_error_count; |
1281 | + if (arg.sh.verbose > 0) { |
1282 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1283 | + "unexpected_update_success\n", |
1284 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1285 | + } |
1286 | + ret = 1; |
1287 | + } |
1288 | + } |
1289 | + if (op_success) { |
1290 | + rec.values.resize(4); |
1291 | + rec.values[0] = k; |
1292 | + rec.values[1] = v1; |
1293 | + rec.values[2] = v2; |
1294 | + rec.values[3] = v3; |
1295 | + if (ret == 0 && !rec.unknown_state) { |
1296 | + ++stat.success_count; |
1297 | + } |
1298 | + } |
1299 | + rec.unknown_state = cur_unknown_state; |
1300 | + if (arg.sh.verbose >= 100 && ret == 0) { |
1301 | + fprintf(stderr, "%s %s %s %s %s\n", arg.worker_type.c_str(), |
1302 | + k.c_str(), v1.c_str(), v2.c_str(), v3.c_str()); |
1303 | + } |
1304 | + return ret; |
1305 | +} |
1306 | + |
1307 | +int |
1308 | +hs_longrun_thread_base::verify_read(const std::string& k, |
1309 | + uint32_t num_rows, uint32_t num_flds, const std::string rrec[4], |
1310 | + record_value& rec) |
1311 | +{ |
1312 | + const bool op_success = num_rows != 0; |
1313 | + int ret = 0; |
1314 | + if (!rec.unknown_state) { |
1315 | + if (!rec.deleted && !op_success) { |
1316 | + ++stat.verify_error_count; |
1317 | + if (arg.sh.verbose > 0) { |
1318 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1319 | + "unexpected_read_failure\n", |
1320 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1321 | + } |
1322 | + ret = 1; |
1323 | + } else if (rec.deleted && op_success) { |
1324 | + ++stat.verify_error_count; |
1325 | + if (arg.sh.verbose > 0) { |
1326 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1327 | + "unexpected_read_success\n", |
1328 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1329 | + } |
1330 | + ret = 1; |
1331 | + } else if (num_flds != 4) { |
1332 | + ++stat.verify_error_count; |
1333 | + if (arg.sh.verbose > 0) { |
1334 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1335 | + "unexpected_read_fldnum %d\n", |
1336 | + arg.worker_type.c_str(), arg.id, k.c_str(), |
1337 | + static_cast<int>(num_flds)); |
1338 | + } |
1339 | + ret = 1; |
1340 | + } else if (rec.deleted) { |
1341 | + /* nothing to verify */ |
1342 | + } else { |
1343 | + int diff = 0; |
1344 | + for (size_t i = 0; i < 4; ++i) { |
1345 | + if (rec.values[i] == rrec[i]) { |
1346 | + /* ok */ |
1347 | + } else { |
1348 | + diff = 1; |
1349 | + } |
1350 | + } |
1351 | + if (diff) { |
1352 | + std::string mess; |
1353 | + for (size_t i = 0; i < 4; ++i) { |
1354 | + const std::string& expected = rec.values[i]; |
1355 | + const std::string& val = rrec[i]; |
1356 | + mess += " " + val + "/" + expected; |
1357 | + } |
1358 | + if (arg.sh.verbose > 0) { |
1359 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1360 | + "unexpected_read_value %s\n", |
1361 | + arg.worker_type.c_str(), arg.id, k.c_str(), mess.c_str()); |
1362 | + } |
1363 | + ret = 1; |
1364 | + } |
1365 | + } |
1366 | + } |
1367 | + if (arg.sh.verbose >= 100 && ret == 0) { |
1368 | + fprintf(stderr, "%s %s\n", arg.worker_type.c_str(), k.c_str()); |
1369 | + } |
1370 | + if (ret == 0 && !rec.unknown_state) { |
1371 | + ++stat.success_count; |
1372 | + } |
1373 | + return ret; |
1374 | +} |
1375 | + |
1376 | +int |
1377 | +hs_longrun_thread_base::verify_readnolock(const std::string& k, |
1378 | + uint32_t num_rows, uint32_t num_flds, const std::string rrec[4]) |
1379 | +{ |
1380 | + int ret = 0; |
1381 | + if (num_rows != 1 || num_flds != 4) { |
1382 | + ++stat.verify_error_count; |
1383 | + if (arg.sh.verbose > 0) { |
1384 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1385 | + "unexpected_read_failure\n", |
1386 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1387 | + } |
1388 | + ret = 1; |
1389 | + } |
1390 | + if (arg.sh.verbose >= 100 && ret == 0) { |
1391 | + fprintf(stderr, "%s -> %s %s %s %s %s\n", arg.worker_type.c_str(), |
1392 | + k.c_str(), rrec[0].c_str(), rrec[1].c_str(), rrec[2].c_str(), |
1393 | + rrec[3].c_str()); |
1394 | + } |
1395 | + if (ret == 0) { |
1396 | + ++stat.success_count; |
1397 | + } |
1398 | + return ret; |
1399 | +} |
1400 | + |
1401 | +struct hs_longrun_thread_hs : public hs_longrun_thread_base { |
1402 | + hs_longrun_thread_hs(const arg_type& arg) |
1403 | + : hs_longrun_thread_base(arg) { } |
1404 | + void run(); |
1405 | + int check_hs_error(const char *mess, record_value *rec); |
1406 | + int op_insert(record_value& rec); |
1407 | + int op_delete(record_value& rec); |
1408 | + int op_update(record_value& rec); |
1409 | + int op_read(record_value& rec); |
1410 | + int op_readnolock(int k); |
1411 | + hstcpcli_ptr cli; |
1412 | + socket_args sockargs; |
1413 | +}; |
1414 | + |
1415 | +struct lock_guard : noncopyable { |
1416 | + lock_guard(mutex& mtx) : mtx(mtx) { |
1417 | + mtx.lock(); |
1418 | + } |
1419 | + ~lock_guard() { |
1420 | + mtx.unlock(); |
1421 | + } |
1422 | + mutex& mtx; |
1423 | +}; |
1424 | + |
1425 | +string_ref |
1426 | +to_string_ref(const std::string& s) |
1427 | +{ |
1428 | + return string_ref(s.data(), s.size()); |
1429 | +} |
1430 | + |
1431 | +std::string |
1432 | +to_string(const string_ref& s) |
1433 | +{ |
1434 | + return std::string(s.begin(), s.size()); |
1435 | +} |
1436 | + |
1437 | +void |
1438 | +hs_longrun_thread_hs::run() |
1439 | +{ |
1440 | + config c = arg.sh.conf; |
1441 | + if (arg.op == 'R' || arg.op == 'N') { |
1442 | + c["port"] = to_stdstring(arg.sh.conf.get_int("hsport", 9998)); |
1443 | + } else { |
1444 | + c["port"] = to_stdstring(arg.sh.conf.get_int("hsport_wr", 9999)); |
1445 | + } |
1446 | + sockargs.set(c); |
1447 | + |
1448 | + while (arg.sh.running) { |
1449 | + if (cli.get() == 0 || !cli->stable_point()) { |
1450 | + cli = hstcpcli_i::create(sockargs); |
1451 | + if (check_hs_error("connect", 0) != 0) { |
1452 | + cli.reset(); |
1453 | + continue; |
1454 | + } |
1455 | + cli->request_buf_open_index(0, "hstestdb", "hstesttbl", "PRIMARY", |
1456 | + "k,v1,v2,v3", "k,v1,v2,v3"); |
1457 | + cli->request_send(); |
1458 | + if (check_hs_error("openindex_send", 0) != 0) { |
1459 | + cli.reset(); |
1460 | + continue; |
1461 | + } |
1462 | + size_t num_flds = 0; |
1463 | + cli->response_recv(num_flds); |
1464 | + if (check_hs_error("openindex_recv", 0) != 0) { |
1465 | + cli.reset(); |
1466 | + continue; |
1467 | + } |
1468 | + cli->response_buf_remove(); |
1469 | + } |
1470 | + const size_t rec_id = rand_record(); |
1471 | + if (arg.lock_flag) { |
1472 | + record_value& rec = *arg.sh.records[rec_id]; |
1473 | + lock_guard g(rec.lock); |
1474 | + int e = 0; |
1475 | + switch (arg.op) { |
1476 | + case 'I': |
1477 | + e = op_insert(rec); |
1478 | + break; |
1479 | + case 'D': |
1480 | + e = op_delete(rec); |
1481 | + break; |
1482 | + case 'U': |
1483 | + e = op_update(rec); |
1484 | + break; |
1485 | + case 'R': |
1486 | + e = op_read(rec); |
1487 | + break; |
1488 | + default: |
1489 | + break; |
1490 | + } |
1491 | + } else { |
1492 | + int e = 0; |
1493 | + switch (arg.op) { |
1494 | + case 'N': |
1495 | + e = op_readnolock(rec_id); |
1496 | + break; |
1497 | + default: |
1498 | + break; |
1499 | + } |
1500 | + } |
1501 | + } |
1502 | +} |
1503 | + |
1504 | +int |
1505 | +hs_longrun_thread_hs::op_insert(record_value& rec) |
1506 | +{ |
1507 | + const std::string k = rec.key; |
1508 | + const std::string v1 = "iv1_" + k + "_" + to_stdstring(arg.id); |
1509 | + const std::string v2 = "iv2_" + k + "_" + to_stdstring(arg.id); |
1510 | + const std::string v3 = "iv3_" + k + "_" + to_stdstring(arg.id); |
1511 | + const string_ref op_ref("+", 1); |
1512 | + const string_ref op_args[4] = { |
1513 | + to_string_ref(k), |
1514 | + to_string_ref(v1), |
1515 | + to_string_ref(v2), |
1516 | + to_string_ref(v3) |
1517 | + }; |
1518 | + cli->request_buf_exec_generic(0, op_ref, op_args, 4, 1, 0, |
1519 | + string_ref(), 0, 0, 0, 0); |
1520 | + cli->request_send(); |
1521 | + if (check_hs_error("op_insert_send", &rec) != 0) { return 1; } |
1522 | + size_t numflds = 0; |
1523 | + cli->response_recv(numflds); |
1524 | + if (arg.sh.verbose > 10) { |
1525 | + const string_ref *row = cli->get_next_row(); |
1526 | + fprintf(stderr, "HS op=+ errrcode=%d errmess=[%s]\n", cli->get_error_code(), |
1527 | + row ? to_string(row[0]).c_str() : ""); |
1528 | + } |
1529 | + const bool op_success = cli->get_error_code() == 0; |
1530 | + int ret = 0; |
1531 | + if (!rec.unknown_state) { |
1532 | + if (rec.deleted && !op_success) { |
1533 | + ++stat.verify_error_count; |
1534 | + if (arg.sh.verbose > 0) { |
1535 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1536 | + "unexpected_insert_failure\n", |
1537 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1538 | + } |
1539 | + ret = 1; |
1540 | + } else if (!rec.deleted && op_success) { |
1541 | + ++stat.verify_error_count; |
1542 | + if (arg.sh.verbose > 0) { |
1543 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1544 | + "unexpected_insert_success\n", |
1545 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1546 | + } |
1547 | + ret = 1; |
1548 | + } |
1549 | + } else { |
1550 | + ++stat.unknown_count; |
1551 | + } |
1552 | + if (op_success) { |
1553 | + rec.values.resize(4); |
1554 | + rec.values[0] = k; |
1555 | + rec.values[1] = v1; |
1556 | + rec.values[2] = v2; |
1557 | + rec.values[3] = v3; |
1558 | + rec.deleted = false; |
1559 | + if (arg.sh.verbose >= 100 && ret == 0) { |
1560 | + fprintf(stderr, "HS_INSERT %s %s %s %s\n", k.c_str(), v1.c_str(), |
1561 | + v2.c_str(), v3.c_str()); |
1562 | + } |
1563 | + if (ret == 0 && !rec.unknown_state) { |
1564 | + ++stat.success_count; |
1565 | + } |
1566 | + rec.unknown_state = false; |
1567 | + } |
1568 | + cli->response_buf_remove(); |
1569 | + return ret; |
1570 | +} |
1571 | + |
1572 | +int |
1573 | +hs_longrun_thread_hs::op_delete(record_value& rec) |
1574 | +{ |
1575 | + const std::string k = rec.key; |
1576 | + const string_ref op_ref("=", 1); |
1577 | + const string_ref op_args[1] = { |
1578 | + to_string_ref(k), |
1579 | + }; |
1580 | + const string_ref modop_ref("D", 1); |
1581 | + cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
1582 | + modop_ref, 0, 0, 0, 0); |
1583 | + cli->request_send(); |
1584 | + if (check_hs_error("op_delete_send", &rec) != 0) { return 1; } |
1585 | + size_t numflds = 0; |
1586 | + cli->response_recv(numflds); |
1587 | + if (check_hs_error("op_delete_recv", &rec) != 0) { return 1; } |
1588 | + const string_ref *row = cli->get_next_row(); |
1589 | + const bool op_success = (numflds > 0 && row != 0 && |
1590 | + to_string(row[0]) == "1"); |
1591 | + int ret = 0; |
1592 | + if (!rec.unknown_state) { |
1593 | + if (!rec.deleted && !op_success) { |
1594 | + ++stat.verify_error_count; |
1595 | + if (arg.sh.verbose > 0) { |
1596 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1597 | + "unexpected_delete_failure\n", |
1598 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1599 | + } |
1600 | + ret = 1; |
1601 | + } else if (rec.deleted && op_success) { |
1602 | + ++stat.verify_error_count; |
1603 | + if (arg.sh.verbose > 0) { |
1604 | + fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
1605 | + "unexpected_delete_success\n", |
1606 | + arg.worker_type.c_str(), arg.id, k.c_str()); |
1607 | + } |
1608 | + ret = 1; |
1609 | + } |
1610 | + } |
1611 | + cli->response_buf_remove(); |
1612 | + if (op_success) { |
1613 | + rec.deleted = true; |
1614 | + if (ret == 0 && !rec.unknown_state) { |
1615 | + ++stat.success_count; |
1616 | + } |
1617 | + rec.unknown_state = false; |
1618 | + } |
1619 | + if (arg.sh.verbose >= 100 && ret == 0) { |
1620 | + fprintf(stderr, "HS_DELETE %s\n", k.c_str()); |
1621 | + } |
1622 | + return ret; |
1623 | +} |
1624 | + |
1625 | +int |
1626 | +hs_longrun_thread_hs::op_update(record_value& rec) |
1627 | +{ |
1628 | + const std::string k = rec.key; |
1629 | + const std::string v1 = "uv1_" + k + "_" + to_stdstring(arg.id); |
1630 | + const std::string v2 = "uv2_" + k + "_" + to_stdstring(arg.id); |
1631 | + const std::string v3 = "uv3_" + k + "_" + to_stdstring(arg.id); |
1632 | + const string_ref op_ref("=", 1); |
1633 | + const string_ref op_args[1] = { |
1634 | + to_string_ref(k), |
1635 | + }; |
1636 | + const string_ref modop_ref("U", 1); |
1637 | + const string_ref modop_args[4] = { |
1638 | + to_string_ref(k), |
1639 | + to_string_ref(v1), |
1640 | + to_string_ref(v2), |
1641 | + to_string_ref(v3) |
1642 | + }; |
1643 | + cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
1644 | + modop_ref, modop_args, 4, 0, 0); |
1645 | + cli->request_send(); |
1646 | + if (check_hs_error("op_update_send", &rec) != 0) { return 1; } |
1647 | + size_t numflds = 0; |
1648 | + cli->response_recv(numflds); |
1649 | + if (check_hs_error("op_update_recv", &rec) != 0) { return 1; } |
1650 | + const string_ref *row = cli->get_next_row(); |
1651 | + uint32_t num_rows = row |
1652 | + ? atoi_uint32_nocheck(row[0].begin(), row[0].end()) : 0; |
1653 | + cli->response_buf_remove(); |
1654 | + const bool cur_unknown_state = (num_rows == 1); |
1655 | + return verify_update(k, v1, v2, v3, rec, num_rows, cur_unknown_state); |
1656 | +} |
1657 | + |
1658 | +int |
1659 | +hs_longrun_thread_hs::op_read(record_value& rec) |
1660 | +{ |
1661 | + const std::string k = rec.key; |
1662 | + const string_ref op_ref("=", 1); |
1663 | + const string_ref op_args[1] = { |
1664 | + to_string_ref(k), |
1665 | + }; |
1666 | + cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
1667 | + string_ref(), 0, 0, 0, 0); |
1668 | + cli->request_send(); |
1669 | + if (check_hs_error("op_read_send", 0) != 0) { return 1; } |
1670 | + size_t num_flds = 0; |
1671 | + size_t num_rows = 0; |
1672 | + cli->response_recv(num_flds); |
1673 | + if (check_hs_error("op_read_recv", 0) != 0) { return 1; } |
1674 | + const string_ref *row = cli->get_next_row(); |
1675 | + std::string rrec[4]; |
1676 | + if (row != 0 && num_flds == 4) { |
1677 | + for (int i = 0; i < 4; ++i) { |
1678 | + rrec[i] = to_string(row[i]); |
1679 | + } |
1680 | + ++num_rows; |
1681 | + } |
1682 | + row = cli->get_next_row(); |
1683 | + if (row != 0) { |
1684 | + ++num_rows; |
1685 | + } |
1686 | + cli->response_buf_remove(); |
1687 | + return verify_read(k, num_rows, num_flds, rrec, rec); |
1688 | +} |
1689 | + |
1690 | +int |
1691 | +hs_longrun_thread_hs::op_readnolock(int key) |
1692 | +{ |
1693 | + const std::string k = to_stdstring(key); |
1694 | + const string_ref op_ref("=", 1); |
1695 | + const string_ref op_args[1] = { |
1696 | + to_string_ref(k), |
1697 | + }; |
1698 | + cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
1699 | + string_ref(), 0, 0, 0, 0); |
1700 | + cli->request_send(); |
1701 | + if (check_hs_error("op_read_send", 0) != 0) { return 1; } |
1702 | + size_t num_flds = 0; |
1703 | + size_t num_rows = 0; |
1704 | + cli->response_recv(num_flds); |
1705 | + if (check_hs_error("op_read_recv", 0) != 0) { return 1; } |
1706 | + const string_ref *row = cli->get_next_row(); |
1707 | + std::string rrec[4]; |
1708 | + if (row != 0 && num_flds == 4) { |
1709 | + for (int i = 0; i < 4; ++i) { |
1710 | + rrec[i] = to_string(row[i]); |
1711 | + } |
1712 | + ++num_rows; |
1713 | + } |
1714 | + row = cli->get_next_row(); |
1715 | + if (row != 0) { |
1716 | + ++num_rows; |
1717 | + } |
1718 | + cli->response_buf_remove(); |
1719 | + return verify_readnolock(k, num_rows, num_flds, rrec); |
1720 | +} |
1721 | + |
1722 | +int |
1723 | +hs_longrun_thread_hs::check_hs_error(const char *mess, record_value *rec) |
1724 | +{ |
1725 | + const int err = cli->get_error_code(); |
1726 | + if (err == 0) { |
1727 | + return 0; |
1728 | + } |
1729 | + ++stat.runtime_error_count; |
1730 | + if (arg.sh.verbose > 0) { |
1731 | + const std::string estr = cli->get_error(); |
1732 | + fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d %s: %d %s\n", |
1733 | + arg.op, arg.id, mess, err, estr.c_str()); |
1734 | + } |
1735 | + if (rec) { |
1736 | + rec->unknown_state = true; |
1737 | + } |
1738 | + return 1; |
1739 | +} |
1740 | + |
1741 | +struct hs_longrun_thread_my : public hs_longrun_thread_base { |
1742 | + hs_longrun_thread_my(const arg_type& arg) |
1743 | + : hs_longrun_thread_base(arg), connected(false) { } |
1744 | + void run(); |
1745 | + void show_mysql_error(const char *mess, record_value *rec); |
1746 | + int op_insert(record_value& rec); |
1747 | + int op_delete(record_value& rec); |
1748 | + int op_update(record_value& rec); |
1749 | + int op_delins(record_value& rec); |
1750 | + int op_read(record_value& rec); |
1751 | + auto_mysql db; |
1752 | + bool connected; |
1753 | +}; |
1754 | + |
1755 | +void |
1756 | +hs_longrun_thread_my::run() |
1757 | +{ |
1758 | + const std::string mysql_host = arg.sh.conf.get_str("host", "localhost"); |
1759 | + const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root"); |
1760 | + const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", ""); |
1761 | + const std::string mysql_dbname = "hstestdb"; |
1762 | + |
1763 | + while (arg.sh.running) { |
1764 | + if (!connected) { |
1765 | + if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(), |
1766 | + mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) { |
1767 | + show_mysql_error("mysql_real_connect", 0); |
1768 | + continue; |
1769 | + } |
1770 | + } |
1771 | + connected = true; |
1772 | + const size_t rec_id = rand_record(); |
1773 | + record_value& rec = *arg.sh.records[rec_id]; |
1774 | + lock_guard g(rec.lock); |
1775 | + int e = 0; |
1776 | + switch (arg.op) { |
1777 | + #if 0 |
1778 | + case 'I': |
1779 | + e = op_insert(rec); |
1780 | + break; |
1781 | + case 'D': |
1782 | + e = op_delete(rec); |
1783 | + break; |
1784 | + case 'U': |
1785 | + e = op_update(rec); |
1786 | + break; |
1787 | + #endif |
1788 | + case 'T': |
1789 | + e = op_delins(rec); |
1790 | + break; |
1791 | + case 'R': |
1792 | + e = op_read(rec); |
1793 | + break; |
1794 | + default: |
1795 | + break; |
1796 | + } |
1797 | + } |
1798 | +} |
1799 | + |
1800 | +int |
1801 | +hs_longrun_thread_my::op_delins(record_value& rec) |
1802 | +{ |
1803 | + const std::string k = rec.key; |
1804 | + const std::string v1 = "div1_" + k + "_" + to_stdstring(arg.id); |
1805 | + const std::string v2 = "div2_" + k + "_" + to_stdstring(arg.id); |
1806 | + const std::string v3 = "div3_" + k + "_" + to_stdstring(arg.id); |
1807 | + int success = 0; |
1808 | + bool cur_unknown_state = false; |
1809 | + do { |
1810 | + char query[1024]; |
1811 | + #if 1 |
1812 | + if (mysql_query(db, "begin") != 0) { |
1813 | + if (arg.sh.verbose >= 20) { |
1814 | + fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "begin"); |
1815 | + } |
1816 | + break; |
1817 | + } |
1818 | + #endif |
1819 | + cur_unknown_state = true; |
1820 | + snprintf(query, 1024, |
1821 | + "delete from hstesttbl where k = '%s'", k.c_str()); |
1822 | + if (mysql_query(db, query) != 0) { |
1823 | + if (arg.sh.verbose >= 20) { |
1824 | + fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
1825 | + } |
1826 | + break; |
1827 | + } |
1828 | + if (mysql_affected_rows(db) != 1) { |
1829 | + if (arg.sh.verbose >= 20) { |
1830 | + fprintf(stderr, "mysql: notfound: [%s]\n", query); |
1831 | + } |
1832 | + break; |
1833 | + } |
1834 | + snprintf(query, 1024, |
1835 | + "insert into hstesttbl values ('%s', '%s', '%s', '%s')", |
1836 | + k.c_str(), v1.c_str(), v2.c_str(), v3.c_str()); |
1837 | + if (mysql_query(db, query) != 0) { |
1838 | + if (arg.sh.verbose >= 20) { |
1839 | + fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
1840 | + } |
1841 | + break; |
1842 | + } |
1843 | + #if 1 |
1844 | + if (mysql_query(db, "commit") != 0) { |
1845 | + if (arg.sh.verbose >= 20) { |
1846 | + fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "commit"); |
1847 | + } |
1848 | + break; |
1849 | + } |
1850 | + #endif |
1851 | + success = true; |
1852 | + cur_unknown_state = false; |
1853 | + } while (false); |
1854 | + return verify_update(k, v1, v2, v3, rec, (success != 0), cur_unknown_state); |
1855 | +} |
1856 | + |
1857 | +int |
1858 | +hs_longrun_thread_my::op_read(record_value& rec) |
1859 | +{ |
1860 | + const std::string k = rec.key; |
1861 | + char query[1024] = { 0 }; |
1862 | + const int len = snprintf(query, 1024, |
1863 | + "select k,v1,v2,v3 from hstesttbl where k='%s'", k.c_str()); |
1864 | + const int r = mysql_real_query(db, query, len > 0 ? len : 0); |
1865 | + if (r != 0) { |
1866 | + show_mysql_error(query, 0); |
1867 | + return 1; |
1868 | + } |
1869 | + MYSQL_ROW row = 0; |
1870 | + unsigned long *lengths = 0; |
1871 | + unsigned int num_rows = 0; |
1872 | + unsigned int num_flds = 0; |
1873 | + auto_mysql_res res(db); |
1874 | + std::string rrec[4]; |
1875 | + if (res != 0) { |
1876 | + num_flds = mysql_num_fields(res); |
1877 | + row = mysql_fetch_row(res); |
1878 | + if (row != 0) { |
1879 | + lengths = mysql_fetch_lengths(res); |
1880 | + if (num_flds == 4) { |
1881 | + for (int i = 0; i < 4; ++i) { |
1882 | + rrec[i] = std::string(row[i], lengths[i]); |
1883 | + } |
1884 | + } |
1885 | + ++num_rows; |
1886 | + row = mysql_fetch_row(res); |
1887 | + if (row != 0) { |
1888 | + ++num_rows; |
1889 | + } |
1890 | + } |
1891 | + } |
1892 | + return verify_read(k, num_rows, num_flds, rrec, rec); |
1893 | +} |
1894 | + |
1895 | +void |
1896 | +hs_longrun_thread_my::show_mysql_error(const char *mess, record_value *rec) |
1897 | +{ |
1898 | + ++stat.runtime_error_count; |
1899 | + if (arg.sh.verbose > 0) { |
1900 | + fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d [%s]: %s\n", |
1901 | + arg.op, arg.id, mess, mysql_error(db)); |
1902 | + } |
1903 | + if (rec) { |
1904 | + rec->unknown_state = true; |
1905 | + } |
1906 | + db.reset(); |
1907 | + connected = false; |
1908 | +} |
1909 | + |
1910 | +void |
1911 | +mysql_do(MYSQL *db, const char *query) |
1912 | +{ |
1913 | + if (mysql_real_query(db, query, strlen(query)) != 0) { |
1914 | + fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
1915 | + fatal_exit("mysql_do"); |
1916 | + } |
1917 | +} |
1918 | + |
1919 | +void |
1920 | +hs_longrun_init_table(const config& conf, int num_prepare, |
1921 | + hs_longrun_shared& shared) |
1922 | +{ |
1923 | + const std::string mysql_host = conf.get_str("host", "localhost"); |
1924 | + const std::string mysql_user = conf.get_str("mysqluser", "root"); |
1925 | + const std::string mysql_passwd = conf.get_str("mysqlpass", ""); |
1926 | + const std::string mysql_dbname = ""; |
1927 | + auto_mysql db; |
1928 | + if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(), |
1929 | + mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) { |
1930 | + fprintf(stderr, "mysql: error=[%s]\n", mysql_error(db)); |
1931 | + fatal_exit("hs_longrun_init_table"); |
1932 | + } |
1933 | + mysql_do(db, "drop database if exists hstestdb"); |
1934 | + mysql_do(db, "create database hstestdb"); |
1935 | + mysql_do(db, "use hstestdb"); |
1936 | + mysql_do(db, |
1937 | + "create table hstesttbl (" |
1938 | + "k int primary key," |
1939 | + "v1 varchar(32) not null," |
1940 | + "v2 varchar(32) not null," |
1941 | + "v3 varchar(32) not null" |
1942 | + ") character set utf8 collate utf8_bin engine = innodb"); |
1943 | + for (int i = 0; i < num_prepare; ++i) { |
1944 | + const std::string i_str = to_stdstring(i); |
1945 | + const std::string v1 = "pv1_" + i_str; |
1946 | + const std::string v2 = "pv2_" + i_str; |
1947 | + const std::string v3 = "pv3_" + i_str; |
1948 | + char buf[1024]; |
1949 | + snprintf(buf, 1024, "insert into hstesttbl(k, v1, v2, v3) values" |
1950 | + "(%d, '%s', '%s', '%s')", i, v1.c_str(), v2.c_str(), v3.c_str()); |
1951 | + mysql_do(db, buf); |
1952 | + record_value *rec = shared.records[i]; |
1953 | + rec->key = i_str; |
1954 | + rec->values.resize(4); |
1955 | + rec->values[0] = i_str; |
1956 | + rec->values[1] = v1; |
1957 | + rec->values[2] = v2; |
1958 | + rec->values[3] = v3; |
1959 | + rec->deleted = false; |
1960 | + } |
1961 | +} |
1962 | + |
1963 | +int |
1964 | +hs_longrun_main(int argc, char **argv) |
1965 | +{ |
1966 | + hs_longrun_shared shared; |
1967 | + parse_args(argc, argv, shared.conf); |
1968 | + shared.conf["host"] = shared.conf.get_str("host", "localhost"); |
1969 | + shared.verbose = shared.conf.get_int("verbose", 1); |
1970 | + const int table_size = shared.conf.get_int("table_size", 10000); |
1971 | + for (int i = 0; i < table_size; ++i) { |
1972 | + std::auto_ptr<record_value> rec(new record_value()); |
1973 | + rec->key = to_stdstring(i); |
1974 | + shared.records.push_back_ptr(rec); |
1975 | + } |
1976 | + mysql_library_init(0, 0, 0); |
1977 | + const int duration = shared.conf.get_int("duration", 10); |
1978 | + const int num_hsinsert = shared.conf.get_int("num_hsinsert", 10); |
1979 | + const int num_hsdelete = shared.conf.get_int("num_hsdelete", 10); |
1980 | + const int num_hsupdate = shared.conf.get_int("num_hsupdate", 10); |
1981 | + const int num_hsread = shared.conf.get_int("num_hsread", 10); |
1982 | + const int num_myread = shared.conf.get_int("num_myread", 10); |
1983 | + const int num_mydelins = shared.conf.get_int("num_mydelins", 10); |
1984 | + int num_hsreadnolock = shared.conf.get_int("num_hsreadnolock", 10); |
1985 | + const bool always_filled = (num_hsinsert == 0 && num_hsdelete == 0); |
1986 | + if (!always_filled) { |
1987 | + num_hsreadnolock = 0; |
1988 | + } |
1989 | + hs_longrun_init_table(shared.conf, always_filled ? table_size : 0, |
1990 | + shared); |
1991 | + /* create worker threads */ |
1992 | + static const struct thrtmpl_type { |
1993 | + const char *type; char op; int num; int hs; int lock; |
1994 | + } thrtmpl[] = { |
1995 | + { "hsinsert", 'I', num_hsinsert, 1, 1 }, |
1996 | + { "hsdelete", 'D', num_hsdelete, 1, 1 }, |
1997 | + { "hsupdate", 'U', num_hsupdate, 1, 1 }, |
1998 | + { "hsread", 'R', num_hsread, 1, 1 }, |
1999 | + { "hsreadnolock", 'N', num_hsreadnolock, 1, 0 }, |
2000 | + { "myread", 'R', num_myread, 0, 1 }, |
2001 | + { "mydelins", 'T', num_mydelins, 0, 1 }, |
2002 | + }; |
2003 | + typedef auto_ptrcontainer< std::vector<hs_longrun_thread_base *> > thrs_type; |
2004 | + thrs_type thrs; |
2005 | + for (size_t i = 0; i < sizeof(thrtmpl)/sizeof(thrtmpl[0]); ++i) { |
2006 | + const thrtmpl_type& e = thrtmpl[i]; |
2007 | + for (int j = 0; j < e.num; ++j) { |
2008 | + int id = thrs.size(); |
2009 | + const hs_longrun_thread_hs::arg_type arg(id, e.type, e.op, e.lock, |
2010 | + shared); |
2011 | + std::auto_ptr<hs_longrun_thread_base> thr; |
2012 | + if (e.hs) { |
2013 | + thr.reset(new hs_longrun_thread_hs(arg)); |
2014 | + } else { |
2015 | + thr.reset(new hs_longrun_thread_my(arg)); |
2016 | + } |
2017 | + thrs.push_back_ptr(thr); |
2018 | + } |
2019 | + } |
2020 | + shared.num_threads = thrs.size(); |
2021 | + /* start threads */ |
2022 | + fprintf(stderr, "START\n"); |
2023 | + shared.running = 1; |
2024 | + for (size_t i = 0; i < thrs.size(); ++i) { |
2025 | + thrs[i]->start(); |
2026 | + } |
2027 | + /* wait */ |
2028 | + sleep(duration); |
2029 | + /* stop thread */ |
2030 | + shared.running = 0; |
2031 | + for (size_t i = 0; i < thrs.size(); ++i) { |
2032 | + thrs[i]->join(); |
2033 | + } |
2034 | + fprintf(stderr, "DONE\n"); |
2035 | + /* summary */ |
2036 | + typedef std::map<std::string, hs_longrun_stat> stat_map; |
2037 | + stat_map sm; |
2038 | + for (size_t i = 0; i < thrs.size(); ++i) { |
2039 | + hs_longrun_thread_base *const thr = thrs[i]; |
2040 | + const std::string wt = thr->arg.worker_type; |
2041 | + hs_longrun_stat& v = sm[wt]; |
2042 | + v.add(thr->stat); |
2043 | + } |
2044 | + hs_longrun_stat total; |
2045 | + for (stat_map::const_iterator i = sm.begin(); i != sm.end(); ++i) { |
2046 | + if (i->second.verify_error_count != 0) { |
2047 | + fprintf(stderr, "%s verify_error %llu\n", i->first.c_str(), |
2048 | + i->second.verify_error_count); |
2049 | + } |
2050 | + if (i->second.runtime_error_count) { |
2051 | + fprintf(stderr, "%s runtime_error %llu\n", i->first.c_str(), |
2052 | + i->second.runtime_error_count); |
2053 | + } |
2054 | + if (i->second.unknown_count) { |
2055 | + fprintf(stderr, "%s unknown %llu\n", i->first.c_str(), |
2056 | + i->second.unknown_count); |
2057 | + } |
2058 | + fprintf(stderr, "%s success %llu\n", i->first.c_str(), |
2059 | + i->second.success_count); |
2060 | + total.add(i->second); |
2061 | + } |
2062 | + if (total.verify_error_count != 0) { |
2063 | + fprintf(stderr, "TOTAL verify_error %llu\n", total.verify_error_count); |
2064 | + } |
2065 | + if (total.runtime_error_count != 0) { |
2066 | + fprintf(stderr, "TOTAL runtime_error %llu\n", total.runtime_error_count); |
2067 | + } |
2068 | + if (total.unknown_count != 0) { |
2069 | + fprintf(stderr, "TOTAL unknown %llu\n", total.unknown_count); |
2070 | + } |
2071 | + fprintf(stderr, "TOTAL success %llu\n", total.success_count); |
2072 | + mysql_library_end(); |
2073 | + return 0; |
2074 | +} |
2075 | + |
2076 | +}; |
2077 | + |
2078 | +int |
2079 | +main(int argc, char **argv) |
2080 | +{ |
2081 | + return dena::hs_longrun_main(argc, argv); |
2082 | +} |
2083 | + |
2084 | |
2085 | === removed file 'HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp' |
2086 | --- HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp 2011-04-19 12:57:00 +0000 |
2087 | +++ HandlerSocket-Plugin-for-MySQL/client/hslongrun.cpp 1970-01-01 00:00:00 +0000 |
2088 | @@ -1,1041 +0,0 @@ |
2089 | - |
2090 | -// vim:sw=2:ai |
2091 | - |
2092 | -#include <signal.h> |
2093 | -#include <sys/time.h> |
2094 | -#include <stdio.h> |
2095 | -#include <string.h> |
2096 | -#include <vector> |
2097 | -#include <map> |
2098 | -#include <stdlib.h> |
2099 | -#include <memory> |
2100 | -#include <errno.h> |
2101 | -#include <mysql.h> |
2102 | -#include <time.h> |
2103 | -#include <sys/types.h> |
2104 | -#include <sys/stat.h> |
2105 | -#include <fcntl.h> |
2106 | - |
2107 | -#include "util.hpp" |
2108 | -#include "auto_ptrcontainer.hpp" |
2109 | -#include "socket.hpp" |
2110 | -#include "hstcpcli.hpp" |
2111 | -#include "string_util.hpp" |
2112 | -#include "mutex.hpp" |
2113 | - |
2114 | -namespace dena { |
2115 | - |
2116 | -struct auto_mysql : private noncopyable { |
2117 | - auto_mysql() : db(0) { |
2118 | - reset(); |
2119 | - } |
2120 | - ~auto_mysql() { |
2121 | - if (db) { |
2122 | - mysql_close(db); |
2123 | - } |
2124 | - } |
2125 | - void reset() { |
2126 | - if (db) { |
2127 | - mysql_close(db); |
2128 | - } |
2129 | - if ((db = mysql_init(0)) == 0) { |
2130 | - fatal_exit("failed to initialize mysql client"); |
2131 | - } |
2132 | - } |
2133 | - operator MYSQL *() const { return db; } |
2134 | - private: |
2135 | - MYSQL *db; |
2136 | -}; |
2137 | - |
2138 | -struct auto_mysql_res : private noncopyable { |
2139 | - auto_mysql_res(MYSQL *db) { |
2140 | - res = mysql_store_result(db); |
2141 | - } |
2142 | - ~auto_mysql_res() { |
2143 | - if (res) { |
2144 | - mysql_free_result(res); |
2145 | - } |
2146 | - } |
2147 | - operator MYSQL_RES *() const { return res; } |
2148 | - private: |
2149 | - MYSQL_RES *res; |
2150 | -}; |
2151 | - |
2152 | -struct auto_mysql_stmt : private noncopyable { |
2153 | - auto_mysql_stmt(MYSQL *db) { |
2154 | - stmt = mysql_stmt_init(db); |
2155 | - } |
2156 | - ~auto_mysql_stmt() { |
2157 | - if (stmt) { |
2158 | - mysql_stmt_close(stmt); |
2159 | - } |
2160 | - } |
2161 | - operator MYSQL_STMT *() const { return stmt; } |
2162 | - private: |
2163 | - MYSQL_STMT *stmt; |
2164 | -}; |
2165 | - |
2166 | -double |
2167 | -gettimeofday_double() |
2168 | -{ |
2169 | - struct timeval tv = { }; |
2170 | - if (gettimeofday(&tv, 0) != 0) { |
2171 | - fatal_abort("gettimeofday"); |
2172 | - } |
2173 | - return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec; |
2174 | -} |
2175 | - |
2176 | -struct record_value { |
2177 | - mutex lock; |
2178 | - bool deleted; |
2179 | - bool unknown_state; |
2180 | - std::string key; |
2181 | - std::vector<std::string> values; |
2182 | - record_value() : deleted(true), unknown_state(false) { } |
2183 | -}; |
2184 | - |
2185 | -struct hs_longrun_shared { |
2186 | - config conf; |
2187 | - socket_args arg; |
2188 | - int verbose; |
2189 | - long num_threads; |
2190 | - int usleep; |
2191 | - volatile mutable int running; |
2192 | - auto_ptrcontainer< std::vector<record_value *> > records; |
2193 | - hs_longrun_shared() : verbose(0), num_threads(0), usleep(0), running(1) { } |
2194 | -}; |
2195 | - |
2196 | -struct thread_base { |
2197 | - thread_base() : need_join(false), stack_size(256 * 1024) { } |
2198 | - virtual ~thread_base() { |
2199 | - join(); |
2200 | - } |
2201 | - virtual void run() = 0; |
2202 | - void start() { |
2203 | - if (!start_nothrow()) { |
2204 | - fatal_abort("thread::start"); |
2205 | - } |
2206 | - } |
2207 | - bool start_nothrow() { |
2208 | - if (need_join) { |
2209 | - return need_join; /* true */ |
2210 | - } |
2211 | - void *const arg = this; |
2212 | - pthread_attr_t attr; |
2213 | - if (pthread_attr_init(&attr) != 0) { |
2214 | - fatal_abort("pthread_attr_init"); |
2215 | - } |
2216 | - if (pthread_attr_setstacksize(&attr, stack_size) != 0) { |
2217 | - fatal_abort("pthread_attr_setstacksize"); |
2218 | - } |
2219 | - const int r = pthread_create(&thr, &attr, thread_main, arg); |
2220 | - if (pthread_attr_destroy(&attr) != 0) { |
2221 | - fatal_abort("pthread_attr_destroy"); |
2222 | - } |
2223 | - if (r != 0) { |
2224 | - return need_join; /* false */ |
2225 | - } |
2226 | - need_join = true; |
2227 | - return need_join; /* true */ |
2228 | - } |
2229 | - void join() { |
2230 | - if (!need_join) { |
2231 | - return; |
2232 | - } |
2233 | - int e = 0; |
2234 | - if ((e = pthread_join(thr, 0)) != 0) { |
2235 | - fatal_abort("pthread_join"); |
2236 | - } |
2237 | - need_join = false; |
2238 | - } |
2239 | - private: |
2240 | - static void *thread_main(void *arg) { |
2241 | - thread_base *p = static_cast<thread_base *>(arg); |
2242 | - p->run(); |
2243 | - return 0; |
2244 | - } |
2245 | - private: |
2246 | - pthread_t thr; |
2247 | - bool need_join; |
2248 | - size_t stack_size; |
2249 | -}; |
2250 | - |
2251 | -struct hs_longrun_stat { |
2252 | - unsigned long long verify_error_count; |
2253 | - unsigned long long runtime_error_count; |
2254 | - unsigned long long unknown_count; |
2255 | - unsigned long long success_count; |
2256 | - hs_longrun_stat() |
2257 | - : verify_error_count(0), runtime_error_count(0), |
2258 | - unknown_count(0), success_count(0) { } |
2259 | - void add(const hs_longrun_stat& x) { |
2260 | - verify_error_count += x.verify_error_count; |
2261 | - runtime_error_count += x.runtime_error_count; |
2262 | - unknown_count += x.unknown_count; |
2263 | - success_count += x.success_count; |
2264 | - } |
2265 | -}; |
2266 | - |
2267 | -struct hs_longrun_thread_base : public thread_base { |
2268 | - struct arg_type { |
2269 | - int id; |
2270 | - std::string worker_type; |
2271 | - char op; |
2272 | - int lock_flag; |
2273 | - const hs_longrun_shared& sh; |
2274 | - arg_type(int id, const std::string& worker_type, char op, int lock_flag, |
2275 | - const hs_longrun_shared& sh) |
2276 | - : id(id), worker_type(worker_type), op(op), lock_flag(lock_flag), |
2277 | - sh(sh) { } |
2278 | - }; |
2279 | - arg_type arg; |
2280 | - hs_longrun_stat stat; |
2281 | - drand48_data randbuf; |
2282 | - unsigned int seed; |
2283 | - hs_longrun_thread_base(const arg_type& arg) |
2284 | - : arg(arg), seed(0) { |
2285 | - seed = time(0) + arg.id + 1; |
2286 | - srand48_r(seed, &randbuf); |
2287 | - } |
2288 | - virtual ~hs_longrun_thread_base() { } |
2289 | - virtual void run() = 0; |
2290 | - size_t rand_record() { |
2291 | - double v = 0; |
2292 | - drand48_r(&randbuf, &v); |
2293 | - const size_t sz = arg.sh.records.size(); |
2294 | - size_t r = size_t(v * sz); |
2295 | - if (r >= sz) { |
2296 | - r = 0; |
2297 | - } |
2298 | - return r; |
2299 | - } |
2300 | - int verify_update(const std::string& k, const std::string& v1, |
2301 | - const std::string& v2, const std::string& v3, record_value& rec, |
2302 | - uint32_t num_rows, bool cur_unknown_state); |
2303 | - int verify_read(const std::string& k, uint32_t num_rows, uint32_t num_flds, |
2304 | - const std::string rrec[4], record_value& rec); |
2305 | - int verify_readnolock(const std::string& k, uint32_t num_rows, |
2306 | - uint32_t num_flds, const std::string rrec[4]); |
2307 | -}; |
2308 | - |
2309 | -int |
2310 | -hs_longrun_thread_base::verify_update(const std::string& k, |
2311 | - const std::string& v1, const std::string& v2, const std::string& v3, |
2312 | - record_value& rec, uint32_t num_rows, bool cur_unknown_state) |
2313 | -{ |
2314 | - const bool op_success = num_rows == 1; |
2315 | - int ret = 0; |
2316 | - if (!rec.unknown_state) { |
2317 | - if (!rec.deleted && !op_success) { |
2318 | - ++stat.verify_error_count; |
2319 | - if (arg.sh.verbose > 0) { |
2320 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2321 | - "unexpected_update_failure\n", |
2322 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2323 | - } |
2324 | - ret = 1; |
2325 | - } else if (rec.deleted && op_success) { |
2326 | - ++stat.verify_error_count; |
2327 | - if (arg.sh.verbose > 0) { |
2328 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2329 | - "unexpected_update_success\n", |
2330 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2331 | - } |
2332 | - ret = 1; |
2333 | - } |
2334 | - } |
2335 | - if (op_success) { |
2336 | - rec.values.resize(4); |
2337 | - rec.values[0] = k; |
2338 | - rec.values[1] = v1; |
2339 | - rec.values[2] = v2; |
2340 | - rec.values[3] = v3; |
2341 | - if (ret == 0 && !rec.unknown_state) { |
2342 | - ++stat.success_count; |
2343 | - } |
2344 | - } |
2345 | - rec.unknown_state = cur_unknown_state; |
2346 | - if (arg.sh.verbose >= 100 && ret == 0) { |
2347 | - fprintf(stderr, "%s %s %s %s %s\n", arg.worker_type.c_str(), |
2348 | - k.c_str(), v1.c_str(), v2.c_str(), v3.c_str()); |
2349 | - } |
2350 | - return ret; |
2351 | -} |
2352 | - |
2353 | -int |
2354 | -hs_longrun_thread_base::verify_read(const std::string& k, |
2355 | - uint32_t num_rows, uint32_t num_flds, const std::string rrec[4], |
2356 | - record_value& rec) |
2357 | -{ |
2358 | - const bool op_success = num_rows != 0; |
2359 | - int ret = 0; |
2360 | - if (!rec.unknown_state) { |
2361 | - if (!rec.deleted && !op_success) { |
2362 | - ++stat.verify_error_count; |
2363 | - if (arg.sh.verbose > 0) { |
2364 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2365 | - "unexpected_read_failure\n", |
2366 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2367 | - } |
2368 | - ret = 1; |
2369 | - } else if (rec.deleted && op_success) { |
2370 | - ++stat.verify_error_count; |
2371 | - if (arg.sh.verbose > 0) { |
2372 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2373 | - "unexpected_read_success\n", |
2374 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2375 | - } |
2376 | - ret = 1; |
2377 | - } else if (num_flds != 4) { |
2378 | - ++stat.verify_error_count; |
2379 | - if (arg.sh.verbose > 0) { |
2380 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2381 | - "unexpected_read_fldnum %d\n", |
2382 | - arg.worker_type.c_str(), arg.id, k.c_str(), |
2383 | - static_cast<int>(num_flds)); |
2384 | - } |
2385 | - ret = 1; |
2386 | - } else if (rec.deleted) { |
2387 | - /* nothing to verify */ |
2388 | - } else { |
2389 | - int diff = 0; |
2390 | - for (size_t i = 0; i < 4; ++i) { |
2391 | - if (rec.values[i] == rrec[i]) { |
2392 | - /* ok */ |
2393 | - } else { |
2394 | - diff = 1; |
2395 | - } |
2396 | - } |
2397 | - if (diff) { |
2398 | - std::string mess; |
2399 | - for (size_t i = 0; i < 4; ++i) { |
2400 | - const std::string& expected = rec.values[i]; |
2401 | - const std::string& val = rrec[i]; |
2402 | - mess += " " + val + "/" + expected; |
2403 | - } |
2404 | - if (arg.sh.verbose > 0) { |
2405 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2406 | - "unexpected_read_value %s\n", |
2407 | - arg.worker_type.c_str(), arg.id, k.c_str(), mess.c_str()); |
2408 | - } |
2409 | - ret = 1; |
2410 | - } |
2411 | - } |
2412 | - } |
2413 | - if (arg.sh.verbose >= 100 && ret == 0) { |
2414 | - fprintf(stderr, "%s %s\n", arg.worker_type.c_str(), k.c_str()); |
2415 | - } |
2416 | - if (ret == 0 && !rec.unknown_state) { |
2417 | - ++stat.success_count; |
2418 | - } |
2419 | - return ret; |
2420 | -} |
2421 | - |
2422 | -int |
2423 | -hs_longrun_thread_base::verify_readnolock(const std::string& k, |
2424 | - uint32_t num_rows, uint32_t num_flds, const std::string rrec[4]) |
2425 | -{ |
2426 | - int ret = 0; |
2427 | - if (num_rows != 1 || num_flds != 4) { |
2428 | - ++stat.verify_error_count; |
2429 | - if (arg.sh.verbose > 0) { |
2430 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2431 | - "unexpected_read_failure\n", |
2432 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2433 | - } |
2434 | - ret = 1; |
2435 | - } |
2436 | - if (arg.sh.verbose >= 100 && ret == 0) { |
2437 | - fprintf(stderr, "%s -> %s %s %s %s %s\n", arg.worker_type.c_str(), |
2438 | - k.c_str(), rrec[0].c_str(), rrec[1].c_str(), rrec[2].c_str(), |
2439 | - rrec[3].c_str()); |
2440 | - } |
2441 | - if (ret == 0) { |
2442 | - ++stat.success_count; |
2443 | - } |
2444 | - return ret; |
2445 | -} |
2446 | - |
2447 | -struct hs_longrun_thread_hs : public hs_longrun_thread_base { |
2448 | - hs_longrun_thread_hs(const arg_type& arg) |
2449 | - : hs_longrun_thread_base(arg) { } |
2450 | - void run(); |
2451 | - int check_hs_error(const char *mess, record_value *rec); |
2452 | - int op_insert(record_value& rec); |
2453 | - int op_delete(record_value& rec); |
2454 | - int op_update(record_value& rec); |
2455 | - int op_read(record_value& rec); |
2456 | - int op_readnolock(int k); |
2457 | - hstcpcli_ptr cli; |
2458 | - socket_args sockargs; |
2459 | -}; |
2460 | - |
2461 | -struct lock_guard : noncopyable { |
2462 | - lock_guard(mutex& mtx) : mtx(mtx) { |
2463 | - mtx.lock(); |
2464 | - } |
2465 | - ~lock_guard() { |
2466 | - mtx.unlock(); |
2467 | - } |
2468 | - mutex& mtx; |
2469 | -}; |
2470 | - |
2471 | -string_ref |
2472 | -to_string_ref(const std::string& s) |
2473 | -{ |
2474 | - return string_ref(s.data(), s.size()); |
2475 | -} |
2476 | - |
2477 | -std::string |
2478 | -to_string(const string_ref& s) |
2479 | -{ |
2480 | - return std::string(s.begin(), s.size()); |
2481 | -} |
2482 | - |
2483 | -void |
2484 | -hs_longrun_thread_hs::run() |
2485 | -{ |
2486 | - config c = arg.sh.conf; |
2487 | - if (arg.op == 'R' || arg.op == 'N') { |
2488 | - c["port"] = to_stdstring(arg.sh.conf.get_int("hsport", 9998)); |
2489 | - } else { |
2490 | - c["port"] = to_stdstring(arg.sh.conf.get_int("hsport_wr", 9999)); |
2491 | - } |
2492 | - sockargs.set(c); |
2493 | - |
2494 | - while (arg.sh.running) { |
2495 | - if (cli.get() == 0 || !cli->stable_point()) { |
2496 | - cli = hstcpcli_i::create(sockargs); |
2497 | - if (check_hs_error("connect", 0) != 0) { |
2498 | - cli.reset(); |
2499 | - continue; |
2500 | - } |
2501 | - cli->request_buf_open_index(0, "hstestdb", "hstesttbl", "PRIMARY", |
2502 | - "k,v1,v2,v3", "k,v1,v2,v3"); |
2503 | - cli->request_send(); |
2504 | - if (check_hs_error("openindex_send", 0) != 0) { |
2505 | - cli.reset(); |
2506 | - continue; |
2507 | - } |
2508 | - size_t num_flds = 0; |
2509 | - cli->response_recv(num_flds); |
2510 | - if (check_hs_error("openindex_recv", 0) != 0) { |
2511 | - cli.reset(); |
2512 | - continue; |
2513 | - } |
2514 | - cli->response_buf_remove(); |
2515 | - } |
2516 | - const size_t rec_id = rand_record(); |
2517 | - if (arg.lock_flag) { |
2518 | - record_value& rec = *arg.sh.records[rec_id]; |
2519 | - lock_guard g(rec.lock); |
2520 | - int e = 0; |
2521 | - switch (arg.op) { |
2522 | - case 'I': |
2523 | - e = op_insert(rec); |
2524 | - break; |
2525 | - case 'D': |
2526 | - e = op_delete(rec); |
2527 | - break; |
2528 | - case 'U': |
2529 | - e = op_update(rec); |
2530 | - break; |
2531 | - case 'R': |
2532 | - e = op_read(rec); |
2533 | - break; |
2534 | - default: |
2535 | - break; |
2536 | - } |
2537 | - } else { |
2538 | - int e = 0; |
2539 | - switch (arg.op) { |
2540 | - case 'N': |
2541 | - e = op_readnolock(rec_id); |
2542 | - break; |
2543 | - default: |
2544 | - break; |
2545 | - } |
2546 | - } |
2547 | - } |
2548 | -} |
2549 | - |
2550 | -int |
2551 | -hs_longrun_thread_hs::op_insert(record_value& rec) |
2552 | -{ |
2553 | - const std::string k = rec.key; |
2554 | - const std::string v1 = "iv1_" + k + "_" + to_stdstring(arg.id); |
2555 | - const std::string v2 = "iv2_" + k + "_" + to_stdstring(arg.id); |
2556 | - const std::string v3 = "iv3_" + k + "_" + to_stdstring(arg.id); |
2557 | - const string_ref op_ref("+", 1); |
2558 | - const string_ref op_args[4] = { |
2559 | - to_string_ref(k), |
2560 | - to_string_ref(v1), |
2561 | - to_string_ref(v2), |
2562 | - to_string_ref(v3) |
2563 | - }; |
2564 | - cli->request_buf_exec_generic(0, op_ref, op_args, 4, 1, 0, |
2565 | - string_ref(), 0, 0, 0, 0); |
2566 | - cli->request_send(); |
2567 | - if (check_hs_error("op_insert_send", &rec) != 0) { return 1; } |
2568 | - size_t numflds = 0; |
2569 | - cli->response_recv(numflds); |
2570 | - if (arg.sh.verbose > 10) { |
2571 | - const string_ref *row = cli->get_next_row(); |
2572 | - fprintf(stderr, "HS op=+ errrcode=%d errmess=[%s]\n", cli->get_error_code(), |
2573 | - row ? to_string(row[0]).c_str() : ""); |
2574 | - } |
2575 | - const bool op_success = cli->get_error_code() == 0; |
2576 | - int ret = 0; |
2577 | - if (!rec.unknown_state) { |
2578 | - if (rec.deleted && !op_success) { |
2579 | - ++stat.verify_error_count; |
2580 | - if (arg.sh.verbose > 0) { |
2581 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2582 | - "unexpected_insert_failure\n", |
2583 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2584 | - } |
2585 | - ret = 1; |
2586 | - } else if (!rec.deleted && op_success) { |
2587 | - ++stat.verify_error_count; |
2588 | - if (arg.sh.verbose > 0) { |
2589 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2590 | - "unexpected_insert_success\n", |
2591 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2592 | - } |
2593 | - ret = 1; |
2594 | - } |
2595 | - } else { |
2596 | - ++stat.unknown_count; |
2597 | - } |
2598 | - if (op_success) { |
2599 | - rec.values.resize(4); |
2600 | - rec.values[0] = k; |
2601 | - rec.values[1] = v1; |
2602 | - rec.values[2] = v2; |
2603 | - rec.values[3] = v3; |
2604 | - rec.deleted = false; |
2605 | - if (arg.sh.verbose >= 100 && ret == 0) { |
2606 | - fprintf(stderr, "HS_INSERT %s %s %s %s\n", k.c_str(), v1.c_str(), |
2607 | - v2.c_str(), v3.c_str()); |
2608 | - } |
2609 | - if (ret == 0 && !rec.unknown_state) { |
2610 | - ++stat.success_count; |
2611 | - } |
2612 | - rec.unknown_state = false; |
2613 | - } |
2614 | - cli->response_buf_remove(); |
2615 | - return ret; |
2616 | -} |
2617 | - |
2618 | -int |
2619 | -hs_longrun_thread_hs::op_delete(record_value& rec) |
2620 | -{ |
2621 | - const std::string k = rec.key; |
2622 | - const string_ref op_ref("=", 1); |
2623 | - const string_ref op_args[1] = { |
2624 | - to_string_ref(k), |
2625 | - }; |
2626 | - const string_ref modop_ref("D", 1); |
2627 | - cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
2628 | - modop_ref, 0, 0, 0, 0); |
2629 | - cli->request_send(); |
2630 | - if (check_hs_error("op_delete_send", &rec) != 0) { return 1; } |
2631 | - size_t numflds = 0; |
2632 | - cli->response_recv(numflds); |
2633 | - if (check_hs_error("op_delete_recv", &rec) != 0) { return 1; } |
2634 | - const string_ref *row = cli->get_next_row(); |
2635 | - const bool op_success = (numflds > 0 && row != 0 && |
2636 | - to_string(row[0]) == "1"); |
2637 | - int ret = 0; |
2638 | - if (!rec.unknown_state) { |
2639 | - if (!rec.deleted && !op_success) { |
2640 | - ++stat.verify_error_count; |
2641 | - if (arg.sh.verbose > 0) { |
2642 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2643 | - "unexpected_delete_failure\n", |
2644 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2645 | - } |
2646 | - ret = 1; |
2647 | - } else if (rec.deleted && op_success) { |
2648 | - ++stat.verify_error_count; |
2649 | - if (arg.sh.verbose > 0) { |
2650 | - fprintf(stderr, "VERIFY_ERROR: %s wid=%d k=%s " |
2651 | - "unexpected_delete_success\n", |
2652 | - arg.worker_type.c_str(), arg.id, k.c_str()); |
2653 | - } |
2654 | - ret = 1; |
2655 | - } |
2656 | - } |
2657 | - cli->response_buf_remove(); |
2658 | - if (op_success) { |
2659 | - rec.deleted = true; |
2660 | - if (ret == 0 && !rec.unknown_state) { |
2661 | - ++stat.success_count; |
2662 | - } |
2663 | - rec.unknown_state = false; |
2664 | - } |
2665 | - if (arg.sh.verbose >= 100 && ret == 0) { |
2666 | - fprintf(stderr, "HS_DELETE %s\n", k.c_str()); |
2667 | - } |
2668 | - return ret; |
2669 | -} |
2670 | - |
2671 | -int |
2672 | -hs_longrun_thread_hs::op_update(record_value& rec) |
2673 | -{ |
2674 | - const std::string k = rec.key; |
2675 | - const std::string v1 = "uv1_" + k + "_" + to_stdstring(arg.id); |
2676 | - const std::string v2 = "uv2_" + k + "_" + to_stdstring(arg.id); |
2677 | - const std::string v3 = "uv3_" + k + "_" + to_stdstring(arg.id); |
2678 | - const string_ref op_ref("=", 1); |
2679 | - const string_ref op_args[1] = { |
2680 | - to_string_ref(k), |
2681 | - }; |
2682 | - const string_ref modop_ref("U", 1); |
2683 | - const string_ref modop_args[4] = { |
2684 | - to_string_ref(k), |
2685 | - to_string_ref(v1), |
2686 | - to_string_ref(v2), |
2687 | - to_string_ref(v3) |
2688 | - }; |
2689 | - cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
2690 | - modop_ref, modop_args, 4, 0, 0); |
2691 | - cli->request_send(); |
2692 | - if (check_hs_error("op_update_send", &rec) != 0) { return 1; } |
2693 | - size_t numflds = 0; |
2694 | - cli->response_recv(numflds); |
2695 | - if (check_hs_error("op_update_recv", &rec) != 0) { return 1; } |
2696 | - const string_ref *row = cli->get_next_row(); |
2697 | - uint32_t num_rows = row |
2698 | - ? atoi_uint32_nocheck(row[0].begin(), row[0].end()) : 0; |
2699 | - cli->response_buf_remove(); |
2700 | - const bool cur_unknown_state = (num_rows == 1); |
2701 | - return verify_update(k, v1, v2, v3, rec, num_rows, cur_unknown_state); |
2702 | -} |
2703 | - |
2704 | -int |
2705 | -hs_longrun_thread_hs::op_read(record_value& rec) |
2706 | -{ |
2707 | - const std::string k = rec.key; |
2708 | - const string_ref op_ref("=", 1); |
2709 | - const string_ref op_args[1] = { |
2710 | - to_string_ref(k), |
2711 | - }; |
2712 | - cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
2713 | - string_ref(), 0, 0, 0, 0); |
2714 | - cli->request_send(); |
2715 | - if (check_hs_error("op_read_send", 0) != 0) { return 1; } |
2716 | - size_t num_flds = 0; |
2717 | - size_t num_rows = 0; |
2718 | - cli->response_recv(num_flds); |
2719 | - if (check_hs_error("op_read_recv", 0) != 0) { return 1; } |
2720 | - const string_ref *row = cli->get_next_row(); |
2721 | - std::string rrec[4]; |
2722 | - if (row != 0 && num_flds == 4) { |
2723 | - for (int i = 0; i < 4; ++i) { |
2724 | - rrec[i] = to_string(row[i]); |
2725 | - } |
2726 | - ++num_rows; |
2727 | - } |
2728 | - row = cli->get_next_row(); |
2729 | - if (row != 0) { |
2730 | - ++num_rows; |
2731 | - } |
2732 | - cli->response_buf_remove(); |
2733 | - return verify_read(k, num_rows, num_flds, rrec, rec); |
2734 | -} |
2735 | - |
2736 | -int |
2737 | -hs_longrun_thread_hs::op_readnolock(int key) |
2738 | -{ |
2739 | - const std::string k = to_stdstring(key); |
2740 | - const string_ref op_ref("=", 1); |
2741 | - const string_ref op_args[1] = { |
2742 | - to_string_ref(k), |
2743 | - }; |
2744 | - cli->request_buf_exec_generic(0, op_ref, op_args, 1, 1, 0, |
2745 | - string_ref(), 0, 0, 0, 0); |
2746 | - cli->request_send(); |
2747 | - if (check_hs_error("op_read_send", 0) != 0) { return 1; } |
2748 | - size_t num_flds = 0; |
2749 | - size_t num_rows = 0; |
2750 | - cli->response_recv(num_flds); |
2751 | - if (check_hs_error("op_read_recv", 0) != 0) { return 1; } |
2752 | - const string_ref *row = cli->get_next_row(); |
2753 | - std::string rrec[4]; |
2754 | - if (row != 0 && num_flds == 4) { |
2755 | - for (int i = 0; i < 4; ++i) { |
2756 | - rrec[i] = to_string(row[i]); |
2757 | - } |
2758 | - ++num_rows; |
2759 | - } |
2760 | - row = cli->get_next_row(); |
2761 | - if (row != 0) { |
2762 | - ++num_rows; |
2763 | - } |
2764 | - cli->response_buf_remove(); |
2765 | - return verify_readnolock(k, num_rows, num_flds, rrec); |
2766 | -} |
2767 | - |
2768 | -int |
2769 | -hs_longrun_thread_hs::check_hs_error(const char *mess, record_value *rec) |
2770 | -{ |
2771 | - const int err = cli->get_error_code(); |
2772 | - if (err == 0) { |
2773 | - return 0; |
2774 | - } |
2775 | - ++stat.runtime_error_count; |
2776 | - if (arg.sh.verbose > 0) { |
2777 | - const std::string estr = cli->get_error(); |
2778 | - fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d %s: %d %s\n", |
2779 | - arg.op, arg.id, mess, err, estr.c_str()); |
2780 | - } |
2781 | - if (rec) { |
2782 | - rec->unknown_state = true; |
2783 | - } |
2784 | - return 1; |
2785 | -} |
2786 | - |
2787 | -struct hs_longrun_thread_my : public hs_longrun_thread_base { |
2788 | - hs_longrun_thread_my(const arg_type& arg) |
2789 | - : hs_longrun_thread_base(arg), connected(false) { } |
2790 | - void run(); |
2791 | - void show_mysql_error(const char *mess, record_value *rec); |
2792 | - int op_insert(record_value& rec); |
2793 | - int op_delete(record_value& rec); |
2794 | - int op_update(record_value& rec); |
2795 | - int op_delins(record_value& rec); |
2796 | - int op_read(record_value& rec); |
2797 | - auto_mysql db; |
2798 | - bool connected; |
2799 | -}; |
2800 | - |
2801 | -void |
2802 | -hs_longrun_thread_my::run() |
2803 | -{ |
2804 | - const std::string mysql_host = arg.sh.conf.get_str("host", "localhost"); |
2805 | - const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root"); |
2806 | - const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", ""); |
2807 | - const std::string mysql_dbname = "hstestdb"; |
2808 | - |
2809 | - while (arg.sh.running) { |
2810 | - if (!connected) { |
2811 | - if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(), |
2812 | - mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) { |
2813 | - show_mysql_error("mysql_real_connect", 0); |
2814 | - continue; |
2815 | - } |
2816 | - } |
2817 | - connected = true; |
2818 | - const size_t rec_id = rand_record(); |
2819 | - record_value& rec = *arg.sh.records[rec_id]; |
2820 | - lock_guard g(rec.lock); |
2821 | - int e = 0; |
2822 | - switch (arg.op) { |
2823 | - #if 0 |
2824 | - case 'I': |
2825 | - e = op_insert(rec); |
2826 | - break; |
2827 | - case 'D': |
2828 | - e = op_delete(rec); |
2829 | - break; |
2830 | - case 'U': |
2831 | - e = op_update(rec); |
2832 | - break; |
2833 | - #endif |
2834 | - case 'T': |
2835 | - e = op_delins(rec); |
2836 | - break; |
2837 | - case 'R': |
2838 | - e = op_read(rec); |
2839 | - break; |
2840 | - default: |
2841 | - break; |
2842 | - } |
2843 | - } |
2844 | -} |
2845 | - |
2846 | -int |
2847 | -hs_longrun_thread_my::op_delins(record_value& rec) |
2848 | -{ |
2849 | - const std::string k = rec.key; |
2850 | - const std::string v1 = "div1_" + k + "_" + to_stdstring(arg.id); |
2851 | - const std::string v2 = "div2_" + k + "_" + to_stdstring(arg.id); |
2852 | - const std::string v3 = "div3_" + k + "_" + to_stdstring(arg.id); |
2853 | - int success = 0; |
2854 | - bool cur_unknown_state = false; |
2855 | - do { |
2856 | - char query[1024]; |
2857 | - #if 1 |
2858 | - if (mysql_query(db, "begin") != 0) { |
2859 | - if (arg.sh.verbose >= 20) { |
2860 | - fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "begin"); |
2861 | - } |
2862 | - break; |
2863 | - } |
2864 | - #endif |
2865 | - cur_unknown_state = true; |
2866 | - snprintf(query, 1024, |
2867 | - "delete from hstesttbl where k = '%s'", k.c_str()); |
2868 | - if (mysql_query(db, query) != 0) { |
2869 | - if (arg.sh.verbose >= 20) { |
2870 | - fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
2871 | - } |
2872 | - break; |
2873 | - } |
2874 | - if (mysql_affected_rows(db) != 1) { |
2875 | - if (arg.sh.verbose >= 20) { |
2876 | - fprintf(stderr, "mysql: notfound: [%s]\n", query); |
2877 | - } |
2878 | - break; |
2879 | - } |
2880 | - snprintf(query, 1024, |
2881 | - "insert into hstesttbl values ('%s', '%s', '%s', '%s')", |
2882 | - k.c_str(), v1.c_str(), v2.c_str(), v3.c_str()); |
2883 | - if (mysql_query(db, query) != 0) { |
2884 | - if (arg.sh.verbose >= 20) { |
2885 | - fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
2886 | - } |
2887 | - break; |
2888 | - } |
2889 | - #if 1 |
2890 | - if (mysql_query(db, "commit") != 0) { |
2891 | - if (arg.sh.verbose >= 20) { |
2892 | - fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), "commit"); |
2893 | - } |
2894 | - break; |
2895 | - } |
2896 | - #endif |
2897 | - success = true; |
2898 | - cur_unknown_state = false; |
2899 | - } while (false); |
2900 | - return verify_update(k, v1, v2, v3, rec, (success != 0), cur_unknown_state); |
2901 | -} |
2902 | - |
2903 | -int |
2904 | -hs_longrun_thread_my::op_read(record_value& rec) |
2905 | -{ |
2906 | - const std::string k = rec.key; |
2907 | - char query[1024] = { 0 }; |
2908 | - const int len = snprintf(query, 1024, |
2909 | - "select k,v1,v2,v3 from hstesttbl where k='%s'", k.c_str()); |
2910 | - const int r = mysql_real_query(db, query, len > 0 ? len : 0); |
2911 | - if (r != 0) { |
2912 | - show_mysql_error(query, 0); |
2913 | - return 1; |
2914 | - } |
2915 | - MYSQL_ROW row = 0; |
2916 | - unsigned long *lengths = 0; |
2917 | - unsigned int num_rows = 0; |
2918 | - unsigned int num_flds = 0; |
2919 | - auto_mysql_res res(db); |
2920 | - std::string rrec[4]; |
2921 | - if (res != 0) { |
2922 | - num_flds = mysql_num_fields(res); |
2923 | - row = mysql_fetch_row(res); |
2924 | - if (row != 0) { |
2925 | - lengths = mysql_fetch_lengths(res); |
2926 | - if (num_flds == 4) { |
2927 | - for (int i = 0; i < 4; ++i) { |
2928 | - rrec[i] = std::string(row[i], lengths[i]); |
2929 | - } |
2930 | - } |
2931 | - ++num_rows; |
2932 | - row = mysql_fetch_row(res); |
2933 | - if (row != 0) { |
2934 | - ++num_rows; |
2935 | - } |
2936 | - } |
2937 | - } |
2938 | - return verify_read(k, num_rows, num_flds, rrec, rec); |
2939 | -} |
2940 | - |
2941 | -void |
2942 | -hs_longrun_thread_my::show_mysql_error(const char *mess, record_value *rec) |
2943 | -{ |
2944 | - ++stat.runtime_error_count; |
2945 | - if (arg.sh.verbose > 0) { |
2946 | - fprintf(stderr, "RUNTIME_ERROR: op=%c wid=%d [%s]: %s\n", |
2947 | - arg.op, arg.id, mess, mysql_error(db)); |
2948 | - } |
2949 | - if (rec) { |
2950 | - rec->unknown_state = true; |
2951 | - } |
2952 | - db.reset(); |
2953 | - connected = false; |
2954 | -} |
2955 | - |
2956 | -void |
2957 | -mysql_do(MYSQL *db, const char *query) |
2958 | -{ |
2959 | - if (mysql_real_query(db, query, strlen(query)) != 0) { |
2960 | - fprintf(stderr, "mysql: e=[%s] q=[%s]\n", mysql_error(db), query); |
2961 | - fatal_exit("mysql_do"); |
2962 | - } |
2963 | -} |
2964 | - |
2965 | -void |
2966 | -hs_longrun_init_table(const config& conf, int num_prepare, |
2967 | - hs_longrun_shared& shared) |
2968 | -{ |
2969 | - const std::string mysql_host = conf.get_str("host", "localhost"); |
2970 | - const std::string mysql_user = conf.get_str("mysqluser", "root"); |
2971 | - const std::string mysql_passwd = conf.get_str("mysqlpass", ""); |
2972 | - const std::string mysql_dbname = ""; |
2973 | - auto_mysql db; |
2974 | - if (!mysql_real_connect(db, mysql_host.c_str(), mysql_user.c_str(), |
2975 | - mysql_passwd.c_str(), mysql_dbname.c_str(), mysql_port, 0, 0)) { |
2976 | - fprintf(stderr, "mysql: error=[%s]\n", mysql_error(db)); |
2977 | - fatal_exit("hs_longrun_init_table"); |
2978 | - } |
2979 | - mysql_do(db, "drop database if exists hstestdb"); |
2980 | - mysql_do(db, "create database hstestdb"); |
2981 | - mysql_do(db, "use hstestdb"); |
2982 | - mysql_do(db, |
2983 | - "create table hstesttbl (" |
2984 | - "k int primary key," |
2985 | - "v1 varchar(32) not null," |
2986 | - "v2 varchar(32) not null," |
2987 | - "v3 varchar(32) not null" |
2988 | - ") character set utf8 collate utf8_bin engine = innodb"); |
2989 | - for (int i = 0; i < num_prepare; ++i) { |
2990 | - const std::string i_str = to_stdstring(i); |
2991 | - const std::string v1 = "pv1_" + i_str; |
2992 | - const std::string v2 = "pv2_" + i_str; |
2993 | - const std::string v3 = "pv3_" + i_str; |
2994 | - char buf[1024]; |
2995 | - snprintf(buf, 1024, "insert into hstesttbl(k, v1, v2, v3) values" |
2996 | - "(%d, '%s', '%s', '%s')", i, v1.c_str(), v2.c_str(), v3.c_str()); |
2997 | - mysql_do(db, buf); |
2998 | - record_value *rec = shared.records[i]; |
2999 | - rec->key = i_str; |
3000 | - rec->values.resize(4); |
3001 | - rec->values[0] = i_str; |
3002 | - rec->values[1] = v1; |
3003 | - rec->values[2] = v2; |
3004 | - rec->values[3] = v3; |
3005 | - rec->deleted = false; |
3006 | - } |
3007 | -} |
3008 | - |
3009 | -int |
3010 | -hs_longrun_main(int argc, char **argv) |
3011 | -{ |
3012 | - hs_longrun_shared shared; |
3013 | - parse_args(argc, argv, shared.conf); |
3014 | - shared.conf["host"] = shared.conf.get_str("host", "localhost"); |
3015 | - shared.verbose = shared.conf.get_int("verbose", 1); |
3016 | - const int table_size = shared.conf.get_int("table_size", 10000); |
3017 | - for (int i = 0; i < table_size; ++i) { |
3018 | - std::auto_ptr<record_value> rec(new record_value()); |
3019 | - rec->key = to_stdstring(i); |
3020 | - shared.records.push_back_ptr(rec); |
3021 | - } |
3022 | - mysql_library_init(0, 0, 0); |
3023 | - const int duration = shared.conf.get_int("duration", 10); |
3024 | - const int num_hsinsert = shared.conf.get_int("num_hsinsert", 10); |
3025 | - const int num_hsdelete = shared.conf.get_int("num_hsdelete", 10); |
3026 | - const int num_hsupdate = shared.conf.get_int("num_hsupdate", 10); |
3027 | - const int num_hsread = shared.conf.get_int("num_hsread", 10); |
3028 | - const int num_myread = shared.conf.get_int("num_myread", 10); |
3029 | - const int num_mydelins = shared.conf.get_int("num_mydelins", 10); |
3030 | - int num_hsreadnolock = shared.conf.get_int("num_hsreadnolock", 10); |
3031 | - const bool always_filled = (num_hsinsert == 0 && num_hsdelete == 0); |
3032 | - if (!always_filled) { |
3033 | - num_hsreadnolock = 0; |
3034 | - } |
3035 | - hs_longrun_init_table(shared.conf, always_filled ? table_size : 0, |
3036 | - shared); |
3037 | - /* create worker threads */ |
3038 | - static const struct thrtmpl_type { |
3039 | - const char *type; char op; int num; int hs; int lock; |
3040 | - } thrtmpl[] = { |
3041 | - { "hsinsert", 'I', num_hsinsert, 1, 1 }, |
3042 | - { "hsdelete", 'D', num_hsdelete, 1, 1 }, |
3043 | - { "hsupdate", 'U', num_hsupdate, 1, 1 }, |
3044 | - { "hsread", 'R', num_hsread, 1, 1 }, |
3045 | - { "hsreadnolock", 'N', num_hsreadnolock, 1, 0 }, |
3046 | - { "myread", 'R', num_myread, 0, 1 }, |
3047 | - { "mydelins", 'T', num_mydelins, 0, 1 }, |
3048 | - }; |
3049 | - typedef auto_ptrcontainer< std::vector<hs_longrun_thread_base *> > thrs_type; |
3050 | - thrs_type thrs; |
3051 | - for (size_t i = 0; i < sizeof(thrtmpl)/sizeof(thrtmpl[0]); ++i) { |
3052 | - const thrtmpl_type& e = thrtmpl[i]; |
3053 | - for (int j = 0; j < e.num; ++j) { |
3054 | - int id = thrs.size(); |
3055 | - const hs_longrun_thread_hs::arg_type arg(id, e.type, e.op, e.lock, |
3056 | - shared); |
3057 | - std::auto_ptr<hs_longrun_thread_base> thr; |
3058 | - if (e.hs) { |
3059 | - thr.reset(new hs_longrun_thread_hs(arg)); |
3060 | - } else { |
3061 | - thr.reset(new hs_longrun_thread_my(arg)); |
3062 | - } |
3063 | - thrs.push_back_ptr(thr); |
3064 | - } |
3065 | - } |
3066 | - shared.num_threads = thrs.size(); |
3067 | - /* start threads */ |
3068 | - fprintf(stderr, "START\n"); |
3069 | - shared.running = 1; |
3070 | - for (size_t i = 0; i < thrs.size(); ++i) { |
3071 | - thrs[i]->start(); |
3072 | - } |
3073 | - /* wait */ |
3074 | - sleep(duration); |
3075 | - /* stop thread */ |
3076 | - shared.running = 0; |
3077 | - for (size_t i = 0; i < thrs.size(); ++i) { |
3078 | - thrs[i]->join(); |
3079 | - } |
3080 | - fprintf(stderr, "DONE\n"); |
3081 | - /* summary */ |
3082 | - typedef std::map<std::string, hs_longrun_stat> stat_map; |
3083 | - stat_map sm; |
3084 | - for (size_t i = 0; i < thrs.size(); ++i) { |
3085 | - hs_longrun_thread_base *const thr = thrs[i]; |
3086 | - const std::string wt = thr->arg.worker_type; |
3087 | - hs_longrun_stat& v = sm[wt]; |
3088 | - v.add(thr->stat); |
3089 | - } |
3090 | - hs_longrun_stat total; |
3091 | - for (stat_map::const_iterator i = sm.begin(); i != sm.end(); ++i) { |
3092 | - if (i->second.verify_error_count != 0) { |
3093 | - fprintf(stderr, "%s verify_error %llu\n", i->first.c_str(), |
3094 | - i->second.verify_error_count); |
3095 | - } |
3096 | - if (i->second.runtime_error_count) { |
3097 | - fprintf(stderr, "%s runtime_error %llu\n", i->first.c_str(), |
3098 | - i->second.runtime_error_count); |
3099 | - } |
3100 | - if (i->second.unknown_count) { |
3101 | - fprintf(stderr, "%s unknown %llu\n", i->first.c_str(), |
3102 | - i->second.unknown_count); |
3103 | - } |
3104 | - fprintf(stderr, "%s success %llu\n", i->first.c_str(), |
3105 | - i->second.success_count); |
3106 | - total.add(i->second); |
3107 | - } |
3108 | - if (total.verify_error_count != 0) { |
3109 | - fprintf(stderr, "TOTAL verify_error %llu\n", total.verify_error_count); |
3110 | - } |
3111 | - if (total.runtime_error_count != 0) { |
3112 | - fprintf(stderr, "TOTAL runtime_error %llu\n", total.runtime_error_count); |
3113 | - } |
3114 | - if (total.unknown_count != 0) { |
3115 | - fprintf(stderr, "TOTAL unknown %llu\n", total.unknown_count); |
3116 | - } |
3117 | - fprintf(stderr, "TOTAL success %llu\n", total.success_count); |
3118 | - mysql_library_end(); |
3119 | - return 0; |
3120 | -} |
3121 | - |
3122 | -}; |
3123 | - |
3124 | -int |
3125 | -main(int argc, char **argv) |
3126 | -{ |
3127 | - return dena::hs_longrun_main(argc, argv); |
3128 | -} |
3129 | - |
3130 | |
3131 | === added file 'HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl' |
3132 | --- HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl 1970-01-01 00:00:00 +0000 |
3133 | +++ HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl 2012-06-25 04:42:22 +0000 |
3134 | @@ -0,0 +1,224 @@ |
3135 | +#!/usr/bin/perl |
3136 | + |
3137 | +use strict; |
3138 | +use warnings; |
3139 | +use DB::HandlerSocket::Pool; |
3140 | +use DBI; |
3141 | + |
3142 | +my %conf = (); |
3143 | +for my $i (@ARGV) { |
3144 | + my ($k, $v) = split(/=/, $i); |
3145 | + $conf{$k} = $v; |
3146 | +} |
3147 | + |
3148 | +my $verbose = get_conf("verbose", 0); |
3149 | +my $actions_str = get_conf("actions", |
3150 | + "create,insert,verify,verify2,verify3,verify4,clean"); |
3151 | +my $tablesize = get_conf("tablesize", 1000); |
3152 | +my $db = get_conf("db", "hstestdb"); |
3153 | +my $table = get_conf("table", "testtbl"); |
3154 | +my $table_schema = get_conf("table_schema", undef); |
3155 | +my $engine = get_conf("engine", "innodb"); |
3156 | +my $host = get_conf("host", "localhost"); |
3157 | +my $mysqlport = get_conf("mysqlport", 3306); |
3158 | +my $hsport_rd = get_conf("hsport_rd", 9998); |
3159 | +my $hsport_wr = get_conf("hsport_wr", 9999); |
3160 | +my $loop = get_conf("loop", 10000); |
3161 | +my $op = get_conf("op", "="); |
3162 | +my $ssps = get_conf("ssps", 0); |
3163 | +my $num_moreflds = get_conf("moreflds", 0); |
3164 | +my $moreflds_prefix = get_conf("moreflds_prefix", "f"); |
3165 | +my $mysql_user = 'root'; |
3166 | +my $mysql_password = ''; |
3167 | + |
3168 | +my $dsn = "DBI:mysql:database=;host=$host;port=$mysqlport" |
3169 | + . ";mysql_server_prepare=$ssps"; |
3170 | +my $dbh = DBI->connect($dsn, $mysql_user, $mysql_password, |
3171 | + { RaiseError => 1 }); |
3172 | +my $hsargs = { 'host' => $host, 'port' => $hsport_rd }; |
3173 | +my $hspool = new DB::HandlerSocket::Pool({ |
3174 | + hostmap => { |
3175 | + "$db.$table" => { |
3176 | + host => $host, |
3177 | + port => $hsport_rd, |
3178 | + }, |
3179 | + }, |
3180 | + resolve => undef, |
3181 | + error => undef, |
3182 | +}); |
3183 | +$table_schema = "(k int primary key, fc30 varchar(30), ft text)" |
3184 | + if (!defined($table_schema)); |
3185 | + |
3186 | +my @actions = split(/,/, $actions_str); |
3187 | +for my $action (@actions) { |
3188 | + print "ACTION: $action\n"; |
3189 | + eval "hstest_$action()"; |
3190 | + if ($@) { |
3191 | + die $@; |
3192 | + } |
3193 | + print "ACTION: $action DONE\n"; |
3194 | +} |
3195 | + |
3196 | +sub get_conf { |
3197 | + my ($key, $def) = @_; |
3198 | + my $val = $conf{$key}; |
3199 | + if ($val) { |
3200 | + print "$key=$val\n"; |
3201 | + } else { |
3202 | + $val = $def; |
3203 | + my $defstr = $def || "(undef)"; |
3204 | + print "$key=$defstr(default)\n"; |
3205 | + } |
3206 | + return $val; |
3207 | +} |
3208 | + |
3209 | +sub hstest_create { |
3210 | + $dbh->do("drop database if exists $db"); |
3211 | + $dbh->do("create database $db"); |
3212 | + $dbh->do("use $db"); |
3213 | + $dbh->do("create table $table $table_schema engine=$engine"); |
3214 | +} |
3215 | + |
3216 | +sub hstest_dump { |
3217 | + $dbh->do("use $db"); |
3218 | + my $sth = $dbh->prepare("select * from $table"); |
3219 | + $sth->execute(); |
3220 | + my $arr = $sth->fetchall_arrayref(); |
3221 | + for my $rec (@$arr) { |
3222 | + print "REC:"; |
3223 | + for my $row (@$rec) { |
3224 | + print " $row"; |
3225 | + } |
3226 | + print "\n"; |
3227 | + } |
3228 | +} |
3229 | + |
3230 | +sub hstest_insert { |
3231 | + $dbh->do("use $db"); |
3232 | + my $sth = $dbh->prepare("insert into $table values (?, ?, ?)"); |
3233 | + for (my $k = 0; $k < $tablesize; ++$k) { |
3234 | + my $fc30 = "fc30_$k"; |
3235 | + my $ft = "ft_$k"; |
3236 | + $sth->execute($k, $fc30, $ft); |
3237 | + } |
3238 | +} |
3239 | + |
3240 | +sub hstest_verify { |
3241 | + $dbh->do("use $db"); |
3242 | + my $sth = $dbh->prepare("select * from $table order by k"); |
3243 | + $sth->execute(); |
3244 | + my $arr = $sth->fetchall_arrayref(); |
3245 | + my $hsres = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3246 | + ">=", [ 0 ], $tablesize, 0); |
3247 | + for (my $i = 0; $i < $tablesize; ++$i) { |
3248 | + my $rec = $arr->[$i]; |
3249 | + my $differ = 0; |
3250 | + print "REC:" if $verbose; |
3251 | + for (my $j = 0; $j < 3; ++$j) { |
3252 | + my $fld = $rec->[$j]; |
3253 | + my $hsidx = $i * 3 + $j; |
3254 | + my $hsfld = $hsres->[$hsidx]; |
3255 | + if ($hsfld ne $fld) { |
3256 | + $differ = 1; |
3257 | + } |
3258 | + if ($differ) { |
3259 | + print " $fld:$hsfld" if $verbose; |
3260 | + } else { |
3261 | + print " $hsfld" if $verbose; |
3262 | + } |
3263 | + } |
3264 | + print "\n" if $verbose; |
3265 | + if ($differ) { |
3266 | + die "verification failed"; |
3267 | + } |
3268 | + } |
3269 | +} |
3270 | + |
3271 | +sub hstest_verify2 { |
3272 | + $dbh->do("use $db"); |
3273 | + my $sth = $dbh->prepare("select * from $table order by k"); |
3274 | + $sth->execute(); |
3275 | + my $arr = $sth->fetchall_arrayref(); |
3276 | + my $hsresa = $hspool->index_find_multi($db, $table, "PRIMARY", |
3277 | + "k,fc30,ft", [ [ -1, ">=", [ 0 ], $tablesize, 0 ] ]); |
3278 | + my $hsres = $hsresa->[0]; |
3279 | + for (my $i = 0; $i < $tablesize; ++$i) { |
3280 | + my $rec = $arr->[$i]; |
3281 | + my $differ = 0; |
3282 | + print "REC:" if $verbose; |
3283 | + for (my $j = 0; $j < 3; ++$j) { |
3284 | + my $fld = $rec->[$j]; |
3285 | + my $hsidx = $i * 3 + $j; |
3286 | + my $hsfld = $hsres->[$hsidx]; |
3287 | + if ($hsfld ne $fld) { |
3288 | + $differ = 1; |
3289 | + } |
3290 | + if ($differ) { |
3291 | + print " $fld:$hsfld" if $verbose; |
3292 | + } else { |
3293 | + print " $hsfld" if $verbose; |
3294 | + } |
3295 | + } |
3296 | + print "\n" if $verbose; |
3297 | + if ($differ) { |
3298 | + die "verification failed"; |
3299 | + } |
3300 | + } |
3301 | +} |
3302 | + |
3303 | +sub hashref_to_str { |
3304 | + my $href = $_[0]; |
3305 | + my $r = ''; |
3306 | + for my $k (sort keys %$href) { |
3307 | + my $v = $href->{$k}; |
3308 | + $r .= "($k=>$v)"; |
3309 | + } |
3310 | + return $r; |
3311 | +} |
3312 | + |
3313 | +sub hstest_verify3 { |
3314 | + $dbh->do("use $db"); |
3315 | + my $sth = $dbh->prepare("select * from $table order by k"); |
3316 | + $sth->execute(); |
3317 | + my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3318 | + ">=", [ 0 ], $tablesize, 0); |
3319 | + my $hsres = DB::HandlerSocket::Pool::result_single_to_hasharr( |
3320 | + [ 'k', 'fc30', 'ft' ], $hsres_t); |
3321 | + for (my $i = 0; $i < $tablesize; ++$i) { |
3322 | + my $mystr = hashref_to_str($sth->fetchrow_hashref()); |
3323 | + my $hsstr = hashref_to_str($hsres->[$i]); |
3324 | + if ($mystr ne $hsstr) { |
3325 | + print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose; |
3326 | + die "verification failed"; |
3327 | + } else { |
3328 | + print "OK $hsstr\n" if $verbose; |
3329 | + } |
3330 | + } |
3331 | +} |
3332 | + |
3333 | +sub hstest_verify4 { |
3334 | + $dbh->do("use $db"); |
3335 | + my $sth = $dbh->prepare("select * from $table order by k"); |
3336 | + $sth->execute(); |
3337 | + my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3338 | + ">=", [ 0 ], $tablesize, 0); |
3339 | + my $hsres = DB::HandlerSocket::Pool::result_single_to_hashhash( |
3340 | + [ 'k', 'fc30', 'ft' ], 'k', $hsres_t); |
3341 | + my $rechash = $sth->fetchall_hashref('k'); |
3342 | + while (my ($k, $href) = each (%$rechash)) { |
3343 | + my $mystr = hashref_to_str($href); |
3344 | + my $hsstr = hashref_to_str($hsres->{$k}); |
3345 | + if ($mystr ne $hsstr) { |
3346 | + print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose; |
3347 | + die "verification failed"; |
3348 | + } else { |
3349 | + print "OK $hsstr\n" if $verbose; |
3350 | + } |
3351 | + } |
3352 | +} |
3353 | + |
3354 | +sub hstest_clean { |
3355 | + $hspool->clear_pool(); |
3356 | + $dbh->do("drop database if exists $db"); |
3357 | +} |
3358 | + |
3359 | |
3360 | === removed file 'HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl' |
3361 | --- HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl 2011-01-10 13:39:35 +0000 |
3362 | +++ HandlerSocket-Plugin-for-MySQL/client/hspool_test.pl 1970-01-01 00:00:00 +0000 |
3363 | @@ -1,224 +0,0 @@ |
3364 | -#!/usr/bin/perl |
3365 | - |
3366 | -use strict; |
3367 | -use warnings; |
3368 | -use DB::HandlerSocket::Pool; |
3369 | -use DBI; |
3370 | - |
3371 | -my %conf = (); |
3372 | -for my $i (@ARGV) { |
3373 | - my ($k, $v) = split(/=/, $i); |
3374 | - $conf{$k} = $v; |
3375 | -} |
3376 | - |
3377 | -my $verbose = get_conf("verbose", 0); |
3378 | -my $actions_str = get_conf("actions", |
3379 | - "create,insert,verify,verify2,verify3,verify4,clean"); |
3380 | -my $tablesize = get_conf("tablesize", 1000); |
3381 | -my $db = get_conf("db", "hstestdb"); |
3382 | -my $table = get_conf("table", "testtbl"); |
3383 | -my $table_schema = get_conf("table_schema", undef); |
3384 | -my $engine = get_conf("engine", "innodb"); |
3385 | -my $host = get_conf("host", "localhost"); |
3386 | -my $mysqlport = get_conf("mysqlport", 3306); |
3387 | -my $hsport_rd = get_conf("hsport_rd", 9998); |
3388 | -my $hsport_wr = get_conf("hsport_wr", 9999); |
3389 | -my $loop = get_conf("loop", 10000); |
3390 | -my $op = get_conf("op", "="); |
3391 | -my $ssps = get_conf("ssps", 0); |
3392 | -my $num_moreflds = get_conf("moreflds", 0); |
3393 | -my $moreflds_prefix = get_conf("moreflds_prefix", "f"); |
3394 | -my $mysql_user = 'root'; |
3395 | -my $mysql_password = ''; |
3396 | - |
3397 | -my $dsn = "DBI:mysql:database=;host=$host;port=$mysqlport" |
3398 | - . ";mysql_server_prepare=$ssps"; |
3399 | -my $dbh = DBI->connect($dsn, $mysql_user, $mysql_password, |
3400 | - { RaiseError => 1 }); |
3401 | -my $hsargs = { 'host' => $host, 'port' => $hsport_rd }; |
3402 | -my $hspool = new DB::HandlerSocket::Pool({ |
3403 | - hostmap => { |
3404 | - "$db.$table" => { |
3405 | - host => $host, |
3406 | - port => $hsport_rd, |
3407 | - }, |
3408 | - }, |
3409 | - resolve => undef, |
3410 | - error => undef, |
3411 | -}); |
3412 | -$table_schema = "(k int primary key, fc30 varchar(30), ft text)" |
3413 | - if (!defined($table_schema)); |
3414 | - |
3415 | -my @actions = split(/,/, $actions_str); |
3416 | -for my $action (@actions) { |
3417 | - print "ACTION: $action\n"; |
3418 | - eval "hstest_$action()"; |
3419 | - if ($@) { |
3420 | - die $@; |
3421 | - } |
3422 | - print "ACTION: $action DONE\n"; |
3423 | -} |
3424 | - |
3425 | -sub get_conf { |
3426 | - my ($key, $def) = @_; |
3427 | - my $val = $conf{$key}; |
3428 | - if ($val) { |
3429 | - print "$key=$val\n"; |
3430 | - } else { |
3431 | - $val = $def; |
3432 | - my $defstr = $def || "(undef)"; |
3433 | - print "$key=$defstr(default)\n"; |
3434 | - } |
3435 | - return $val; |
3436 | -} |
3437 | - |
3438 | -sub hstest_create { |
3439 | - $dbh->do("drop database if exists $db"); |
3440 | - $dbh->do("create database $db"); |
3441 | - $dbh->do("use $db"); |
3442 | - $dbh->do("create table $table $table_schema engine=$engine"); |
3443 | -} |
3444 | - |
3445 | -sub hstest_dump { |
3446 | - $dbh->do("use $db"); |
3447 | - my $sth = $dbh->prepare("select * from $table"); |
3448 | - $sth->execute(); |
3449 | - my $arr = $sth->fetchall_arrayref(); |
3450 | - for my $rec (@$arr) { |
3451 | - print "REC:"; |
3452 | - for my $row (@$rec) { |
3453 | - print " $row"; |
3454 | - } |
3455 | - print "\n"; |
3456 | - } |
3457 | -} |
3458 | - |
3459 | -sub hstest_insert { |
3460 | - $dbh->do("use $db"); |
3461 | - my $sth = $dbh->prepare("insert into $table values (?, ?, ?)"); |
3462 | - for (my $k = 0; $k < $tablesize; ++$k) { |
3463 | - my $fc30 = "fc30_$k"; |
3464 | - my $ft = "ft_$k"; |
3465 | - $sth->execute($k, $fc30, $ft); |
3466 | - } |
3467 | -} |
3468 | - |
3469 | -sub hstest_verify { |
3470 | - $dbh->do("use $db"); |
3471 | - my $sth = $dbh->prepare("select * from $table order by k"); |
3472 | - $sth->execute(); |
3473 | - my $arr = $sth->fetchall_arrayref(); |
3474 | - my $hsres = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3475 | - ">=", [ 0 ], $tablesize, 0); |
3476 | - for (my $i = 0; $i < $tablesize; ++$i) { |
3477 | - my $rec = $arr->[$i]; |
3478 | - my $differ = 0; |
3479 | - print "REC:" if $verbose; |
3480 | - for (my $j = 0; $j < 3; ++$j) { |
3481 | - my $fld = $rec->[$j]; |
3482 | - my $hsidx = $i * 3 + $j; |
3483 | - my $hsfld = $hsres->[$hsidx]; |
3484 | - if ($hsfld ne $fld) { |
3485 | - $differ = 1; |
3486 | - } |
3487 | - if ($differ) { |
3488 | - print " $fld:$hsfld" if $verbose; |
3489 | - } else { |
3490 | - print " $hsfld" if $verbose; |
3491 | - } |
3492 | - } |
3493 | - print "\n" if $verbose; |
3494 | - if ($differ) { |
3495 | - die "verification failed"; |
3496 | - } |
3497 | - } |
3498 | -} |
3499 | - |
3500 | -sub hstest_verify2 { |
3501 | - $dbh->do("use $db"); |
3502 | - my $sth = $dbh->prepare("select * from $table order by k"); |
3503 | - $sth->execute(); |
3504 | - my $arr = $sth->fetchall_arrayref(); |
3505 | - my $hsresa = $hspool->index_find_multi($db, $table, "PRIMARY", |
3506 | - "k,fc30,ft", [ [ -1, ">=", [ 0 ], $tablesize, 0 ] ]); |
3507 | - my $hsres = $hsresa->[0]; |
3508 | - for (my $i = 0; $i < $tablesize; ++$i) { |
3509 | - my $rec = $arr->[$i]; |
3510 | - my $differ = 0; |
3511 | - print "REC:" if $verbose; |
3512 | - for (my $j = 0; $j < 3; ++$j) { |
3513 | - my $fld = $rec->[$j]; |
3514 | - my $hsidx = $i * 3 + $j; |
3515 | - my $hsfld = $hsres->[$hsidx]; |
3516 | - if ($hsfld ne $fld) { |
3517 | - $differ = 1; |
3518 | - } |
3519 | - if ($differ) { |
3520 | - print " $fld:$hsfld" if $verbose; |
3521 | - } else { |
3522 | - print " $hsfld" if $verbose; |
3523 | - } |
3524 | - } |
3525 | - print "\n" if $verbose; |
3526 | - if ($differ) { |
3527 | - die "verification failed"; |
3528 | - } |
3529 | - } |
3530 | -} |
3531 | - |
3532 | -sub hashref_to_str { |
3533 | - my $href = $_[0]; |
3534 | - my $r = ''; |
3535 | - for my $k (sort keys %$href) { |
3536 | - my $v = $href->{$k}; |
3537 | - $r .= "($k=>$v)"; |
3538 | - } |
3539 | - return $r; |
3540 | -} |
3541 | - |
3542 | -sub hstest_verify3 { |
3543 | - $dbh->do("use $db"); |
3544 | - my $sth = $dbh->prepare("select * from $table order by k"); |
3545 | - $sth->execute(); |
3546 | - my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3547 | - ">=", [ 0 ], $tablesize, 0); |
3548 | - my $hsres = DB::HandlerSocket::Pool::result_single_to_hasharr( |
3549 | - [ 'k', 'fc30', 'ft' ], $hsres_t); |
3550 | - for (my $i = 0; $i < $tablesize; ++$i) { |
3551 | - my $mystr = hashref_to_str($sth->fetchrow_hashref()); |
3552 | - my $hsstr = hashref_to_str($hsres->[$i]); |
3553 | - if ($mystr ne $hsstr) { |
3554 | - print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose; |
3555 | - die "verification failed"; |
3556 | - } else { |
3557 | - print "OK $hsstr\n" if $verbose; |
3558 | - } |
3559 | - } |
3560 | -} |
3561 | - |
3562 | -sub hstest_verify4 { |
3563 | - $dbh->do("use $db"); |
3564 | - my $sth = $dbh->prepare("select * from $table order by k"); |
3565 | - $sth->execute(); |
3566 | - my $hsres_t = $hspool->index_find($db, $table, "PRIMARY", "k,fc30,ft", |
3567 | - ">=", [ 0 ], $tablesize, 0); |
3568 | - my $hsres = DB::HandlerSocket::Pool::result_single_to_hashhash( |
3569 | - [ 'k', 'fc30', 'ft' ], 'k', $hsres_t); |
3570 | - my $rechash = $sth->fetchall_hashref('k'); |
3571 | - while (my ($k, $href) = each (%$rechash)) { |
3572 | - my $mystr = hashref_to_str($href); |
3573 | - my $hsstr = hashref_to_str($hsres->{$k}); |
3574 | - if ($mystr ne $hsstr) { |
3575 | - print "DIFF my=[$mystr] hs=[$hsstr]\n" if $verbose; |
3576 | - die "verification failed"; |
3577 | - } else { |
3578 | - print "OK $hsstr\n" if $verbose; |
3579 | - } |
3580 | - } |
3581 | -} |
3582 | - |
3583 | -sub hstest_clean { |
3584 | - $hspool->clear_pool(); |
3585 | - $dbh->do("drop database if exists $db"); |
3586 | -} |
3587 | - |
3588 | |
3589 | === added file 'HandlerSocket-Plugin-for-MySQL/client/hstest.cpp' |
3590 | --- HandlerSocket-Plugin-for-MySQL/client/hstest.cpp 1970-01-01 00:00:00 +0000 |
3591 | +++ HandlerSocket-Plugin-for-MySQL/client/hstest.cpp 2012-06-25 04:42:22 +0000 |
3592 | @@ -0,0 +1,1532 @@ |
3593 | + |
3594 | +// vim:sw=2:ai |
3595 | + |
3596 | +#include <signal.h> |
3597 | +#include <sys/time.h> |
3598 | +#include <stdio.h> |
3599 | +#include <string.h> |
3600 | +#include <vector> |
3601 | +#include <stdlib.h> |
3602 | +#include <memory> |
3603 | +#include <errno.h> |
3604 | +#include <mysql.h> |
3605 | +#include <time.h> |
3606 | +#include <sys/types.h> |
3607 | +#include <sys/stat.h> |
3608 | +#include <fcntl.h> |
3609 | + |
3610 | +#include "util.hpp" |
3611 | +#include "auto_ptrcontainer.hpp" |
3612 | +#include "socket.hpp" |
3613 | +#include "thread.hpp" |
3614 | +#include "hstcpcli.hpp" |
3615 | + |
3616 | +#if __GNUC__ >= 4 |
3617 | +long atomic_exchange_and_add(volatile long *valp, long c) |
3618 | +{ |
3619 | + return __sync_fetch_and_add(valp, c); |
3620 | +} |
3621 | +#else |
3622 | +#include <bits/atomicity.h> |
3623 | +using namespace __gnu_cxx; |
3624 | +long atomic_exchange_and_add(volatile long *valp, long c) |
3625 | +{ |
3626 | + return __exchange_and_add((volatile _Atomic_word *)valp, c); |
3627 | +} |
3628 | +#endif |
3629 | + |
3630 | +namespace dena { |
3631 | + |
3632 | +struct auto_mysql : private noncopyable { |
3633 | + auto_mysql() : db(0) { |
3634 | + reset(); |
3635 | + } |
3636 | + ~auto_mysql() { |
3637 | + if (db) { |
3638 | + mysql_close(db); |
3639 | + } |
3640 | + } |
3641 | + void reset() { |
3642 | + if (db) { |
3643 | + mysql_close(db); |
3644 | + } |
3645 | + if ((db = mysql_init(0)) == 0) { |
3646 | + fatal_abort("failed to initialize mysql client"); |
3647 | + } |
3648 | + } |
3649 | + operator MYSQL *() const { return db; } |
3650 | + private: |
3651 | + MYSQL *db; |
3652 | +}; |
3653 | + |
3654 | +struct auto_mysql_res : private noncopyable { |
3655 | + auto_mysql_res(MYSQL *db) { |
3656 | + res = mysql_store_result(db); |
3657 | + } |
3658 | + ~auto_mysql_res() { |
3659 | + if (res) { |
3660 | + mysql_free_result(res); |
3661 | + } |
3662 | + } |
3663 | + operator MYSQL_RES *() const { return res; } |
3664 | + private: |
3665 | + MYSQL_RES *res; |
3666 | +}; |
3667 | + |
3668 | +struct auto_mysql_stmt : private noncopyable { |
3669 | + auto_mysql_stmt(MYSQL *db) { |
3670 | + stmt = mysql_stmt_init(db); |
3671 | + } |
3672 | + ~auto_mysql_stmt() { |
3673 | + if (stmt) { |
3674 | + mysql_stmt_close(stmt); |
3675 | + } |
3676 | + } |
3677 | + operator MYSQL_STMT *() const { return stmt; } |
3678 | + private: |
3679 | + MYSQL_STMT *stmt; |
3680 | +}; |
3681 | + |
3682 | +namespace { |
3683 | + |
3684 | +double |
3685 | +gettimeofday_double() |
3686 | +{ |
3687 | + struct timeval tv = { }; |
3688 | + if (gettimeofday(&tv, 0) != 0) { |
3689 | + fatal_abort("gettimeofday"); |
3690 | + } |
3691 | + return static_cast<double>(tv.tv_usec) / 1000000 + tv.tv_sec; |
3692 | +} |
3693 | + |
3694 | +// unused |
3695 | +void |
3696 | +wait_close(int fd) |
3697 | +{ |
3698 | + char buf[1024]; |
3699 | + while (true) { |
3700 | + int r = read(fd, buf, sizeof(buf)); |
3701 | + if (r <= 0) { |
3702 | + break; |
3703 | + } |
3704 | + } |
3705 | +} |
3706 | + |
3707 | +// unused |
3708 | +void |
3709 | +gentle_close(int fd) |
3710 | +{ |
3711 | + int r = shutdown(fd, SHUT_WR); |
3712 | + if (r != 0) { |
3713 | + return; |
3714 | + } |
3715 | + wait_close(fd); |
3716 | +} |
3717 | + |
3718 | +}; |
3719 | + |
3720 | +struct hstest_shared { |
3721 | + config conf; |
3722 | + socket_args arg; |
3723 | + int verbose; |
3724 | + size_t loop; |
3725 | + size_t pipe; |
3726 | + char op; |
3727 | + long num_threads; |
3728 | + mutable volatile long count; |
3729 | + mutable volatile long conn_count; |
3730 | + long wait_conn; |
3731 | + volatile char *keygen; |
3732 | + long keygen_size; |
3733 | + mutable volatile int enable_timing; |
3734 | + int usleep; |
3735 | + int dump; |
3736 | + hstest_shared() : verbose(0), loop(0), pipe(0), op('G'), num_threads(0), |
3737 | + count(0), conn_count(0), wait_conn(0), keygen(0), keygen_size(0), |
3738 | + enable_timing(0), usleep(0), dump(0) { } |
3739 | + void increment_count(unsigned int c = 1) const volatile { |
3740 | + atomic_exchange_and_add(&count, c); |
3741 | + } |
3742 | + void increment_conn(unsigned int c) const volatile { |
3743 | + atomic_exchange_and_add(&conn_count, c); |
3744 | + while (wait_conn != 0 && conn_count < wait_conn) { |
3745 | + sleep(1); |
3746 | + } |
3747 | + // fprintf(stderr, "wait_conn=%ld done\n", wait_conn); |
3748 | + } |
3749 | +}; |
3750 | + |
3751 | +struct hstest_thread { |
3752 | + struct arg_type { |
3753 | + size_t id; |
3754 | + const hstest_shared& sh; |
3755 | + bool watch_flag; |
3756 | + arg_type(size_t i, const hstest_shared& s, bool w) |
3757 | + : id(i), sh(s), watch_flag(w) { } |
3758 | + }; |
3759 | + hstest_thread(const arg_type& a) : arg(a), io_success_count(0), |
3760 | + op_success_count(0), response_min(99999), response_max(0), |
3761 | + response_sum(0), response_avg(0) { } |
3762 | + void operator ()(); |
3763 | + void test_1(); |
3764 | + void test_2_3(int test_num); |
3765 | + void test_4_5(int test_num); |
3766 | + void test_6(int test_num); |
3767 | + void test_7(int test_num); |
3768 | + void test_8(int test_num); |
3769 | + void test_9(int test_num); |
3770 | + void test_10(int test_num); |
3771 | + void test_11(int test_num); |
3772 | + void test_12(int test_num); |
3773 | + void test_21(int test_num); |
3774 | + void test_22(int test_num); |
3775 | + void test_watch(); |
3776 | + void sleep_if(); |
3777 | + void set_timing(double time_spent); |
3778 | + arg_type arg; |
3779 | + auto_file fd; |
3780 | + size_t io_success_count; |
3781 | + size_t op_success_count; |
3782 | + double response_min, response_max, response_sum, response_avg; |
3783 | +}; |
3784 | + |
3785 | +void |
3786 | +hstest_thread::test_1() |
3787 | +{ |
3788 | + char buf[1024]; |
3789 | + unsigned int seed = arg.id; |
3790 | + seed ^= arg.sh.conf.get_int("seed_xor", 0); |
3791 | + std::string err; |
3792 | + if (socket_connect(fd, arg.sh.arg, err) != 0) { |
3793 | + fprintf(stderr, "connect: %d %s\n", errno, strerror(errno)); |
3794 | + return; |
3795 | + } |
3796 | + const char op = arg.sh.op; |
3797 | + const int tablesize = arg.sh.conf.get_int("tablesize", 0); |
3798 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
3799 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
3800 | + int k = 0, v = 0, len = 0; |
3801 | + if (op == 'G') { |
3802 | + k = rand_r(&seed); |
3803 | + v = rand_r(&seed); /* unused */ |
3804 | + if (tablesize != 0) { |
3805 | + k &= tablesize; |
3806 | + } |
3807 | + len = snprintf(buf, sizeof(buf), "%c\tk%d\n", op, k); |
3808 | + } else { |
3809 | + k = rand_r(&seed); |
3810 | + v = rand_r(&seed); |
3811 | + if (tablesize != 0) { |
3812 | + k &= tablesize; |
3813 | + } |
3814 | + len = snprintf(buf, sizeof(buf), "%c\tk%d\tv%d\n", op, k, v); |
3815 | + } |
3816 | + const int wlen = write(fd.get(), buf, len); |
3817 | + if (wlen != len) { |
3818 | + return; |
3819 | + } |
3820 | + } |
3821 | + size_t read_cnt = 0; |
3822 | + size_t read_pos = 0; |
3823 | + while (read_cnt < arg.sh.pipe) { |
3824 | + const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos); |
3825 | + if (rlen <= 0) { |
3826 | + return; |
3827 | + } |
3828 | + read_pos += rlen; |
3829 | + while (true) { |
3830 | + const char *const p = static_cast<const char *>(memchr(buf, '\n', |
3831 | + read_pos)); |
3832 | + if (p == 0) { |
3833 | + break; |
3834 | + } |
3835 | + ++read_cnt; |
3836 | + ++io_success_count; |
3837 | + arg.sh.increment_count(); |
3838 | + if (p != buf && buf[0] == '=') { |
3839 | + ++op_success_count; |
3840 | + } |
3841 | + const size_t rest_size = buf + read_pos - (p + 1); |
3842 | + if (rest_size != 0) { |
3843 | + memmove(buf, p + 1, rest_size); |
3844 | + } |
3845 | + read_pos = rest_size; |
3846 | + } |
3847 | + } |
3848 | + } |
3849 | +} |
3850 | + |
3851 | +void |
3852 | +hstest_thread::test_2_3(int test_num) |
3853 | +{ |
3854 | +#if 0 |
3855 | + char buf_k[128], buf_v[128]; |
3856 | + unsigned int seed = arg.id; |
3857 | + op_base_t op = static_cast<op_base_t>(arg.sh.op); |
3858 | + micli_ptr hnd; |
3859 | + if (test_num == 2) { |
3860 | + hnd = micli_i::create_remote(arg.sh.conf); |
3861 | + } else if (test_num == 3) { |
3862 | + // hnd = micli_i::create_inproc(arg.sh.localdb); |
3863 | + } |
3864 | + if (hnd.get() == 0) { |
3865 | + return; |
3866 | + } |
3867 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
3868 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
3869 | + int k = 0, v = 0, klen = 0, vlen = 0; |
3870 | + k = rand_r(&seed); |
3871 | + klen = snprintf(buf_k, sizeof(buf_k), "k%d", k); |
3872 | + v = rand_r(&seed); /* unused */ |
3873 | + vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v); |
3874 | + string_ref arr[2]; |
3875 | + arr[0] = string_ref(buf_k, klen); |
3876 | + arr[1] = string_ref(buf_v, vlen); |
3877 | + pstrarr_ptr rec(arr, 2); |
3878 | + if (hnd->execute(op, 0, 0, rec.get_const())) { |
3879 | + ++io_success_count; |
3880 | + arg.sh.increment_count(); |
3881 | + const dataset& res = hnd->get_result_ref(); |
3882 | + if (res.size() == 1) { |
3883 | + ++op_success_count; |
3884 | + } |
3885 | + } |
3886 | + } |
3887 | + } |
3888 | +#endif |
3889 | +} |
3890 | + |
3891 | +void |
3892 | +hstest_thread::test_4_5(int test_num) |
3893 | +{ |
3894 | +#if 0 |
3895 | + char buf_k[128], buf_v[8192]; |
3896 | + memset(buf_v, ' ', sizeof(buf_v)); |
3897 | + unsigned int seed = arg.id; |
3898 | + op_base_t op = static_cast<op_base_t>(arg.sh.op); |
3899 | + micli_ptr hnd; |
3900 | + if (test_num == 4) { |
3901 | + hnd = micli_i::create_remote(arg.sh.conf); |
3902 | + } else if (test_num == 5) { |
3903 | + hnd = micli_i::create_inproc(arg.sh.localdb); |
3904 | + } |
3905 | + if (hnd.get() == 0) { |
3906 | + return; |
3907 | + } |
3908 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
3909 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
3910 | + int k = 0, klen = 0, vlen = 0; |
3911 | + k = i & 0x0000ffffUL; |
3912 | + if (k == 0) { |
3913 | + fprintf(stderr, "k=0\n"); |
3914 | + } |
3915 | + klen = snprintf(buf_k, sizeof(buf_k), "k%d", k); |
3916 | + vlen = rand_r(&seed) % 8192; |
3917 | + string_ref arr[2]; |
3918 | + arr[0] = string_ref(buf_k, klen); |
3919 | + arr[1] = string_ref(buf_v, vlen); |
3920 | + pstrarr_ptr rec(arr, 2); |
3921 | + if (hnd->execute(op, 0, 0, rec.get_const())) { |
3922 | + ++io_success_count; |
3923 | + const dataset& res = hnd->get_result_ref(); |
3924 | + if (res.size() == 1) { |
3925 | + ++op_success_count; |
3926 | + } |
3927 | + } |
3928 | + } |
3929 | + } |
3930 | +#endif |
3931 | +} |
3932 | + |
3933 | +void |
3934 | +hstest_thread::test_6(int test_num) |
3935 | +{ |
3936 | + int count = arg.sh.conf.get_int("count", 1); |
3937 | + auto_file fds[count]; |
3938 | + for (int i = 0; i < count; ++i) { |
3939 | + const double t1 = gettimeofday_double(); |
3940 | + std::string err; |
3941 | + if (socket_connect(fds[i], arg.sh.arg, err) != 0) { |
3942 | + fprintf(stderr, "id=%zu i=%d err=%s\n", arg.id, i, err.c_str()); |
3943 | + } |
3944 | + const double t2 = gettimeofday_double(); |
3945 | + if (t2 - t1 > 1) { |
3946 | + fprintf(stderr, "id=%zu i=%d time %f\n", arg.id, i, t2 - t1); |
3947 | + } |
3948 | + } |
3949 | +} |
3950 | + |
3951 | +void |
3952 | +hstest_thread::test_7(int num) |
3953 | +{ |
3954 | + /* |
3955 | + set foo 0 0 10 |
3956 | + 0123456789 |
3957 | + STORED |
3958 | + get foo |
3959 | + VALUE foo 0 10 |
3960 | + 0123456789 |
3961 | + END |
3962 | + get var |
3963 | + END |
3964 | + */ |
3965 | + char buf[1024]; |
3966 | + const int keep_connection = arg.sh.conf.get_int("keep_connection", 1); |
3967 | + unsigned int seed = arg.id; |
3968 | + seed ^= arg.sh.conf.get_int("seed_xor", 0); |
3969 | + const int tablesize = arg.sh.conf.get_int("tablesize", 0); |
3970 | + const char op = arg.sh.op; |
3971 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
3972 | + const double tm1 = gettimeofday_double(); |
3973 | + std::string err; |
3974 | + if (fd.get() < 0 && socket_connect(fd, arg.sh.arg, err) != 0) { |
3975 | + fprintf(stderr, "connect: %d %s\n", errno, strerror(errno)); |
3976 | + return; |
3977 | + } |
3978 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
3979 | + int k = 0, v = 0, len = 0; |
3980 | + if (op == 'G') { |
3981 | + k = rand_r(&seed); |
3982 | + v = rand_r(&seed); /* unused */ |
3983 | + if (tablesize != 0) { |
3984 | + k &= tablesize; |
3985 | + } |
3986 | + len = snprintf(buf, sizeof(buf), "get k%d\r\n", k); |
3987 | + } else { |
3988 | + k = rand_r(&seed); |
3989 | + v = rand_r(&seed); |
3990 | + if (tablesize != 0) { |
3991 | + k &= tablesize; |
3992 | + } |
3993 | + char vbuf[1024]; |
3994 | + int vlen = snprintf(vbuf, sizeof(vbuf), |
3995 | + "v%d" |
3996 | + // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
3997 | + // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
3998 | + // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
3999 | + // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
4000 | + // "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" |
4001 | + , v); |
4002 | + len = snprintf(buf, sizeof(buf), "set k%d 0 0 %d\r\n%s\r\n", |
4003 | + k, vlen, vbuf); |
4004 | + } |
4005 | + const int wlen = write(fd.get(), buf, len); |
4006 | + if (wlen != len) { |
4007 | + return; |
4008 | + } |
4009 | + } |
4010 | + size_t read_cnt = 0; |
4011 | + size_t read_pos = 0; |
4012 | + bool read_response_done = false; |
4013 | + bool expect_value = false; |
4014 | + while (!read_response_done) { |
4015 | + const int rlen = read(fd.get(), buf + read_pos, sizeof(buf) - read_pos); |
4016 | + if (rlen <= 0) { |
4017 | + return; |
4018 | + } |
4019 | + read_pos += rlen; |
4020 | + while (true) { |
4021 | + const char *const p = static_cast<const char *>(memchr(buf, '\n', |
4022 | + read_pos)); |
4023 | + if (p == 0) { |
4024 | + break; |
4025 | + } |
4026 | + ++read_cnt; |
4027 | + if (expect_value) { |
4028 | + expect_value = false; |
4029 | + } else if (p >= buf + 6 && memcmp(buf, "VALUE ", 6) == 0) { |
4030 | + expect_value = true; |
4031 | + ++op_success_count; |
4032 | + } else { |
4033 | + if (p == buf + 7 && memcmp(buf, "STORED\r", 7) == 0) { |
4034 | + ++op_success_count; |
4035 | + } |
4036 | + read_response_done = true; |
4037 | + } |
4038 | + const size_t rest_size = buf + read_pos - (p + 1); |
4039 | + if (rest_size != 0) { |
4040 | + memmove(buf, p + 1, rest_size); |
4041 | + } |
4042 | + read_pos = rest_size; |
4043 | + } |
4044 | + ++io_success_count; |
4045 | + } |
4046 | + arg.sh.increment_count(); |
4047 | + if (!keep_connection) { |
4048 | + fd.close(); |
4049 | + } |
4050 | + const double tm2 = gettimeofday_double(); |
4051 | + set_timing(tm2 - tm1); |
4052 | + sleep_if(); |
4053 | + } |
4054 | +} |
4055 | + |
4056 | +struct rec { |
4057 | + std::string key; |
4058 | + std::string value; |
4059 | +}; |
4060 | + |
4061 | +void |
4062 | +hstest_thread::test_8(int test_num) |
4063 | +{ |
4064 | +#if 0 |
4065 | + char buf_k[128], buf_v[128]; |
4066 | + unsigned int seed = arg.id; |
4067 | + // op_base_t op = static_cast<op_base_t>(arg.sh.op); |
4068 | + using namespace boost::multi_index; |
4069 | + typedef member<rec, std::string, &rec::key> rec_get_key; |
4070 | + typedef ordered_unique<rec_get_key> oui; |
4071 | + typedef multi_index_container< rec, indexed_by<oui> > mic; |
4072 | + #if 0 |
4073 | + typedef std::map<std::string, std::string> m_type; |
4074 | + m_type m; |
4075 | + #endif |
4076 | + mic m; |
4077 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
4078 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
4079 | + int k = 0, v = 0, klen = 0, vlen = 0; |
4080 | + k = rand_r(&seed); |
4081 | + klen = snprintf(buf_k, sizeof(buf_k), "k%d", k); |
4082 | + v = rand_r(&seed); /* unused */ |
4083 | + vlen = snprintf(buf_v, sizeof(buf_v), "v%d", v); |
4084 | + const std::string ks(buf_k, klen); |
4085 | + const std::string vs(buf_v, vlen); |
4086 | + rec r; |
4087 | + r.key = ks; |
4088 | + r.value = vs; |
4089 | + m.insert(r); |
4090 | + // m.insert(std::make_pair(ks, vs)); |
4091 | + ++io_success_count; |
4092 | + ++op_success_count; |
4093 | + arg.sh.increment_count(); |
4094 | + } |
4095 | + } |
4096 | +#endif |
4097 | +} |
4098 | + |
4099 | +struct mysqltest_thread_initobj : private noncopyable { |
4100 | + mysqltest_thread_initobj() { |
4101 | + mysql_thread_init(); |
4102 | + } |
4103 | + ~mysqltest_thread_initobj() { |
4104 | + mysql_thread_end(); |
4105 | + } |
4106 | +}; |
4107 | + |
4108 | +void |
4109 | +hstest_thread::test_9(int test_num) |
4110 | +{ |
4111 | + /* create table hstest |
4112 | + * ( k varchar(255) not null, v varchar(255) not null, primary key(k)) |
4113 | + * engine = innodb; */ |
4114 | + auto_mysql db; |
4115 | + // mysqltest_thread_initobj initobj; |
4116 | + std::string err; |
4117 | + const char op = arg.sh.op; |
4118 | + const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd"); |
4119 | + unsigned long long err_cnt = 0; |
4120 | + unsigned long long query_cnt = 0; |
4121 | + #if 0 |
4122 | + my_bool reconnect = 0; |
4123 | + if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) { |
4124 | + err = "mysql_options() failed"; |
4125 | + ++err_cnt; |
4126 | + return; |
4127 | + } |
4128 | + #endif |
4129 | + unsigned int seed = time(0) + arg.id + 1; |
4130 | + seed ^= arg.sh.conf.get_int("seed_xor", 0); |
4131 | + drand48_data randbuf; |
4132 | + srand48_r(seed, &randbuf); |
4133 | + const std::string mysql_host = arg.sh.conf.get_str("host", "localhost"); |
4134 | + const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306); |
4135 | + const int num = arg.sh.loop; |
4136 | + const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root"); |
4137 | + const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", ""); |
4138 | + const std::string mysql_dbname = arg.sh.conf.get_str("dbname", "hstest"); |
4139 | + const int keep_connection = arg.sh.conf.get_int("keep_connection", 1); |
4140 | + const int verbose = arg.sh.conf.get_int("verbose", 1); |
4141 | + const int tablesize = arg.sh.conf.get_int("tablesize", 10000); |
4142 | + const int moreflds = arg.sh.conf.get_int("moreflds", 0); |
4143 | + const std::string moreflds_prefix = arg.sh.conf.get_str( |
4144 | + "moreflds_prefix", "column0123456789_"); |
4145 | + const int use_handler = arg.sh.conf.get_int("handler", 0); |
4146 | + const int sched_flag = arg.sh.conf.get_int("sched", 0); |
4147 | + const int use_in = arg.sh.conf.get_int("in", 0); |
4148 | + const int ssps = use_in ? 0 : arg.sh.conf.get_int("ssps", 0); |
4149 | + std::string flds = "v"; |
4150 | + for (int i = 0; i < moreflds; ++i) { |
4151 | + char buf[1024]; |
4152 | + snprintf(buf, sizeof(buf), ",%s%d", moreflds_prefix.c_str(), i); |
4153 | + flds += std::string(buf); |
4154 | + } |
4155 | + int connected = 0; |
4156 | + std::auto_ptr<auto_mysql_stmt> stmt; |
4157 | + string_buffer wbuf; |
4158 | + for (int i = 0; i < num; ++i) { |
4159 | + const double tm1 = gettimeofday_double(); |
4160 | + const int flags = 0; |
4161 | + if (connected == 0) { |
4162 | + if (!mysql_real_connect(db, mysql_host.c_str(), |
4163 | + mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(), |
4164 | + mysql_dbname.c_str(), mysql_port, 0, flags)) { |
4165 | + err = "failed to connect: " + std::string(mysql_error(db)); |
4166 | + if (verbose >= 1) { |
4167 | + fprintf(stderr, "e=[%s]\n", err.c_str()); |
4168 | + } |
4169 | + ++err_cnt; |
4170 | + return; |
4171 | + } |
4172 | + arg.sh.increment_conn(1); |
4173 | + } |
4174 | + int r = 0; |
4175 | + if (connected == 0 && use_handler) { |
4176 | + const char *const q = "handler hstest_table1 open"; |
4177 | + r = mysql_real_query(db, q, strlen(q)); |
4178 | + if (r != 0) { |
4179 | + err = 1; |
4180 | + } |
4181 | + } |
4182 | + if (connected == 0 && ssps) { |
4183 | + stmt.reset(new auto_mysql_stmt(db)); |
4184 | + const char *const q = "select v from hstest_table1 where k = ?"; |
4185 | + r = mysql_stmt_prepare(*stmt, q, strlen(q)); |
4186 | + if (r != 0) { |
4187 | + fprintf(stderr, "ssps err\n"); |
4188 | + ++err_cnt; |
4189 | + return; |
4190 | + } |
4191 | + } |
4192 | + connected = 1; |
4193 | + std::string result_str; |
4194 | + unsigned int err = 0; |
4195 | + unsigned int num_flds = 0, num_affected_rows = 0; |
4196 | + int got_data = 0; |
4197 | + char buf_query[16384]; |
4198 | + int buf_query_len = 0; |
4199 | + int k = 0, v = 0; |
4200 | + { |
4201 | + double kf = 0, vf = 0; |
4202 | + drand48_r(&randbuf, &kf); |
4203 | + drand48_r(&randbuf, &vf); |
4204 | + k = int(kf * tablesize); |
4205 | + v = int(vf * tablesize); |
4206 | + #if 0 |
4207 | + k = rand_r(&seed); |
4208 | + v = rand_r(&seed); |
4209 | + if (tablesize != 0) { |
4210 | + k %= tablesize; |
4211 | + } |
4212 | + #endif |
4213 | + if (op == 'G') { |
4214 | + if (use_handler) { |
4215 | + buf_query_len = snprintf(buf_query, sizeof(buf_query), |
4216 | + "handler hstest_table1 read `primary` = ( '%d' )", k); |
4217 | + // TODO: moreflds |
4218 | + } else if (ssps) { |
4219 | + // |
4220 | + } else if (use_in) { |
4221 | + wbuf.clear(); |
4222 | + char *p = wbuf.make_space(1024); |
4223 | + int len = snprintf(p, 1024, "select %s from hstest_table1 where k in ('%d'", flds.c_str(), k); |
4224 | + wbuf.space_wrote(len); |
4225 | + for (int j = 1; j < use_in; ++j) { |
4226 | + /* generate more key */ |
4227 | + drand48_r(&randbuf, &kf); |
4228 | + k = int(kf * tablesize); |
4229 | + p = wbuf.make_space(1024); |
4230 | + int len = snprintf(p, 1024, ", '%d'", k); |
4231 | + wbuf.space_wrote(len); |
4232 | + } |
4233 | + wbuf.append_literal(")"); |
4234 | + } else { |
4235 | + buf_query_len = snprintf(buf_query, sizeof(buf_query), |
4236 | + "select %s from hstest_table1 where k = '%d'", flds.c_str(), k); |
4237 | + } |
4238 | + } else if (op == 'U') { |
4239 | + buf_query_len = snprintf(buf_query, sizeof(buf_query), |
4240 | + "update hstest_table1 set v = '%d_%d%s' where k = '%d'", |
4241 | + v, k, suffix.c_str(), k); |
4242 | + } else if (op == 'R') { |
4243 | + buf_query_len = snprintf(buf_query, sizeof(buf_query), |
4244 | + "replace into hstest_table1 values ('%d', 'v%d')", k, v); |
4245 | + // TODO: moreflds |
4246 | + } |
4247 | + } |
4248 | + if (r == 0) { |
4249 | + if (ssps) { |
4250 | + MYSQL_BIND bind[1] = { }; |
4251 | + bind[0].buffer_type = MYSQL_TYPE_LONG; |
4252 | + bind[0].buffer = (char *)&k; |
4253 | + bind[0].is_null = 0; |
4254 | + bind[0].length = 0; |
4255 | + if (mysql_stmt_bind_param(*stmt, bind)) { |
4256 | + fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt)); |
4257 | + ++err_cnt; |
4258 | + return; |
4259 | + } |
4260 | + r = mysql_stmt_execute(*stmt); |
4261 | + // fprintf(stderr, "stmt exec\n"); |
4262 | + } else if (use_in) { |
4263 | + r = mysql_real_query(db, wbuf.begin(), wbuf.size()); |
4264 | + } else { |
4265 | + r = mysql_real_query(db, buf_query, buf_query_len); |
4266 | + // fprintf(stderr, "real query\n"); |
4267 | + } |
4268 | + ++query_cnt; |
4269 | + } |
4270 | + if (r != 0) { |
4271 | + err = 1; |
4272 | + } else if (ssps) { |
4273 | + if (verbose >= 0) { |
4274 | + char resbuf[1024]; |
4275 | + unsigned long res_len = 0; |
4276 | + MYSQL_BIND bind[1] = { }; |
4277 | + bind[0].buffer_type = MYSQL_TYPE_STRING; |
4278 | + bind[0].buffer = resbuf; |
4279 | + bind[0].buffer_length = sizeof(resbuf); |
4280 | + bind[0].length = &res_len; |
4281 | + if (mysql_stmt_bind_result(*stmt, bind)) { |
4282 | + fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt)); |
4283 | + ++err_cnt; |
4284 | + return; |
4285 | + } |
4286 | + if (mysql_stmt_fetch(*stmt)) { |
4287 | + fprintf(stderr, "err: %s\n", mysql_stmt_error(*stmt)); |
4288 | + ++err_cnt; |
4289 | + return; |
4290 | + } |
4291 | + if (!result_str.empty()) { |
4292 | + result_str += " "; |
4293 | + } |
4294 | + result_str += std::string(resbuf, res_len); |
4295 | + // fprintf(stderr, "SSPS RES: %s\n", result_str.c_str()); |
4296 | + got_data = 1; |
4297 | + } else { |
4298 | + got_data = 1; |
4299 | + } |
4300 | + } else { |
4301 | + auto_mysql_res res(db); |
4302 | + if (res != 0) { |
4303 | + if (verbose >= 0) { |
4304 | + num_flds = mysql_num_fields(res); |
4305 | + MYSQL_ROW row = 0; |
4306 | + while ((row = mysql_fetch_row(res)) != 0) { |
4307 | + got_data += 1; |
4308 | + unsigned long *const lengths = mysql_fetch_lengths(res); |
4309 | + if (verbose >= 2) { |
4310 | + for (unsigned int i = 0; i < num_flds; ++i) { |
4311 | + if (!result_str.empty()) { |
4312 | + result_str += " "; |
4313 | + } |
4314 | + result_str += std::string(row[i], lengths[i]); |
4315 | + } |
4316 | + } |
4317 | + } |
4318 | + } else { |
4319 | + MYSQL_ROW row = 0; |
4320 | + while ((row = mysql_fetch_row(res)) != 0) { |
4321 | + got_data += 1; |
4322 | + } |
4323 | + } |
4324 | + } else { |
4325 | + if (mysql_field_count(db) == 0) { |
4326 | + num_affected_rows = mysql_affected_rows(db); |
4327 | + } else { |
4328 | + err = 1; |
4329 | + } |
4330 | + } |
4331 | + } |
4332 | + if (verbose >= 2 || (verbose >= 1 && err != 0)) { |
4333 | + if (err) { |
4334 | + ++err_cnt; |
4335 | + const char *const errstr = mysql_error(db); |
4336 | + fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr, |
4337 | + num_affected_rows, buf_query); |
4338 | + } else { |
4339 | + fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows, buf_query, |
4340 | + result_str.c_str()); |
4341 | + } |
4342 | + } |
4343 | + if (err == 0) { |
4344 | + ++io_success_count; |
4345 | + if (num_affected_rows > 0 || got_data > 0) { |
4346 | + op_success_count += got_data; |
4347 | + } else { |
4348 | + if (verbose >= 1) { |
4349 | + fprintf(stderr, "k=%d numaff=%u gotdata=%d\n", |
4350 | + k, num_affected_rows, got_data); |
4351 | + } |
4352 | + } |
4353 | + arg.sh.increment_count(); |
4354 | + } |
4355 | + if (!keep_connection) { |
4356 | + if (stmt.get() != 0) { |
4357 | + stmt.reset(); |
4358 | + } |
4359 | + db.reset(); |
4360 | + connected = 0; |
4361 | + } |
4362 | + const double tm2 = gettimeofday_double(); |
4363 | + set_timing(tm2 - tm1); |
4364 | + sleep_if(); |
4365 | + if (sched_flag) { |
4366 | + sched_yield(); |
4367 | + } |
4368 | + } |
4369 | + if (verbose >= 1) { |
4370 | + fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt); |
4371 | + } |
4372 | +} |
4373 | + |
4374 | +void |
4375 | +hstest_thread::test_10(int test_num) |
4376 | +{ |
4377 | + const int keep_connection = arg.sh.conf.get_int("keep_connection", 1); |
4378 | + unsigned int seed = time(0) + arg.id + 1; |
4379 | + seed ^= arg.sh.conf.get_int("seed_xor", 0); |
4380 | + drand48_data randbuf; |
4381 | + srand48_r(seed, &randbuf); |
4382 | + std::string err; |
4383 | + int keepconn_count = 0; |
4384 | + const char op = arg.sh.op; |
4385 | + const int verbose = arg.sh.conf.get_int("verbose", 1); |
4386 | + const std::string suffix = arg.sh.conf.get_str("value_suffix", "upd"); |
4387 | + const int tablesize = arg.sh.conf.get_int("tablesize", 10000); |
4388 | + const int firstkey = arg.sh.conf.get_int("firstkey", 0); |
4389 | + const int sched_flag = arg.sh.conf.get_int("sched", 0); |
4390 | + const int moreflds = arg.sh.conf.get_int("moreflds", 0); |
4391 | + const std::string dbname = arg.sh.conf.get_str("dbname", "hstest"); |
4392 | + const std::string table = arg.sh.conf.get_str("table", "hstest_table1"); |
4393 | + const std::string index = arg.sh.conf.get_str("index", "PRIMARY"); |
4394 | + const std::string field = arg.sh.conf.get_str("field", "v"); |
4395 | + const int use_in = arg.sh.conf.get_int("in", 0); |
4396 | + const std::string moreflds_prefix = arg.sh.conf.get_str( |
4397 | + "moreflds_prefix", "column0123456789_"); |
4398 | + const int dump = arg.sh.dump; |
4399 | + const int nodup = arg.sh.conf.get_int("nodup", 0); |
4400 | + std::string moreflds_str; |
4401 | + for (int i = 0; i < moreflds; ++i) { |
4402 | + char sbuf[1024]; |
4403 | + snprintf(sbuf, sizeof(sbuf), ",%s%d", moreflds_prefix.c_str(), i); |
4404 | + moreflds_str += std::string(sbuf); |
4405 | + } |
4406 | + string_buffer wbuf; |
4407 | + char rbuf[16384]; |
4408 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
4409 | + int len = 0, rlen = 0, wlen = 0; |
4410 | + #if 0 |
4411 | + const double tm1 = gettimeofday_double(); |
4412 | + #endif |
4413 | + if (fd.get() < 0) { |
4414 | + if (socket_connect(fd, arg.sh.arg, err) != 0) { |
4415 | + fprintf(stderr, "connect: %d %s\n", errno, strerror(errno)); |
4416 | + return; |
4417 | + } |
4418 | + char *wp = wbuf.make_space(1024); |
4419 | + len = snprintf(wp, 1024, |
4420 | + "P\t1\t%s\t%s\tPRIMARY\t%s%s\n", dbname.c_str(), table.c_str(), |
4421 | + field.c_str(), moreflds_str.c_str()); |
4422 | + /* pst_num, db, table, index, retflds */ |
4423 | + wbuf.space_wrote(len); |
4424 | + wlen = write(fd.get(), wbuf.begin(), len); |
4425 | + if (len != wlen) { |
4426 | + fprintf(stderr, "write: %d %d\n", len, wlen); |
4427 | + return; |
4428 | + } |
4429 | + wbuf.clear(); |
4430 | + rlen = read(fd.get(), rbuf, sizeof(rbuf)); |
4431 | + if (rlen <= 0 || rbuf[rlen - 1] != '\n') { |
4432 | + fprintf(stderr, "read: rlen=%d errno=%d\n", rlen, errno); |
4433 | + return; |
4434 | + } |
4435 | + if (rbuf[0] != '0') { |
4436 | + fprintf(stderr, "failed to open table\n"); |
4437 | + return; |
4438 | + } |
4439 | + arg.sh.increment_conn(1); |
4440 | + } |
4441 | + const double tm1 = gettimeofday_double(); |
4442 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
4443 | + int k = 0, v = 0; |
4444 | + { |
4445 | + while (true) { |
4446 | + double kf = 0, vf = 0; |
4447 | + drand48_r(&randbuf, &kf); |
4448 | + drand48_r(&randbuf, &vf); |
4449 | + k = int(kf * tablesize) + firstkey; |
4450 | + v = int(vf * tablesize) + firstkey; |
4451 | + if (k - firstkey < arg.sh.keygen_size) { |
4452 | + volatile char *const ptr = arg.sh.keygen + (k - firstkey); |
4453 | + // int oldv = __sync_fetch_and_or(ptr, 1); |
4454 | + int oldv = *ptr; |
4455 | + *ptr += 1; |
4456 | + if (nodup && oldv != 0) { |
4457 | + if (dump) { |
4458 | + fprintf(stderr, "retry\n"); |
4459 | + } |
4460 | + continue; |
4461 | + } |
4462 | + } else { |
4463 | + if (nodup) { |
4464 | + if (dump) { |
4465 | + fprintf(stderr, "retry2\n"); |
4466 | + } |
4467 | + continue; |
4468 | + } |
4469 | + } |
4470 | + size_t len = 0; |
4471 | + if (op == 'G') { |
4472 | + if (use_in) { |
4473 | + char *wp = wbuf.make_space(1024); |
4474 | + len = snprintf(wp, 1024, "1\t=\t1\t\t%d\t0\t@\t0\t%d\t%d", |
4475 | + use_in, use_in, k); |
4476 | + wbuf.space_wrote(len); |
4477 | + for (int j = 1; j < use_in; ++j) { |
4478 | + drand48_r(&randbuf, &kf); |
4479 | + k = int(kf * tablesize) + firstkey; |
4480 | + char *wp = wbuf.make_space(1024); |
4481 | + len = snprintf(wp, 1024, "\t%d", k); |
4482 | + wbuf.space_wrote(len); |
4483 | + } |
4484 | + wbuf.append_literal("\n"); |
4485 | + } else { |
4486 | + char *wp = wbuf.make_space(1024); |
4487 | + len = snprintf(wp, 1024, "1\t=\t1\t%d\n", k); |
4488 | + wbuf.space_wrote(len); |
4489 | + } |
4490 | + } else if (op == 'U') { |
4491 | + char *wp = wbuf.make_space(1024); |
4492 | + len = snprintf(wp, 1024, |
4493 | + "1\t=\t1\t%d\t1\t0\tU\t%d_%d%s\n", k, v, k, suffix.c_str()); |
4494 | + wbuf.space_wrote(len); |
4495 | + } |
4496 | + break; |
4497 | + } |
4498 | + } |
4499 | + } |
4500 | + wlen = write(fd.get(), wbuf.begin(), wbuf.size()); |
4501 | + if (wlen != wbuf.size()) { |
4502 | + fprintf(stderr, "write: %d %d\n", (int)wbuf.size(), wlen); |
4503 | + return; |
4504 | + } |
4505 | + wbuf.clear(); |
4506 | + size_t read_cnt = 0; |
4507 | + size_t read_pos = 0; |
4508 | + while (read_cnt < arg.sh.pipe) { |
4509 | + rlen = read(fd.get(), rbuf + read_pos, sizeof(rbuf) - read_pos); |
4510 | + if (rlen <= 0) { |
4511 | + fprintf(stderr, "read: %d\n", rlen); |
4512 | + return; |
4513 | + } |
4514 | + read_pos += rlen; |
4515 | + while (true) { |
4516 | + const char *const nl = static_cast<const char *>(memchr(rbuf, '\n', |
4517 | + read_pos)); |
4518 | + if (nl == 0) { |
4519 | + break; |
4520 | + } |
4521 | + ++read_cnt; |
4522 | + ++io_success_count; |
4523 | + const char *t1 = static_cast<const char *>(memchr(rbuf, '\t', |
4524 | + nl - rbuf)); |
4525 | + if (t1 == 0) { |
4526 | + fprintf(stderr, "error \n"); |
4527 | + break; |
4528 | + } |
4529 | + ++t1; |
4530 | + const char *t2 = static_cast<const char *>(memchr(t1, '\t', |
4531 | + nl - t1)); |
4532 | + if (t2 == 0) { |
4533 | + if (verbose > 1) { |
4534 | + fprintf(stderr, "key: notfound \n"); |
4535 | + } |
4536 | + break; |
4537 | + } |
4538 | + ++t2; |
4539 | + if (t1 == rbuf + 2 && rbuf[0] == '0') { |
4540 | + if (op == 'G') { |
4541 | + ++op_success_count; |
4542 | + arg.sh.increment_count(); |
4543 | + } else if (op == 'U') { |
4544 | + const char *t3 = t2; |
4545 | + while (t3 != nl && t3[0] >= 0x10) { |
4546 | + ++t3; |
4547 | + } |
4548 | + if (t3 != t2 + 1 || t2[0] != '1') { |
4549 | + const std::string mess(t2, t3); |
4550 | + fprintf(stderr, "mod: %s\n", mess.c_str()); |
4551 | + } else { |
4552 | + ++op_success_count; |
4553 | + arg.sh.increment_count(); |
4554 | + if (arg.sh.dump && arg.sh.pipe == 1) { |
4555 | + fwrite(wbuf.begin(), wbuf.size(), 1, stderr); |
4556 | + } |
4557 | + } |
4558 | + } |
4559 | + } else { |
4560 | + const char *t3 = t2; |
4561 | + while (t3 != nl && t3[0] >= 0x10) { |
4562 | + ++t3; |
4563 | + } |
4564 | + const std::string mess(t2, t3); |
4565 | + fprintf(stderr, "err: %s\n", mess.c_str()); |
4566 | + } |
4567 | + const size_t rest_size = rbuf + read_pos - (nl + 1); |
4568 | + if (rest_size != 0) { |
4569 | + memmove(rbuf, nl + 1, rest_size); |
4570 | + } |
4571 | + read_pos = rest_size; |
4572 | + } |
4573 | + } |
4574 | + if (!keep_connection) { |
4575 | + fd.reset(); |
4576 | + arg.sh.increment_conn(-1); |
4577 | + } else if (keep_connection > 1 && ++keepconn_count > keep_connection) { |
4578 | + keepconn_count = 0; |
4579 | + fd.reset(); |
4580 | + arg.sh.increment_conn(-1); |
4581 | + } |
4582 | + const double tm2 = gettimeofday_double(); |
4583 | + set_timing(tm2 - tm1); |
4584 | + sleep_if(); |
4585 | + if (sched_flag) { |
4586 | + sched_yield(); |
4587 | + } |
4588 | + } |
4589 | + if (dump) { |
4590 | + fprintf(stderr, "done\n"); |
4591 | + } |
4592 | +} |
4593 | + |
4594 | +void |
4595 | +hstest_thread::sleep_if() |
4596 | +{ |
4597 | + if (arg.sh.usleep) { |
4598 | + struct timespec ts = { |
4599 | + arg.sh.usleep / 1000000, |
4600 | + (arg.sh.usleep % 1000000) * 1000 |
4601 | + }; |
4602 | + nanosleep(&ts, 0); |
4603 | + } |
4604 | +} |
4605 | + |
4606 | +void |
4607 | +hstest_thread::set_timing(double time_spent) |
4608 | +{ |
4609 | + response_min = std::min(response_min, time_spent); |
4610 | + response_max = std::max(response_max, time_spent); |
4611 | + response_sum += time_spent; |
4612 | + if (op_success_count != 0) { |
4613 | + response_avg = response_sum / op_success_count; |
4614 | + } |
4615 | +} |
4616 | + |
4617 | +void |
4618 | +hstest_thread::test_11(int test_num) |
4619 | +{ |
4620 | + const int keep_connection = arg.sh.conf.get_int("keep_connection", 1); |
4621 | + const int tablesize = arg.sh.conf.get_int("tablesize", 0); |
4622 | + unsigned int seed = arg.id; |
4623 | + seed ^= arg.sh.conf.get_int("seed_xor", 0); |
4624 | + std::string err; |
4625 | + hstcpcli_ptr cli; |
4626 | + for (size_t i = 0; i < arg.sh.loop; ++i) { |
4627 | + if (cli.get() == 0) { |
4628 | + cli = hstcpcli_i::create(arg.sh.arg); |
4629 | + cli->request_buf_open_index(0, "hstest", "hstest_table1", "", "v"); |
4630 | + /* pst_num, db, table, index, retflds */ |
4631 | + if (cli->request_send() != 0) { |
4632 | + fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str()); |
4633 | + return; |
4634 | + } |
4635 | + size_t num_flds = 0; |
4636 | + if (cli->response_recv(num_flds) != 0) { |
4637 | + fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str()); |
4638 | + return; |
4639 | + } |
4640 | + cli->response_buf_remove(); |
4641 | + } |
4642 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
4643 | + char buf[256]; |
4644 | + int k = 0, v = 0, len = 0; |
4645 | + { |
4646 | + k = rand_r(&seed); |
4647 | + v = rand_r(&seed); /* unused */ |
4648 | + if (tablesize != 0) { |
4649 | + k &= tablesize; |
4650 | + } |
4651 | + len = snprintf(buf, sizeof(buf), "%d", k); |
4652 | + } |
4653 | + const string_ref key(buf, len); |
4654 | + const string_ref op("=", 1); |
4655 | + cli->request_buf_exec_generic(0, op, &key, 1, 1, 0, string_ref(), 0, 0); |
4656 | + } |
4657 | + if (cli->request_send() != 0) { |
4658 | + fprintf(stderr, "reuqest_send: %s\n", cli->get_error().c_str()); |
4659 | + return; |
4660 | + } |
4661 | + size_t read_cnt = 0; |
4662 | + for (size_t j = 0; j < arg.sh.pipe; ++j) { |
4663 | + size_t num_flds = 0; |
4664 | + if (cli->response_recv(num_flds) != 0) { |
4665 | + fprintf(stderr, "reuqest_recv: %s\n", cli->get_error().c_str()); |
4666 | + return; |
4667 | + } |
4668 | + { |
4669 | + ++read_cnt; |
4670 | + ++io_success_count; |
4671 | + arg.sh.increment_count(); |
4672 | + { |
4673 | + ++op_success_count; |
4674 | + } |
4675 | + } |
4676 | + cli->response_buf_remove(); |
4677 | + } |
4678 | + if (!keep_connection) { |
4679 | + cli.reset(); |
4680 | + } |
4681 | + } |
4682 | +} |
4683 | + |
4684 | +void |
4685 | +hstest_thread::test_watch() |
4686 | +{ |
4687 | + const int timelimit = arg.sh.conf.get_int("timelimit", 0); |
4688 | + const int timelimit_offset = timelimit / 2; |
4689 | + int loop = 0; |
4690 | + double t1 = 0, t2 = 0; |
4691 | + size_t cnt_t1 = 0, cnt_t2 = 0; |
4692 | + size_t prev_cnt = 0; |
4693 | + double now_f = 0; |
4694 | + while (true) { |
4695 | + sleep(1); |
4696 | + const size_t cnt = arg.sh.count; |
4697 | + const size_t df = cnt - prev_cnt; |
4698 | + prev_cnt = cnt; |
4699 | + const double now_prev = now_f; |
4700 | + now_f = gettimeofday_double(); |
4701 | + if (now_prev != 0) { |
4702 | + const double rps = static_cast<double>(df) / (now_f - now_prev); |
4703 | + fprintf(stderr, "now: %zu cntdiff: %zu tdiff: %f rps: %f\n", |
4704 | + static_cast<size_t>(now_f), df, now_f - now_prev, rps); |
4705 | + } |
4706 | + if (timelimit != 0) { |
4707 | + if (arg.sh.wait_conn == 0 || arg.sh.conn_count >= arg.sh.wait_conn) { |
4708 | + ++loop; |
4709 | + } |
4710 | + if (loop == timelimit_offset) { |
4711 | + t1 = gettimeofday_double(); |
4712 | + cnt_t1 = cnt; |
4713 | + arg.sh.enable_timing = 1; |
4714 | + fprintf(stderr, "start timing\n"); |
4715 | + } else if (loop == timelimit_offset + timelimit) { |
4716 | + t2 = gettimeofday_double(); |
4717 | + cnt_t2 = cnt; |
4718 | + const size_t cnt_diff = cnt_t2 - cnt_t1; |
4719 | + const double tdiff = t2 - t1; |
4720 | + const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1); |
4721 | + fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n", |
4722 | + t1, cnt_t1, t2, cnt_t2, qps); |
4723 | + size_t keycnt = 0; |
4724 | + for (int i = 0; i < arg.sh.keygen_size; ++i) { |
4725 | + if (arg.sh.keygen[i]) { |
4726 | + ++keycnt; |
4727 | + } |
4728 | + } |
4729 | + fprintf(stderr, "keygen=%zu\n", keycnt); |
4730 | + break; |
4731 | + } |
4732 | + } |
4733 | + } |
4734 | +#if 0 |
4735 | + int loop = 0; |
4736 | + double t1 = 0, t2 = 0; |
4737 | + size_t cnt_t1 = 0, cnt_t2 = 0; |
4738 | + size_t prev_cnt = 0; |
4739 | + while (true) { |
4740 | + sleep(1); |
4741 | + const size_t cnt = arg.sh.count; |
4742 | + const size_t df = cnt - prev_cnt; |
4743 | + prev_cnt = cnt; |
4744 | + const size_t now = time(0); |
4745 | + fprintf(stderr, "%zu %zu\n", now, df); |
4746 | + if (timelimit != 0) { |
4747 | + ++loop; |
4748 | + if (loop == timelimit_offset) { |
4749 | + t1 = gettimeofday_double(); |
4750 | + cnt_t1 = cnt; |
4751 | + } else if (loop == timelimit_offset + timelimit) { |
4752 | + t2 = gettimeofday_double(); |
4753 | + cnt_t2 = cnt; |
4754 | + const size_t cnt_diff = cnt_t2 - cnt_t1; |
4755 | + const double tdiff = t2 - t1; |
4756 | + const double qps = cnt_diff / (tdiff != 0 ? tdiff : 1); |
4757 | + fprintf(stderr, "(%f: %zu, %f: %zu), %10.5f qps\n", |
4758 | + t1, cnt_t1, t2, cnt_t2, qps); |
4759 | + size_t keycnt = 0; |
4760 | + for (int i = 0; i < arg.sh.keygen_size; ++i) { |
4761 | + if (arg.sh.keygen[i]) { |
4762 | + ++keycnt; |
4763 | + } |
4764 | + } |
4765 | + fprintf(stderr, "keygen=%zu\n", keycnt); |
4766 | + _exit(0); |
4767 | + } |
4768 | + } |
4769 | + } |
4770 | +#endif |
4771 | +} |
4772 | + |
4773 | +void |
4774 | +hstest_thread::test_12(int test_num) |
4775 | +{ |
4776 | + /* NOTE: num_threads should be 1 */ |
4777 | + /* create table hstest |
4778 | + * ( k varchar(255) not null, v varchar(255) not null, primary key(k)) |
4779 | + * engine = innodb; */ |
4780 | + mysqltest_thread_initobj initobj; |
4781 | + auto_mysql db; |
4782 | + std::string err; |
4783 | + unsigned long long err_cnt = 0; |
4784 | + unsigned long long query_cnt = 0; |
4785 | + #if 0 |
4786 | + my_bool reconnect = 0; |
4787 | + if (mysql_options(db, MYSQL_OPT_RECONNECT, &reconnect) != 0) { |
4788 | + err = "mysql_options() failed"; |
4789 | + ++err_cnt; |
4790 | + return; |
4791 | + } |
4792 | + #endif |
4793 | + const std::string mysql_host = arg.sh.conf.get_str("host", "localhost"); |
4794 | + const int mysql_port = arg.sh.conf.get_int("mysqlport", 3306); |
4795 | + const unsigned int num = arg.sh.loop; |
4796 | + const size_t pipe = arg.sh.pipe; |
4797 | + const std::string mysql_user = arg.sh.conf.get_str("mysqluser", "root"); |
4798 | + const std::string mysql_passwd = arg.sh.conf.get_str("mysqlpass", ""); |
4799 | + const std::string mysql_dbname = arg.sh.conf.get_str("db", "hstest"); |
4800 | + const int keep_connection = arg.sh.conf.get_int("keep_connection", 1); |
4801 | + const int verbose = arg.sh.conf.get_int("verbose", 1); |
4802 | + const int use_handler = arg.sh.conf.get_int("handler", 0); |
4803 | + int connected = 0; |
4804 | + unsigned int k = 0; |
4805 | + string_buffer buf; |
4806 | + for (unsigned int i = 0; i < num; ++i) { |
4807 | + const int flags = 0; |
4808 | + if (connected == 0 && !mysql_real_connect(db, mysql_host.c_str(), |
4809 | + mysql_user.c_str(), mysql_user.empty() ? 0 : mysql_passwd.c_str(), |
4810 | + mysql_dbname.c_str(), mysql_port, 0, flags)) { |
4811 | + err = "failed to connect: " + std::string(mysql_error(db)); |
4812 | + if (verbose >= 1) { |
4813 | + fprintf(stderr, "e=[%s]\n", err.c_str()); |
4814 | + } |
4815 | + ++err_cnt; |
4816 | + return; |
4817 | + } |
4818 | + int r = 0; |
4819 | + if (connected == 0 && use_handler) { |
4820 | + const char *const q = "handler hstest open"; |
4821 | + r = mysql_real_query(db, q, strlen(q)); |
4822 | + if (r != 0) { |
4823 | + err = 1; |
4824 | + } |
4825 | + } |
4826 | + connected = 1; |
4827 | + std::string result_str; |
4828 | + unsigned int err = 0; |
4829 | + unsigned int num_flds = 0, num_affected_rows = 0; |
4830 | + int got_data = 0; |
4831 | + buf.clear(); |
4832 | + buf.append_literal("insert into hstest values "); |
4833 | + for (size_t j = 0; j < pipe; ++j) { |
4834 | + const unsigned int v = ~k; |
4835 | + if (j != 0) { |
4836 | + buf.append_literal(","); |
4837 | + } |
4838 | + char *wp = buf.make_space(64); |
4839 | + int buf_query_len = snprintf(wp, 64, "('k%u', 'v%u')", k, v); |
4840 | + buf.space_wrote(buf_query_len); |
4841 | + ++k; |
4842 | + } |
4843 | + if (r == 0) { |
4844 | + r = mysql_real_query(db, buf.begin(), buf.size()); |
4845 | + ++query_cnt; |
4846 | + } |
4847 | + if (r != 0) { |
4848 | + err = 1; |
4849 | + } else { |
4850 | + auto_mysql_res res(db); |
4851 | + if (res != 0) { |
4852 | + if (verbose >= 0) { |
4853 | + num_flds = mysql_num_fields(res); |
4854 | + MYSQL_ROW row = 0; |
4855 | + while ((row = mysql_fetch_row(res)) != 0) { |
4856 | + got_data = 1; |
4857 | + unsigned long *const lengths = mysql_fetch_lengths(res); |
4858 | + if (verbose >= 2) { |
4859 | + for (unsigned int i = 0; i < num_flds; ++i) { |
4860 | + if (!result_str.empty()) { |
4861 | + result_str += " "; |
4862 | + } |
4863 | + result_str += std::string(row[i], lengths[i]); |
4864 | + } |
4865 | + } |
4866 | + } |
4867 | + } |
4868 | + } else { |
4869 | + if (mysql_field_count(db) == 0) { |
4870 | + num_affected_rows = mysql_affected_rows(db); |
4871 | + } else { |
4872 | + err = 1; |
4873 | + } |
4874 | + } |
4875 | + } |
4876 | + if (verbose >= 2 || (verbose >= 1 && err != 0)) { |
4877 | + if (err) { |
4878 | + ++err_cnt; |
4879 | + const char *const errstr = mysql_error(db); |
4880 | + fprintf(stderr, "e=[%s] a=%u q=[%s]\n", errstr, |
4881 | + num_affected_rows, std::string(buf.begin(), buf.size()).c_str()); |
4882 | + } else { |
4883 | + fprintf(stderr, "a=%u q=[%s] r=[%s]\n", num_affected_rows, |
4884 | + std::string(buf.begin(), buf.size()).c_str(), |
4885 | + result_str.c_str()); |
4886 | + } |
4887 | + } |
4888 | + if (err == 0) { |
4889 | + ++io_success_count; |
4890 | + if (num_affected_rows > 0 || got_data > 0) { |
4891 | + ++op_success_count; |
4892 | + } |
4893 | + arg.sh.increment_count(pipe); |
4894 | + } |
4895 | + if (!keep_connection) { |
4896 | + db.reset(); |
4897 | + connected = 0; |
4898 | + } |
4899 | + } |
4900 | + if (verbose >= 1) { |
4901 | + fprintf(stderr, "thread finished (error_count=%llu)\n", err_cnt); |
4902 | + } |
4903 | +} |
4904 | + |
4905 | +void |
4906 | +hstest_thread::test_21(int num) |
4907 | +{ |
4908 | + /* fsync test */ |
4909 | + unsigned int id = arg.id; |
4910 | + std::string err; |
4911 | + #if 0 |
4912 | + if (socket_connect(fd, arg.sh.arg, err) != 0) { |
4913 | + fprintf(stderr, "connect: %d %s\n", errno, strerror(errno)); |
4914 | + return; |
4915 | + } |
4916 | + #endif |
4917 | + auto_file logfd; |
4918 | + char fname[1024]; |
4919 | + snprintf(fname, sizeof(fname), "synctest_%u", id); |
4920 | + int open_flags = O_WRONLY | O_CREAT | O_TRUNC | O_APPEND; |
4921 | + logfd.reset(open(fname, open_flags, 0644)); |
4922 | + if (logfd.get() < 0) { |
4923 | + fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno)); |
4924 | + return; |
4925 | + } |
4926 | + char buf[1024]; |
4927 | + unsigned long long count = 0; |
4928 | + while (true) { |
4929 | + snprintf(buf, sizeof(buf), "%u %llu\n", id, count); |
4930 | + const size_t len = strlen(buf); |
4931 | + if (write(logfd.get(), buf, len) != (ssize_t)len) { |
4932 | + fprintf(stderr, "write: %s: %d %s\n", fname, errno, strerror(errno)); |
4933 | + return; |
4934 | + } |
4935 | + #if 0 |
4936 | + if (write(fd.get(), buf, len) != (ssize_t)len) { |
4937 | + fprintf(stderr, "write(sock): %d %s\n", errno, strerror(errno)); |
4938 | + return; |
4939 | + } |
4940 | + #endif |
4941 | + if (fdatasync(logfd.get()) != 0) { |
4942 | + fprintf(stderr, "fsync: %s: %d %s\n", fname, errno, strerror(errno)); |
4943 | + return; |
4944 | + } |
4945 | + ++count; |
4946 | + ++op_success_count; |
4947 | + arg.sh.increment_count(); |
4948 | + } |
4949 | +} |
4950 | + |
4951 | +void |
4952 | +hstest_thread::test_22(int num) |
4953 | +{ |
4954 | + /* dd if=/dev/zero of=dummy.dat bs=1024M count=100 */ |
4955 | + unsigned int id = arg.id; |
4956 | + std::string err; |
4957 | + auto_file filefd; |
4958 | + char fname[1024]; |
4959 | + snprintf(fname, sizeof(fname), "dummy.dat"); |
4960 | + int open_flags = O_RDONLY | O_DIRECT; |
4961 | + filefd.reset(open(fname, open_flags, 0644)); |
4962 | + if (filefd.get() < 0) { |
4963 | + fprintf(stderr, "open: %s: %d %s\n", fname, errno, strerror(errno)); |
4964 | + return; |
4965 | + } |
4966 | + char buf_x[4096 * 2]; |
4967 | + char *const buf = (char *)(size_t(buf_x + 4096) / 4096 * 4096); |
4968 | + unsigned long long count = 0; |
4969 | + drand48_data randbuf; |
4970 | + unsigned long long seed = time(0); |
4971 | + seed *= 10; |
4972 | + seed += id; |
4973 | + srand48_r(seed, &randbuf); |
4974 | + for (unsigned int i = 0; i < arg.sh.loop; ++i) { |
4975 | + double kf = 0; |
4976 | + drand48_r(&randbuf, &kf); |
4977 | + kf *= (209715200 / 1); |
4978 | + // fprintf(stderr, "v=%f\n", kf); |
4979 | + off_t v = static_cast<off_t>(kf); |
4980 | + v %= (209715200 / 1); |
4981 | + v *= (512 * 1); |
4982 | + const double tm1 = gettimeofday_double(); |
4983 | + const ssize_t r = pread(filefd.get(), buf, (512 * 1), v); |
4984 | + const double tm2 = gettimeofday_double(); |
4985 | + if (r < 0) { |
4986 | + fprintf(stderr, "pread: %s: %d %s\n", fname, errno, strerror(errno)); |
4987 | + return; |
4988 | + } |
4989 | + ++count; |
4990 | + ++op_success_count; |
4991 | + arg.sh.increment_count(); |
4992 | + set_timing(tm2 - tm1); |
4993 | + } |
4994 | +} |
4995 | + |
4996 | +void |
4997 | +hstest_thread::operator ()() |
4998 | +{ |
4999 | + if (arg.watch_flag) { |
5000 | + return test_watch(); |
The diff has been truncated for viewing.
Same comment as for the 5.1 MP.
Also, for 5.5, is it a merge from 5.1? I'm asking because the commit message does not say "merge from 5.1" or similar.