00001
00040 #include "calInt.h"
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 #ifdef USE_POWER_OF_2
00065 #define CalDoHash3(fBddNode, gBddNode, hBddNode,table) \
00066 ((((CalAddress_t)fBddNode + \
00067 (CalAddress_t)gBddNode + \
00068 (CalAddress_t) hBddNode) \
00069 / NODE_SIZE) & ((table)->numBins-1))
00070 #else
00071 #define CalDoHash3(fBddNode, gBddNode, hBddNode,table) \
00072 ((((CalAddress_t)fBddNode + \
00073 (CalAddress_t)gBddNode + \
00074 (CalAddress_t) hBddNode) \
00075 / NODE_SIZE)% table->numBins)
00076 #endif
00077
00079
00080
00081
00082
00083 static void CalHashTableThreeRehash(CalHashTable_t *hashTable, int grow);
00084
00088
00089
00090
00091
00092
00093
00094
00095
00107 int
00108 CalHashTableThreeFindOrAdd(CalHashTable_t * hashTable,
00109 Cal_Bdd_t f,
00110 Cal_Bdd_t g,
00111 Cal_Bdd_t h,
00112 Cal_Bdd_t * bddPtr)
00113 {
00114 CalBddNode_t *ptr, *ptrIndirect;
00115 Cal_Bdd_t tmpBdd;
00116 int hashValue;
00117
00118 hashValue = CalDoHash3(CalBddGetBddNode(f),
00119 CalBddGetBddNode(g), CalBddGetBddNode(h), hashTable);
00120 ptr = hashTable->bins[hashValue];
00121 while(ptr != Cal_Nil(CalBddNode_t)){
00122 CalBddNodeGetThenBdd(ptr, tmpBdd);
00123 if(CalBddIsEqual(f, tmpBdd)){
00124 ptrIndirect = CalBddNodeGetElseBddNode(ptr);
00125 CalBddNodeGetThenBdd(ptrIndirect, tmpBdd);
00126 if(CalBddIsEqual(g, tmpBdd)){
00127 CalBddNodeGetElseBdd(ptrIndirect, tmpBdd);
00128 if(CalBddIsEqual(h, tmpBdd)){
00129 CalBddPutBddId(*bddPtr, hashTable->bddId);
00130 CalBddPutBddNode(*bddPtr, ptr);
00131 return 1;
00132 }
00133 }
00134 }
00135 ptr = CalBddNodeGetNextBddNode(ptr);
00136 }
00137 hashTable->numEntries++;
00138 if(hashTable->numEntries > hashTable->maxCapacity){
00139 CalHashTableThreeRehash(hashTable,1);
00140 hashValue = CalDoHash3(CalBddGetBddNode(f),
00141 CalBddGetBddNode(g), CalBddGetBddNode(h), hashTable);
00142 }
00143 CalNodeManagerAllocNode(hashTable->nodeManager, ptr);
00144 CalNodeManagerAllocNode(hashTable->nodeManager, ptrIndirect);
00145 CalBddNodePutThenBdd(ptr, f);
00146 CalBddNodePutThenBdd(ptrIndirect, g);
00147 CalBddNodePutElseBdd(ptrIndirect, h);
00148 CalBddNodePutElseBddNode(ptr, ptrIndirect);
00149 CalBddNodePutNextBddNode(ptr, hashTable->bins[hashValue]);
00150 hashTable->bins[hashValue] = ptr;
00151 CalBddPutBddId(*bddPtr, hashTable->bddId);
00152 CalBddPutBddNode(*bddPtr, ptr);
00153 return 0;
00154 }
00155
00156
00157
00158
00170 static void
00171 CalHashTableThreeRehash(CalHashTable_t *hashTable, int grow)
00172 {
00173 CalBddNode_t *ptr, *ptrIndirect, *next;
00174 CalBddNode_t **oldBins = hashTable->bins;
00175 int i, hashValue;
00176 int oldNumBins = hashTable->numBins;
00177
00178 if(grow){
00179 hashTable->sizeIndex++;
00180 }
00181 else{
00182 if (hashTable->sizeIndex <= HASH_TABLE_DEFAULT_SIZE_INDEX){
00183 return;
00184 }
00185 hashTable->sizeIndex--;
00186 }
00187
00188 hashTable->numBins = TABLE_SIZE(hashTable->sizeIndex);
00189 hashTable->numBins = hashTable->numBins;
00190 hashTable->maxCapacity = hashTable->numBins * HASH_TABLE_DEFAULT_MAX_DENSITY;
00191 hashTable->bins = Cal_MemAlloc(CalBddNode_t *, hashTable->numBins);
00192 if(hashTable->bins == Cal_Nil(CalBddNode_t *)){
00193 CalBddFatalMessage("out of memory");
00194 }
00195 for(i = 0; i < hashTable->numBins; i++){
00196 hashTable->bins[i] = Cal_Nil(CalBddNode_t);
00197 }
00198
00199 for(i = 0; i < oldNumBins; i++){
00200 ptr = oldBins[i];
00201 while(ptr != Cal_Nil(CalBddNode_t)){
00202 next = CalBddNodeGetNextBddNode(ptr);
00203 ptrIndirect = CalBddNodeGetElseBddNode(ptr);
00204 hashValue = CalDoHash3(CalBddNodeGetThenBddNode(ptr),
00205 CalBddNodeGetThenBddNode(ptrIndirect),
00206 CalBddNodeGetElseBddNode(ptrIndirect), hashTable);
00207 CalBddNodePutNextBddNode(ptr, hashTable->bins[hashValue]);
00208 hashTable->bins[hashValue] = ptr;
00209 ptr = next;
00210 }
00211 }
00212 Cal_MemFree(oldBins);
00213 }
00214
00215
00216
00217
00218
00219
00220
00221