~drizzle-trunk/drizzle/development

1 by brian
clean slate
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
void free_record(void *record);
34
35
static uchar *hash2_key(const uchar *rec,uint *length,
36
		       my_bool not_used __attribute__((unused)))
37
{
38
  *length=(uint) (uchar) rec[reclength-1];
39
  return (uchar*) rec;
40
}
41
42
/* main program */
43
44
int main(int argc,char *argv[])
45
{
46
  MY_INIT(argv[0]);
47
48
  get_options(argc,argv);
49
50
  exit(do_test());
51
}
52
53
static int do_test()
54
{
55
  register uint i,j;
56
  uint n1,n2,n3;
57
  uint write_count,update,delete;
58
  ulong pos;
59
  unsigned long key_check;
60
  char *record,*recpos,oldrecord[120],key[10];
61
  HASH hash,hash2;
62
63
  write_count=update=delete=0;
64
  key_check=0;
65
  bzero((char*) key1,sizeof(key1[0])*1000);
66
67
  printf("- Creating hash\n");
68
  if (hash_init(&hash, default_charset_info, recant/2, 0, 6, 0, free_record, 0))
69
    goto err;
70
  printf("- Writing records:\n");
71
72
  for (i=0 ; i < recant ; i++)
73
  {
74
    n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*5,MAX_RECORDS));
75
    record= (char*) my_malloc(reclength,MYF(MY_FAE));
76
    sprintf(record,"%6d:%4d:%8d:Pos: %4d      ",n1,n2,n3,write_count);
77
    if (my_hash_insert(&hash,record))
78
    {
79
      printf("Error: %d in write at record: %d\n",my_errno,i);
80
      goto err;
81
    }
82
    key1[n1]++;
83
    key_check+=n1;
84
    write_count++;
85
  }
86
  printf("- Delete\n");
87
  for (i=0 ; i < write_count/10 ; i++)
88
  {
89
    for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
90
    if (j != 0)
91
    {
92
      sprintf(key,"%6d",j);
93
      if (!(recpos=hash_search(&hash,key,0)))
94
      {
95
	printf("can't find key1: \"%s\"\n",key);
96
	goto err;
97
      }
98
      key1[atoi(recpos)]--;
99
      key_check-=atoi(recpos);
100
      memcpy(oldrecord,recpos,reclength);
101
      if (hash_delete(&hash,recpos))
102
      {
103
	printf("error: %d; can't delete record: \"%s\"\n", my_errno,oldrecord);
104
	goto err;
105
      }
106
      delete++;
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
107
      if (testflag == 2)
1 by brian
clean slate
108
      {
109
	puts("Heap keys crashed");
110
	goto err;
111
      }
112
    }
113
  }
114
115
  printf("- Update\n");
116
  for (i=0 ; i < write_count/10 ; i++)
117
  {
118
    n1=rnd(1000); n2=rnd(100); n3=rnd(min(recant*2,MAX_RECORDS));
119
    for (j=rnd(1000) ; j>0 && key1[j] == 0 ; j--) ;
120
    if (j)
121
    {
122
      sprintf(key,"%6d",j);
123
      if (!(recpos=hash_search(&hash,key,0)))
124
      {
125
	printf("can't find key1: \"%s\"\n",key);
126
	goto err;
127
      }
128
      key1[atoi(recpos)]--;
129
      key_check=key_check-atoi(recpos)+n1;
130
      key1[n1]++;
131
      sprintf(recpos,"%6d:%4d:%8d:XXX: %4d      ",n1,n2,n3,update);
132
      update++;
133
      if (hash_update(&hash,recpos,key,0))
134
      {
135
	printf("can't update key1: \"%s\"\n",key);
136
	goto err;
137
      }
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
138
      if (testflag == 3) 
1 by brian
clean slate
139
      {
140
	printf("Heap keys crashed for %d update\n",update);
141
	goto err;
142
      }
143
    }
144
  }
145
146
  for (j=0 ; j < 1000 ; j++)
147
    if (key1[j] > 1)
148
      break;
149
  if (key1[j] > 1)
150
  {
151
    HASH_SEARCH_STATE state;
152
    printf("- Testing identical read\n");
153
    sprintf(key,"%6d",j);
154
    pos=1;
155
    if (!(recpos= hash_first(&hash, key, 0, &state)))
156
    {
157
      printf("can't find key1: \"%s\"\n",key);
158
      goto err;
159
    }
160
    while (hash_next(&hash, key, 0, &state) && pos < (ulong) (key1[j]+10))
161
      pos++;
162
    if (pos != (ulong) key1[j])
163
    {
164
      printf("Found %ld copies of key: %s. Should be %d",pos,key,key1[j]);
165
      goto err;
166
    }
167
  }
168
  printf("- Creating output heap-file 2\n");
169
  if (hash_init(&hash2, default_charset_info, hash.records, 0, 0, hash2_key, free_record,0))
170
    goto err;
171
172
  printf("- Copying and removing records\n");
173
  pos=0;
174
  while ((recpos=hash_element(&hash,0)))
175
  {
176
    record=(uchar*) my_malloc(reclength,MYF(MY_FAE));
177
    memcpy(record,recpos,reclength);
178
    record[reclength-1]=rnd(5)+1;
179
    if (my_hash_insert(&hash2,record))
180
    {
181
      printf("Got error when inserting record: %*s",reclength,record);
182
      goto err;
183
    }
184
    key_check-=atoi(record);
185
    write_count++;
186
    if (hash_delete(&hash,recpos))
187
    {
188
      printf("Got error when deleting record: %*s",reclength,recpos);
189
      goto err;
190
    }
191
    pos++;
192
  }
193
  if (key_check != 0)
194
  {
195
    printf("Key check didn't get to 0 (%ld)\n",key_check);
196
  }
197
198
  printf("\nFollowing test have been made:\n");
199
  printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n", write_count,
200
	 update,delete);
201
  hash_free(&hash); hash_free(&hash2);
202
  my_end(MY_GIVE_INFO);
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
203
  return(0);
1 by brian
clean slate
204
err:
205
  printf("Got error: %d when using hashing\n",my_errno);
51.3.15 by Jay Pipes
Phase 3 removal of DBUG in mysys
206
  return(-1);
1 by brian
clean slate
207
} /* main */
208
209
210
/* read options */
211
212
static int get_options(int argc, char **argv)
213
{
214
  char *pos,*progname;
215
216
  progname= argv[0];
217
218
  while (--argc >0 && *(pos = *(++argv)) == '-' ) {
219
    switch(*++pos) {
220
    case 'm':				/* records */
221
      recant=atoi(++pos);
222
      break;
223
    case 't':
224
      testflag=atoi(++pos);		/* testmod */
225
      break;
226
    case 'V':
227
    case 'I':
228
    case '?':
229
      printf("%s  Ver 1.0 for %s at %s\n",progname,SYSTEM_TYPE,MACHINE_TYPE);
230
      printf("MySQL AB, by Monty\n\n");
231
      printf("Usage: %s [-?ABIKLWv] [-m#] [-t#]\n",progname);
232
      exit(0);
233
    }
234
  }
235
  return 0;
236
} /* get_options */
237
238
239
/* Get a random number in the interval 0 <= x <= n */
240
241
static int rnd(int max_value)
242
{
243
  return (int) ((rand() & 32767)/32767.0*max_value);
244
} /* rnd */
245
246
247
void free_record(void *record)
248
{
249
  my_free(record,MYF(0));
250
}