/* * hash.c * A hashed lookup mechanism */ #include #include /* #include */ #include #include "hash.h" static unsigned int hashidstr(register const char* key, unsigned int size) { register unsigned int h; for (h = 0; *key; key++) { h = ( (64 * h) + *key) % size; } return h; } struct hash * hash_alloc(int hashsize) { struct hash *h; if (hashsize <= 0) { return NULL; } h = (struct hash *)malloc(sizeof(struct hash) + hashsize*sizeof(struct hash *)); if (h) { h->h_hashsize = hashsize; memset(&h->h_hash, 0, hashsize*sizeof(struct hash *)); } return(h); } int hash_insert_str(struct hash *h, const char *key, void *val) { struct hash_node *hn; unsigned int idx; if (!h) { return(1); } idx = hashidstr(key, h->h_hashsize); hn = (struct hash_node *)malloc(sizeof(struct hash_node)); if (!hn) { return(1); } hn->h_key = (long)key; hn->h_data = val; hn->h_next = h->h_hash[idx]; h->h_hash[idx] = hn; return(0); } int hash_delete_str(struct hash *h, const char *key) { struct hash_node **hnp, *hn; unsigned int idx; if (!h) { return(1); } idx = hashidstr(key, h->h_hashsize); hnp = &h->h_hash[idx]; hn = *hnp; while (hn) { if (strcmp((char *)hn->h_key, key) == 0 ) { *hnp = hn->h_next; free(hn); return(0); } hnp = &hn->h_next; hn = *hnp; } return(1); } void hash_dealloc(struct hash *h) { unsigned int x; struct hash_node *hn, *hnn; for (x = 0; x < h->h_hashsize; ++x) { for (hn = h->h_hash[x]; hn; hn = hnn) { hnn = hn->h_next; free(hn); } } free(h); } void * hash_lookup_str(struct hash *h, const char *key) { struct hash_node *hn; unsigned int idx; if (!h) { return(0); } idx = hashidstr(key, h->h_hashsize); for (hn = h->h_hash[idx]; hn; hn = hn->h_next) { if (strcmp((char *)hn->h_key, key) == 0) { return(hn->h_data); } } return(0); } void * hash_lookup_str2(struct hash *h, const char *key, unsigned int *found, struct hash_node **hn2) { struct hash_node *hn; unsigned int idx; if (!h) { return(0); } idx = hashidstr(key, h->h_hashsize); if (*hn2) { hn = *hn2; } else { if (*found) { return 0; } hn = h->h_hash[idx]; } for (; hn; hn = hn->h_next) { if (strcmp((char *)hn->h_key, key) == 0) { *hn2 = hn->h_next; (*found)++; return (hn->h_data); } } return(0); }