VIS
|
00001 00033 #include "imgInt.h" 00034 00035 static char rcsid[] UNUSED = "$Id: imgTfmCache.c,v 1.8 2005/04/23 14:30:54 jinh Exp $"; 00036 00037 /*---------------------------------------------------------------------------*/ 00038 /* Constant declarations */ 00039 /*---------------------------------------------------------------------------*/ 00040 00041 /*---------------------------------------------------------------------------*/ 00042 /* Type declarations */ 00043 /*---------------------------------------------------------------------------*/ 00044 00045 /*---------------------------------------------------------------------------*/ 00046 /* Structure declarations */ 00047 /*---------------------------------------------------------------------------*/ 00048 00049 /*---------------------------------------------------------------------------*/ 00050 /* Variable declarations */ 00051 /*---------------------------------------------------------------------------*/ 00052 00053 static int ComplementFlag; /* If set, returns the negation of the 00054 result from cache */ 00055 static array_t *SubstituteVector; /* returns the result from cache by 00056 substituting the variables */ 00057 static ImgCacheTable_t *ImgGlobalCache; /* global image cache */ 00058 static ImgCacheTable_t *PreGlobalCache; /* global preimage cache */ 00059 static int ImgGlobalCacheRef; /* the number of image-info 00060 refering to the image cache */ 00061 static int PreGlobalCacheRef; /* the number of image-info 00062 refering to the preimage cache */ 00063 00064 /*---------------------------------------------------------------------------*/ 00065 /* Macro declarations */ 00066 /*---------------------------------------------------------------------------*/ 00067 00068 00071 /*---------------------------------------------------------------------------*/ 00072 /* Static function prototypes */ 00073 /*---------------------------------------------------------------------------*/ 00074 00075 static void CacheDestroyEntry(ImgCacheEntry_t *entry, boolean freeEntry); 00076 static int VectorHash(ImgCacheTable_t *table, array_t *delta, bdd_t *constraint); 00077 static int VectorStHash(char *key, int modulus); 00078 static int KeyStHash(char *key, int modulus); 00079 static int VectorCompare(array_t *vector1, array_t *vector2); 00080 static int VectorSortCompare(array_t *vector1, array_t *vector2); 00081 static int VectorSortCompareWithConstraint(array_t *vector1, array_t *vector2); 00082 static int ImageKeyCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2); 00083 static int ImageKeySortCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2); 00084 static int PreImageKeyCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2); 00085 static mdd_t * SubstituteCacheResult(ImgTfmInfo_t *info, array_t *keyVector, array_t *cacheVector, mdd_t *result); 00086 static mdd_t * SubstituteCacheResultRecur(mdd_t *result, array_t *varArray, array_t *funcArray, int pos); 00087 00091 /*---------------------------------------------------------------------------*/ 00092 /* Definition of exported functions */ 00093 /*---------------------------------------------------------------------------*/ 00094 00095 00109 int 00110 Img_TfmGetCacheStatistics(Img_ImageInfo_t *imageInfo, int preFlag, 00111 double *inserts, double *lookups, double *hits, 00112 double *entries, int *nSlots, int *maxChainLength) 00113 { 00114 ImgTfmInfo_t *info; 00115 ImgCacheTable_t *cache; 00116 00117 if (imageInfo) { 00118 if (imageInfo->methodType != Img_Tfm_c && 00119 imageInfo->methodType != Img_Hybrid_c) { 00120 return(0); 00121 } 00122 00123 info = (ImgTfmInfo_t *)imageInfo->methodData; 00124 if (!info->option->useCache) 00125 return(0); 00126 00127 if (preFlag) 00128 cache = info->preCache; 00129 else 00130 cache = info->imgCache; 00131 if (!cache) 00132 return(0); 00133 } else { 00134 if (preFlag) 00135 cache = PreGlobalCache; 00136 else 00137 cache = ImgGlobalCache; 00138 if (!cache) 00139 return(0); 00140 } 00141 00142 *inserts = cache->inserts; 00143 *lookups = cache->lookups; 00144 *hits = cache->hits; 00145 *entries = cache->entries; 00146 if (cache->stTable) { 00147 *nSlots = 0; 00148 *maxChainLength = 0; 00149 } else { 00150 *nSlots = cache->nSlots; 00151 *maxChainLength = cache->maxChainLength; 00152 } 00153 return(1); 00154 } 00155 00156 00173 int 00174 Img_TfmCheckGlobalCache(int preFlag) 00175 { 00176 if (preFlag) { 00177 if (PreGlobalCache) 00178 return(1); 00179 else 00180 return(0); 00181 } else { 00182 if (ImgGlobalCache) 00183 return(1); 00184 else 00185 return(0); 00186 } 00187 } 00188 00189 00203 void 00204 Img_TfmPrintCacheStatistics(Img_ImageInfo_t *imageInfo, int preFlag) 00205 { 00206 ImgTfmInfo_t *info; 00207 ImgCacheTable_t *cache; 00208 00209 if (imageInfo) { 00210 if (imageInfo->methodType != Img_Tfm_c && 00211 imageInfo->methodType != Img_Hybrid_c) { 00212 return; 00213 } 00214 00215 info = (ImgTfmInfo_t *)imageInfo->methodData; 00216 if (!info->option->useCache) 00217 return; 00218 00219 if (preFlag) 00220 cache = info->preCache; 00221 else 00222 cache = info->imgCache; 00223 if (!cache) 00224 return; 00225 } else { 00226 if (preFlag) 00227 cache = PreGlobalCache; 00228 else 00229 cache = ImgGlobalCache; 00230 if (!cache) 00231 return; 00232 } 00233 ImgPrintCacheStatistics(cache); 00234 } 00235 00236 00251 void 00252 Img_TfmFlushCache(Img_ImageInfo_t *imageInfo, int preFlag) 00253 { 00254 ImgTfmInfo_t *info; 00255 00256 if (imageInfo) { 00257 if (imageInfo->methodType != Img_Tfm_c && 00258 imageInfo->methodType != Img_Hybrid_c) { 00259 return; 00260 } 00261 00262 info = (ImgTfmInfo_t *)imageInfo->methodData; 00263 00264 if (info->option->autoFlushCache == 0) { 00265 if (preFlag) 00266 ImgFlushCache(info->preCache); 00267 else 00268 ImgFlushCache(info->imgCache); 00269 } 00270 } 00271 } 00272 00273 00274 /*---------------------------------------------------------------------------*/ 00275 /* Definition of internal functions */ 00276 /*---------------------------------------------------------------------------*/ 00277 00278 00288 void 00289 ImgCacheInitTable(ImgTfmInfo_t *info, int num_slot, int globalCache, 00290 boolean preImgFlag) 00291 { 00292 ImgCacheTable_t *table; 00293 ImgTfmOption_t *option = info->option; 00294 00295 if (globalCache) { 00296 if (preImgFlag && PreGlobalCache) { 00297 info->preCache = PreGlobalCache; 00298 PreGlobalCacheRef++; 00299 return; 00300 } else if (!preImgFlag && ImgGlobalCache) { 00301 info->imgCache = ImgGlobalCache; 00302 ImgGlobalCacheRef++; 00303 return; 00304 } 00305 } 00306 00307 table = ALLOC(ImgCacheTable_t, 1); 00308 memset(table, 0, sizeof(ImgCacheTable_t)); 00309 table->nSlots = num_slot; 00310 if (option->useCache == 2) { 00311 if (preImgFlag) 00312 table->stTable = st_init_table((ST_PFICPCP)PreImageKeyCompare, 00313 KeyStHash); 00314 else if (info->useConstraint && option->sortVectorFlag) 00315 table->stTable = st_init_table((ST_PFICPCP)ImageKeySortCompare, 00316 KeyStHash); 00317 else if (info->useConstraint) 00318 table->stTable = st_init_table((ST_PFICPCP)ImageKeyCompare, 00319 KeyStHash); 00320 else if (option->sortVectorFlag) 00321 table->stTable = st_init_table((ST_PFICPCP)VectorSortCompare, 00322 VectorStHash); 00323 else 00324 table->stTable = st_init_table((ST_PFICPCP)VectorCompare, 00325 VectorStHash); 00326 } else { 00327 table->slot = ALLOC(ImgCacheEntry_t *, num_slot); 00328 memset(table->slot, 0, sizeof(ImgCacheEntry_t *) * num_slot); 00329 } 00330 table->maxChainLength = option->maxChainLength; 00331 table->preImgFlag = preImgFlag; 00332 table->useConstraint = info->useConstraint; 00333 if (preImgFlag) { 00334 table->compareFunc = VectorCompare; 00335 info->preCache = table; 00336 } else { 00337 if (option->sortVectorFlag) { 00338 if (info->useConstraint) 00339 table->compareFunc = VectorSortCompareWithConstraint; 00340 else 00341 table->compareFunc = VectorSortCompare; 00342 } else 00343 table->compareFunc = VectorCompare; 00344 info->imgCache = table; 00345 } 00346 00347 if (globalCache) { 00348 if (preImgFlag) { 00349 PreGlobalCache = table; 00350 PreGlobalCacheRef = 1; 00351 } else { 00352 ImgGlobalCache = table; 00353 ImgGlobalCacheRef = 1; 00354 } 00355 } 00356 } 00357 00358 00368 void 00369 ImgCacheDestroyTable(ImgCacheTable_t *table, int globalCache) 00370 { 00371 unsigned int i; 00372 ImgCacheEntry_t *entry, *next; 00373 array_t *vector; 00374 bdd_t *result; 00375 st_generator *stGen; 00376 ImgCacheStKey_t *key; 00377 00378 if (globalCache) { 00379 if (table->preImgFlag) { 00380 PreGlobalCacheRef--; 00381 if (PreGlobalCacheRef > 0) 00382 return; 00383 } else { 00384 ImgGlobalCacheRef--; 00385 if (ImgGlobalCacheRef > 0) 00386 return; 00387 } 00388 } 00389 00390 if (table->stTable) { 00391 if (table->preImgFlag || table->useConstraint) { 00392 st_foreach_item(table->stTable, stGen, &key, &result) { 00393 ImgVectorFree(key->vector); 00394 if (key->constraint) 00395 mdd_free(key->constraint); 00396 FREE(key); 00397 mdd_free(result); 00398 } 00399 } else { 00400 st_foreach_item(table->stTable, stGen, &vector, &result) { 00401 ImgVectorFree(vector); 00402 mdd_free(result); 00403 } 00404 } 00405 st_free_table(table->stTable); 00406 } else { 00407 for (i = 0; i < table->nSlots; i++) { 00408 entry = table->slot[i]; 00409 while (entry != NIL(ImgCacheEntry_t)) { 00410 next = entry->next; 00411 CacheDestroyEntry(entry, TRUE); 00412 entry = next; 00413 } 00414 } 00415 FREE(table->slot); 00416 } 00417 00418 if (globalCache) { 00419 if (table->preImgFlag) 00420 PreGlobalCache = NIL(ImgCacheTable_t); 00421 else 00422 ImgGlobalCache = NIL(ImgCacheTable_t); 00423 } 00424 00425 FREE(table); 00426 } 00427 00428 00438 bdd_t * 00439 ImgCacheLookupTable(ImgTfmInfo_t *info, ImgCacheTable_t *table, array_t *delta, 00440 bdd_t *constraint) 00441 { 00442 int slot; 00443 ImgCacheEntry_t *entry; 00444 bdd_t *result, *newResult; 00445 int *ptr1, *ptr2; 00446 ImgCacheStKey_t key; 00447 00448 table->lookups += 1.0; 00449 00450 /* lossless cache */ 00451 if (table->stTable) { 00452 if (table->preImgFlag) { 00453 key.vector = delta; 00454 key.constraint = constraint; 00455 if (st_lookup(table->stTable, (char *)&key, &result)) { 00456 table->hits += 1.0; 00457 if (ComplementFlag) 00458 return(mdd_not(result)); 00459 else 00460 return(mdd_dup(result)); 00461 } 00462 } else if (table->useConstraint) { 00463 key.vector = delta; 00464 key.constraint = constraint; 00465 if (st_lookup(table->stTable, (char *)&key, &result)) { 00466 table->hits += 1.0; 00467 if (SubstituteVector) { 00468 newResult = SubstituteCacheResult(info, delta, SubstituteVector, 00469 result); 00470 return(newResult); 00471 } else 00472 return(mdd_dup(result)); 00473 } 00474 } else { 00475 if (st_lookup(table->stTable, (char *)delta, &result)) { 00476 table->hits += 1.0; 00477 if (SubstituteVector) { 00478 newResult = SubstituteCacheResult(info, delta, SubstituteVector, 00479 result); 00480 return(newResult); 00481 } 00482 return(mdd_dup(result)); 00483 } 00484 } 00485 00486 return(NIL(bdd_t)); 00487 } 00488 00489 slot = VectorHash(table, delta, constraint); 00490 00491 entry = table->slot[slot]; 00492 while (entry != NIL(ImgCacheEntry_t)) { 00493 if ((*table->compareFunc)(delta, entry->vector) == 0) { 00494 table->hits++; 00495 if (table->preImgFlag) { /* preimage computation */ 00496 ptr1 = (int *)bdd_pointer(constraint); 00497 ptr2 = (int *)bdd_pointer(entry->constraint); 00498 if (((unsigned long)ptr1 ^ (unsigned long)ptr2) <= 01) { 00499 table->hits++; 00500 if (mdd_equal(constraint, entry->constraint)) 00501 return(mdd_dup(entry->result)); 00502 else 00503 return(mdd_not(entry->result)); 00504 } 00505 } else if (constraint) { /* image computation */ 00506 if (mdd_equal(constraint, entry->constraint)) { 00507 if (SubstituteVector) { 00508 newResult = SubstituteCacheResult(info, delta, SubstituteVector, 00509 entry->result); 00510 return(newResult); 00511 } 00512 return(mdd_dup(entry->result)); 00513 } 00514 } else if (SubstituteVector) { /* range computation */ 00515 newResult = SubstituteCacheResult(info, delta, SubstituteVector, 00516 entry->result); 00517 return(newResult); 00518 } else { 00519 return(mdd_dup(entry->result)); 00520 } 00521 } 00522 entry = entry->next; 00523 } 00524 return(NIL(bdd_t)); 00525 } 00526 00527 00537 void 00538 ImgCacheInsertTable(ImgCacheTable_t *table, array_t *delta, 00539 bdd_t *constraint, bdd_t *result) 00540 { 00541 int slot, num, minSize; 00542 ImgCacheEntry_t *entry, *new_, *pos, *minDeltaEntry; 00543 00544 table->inserts += 1.0; 00545 00546 if (table->stTable) { 00547 table->entries += 1.0; 00548 if (table->preImgFlag || table->useConstraint) { 00549 ImgCacheStKey_t *key; 00550 00551 key = ALLOC(ImgCacheStKey_t, 1); 00552 key->vector = delta; 00553 key->constraint = constraint; 00554 st_insert(table->stTable, (char *)key, (char *)result); 00555 } else 00556 st_insert(table->stTable, (char *)delta, (char *)result); 00557 return; 00558 } 00559 00560 slot = VectorHash(table, delta, constraint); 00561 00562 minSize = 0x7fffffff; 00563 num = 0; 00564 pos = table->slot[slot]; 00565 entry = minDeltaEntry = NIL(ImgCacheEntry_t); 00566 while (pos != NIL(ImgCacheEntry_t)) { 00567 if (array_n(pos->vector) < minSize) { 00568 minDeltaEntry = pos; 00569 minSize = array_n(pos->vector); 00570 } 00571 pos = pos->next; 00572 num++; 00573 } 00574 00575 /* num = the number entries in the slot */ 00576 if (num < table->maxChainLength) { 00577 new_ = ALLOC(ImgCacheEntry_t, 1); 00578 new_->vector = delta; 00579 new_->constraint = constraint; 00580 new_->result = result; 00581 new_->next = table->slot[slot]; 00582 table->slot[slot] = new_; 00583 table->entries += 1.0; 00584 } else if (entry != NIL(ImgCacheEntry_t)) { 00585 CacheDestroyEntry(entry, FALSE); 00586 entry->vector = delta; 00587 entry->constraint = constraint; 00588 entry->result = result; 00589 } else { /* all entries are full of latest entries */ 00590 if (0) { /* Rehash */ 00591 unsigned int i, new_num_slot, new_slot, old_num_slot; 00592 ImgCacheEntry_t *next; 00593 ImgCacheEntry_t **old_bin; 00594 00595 old_num_slot = table->nSlots; 00596 old_bin = table->slot; 00597 new_num_slot = old_num_slot * 2; 00598 table->slot = ALLOC(ImgCacheEntry_t *, new_num_slot); 00599 if (!table->slot) { 00600 printf("VI_insert_table:new_slots"); 00601 exit(-1); 00602 } 00603 memset(table->slot, 0, sizeof(ImgCacheEntry_t *) * new_num_slot); 00604 table->nSlots = new_num_slot; 00605 00606 for (i = 0; i < old_num_slot; i++) { 00607 pos = old_bin[i]; 00608 while (pos != NIL(ImgCacheEntry_t)) { 00609 next = pos->next; 00610 new_slot = VectorHash(table, pos->vector, pos->constraint); 00611 pos->next = table->slot[new_slot]; 00612 table->slot[new_slot] = pos; 00613 pos = next; 00614 } 00615 } 00616 00617 new_slot = VectorHash(table, delta, constraint); 00618 new_ = ALLOC(ImgCacheEntry_t, 1); 00619 new_->vector = delta; 00620 new_->constraint = constraint; 00621 new_->result = result; 00622 new_->next = table->slot[slot]; 00623 table->slot[slot] = new_; 00624 table->entries += 1.0; 00625 } else { 00626 CacheDestroyEntry(minDeltaEntry, FALSE); 00627 minDeltaEntry->vector = delta; 00628 minDeltaEntry->constraint = constraint; 00629 minDeltaEntry->result = result; 00630 } 00631 } 00632 } 00633 00634 00644 void 00645 ImgFlushCache(ImgCacheTable_t *table) 00646 { 00647 unsigned int i; 00648 ImgCacheEntry_t *entry, *next; 00649 array_t *vector; 00650 bdd_t *result; 00651 st_generator *stGen; 00652 ImgCacheStKey_t *key; 00653 00654 if (!table) 00655 return; 00656 00657 if (table->stTable) { 00658 if (table->preImgFlag || table->useConstraint) { 00659 st_foreach_item(table->stTable, stGen, &key, &result) { 00660 st_delete(table->stTable, &key, NIL(char *)); 00661 ImgVectorFree(key->vector); 00662 mdd_free(key->constraint); 00663 FREE(key); 00664 mdd_free(result); 00665 } 00666 } else { 00667 st_foreach_item(table->stTable, stGen, &vector, &result) { 00668 st_delete(table->stTable, &vector, NIL(char *)); 00669 ImgVectorFree(vector); 00670 mdd_free(result); 00671 } 00672 } 00673 } else { 00674 for (i = 0; i < table->nSlots; i++) { 00675 entry = table->slot[i]; 00676 while (entry != NIL(ImgCacheEntry_t)) { 00677 next = entry->next; 00678 CacheDestroyEntry(entry, TRUE); 00679 entry = next; 00680 } 00681 table->slot[i] = NIL(ImgCacheEntry_t); 00682 } 00683 } 00684 table->entries = 0.0; 00685 } 00686 00687 00699 void 00700 ImgPrintCacheStatistics(ImgCacheTable_t *cache) 00701 { 00702 if (cache->preImgFlag) 00703 fprintf(vis_stdout, "** cache statistics (preImg) **\n"); 00704 else 00705 fprintf(vis_stdout, "** cache statistics (img) **\n"); 00706 fprintf(vis_stdout, "# insertions = %g\n", cache->inserts); 00707 if (cache->inserts != 0.0) { 00708 fprintf(vis_stdout, "# lookups = %g\n", cache->lookups); 00709 fprintf(vis_stdout, "# hits = %g (%.2f%%)\n", cache->hits, 00710 cache->hits / cache->lookups * 100.0); 00711 fprintf(vis_stdout, "# misses = %g (%.2f%%)\n", 00712 cache->lookups - cache->hits, 00713 (cache->lookups - cache->hits) / cache->lookups * 100.0); 00714 fprintf(vis_stdout, "# entries = %g\n", cache->entries); 00715 if (!cache->stTable) { 00716 fprintf(vis_stdout, "# slots = %d\n", cache->nSlots); 00717 fprintf(vis_stdout, "maxChainLength = %d\n", cache->maxChainLength); 00718 } 00719 } 00720 } 00721 00722 00723 /*---------------------------------------------------------------------------*/ 00724 /* Definition of static functions */ 00725 /*---------------------------------------------------------------------------*/ 00726 00727 00737 static void 00738 CacheDestroyEntry(ImgCacheEntry_t *entry, boolean freeEntry) 00739 { 00740 ImgVectorFree(entry->vector); 00741 mdd_free(entry->result); 00742 if (entry->constraint) 00743 mdd_free(entry->constraint); 00744 if (freeEntry) 00745 FREE(entry); 00746 } 00747 00748 00758 static int 00759 VectorHash(ImgCacheTable_t *table, array_t *delta, bdd_t *constraint) 00760 { 00761 unsigned long value; 00762 ImgComponent_t *comp; 00763 bdd_t *func; 00764 int i; 00765 00766 value = array_n(delta); 00767 if (constraint) 00768 value += (unsigned long)bdd_pointer(constraint) & ~01; 00769 for (i = 0; i < array_n(delta); i++) { 00770 comp = array_fetch(ImgComponent_t *, delta, i); 00771 func = comp->func; 00772 value += (unsigned long)bdd_pointer(func) & ~01; 00773 } 00774 return((int)(value % table->nSlots)); 00775 } 00776 00777 00787 static int 00788 VectorStHash(char *key, int modulus) 00789 { 00790 unsigned long value; 00791 array_t *delta; 00792 ImgComponent_t *comp; 00793 bdd_t *func; 00794 int i; 00795 00796 delta = (array_t *)key; 00797 value = array_n(delta); 00798 00799 for (i = 0; i < array_n(delta); i++) { 00800 comp = array_fetch(ImgComponent_t *, delta, i); 00801 func = comp->func; 00802 value += (unsigned long)bdd_pointer(func) & ~01; 00803 } 00804 return((int)(value % modulus)); 00805 } 00806 00807 00817 static int 00818 KeyStHash(char *key, int modulus) 00819 { 00820 ImgCacheStKey_t *stKey; 00821 unsigned long value; 00822 array_t *delta; 00823 ImgComponent_t *comp; 00824 bdd_t *func; 00825 int i; 00826 00827 stKey = (ImgCacheStKey_t *)key; 00828 delta = stKey->vector; 00829 value = array_n(delta); 00830 if (stKey->constraint) 00831 value += (unsigned long)bdd_pointer(stKey->constraint) & ~01; 00832 00833 for (i = 0; i < array_n(delta); i++) { 00834 comp = array_fetch(ImgComponent_t *, delta, i); 00835 func = comp->func; 00836 value += (unsigned long)bdd_pointer(func) & ~01; 00837 } 00838 return((int)(value % modulus)); 00839 } 00840 00841 00851 static int 00852 VectorCompare(array_t *vector1, array_t *vector2) 00853 { 00854 ImgComponent_t *comp1, *comp2; 00855 int i, index1, index2; 00856 00857 if (array_n(vector1) != array_n(vector2)) 00858 return(1); 00859 00860 for (i = 0; i < array_n(vector1); i++) { 00861 comp1 = array_fetch(ImgComponent_t *, vector1, i); 00862 comp2 = array_fetch(ImgComponent_t *, vector2, i); 00863 index1 = (int)bdd_top_var_id(comp1->var); 00864 index2 = (int)bdd_top_var_id(comp2->var); 00865 if (index1 != index2) 00866 return(1); 00867 if (!mdd_equal(comp1->func, comp2->func)) 00868 return(1); 00869 } 00870 SubstituteVector = NIL(array_t); 00871 return(0); 00872 } 00873 00874 00884 static int 00885 VectorSortCompare(array_t *vector1, array_t *vector2) 00886 { 00887 ImgComponent_t *comp1, *comp2; 00888 int i, index1, index2; 00889 int *ptr1, *ptr2, *regularPtr1, *regularPtr2; 00890 00891 if (array_n(vector1) != array_n(vector2)) 00892 return(1); 00893 00894 SubstituteVector = NIL(array_t); 00895 for (i = 0; i < array_n(vector1); i++) { 00896 comp1 = array_fetch(ImgComponent_t *, vector1, i); 00897 comp2 = array_fetch(ImgComponent_t *, vector2, i); 00898 index1 = (int)bdd_top_var_id(comp1->var); 00899 index2 = (int)bdd_top_var_id(comp2->var); 00900 if (index1 != index2) 00901 SubstituteVector = vector2; 00902 ptr1 = (int *)bdd_pointer(comp1->func); 00903 ptr2 = (int *)bdd_pointer(comp2->func); 00904 regularPtr1 = (int *)((unsigned long)ptr1 & ~01); 00905 regularPtr2 = (int *)((unsigned long)ptr2 & ~01); 00906 if (regularPtr1 == regularPtr2) { 00907 if (ptr1 != ptr2) { 00908 if (comp1->intermediate || comp2->intermediate) 00909 return(1); 00910 SubstituteVector = vector2; 00911 } 00912 } else 00913 return(1); 00914 } 00915 return(0); 00916 } 00917 00918 00928 static int 00929 VectorSortCompareWithConstraint(array_t *vector1, array_t *vector2) 00930 { 00931 ImgComponent_t *comp1, *comp2; 00932 int i, index1, index2; 00933 00934 if (array_n(vector1) != array_n(vector2)) 00935 return(1); 00936 00937 SubstituteVector = NIL(array_t); 00938 for (i = 0; i < array_n(vector1); i++) { 00939 comp1 = array_fetch(ImgComponent_t *, vector1, i); 00940 comp2 = array_fetch(ImgComponent_t *, vector2, i); 00941 index1 = (int)bdd_top_var_id(comp1->var); 00942 index2 = (int)bdd_top_var_id(comp2->var); 00943 if (index1 != index2) 00944 SubstituteVector = vector2; 00945 if (!mdd_equal(comp1->func, comp2->func)) 00946 return(1); 00947 } 00948 return(0); 00949 } 00950 00951 00961 static int 00962 ImageKeyCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2) 00963 { 00964 ComplementFlag = 0; 00965 if (mdd_equal(key1->constraint, key2->constraint)) { 00966 if (VectorCompare(key1->vector, key2->vector)) 00967 return(1); 00968 } else 00969 return(1); 00970 return(0); 00971 } 00972 00973 00983 static int 00984 ImageKeySortCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2) 00985 { 00986 ComplementFlag = 0; 00987 if (mdd_equal(key1->constraint, key2->constraint)) { 00988 if (VectorSortCompareWithConstraint(key1->vector, key2->vector)) 00989 return(1); 00990 } else 00991 return(1); 00992 return(0); 00993 } 00994 00995 01005 static int 01006 PreImageKeyCompare(ImgCacheStKey_t *key1, ImgCacheStKey_t *key2) 01007 { 01008 unsigned long ptr1, ptr2; 01009 01010 ptr1 = (unsigned long)bdd_pointer(key1->constraint); 01011 ptr2 = (unsigned long)bdd_pointer(key2->constraint); 01012 if ((ComplementFlag = (int) (ptr1 ^ ptr2)) <= 01) { 01013 if (VectorCompare(key1->vector, key2->vector)) 01014 return(1); 01015 } else 01016 return(1); 01017 return(0); 01018 } 01019 01020 01030 static mdd_t * 01031 SubstituteCacheResult(ImgTfmInfo_t *info, array_t *keyVector, 01032 array_t *cacheVector, 01033 mdd_t *result) 01034 { 01035 mdd_t *newResult; 01036 ImgComponent_t *comp1, *comp2; 01037 int *ptr1, *ptr2; 01038 int i, id1, id2; 01039 mdd_t *var, *func; 01040 array_t *varArray, *funcArray; 01041 01042 varArray = array_alloc(mdd_t *, 0); 01043 funcArray = array_alloc(mdd_t *, 0); 01044 01045 for (i = 0; i < array_n(keyVector); i++) { 01046 comp1 = array_fetch(ImgComponent_t *, keyVector, i); 01047 comp2 = array_fetch(ImgComponent_t *, cacheVector, i); 01048 ptr1 = (int *)bdd_pointer(comp1->func); 01049 ptr2 = (int *)bdd_pointer(comp2->func); 01050 id1 = (int)bdd_top_var_id(comp1->var); 01051 id2 = (int)bdd_top_var_id(comp2->var); 01052 if (id1 == id2) { 01053 if (ptr1 != ptr2) { 01054 array_insert_last(mdd_t *, varArray, comp2->var); 01055 func = mdd_not(comp1->var); 01056 array_insert_last(mdd_t *, funcArray, func); 01057 } 01058 } else { 01059 if (ptr1 == ptr2) { 01060 array_insert_last(mdd_t *, varArray, comp2->var); 01061 func = mdd_dup(comp1->var); 01062 array_insert_last(mdd_t *, funcArray, func); 01063 } else { 01064 array_insert_last(mdd_t *, varArray, comp2->var); 01065 func = mdd_not(comp1->var); 01066 array_insert_last(mdd_t *, funcArray, func); 01067 } 01068 } 01069 } 01070 if (array_n(varArray) == 1) { 01071 var = array_fetch(mdd_t *, varArray, 0); 01072 func = array_fetch(mdd_t *, funcArray, 0); 01073 newResult = bdd_compose(result, var, func); 01074 } else if (bdd_get_package_name() == CUDD) 01075 newResult = bdd_vector_compose(result, varArray, funcArray); 01076 else 01077 newResult = SubstituteCacheResultRecur(result, varArray, funcArray, 0); 01078 array_free(varArray); 01079 mdd_array_free(funcArray); 01080 return(newResult); 01081 } 01082 01083 01093 static mdd_t * 01094 SubstituteCacheResultRecur(mdd_t *result, array_t *varArray, array_t *funcArray, 01095 int pos) 01096 { 01097 mdd_t *var, *varNot, *func; 01098 mdd_t *resultT, *resultE, *newResultT, *newResultE, *newResult; 01099 01100 if (pos > array_n(varArray)) 01101 return(mdd_dup(result)); 01102 01103 var = array_fetch(mdd_t *, varArray, pos); 01104 func = array_fetch(mdd_t *, funcArray, pos); 01105 varNot = mdd_not(var); 01106 resultT = bdd_cofactor(result, var); 01107 resultE = bdd_cofactor(result, varNot); 01108 mdd_free(varNot); 01109 newResultT = SubstituteCacheResultRecur(resultT, varArray, funcArray, 01110 pos + 1); 01111 mdd_free(resultT); 01112 newResultE = SubstituteCacheResultRecur(resultE, varArray, funcArray, 01113 pos + 1); 01114 mdd_free(resultE); 01115 newResult = bdd_ite(func, newResultT, newResultE, 1, 1, 1); 01116 mdd_free(newResultT); 01117 mdd_free(newResultE); 01118 return(newResult); 01119 }