mySQL 5.0.11 sources for tomato
[tomato.git] / release / src / router / mysql / storage / heap / hp_test2.c
blob17b6cffca0b30a2a46352ea1706bdaf9737381ef
1 /*
2 Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; version 2 of the License.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
13 You should have received a copy of the GNU General Public License
14 along with this program; if not, write to the Free Software
15 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 /* Test av isam-databas: stor test */
20 #ifndef USE_MY_FUNC /* We want to be able to dbug this !! */
21 #define USE_MY_FUNC
22 #endif
23 #ifdef DBUG_OFF
24 #undef DBUG_OFF
25 #endif
26 #ifndef SAFEMALLOC
27 #define SAFEMALLOC
28 #endif
30 #include "heapdef.h" /* Because of hp_find_block */
31 #include <signal.h>
33 #define MAX_RECORDS 100000
34 #define MAX_KEYS 4
36 static int get_options(int argc, char *argv[]);
37 static int rnd(int max_value);
38 static sig_handler endprog(int sig_number);
40 static uint flag=0,verbose=0,testflag=0,recant=10000,silent=0;
41 static uint keys=MAX_KEYS;
42 static uint16 key1[1001];
43 static my_bool key3[MAX_RECORDS];
44 static int reclength=39;
47 static int calc_check(uchar *buf,uint length);
48 static void make_record(uchar *record, uint n1, uint n2, uint n3,
49 const char *mark, uint count);
51 /* Main program */
53 int main(int argc, char *argv[])
55 register uint i,j;
56 uint ant,n1,n2,n3;
57 uint write_count,update,opt_delete,check2,dupp_keys,found_key;
58 int error;
59 ulong pos;
60 unsigned long key_check;
61 uchar record[128],record2[128],record3[128],key[10];
62 const char *filename,*filename2;
63 HP_INFO *file,*file2;
64 HP_SHARE *tmp_share;
65 HP_KEYDEF keyinfo[MAX_KEYS];
66 HA_KEYSEG keyseg[MAX_KEYS*5];
67 HEAP_PTR UNINIT_VAR(position);
68 HP_CREATE_INFO hp_create_info;
69 CHARSET_INFO *cs= &my_charset_latin1;
70 MY_INIT(argv[0]); /* init my_sys library & pthreads */
72 filename= "test2";
73 filename2= "test2_2";
74 file=file2=0;
75 get_options(argc,argv);
77 bzero(&hp_create_info, sizeof(hp_create_info));
78 hp_create_info.max_table_size= 1024L*1024L;
80 write_count=update=opt_delete=0;
81 key_check=0;
83 keyinfo[0].seg=keyseg;
84 keyinfo[0].keysegs=1;
85 keyinfo[0].flag= 0;
86 keyinfo[0].algorithm= HA_KEY_ALG_HASH;
87 keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
88 keyinfo[0].seg[0].start=0;
89 keyinfo[0].seg[0].length=6;
90 keyinfo[0].seg[0].null_bit=0;
91 keyinfo[0].seg[0].charset=cs;
92 keyinfo[1].seg=keyseg+1;
93 keyinfo[1].keysegs=2;
94 keyinfo[1].flag=0;
95 keyinfo[1].algorithm= HA_KEY_ALG_HASH;
96 keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
97 keyinfo[1].seg[0].start=7;
98 keyinfo[1].seg[0].length=6;
99 keyinfo[1].seg[0].null_bit=0;
100 keyinfo[1].seg[0].charset=cs;
101 keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
102 keyinfo[1].seg[1].start=0; /* key in two parts */
103 keyinfo[1].seg[1].length=6;
104 keyinfo[1].seg[1].null_bit=0;
105 keyinfo[1].seg[1].charset=cs;
106 keyinfo[2].seg=keyseg+3;
107 keyinfo[2].keysegs=1;
108 keyinfo[2].flag=HA_NOSAME;
109 keyinfo[2].algorithm= HA_KEY_ALG_HASH;
110 keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
111 keyinfo[2].seg[0].start=12;
112 keyinfo[2].seg[0].length=8;
113 keyinfo[2].seg[0].null_bit=0;
114 keyinfo[2].seg[0].charset=cs;
115 keyinfo[3].seg=keyseg+4;
116 keyinfo[3].keysegs=1;
117 keyinfo[3].flag=HA_NOSAME;
118 keyinfo[3].algorithm= HA_KEY_ALG_HASH;
119 keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY;
120 keyinfo[3].seg[0].start=37;
121 keyinfo[3].seg[0].length=1;
122 keyinfo[3].seg[0].null_bit=1;
123 keyinfo[3].seg[0].null_pos=38;
124 keyinfo[3].seg[0].charset=cs;
126 bzero((char*) key1,sizeof(key1));
127 bzero((char*) key3,sizeof(key3));
129 printf("- Creating heap-file\n");
130 if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
131 (ulong) recant/2, &hp_create_info, &tmp_share) ||
132 !(file= heap_open(filename, 2)))
133 goto err;
134 signal(SIGINT,endprog);
136 printf("- Writing records:s\n");
137 strmov((char*) record," ..... key");
139 for (i=0 ; i < recant ; i++)
141 n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
142 make_record(record,n1,n2,n3,"Pos",write_count);
144 if (heap_write(file,record))
146 if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
148 printf("Error: %d in write at record: %d\n",my_errno,i);
149 goto err;
151 if (verbose) printf(" Double key: %d\n",n3);
153 else
155 if (key3[n3] == 1)
157 printf("Error: Didn't get error when writing second key: '%8d'\n",n3);
158 goto err;
160 write_count++; key1[n1]++; key3[n3]=1;
161 key_check+=n1;
163 if (testflag == 1 && heap_check_heap(file,0))
165 puts("Heap keys crashed");
166 goto err;
169 if (testflag == 1)
170 goto end;
171 if (heap_check_heap(file,0))
173 puts("Heap keys crashed");
174 goto err;
177 printf("- Delete\n");
178 for (i=0 ; i < write_count/10 ; i++)
180 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
181 if (j != 0)
183 sprintf((char*) key,"%6d",j);
184 if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
186 printf("can't find key1: \"%s\"\n",(char*) key);
187 goto err;
189 #ifdef NOT_USED
190 if (file->current_ptr == hp_find_block(&file->s->block,0) ||
191 file->current_ptr == hp_find_block(&file->s->block,1))
192 continue; /* Don't remove 2 first records */
193 #endif
194 if (heap_delete(file,record))
196 printf("error: %d; can't delete record: \"%s\"\n", my_errno,(char*) record);
197 goto err;
199 opt_delete++;
200 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
201 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
202 key_check-=atoi((char*) record);
203 if (testflag == 2 && heap_check_heap(file,0))
205 puts("Heap keys crashed");
206 goto err;
209 else
210 puts("Warning: Skipping delete test because no dupplicate keys");
212 if (testflag==2) goto end;
213 if (heap_check_heap(file,0))
215 puts("Heap keys crashed");
216 goto err;
219 printf("- Update\n");
220 for (i=0 ; i < write_count/10 ; i++)
222 n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
223 make_record(record2, n1, n2, n3, "XXX", update);
224 if (rnd(2) == 1)
226 if (heap_scan_init(file))
227 goto err;
228 j=rnd(write_count-opt_delete);
229 while ((error=heap_scan(file,record) == HA_ERR_RECORD_DELETED) ||
230 (!error && j))
232 if (!error)
233 j--;
235 if (error)
236 goto err;
238 else
240 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
241 if (!key1[j])
242 continue;
243 sprintf((char*) key,"%6d",j);
244 if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
246 printf("can't find key1: \"%s\"\n",(char*) key);
247 goto err;
250 if (heap_update(file,record,record2))
252 if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
254 printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n",
255 my_errno,(char*) record, (char*) record2);
256 goto err;
258 if (verbose)
259 printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",
260 (char*) record, (char*) record2);
262 else
264 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
265 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
266 key1[n1]++; key3[n3]=1;
267 update++;
268 key_check=key_check-atoi((char*) record)+n1;
270 if (testflag == 3 && heap_check_heap(file,0))
272 puts("Heap keys crashed");
273 goto err;
276 if (testflag == 3) goto end;
277 if (heap_check_heap(file,0))
279 puts("Heap keys crashed");
280 goto err;
283 for (i=999, dupp_keys=found_key=0 ; i>0 ; i--)
285 if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; }
286 sprintf((char*) key,"%6d",found_key);
289 if (dupp_keys > 3)
291 if (!silent)
292 printf("- Read first key - next - delete - next -> last\n");
293 DBUG_PRINT("progpos",("first - next - delete - next -> last"));
295 if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
296 goto err;
297 if (heap_rnext(file,record3)) goto err;
298 if (heap_delete(file,record3)) goto err;
299 key_check-=atoi((char*) record3);
300 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
301 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
302 opt_delete++;
303 ant=2;
304 while ((error=heap_rnext(file,record3)) == 0 ||
305 error == HA_ERR_RECORD_DELETED)
306 if (! error)
307 ant++;
308 if (ant != dupp_keys)
310 printf("next: I can only find: %d records of %d\n",
311 ant,dupp_keys);
312 goto end;
314 dupp_keys--;
315 if (heap_check_heap(file,0))
317 puts("Heap keys crashed");
318 goto err;
321 if (!silent)
322 printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n");
324 if (heap_rlast(file,record3,0)) goto err;
325 if (heap_delete(file,record3)) goto err;
326 key_check-=atoi((char*) record3);
327 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
328 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
329 opt_delete++;
330 if (heap_rprev(file,record3) || heap_rprev(file,record3))
331 goto err;
332 if (heap_delete(file,record3)) goto err;
333 key_check-=atoi((char*) record3);
334 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
335 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
336 opt_delete++;
337 ant=3;
338 while ((error=heap_rprev(file,record3)) == 0 ||
339 error == HA_ERR_RECORD_DELETED)
341 if (! error)
342 ant++;
344 if (ant != dupp_keys)
346 printf("next: I can only find: %d records of %d\n",
347 ant,dupp_keys);
348 goto end;
350 dupp_keys-=2;
351 if (heap_check_heap(file,0))
353 puts("Heap keys crashed");
354 goto err;
357 else
358 puts("Warning: Not enough duplicated keys: Skipping delete key check");
360 if (!silent)
361 printf("- Read (first) - next - delete - next -> last\n");
362 DBUG_PRINT("progpos",("first - next - delete - next -> last"));
364 if (heap_scan_init(file))
365 goto err;
366 while ((error=heap_scan(file,record3) == HA_ERR_RECORD_DELETED)) ;
367 if (error)
368 goto err;
369 if (heap_delete(file,record3)) goto err;
370 key_check-=atoi((char*) record3);
371 opt_delete++;
372 key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
373 key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
374 ant=0;
375 while ((error=heap_scan(file,record3)) == 0 ||
376 error == HA_ERR_RECORD_DELETED)
377 if (! error)
378 ant++;
379 if (ant != write_count-opt_delete)
381 printf("next: Found: %d records of %d\n",ant,write_count-opt_delete);
382 goto end;
384 if (heap_check_heap(file,0))
386 puts("Heap keys crashed");
387 goto err;
390 puts("- Test if: Read rrnd - same - rkey - same");
391 DBUG_PRINT("progpos",("Read rrnd - same"));
392 pos=rnd(write_count-opt_delete-5)+5;
393 heap_scan_init(file);
394 i=5;
395 while ((error=heap_scan(file,record)) == HA_ERR_RECORD_DELETED ||
396 (error == 0 && pos))
398 if (!error)
399 pos--;
400 if (i-- == 0)
402 bmove(record3,record,reclength);
403 position=heap_position(file);
406 if (error)
407 goto err;
408 bmove(record2,record,reclength);
409 if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2))
410 goto err;
411 if (memcmp(record2,record,reclength))
413 puts("heap_rsame didn't find right record");
414 goto end;
417 puts("- Test of read through position");
418 if (heap_rrnd(file,record,position))
419 goto err;
420 if (memcmp(record3,record,reclength))
422 puts("heap_frnd didn't find right record");
423 goto end;
426 printf("- heap_info\n");
428 HEAPINFO info;
429 heap_info(file,&info,0);
430 /* We have to test with opt_delete +1 as this may be the case if the last
431 inserted row was a duplicate key */
432 if (info.records != write_count-opt_delete ||
433 (info.deleted != opt_delete && info.deleted != opt_delete+1))
435 puts("Wrong info from heap_info");
436 printf("Got: records: %ld(%d) deleted: %ld(%d)\n",
437 info.records,write_count-opt_delete,info.deleted,opt_delete);
441 #ifdef OLD_HEAP_VERSION
443 uint check;
444 printf("- Read through all records with rnd\n");
445 if (heap_extra(file,HA_EXTRA_RESET) || heap_extra(file,HA_EXTRA_CACHE))
447 puts("got error from heap_extra");
448 goto end;
450 ant=check=0;
451 while ((error=heap_rrnd(file,record,(ulong) -1)) != HA_ERR_END_OF_FILE &&
452 ant < write_count + 10)
454 if (!error)
456 ant++;
457 check+=calc_check(record,reclength);
460 if (ant != write_count-opt_delete)
462 printf("rrnd: I can only find: %d records of %d\n", ant,
463 write_count-opt_delete);
464 goto end;
466 if (heap_extra(file,HA_EXTRA_NO_CACHE))
468 puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
469 goto end;
472 #endif
474 printf("- Read through all records with scan\n");
475 if (heap_reset(file) || heap_extra(file,HA_EXTRA_CACHE))
477 puts("got error from heap_extra");
478 goto end;
480 ant=check2=0;
481 heap_scan_init(file);
482 while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE &&
483 ant < write_count + 10)
485 if (!error)
487 ant++;
488 check2+=calc_check(record,reclength);
491 if (ant != write_count-opt_delete)
493 printf("scan: I can only find: %d records of %d\n", ant,
494 write_count-opt_delete);
495 goto end;
497 #ifdef OLD_HEAP_VERSION
498 if (check != check2)
500 puts("scan: Checksum didn't match reading with rrnd");
501 goto end;
503 #endif
506 if (heap_extra(file,HA_EXTRA_NO_CACHE))
508 puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
509 goto end;
512 for (i=999, dupp_keys=found_key=0 ; i>0 ; i--)
514 if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; }
515 sprintf((char*) key,"%6d",found_key);
517 printf("- Read through all keys with first-next-last-prev\n");
518 ant=0;
519 for (error=heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT);
520 ! error ;
521 error=heap_rnext(file,record))
522 ant++;
523 if (ant != dupp_keys)
525 printf("first-next: I can only find: %d records of %d\n", ant,
526 dupp_keys);
527 goto end;
530 ant=0;
531 for (error=heap_rlast(file,record,0) ;
532 ! error ;
533 error=heap_rprev(file,record))
535 ant++;
536 check2+=calc_check(record,reclength);
538 if (ant != dupp_keys)
540 printf("last-prev: I can only find: %d records of %d\n", ant,
541 dupp_keys);
542 goto end;
545 if (testflag == 4) goto end;
547 printf("- Reading through all rows through keys\n");
548 if (!(file2=heap_open(filename, 2)))
549 goto err;
550 if (heap_scan_init(file))
551 goto err;
552 while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE)
554 if (error == 0)
556 if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start,8,
557 HA_READ_KEY_EXACT))
559 printf("can't find key3: \"%.8s\"\n",
560 record+keyinfo[2].seg[0].start);
561 goto err;
565 heap_close(file2);
567 printf("- Creating output heap-file 2\n");
568 if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info,
569 &tmp_share) ||
570 !(file2= heap_open_from_share_and_register(tmp_share, 2)))
571 goto err;
573 printf("- Copying and removing records\n");
574 if (heap_scan_init(file))
575 goto err;
576 while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE)
578 if (error == 0)
580 if (heap_write(file2,record))
581 goto err;
582 key_check-=atoi((char*) record);
583 write_count++;
584 if (heap_delete(file,record))
585 goto err;
586 opt_delete++;
588 pos++;
590 printf("- Checking heap tables\n");
591 if (heap_check_heap(file,1) || heap_check_heap(file2,1))
593 puts("Heap keys crashed");
594 goto err;
597 if (my_errno != HA_ERR_END_OF_FILE)
598 printf("error: %d from heap_rrnd\n",my_errno);
599 if (key_check)
600 printf("error: Some read got wrong: check is %ld\n",(long) key_check);
602 end:
603 printf("\nFollowing test have been made:\n");
604 printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,update,opt_delete);
605 heap_clear(file);
606 if (heap_close(file) || (file2 && heap_close(file2)))
607 goto err;
608 heap_delete_table(filename2);
609 hp_panic(HA_PANIC_CLOSE);
610 my_end(MY_GIVE_INFO);
611 return(0);
612 err:
613 printf("Got error: %d when using heap-database\n",my_errno);
614 VOID(heap_close(file));
615 return(1);
616 } /* main */
619 /* Read options */
621 static int get_options(int argc,char *argv[])
623 char *pos,*progname;
625 progname= argv[0];
627 while (--argc >0 && *(pos = *(++argv)) == '-' ) {
628 switch(*++pos) {
629 case 'B': /* Big file */
630 flag=1;
631 break;
632 case 'v': /* verbose */
633 verbose=1;
634 break;
635 case 'm': /* records */
636 recant=atoi(++pos);
637 break;
638 case 's':
639 silent=1;
640 break;
641 case 't':
642 testflag=atoi(++pos); /* testmod */
643 break;
644 case 'V':
645 case 'I':
646 case '?':
647 printf("%s Ver 1.1 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
648 puts("TCX Datakonsult AB, by Monty, for your professional use\n");
649 printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname);
650 exit(0);
651 case '#':
652 DBUG_PUSH (++pos);
653 break;
656 return 0;
657 } /* get options */
659 /* Generate a random value in intervall 0 <=x <= n */
661 static int rnd(int max_value)
663 return (int) ((rand() & 32767)/32767.0*max_value);
664 } /* rnd */
667 static sig_handler endprog(int sig_number __attribute__((unused)))
669 #ifndef THREAD
670 if (my_dont_interrupt)
671 my_remember_signal(sig_number,endprog);
672 else
673 #endif
675 hp_panic(HA_PANIC_CLOSE);
676 my_end(1);
677 exit(1);
681 static int calc_check(uchar *buf, uint length)
683 int check=0;
684 while (length--)
685 check+= (int) (uchar) *(buf++);
686 return check;
689 static void make_record(uchar *record, uint n1, uint n2, uint n3,
690 const char *mark, uint count)
692 bfill(record,reclength,' ');
693 sprintf((char*) record,"%6d:%4d:%8d:%3.3s: %4d",
694 n1,n2,n3,mark,count);
695 record[37]='A'; /* Store A in null key */
696 record[38]=1; /* set as null */