/ * * Header file * Description: This implementation does not save objects, only save objects * / # ifndef _hash_h # define _hash_h # ifdef __cplusplusextern "c" {#ENDIF
Typedef struct taghashbucket hashbucket, * lphashbucket; typedef struct taghashtable hashtable, * lphashtable
struct tagHASHBUCKET {unsigned long h; unsigned int key_length; void * data; LPHASHBUCKET next; LPHASHBUCKET previous; LPHASHBUCKET conflict_next; LPHASHBUCKET conflict_previous; char key [1];};
Typedef unsigned long (* hash_func_t) (char *, unsigned int);
struct tagHASHTABLE {unsigned int table_size; unsigned int size_index; unsigned int elements; hash_func_t hash; LPHASHBUCKET p; LPHASHBUCKET head; LPHASHBUCKET tail; LPHASHBUCKET * buckets;};
extern int hash_create (LPHASHTABLE, unsigned int, hash_func_t); extern int hash_entry (LPHASHTABLE, char *, unsigned int, void *); extern int hash_find (LPHASHTABLE, char *, unsigned int, void **); extern int hash_update (LPHASHTABLE , char *, unsigned int, void *); extern int hash_remove (LPHASHTABLE, char *, unsigned int); extern int hash_destroy (LPHASHTABLE); # ifdef __cplusplus}; # endif # endif / * * HASH implemented * / # include < STDLIB.H> #include
Static unsigned int size_table [] = {5, 11, 19, 53, 107, 223, 463, 983, 1979, 3,2531, 654,09,87, 2,62237, 5,24521, 1048793, 5,245,1, 10,487,03, 20,973,87, 4,194103, 8388857, 16777447, 335554201, 67108961, 134217487, 268435697, 536870683, 1073741621, 2147483399}; # define counts_of_size_table (sizeof (size) / sizeof (size_table [0]))
Static unsigned longhashpjw (char * key, unsigned int key_length) {UNSIGNED Long H, g; char * p;
H = 0; p = key key_length; while (key
> 24); h = h ^ g;}} Return H;
Static inthash_do_rehash (lphashtable pHT) {lphashbucket p; unsigned int index;
MEMSET (PHT-> BUCKETS, 0, SIZEOF (LPHASHBUCKET) * SIZE_TABLE [PHT-> SIZE_INDEX]); for (p = pht-> head; p; p = p-> next) {index = p-> h% pht -> Table_size; p-> conflict_next = 0; p-> conflict_previous = pht-> buckets [index]; if (p-> conflict_previous) {p-> conflict_previous-> conflict_next = p;} pht-> buckets [index] = P;}
Return 0;}
Static inthash_do_resize (lphashtable pht) {lphashbucket * pp;
IF (PHT-> SIZE_INDEX <(unsigned int) counts_of_size_table - 1) {pp = (lphashbucket *) Realloc (pht-> buckets, size_table [pht-> size_index 1] * sizeof (lphashbucket)); if (pp) { PHT-> buckets = PP; pht-> size_index ; pht-> table_size = size_table [pht-> size_index]; haveh_do_rehash (pHT); return 0;} return -1;}
Return 0;}
INTHASH_CREATE (LPHASHTABLE PHT, UNSIGNED INT SIZE, HASH_FUNC_T HASH) {INT I;
For (i = 0; i
Return 0;}
INTHASH_ENTRY (LPHASHTABLE PHT, CHAR * Key, Unsigned Int Key_LENGTH, VOID * DATA) {Unsigned Long H; UNSIGNED INDEX; LPHASHBUCKET P;
H = pht-> hash (key, key_length); index = h% pht-> table_size;
For (p = pht-> buckets [index]; p; p = p-> conflict_previous) {if (p-> h == h && p-> key_length == key_length) {if (! Memcmp (P-> Key , Key, Key_Length) {RETURN -1;}}}
P = (LPHASHBUCKET) Malloc (Sizeof (Hashbucket) - 1 Key_Length); if (! p) {return -1;} Memcpy (P-> Key, Key, Key_Length); P-> Key_Length = Key_Length; P-> H = h; p-> Data = data;
P-> conflict_next = 0; P-> conflict_previous = pht-> buckets [index]; if (p-> conflict_previous) {p-> confiosct_previous-> confiict_next = p;} P-> previous = pht-> tail; P -> Next = 0; pht-> tail = p; if (p-> previous) {p-> previous-> next = p;} if (! pHt-> head) {pht-> head = p;} pht -> buckets [index] = p; pht-> Elements; if (pht-> elements> pht-> table_size) {hash_do_resize (pht);}
Return 0;}
INTHASH_FIND (LPHASHTABLE PHT, Char * Key, Unsigned Int Key_LENGTH, VOID ** DATA) {Unsigned Long H; UNSIGNED INDEX; LPHASHBUCKET P;
H = pht-> hash (key, key_length); index = h% pht-> table_size;
For (p = pht-> buckets [index]; p; p = p-> confict_previous) {if (p-> h == h && p-> key_length == key_length &&! memcmp (p-> key, key, Key_Length)) {* data = p-> data; return 0;}}
Return -1;
INTHASH_REMOVE (LPHASHTABLE PHT, CHAR * Key, unsigned int key_length) {Unsigned long h; unsigned int index; lphashbucket p;
H = pht-> hash (key, key_length); index = h% pht-> table_size;
For (p = pht-> buckets [index]; p; p = p-> confict_previous) {if (p-> h == h && p-> key_length == key_length &&! memcmp (p-> key, key, key_length)) {if (p-> conflict_previous) {p-> conflict_previous-> conflict_next = p-> conflict_next;} if (p-> conflict_next) {p-> conflict_next-> conflict_previous = p-> conflict_previous;} if ( P-> previous) {p-> prepious-> next = p-> next;} if (p-> next) {p-> next-> previous = p-> previous;} if (pht-> buckets [index ] == p) {pht-> BUCKETS [INDEX] = P-> conflict_previous;} if (pht-> head == p) {pht-> head = p-> next;} if (pht-> tail == p) {pht-> tail = p-> previous;} --pht-> elements; free (p); return 0; }
Return -1;
INTHASH_UPDATE (LPHASHTABLE PHT, CHAR * Key, Unsigned Int Key_LENGTH, VOID * DATA) {UNSIGNED Long H; unsigned int index; lphashbucket p;
H = pht-> hash (key, key_length); index = h% pht-> table_size;
For (p = pht-> buckets [index]; p; p = p-> confict_previous) {if (p-> h == h && p-> key_length == key_length &&! memcmp (p-> key, key, Key_Length)) {P-> Data = DATA; RETURN 0;}}
Return -1;} inthash_destroy (lphashbucket p, q; p = pht-> head; while (p) {q = p; p = p-> next; free (q);} free (pht-> Buckets;
Return 0;}