testhash.c
上传用户:romrleung
上传日期:2022-05-23
资源大小:18897k
文件大小:7k
源码类别:

MySQL数据库

开发平台:

Visual C++

  1. /* Copyright (C) 2000 MySQL AB
  2.    This program is free software; you can redistribute it and/or modify
  3.    it under the terms of the GNU General Public License as published by
  4.    the Free Software Foundation; either version 2 of the License, or
  5.    (at your option) any later version.
  6.    This program is distributed in the hope that it will be useful,
  7.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  8.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  9.    GNU General Public License for more details.
  10.    You should have received a copy of the GNU General Public License
  11.    along with this program; if not, write to the Free Software
  12.    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
  13. /* Test of hash library: big test */
  14. #include <my_global.h>
  15. #include <my_sys.h>
  16. #include <hash.h>
  17. #include <m_string.h>
  18. #define MAX_RECORDS 100000
  19. #define MAX_KEYS 3
  20. static int get_options(int argc, char *argv[]);
  21. static int do_test();
  22. static int rnd(int max_value);
  23. static uint testflag=0,recant=10000,reclength=37;
  24. static uint16 key1[1000];
  25. #ifdef DBUG_OFF
  26. #define hash_check(A) 0
  27. #else
  28. my_bool hash_check(HASH *hash);
  29. #endif
  30. void free_record(void *record);
  31. static byte *hash2_key(const byte *rec,uint *length,
  32.        my_bool not_used __attribute__((unused)))
  33. {
  34.   *length=(uint) (uchar) rec[reclength-1];
  35.   return (byte*) rec;
  36. }
  37. /* main program */
  38. int main(int argc,char *argv[])
  39. {
  40.   MY_INIT(argv[0]);
  41.   DBUG_PROCESS(argv[0]);
  42.   get_options(argc,argv);
  43.   exit(do_test());
  44. }
  45. static int do_test()
  46. {
  47.   register uint i,j;
  48.   uint n1,n2,n3;
  49.   uint write_count,update,delete;
  50.   ulong pos;
  51.   unsigned long key_check;
  52.   char *record,*recpos,oldrecord[120],key[10];
  53.   HASH hash,hash2;
  54.   DBUG_ENTER("do_test");
  55.   write_count=update=delete=0;
  56.   key_check=0;
  57.   bzero((char*) key1,sizeof(key1[0])*1000);
  58.   printf("- Creating hashn");
  59.   if (hash_init(&hash,recant/2,0,6,0,free_record,0))
  60.     goto err;
  61.   printf("- Writing records:n");
  62.   for (i=0 ; i < recant ; i++)
  63.   {
  64.     n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
  65.     record= (char*) my_malloc(reclength,MYF(MY_FAE));
  66.     sprintf(record,"%6d:%4d:%8d:Pos: %4d      ",n1,n2,n3,write_count);
  67.     if (my_hash_insert(&hash,record))
  68.     {
  69.       printf("Error: %d in write at record: %dn",my_errno,i);
  70.       goto err;
  71.     }
  72.     key1[n1]++;
  73.     key_check+=n1;
  74.     write_count++;
  75.   }
  76.   if (hash_check(&hash))
  77.   {
  78.     puts("Heap keys crashed");
  79.     goto err;
  80.   }
  81.   printf("- Deleten");
  82.   for (i=0 ; i < write_count/10 ; i++)
  83.   {
  84.     for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
  85.     if (j != 0)
  86.     {
  87.       sprintf(key,"%6d",j);
  88.       if (!(recpos=hash_search(&hash,key,0)))
  89.       {
  90. printf("can't find key1: "%s"n",key);
  91. goto err;
  92.       }
  93.       key1[atoi(recpos)]--;
  94.       key_check-=atoi(recpos);
  95.       memcpy(oldrecord,recpos,reclength);
  96.       if (hash_delete(&hash,recpos))
  97.       {
  98. printf("error: %d; can't delete record: "%s"n", my_errno,oldrecord);
  99. goto err;
  100.       }
  101.       delete++;
  102.       if (testflag == 2 && hash_check(&hash))
  103.       {
  104. puts("Heap keys crashed");
  105. goto err;
  106.       }
  107.     }
  108.   }
  109.   if (hash_check(&hash))
  110.   {
  111.     puts("Hash keys crashed");
  112.     goto err;
  113.   }
  114.   printf("- Updaten");
  115.   for (i=0 ; i < write_count/10 ; i++)
  116.   {
  117.     n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
  118.     for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
  119.     if (j)
  120.     {
  121.       sprintf(key,"%6d",j);
  122.       if (!(recpos=hash_search(&hash,key,0)))
  123.       {
  124. printf("can't find key1: "%s"n",key);
  125. goto err;
  126.       }
  127.       key1[atoi(recpos)]--;
  128.       key_check=key_check-atoi(recpos)+n1;
  129.       key1[n1]++;
  130.       sprintf(recpos,"%6d:%4d:%8d:XXX: %4d      ",n1,n2,n3,update);
  131.       update++;
  132.       if (hash_update(&hash,recpos,key,0))
  133.       {
  134. printf("can't update key1: "%s"n",key);
  135. goto err;
  136.       }
  137.       if (testflag == 3 && hash_check(&hash))
  138.       {
  139. printf("Heap keys crashed for %d updaten",update);
  140. goto err;
  141.       }
  142.     }
  143.   }
  144.   if (hash_check(&hash))
  145.   {
  146.     puts("Heap keys crashed");
  147.     goto err;
  148.   }
  149.   for (j=0 ; j < 1000 ; j++)
  150.     if (key1[j] > 1)
  151.       break;
  152.   if (key1[j] > 1)
  153.   {
  154.     printf("- Testing identical readn");
  155.     sprintf(key,"%6d",j);
  156.     pos=1;
  157.     if (!(recpos=hash_search(&hash,key,0)))
  158.     {
  159.       printf("can't find key1: "%s"n",key);
  160.       goto err;
  161.     }
  162.     while (hash_next(&hash,key,0) && pos < (ulong) (key1[j]+10))
  163.       pos++;
  164.     if (pos != (ulong) key1[j])
  165.     {
  166.       printf("Found %ld copies of key: %s. Should be %d",pos,key,key1[j]);
  167.       goto err;
  168.     }
  169.   }
  170.   printf("- Creating output heap-file 2n");
  171.   if (hash_init(&hash2,hash.records,0,0,hash2_key,free_record,0))
  172.     goto err;
  173.   printf("- Copying and removing recordsn");
  174.   pos=0;
  175.   while ((recpos=hash_element(&hash,0)))
  176.   {
  177.     record=(byte*) my_malloc(reclength,MYF(MY_FAE));
  178.     memcpy(record,recpos,reclength);
  179.     record[reclength-1]=rnd(5)+1;
  180.     if (my_hash_insert(&hash2,record))
  181.     {
  182.       printf("Got error when inserting record: %*s",reclength,record);
  183.       goto err;
  184.     }
  185.     key_check-=atoi(record);
  186.     write_count++;
  187.     if (hash_delete(&hash,recpos))
  188.     {
  189.       printf("Got error when deleting record: %*s",reclength,recpos);
  190.       goto err;
  191.     }
  192.     if (testflag==4)
  193.     {
  194.       if (hash_check(&hash) || hash_check(&hash2))
  195.       {
  196. puts("Hash keys crashed");
  197. goto err;
  198.       }
  199.     }
  200.     pos++;
  201.   }
  202.   if (hash_check(&hash) || hash_check(&hash2))
  203.   {
  204.     puts("Hash keys crashed");
  205.     goto err;
  206.   }
  207.   if (key_check != 0)
  208.   {
  209.     printf("Key check didn't get to 0 (%ld)n",key_check);
  210.   }
  211.   printf("nFollowing test have been made:n");
  212.   printf("Write records: %dnUpdate records: %dnDelete records: %dn", write_count,
  213.  update,delete);
  214.   hash_free(&hash); hash_free(&hash2);
  215.   my_end(MY_GIVE_INFO);
  216.   DBUG_RETURN(0);
  217. err:
  218.   printf("Got error: %d when using hashingn",my_errno);
  219.   DBUG_RETURN(-1);
  220. } /* main */
  221. /* read options */
  222. /* NOTE! DBUG not initialised - no debugging here! */
  223. static int get_options(int argc, char **argv)
  224. {
  225.   char *pos,*progname;
  226.   DEBUGGER_OFF;
  227.   progname= argv[0];
  228.   while (--argc >0 && *(pos = *(++argv)) == '-' ) {
  229.     switch(*++pos) {
  230.     case 'm': /* records */
  231.       recant=atoi(++pos);
  232.       break;
  233.     case 't':
  234.       testflag=atoi(++pos); /* testmod */
  235.       break;
  236.     case 'V':
  237.     case 'I':
  238.     case '?':
  239.       printf("%s  Ver 1.0 for %s at %sn",progname,SYSTEM_TYPE,MACHINE_TYPE);
  240.       printf("MySQL AB, by Montynn");
  241.       printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]n",progname);
  242.       exit(0);
  243.     case '#':
  244.       DEBUGGER_ON;
  245.       DBUG_PUSH (++pos);
  246.       break;
  247.     }
  248.   }
  249.   return 0;
  250. } /* get_options */
  251. /* Get a random number in the interval 0 <= x <= n */
  252. static int rnd(int max_value)
  253. {
  254.   return (int) ((rand() & 32767)/32767.0*max_value);
  255. } /* rnd */
  256. void free_record(void *record)
  257. {
  258.   my_free(record,MYF(0));
  259. }