1
/* Copyright (C) 2000-2003, 2006 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
16
/* Test av isam-databas: stor test */
18
#ifndef USE_MY_FUNC /* We want to be able to dbug this !! */
25
#include "heapdef.h" /* Because of hp_find_block */
28
#define MAX_RECORDS 100000
31
static int get_options(int argc, char *argv[]);
32
static int rnd(int max_value);
33
static sig_handler endprog(int sig_number);
35
static uint flag=0,verbose=0,testflag=0,recant=10000,silent=0;
36
static uint keys=MAX_KEYS;
37
static uint16 key1[1001];
38
static my_bool key3[MAX_RECORDS];
39
static int reclength=39;
42
static int calc_check(uchar *buf,uint length);
43
static void make_record(uchar *record, uint n1, uint n2, uint n3,
44
const char *mark, uint count);
48
int main(int argc, char *argv[])
52
uint write_count,update,opt_delete,check2,dupp_keys,found_key;
55
unsigned long key_check;
56
uchar record[128],record2[128],record3[128],key[10];
57
const char *filename,*filename2;
60
HP_KEYDEF keyinfo[MAX_KEYS];
61
HA_KEYSEG keyseg[MAX_KEYS*5];
62
HEAP_PTR position= NULL;
63
HP_CREATE_INFO hp_create_info;
64
CHARSET_INFO *cs= &my_charset_latin1;
65
MY_INIT(argv[0]); /* init my_sys library & pthreads */
70
get_options(argc,argv);
72
bzero(&hp_create_info, sizeof(hp_create_info));
73
hp_create_info.max_table_size= 1024L*1024L;
75
write_count=update=opt_delete=0;
78
keyinfo[0].seg=keyseg;
81
keyinfo[0].algorithm= HA_KEY_ALG_HASH;
82
keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY;
83
keyinfo[0].seg[0].start=0;
84
keyinfo[0].seg[0].length=6;
85
keyinfo[0].seg[0].null_bit=0;
86
keyinfo[0].seg[0].charset=cs;
87
keyinfo[1].seg=keyseg+1;
90
keyinfo[1].algorithm= HA_KEY_ALG_HASH;
91
keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY;
92
keyinfo[1].seg[0].start=7;
93
keyinfo[1].seg[0].length=6;
94
keyinfo[1].seg[0].null_bit=0;
95
keyinfo[1].seg[0].charset=cs;
96
keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT;
97
keyinfo[1].seg[1].start=0; /* key in two parts */
98
keyinfo[1].seg[1].length=6;
99
keyinfo[1].seg[1].null_bit=0;
100
keyinfo[1].seg[1].charset=cs;
101
keyinfo[2].seg=keyseg+3;
102
keyinfo[2].keysegs=1;
103
keyinfo[2].flag=HA_NOSAME;
104
keyinfo[2].algorithm= HA_KEY_ALG_HASH;
105
keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY;
106
keyinfo[2].seg[0].start=12;
107
keyinfo[2].seg[0].length=8;
108
keyinfo[2].seg[0].null_bit=0;
109
keyinfo[2].seg[0].charset=cs;
110
keyinfo[3].seg=keyseg+4;
111
keyinfo[3].keysegs=1;
112
keyinfo[3].flag=HA_NOSAME;
113
keyinfo[3].algorithm= HA_KEY_ALG_HASH;
114
keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY;
115
keyinfo[3].seg[0].start=37;
116
keyinfo[3].seg[0].length=1;
117
keyinfo[3].seg[0].null_bit=1;
118
keyinfo[3].seg[0].null_pos=38;
119
keyinfo[3].seg[0].charset=cs;
121
bzero((char*) key1,sizeof(key1));
122
bzero((char*) key3,sizeof(key3));
124
printf("- Creating heap-file\n");
125
if (heap_create(filename,keys,keyinfo,reclength,(ulong) flag*100000L,
126
(ulong) recant/2, &hp_create_info, &tmp_share) ||
127
!(file= heap_open(filename, 2)))
129
signal(SIGINT,endprog);
131
printf("- Writing records:s\n");
132
strmov((char*) record," ..... key");
134
for (i=0 ; i < recant ; i++)
136
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
137
make_record(record,n1,n2,n3,"Pos",write_count);
139
if (heap_write(file,record))
141
if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
143
printf("Error: %d in write at record: %d\n",my_errno,i);
146
if (verbose) printf(" Double key: %d\n",n3);
152
printf("Error: Didn't get error when writing second key: '%8d'\n",n3);
155
write_count++; key1[n1]++; key3[n3]=1;
158
if (testflag == 1 && heap_check_heap(file,0))
160
puts("Heap keys crashed");
166
if (heap_check_heap(file,0))
168
puts("Heap keys crashed");
172
printf("- Delete\n");
173
for (i=0 ; i < write_count/10 ; i++)
175
for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
178
sprintf((char*) key,"%6d",j);
179
if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
181
printf("can't find key1: \"%s\"\n",(char*) key);
185
if (file->current_ptr == hp_find_block(&file->s->block,0) ||
186
file->current_ptr == hp_find_block(&file->s->block,1))
187
continue; /* Don't remove 2 first records */
189
if (heap_delete(file,record))
191
printf("error: %d; can't delete record: \"%s\"\n", my_errno,(char*) record);
195
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
196
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
197
key_check-=atoi((char*) record);
198
if (testflag == 2 && heap_check_heap(file,0))
200
puts("Heap keys crashed");
205
puts("Warning: Skipping delete test because no dupplicate keys");
207
if (testflag==2) goto end;
208
if (heap_check_heap(file,0))
210
puts("Heap keys crashed");
214
printf("- Update\n");
215
for (i=0 ; i < write_count/10 ; i++)
217
n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
218
make_record(record2, n1, n2, n3, "XXX", update);
221
if (heap_scan_init(file))
223
j=rnd(write_count-opt_delete);
224
while ((error=heap_scan(file,record) == HA_ERR_RECORD_DELETED) ||
235
for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ;
238
sprintf((char*) key,"%6d",j);
239
if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
241
printf("can't find key1: \"%s\"\n",(char*) key);
245
if (heap_update(file,record,record2))
247
if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0)
249
printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n",
250
my_errno,(char*) record, (char*) record2);
254
printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",
255
(char*) record, (char*) record2);
259
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
260
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
261
key1[n1]++; key3[n3]=1;
263
key_check=key_check-atoi((char*) record)+n1;
265
if (testflag == 3 && heap_check_heap(file,0))
267
puts("Heap keys crashed");
271
if (testflag == 3) goto end;
272
if (heap_check_heap(file,0))
274
puts("Heap keys crashed");
278
for (i=999, dupp_keys=found_key=0 ; i>0 ; i--)
280
if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; }
281
sprintf((char*) key,"%6d",found_key);
287
printf("- Read first key - next - delete - next -> last\n");
288
DBUG_PRINT("progpos",("first - next - delete - next -> last"));
290
if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT))
292
if (heap_rnext(file,record3)) goto err;
293
if (heap_delete(file,record3)) goto err;
294
key_check-=atoi((char*) record3);
295
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
296
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
299
while ((error=heap_rnext(file,record3)) == 0 ||
300
error == HA_ERR_RECORD_DELETED)
303
if (ant != dupp_keys)
305
printf("next: I can only find: %d records of %d\n",
310
if (heap_check_heap(file,0))
312
puts("Heap keys crashed");
317
printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n");
319
if (heap_rlast(file,record3,0)) goto err;
320
if (heap_delete(file,record3)) goto err;
321
key_check-=atoi((char*) record3);
322
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
323
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
325
if (heap_rprev(file,record3) || heap_rprev(file,record3))
327
if (heap_delete(file,record3)) goto err;
328
key_check-=atoi((char*) record3);
329
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
330
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
333
while ((error=heap_rprev(file,record3)) == 0 ||
334
error == HA_ERR_RECORD_DELETED)
339
if (ant != dupp_keys)
341
printf("next: I can only find: %d records of %d\n",
346
if (heap_check_heap(file,0))
348
puts("Heap keys crashed");
353
puts("Warning: Not enough duplicated keys: Skipping delete key check");
356
printf("- Read (first) - next - delete - next -> last\n");
357
DBUG_PRINT("progpos",("first - next - delete - next -> last"));
359
if (heap_scan_init(file))
361
while ((error=heap_scan(file,record3) == HA_ERR_RECORD_DELETED)) ;
364
if (heap_delete(file,record3)) goto err;
365
key_check-=atoi((char*) record3);
367
key1[atoi((char*) record+keyinfo[0].seg[0].start)]--;
368
key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0;
370
while ((error=heap_scan(file,record3)) == 0 ||
371
error == HA_ERR_RECORD_DELETED)
374
if (ant != write_count-opt_delete)
376
printf("next: Found: %d records of %d\n",ant,write_count-opt_delete);
379
if (heap_check_heap(file,0))
381
puts("Heap keys crashed");
385
puts("- Test if: Read rrnd - same - rkey - same");
386
DBUG_PRINT("progpos",("Read rrnd - same"));
387
pos=rnd(write_count-opt_delete-5)+5;
388
heap_scan_init(file);
390
while ((error=heap_scan(file,record)) == HA_ERR_RECORD_DELETED ||
397
bmove(record3,record,reclength);
398
position=heap_position(file);
403
bmove(record2,record,reclength);
404
if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2))
406
if (bcmp(record2,record,reclength))
408
puts("heap_rsame didn't find right record");
412
puts("- Test of read through position");
413
if (heap_rrnd(file,record,position))
415
if (bcmp(record3,record,reclength))
417
puts("heap_frnd didn't find right record");
421
printf("- heap_info\n");
424
heap_info(file,&info,0);
425
/* We have to test with opt_delete +1 as this may be the case if the last
426
inserted row was a duplicate key */
427
if (info.records != write_count-opt_delete ||
428
(info.deleted != opt_delete && info.deleted != opt_delete+1))
430
puts("Wrong info from heap_info");
431
printf("Got: records: %ld(%d) deleted: %ld(%d)\n",
432
info.records,write_count-opt_delete,info.deleted,opt_delete);
436
#ifdef OLD_HEAP_VERSION
439
printf("- Read through all records with rnd\n");
440
if (heap_extra(file,HA_EXTRA_RESET) || heap_extra(file,HA_EXTRA_CACHE))
442
puts("got error from heap_extra");
446
while ((error=heap_rrnd(file,record,(ulong) -1)) != HA_ERR_END_OF_FILE &&
447
ant < write_count + 10)
452
check+=calc_check(record,reclength);
455
if (ant != write_count-opt_delete)
457
printf("rrnd: I can only find: %d records of %d\n", ant,
458
write_count-opt_delete);
461
if (heap_extra(file,HA_EXTRA_NO_CACHE))
463
puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
469
printf("- Read through all records with scan\n");
470
if (heap_reset(file) || heap_extra(file,HA_EXTRA_CACHE))
472
puts("got error from heap_extra");
476
heap_scan_init(file);
477
while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE &&
478
ant < write_count + 10)
483
check2+=calc_check(record,reclength);
486
if (ant != write_count-opt_delete)
488
printf("scan: I can only find: %d records of %d\n", ant,
489
write_count-opt_delete);
492
#ifdef OLD_HEAP_VERSION
495
puts("scan: Checksum didn't match reading with rrnd");
501
if (heap_extra(file,HA_EXTRA_NO_CACHE))
503
puts("got error from heap_extra(HA_EXTRA_NO_CACHE)");
507
for (i=999, dupp_keys=found_key=0 ; i>0 ; i--)
509
if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; }
510
sprintf((char*) key,"%6d",found_key);
512
printf("- Read through all keys with first-next-last-prev\n");
514
for (error=heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT);
516
error=heap_rnext(file,record))
518
if (ant != dupp_keys)
520
printf("first-next: I can only find: %d records of %d\n", ant,
526
for (error=heap_rlast(file,record,0) ;
528
error=heap_rprev(file,record))
531
check2+=calc_check(record,reclength);
533
if (ant != dupp_keys)
535
printf("last-prev: I can only find: %d records of %d\n", ant,
540
if (testflag == 4) goto end;
542
printf("- Reading through all rows through keys\n");
543
if (!(file2=heap_open(filename, 2)))
545
if (heap_scan_init(file))
547
while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE)
551
if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start,8,
554
printf("can't find key3: \"%.8s\"\n",
555
record+keyinfo[2].seg[0].start);
562
printf("- Creating output heap-file 2\n");
563
if (heap_create(filename2, 1, keyinfo, reclength, 0L, 0L, &hp_create_info,
565
!(file2= heap_open_from_share_and_register(tmp_share, 2)))
568
printf("- Copying and removing records\n");
569
if (heap_scan_init(file))
571
while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE)
575
if (heap_write(file2,record))
577
key_check-=atoi((char*) record);
579
if (heap_delete(file,record))
585
printf("- Checking heap tables\n");
586
if (heap_check_heap(file,1) || heap_check_heap(file2,1))
588
puts("Heap keys crashed");
592
if (my_errno != HA_ERR_END_OF_FILE)
593
printf("error: %d from heap_rrnd\n",my_errno);
595
printf("error: Some read got wrong: check is %ld\n",(long) key_check);
598
printf("\nFollowing test have been made:\n");
599
printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,update,opt_delete);
601
if (heap_close(file) || (file2 && heap_close(file2)))
603
heap_delete_table(filename2);
604
hp_panic(HA_PANIC_CLOSE);
605
my_end(MY_GIVE_INFO);
608
printf("Got error: %d when using heap-database\n",my_errno);
609
VOID(heap_close(file));
616
static int get_options(int argc,char *argv[])
622
while (--argc >0 && *(pos = *(++argv)) == '-' ) {
624
case 'B': /* Big file */
627
case 'v': /* verbose */
630
case 'm': /* records */
637
testflag=atoi(++pos); /* testmod */
642
printf("%s Ver 1.1 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
643
puts("TCX Datakonsult AB, by Monty, for your professional use\n");
644
printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n",progname);
654
/* Generate a random value in intervall 0 <=x <= n */
656
static int rnd(int max_value)
658
return (int) ((rand() & 32767)/32767.0*max_value);
662
static sig_handler endprog(int sig_number __attribute__((unused)))
665
hp_panic(HA_PANIC_CLOSE);
671
static int calc_check(uchar *buf, uint length)
675
check+= (int) (uchar) *(buf++);
679
static void make_record(uchar *record, uint n1, uint n2, uint n3,
680
const char *mark, uint count)
682
bfill(record,reclength,' ');
683
sprintf((char*) record,"%6d:%4d:%8d:%3.3s: %4d",
684
n1,n2,n3,mark,count);
685
record[37]='A'; /* Store A in null key */
686
record[38]=1; /* set as null */