mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / myisam / mi_test3.c
blobf6226809ff1c03d7488b38050cfe8e22994f5638
1 /* Copyright (c) 2000-2008 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 /* Test av locking */
18 #ifndef __NETWARE__
20 #include "myisam.h"
21 #include <sys/types.h>
22 #ifdef HAVE_SYS_WAIT_H
23 # include <sys/wait.h>
24 #endif
25 #ifndef WEXITSTATUS
26 # define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)
27 #endif
28 #ifndef WIFEXITED
29 # define WIFEXITED(stat_val) (((stat_val) & 255) == 0)
30 #endif
33 #if defined(HAVE_LRAND48)
34 #define rnd(X) (lrand48() % X)
35 #define rnd_init(X) srand48(X)
36 #else
37 #define rnd(X) (random() % X)
38 #define rnd_init(X) srandom(X)
39 #endif
42 const char *filename= "test3";
43 uint tests=10,forks=10,key_cacheing=0,use_log=0;
45 static void get_options(int argc, char *argv[]);
46 void start_test(int id);
47 int test_read(MI_INFO *,int),test_write(MI_INFO *,int,int),
48 test_update(MI_INFO *,int,int),test_rrnd(MI_INFO *,int);
50 struct record {
51 uchar id[8];
52 uchar nr[4];
53 uchar text[10];
54 } record;
57 int main(int argc,char **argv)
59 int status,wait_ret;
60 uint i=0;
61 MI_KEYDEF keyinfo[10];
62 MI_COLUMNDEF recinfo[10];
63 HA_KEYSEG keyseg[10][2];
64 MY_INIT(argv[0]);
65 get_options(argc,argv);
67 bzero((char*) keyinfo,sizeof(keyinfo));
68 bzero((char*) recinfo,sizeof(recinfo));
69 bzero((char*) keyseg,sizeof(keyseg));
70 keyinfo[0].seg= &keyseg[0][0];
71 keyinfo[0].seg[0].start=0;
72 keyinfo[0].seg[0].length=8;
73 keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT;
74 keyinfo[0].seg[0].flag=HA_SPACE_PACK;
75 keyinfo[0].key_alg=HA_KEY_ALG_BTREE;
76 keyinfo[0].keysegs=1;
77 keyinfo[0].flag = (uint8) HA_PACK_KEY;
78 keyinfo[0].block_length= 0; /* Default block length */
79 keyinfo[1].seg= &keyseg[1][0];
80 keyinfo[1].seg[0].start=8;
81 keyinfo[1].seg[0].length=4; /* Long is always 4 in myisam */
82 keyinfo[1].seg[0].type=HA_KEYTYPE_LONG_INT;
83 keyinfo[1].seg[0].flag=0;
84 keyinfo[1].key_alg=HA_KEY_ALG_BTREE;
85 keyinfo[1].keysegs=1;
86 keyinfo[1].flag =HA_NOSAME;
87 keyinfo[1].block_length= 0; /* Default block length */
89 recinfo[0].type=0;
90 recinfo[0].length=sizeof(record.id);
91 recinfo[1].type=0;
92 recinfo[1].length=sizeof(record.nr);
93 recinfo[2].type=0;
94 recinfo[2].length=sizeof(record.text);
96 puts("- Creating myisam-file");
97 my_delete(filename,MYF(0)); /* Remove old locks under gdb */
98 if (mi_create(filename,2,&keyinfo[0],2,&recinfo[0],0,(MI_UNIQUEDEF*) 0,
99 (MI_CREATE_INFO*) 0,0))
100 exit(1);
102 rnd_init(0);
103 printf("- Starting %d processes\n",forks); fflush(stdout);
104 for (i=0 ; i < forks; i++)
106 if (!fork())
108 start_test(i+1);
109 sleep(1);
110 return 0;
112 VOID(rnd(1));
115 for (i=0 ; i < forks ; i++)
116 while ((wait_ret=wait(&status)) && wait_ret == -1);
117 return 0;
121 static void get_options(int argc, char **argv)
123 char *pos,*progname;
125 progname= argv[0];
127 while (--argc >0 && *(pos = *(++argv)) == '-' ) {
128 switch(*++pos) {
129 case 'l':
130 use_log=1;
131 break;
132 case 'f':
133 forks=atoi(++pos);
134 break;
135 case 't':
136 tests=atoi(++pos);
137 break;
138 case 'K': /* Use key cacheing */
139 key_cacheing=1;
140 break;
141 case 'A': /* All flags */
142 use_log=key_cacheing=1;
143 break;
144 case '?':
145 case 'I':
146 case 'V':
147 printf("%s Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
148 puts("By Monty, for your professional use\n");
149 puts("Test av locking with threads\n");
150 printf("Usage: %s [-?lKA] [-f#] [-t#]\n",progname);
151 exit(0);
152 case '#':
153 DBUG_PUSH (++pos);
154 break;
155 default:
156 printf("Illegal option: '%c'\n",*pos);
157 break;
160 return;
164 void start_test(int id)
166 uint i;
167 int error,lock_type;
168 MI_ISAMINFO isam_info;
169 MI_INFO *file,*file1,*file2=0,*lock;
171 if (use_log)
172 mi_log(1);
173 if (!(file1=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)) ||
174 !(file2=mi_open(filename,O_RDWR,HA_OPEN_WAIT_IF_LOCKED)))
176 fprintf(stderr,"Can't open isam-file: %s\n",filename);
177 exit(1);
179 if (key_cacheing && rnd(2) == 0)
180 init_key_cache(dflt_key_cache, KEY_CACHE_BLOCK_SIZE, 65536L, 0, 0);
181 printf("Process %d, pid: %d\n",id,getpid()); fflush(stdout);
183 for (error=i=0 ; i < tests && !error; i++)
185 file= (rnd(2) == 1) ? file1 : file2;
186 lock=0 ; lock_type=0;
187 if (rnd(10) == 0)
189 if (mi_lock_database(lock=(rnd(2) ? file1 : file2),
190 lock_type=(rnd(2) == 0 ? F_RDLCK : F_WRLCK)))
192 fprintf(stderr,"%2d: start: Can't lock table %d\n",id,my_errno);
193 error=1;
194 break;
197 switch (rnd(4)) {
198 case 0: error=test_read(file,id); break;
199 case 1: error=test_rrnd(file,id); break;
200 case 2: error=test_write(file,id,lock_type); break;
201 case 3: error=test_update(file,id,lock_type); break;
203 if (lock)
204 mi_lock_database(lock,F_UNLCK);
206 if (!error)
208 mi_status(file1,&isam_info,HA_STATUS_VARIABLE);
209 printf("%2d: End of test. Records: %ld Deleted: %ld\n",
210 id,(long) isam_info.records, (long) isam_info.deleted);
211 fflush(stdout);
214 mi_close(file1);
215 mi_close(file2);
216 if (use_log)
217 mi_log(0);
218 if (error)
220 printf("%2d: Aborted\n",id); fflush(stdout);
221 exit(1);
226 int test_read(MI_INFO *file,int id)
228 uint i,lock,found,next,prev;
229 ulong find;
231 lock=0;
232 if (rnd(2) == 0)
234 lock=1;
235 if (mi_lock_database(file,F_RDLCK))
237 fprintf(stderr,"%2d: Can't lock table %d\n",id,my_errno);
238 return 1;
242 found=next=prev=0;
243 for (i=0 ; i < 100 ; i++)
245 find=rnd(100000);
246 if (!mi_rkey(file,record.id,1,(uchar*) &find, HA_WHOLE_KEY,
247 HA_READ_KEY_EXACT))
248 found++;
249 else
251 if (my_errno != HA_ERR_KEY_NOT_FOUND)
253 fprintf(stderr,"%2d: Got error %d from read in read\n",id,my_errno);
254 return 1;
256 else if (!mi_rnext(file,record.id,1))
257 next++;
258 else
260 if (my_errno != HA_ERR_END_OF_FILE)
262 fprintf(stderr,"%2d: Got error %d from rnext in read\n",id,my_errno);
263 return 1;
265 else if (!mi_rprev(file,record.id,1))
266 prev++;
267 else
269 if (my_errno != HA_ERR_END_OF_FILE)
271 fprintf(stderr,"%2d: Got error %d from rnext in read\n",
272 id,my_errno);
273 return 1;
279 if (lock)
281 if (mi_lock_database(file,F_UNLCK))
283 fprintf(stderr,"%2d: Can't unlock table\n",id);
284 return 1;
287 printf("%2d: read: found: %5d next: %5d prev: %5d\n",
288 id,found,next,prev);
289 fflush(stdout);
290 return 0;
294 int test_rrnd(MI_INFO *file,int id)
296 uint count,lock;
298 lock=0;
299 if (rnd(2) == 0)
301 lock=1;
302 if (mi_lock_database(file,F_RDLCK))
304 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
305 mi_close(file);
306 return 1;
308 if (rnd(2) == 0)
309 mi_extra(file,HA_EXTRA_CACHE,0);
312 count=0;
313 if (mi_rrnd(file,record.id,0L))
315 if (my_errno == HA_ERR_END_OF_FILE)
316 goto end;
317 fprintf(stderr,"%2d: Can't read first record (%d)\n",id,my_errno);
318 return 1;
320 for (count=1 ; !mi_rrnd(file,record.id,HA_OFFSET_ERROR) ;count++) ;
321 if (my_errno != HA_ERR_END_OF_FILE)
323 fprintf(stderr,"%2d: Got error %d from rrnd\n",id,my_errno);
324 return 1;
327 end:
328 if (lock)
330 mi_extra(file,HA_EXTRA_NO_CACHE,0);
331 if (mi_lock_database(file,F_UNLCK))
333 fprintf(stderr,"%2d: Can't unlock table\n",id);
334 exit(0);
337 printf("%2d: rrnd: %5d\n",id,count); fflush(stdout);
338 return 0;
342 int test_write(MI_INFO *file,int id,int lock_type)
344 uint i,tries,count,lock;
346 lock=0;
347 if (rnd(2) == 0 || lock_type == F_RDLCK)
349 lock=1;
350 if (mi_lock_database(file,F_WRLCK))
352 if (lock_type == F_RDLCK && my_errno == EDEADLK)
354 printf("%2d: write: deadlock\n",id); fflush(stdout);
355 return 0;
357 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
358 mi_close(file);
359 return 1;
361 if (rnd(2) == 0)
362 mi_extra(file,HA_EXTRA_WRITE_CACHE,0);
365 sprintf((char*) record.id,"%7d",getpid());
366 strnmov((char*) record.text,"Testing...", sizeof(record.text));
368 tries=(uint) rnd(100)+10;
369 for (i=count=0 ; i < tries ; i++)
371 uint32 tmp=rnd(80000)+20000;
372 int4store(record.nr,tmp);
373 if (!mi_write(file,record.id))
374 count++;
375 else
377 if (my_errno != HA_ERR_FOUND_DUPP_KEY)
379 fprintf(stderr,"%2d: Got error %d (errno %d) from write\n",id,my_errno,
380 errno);
381 return 1;
385 if (lock)
387 mi_extra(file,HA_EXTRA_NO_CACHE,0);
388 if (mi_lock_database(file,F_UNLCK))
390 fprintf(stderr,"%2d: Can't unlock table\n",id);
391 exit(0);
394 printf("%2d: write: %5d\n",id,count); fflush(stdout);
395 return 0;
399 int test_update(MI_INFO *file,int id,int lock_type)
401 uint i,lock,found,next,prev,update;
402 uint32 tmp;
403 char find[4];
404 struct record new_record;
406 lock=0;
407 if (rnd(2) == 0 || lock_type == F_RDLCK)
409 lock=1;
410 if (mi_lock_database(file,F_WRLCK))
412 if (lock_type == F_RDLCK && my_errno == EDEADLK)
414 printf("%2d: write: deadlock\n",id); fflush(stdout);
415 return 0;
417 fprintf(stderr,"%2d: Can't lock table (%d)\n",id,my_errno);
418 return 1;
421 bzero((char*) &new_record,sizeof(new_record));
422 strmov((char*) new_record.text,"Updated");
424 found=next=prev=update=0;
425 for (i=0 ; i < 100 ; i++)
427 tmp=rnd(100000);
428 int4store(find,tmp);
429 if (!mi_rkey(file,record.id,1,(uchar*) find, HA_WHOLE_KEY,
430 HA_READ_KEY_EXACT))
431 found++;
432 else
434 if (my_errno != HA_ERR_KEY_NOT_FOUND)
436 fprintf(stderr,"%2d: Got error %d from read in update\n",id,my_errno);
437 return 1;
439 else if (!mi_rnext(file,record.id,1))
440 next++;
441 else
443 if (my_errno != HA_ERR_END_OF_FILE)
445 fprintf(stderr,"%2d: Got error %d from rnext in update\n",
446 id,my_errno);
447 return 1;
449 else if (!mi_rprev(file,record.id,1))
450 prev++;
451 else
453 if (my_errno != HA_ERR_END_OF_FILE)
455 fprintf(stderr,"%2d: Got error %d from rnext in update\n",
456 id,my_errno);
457 return 1;
459 continue;
463 memcpy_fixed(new_record.id,record.id,sizeof(record.id));
464 tmp=rnd(20000)+40000;
465 int4store(new_record.nr,tmp);
466 if (!mi_update(file,record.id,new_record.id))
467 update++;
468 else
470 if (my_errno != HA_ERR_RECORD_CHANGED &&
471 my_errno != HA_ERR_RECORD_DELETED &&
472 my_errno != HA_ERR_FOUND_DUPP_KEY)
474 fprintf(stderr,"%2d: Got error %d from update\n",id,my_errno);
475 return 1;
479 if (lock)
481 if (mi_lock_database(file,F_UNLCK))
483 fprintf(stderr,"Can't unlock table,id, error%d\n",my_errno);
484 return 1;
487 printf("%2d: update: %5d\n",id,update); fflush(stdout);
488 return 0;
491 #else /* __NETWARE__ */
493 #include <stdio.h>
495 main()
497 fprintf(stderr,"this test has not been ported to NetWare\n");
498 return 0;
501 #endif /* __NETWARE__ */