~linuxjedi/drizzle/trunk-bug-667053

« back to all changes in this revision

Viewing changes to mysys/testhash.c

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2000 MySQL AB
 
2
 
 
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.
 
6
 
 
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.
 
11
 
 
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 */
 
15
 
 
16
/* Test of hash library: big test */
 
17
 
 
18
#include <my_global.h>
 
19
#include <my_sys.h>
 
20
#include <hash.h>
 
21
#include <m_string.h>
 
22
 
 
23
#define MAX_RECORDS 100000
 
24
#define MAX_KEYS 3
 
25
 
 
26
static int get_options(int argc, char *argv[]);
 
27
static int do_test();
 
28
static int rnd(int max_value);
 
29
 
 
30
static uint testflag=0,recant=10000,reclength=37;
 
31
static uint16 key1[1000];
 
32
 
 
33
#ifdef DBUG_OFF
 
34
#define hash_check(A) 0
 
35
#else
 
36
my_bool hash_check(HASH *hash);
 
37
#endif
 
38
 
 
39
void free_record(void *record);
 
40
 
 
41
static uchar *hash2_key(const uchar *rec,uint *length,
 
42
                       my_bool not_used __attribute__((unused)))
 
43
{
 
44
  *length=(uint) (uchar) rec[reclength-1];
 
45
  return (uchar*) rec;
 
46
}
 
47
 
 
48
/* main program */
 
49
 
 
50
int main(int argc,char *argv[])
 
51
{
 
52
  MY_INIT(argv[0]);
 
53
  DBUG_PROCESS(argv[0]);
 
54
 
 
55
  get_options(argc,argv);
 
56
 
 
57
  exit(do_test());
 
58
}
 
59
 
 
60
static int do_test()
 
61
{
 
62
  register uint i,j;
 
63
  uint n1,n2,n3;
 
64
  uint write_count,update,delete;
 
65
  ulong pos;
 
66
  unsigned long key_check;
 
67
  char *record,*recpos,oldrecord[120],key[10];
 
68
  HASH hash,hash2;
 
69
  DBUG_ENTER("do_test");
 
70
 
 
71
  write_count=update=delete=0;
 
72
  key_check=0;
 
73
  bzero((char*) key1,sizeof(key1[0])*1000);
 
74
 
 
75
  printf("- Creating hash\n");
 
76
  if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0))
 
77
    goto err;
 
78
  printf("- Writing records:\n");
 
79
 
 
80
  for (i=0 ; i < recant ; i++)
 
81
  {
 
82
    n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
 
83
    record= (char*) my_malloc(reclength,MYF(MY_FAE));
 
84
    sprintf(record,"%6d:%4d:%8d:Pos: %4d      ",n1,n2,n3,write_count);
 
85
    if (my_hash_insert(&hash,record))
 
86
    {
 
87
      printf("Error: %d in write at record: %d\n",my_errno,i);
 
88
      goto err;
 
89
    }
 
90
    key1[n1]++;
 
91
    key_check+=n1;
 
92
    write_count++;
 
93
  }
 
94
  if (hash_check(&hash))
 
95
  {
 
96
    puts("Heap keys crashed");
 
97
    goto err;
 
98
  }
 
99
  printf("- Delete\n");
 
100
  for (i=0 ; i < write_count/10 ; i++)
 
101
  {
 
102
    for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
 
103
    if (j != 0)
 
104
    {
 
105
      sprintf(key,"%6d",j);
 
106
      if (!(recpos=hash_search(&hash,key,0)))
 
107
      {
 
108
        printf("can't find key1: \"%s\"\n",key);
 
109
        goto err;
 
110
      }
 
111
      key1[atoi(recpos)]--;
 
112
      key_check-=atoi(recpos);
 
113
      memcpy(oldrecord,recpos,reclength);
 
114
      if (hash_delete(&hash,recpos))
 
115
      {
 
116
        printf("error: %d; can't delete record: \"%s\"\n", my_errno,oldrecord);
 
117
        goto err;
 
118
      }
 
119
      delete++;
 
120
      if (testflag == 2 && hash_check(&hash))
 
121
      {
 
122
        puts("Heap keys crashed");
 
123
        goto err;
 
124
      }
 
125
    }
 
126
  }
 
127
  if (hash_check(&hash))
 
128
  {
 
129
    puts("Hash keys crashed");
 
130
    goto err;
 
131
  }
 
132
 
 
133
  printf("- Update\n");
 
134
  for (i=0 ; i < write_count/10 ; i++)
 
135
  {
 
136
    n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
 
137
    for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
 
138
    if (j)
 
139
    {
 
140
      sprintf(key,"%6d",j);
 
141
      if (!(recpos=hash_search(&hash,key,0)))
 
142
      {
 
143
        printf("can't find key1: \"%s\"\n",key);
 
144
        goto err;
 
145
      }
 
146
      key1[atoi(recpos)]--;
 
147
      key_check=key_check-atoi(recpos)+n1;
 
148
      key1[n1]++;
 
149
      sprintf(recpos,"%6d:%4d:%8d:XXX: %4d      ",n1,n2,n3,update);
 
150
      update++;
 
151
      if (hash_update(&hash,recpos,key,0))
 
152
      {
 
153
        printf("can't update key1: \"%s\"\n",key);
 
154
        goto err;
 
155
      }
 
156
      if (testflag == 3 && hash_check(&hash))
 
157
      {
 
158
        printf("Heap keys crashed for %d update\n",update);
 
159
        goto err;
 
160
      }
 
161
    }
 
162
  }
 
163
  if (hash_check(&hash))
 
164
  {
 
165
    puts("Heap keys crashed");
 
166
    goto err;
 
167
  }
 
168
 
 
169
  for (j=0 ; j < 1000 ; j++)
 
170
    if (key1[j] > 1)
 
171
      break;
 
172
  if (key1[j] > 1)
 
173
  {
 
174
    HASH_SEARCH_STATE state;
 
175
    printf("- Testing identical read\n");
 
176
    sprintf(key,"%6d",j);
 
177
    pos=1;
 
178
    if (!(recpos= hash_first(&hash, key, 0, &state)))
 
179
    {
 
180
      printf("can't find key1: \"%s\"\n",key);
 
181
      goto err;
 
182
    }
 
183
    while (hash_next(&hash, key, 0, &state) && 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, default_charset_info, 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=(uchar*) my_malloc(reclength,MYF(MY_FAE));
 
200
    memcpy(record,recpos,reclength);
 
201
    record[reclength-1]=rnd(5)+1;
 
202
    if (my_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
/* read options */
 
247
/* NOTE! DBUG not initialised - no debugging here! */
 
248
 
 
249
static int get_options(int argc, char **argv)
 
250
{
 
251
  char *pos,*progname;
 
252
 
 
253
  progname= argv[0];
 
254
 
 
255
  while (--argc >0 && *(pos = *(++argv)) == '-' ) {
 
256
    switch(*++pos) {
 
257
    case 'm':                           /* records */
 
258
      recant=atoi(++pos);
 
259
      break;
 
260
    case 't':
 
261
      testflag=atoi(++pos);             /* testmod */
 
262
      break;
 
263
    case 'V':
 
264
    case 'I':
 
265
    case '?':
 
266
      printf("%s  Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
 
267
      printf("MySQL AB, by Monty\n\n");
 
268
      printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname);
 
269
      exit(0);
 
270
    case '#':
 
271
      DBUG_PUSH (++pos);
 
272
      break;
 
273
    }
 
274
  }
 
275
  return 0;
 
276
} /* get_options */
 
277
 
 
278
 
 
279
/* Get a random number in the interval 0 <= x <= n */
 
280
 
 
281
static int rnd(int max_value)
 
282
{
 
283
  return (int) ((rand() & 32767)/32767.0*max_value);
 
284
} /* rnd */
 
285
 
 
286
 
 
287
void free_record(void *record)
 
288
{
 
289
  my_free(record,MYF(0));
 
290
}