Alexandre Julliard | e2991ea | 1995-07-29 13:09:43 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * Copyright 1995 Michael Veksler. mveksler@vnet.ibm.com |
| 3 | *************************************************************************** |
| 4 | * File: hash_test.c |
| 5 | * Purpose : test generic_hash correctness. |
| 6 | * NOTE: |
| 7 | * This code covers only about 80% of generic_hash code. |
| 8 | * There might be bugs in the remaining 20% - although most |
| 9 | * of the functionality is tested with wine linckage. |
| 10 | * For complete testing a little more work should be done. |
| 11 | *************************************************************************** |
| 12 | */ |
| 13 | |
| 14 | #include <stdlib.h> |
| 15 | #include <stdio.h> |
| 16 | #include <assert.h> |
| 17 | #include "generic_hash.h" |
| 18 | |
| 19 | #define SIZE 200 |
| 20 | typedef struct { int a,b;} DATA ; |
| 21 | DATA data[SIZE]; |
| 22 | int keys[SIZE]; |
| 23 | int peeks=0; |
| 24 | |
| 25 | HASH_CONTAINER *hash1; |
| 26 | HASH_CONTAINER *hash2; /* actual data is shared with hash1 */ |
| 27 | |
| 28 | /* test insertion using keys[] and data[] inserting using hash1 and */ |
| 29 | /* hash2 periodically, test hash after every 2 insertions */ |
| 30 | void test_insert() |
| 31 | { |
| 32 | int i,j; |
| 33 | HASH_VAL *item; |
| 34 | |
| 35 | printf("testing insertion \n"); |
| 36 | for (i=0 ; i < SIZE-1 ; i+=2) { |
| 37 | assert(hash_add_item(hash1, keys[i], (HASH_VAL *)&data[i])); |
| 38 | assert(hash_add_item(hash2, keys[i+1], (HASH_VAL *)&data[i+1])); |
| 39 | for (j=0 ; j <= i+1 ; j++) { |
| 40 | item= hash_locate_item(hash1, keys[j], (HASH_VAL *)&data[j]); |
| 41 | if (item == NULL) { |
| 42 | printf("NULL item: i=%d,j=%d\n",i,j); |
| 43 | continue; |
| 44 | } |
| 45 | peeks++; |
| 46 | if (memcmp(item,&data[j],sizeof(DATA))!=0) { |
| 47 | printf("i=%d,j=%d\n",i,j); |
| 48 | printf("saved=(%d,%d), orig=(%d,%d)\n", |
| 49 | ((DATA*)item)->a, ((DATA*)item)->b, |
| 50 | data[j].a, data[j].b); |
| 51 | } |
| 52 | } |
| 53 | } |
| 54 | } |
| 55 | |
| 56 | /* test deletion using keys[] and data[] deleting using hash1 and */ |
| 57 | /* hash2 periodicly, test hash after every 2 deletions */ |
| 58 | void test_delete() |
| 59 | { |
| 60 | int i,j; |
| 61 | HASH_VAL *item; |
| 62 | |
| 63 | printf("testing deletion\n"); |
| 64 | for (i=0 ; i < SIZE-1 ; i+=2) { |
| 65 | assert(hash_delete_item(hash2, keys[i], NULL)); |
| 66 | assert(hash_delete_item(hash1, keys[i+1], NULL)); |
| 67 | for (j=0 ; j < SIZE ; j++) { |
| 68 | item= hash_locate_item(hash2, keys[j], (HASH_VAL *)&data[j]); |
| 69 | if (item == NULL) { |
| 70 | if ( j > i+1) |
| 71 | printf("NULL item: i=%d,j=%d\n",i,j); |
| 72 | continue; |
| 73 | } |
| 74 | if (item != NULL && j <= i+1) { |
| 75 | printf("Non NULL item: i=%d,j=%d\n",i,j); |
| 76 | continue; |
| 77 | } |
| 78 | if (memcmp(item,&data[j],sizeof(DATA))!=0) { |
| 79 | printf("i=%d,j=%d\n",i,j); |
| 80 | printf("saved=(%d,%d), orig=(%d,%d)\n", |
| 81 | ((DATA*)item)->a, ((DATA*)item)->b, |
| 82 | data[j].a, data[j].b); |
| 83 | } |
| 84 | } |
| 85 | } |
| 86 | |
| 87 | } |
| 88 | |
| 89 | |
| 90 | int main() |
| 91 | { |
| 92 | int i; |
| 93 | |
| 94 | hash1= create_hash(sizeof(DATA), 1); |
| 95 | assert(hash1); |
| 96 | hash2= attach_remote_hash(hash1->shared, sizeof(DATA), HASH_MEM_ACCESS); |
| 97 | assert(hash2); |
| 98 | |
| 99 | for (i=0 ; i< SIZE ; i++) { |
| 100 | data[i].a= rand(); |
| 101 | data[i].b= rand(); |
| 102 | keys[i]= rand(); |
| 103 | } |
| 104 | |
| 105 | test_insert(); |
| 106 | detach_hash(hash1); |
| 107 | free(hash1); |
| 108 | hash1= attach_remote_hash(hash2->shared, sizeof(DATA), HASH_MEM_ACCESS); |
| 109 | |
| 110 | test_delete(); |
| 111 | test_insert(); |
| 112 | |
| 113 | detach_hash(hash1); |
| 114 | destroy_hash(hash2); |
| 115 | printf("peeks=%d\n", peeks); |
| 116 | return 0; |
| 117 | } |