1 /****************************************************************************/
3 /* Chaine de CAO & VLSI AVERTEC */
5 /* Produit : STM Version 1.00 */
6 /* Fichier : stm_ht.c */
8 /* (c) copyright 2000 AVERTEC */
9 /* Tous droits reserves */
11 /* Auteur(s) : Gilles Augustins */
13 /****************************************************************************/
15 /****************************************************************************/
17 /****************************************************************************/
21 /****************************************************************************/
23 /****************************************************************************/
25 /* Random hash function due to Don. E. Knuth, The Stanford Graph Base.
26 * Truly better than the previous one from my own experimentations. */
27 #define STM_HASH_MULT 314159
28 #define STM_HASH_PRIME 516595003
29 /* namealloc hash table size: the 1230th prime */
30 #define STM_HASH_VAL 100007
32 static int HASH_FUNC (char *inputname
)
39 code
+= (code
^ (code
>> 1)) + STM_HASH_MULT
* c
;
40 while (code
>= STM_HASH_PRIME
)
41 code
-= STM_HASH_PRIME
;
48 /****************************************************************************/
49 /* function addht, create a hash table */
50 /****************************************************************************/
52 stm_ht
*stm_addht (unsigned long len
)
59 avt_errmsg (STM_ERRMSG
,"008", AVT_ERROR
);
63 pTable
= (stm_ht
*)mbkalloc (sizeof (struct stm_htable
));
65 pEl
= (stm_htitem
*)mbkalloc (len
* (sizeof (struct stm_htitem
)));
67 for (i
= 0; i
< len
; i
++) {
69 pEl
[i
].value
= STM_EMPTYHT
;
75 /****************************************************************************/
76 /* function delht, delete a hash table */
77 /****************************************************************************/
79 void stm_delht (stm_ht
*pTable
)
88 /****************************************************************************/
89 /* function gethtitem, get an element in a hash table */
90 /****************************************************************************/
92 long stm_gethtitem (stm_ht
*pTable
, char *key
)
98 indice
= HASH_FUNC (key
) % pTable
->length
;
100 if (co
++ > STM_HMAX_CALLS
) {
101 if ((pTable
->count
> (pTable
->length
) * 2 / 10) || (co
>= pTable
->length
)) {
102 stm_reallocht (pTable
);
103 return stm_gethtitem (pTable
, key
);
107 pEl
= (pTable
->pElem
) + indice
;
108 if (pEl
->value
!= STM_EMPTYHT
&& pEl
->value
!= STM_DELETEHT
) {
109 if (!strcmp (key
, pEl
->key
))
111 } else if (pEl
->value
== STM_EMPTYHT
)
113 indice
= (indice
+ 1) % pTable
->length
;
117 /****************************************************************************/
118 /* function addhtitem, get an element in a hash table */
119 /****************************************************************************/
121 long stm_addhtitem (stm_ht
*pTable
, char *key
, long value
)
127 if (value
== STM_EMPTYHT
|| value
== STM_DELETEHT
) {
128 avt_errmsg (STM_ERRMSG
,"009", AVT_ERROR
);
132 if (pTable
->count
++ > (pTable
->length
) * 8 / 10) {
133 stm_reallocht (pTable
);
134 return stm_addhtitem (pTable
, key
, value
);
137 indice
= HASH_FUNC (key
) % pTable
->length
;
139 if (co
++ > STM_HMAX_CALLS
) {
140 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
141 stm_reallocht (pTable
);
142 return stm_addhtitem (pTable
, key
, value
);
145 pEl
= (pTable
->pElem
) + indice
;
146 if (pEl
->value
== STM_EMPTYHT
|| pEl
->value
== STM_DELETEHT
) {
148 pEl
->key
= strdup (key
);
150 } else if (!strcmp (pEl
->key
, key
)) {
155 indice
= (indice
+ 1) % pTable
->length
;
159 /****************************************************************************/
160 /* function delhtitem, delete an element in a hash table */
161 /****************************************************************************/
163 long stm_delhtitem (stm_ht
*pTable
, char *key
)
169 indice
= HASH_FUNC (key
) % pTable
->length
;
171 if (co
++ > STM_HMAX_CALLS
) {
172 if (pTable
->count
> (pTable
->length
) * 2 / 10 || (co
>= pTable
->length
)) {
173 stm_reallocht (pTable
);
174 return stm_delhtitem (pTable
, key
);
178 pEl
= (pTable
->pElem
) + indice
;
179 if (pEl
->value
!= STM_EMPTYHT
&& pEl
->value
!= STM_DELETEHT
) {
180 if (!strcmp (key
, pEl
->key
)) {
182 pEl
->value
= STM_DELETEHT
;
186 } else if (pEl
->value
== STM_EMPTYHT
)
188 indice
= (indice
+ 1) % pTable
->length
;
192 /****************************************************************************/
193 /* realloc space to adapt hash table size to number of entries */
194 /****************************************************************************/
196 void stm_reallocht (stm_ht
*pTable
)
205 ratio
= (double)pTable
->count
/ (double)pTable
->length
;
206 if (ratio
> 0.8) ratio
= 1;
207 else if (ratio
< 0.3) ratio
= 0.3;
209 tabBis
= stm_addht ((unsigned long)((double)(pTable
->length
) * 5.0 * ratio
));
210 for (i
= 0; i
< pTable
->length
; i
++) {
211 if (pEl
->value
!= STM_EMPTYHT
&& pEl
->value
!= STM_DELETEHT
)
212 stm_addhtitem (tabBis
, pEl
->key
, pEl
->value
);
215 mbkfree (pTable
->pElem
);
216 pTable
->length
= tabBis
->length
;
217 pTable
->pElem
= tabBis
->pElem
;
218 pTable
->count
= tabBis
->count
;