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 !! */
30 #include "heapdef.h" /* Because of hp_find_block */
33 #define MAX_RECORDS 100000
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
);
53 int main(int argc
, char *argv
[])
57 uint write_count
,update
,opt_delete
,check2
,dupp_keys
,found_key
;
60 unsigned long key_check
;
61 uchar record
[128],record2
[128],record3
[128],key
[10];
62 const char *filename
,*filename2
;
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 */
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;
83 keyinfo
[0].seg
=keyseg
;
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;
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)))
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
);
151 if (verbose
) printf(" Double key: %d\n",n3
);
157 printf("Error: Didn't get error when writing second key: '%8d'\n",n3
);
160 write_count
++; key1
[n1
]++; key3
[n3
]=1;
163 if (testflag
== 1 && heap_check_heap(file
,0))
165 puts("Heap keys crashed");
171 if (heap_check_heap(file
,0))
173 puts("Heap keys crashed");
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
--) ;
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
);
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 */
194 if (heap_delete(file
,record
))
196 printf("error: %d; can't delete record: \"%s\"\n", my_errno
,(char*) record
);
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");
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");
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
);
226 if (heap_scan_init(file
))
228 j
=rnd(write_count
-opt_delete
);
229 while ((error
=heap_scan(file
,record
) == HA_ERR_RECORD_DELETED
) ||
240 for (j
=rnd(1000)+1 ; j
>0 && key1
[j
] == 0 ; j
--) ;
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
);
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
);
259 printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",
260 (char*) record
, (char*) record2
);
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;
268 key_check
=key_check
-atoi((char*) record
)+n1
;
270 if (testflag
== 3 && heap_check_heap(file
,0))
272 puts("Heap keys crashed");
276 if (testflag
== 3) goto end
;
277 if (heap_check_heap(file
,0))
279 puts("Heap keys crashed");
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
);
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
))
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;
304 while ((error
=heap_rnext(file
,record3
)) == 0 ||
305 error
== HA_ERR_RECORD_DELETED
)
308 if (ant
!= dupp_keys
)
310 printf("next: I can only find: %d records of %d\n",
315 if (heap_check_heap(file
,0))
317 puts("Heap keys crashed");
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;
330 if (heap_rprev(file
,record3
) || heap_rprev(file
,record3
))
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;
338 while ((error
=heap_rprev(file
,record3
)) == 0 ||
339 error
== HA_ERR_RECORD_DELETED
)
344 if (ant
!= dupp_keys
)
346 printf("next: I can only find: %d records of %d\n",
351 if (heap_check_heap(file
,0))
353 puts("Heap keys crashed");
358 puts("Warning: Not enough duplicated keys: Skipping delete key check");
361 printf("- Read (first) - next - delete - next -> last\n");
362 DBUG_PRINT("progpos",("first - next - delete - next -> last"));
364 if (heap_scan_init(file
))
366 while ((error
=heap_scan(file
,record3
) == HA_ERR_RECORD_DELETED
)) ;
369 if (heap_delete(file
,record3
)) goto err
;
370 key_check
-=atoi((char*) record3
);
372 key1
[atoi((char*) record
+keyinfo
[0].seg
[0].start
)]--;
373 key3
[atoi((char*) record
+keyinfo
[2].seg
[0].start
)]=0;
375 while ((error
=heap_scan(file
,record3
)) == 0 ||
376 error
== HA_ERR_RECORD_DELETED
)
379 if (ant
!= write_count
-opt_delete
)
381 printf("next: Found: %d records of %d\n",ant
,write_count
-opt_delete
);
384 if (heap_check_heap(file
,0))
386 puts("Heap keys crashed");
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
);
395 while ((error
=heap_scan(file
,record
)) == HA_ERR_RECORD_DELETED
||
402 bmove(record3
,record
,reclength
);
403 position
=heap_position(file
);
408 bmove(record2
,record
,reclength
);
409 if (heap_rsame(file
,record
,-1) || heap_rsame(file
,record2
,2))
411 if (memcmp(record2
,record
,reclength
))
413 puts("heap_rsame didn't find right record");
417 puts("- Test of read through position");
418 if (heap_rrnd(file
,record
,position
))
420 if (memcmp(record3
,record
,reclength
))
422 puts("heap_frnd didn't find right record");
426 printf("- heap_info\n");
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
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");
451 while ((error
=heap_rrnd(file
,record
,(ulong
) -1)) != HA_ERR_END_OF_FILE
&&
452 ant
< write_count
+ 10)
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
);
466 if (heap_extra(file
,HA_EXTRA_NO_CACHE
))
468 puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
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");
481 heap_scan_init(file
);
482 while ((error
=heap_scan(file
,record
)) != HA_ERR_END_OF_FILE
&&
483 ant
< write_count
+ 10)
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
);
497 #ifdef OLD_HEAP_VERSION
500 puts("scan: Checksum didn't match reading with rrnd");
506 if (heap_extra(file
,HA_EXTRA_NO_CACHE
))
508 puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
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");
519 for (error
=heap_rkey(file
,record
,0,key
,6, HA_READ_KEY_EXACT
);
521 error
=heap_rnext(file
,record
))
523 if (ant
!= dupp_keys
)
525 printf("first-next: I can only find: %d records of %d\n", ant
,
531 for (error
=heap_rlast(file
,record
,0) ;
533 error
=heap_rprev(file
,record
))
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
,
545 if (testflag
== 4) goto end
;
547 printf("- Reading through all rows through keys\n");
548 if (!(file2
=heap_open(filename
, 2)))
550 if (heap_scan_init(file
))
552 while ((error
=heap_scan(file
,record
)) != HA_ERR_END_OF_FILE
)
556 if (heap_rkey(file2
,record2
,2,record
+keyinfo
[2].seg
[0].start
,8,
559 printf("can't find key3: \"%.8s\"\n",
560 record
+keyinfo
[2].seg
[0].start
);
567 printf("- Creating output heap-file 2\n");
568 if (heap_create(filename2
, 1, keyinfo
, reclength
, 0L, 0L, &hp_create_info
,
570 !(file2
= heap_open_from_share_and_register(tmp_share
, 2)))
573 printf("- Copying and removing records\n");
574 if (heap_scan_init(file
))
576 while ((error
=heap_scan(file
,record
)) != HA_ERR_END_OF_FILE
)
580 if (heap_write(file2
,record
))
582 key_check
-=atoi((char*) record
);
584 if (heap_delete(file
,record
))
590 printf("- Checking heap tables\n");
591 if (heap_check_heap(file
,1) || heap_check_heap(file2
,1))
593 puts("Heap keys crashed");
597 if (my_errno
!= HA_ERR_END_OF_FILE
)
598 printf("error: %d from heap_rrnd\n",my_errno
);
600 printf("error: Some read got wrong: check is %ld\n",(long) key_check
);
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
);
606 if (heap_close(file
) || (file2
&& heap_close(file2
)))
608 heap_delete_table(filename2
);
609 hp_panic(HA_PANIC_CLOSE
);
610 my_end(MY_GIVE_INFO
);
613 printf("Got error: %d when using heap-database\n",my_errno
);
614 VOID(heap_close(file
));
621 static int get_options(int argc
,char *argv
[])
627 while (--argc
>0 && *(pos
= *(++argv
)) == '-' ) {
629 case 'B': /* Big file */
632 case 'v': /* verbose */
635 case 'm': /* records */
642 testflag
=atoi(++pos
); /* testmod */
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
);
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
);
667 static sig_handler
endprog(int sig_number
__attribute__((unused
)))
670 if (my_dont_interrupt
)
671 my_remember_signal(sig_number
,endprog
);
675 hp_panic(HA_PANIC_CLOSE
);
681 static int calc_check(uchar
*buf
, uint length
)
685 check
+= (int) (uchar
) *(buf
++);
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 */