00001 /* Copyright (C) 2000 MySQL AB & MySQL Finland AB & TCX DataKonsult AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 /* Test av isam-databas: stor test */ 00018 00019 #ifndef USE_MY_FUNC /* We want to be able to dbug this !! */ 00020 #define USE_MY_FUNC 00021 #endif 00022 #ifdef DBUG_OFF 00023 #undef DBUG_OFF 00024 #endif 00025 #ifndef SAFEMALLOC 00026 #define SAFEMALLOC 00027 #endif 00028 #include "myisamdef.h" 00029 #include <m_ctype.h> 00030 00031 #define STANDARD_LENGTH 37 00032 #define MYISAM_KEYS 6 00033 #define MAX_PARTS 4 00034 #if !defined(MSDOS) && !defined(labs) 00035 #define labs(a) abs(a) 00036 #endif 00037 00038 static void get_options(int argc, char *argv[]); 00039 static uint rnd(uint max_value); 00040 static void fix_length(byte *record,uint length); 00041 static void put_blob_in_record(char *blob_pos,char **blob_buffer); 00042 static void copy_key(struct st_myisam_info *info,uint inx, 00043 uchar *record,uchar *key); 00044 00045 static int verbose=0,testflag=0, 00046 first_key=0,async_io=0,key_cacheing=0,write_cacheing=0,locking=0, 00047 rec_pointer_size=0,pack_fields=1,use_log=0,silent=0, 00048 opt_quick_mode=0; 00049 static int pack_seg=HA_SPACE_PACK,pack_type=HA_PACK_KEY,remove_count=-1, 00050 create_flag=0; 00051 static ulong key_cache_size=IO_SIZE*16; 00052 static uint key_cache_block_size= KEY_CACHE_BLOCK_SIZE; 00053 00054 static uint keys=MYISAM_KEYS,recant=1000; 00055 static uint use_blob=0; 00056 static uint16 key1[1001],key3[5000]; 00057 static char record[300],record2[300],key[100],key2[100], 00058 read_record[300],read_record2[300],read_record3[300]; 00059 static HA_KEYSEG glob_keyseg[MYISAM_KEYS][MAX_PARTS]; 00060 00061 /* Test program */ 00062 00063 int main(int argc, char *argv[]) 00064 { 00065 uint i; 00066 int j,n1,n2,n3,error,k; 00067 uint write_count,update,dupp_keys,opt_delete,start,length,blob_pos, 00068 reclength,ant,found_parts; 00069 my_off_t lastpos; 00070 ha_rows range_records,records; 00071 MI_INFO *file; 00072 MI_KEYDEF keyinfo[10]; 00073 MI_COLUMNDEF recinfo[10]; 00074 MI_ISAMINFO info; 00075 const char *filename; 00076 char *blob_buffer; 00077 MI_CREATE_INFO create_info; 00078 MY_INIT(argv[0]); 00079 00080 filename= "test2"; 00081 get_options(argc,argv); 00082 if (! async_io) 00083 my_disable_async_io=1; 00084 00085 reclength=STANDARD_LENGTH+60+(use_blob ? 8 : 0); 00086 blob_pos=STANDARD_LENGTH+60; 00087 keyinfo[0].seg= &glob_keyseg[0][0]; 00088 keyinfo[0].seg[0].start=0; 00089 keyinfo[0].seg[0].length=6; 00090 keyinfo[0].seg[0].type=HA_KEYTYPE_TEXT; 00091 keyinfo[0].seg[0].language= default_charset_info->number; 00092 keyinfo[0].seg[0].flag=(uint8) pack_seg; 00093 keyinfo[0].seg[0].null_bit=0; 00094 keyinfo[0].seg[0].null_pos=0; 00095 keyinfo[0].key_alg=HA_KEY_ALG_BTREE; 00096 keyinfo[0].keysegs=1; 00097 keyinfo[0].flag = pack_type; 00098 keyinfo[0].block_length= 0; /* Default block length */ 00099 keyinfo[1].seg= &glob_keyseg[1][0]; 00100 keyinfo[1].seg[0].start=7; 00101 keyinfo[1].seg[0].length=6; 00102 keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY; 00103 keyinfo[1].seg[0].flag=0; 00104 keyinfo[1].seg[0].null_bit=0; 00105 keyinfo[1].seg[0].null_pos=0; 00106 keyinfo[1].seg[1].start=0; /* two part key */ 00107 keyinfo[1].seg[1].length=6; 00108 keyinfo[1].seg[1].type=HA_KEYTYPE_NUM; 00109 keyinfo[1].seg[1].flag=HA_REVERSE_SORT; 00110 keyinfo[1].seg[1].null_bit=0; 00111 keyinfo[1].seg[1].null_pos=0; 00112 keyinfo[1].key_alg=HA_KEY_ALG_BTREE; 00113 keyinfo[1].keysegs=2; 00114 keyinfo[1].flag =0; 00115 keyinfo[1].block_length= MI_MIN_KEY_BLOCK_LENGTH; /* Diff blocklength */ 00116 keyinfo[2].seg= &glob_keyseg[2][0]; 00117 keyinfo[2].seg[0].start=12; 00118 keyinfo[2].seg[0].length=8; 00119 keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY; 00120 keyinfo[2].seg[0].flag=HA_REVERSE_SORT; 00121 keyinfo[2].seg[0].null_bit=0; 00122 keyinfo[2].seg[0].null_pos=0; 00123 keyinfo[2].key_alg=HA_KEY_ALG_BTREE; 00124 keyinfo[2].keysegs=1; 00125 keyinfo[2].flag =HA_NOSAME; 00126 keyinfo[2].block_length= 0; /* Default block length */ 00127 keyinfo[3].seg= &glob_keyseg[3][0]; 00128 keyinfo[3].seg[0].start=0; 00129 keyinfo[3].seg[0].length=reclength-(use_blob ? 8 : 0); 00130 keyinfo[3].seg[0].type=HA_KEYTYPE_TEXT; 00131 keyinfo[3].seg[0].language=default_charset_info->number; 00132 keyinfo[3].seg[0].flag=(uint8) pack_seg; 00133 keyinfo[3].seg[0].null_bit=0; 00134 keyinfo[3].seg[0].null_pos=0; 00135 keyinfo[3].key_alg=HA_KEY_ALG_BTREE; 00136 keyinfo[3].keysegs=1; 00137 keyinfo[3].flag = pack_type; 00138 keyinfo[3].block_length= 0; /* Default block length */ 00139 keyinfo[4].seg= &glob_keyseg[4][0]; 00140 keyinfo[4].seg[0].start=0; 00141 keyinfo[4].seg[0].length=5; 00142 keyinfo[4].seg[0].type=HA_KEYTYPE_TEXT; 00143 keyinfo[4].seg[0].language=default_charset_info->number; 00144 keyinfo[4].seg[0].flag=0; 00145 keyinfo[4].seg[0].null_bit=0; 00146 keyinfo[4].seg[0].null_pos=0; 00147 keyinfo[4].key_alg=HA_KEY_ALG_BTREE; 00148 keyinfo[4].keysegs=1; 00149 keyinfo[4].flag = pack_type; 00150 keyinfo[4].block_length= 0; /* Default block length */ 00151 keyinfo[5].seg= &glob_keyseg[5][0]; 00152 keyinfo[5].seg[0].start=0; 00153 keyinfo[5].seg[0].length=4; 00154 keyinfo[5].seg[0].type=HA_KEYTYPE_TEXT; 00155 keyinfo[5].seg[0].language=default_charset_info->number; 00156 keyinfo[5].seg[0].flag=pack_seg; 00157 keyinfo[5].seg[0].null_bit=0; 00158 keyinfo[5].seg[0].null_pos=0; 00159 keyinfo[5].key_alg=HA_KEY_ALG_BTREE; 00160 keyinfo[5].keysegs=1; 00161 keyinfo[5].flag = pack_type; 00162 keyinfo[5].block_length= 0; /* Default block length */ 00163 00164 recinfo[0].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; 00165 recinfo[0].length=7; 00166 recinfo[0].null_bit=0; 00167 recinfo[0].null_pos=0; 00168 recinfo[1].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; 00169 recinfo[1].length=5; 00170 recinfo[1].null_bit=0; 00171 recinfo[1].null_pos=0; 00172 recinfo[2].type=pack_fields ? FIELD_SKIP_PRESPACE : 0; 00173 recinfo[2].length=9; 00174 recinfo[2].null_bit=0; 00175 recinfo[2].null_pos=0; 00176 recinfo[3].type=FIELD_NORMAL; 00177 recinfo[3].length=STANDARD_LENGTH-7-5-9-4; 00178 recinfo[3].null_bit=0; 00179 recinfo[3].null_pos=0; 00180 recinfo[4].type=pack_fields ? FIELD_SKIP_ZERO : 0; 00181 recinfo[4].length=4; 00182 recinfo[4].null_bit=0; 00183 recinfo[4].null_pos=0; 00184 recinfo[5].type=pack_fields ? FIELD_SKIP_ENDSPACE : 0; 00185 recinfo[5].length=60; 00186 recinfo[5].null_bit=0; 00187 recinfo[5].null_pos=0; 00188 if (use_blob) 00189 { 00190 recinfo[6].type=FIELD_BLOB; 00191 recinfo[6].length=4+mi_portable_sizeof_char_ptr; 00192 recinfo[6].null_bit=0; 00193 recinfo[6].null_pos=0; 00194 } 00195 00196 write_count=update=dupp_keys=opt_delete=0; 00197 blob_buffer=0; 00198 00199 for (i=1000 ; i>0 ; i--) key1[i]=0; 00200 for (i=4999 ; i>0 ; i--) key3[i]=0; 00201 00202 if (!silent) 00203 printf("- Creating isam-file\n"); 00204 /* DBUG_PUSH(""); */ 00205 /* my_delete(filename,MYF(0)); */ /* Remove old locks under gdb */ 00206 file= 0; 00207 bzero((char*) &create_info,sizeof(create_info)); 00208 create_info.max_rows=(ha_rows) (rec_pointer_size ? 00209 (1L << (rec_pointer_size*8))/ 00210 reclength : 0); 00211 create_info.reloc_rows=(ha_rows) 100; 00212 if (mi_create(filename,keys,&keyinfo[first_key], 00213 use_blob ? 7 : 6, &recinfo[0], 00214 0,(MI_UNIQUEDEF*) 0, 00215 &create_info,create_flag)) 00216 goto err; 00217 if (use_log) 00218 mi_log(1); 00219 if (!(file=mi_open(filename,2,HA_OPEN_ABORT_IF_LOCKED))) 00220 goto err; 00221 if (!silent) 00222 printf("- Writing key:s\n"); 00223 if (key_cacheing) 00224 init_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size,0,0); 00225 if (locking) 00226 mi_lock_database(file,F_WRLCK); 00227 if (write_cacheing) 00228 mi_extra(file,HA_EXTRA_WRITE_CACHE,0); 00229 if (opt_quick_mode) 00230 mi_extra(file,HA_EXTRA_QUICK,0); 00231 00232 for (i=0 ; i < recant ; i++) 00233 { 00234 n1=rnd(1000); n2=rnd(100); n3=rnd(5000); 00235 sprintf(record,"%6d:%4d:%8d:Pos: %4d ",n1,n2,n3,write_count); 00236 int4store(record+STANDARD_LENGTH-4,(long) i); 00237 fix_length(record,(uint) STANDARD_LENGTH+rnd(60)); 00238 put_blob_in_record(record+blob_pos,&blob_buffer); 00239 DBUG_PRINT("test",("record: %d",i)); 00240 00241 if (mi_write(file,record)) 00242 { 00243 if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) 00244 { 00245 printf("Error: %d in write at record: %d\n",my_errno,i); 00246 goto err; 00247 } 00248 if (verbose) printf(" Double key: %d\n",n3); 00249 } 00250 else 00251 { 00252 if (key3[n3] == 1 && first_key <3 && first_key+keys >= 3) 00253 { 00254 printf("Error: Didn't get error when writing second key: '%8d'\n",n3); 00255 goto err; 00256 } 00257 write_count++; key1[n1]++; key3[n3]=1; 00258 } 00259 00260 /* Check if we can find key without flushing database */ 00261 if (i == recant/2) 00262 { 00263 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; 00264 if (!j) 00265 for (j=999 ; j>0 && key1[j] == 0 ; j--) ; 00266 sprintf(key,"%6d",j); 00267 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) 00268 { 00269 printf("Test in loop: Can't find key: \"%s\"\n",key); 00270 goto err; 00271 } 00272 } 00273 } 00274 if (testflag==1) goto end; 00275 00276 if (write_cacheing) 00277 { 00278 if (mi_extra(file,HA_EXTRA_NO_CACHE,0)) 00279 { 00280 puts("got error from mi_extra(HA_EXTRA_NO_CACHE)"); 00281 goto end; 00282 } 00283 } 00284 if (key_cacheing) 00285 resize_key_cache(dflt_key_cache,key_cache_block_size,key_cache_size*2,0,0); 00286 00287 if (!silent) 00288 printf("- Delete\n"); 00289 for (i=0 ; i<recant/10 ; i++) 00290 { 00291 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; 00292 if (j != 0) 00293 { 00294 sprintf(key,"%6d",j); 00295 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) 00296 { 00297 printf("can't find key1: \"%s\"\n",key); 00298 goto err; 00299 } 00300 if (opt_delete == (uint) remove_count) /* While testing */ 00301 goto end; 00302 if (mi_delete(file,read_record)) 00303 { 00304 printf("error: %d; can't delete record: \"%s\"\n", my_errno,read_record); 00305 goto err; 00306 } 00307 opt_delete++; 00308 key1[atoi(read_record+keyinfo[0].seg[0].start)]--; 00309 key3[atoi(read_record+keyinfo[2].seg[0].start)]=0; 00310 } 00311 else 00312 puts("Warning: Skipping delete test because no dupplicate keys"); 00313 } 00314 if (testflag==2) goto end; 00315 00316 if (!silent) 00317 printf("- Update\n"); 00318 for (i=0 ; i<recant/10 ; i++) 00319 { 00320 n1=rnd(1000); n2=rnd(100); n3=rnd(5000); 00321 sprintf(record2,"%6d:%4d:%8d:XXX: %4d ",n1,n2,n3,update); 00322 int4store(record2+STANDARD_LENGTH-4,(long) i); 00323 fix_length(record2,(uint) STANDARD_LENGTH+rnd(60)); 00324 00325 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; 00326 if (j != 0) 00327 { 00328 sprintf(key,"%6d",j); 00329 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) 00330 { 00331 printf("can't find key1: \"%s\"\n",key); 00332 goto err; 00333 } 00334 if (use_blob) 00335 { 00336 if (i & 1) 00337 put_blob_in_record(record+blob_pos,&blob_buffer); 00338 else 00339 bmove(record+blob_pos,read_record+blob_pos,8); 00340 } 00341 if (mi_update(file,read_record,record2)) 00342 { 00343 if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) 00344 { 00345 printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n", 00346 my_errno,read_record,record2); 00347 goto err; 00348 } 00349 if (verbose) 00350 printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n",record,record2); 00351 } 00352 else 00353 { 00354 key1[atoi(read_record+keyinfo[0].seg[0].start)]--; 00355 key3[atoi(read_record+keyinfo[2].seg[0].start)]=0; 00356 key1[n1]++; key3[n3]=1; 00357 update++; 00358 } 00359 } 00360 } 00361 if (testflag == 3) 00362 goto end; 00363 00364 for (i=999, dupp_keys=j=0 ; i>0 ; i--) 00365 { 00366 if (key1[i] > dupp_keys) 00367 { 00368 dupp_keys=key1[i]; j=i; 00369 } 00370 } 00371 sprintf(key,"%6d",j); 00372 start=keyinfo[0].seg[0].start; 00373 length=keyinfo[0].seg[0].length; 00374 if (dupp_keys) 00375 { 00376 if (!silent) 00377 printf("- Same key: first - next -> last - prev -> first\n"); 00378 DBUG_PRINT("progpos",("first - next -> last - prev -> first")); 00379 if (verbose) printf(" Using key: \"%s\" Keys: %d\n",key,dupp_keys); 00380 00381 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) 00382 goto err; 00383 if (mi_rsame(file,read_record2,-1)) 00384 goto err; 00385 if (memcmp(read_record,read_record2,reclength) != 0) 00386 { 00387 printf("mi_rsame didn't find same record\n"); 00388 goto end; 00389 } 00390 info.recpos=mi_position(file); 00391 if (mi_rfirst(file,read_record2,0) || 00392 mi_rsame_with_pos(file,read_record2,0,info.recpos) || 00393 memcmp(read_record,read_record2,reclength) != 0) 00394 { 00395 printf("mi_rsame_with_pos didn't find same record\n"); 00396 goto end; 00397 } 00398 { 00399 int skr=mi_rnext(file,read_record2,0); 00400 if ((skr && my_errno != HA_ERR_END_OF_FILE) || 00401 mi_rprev(file,read_record2,-1) || 00402 memcmp(read_record,read_record2,reclength) != 0) 00403 { 00404 printf("mi_rsame_with_pos lost position\n"); 00405 goto end; 00406 } 00407 } 00408 ant=1; 00409 while (mi_rnext(file,read_record2,0) == 0 && 00410 memcmp(read_record2+start,key,length) == 0) ant++; 00411 if (ant != dupp_keys) 00412 { 00413 printf("next: Found: %d keys of %d\n",ant,dupp_keys); 00414 goto end; 00415 } 00416 ant=0; 00417 while (mi_rprev(file,read_record3,0) == 0 && 00418 bcmp(read_record3+start,key,length) == 0) ant++; 00419 if (ant != dupp_keys) 00420 { 00421 printf("prev: Found: %d records of %d\n",ant,dupp_keys); 00422 goto end; 00423 } 00424 00425 /* Check of mi_rnext_same */ 00426 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) 00427 goto err; 00428 ant=1; 00429 while (!mi_rnext_same(file,read_record3) && ant < dupp_keys+10) 00430 ant++; 00431 if (ant != dupp_keys || my_errno != HA_ERR_END_OF_FILE) 00432 { 00433 printf("mi_rnext_same: Found: %d records of %d\n",ant,dupp_keys); 00434 goto end; 00435 } 00436 } 00437 00438 if (!silent) 00439 printf("- All keys: first - next -> last - prev -> first\n"); 00440 DBUG_PRINT("progpos",("All keys: first - next -> last - prev -> first")); 00441 ant=1; 00442 if (mi_rfirst(file,read_record,0)) 00443 { 00444 printf("Can't find first record\n"); 00445 goto end; 00446 } 00447 while ((error=mi_rnext(file,read_record3,0)) == 0 && ant < write_count+10) 00448 ant++; 00449 if (ant != write_count - opt_delete || error != HA_ERR_END_OF_FILE) 00450 { 00451 printf("next: I found: %d records of %d (error: %d)\n", 00452 ant, write_count - opt_delete, error); 00453 goto end; 00454 } 00455 if (mi_rlast(file,read_record2,0) || 00456 bcmp(read_record2,read_record3,reclength)) 00457 { 00458 printf("Can't find last record\n"); 00459 DBUG_DUMP("record2",(byte*) read_record2,reclength); 00460 DBUG_DUMP("record3",(byte*) read_record3,reclength); 00461 goto end; 00462 } 00463 ant=1; 00464 while (mi_rprev(file,read_record3,0) == 0 && ant < write_count+10) 00465 ant++; 00466 if (ant != write_count - opt_delete) 00467 { 00468 printf("prev: I found: %d records of %d\n",ant,write_count); 00469 goto end; 00470 } 00471 if (bcmp(read_record,read_record3,reclength)) 00472 { 00473 printf("Can't find first record\n"); 00474 goto end; 00475 } 00476 00477 if (!silent) 00478 printf("- Test if: Read first - next - prev - prev - next == first\n"); 00479 DBUG_PRINT("progpos",("- Read first - next - prev - prev - next == first")); 00480 if (mi_rfirst(file,read_record,0) || 00481 mi_rnext(file,read_record3,0) || 00482 mi_rprev(file,read_record3,0) || 00483 mi_rprev(file,read_record3,0) == 0 || 00484 mi_rnext(file,read_record3,0)) 00485 goto err; 00486 if (bcmp(read_record,read_record3,reclength) != 0) 00487 printf("Can't find first record\n"); 00488 00489 if (!silent) 00490 printf("- Test if: Read last - prev - next - next - prev == last\n"); 00491 DBUG_PRINT("progpos",("Read last - prev - next - next - prev == last")); 00492 if (mi_rlast(file,read_record2,0) || 00493 mi_rprev(file,read_record3,0) || 00494 mi_rnext(file,read_record3,0) || 00495 mi_rnext(file,read_record3,0) == 0 || 00496 mi_rprev(file,read_record3,0)) 00497 goto err; 00498 if (bcmp(read_record2,read_record3,reclength)) 00499 printf("Can't find last record\n"); 00500 00501 if (!silent) 00502 puts("- Test read key-part"); 00503 strmov(key2,key); 00504 for(i=strlen(key2) ; i-- > 1 ;) 00505 { 00506 key2[i]=0; 00507 00508 /* The following row is just to catch some bugs in the key code */ 00509 bzero((char*) file->lastkey,file->s->base.max_key_length*2); 00510 if (mi_rkey(file,read_record,0,key2,(uint) i,HA_READ_PREFIX)) 00511 goto err; 00512 if (bcmp(read_record+start,key,(uint) i)) 00513 { 00514 puts("Didn't find right record"); 00515 goto end; 00516 } 00517 } 00518 if (dupp_keys > 2) 00519 { 00520 if (!silent) 00521 printf("- Read key (first) - next - delete - next -> last\n"); 00522 DBUG_PRINT("progpos",("first - next - delete - next -> last")); 00523 if (mi_rkey(file,read_record,0,key,0,HA_READ_KEY_EXACT)) goto err; 00524 if (mi_rnext(file,read_record3,0)) goto err; 00525 if (mi_delete(file,read_record3)) goto err; 00526 opt_delete++; 00527 ant=1; 00528 while (mi_rnext(file,read_record3,0) == 0 && 00529 bcmp(read_record3+start,key,length) == 0) ant++; 00530 if (ant != dupp_keys-1) 00531 { 00532 printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-1); 00533 goto end; 00534 } 00535 } 00536 if (dupp_keys>4) 00537 { 00538 if (!silent) 00539 printf("- Read last of key - prev - delete - prev -> first\n"); 00540 DBUG_PRINT("progpos",("last - prev - delete - prev -> first")); 00541 if (mi_rprev(file,read_record3,0)) goto err; 00542 if (mi_rprev(file,read_record3,0)) goto err; 00543 if (mi_delete(file,read_record3)) goto err; 00544 opt_delete++; 00545 ant=1; 00546 while (mi_rprev(file,read_record3,0) == 0 && 00547 bcmp(read_record3+start,key,length) == 0) ant++; 00548 if (ant != dupp_keys-2) 00549 { 00550 printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-2); 00551 goto end; 00552 } 00553 } 00554 if (dupp_keys > 6) 00555 { 00556 if (!silent) 00557 printf("- Read first - delete - next -> last\n"); 00558 DBUG_PRINT("progpos",("first - delete - next -> last")); 00559 if (mi_rkey(file,read_record3,0,key,0,HA_READ_KEY_EXACT)) goto err; 00560 if (mi_delete(file,read_record3)) goto err; 00561 opt_delete++; 00562 ant=1; 00563 if (mi_rnext(file,read_record,0)) 00564 goto err; /* Skall finnas poster */ 00565 while (mi_rnext(file,read_record3,0) == 0 && 00566 bcmp(read_record3+start,key,length) == 0) ant++; 00567 if (ant != dupp_keys-3) 00568 { 00569 printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-3); 00570 goto end; 00571 } 00572 00573 if (!silent) 00574 printf("- Read last - delete - prev -> first\n"); 00575 DBUG_PRINT("progpos",("last - delete - prev -> first")); 00576 if (mi_rprev(file,read_record3,0)) goto err; 00577 if (mi_delete(file,read_record3)) goto err; 00578 opt_delete++; 00579 ant=0; 00580 while (mi_rprev(file,read_record3,0) == 0 && 00581 bcmp(read_record3+start,key,length) == 0) ant++; 00582 if (ant != dupp_keys-4) 00583 { 00584 printf("next: I can only find: %d keys of %d\n",ant,dupp_keys-4); 00585 goto end; 00586 } 00587 } 00588 00589 if (!silent) 00590 puts("- Test if: Read rrnd - same"); 00591 DBUG_PRINT("progpos",("Read rrnd - same")); 00592 for (i=0 ; i < write_count ; i++) 00593 { 00594 if (mi_rrnd(file,read_record,i == 0 ? 0L : HA_OFFSET_ERROR) == 0) 00595 break; 00596 } 00597 if (i == write_count) 00598 goto err; 00599 00600 bmove(read_record2,read_record,reclength); 00601 for (i=min(2,keys) ; i-- > 0 ;) 00602 { 00603 if (mi_rsame(file,read_record2,(int) i)) goto err; 00604 if (bcmp(read_record,read_record2,reclength) != 0) 00605 { 00606 printf("is_rsame didn't find same record\n"); 00607 goto end; 00608 } 00609 } 00610 if (!silent) 00611 puts("- Test mi_records_in_range"); 00612 mi_status(file,&info,HA_STATUS_VARIABLE); 00613 for (i=0 ; i < info.keys ; i++) 00614 { 00615 key_range min_key, max_key; 00616 if (mi_rfirst(file,read_record,(int) i) || 00617 mi_rlast(file,read_record2,(int) i)) 00618 goto err; 00619 copy_key(file,(uint) i,(uchar*) read_record,(uchar*) key); 00620 copy_key(file,(uint) i,(uchar*) read_record2,(uchar*) key2); 00621 min_key.key= key; 00622 min_key.length= USE_WHOLE_KEY; 00623 min_key.flag= HA_READ_KEY_EXACT; 00624 max_key.key= key2; 00625 max_key.length= USE_WHOLE_KEY; 00626 max_key.flag= HA_READ_AFTER_KEY; 00627 00628 range_records= mi_records_in_range(file,(int) i, &min_key, &max_key); 00629 if (range_records < info.records*8/10 || 00630 range_records > info.records*12/10) 00631 { 00632 printf("mi_records_range returned %ld; Should be about %ld\n", 00633 (long) range_records,(long) info.records); 00634 goto end; 00635 } 00636 if (verbose) 00637 { 00638 printf("mi_records_range returned %ld; Exact is %ld (diff: %4.2g %%)\n", 00639 (long) range_records, (long) info.records, 00640 labs((long) range_records - (long) info.records)*100.0/ 00641 info.records); 00642 } 00643 } 00644 for (i=0 ; i < 5 ; i++) 00645 { 00646 for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; 00647 for (k=rnd(1000)+1 ; k>0 && key1[k] == 0 ; k--) ; 00648 if (j != 0 && k != 0) 00649 { 00650 key_range min_key, max_key; 00651 if (j > k) 00652 swap_variables(int, j, k); 00653 sprintf(key,"%6d",j); 00654 sprintf(key2,"%6d",k); 00655 00656 min_key.key= key; 00657 min_key.length= USE_WHOLE_KEY; 00658 min_key.flag= HA_READ_AFTER_KEY; 00659 max_key.key= key2; 00660 max_key.length= USE_WHOLE_KEY; 00661 max_key.flag= HA_READ_BEFORE_KEY; 00662 range_records= mi_records_in_range(file, 0, &min_key, &max_key); 00663 records=0; 00664 for (j++ ; j < k ; j++) 00665 records+=key1[j]; 00666 if ((long) range_records < (long) records*7/10-2 || 00667 (long) range_records > (long) records*14/10+2) 00668 { 00669 printf("mi_records_range for key: %d returned %lu; Should be about %lu\n", 00670 i, (ulong) range_records, (ulong) records); 00671 goto end; 00672 } 00673 if (verbose && records) 00674 { 00675 printf("mi_records_range returned %lu; Exact is %lu (diff: %4.2g %%)\n", 00676 (ulong) range_records, (ulong) records, 00677 labs((long) range_records-(long) records)*100.0/records); 00678 00679 } 00680 } 00681 } 00682 00683 if (!silent) 00684 printf("- mi_info\n"); 00685 mi_status(file,&info,HA_STATUS_VARIABLE | HA_STATUS_CONST); 00686 if (info.records != write_count-opt_delete || info.deleted > opt_delete + update 00687 || info.keys != keys) 00688 { 00689 puts("Wrong info from mi_info"); 00690 printf("Got: records: %lu delete: %lu i_keys: %d\n", 00691 (ulong) info.records, (ulong) info.deleted, info.keys); 00692 } 00693 if (verbose) 00694 { 00695 char buff[80]; 00696 get_date(buff,3,info.create_time); 00697 printf("info: Created %s\n",buff); 00698 get_date(buff,3,info.check_time); 00699 printf("info: checked %s\n",buff); 00700 get_date(buff,3,info.update_time); 00701 printf("info: Modified %s\n",buff); 00702 } 00703 00704 mi_panic(HA_PANIC_WRITE); 00705 mi_panic(HA_PANIC_READ); 00706 if (mi_is_changed(file)) 00707 puts("Warning: mi_is_changed reported that datafile was changed"); 00708 00709 if (!silent) 00710 printf("- mi_extra(CACHE) + mi_rrnd.... + mi_extra(NO_CACHE)\n"); 00711 if (mi_reset(file) || mi_extra(file,HA_EXTRA_CACHE,0)) 00712 { 00713 if (locking || (!use_blob && !pack_fields)) 00714 { 00715 puts("got error from mi_extra(HA_EXTRA_CACHE)"); 00716 goto end; 00717 } 00718 } 00719 ant=0; 00720 while ((error=mi_rrnd(file,record,HA_OFFSET_ERROR)) != HA_ERR_END_OF_FILE && 00721 ant < write_count + 10) 00722 ant+= error ? 0 : 1; 00723 if (ant != write_count-opt_delete) 00724 { 00725 printf("rrnd with cache: I can only find: %d records of %d\n", 00726 ant,write_count-opt_delete); 00727 goto end; 00728 } 00729 if (mi_extra(file,HA_EXTRA_NO_CACHE,0)) 00730 { 00731 puts("got error from mi_extra(HA_EXTRA_NO_CACHE)"); 00732 goto end; 00733 } 00734 00735 ant=0; 00736 mi_scan_init(file); 00737 while ((error=mi_scan(file,record)) != HA_ERR_END_OF_FILE && 00738 ant < write_count + 10) 00739 ant+= error ? 0 : 1; 00740 if (ant != write_count-opt_delete) 00741 { 00742 printf("scan with cache: I can only find: %d records of %d\n", 00743 ant,write_count-opt_delete); 00744 goto end; 00745 } 00746 00747 if (testflag == 4) goto end; 00748 00749 if (!silent) 00750 printf("- Removing keys\n"); 00751 DBUG_PRINT("progpos",("Removing keys")); 00752 lastpos = HA_OFFSET_ERROR; 00753 /* DBUG_POP(); */ 00754 mi_reset(file); 00755 found_parts=0; 00756 while ((error=mi_rrnd(file,read_record,HA_OFFSET_ERROR)) != 00757 HA_ERR_END_OF_FILE) 00758 { 00759 info.recpos=mi_position(file); 00760 if (lastpos >= info.recpos && lastpos != HA_OFFSET_ERROR) 00761 { 00762 printf("mi_rrnd didn't advance filepointer; old: %ld, new: %ld\n", 00763 (long) lastpos, (long) info.recpos); 00764 goto err; 00765 } 00766 lastpos=info.recpos; 00767 if (error == 0) 00768 { 00769 if (opt_delete == (uint) remove_count) /* While testing */ 00770 goto end; 00771 if (mi_rsame(file,read_record,-1)) 00772 { 00773 printf("can't find record %lx\n",(long) info.recpos); 00774 goto err; 00775 } 00776 if (use_blob) 00777 { 00778 ulong blob_length,pos; 00779 uchar *ptr; 00780 longget(blob_length,read_record+blob_pos+4); 00781 ptr=(uchar*) blob_length; 00782 longget(blob_length,read_record+blob_pos); 00783 for (pos=0 ; pos < blob_length ; pos++) 00784 { 00785 if (ptr[pos] != (uchar) (blob_length+pos)) 00786 { 00787 printf("found blob with wrong info at %ld\n",(long) lastpos); 00788 use_blob=0; 00789 break; 00790 } 00791 } 00792 } 00793 if (mi_delete(file,read_record)) 00794 { 00795 printf("can't delete record: %6.6s, delete_count: %d\n", 00796 read_record, opt_delete); 00797 goto err; 00798 } 00799 opt_delete++; 00800 } 00801 else 00802 found_parts++; 00803 } 00804 if (my_errno != HA_ERR_END_OF_FILE && my_errno != HA_ERR_RECORD_DELETED) 00805 printf("error: %d from mi_rrnd\n",my_errno); 00806 if (write_count != opt_delete) 00807 { 00808 printf("Deleted only %d of %d records (%d parts)\n",opt_delete,write_count, 00809 found_parts); 00810 goto err; 00811 } 00812 end: 00813 if (mi_close(file)) 00814 goto err; 00815 mi_panic(HA_PANIC_CLOSE); /* Should close log */ 00816 if (!silent) 00817 { 00818 printf("\nFollowing test have been made:\n"); 00819 printf("Write records: %d\nUpdate records: %d\nSame-key-read: %d\nDelete records: %d\n", write_count,update,dupp_keys,opt_delete); 00820 if (rec_pointer_size) 00821 printf("Record pointer size: %d\n",rec_pointer_size); 00822 printf("myisam_block_size: %lu\n", myisam_block_size); 00823 if (key_cacheing) 00824 { 00825 puts("Key cache used"); 00826 printf("key_cache_block_size: %u\n", key_cache_block_size); 00827 if (write_cacheing) 00828 puts("Key cache resized"); 00829 } 00830 if (write_cacheing) 00831 puts("Write cacheing used"); 00832 if (write_cacheing) 00833 puts("quick mode"); 00834 if (async_io && locking) 00835 puts("Asyncron io with locking used"); 00836 else if (locking) 00837 puts("Locking used"); 00838 if (use_blob) 00839 puts("blobs used"); 00840 printf("key cache status: \n\ 00841 blocks used:%10lu\n\ 00842 not flushed:%10lu\n\ 00843 w_requests: %10lu\n\ 00844 writes: %10lu\n\ 00845 r_requests: %10lu\n\ 00846 reads: %10lu\n", 00847 dflt_key_cache->blocks_used, 00848 dflt_key_cache->global_blocks_changed, 00849 (ulong) dflt_key_cache->global_cache_w_requests, 00850 (ulong) dflt_key_cache->global_cache_write, 00851 (ulong) dflt_key_cache->global_cache_r_requests, 00852 (ulong) dflt_key_cache->global_cache_read); 00853 } 00854 end_key_cache(dflt_key_cache,1); 00855 if (blob_buffer) 00856 my_free(blob_buffer,MYF(0)); 00857 my_end(silent ? MY_CHECK_ERROR : MY_CHECK_ERROR | MY_GIVE_INFO); 00858 return(0); 00859 err: 00860 printf("got error: %d when using MyISAM-database\n",my_errno); 00861 if (file) 00862 VOID(mi_close(file)); 00863 return(1); 00864 } /* main */ 00865 00866 00867 /* l{ser optioner */ 00868 /* OBS! intierar endast DEBUG - ingen debuggning h{r ! */ 00869 00870 static void get_options(int argc, char **argv) 00871 { 00872 char *pos,*progname; 00873 00874 progname= argv[0]; 00875 00876 while (--argc >0 && *(pos = *(++argv)) == '-' ) { 00877 switch(*++pos) { 00878 case 'B': 00879 pack_type= HA_BINARY_PACK_KEY; 00880 break; 00881 case 'b': 00882 use_blob=1; 00883 break; 00884 case 'K': /* Use key cacheing */ 00885 key_cacheing=1; 00886 if (*++pos) 00887 key_cache_size=atol(pos); 00888 break; 00889 case 'W': /* Use write cacheing */ 00890 write_cacheing=1; 00891 if (*++pos) 00892 my_default_record_cache_size=atoi(pos); 00893 break; 00894 case 'd': 00895 remove_count= atoi(++pos); 00896 break; 00897 case 'i': 00898 if (*++pos) 00899 srand(atoi(pos)); 00900 break; 00901 case 'l': 00902 use_log=1; 00903 break; 00904 case 'L': 00905 locking=1; 00906 break; 00907 case 'A': /* use asyncron io */ 00908 async_io=1; 00909 if (*++pos) 00910 my_default_record_cache_size=atoi(pos); 00911 break; 00912 case 'v': /* verbose */ 00913 verbose=1; 00914 break; 00915 case 'm': /* records */ 00916 if ((recant=atoi(++pos)) < 10) 00917 { 00918 fprintf(stderr,"record count must be >= 10\n"); 00919 exit(1); 00920 } 00921 break; 00922 case 'e': /* myisam_block_length */ 00923 if ((myisam_block_size= atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || 00924 myisam_block_size > MI_MAX_KEY_BLOCK_LENGTH) 00925 { 00926 fprintf(stderr,"Wrong myisam_block_length\n"); 00927 exit(1); 00928 } 00929 myisam_block_size= my_round_up_to_next_power(myisam_block_size); 00930 break; 00931 case 'E': /* myisam_block_length */ 00932 if ((key_cache_block_size=atoi(++pos)) < MI_MIN_KEY_BLOCK_LENGTH || 00933 key_cache_block_size > MI_MAX_KEY_BLOCK_LENGTH) 00934 { 00935 fprintf(stderr,"Wrong key_cache_block_size\n"); 00936 exit(1); 00937 } 00938 key_cache_block_size= my_round_up_to_next_power(key_cache_block_size); 00939 break; 00940 case 'f': 00941 if ((first_key=atoi(++pos)) < 0 || first_key >= MYISAM_KEYS) 00942 first_key=0; 00943 break; 00944 case 'k': 00945 if ((keys=(uint) atoi(++pos)) < 1 || 00946 keys > (uint) (MYISAM_KEYS-first_key)) 00947 keys=MYISAM_KEYS-first_key; 00948 break; 00949 case 'P': 00950 pack_type=0; /* Don't use DIFF_LENGTH */ 00951 pack_seg=0; 00952 break; 00953 case 'R': /* Length of record pointer */ 00954 rec_pointer_size=atoi(++pos); 00955 if (rec_pointer_size > 7) 00956 rec_pointer_size=0; 00957 break; 00958 case 'S': 00959 pack_fields=0; /* Static-length-records */ 00960 break; 00961 case 's': 00962 silent=1; 00963 break; 00964 case 't': 00965 testflag=atoi(++pos); /* testmod */ 00966 break; 00967 case 'q': 00968 opt_quick_mode=1; 00969 break; 00970 case 'c': 00971 create_flag|= HA_CREATE_CHECKSUM; 00972 break; 00973 case 'D': 00974 create_flag|=HA_CREATE_DELAY_KEY_WRITE; 00975 break; 00976 case '?': 00977 case 'I': 00978 case 'V': 00979 printf("%s Ver 1.2 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE); 00980 puts("By Monty, for your professional use\n"); 00981 printf("Usage: %s [-?AbBcDIKLPRqSsVWltv] [-k#] [-f#] [-m#] [-e#] [-E#] [-t#]\n", 00982 progname); 00983 exit(0); 00984 case '#': 00985 DBUG_PUSH (++pos); 00986 break; 00987 default: 00988 printf("Illegal option: '%c'\n",*pos); 00989 break; 00990 } 00991 } 00992 return; 00993 } /* get options */ 00994 00995 /* Get a random value 0 <= x <= n */ 00996 00997 static uint rnd(uint max_value) 00998 { 00999 return (uint) ((rand() & 32767)/32767.0*max_value); 01000 } /* rnd */ 01001 01002 01003 /* Create a variable length record */ 01004 01005 static void fix_length(byte *rec, uint length) 01006 { 01007 bmove(rec+STANDARD_LENGTH, 01008 "0123456789012345678901234567890123456789012345678901234567890", 01009 length-STANDARD_LENGTH); 01010 strfill(rec+length,STANDARD_LENGTH+60-length,' '); 01011 } /* fix_length */ 01012 01013 01014 /* Put maybe a blob in record */ 01015 01016 static void put_blob_in_record(char *blob_pos, char **blob_buffer) 01017 { 01018 ulong i,length; 01019 if (use_blob) 01020 { 01021 if (rnd(10) == 0) 01022 { 01023 if (! *blob_buffer && 01024 !(*blob_buffer=my_malloc((uint) use_blob,MYF(MY_WME)))) 01025 { 01026 use_blob=0; 01027 return; 01028 } 01029 length=rnd(use_blob); 01030 for (i=0 ; i < length ; i++) 01031 (*blob_buffer)[i]=(char) (length+i); 01032 int4store(blob_pos,length); 01033 memcpy_fixed(blob_pos+4,(char*) blob_buffer,sizeof(char*)); 01034 } 01035 else 01036 { 01037 int4store(blob_pos,0); 01038 } 01039 } 01040 return; 01041 } 01042 01043 01044 static void copy_key(MI_INFO *info,uint inx,uchar *rec,uchar *key_buff) 01045 { 01046 HA_KEYSEG *keyseg; 01047 01048 for (keyseg=info->s->keyinfo[inx].seg ; keyseg->type ; keyseg++) 01049 { 01050 memcpy(key_buff,rec+keyseg->start,(size_t) keyseg->length); 01051 key_buff+=keyseg->length; 01052 } 01053 return; 01054 }
1.4.7

