Main Page | Modules | Alphabetical List | Data Structures | File List | Data Fields | Related Pages

scache.c

00001 /* 00002 * copyright (c) 1997-2003 the cdg team <cdg@nats.informatik.uni-hamburg.de> 00003 * 00004 * this file is free software; as a special exception the author gives 00005 * unlimited permission to copy and/or distribute it, with or without 00006 * modifications, as long as this notice is preserved. 00007 * 00008 * this program is distributed in the hope that it will be useful, but 00009 * without any warranty, to the extent permitted by law; without even the 00010 * implied warranty of merchantability or fitness for a particular purpose. 00011 * 00012 * $id: skel.c,v 1.8 2003/05/14 15:07:59 micha exp $ 00013 */ 00014 00015 /* ------------------------------------------------------------------------- 00016 * @addtogroup Scache Scache - Cache structures for binary LV scores 00017 * @author Michael Schulz 00018 * @date somewhen in 1998 00019 * 00020 * A score cache serves much the same purpose as the score matrices in 00021 * the edges of a constraint net, except that it can be used even if the 00022 * constraint net has no edges in it. This simply means that the binary 00023 * score of a pair of LVs will be computed when it is used for the first 00024 * time rather than upon initializing the net. 00025 * 00026 * @{ 00027 */ 00028 00029 /* ---------------------------------------------------------------------- */ 00030 #include <config.h> 00031 00032 #include <stdio.h> 00033 #include "scache.h" 00034 #include "hook.h" 00035 #include "set.h" 00036 00037 /* ---------------------------------------------------------------------- */ 00038 /** determines the index of a given pair */ 00039 #define indexOfPair(x,y) ((x<y) ? (((y*(y-1))>>1)+x) : (((x*(x-1))>>1)+y)) 00040 /** debug flag */ 00041 #define DEBUG_SCORECACHE 0 00042 00043 /* ---------------------------------------------------------------------- 00044 * implements the CDG variable \b cache. 00045 * If this flag is set, binary constraints are never evaluated twice on the 00046 * same pair of LVs. The function evalBinary() will then simply call 00047 * scGetScore() instead of evalConstraint(). 00048 * 00049 * This variable is exported because it's cheaper for the calling function 00050 * to check a boolean variable than calling a cache function which does 00051 * nothing again and again. 00052 */ 00053 Boolean scUseCache=FALSE; 00054 00055 /* ---------------------------------------------------------------------- 00056 * return an initial score-cache 00057 * 00058 * This function returns a pointer to a new cache. The fields 00059 * \b count and \b hits are initialized to 0. All elements of the 00060 * underlying Vector are set to -1. 00061 */ 00062 ScoreCache scNew(int noValues) 00063 { 00064 ScoreCache cache; 00065 int capacity = indexOfPair(noValues, noValues - 1); 00066 00067 cache = (ScoreCache) memMalloc(sizeof (ScoreCacheStruct)); 00068 cache->count = 0; 00069 cache->size = 0; 00070 cache->capacity = capacity; 00071 cache->hits = 0; 00072 00073 cache->data = (Number *) memMalloc(sizeof (Number) * capacity); 00074 #if 0 00075 for (i = 0; i < capacity; i++) { 00076 cache->data[i] = -1.0; 00077 } 00078 #endif 00079 00080 return cache; 00081 } 00082 00083 /* ---------------------------------------------------------------------- 00084 * free memory from a cache 00085 * 00086 * This function deallocates a cache. 00087 */ 00088 void scDelete(ScoreCache cache) 00089 { 00090 if(!cache) { return; } 00091 00092 memFree(cache->data); 00093 memFree(cache); 00094 } 00095 00096 /* ---------------------------------------------------------------------- 00097 * retrieve score from cache if available, else return -1.0 00098 * 00099 * This function returns the mutual score for the LVs \b a and 00100 * \b b from the score. If it is not yet known, -1 is returned. 00101 */ 00102 Number scGetScore(ScoreCache cache, LevelValue a, LevelValue b) 00103 { 00104 Number score; 00105 int index; 00106 00107 if (!cache || a->no < 0 || b->no < 0 00108 || a->indexWRTNet == -1 || a->indexWRTNet == -1) { // frobbing hack 00109 return -1.0; 00110 } 00111 00112 index = indexOfPair(a->no, b->no); 00113 if (index >= cache->size) { 00114 return -1.0; 00115 } 00116 00117 score = cache->data[index]; 00118 if (score != -1.0) { 00119 cache->hits++; 00120 } 00121 00122 return score; 00123 } 00124 00125 /* ---------------------------------------------------------------------- 00126 * store score in cache 00127 * 00128 * This function registers a binary score in the cache. It behaves as follows: 00129 * 00130 * - If \b cache is \b NULL the function returns. 00131 * - If either of the LVs still has its \b no set to -1, 00132 * \b registerValue() is applied to it. 00133 * - A unique index is computed from the fields \b no of both LVs. 00134 * - The underlying Vector is resize if necessary. 00135 * - \b score is entered in the corresponding cell. 00136 */ 00137 void scSetScore(ScoreCache cache, LevelValue a, LevelValue b, Number score) 00138 { 00139 int index; 00140 int i; 00141 00142 if (!cache 00143 || a->indexWRTNet == -1 || b->indexWRTNet == -1) { // frobbing hack 00144 return; 00145 } 00146 00147 if (a->no < 0) { 00148 a->no = cache->count++; 00149 } 00150 if (b->no < 0) { 00151 b->no = cache->count++; 00152 } 00153 00154 index = indexOfPair(a->no, b->no); 00155 00156 /* 00157 * resizing should only happen if we don't know the maximum number 00158 * of levelvalues in a constraintnet in advance, ie. in incremental 00159 * computations 00160 */ 00161 if (index >= cache->capacity) { 00162 int old; 00163 00164 old = cache->capacity; 00165 while (index >= cache->capacity) { 00166 cache->capacity *= 2; 00167 } 00168 00169 #if DEBUG_SCORECACHE 00170 cdgPrintf(CDG_DEBUG, 00171 "DEBUG: resizing score-cache from %d to %d " 00172 "because of levelvalues %d, %d (index %d)\n", 00173 old, cache->capacity, a->no, b->no, index); 00174 #endif 00175 00176 cache->data = (Number *) memRealloc(cache->data, 00177 sizeof (Number) * cache->capacity); 00178 00179 #if 0 00180 for (i = old; i < cache->capacity; i++) { 00181 cache->data[i] = -1.0; 00182 } 00183 #endif 00184 } 00185 00186 /* 00187 * if we want a bucket behind the used size then initialize the unused part 00188 */ 00189 if (cache->size < index) { 00190 for (i = cache->size; i < index; i++) { 00191 cache->data[i] = -1.0; 00192 } 00193 cache->size = index; 00194 } 00195 00196 #if DEBUG_SCORECACHE 00197 else { 00198 Number s; 00199 00200 s = cache->data[index]; 00201 if (s != -1.0 && s != score) { 00202 cdgPrintf(CDG_ERROR, 00203 "ERROR: overwriting binary score %f with %f\n", s, score); 00204 cdgPrintf(CDG_ERROR, " a=%d b=%d index=%d\n", a->no, b->no, index); 00205 } 00206 } 00207 #endif 00208 00209 cache->data[index] = score; 00210 } 00211 00212 /* ---------------------------------------------------------------------- 00213 * initialize the module \b Scache. It registers 00214 * the module's CDG variables. 00215 */ 00216 void scInitialize() 00217 { 00218 setRegister("cache", SET_BOOL, &scUseCache, NULL, NULL, NULL, NULL); 00219 } 00220 /** @} */

CDG 0.95 (20 Oct 2004)