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