1 | /* Copyright (c) 2000, 2011, Oracle and/or its affiliates. |
2 | Copyright (c) 2010, 2011, Monty Program Ab |
3 | |
4 | This program is free software; you can redistribute it and/or modify |
5 | it under the terms of the GNU General Public License as published by |
6 | the Free Software Foundation; version 2 of the License. |
7 | |
8 | This program 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 |
11 | GNU General Public License for more details. |
12 | |
13 | You should have received a copy of the GNU General Public License |
14 | along with this program; if not, write to the Free Software |
15 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ |
16 | |
17 | /* Test av isam-databas: stor test */ |
18 | |
19 | #include "heapdef.h" /* Because of hp_find_block */ |
20 | #include <signal.h> |
21 | |
22 | #define MAX_RECORDS 100000 |
23 | #define MAX_KEYS 4 |
24 | |
25 | static int get_options(int argc, char *argv[]); |
26 | static int rnd(int max_value); |
27 | static sig_handler endprog(int sig_number); |
28 | |
29 | static uint flag=0,verbose=0,testflag=0,recant=10000,silent=0; |
30 | static uint keys=MAX_KEYS; |
31 | static uint16 key1[1001]; |
32 | static my_bool key3[MAX_RECORDS]; |
33 | static int reclength=39; |
34 | |
35 | |
36 | static int calc_check(uchar *buf,uint length); |
37 | static void make_record(uchar *record, uint n1, uint n2, uint n3, |
38 | const char *mark, uint count); |
39 | |
40 | /* Main program */ |
41 | |
42 | int main(int argc, char *argv[]) |
43 | { |
44 | register uint i,j; |
45 | uint ant,n1,n2,n3; |
46 | uint write_count,update,opt_delete,check2,dupp_keys,found_key; |
47 | int error; |
48 | ulong pos; |
49 | unsigned long key_check; |
50 | uchar record[128],record2[128],record3[128],key[10]; |
51 | const char *filename,*filename2; |
52 | HP_INFO *file,*file2; |
53 | HP_SHARE *tmp_share; |
54 | HP_KEYDEF keyinfo[MAX_KEYS]; |
55 | HA_KEYSEG keyseg[MAX_KEYS*5]; |
56 | HEAP_PTR UNINIT_VAR(position); |
57 | HP_CREATE_INFO hp_create_info; |
58 | CHARSET_INFO *cs= &my_charset_latin1; |
59 | my_bool unused; |
60 | MY_INIT(argv[0]); /* init my_sys library & pthreads */ |
61 | |
62 | filename= "test2" ; |
63 | filename2= "test2_2" ; |
64 | file=file2=0; |
65 | get_options(argc,argv); |
66 | |
67 | bzero(&hp_create_info, sizeof(hp_create_info)); |
68 | hp_create_info.max_table_size= 2*1024L*1024L; |
69 | hp_create_info.keys= keys; |
70 | hp_create_info.keydef= keyinfo; |
71 | hp_create_info.reclength= reclength; |
72 | hp_create_info.max_records= (ulong) flag*100000L; |
73 | hp_create_info.min_records= (ulong) recant/2; |
74 | |
75 | write_count=update=opt_delete=0; |
76 | key_check=0; |
77 | |
78 | keyinfo[0].seg=keyseg; |
79 | keyinfo[0].keysegs=1; |
80 | keyinfo[0].flag= 0; |
81 | keyinfo[0].algorithm= HA_KEY_ALG_HASH; |
82 | keyinfo[0].seg[0].type=HA_KEYTYPE_BINARY; |
83 | keyinfo[0].seg[0].start=0; |
84 | keyinfo[0].seg[0].length=6; |
85 | keyinfo[0].seg[0].null_bit=0; |
86 | keyinfo[0].seg[0].charset=cs; |
87 | keyinfo[1].seg=keyseg+1; |
88 | keyinfo[1].keysegs=2; |
89 | keyinfo[1].flag=0; |
90 | keyinfo[1].algorithm= HA_KEY_ALG_HASH; |
91 | keyinfo[1].seg[0].type=HA_KEYTYPE_BINARY; |
92 | keyinfo[1].seg[0].start=7; |
93 | keyinfo[1].seg[0].length=6; |
94 | keyinfo[1].seg[0].null_bit=0; |
95 | keyinfo[1].seg[0].charset=cs; |
96 | keyinfo[1].seg[1].type=HA_KEYTYPE_TEXT; |
97 | keyinfo[1].seg[1].start=0; /* key in two parts */ |
98 | keyinfo[1].seg[1].length=6; |
99 | keyinfo[1].seg[1].null_bit=0; |
100 | keyinfo[1].seg[1].charset=cs; |
101 | keyinfo[2].seg=keyseg+3; |
102 | keyinfo[2].keysegs=1; |
103 | keyinfo[2].flag=HA_NOSAME; |
104 | keyinfo[2].algorithm= HA_KEY_ALG_HASH; |
105 | keyinfo[2].seg[0].type=HA_KEYTYPE_BINARY; |
106 | keyinfo[2].seg[0].start=12; |
107 | keyinfo[2].seg[0].length=8; |
108 | keyinfo[2].seg[0].null_bit=0; |
109 | keyinfo[2].seg[0].charset=cs; |
110 | keyinfo[3].seg=keyseg+4; |
111 | keyinfo[3].keysegs=1; |
112 | keyinfo[3].flag=HA_NOSAME; |
113 | keyinfo[3].algorithm= HA_KEY_ALG_HASH; |
114 | keyinfo[3].seg[0].type=HA_KEYTYPE_BINARY; |
115 | keyinfo[3].seg[0].start=37; |
116 | keyinfo[3].seg[0].length=1; |
117 | keyinfo[3].seg[0].null_bit=1; |
118 | keyinfo[3].seg[0].null_pos=38; |
119 | keyinfo[3].seg[0].charset=cs; |
120 | |
121 | bzero((char*) key1,sizeof(key1)); |
122 | bzero((char*) key3,sizeof(key3)); |
123 | |
124 | printf("- Creating heap-file\n" ); |
125 | if (heap_create(filename, &hp_create_info, &tmp_share, &unused) || |
126 | !(file= heap_open(filename, 2))) |
127 | goto err; |
128 | signal(SIGINT,endprog); |
129 | |
130 | printf("- Writing records:s\n" ); |
131 | strmov((char*) record," ..... key" ); |
132 | |
133 | for (i=0 ; i < recant ; i++) |
134 | { |
135 | n1=rnd(1000); n2=rnd(100); n3=rnd(MY_MIN(recant*5,MAX_RECORDS)); |
136 | make_record(record,n1,n2,n3,"Pos" ,write_count); |
137 | |
138 | if (heap_write(file,record)) |
139 | { |
140 | if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) |
141 | { |
142 | printf("Error: %d in write at record: %d\n" ,my_errno,i); |
143 | goto err; |
144 | } |
145 | if (verbose) printf(" Double key: %d\n" ,n3); |
146 | } |
147 | else |
148 | { |
149 | if (key3[n3] == 1) |
150 | { |
151 | printf("Error: Didn't get error when writing second key: '%8d'\n" ,n3); |
152 | goto err; |
153 | } |
154 | write_count++; key1[n1]++; key3[n3]=1; |
155 | key_check+=n1; |
156 | } |
157 | if (testflag == 1 && heap_check_heap(file,0)) |
158 | { |
159 | puts("Heap keys crashed" ); |
160 | goto err; |
161 | } |
162 | } |
163 | if (testflag == 1) |
164 | goto end; |
165 | if (heap_check_heap(file,0)) |
166 | { |
167 | puts("Heap keys crashed" ); |
168 | goto err; |
169 | } |
170 | |
171 | printf("- Delete\n" ); |
172 | for (i=0 ; i < write_count/10 ; i++) |
173 | { |
174 | for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; |
175 | if (j != 0) |
176 | { |
177 | sprintf((char*) key,"%6d" ,j); |
178 | if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) |
179 | { |
180 | printf("can't find key1: \"%s\"\n" ,(char*) key); |
181 | goto err; |
182 | } |
183 | if (heap_delete(file,record)) |
184 | { |
185 | printf("error: %d; can't delete record: \"%s\"\n" , my_errno,(char*) record); |
186 | goto err; |
187 | } |
188 | opt_delete++; |
189 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
190 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
191 | key_check-=atoi((char*) record); |
192 | if (testflag == 2 && heap_check_heap(file,0)) |
193 | { |
194 | puts("Heap keys crashed" ); |
195 | goto err; |
196 | } |
197 | } |
198 | else |
199 | puts("Warning: Skipping delete test because no dupplicate keys" ); |
200 | } |
201 | if (testflag==2) goto end; |
202 | if (heap_check_heap(file,0)) |
203 | { |
204 | puts("Heap keys crashed" ); |
205 | goto err; |
206 | } |
207 | |
208 | printf("- Update\n" ); |
209 | for (i=0 ; i < write_count/10 ; i++) |
210 | { |
211 | n1=rnd(1000); n2=rnd(100); n3=rnd(MY_MIN(recant*2,MAX_RECORDS)); |
212 | make_record(record2, n1, n2, n3, "XXX" , update); |
213 | if (rnd(2) == 1) |
214 | { |
215 | if (heap_scan_init(file)) |
216 | goto err; |
217 | j=rnd(write_count-opt_delete); |
218 | while ((error=heap_scan(file,record) == HA_ERR_RECORD_DELETED) || |
219 | (!error && j)) |
220 | { |
221 | if (!error) |
222 | j--; |
223 | } |
224 | if (error) |
225 | goto err; |
226 | } |
227 | else |
228 | { |
229 | for (j=rnd(1000)+1 ; j>0 && key1[j] == 0 ; j--) ; |
230 | if (!key1[j]) |
231 | continue; |
232 | sprintf((char*) key,"%6d" ,j); |
233 | if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) |
234 | { |
235 | printf("can't find key1: \"%s\"\n" ,(char*) key); |
236 | goto err; |
237 | } |
238 | } |
239 | if (heap_update(file,record,record2)) |
240 | { |
241 | if (my_errno != HA_ERR_FOUND_DUPP_KEY || key3[n3] == 0) |
242 | { |
243 | printf("error: %d; can't update:\nFrom: \"%s\"\nTo: \"%s\"\n" , |
244 | my_errno,(char*) record, (char*) record2); |
245 | goto err; |
246 | } |
247 | if (verbose) |
248 | printf("Double key when tried to update:\nFrom: \"%s\"\nTo: \"%s\"\n" , |
249 | (char*) record, (char*) record2); |
250 | } |
251 | else |
252 | { |
253 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
254 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
255 | key1[n1]++; key3[n3]=1; |
256 | update++; |
257 | key_check=key_check-atoi((char*) record)+n1; |
258 | } |
259 | if (testflag == 3 && heap_check_heap(file,0)) |
260 | { |
261 | puts("Heap keys crashed" ); |
262 | goto err; |
263 | } |
264 | } |
265 | if (testflag == 3) goto end; |
266 | if (heap_check_heap(file,0)) |
267 | { |
268 | puts("Heap keys crashed" ); |
269 | goto err; |
270 | } |
271 | |
272 | for (i=999, dupp_keys=found_key=0 ; i>0 ; i--) |
273 | { |
274 | if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; } |
275 | sprintf((char*) key,"%6d" ,found_key); |
276 | } |
277 | |
278 | if (dupp_keys > 3) |
279 | { |
280 | if (!silent) |
281 | printf("- Read first key - next - delete - next -> last\n" ); |
282 | DBUG_PRINT("progpos" ,("first - next - delete - next -> last" )); |
283 | |
284 | if (heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT)) |
285 | goto err; |
286 | if (heap_rnext(file,record3)) goto err; |
287 | if (heap_delete(file,record3)) goto err; |
288 | key_check-=atoi((char*) record3); |
289 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
290 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
291 | opt_delete++; |
292 | ant=2; |
293 | while ((error=heap_rnext(file,record3)) == 0 || |
294 | error == HA_ERR_RECORD_DELETED) |
295 | if (! error) |
296 | ant++; |
297 | if (ant != dupp_keys) |
298 | { |
299 | printf("next: I can only find: %d records of %d\n" , |
300 | ant,dupp_keys); |
301 | goto end; |
302 | } |
303 | dupp_keys--; |
304 | if (heap_check_heap(file,0)) |
305 | { |
306 | puts("Heap keys crashed" ); |
307 | goto err; |
308 | } |
309 | |
310 | if (!silent) |
311 | printf("- Read last key - delete - prev - prev - opt_delete - prev -> first\n" ); |
312 | |
313 | if (heap_rprev(file,record)) |
314 | goto err; |
315 | if (heap_delete(file,record3)) goto err; |
316 | key_check-=atoi((char*) record3); |
317 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
318 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
319 | opt_delete++; |
320 | if (heap_rprev(file,record3) || heap_rprev(file,record3)) |
321 | goto err; |
322 | if (heap_delete(file,record3)) goto err; |
323 | key_check-=atoi((char*) record3); |
324 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
325 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
326 | opt_delete++; |
327 | ant=3; |
328 | while ((error=heap_rprev(file,record3)) == 0 || |
329 | error == HA_ERR_RECORD_DELETED) |
330 | { |
331 | if (! error) |
332 | ant++; |
333 | } |
334 | if (ant != dupp_keys) |
335 | { |
336 | printf("next: I can only find: %d records of %d\n" , |
337 | ant,dupp_keys); |
338 | goto end; |
339 | } |
340 | dupp_keys-=2; |
341 | if (heap_check_heap(file,0)) |
342 | { |
343 | puts("Heap keys crashed" ); |
344 | goto err; |
345 | } |
346 | } |
347 | else |
348 | puts("Warning: Not enough duplicated keys: Skipping delete key check" ); |
349 | |
350 | if (!silent) |
351 | printf("- Read (first) - next - delete - next -> last\n" ); |
352 | DBUG_PRINT("progpos" ,("first - next - delete - next -> last" )); |
353 | |
354 | if (heap_scan_init(file)) |
355 | goto err; |
356 | while ((error=heap_scan(file,record3) == HA_ERR_RECORD_DELETED)) ; |
357 | if (error) |
358 | goto err; |
359 | if (heap_delete(file,record3)) goto err; |
360 | key_check-=atoi((char*) record3); |
361 | opt_delete++; |
362 | key1[atoi((char*) record+keyinfo[0].seg[0].start)]--; |
363 | key3[atoi((char*) record+keyinfo[2].seg[0].start)]=0; |
364 | ant=0; |
365 | while ((error=heap_scan(file,record3)) == 0 || |
366 | error == HA_ERR_RECORD_DELETED) |
367 | if (! error) |
368 | ant++; |
369 | if (ant != write_count-opt_delete) |
370 | { |
371 | printf("next: Found: %d records of %d\n" ,ant,write_count-opt_delete); |
372 | goto end; |
373 | } |
374 | if (heap_check_heap(file,0)) |
375 | { |
376 | puts("Heap keys crashed" ); |
377 | goto err; |
378 | } |
379 | |
380 | puts("- Test if: Read rrnd - same - rkey - same" ); |
381 | DBUG_PRINT("progpos" ,("Read rrnd - same" )); |
382 | pos=rnd(write_count-opt_delete-5)+5; |
383 | heap_scan_init(file); |
384 | i=5; |
385 | while ((error=heap_scan(file,record)) == HA_ERR_RECORD_DELETED || |
386 | (error == 0 && pos)) |
387 | { |
388 | if (!error) |
389 | pos--; |
390 | if (i-- == 0) |
391 | { |
392 | bmove(record3,record,reclength); |
393 | position=heap_position(file); |
394 | } |
395 | } |
396 | if (error) |
397 | goto err; |
398 | bmove(record2,record,reclength); |
399 | if (heap_rsame(file,record,-1) || heap_rsame(file,record2,2)) |
400 | goto err; |
401 | if (memcmp(record2,record,reclength)) |
402 | { |
403 | puts("heap_rsame didn't find right record" ); |
404 | goto end; |
405 | } |
406 | |
407 | puts("- Test of read through position" ); |
408 | if (heap_rrnd(file,record,position)) |
409 | goto err; |
410 | if (memcmp(record3,record,reclength)) |
411 | { |
412 | puts("heap_frnd didn't find right record" ); |
413 | goto end; |
414 | } |
415 | |
416 | printf("- heap_info\n" ); |
417 | { |
418 | HEAPINFO info; |
419 | heap_info(file,&info,0); |
420 | /* We have to test with opt_delete +1 as this may be the case if the last |
421 | inserted row was a duplicate key */ |
422 | if (info.records != write_count-opt_delete || |
423 | (info.deleted != opt_delete && info.deleted != opt_delete+1)) |
424 | { |
425 | puts("Wrong info from heap_info" ); |
426 | printf("Got: records: %ld(%d) deleted: %ld(%d)\n" , |
427 | info.records,write_count-opt_delete,info.deleted,opt_delete); |
428 | } |
429 | } |
430 | |
431 | printf("- Read through all records with scan\n" ); |
432 | if (heap_reset(file) || heap_extra(file,HA_EXTRA_CACHE)) |
433 | { |
434 | puts("got error from heap_extra" ); |
435 | goto end; |
436 | } |
437 | ant=check2=0; |
438 | heap_scan_init(file); |
439 | while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE && |
440 | ant < write_count + 10) |
441 | { |
442 | if (!error) |
443 | { |
444 | ant++; |
445 | check2+=calc_check(record,reclength); |
446 | } |
447 | } |
448 | if (ant != write_count-opt_delete) |
449 | { |
450 | printf("scan: I can only find: %d records of %d\n" , ant, |
451 | write_count-opt_delete); |
452 | goto end; |
453 | } |
454 | |
455 | if (heap_extra(file,HA_EXTRA_NO_CACHE)) |
456 | { |
457 | puts("got error from heap_extra(HA_EXTRA_NO_CACHE)" ); |
458 | goto end; |
459 | } |
460 | |
461 | for (i=999, dupp_keys=found_key=0 ; i>0 ; i--) |
462 | { |
463 | if (key1[i] > dupp_keys) { dupp_keys=key1[i]; found_key=i; } |
464 | sprintf((char*) key,"%6d" ,found_key); |
465 | } |
466 | printf("- Read through all keys with first-next-last-prev\n" ); |
467 | ant=0; |
468 | for (error=heap_rkey(file,record,0,key,6, HA_READ_KEY_EXACT); |
469 | ! error ; |
470 | error=heap_rnext(file,record)) |
471 | ant++; |
472 | if (ant != dupp_keys) |
473 | { |
474 | printf("first-next: I can only find: %d records of %d\n" , ant, |
475 | dupp_keys); |
476 | goto end; |
477 | } |
478 | |
479 | ant=0; |
480 | for (error=heap_rprev(file,record) ; |
481 | ! error ; |
482 | error=heap_rprev(file,record)) |
483 | { |
484 | ant++; |
485 | check2+=calc_check(record,reclength); |
486 | } |
487 | if (ant != dupp_keys) |
488 | { |
489 | printf("last-prev: I can only find: %d records of %d\n" , ant, |
490 | dupp_keys); |
491 | goto end; |
492 | } |
493 | |
494 | if (testflag == 4) goto end; |
495 | |
496 | printf("- Reading through all rows through keys\n" ); |
497 | if (!(file2=heap_open(filename, 2))) |
498 | goto err; |
499 | if (heap_scan_init(file)) |
500 | goto err; |
501 | while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE) |
502 | { |
503 | if (error == 0) |
504 | { |
505 | if (heap_rkey(file2,record2,2,record+keyinfo[2].seg[0].start,8, |
506 | HA_READ_KEY_EXACT)) |
507 | { |
508 | printf("can't find key3: \"%.8s\"\n" , |
509 | record+keyinfo[2].seg[0].start); |
510 | goto err; |
511 | } |
512 | } |
513 | } |
514 | heap_close(file2); |
515 | |
516 | printf("- Creating output heap-file 2\n" ); |
517 | hp_create_info.keys= 1; |
518 | hp_create_info.max_records= 0; |
519 | hp_create_info.min_records= 0; |
520 | if (heap_create(filename2, &hp_create_info, &tmp_share, &unused) || |
521 | !(file2= heap_open_from_share_and_register(tmp_share, 2))) |
522 | goto err; |
523 | |
524 | printf("- Copying and removing records\n" ); |
525 | if (heap_scan_init(file)) |
526 | goto err; |
527 | while ((error=heap_scan(file,record)) != HA_ERR_END_OF_FILE) |
528 | { |
529 | if (error == 0) |
530 | { |
531 | if (heap_write(file2,record)) |
532 | goto err; |
533 | key_check-=atoi((char*) record); |
534 | write_count++; |
535 | if (heap_delete(file,record)) |
536 | goto err; |
537 | opt_delete++; |
538 | } |
539 | pos++; |
540 | } |
541 | printf("- Checking heap tables\n" ); |
542 | if (heap_check_heap(file,1) || heap_check_heap(file2,1)) |
543 | { |
544 | puts("Heap keys crashed" ); |
545 | goto err; |
546 | } |
547 | |
548 | if (my_errno != HA_ERR_END_OF_FILE) |
549 | printf("error: %d from heap_rrnd\n" ,my_errno); |
550 | if (key_check) |
551 | printf("error: Some read got wrong: check is %ld\n" ,(long) key_check); |
552 | |
553 | end: |
554 | printf("\nFollowing test have been made:\n" ); |
555 | printf("Write records: %d\nUpdate records: %d\nDelete records: %d\n" , write_count,update,opt_delete); |
556 | heap_clear(file); |
557 | if (heap_close(file) || (file2 && heap_close(file2))) |
558 | goto err; |
559 | heap_delete_table(filename2); |
560 | hp_panic(HA_PANIC_CLOSE); |
561 | my_end(MY_GIVE_INFO); |
562 | return(0); |
563 | err: |
564 | printf("Got error: %d when using heap-database\n" ,my_errno); |
565 | (void) heap_close(file); |
566 | return(1); |
567 | } /* main */ |
568 | |
569 | |
570 | /* Read options */ |
571 | |
572 | static int get_options(int argc,char *argv[]) |
573 | { |
574 | char *pos,*progname; |
575 | |
576 | progname= argv[0]; |
577 | |
578 | while (--argc >0 && *(pos = *(++argv)) == '-' ) { |
579 | switch(*++pos) { |
580 | case 'B': /* Big file */ |
581 | flag=1; |
582 | break; |
583 | case 'v': /* verbose */ |
584 | verbose=1; |
585 | break; |
586 | case 'm': /* records */ |
587 | recant=atoi(++pos); |
588 | break; |
589 | case 's': |
590 | silent=1; |
591 | break; |
592 | case 't': |
593 | testflag=atoi(++pos); /* testmod */ |
594 | break; |
595 | case 'V': |
596 | case 'I': |
597 | case '?': |
598 | printf("%s Ver 1.2 for %s at %s\n" ,progname,SYSTEM_TYPE,MACHINE_TYPE); |
599 | puts("TCX Datakonsult AB, by Monty, for your professional use\n" ); |
600 | printf("Usage: %s [-?ABIKLsWv] [-m#] [-t#]\n" ,progname); |
601 | exit(0); |
602 | case '#': |
603 | DBUG_PUSH (++pos); |
604 | break; |
605 | } |
606 | } |
607 | return 0; |
608 | } /* get options */ |
609 | |
610 | /* Generate a random value in intervall 0 <=x <= n */ |
611 | |
612 | static int rnd(int max_value) |
613 | { |
614 | return (int) ((rand() & 32767)/32767.0*max_value); |
615 | } /* rnd */ |
616 | |
617 | |
618 | static sig_handler endprog(int sig_number __attribute__((unused))) |
619 | { |
620 | { |
621 | hp_panic(HA_PANIC_CLOSE); |
622 | my_end(1); |
623 | exit(1); |
624 | } |
625 | } |
626 | |
627 | static int calc_check(uchar *buf, uint length) |
628 | { |
629 | int check=0; |
630 | while (length--) |
631 | check+= (int) (uchar) *(buf++); |
632 | return check; |
633 | } |
634 | |
635 | static void make_record(uchar *record, uint n1, uint n2, uint n3, |
636 | const char *mark, uint count) |
637 | { |
638 | bfill(record,reclength,' '); |
639 | sprintf((char*) record,"%6d:%4d:%8d:%3.3s: %4d" , |
640 | n1,n2,n3,mark,count); |
641 | record[37]='A'; /* Store A in null key */ |
642 | record[38]=1; /* set as null */ |
643 | } |
644 | |