1 | /* BDD hash table routines */ |
---|
2 | |
---|
3 | |
---|
4 | #include "bddint.h" |
---|
5 | |
---|
6 | |
---|
7 | #define HASH(d) ((INT_PTR)(d)) |
---|
8 | |
---|
9 | |
---|
10 | /* bdd_rehash_hash_table(h) increases the size of h by roughly a */ |
---|
11 | /* factor of 2 and rehashes all of its entries. */ |
---|
12 | |
---|
13 | static |
---|
14 | void |
---|
15 | bdd_rehash_hash_table(hash_table h) |
---|
16 | { |
---|
17 | long i; |
---|
18 | long hash; |
---|
19 | long oldsize; |
---|
20 | hash_rec *newtable; |
---|
21 | hash_rec p, q; |
---|
22 | |
---|
23 | oldsize=h->size; |
---|
24 | h->size_index++; |
---|
25 | h->size=TABLE_SIZE(h->size_index); |
---|
26 | newtable=(hash_rec *)mem_get_block((SIZE_T)(h->size*sizeof(hash_rec))); |
---|
27 | for (i=0; i < h->size; ++i) |
---|
28 | newtable[i]=0; |
---|
29 | for (i=0; i < oldsize; ++i) |
---|
30 | for (p=h->table[i]; p; p=q) |
---|
31 | { |
---|
32 | q=p->next; |
---|
33 | hash=HASH(p->key); |
---|
34 | BDD_REDUCE(hash, h->size); |
---|
35 | p->next=newtable[hash]; |
---|
36 | newtable[hash]=p; |
---|
37 | } |
---|
38 | mem_free_block((pointer)h->table); |
---|
39 | h->table=newtable; |
---|
40 | } |
---|
41 | |
---|
42 | |
---|
43 | /* bdd_insert_in_hash_table(h, f, data) associates the specified data */ |
---|
44 | /* with f in h. */ |
---|
45 | |
---|
46 | void |
---|
47 | bdd_insert_in_hash_table(hash_table h, bdd f, pointer data) |
---|
48 | { |
---|
49 | long hash; |
---|
50 | hash_rec p; |
---|
51 | |
---|
52 | p=(hash_rec)BDD_NEW_REC(h->bddm, ALIGN(sizeof(struct hash_rec_))+h->item_size); |
---|
53 | p->key=f; |
---|
54 | mem_copy((pointer)(ALIGN(sizeof(struct hash_rec_))+(INT_PTR)p), data, (SIZE_T)h->item_size); |
---|
55 | hash=HASH(f); |
---|
56 | BDD_REDUCE(hash, h->size); |
---|
57 | p->next=h->table[hash]; |
---|
58 | h->table[hash]=p; |
---|
59 | h->entries++; |
---|
60 | if ((h->size << 2) < h->entries) |
---|
61 | bdd_rehash_hash_table(h); |
---|
62 | } |
---|
63 | |
---|
64 | |
---|
65 | /* bdd_lookup_in_hash_table(h, f) looks up f in h and returns either a */ |
---|
66 | /* pointer to the associated data or null. */ |
---|
67 | |
---|
68 | pointer |
---|
69 | bdd_lookup_in_hash_table(hash_table h, bdd f) |
---|
70 | { |
---|
71 | long hash; |
---|
72 | hash_rec p; |
---|
73 | |
---|
74 | hash=HASH(f); |
---|
75 | BDD_REDUCE(hash, h->size); |
---|
76 | for (p=h->table[hash]; p; p=p->next) |
---|
77 | if (p->key == f) |
---|
78 | return ((pointer)(ALIGN(sizeof(struct hash_rec_))+(char *)p)); |
---|
79 | return ((pointer)0); |
---|
80 | } |
---|
81 | |
---|
82 | |
---|
83 | /* bdd_new_hash_table(bddm, item_size) creates a new hash table with */ |
---|
84 | /* the specified data item size. */ |
---|
85 | |
---|
86 | hash_table |
---|
87 | bdd_new_hash_table(cmu_bdd_manager bddm, int item_size) |
---|
88 | { |
---|
89 | long i; |
---|
90 | hash_table h; |
---|
91 | |
---|
92 | h=(hash_table)BDD_NEW_REC(bddm, sizeof(struct hash_table_)); |
---|
93 | h->size_index=10; |
---|
94 | h->size=TABLE_SIZE(h->size_index); |
---|
95 | h->table=(hash_rec *)mem_get_block((SIZE_T)(h->size*sizeof(hash_rec))); |
---|
96 | for (i=0; i < h->size; ++i) |
---|
97 | h->table[i]=0; |
---|
98 | h->entries=0; |
---|
99 | h->item_size=item_size; |
---|
100 | h->bddm=bddm; |
---|
101 | return (h); |
---|
102 | } |
---|
103 | |
---|
104 | |
---|
105 | /* cmu_bdd_free_hash_table(h) frees up the storage associated with h. */ |
---|
106 | |
---|
107 | void |
---|
108 | cmu_bdd_free_hash_table(hash_table h) |
---|
109 | { |
---|
110 | long i; |
---|
111 | hash_rec p, q; |
---|
112 | |
---|
113 | for (i=0; i < h->size; ++i) |
---|
114 | for (p=h->table[i]; p; p=q) |
---|
115 | { |
---|
116 | q=p->next; |
---|
117 | BDD_FREE_REC(h->bddm, (pointer)p, ALIGN(sizeof(struct hash_rec_))+h->item_size); |
---|
118 | } |
---|
119 | mem_free_block((pointer)h->table); |
---|
120 | BDD_FREE_REC(h->bddm, (pointer)h, sizeof(struct hash_table_)); |
---|
121 | } |
---|