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 #ifdef USE_POWER_OF_2
00062 #  define HashTableOneDoHash(hashTable, keyBdd) \
00063      (((CalAddress_t)(CalBddGetBddNode(keyBdd)) / NODE_SIZE) & ((hashTable)->numBins - 1))
00064 #else
00065 #  define HashTableOneDoHash(hashTable, keyBdd) \
00066      (((CalAddress_t)(CalBddGetBddNode(keyBdd)) / NODE_SIZE) % hashTable->numBins)
00067 #endif
00068 
00071 
00072 
00073 
00074 
00075 static void HashTableOneRehash(CalHashTable_t * hashTable, int grow);
00076 
00079 
00080 
00081 
00082 
00083 
00084 
00085 
00097 CalHashTable_t *
00098 CalHashTableOneInit(Cal_BddManager_t * bddManager, int  itemSize)
00099 {
00100   int i;
00101   CalHashTable_t *hashTable;
00102 
00103   hashTable = Cal_MemAlloc(CalHashTable_t, 1);
00104   if(hashTable == Cal_Nil(CalHashTable_t)){
00105     CalBddFatalMessage("out of memory");
00106   }
00107   hashTable->sizeIndex = HASH_TABLE_DEFAULT_SIZE_INDEX;
00108   hashTable->numBins = TABLE_SIZE(hashTable->sizeIndex);
00109   hashTable->maxCapacity = hashTable->numBins*HASH_TABLE_DEFAULT_MAX_DENSITY;
00110   hashTable->bins = Cal_MemAlloc(CalBddNode_t *, hashTable->numBins);
00111   if(hashTable->bins == Cal_Nil(CalBddNode_t *)){
00112     CalBddFatalMessage("out of memory");
00113   }
00114   for(i = 0; i < hashTable->numBins; i++){
00115     hashTable->bins[i] = Cal_Nil(CalBddNode_t);
00116   }
00117   hashTable->numEntries = 0;
00118   hashTable->bddId = (Cal_BddId_t)itemSize;
00119   if(itemSize > NODE_SIZE){
00120     CalBddFatalMessage("CalHashTableOneInit: itemSize exceeds NODE_SIZE");
00121   }
00122   hashTable->nodeManager = bddManager->nodeManagerArray[0];
00123   hashTable->requestNodeList = Cal_Nil(CalRequestNode_t);
00124   return hashTable;
00125 }
00126 
00127 
00139 void
00140 CalHashTableOneQuit(
00141   CalHashTable_t * hashTable)
00142 {
00143   CalBddNode_t *ptr, *next, *node;
00144   int i;
00145   if(hashTable == Cal_Nil(CalHashTable_t))return;
00146   for(i = 0; i < hashTable->numBins; i++){
00147     ptr = hashTable->bins[i];
00148     while(ptr != Cal_Nil(CalBddNode_t)){
00149       next = CalBddNodeGetNextBddNode(ptr);
00150       node = CalBddNodeGetElseBddNode(ptr);
00151       CalNodeManagerFreeNode(hashTable->nodeManager, node);
00152       CalNodeManagerFreeNode(hashTable->nodeManager, ptr);
00153       ptr = next;
00154     }
00155   }
00156   Cal_MemFree(hashTable->bins);
00157   Cal_MemFree(hashTable);
00158 }
00159 
00160 
00172 void
00173 CalHashTableOneInsert(CalHashTable_t * hashTable, Cal_Bdd_t  keyBdd,
00174                       char * valuePtr)
00175 {
00176   int hashValue;
00177   CalBddNode_t *bddNode, *dataPtr;
00178 
00179   hashValue = HashTableOneDoHash(hashTable, keyBdd);
00180   hashTable->numEntries++;
00181   if(hashTable->numEntries >= hashTable->maxCapacity){
00182     HashTableOneRehash(hashTable, 1);
00183     hashValue = HashTableOneDoHash(hashTable, keyBdd);
00184   }
00185   CalNodeManagerAllocNode(hashTable->nodeManager, dataPtr);
00186   memcpy(dataPtr, valuePtr, (size_t)hashTable->bddId);
00187   CalNodeManagerAllocNode(hashTable->nodeManager, bddNode);
00188   CalBddNodePutThenBdd(bddNode, keyBdd);
00189   CalBddNodePutElseBddNode(bddNode, dataPtr);
00190   CalBddNodePutNextBddNode(bddNode, hashTable->bins[hashValue]);
00191   hashTable->bins[hashValue] = bddNode;
00192 }
00193 
00205 int
00206 CalHashTableOneLookup(CalHashTable_t * hashTable, Cal_Bdd_t  keyBdd,
00207                       char ** valuePtrPtr)
00208 {
00209   CalBddNode_t *ptr;
00210   Cal_Bdd_t tmpBdd;
00211   int hashValue;
00212   
00213   hashValue = HashTableOneDoHash(hashTable, keyBdd);
00214   ptr = hashTable->bins[hashValue];
00215   while(ptr != Cal_Nil(CalBddNode_t)){
00216     CalBddNodeGetThenBdd(ptr, tmpBdd);
00217     if(CalBddIsEqual(keyBdd, tmpBdd)){
00218       if(valuePtrPtr){
00219         *valuePtrPtr = (char *)CalBddNodeGetElseBddNode(ptr);
00220       }
00221       return 1;
00222     }
00223     ptr = CalBddNodeGetNextBddNode(ptr);
00224   }
00225   if(valuePtrPtr){
00226     *valuePtrPtr = Cal_Nil(char);
00227   }
00228   return 0;
00229 }
00230 
00231 
00232 
00233 
00245 static void
00246 HashTableOneRehash(
00247   CalHashTable_t * hashTable,
00248   int  grow)
00249 {
00250   CalBddNode_t *ptr, *next;
00251   CalBddNode_t **oldBins = hashTable->bins;
00252   int i, hashValue;
00253   int oldNumBins = hashTable->numBins;
00254   Cal_Bdd_t keyBdd;
00255 
00256   if(grow){
00257     hashTable->sizeIndex++;
00258   }
00259   else{
00260     if (hashTable->sizeIndex <= HASH_TABLE_DEFAULT_SIZE_INDEX){
00261       return;
00262     }
00263     hashTable->sizeIndex--;
00264   }
00265 
00266   hashTable->numBins = TABLE_SIZE(hashTable->sizeIndex);
00267   hashTable->maxCapacity = hashTable->numBins * HASH_TABLE_DEFAULT_MAX_DENSITY;
00268   hashTable->bins = Cal_MemAlloc(CalBddNode_t *, hashTable->numBins);
00269   if(hashTable->bins == Cal_Nil(CalBddNode_t *)){
00270     CalBddFatalMessage("out of memory");
00271   }
00272   for(i = 0; i < hashTable->numBins; i++){
00273     hashTable->bins[i] = Cal_Nil(CalBddNode_t);
00274   }
00275 
00276   for(i = 0; i < oldNumBins; i++){
00277     ptr = oldBins[i];
00278     while(ptr != Cal_Nil(CalBddNode_t)){
00279       next = CalBddNodeGetNextBddNode(ptr);
00280       CalBddNodeGetThenBdd(ptr, keyBdd);
00281       hashValue = HashTableOneDoHash(hashTable, keyBdd);
00282       CalBddNodePutNextBddNode(ptr, hashTable->bins[hashValue]);
00283       hashTable->bins[hashValue] = ptr;
00284       ptr = next;
00285     }
00286   }
00287   Cal_MemFree(oldBins);
00288 }
00289 
00290 
00291 
00292 
00293 
00294 
00295 
00296 
00297 
00298