VIS

src/img/imgTfmCache.c

Go to the documentation of this file.
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 }