home *** CD-ROM | disk | FTP | other *** search
/ Chip 2001 January / Chip_2001-01_cd1.bin / tema / mysql / mysql-3.23.28g-win-source.exe / mysys / testhash.c < prev    next >
C/C++ Source or Header  |  2000-08-31  |  7KB  |  292 lines

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