00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "hash.h"
00025 #include <stdlib.h>
00026 #include <string.h>
00027 #include <stdio.h>
00028
00029
00030 static int hash ( char *key ) {
00031 unsigned int hash = 0;
00032
00033 while ( *key ) {
00034
00035
00036 hash ^= *key++;
00037 hash <<= 1;
00038 }
00039
00040 return hash;
00041 }
00042
00043
00044 void *hash_data ( HashTable *t, char *key ) {
00045 unsigned int index;
00046 hashItem *h;
00047
00048 if ( t == NULL || t->size <= 0 || t->hash_func == NULL || key == NULL )
00049 return NULL;
00050
00051 index = t->hash_func(key);
00052 index %= t->size;
00053
00054 for ( h = t->item[index]; h != NULL; h = h->next )
00055 if ( key && strcmp(key, h->key) == 0 )
00056 return h->data;
00057
00058 return NULL;
00059 }
00060
00061
00062
00063 void *hash_del ( HashTable *t, char *key ) {
00064 unsigned int index;
00065 void *data;
00066 hashItem *h, *last = NULL;
00067
00068 if ( t == NULL || t->size <= 0 || t->hash_func == NULL || key == NULL )
00069 return NULL;
00070
00071 index = t->hash_func(key) % t->size;
00072
00073 for ( h = t->item[index]; h != NULL; h = h->next ) {
00074 if ( strcmp(key, h->key) == 0 ) {
00075
00076 if ( last )
00077 last->next = h->next;
00078 else
00079 t->item[index] = h->next;
00080 free(h->key);
00081 data = h->data;
00082 free(h);
00083 h = NULL;
00084 return data;
00085 }
00086 last = h;
00087 }
00088
00089 return NULL;
00090 }
00091
00092
00093
00094 int hash_free ( HashTable *t, void (*free_func)(void *) ) {
00095 int i;
00096 hashItem *h, *next = NULL;
00097
00098 if ( t == NULL || t->size <= 0 || t->hash_func == NULL )
00099 return -1;
00100
00101 for ( i = 0; i < t->size; i++ ) {
00102 for ( h = t->item[i]; h != NULL; h = next ) {
00103 next = h->next;
00104 if ( h->key )
00105 free(h->key);
00106 if ( free_func )
00107 free_func(h->data);
00108 free(h);
00109 }
00110 }
00111 free(t->item);
00112
00113 t->size = 0;
00114 return 0;
00115 }
00116
00117
00118
00119
00120
00121 int hash_init ( HashTable *t, int size, int (* hash_func)(char *) ) {
00122 if ( size <= 0 )
00123 return -1;
00124
00125 if ( t == NULL ) {
00126 t = (HashTable *)malloc(sizeof(HashTable));
00127 if ( t == NULL )
00128 return -1;
00129 }
00130
00131 t->size = size;
00132 t->item = (hashItem **)malloc(sizeof(hashItem *)*size);
00133 if ( t->item == NULL ) {
00134 t->size = 0;
00135 return -1;
00136 }
00137 for ( --size; size >= 0; size-- )
00138 t->item[size] = NULL;
00139
00140 if ( hash_func )
00141 t->hash_func = hash_func;
00142 else
00143 t->hash_func = hash;
00144
00145 return 0;
00146 }
00147
00148
00149
00150 int hash_insert ( HashTable *t, char *key, void *data ) {
00151 unsigned int index;
00152 hashItem *h, *hh;
00153
00154 if ( t == NULL || t->size <= 0 || t->hash_func == NULL || key == NULL )
00155 return -1;
00156
00157 index = t->hash_func(key) % t->size;
00158
00159
00160 if ( t->item[index] == NULL ) {
00161 t->item[index] = (hashItem *)malloc(sizeof(hashItem));
00162 if ( t->item[index] == NULL )
00163 return -1;
00164
00165 t->item[index]->key = strdup(key);
00166 if ( !t->item[index]->key )
00167 return -1;
00168 t->item[index]->data = data;
00169 t->item[index]->next = NULL;
00170
00171 return index;
00172 }
00173
00174
00175 for ( h = t->item[index]; h != NULL; h = h->next ) {
00176 if ( strcmp(key, h->key) == 0 )
00177 return -2;
00178 hh = h;
00179 }
00180
00181 hh->next = (hashItem *)malloc(sizeof(hashItem));
00182 if ( hh->next == NULL )
00183 return -1;
00184
00185 hh->next->key = strdup(key);
00186 if ( !hh->next->key ) {
00187 return -1;
00188 }
00189 hh->next->data = data;
00190 hh->next->next = NULL;
00191
00192 return index;
00193 }
00194
00195
00196
00197 char *hash_key ( HashTable *t, void *data ) {
00198 int i;
00199 hashItem *h;
00200
00201 for ( i = 0; i < t->size; i++ ) {
00202 h = t->item[i];
00203 while ( h ) {
00204 if ( h->data == data )
00205 return h->key;
00206 h = h->next;
00207 }
00208 }
00209 return NULL;
00210 }