3 * Hash table implemenation
9 #define Bucket JOIN(HASHTYPE,Buket)
10 #define Bucket_s JOIN(HASHTYPE,Buket_s)
12 typedef struct Bucket_s * Bucket;
17 HTKEYTYPE key; /*!< hash key */
18 HTDATATYPE * data; /*!< pointer to hashed data */
19 int dataCount; /*!< length of data (0 if unknown) */
20 Bucket next; /*!< pointer to next item in bucket */
26 int numBuckets; /*!< number of hash buckets */
27 Bucket * buckets; /*!< hash bucket array */
28 hashFunctionType fn; /*!< generate hash value for key */
29 hashEqualityType eq; /*!< compare hash keys for equality */
31 hashFreeData freeData;
35 * Find entry in hash table.
36 * @param ht pointer to hash table
37 * @param key pointer to key value
38 * @return pointer to hash bucket of key (or NULL)
41 Bucket HASHPREFIX(findEntry)(HASHTYPE ht, HTKEYTYPE key)
46 hash = ht->fn(key) % ht->numBuckets;
47 b = ht->buckets[hash];
49 while (b && b->key && ht->eq(b->key, key))
55 HASHTYPE HASHPREFIX(Create)(int numBuckets,
56 hashFunctionType fn, hashEqualityType eq,
57 hashFreeKey freeKey, hashFreeData freeData)
61 ht = xmalloc(sizeof(*ht));
62 ht->numBuckets = numBuckets;
63 ht->buckets = xcalloc(numBuckets, sizeof(*ht->buckets));
64 ht->freeKey = freeKey;
65 ht->freeData = freeData;
71 void HASHPREFIX(AddEntry)(HASHTYPE ht, HTKEYTYPE key, HTDATATYPE data)
76 hash = ht->fn(key) % ht->numBuckets;
77 b = ht->buckets[hash];
79 while (b && b->key && ht->eq(b->key, key))
83 b = xmalloc(sizeof(*b));
86 b->next = ht->buckets[hash];
88 ht->buckets[hash] = b;
91 b->data = xrealloc(b->data, sizeof(*b->data) * (b->dataCount + 1));
92 b->data[b->dataCount++] = data;
95 HASHTYPE HASHPREFIX(Free)(HASHTYPE ht)
100 for (i = 0; i < ht->numBuckets; i++) {
104 ht->buckets[i] = NULL;
106 b->key = ht->freeKey(b->key);
112 for (j=0; j < b->dataCount; j++ ) {
113 b->data[j] = ht->freeData(b->data[j]);
116 b->data = _free(b->data);
119 } while ((b = n) != NULL);
122 ht->buckets = _free(ht->buckets);
128 int HASHPREFIX(HasEntry)(HASHTYPE ht, HTKEYTYPE key)
132 if (!(b = HASHPREFIX(findEntry)(ht, key))) return 0; else return 1;
135 int HASHPREFIX(GetEntry)(HASHTYPE ht, HTKEYTYPE key, HTDATATYPE** data,
136 int * dataCount, HTKEYTYPE* tableKey)
140 if ((b = HASHPREFIX(findEntry)(ht, key)) == NULL)
146 *dataCount = b->dataCount;
153 void HASHPREFIX(PrintStats)(HASHTYPE ht) {
157 int hashcnt=0, bucketcnt=0, datacnt=0;
160 for (i=0; i<ht->numBuckets; i++) {
162 for (bucket=ht->buckets[i]; bucket; bucket=bucket->next){
164 datacnt += bucket->dataCount;
166 if (maxbuckets < buckets) maxbuckets = buckets;
167 if (buckets) hashcnt++;
168 bucketcnt += buckets;
170 fprintf(stderr, "Hashsize: %i\n", ht->numBuckets);
171 fprintf(stderr, "Hashbuckets: %i\n", hashcnt);
172 fprintf(stderr, "Keys: %i\n", bucketcnt);
173 fprintf(stderr, "Values: %i\n", datacnt);
174 fprintf(stderr, "Max Keys/Bucket: %i\n", maxbuckets);