00001 #ifndef MST_MULTI_LINE_CACHE_CPP
00002 #define MST_MULTI_LINE_CACHE_CPP
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037 #include "MSTMultiListCache.h"
00038 #include "Utilities.h"
00039 #include <algorithm>
00040 #include <iterator>
00041 #include <cmath>
00042
00043 MSTMultiListCache::MSTMultiListCache(const int totalESTCount,
00044 const int startESTidx,
00045 const int numOwnESTs,
00046 const ESTAnalyzer *estAnalyzer,
00047 const bool repopulate,
00048 const int maxCachePerEST) :
00049 MSTCache(totalESTCount, startESTidx, numOwnESTs, estAnalyzer,
00050 repopulate, maxCachePerEST),
00051 cache(numOwnESTs), cacheRepopulation(0),
00052 prunedEntries(0), analysisCount(0) {
00053
00054 }
00055
00056 void
00057 MSTMultiListCache::pruneCaches(const int estIdxAdded,
00058 std::vector<int>& repopulateList,
00059 const bool prefixListSize) {
00060
00061
00062 repopulateList.clear();
00063 if (prefixListSize) {
00064
00065 int temp = 0;
00066 repopulateList.push_back(temp);
00067 }
00068
00069
00070 for(std::vector<MSTCacheEntry>::iterator curr = cache.begin();
00071 (curr != cache.end()); curr++) {
00072 MSTCacheEntry& entry = *curr;
00073 if (entry.second.empty()) {
00074
00075 continue;
00076 }
00077 if (pruneCache(entry.second, estIdxAdded) && repopulateCaches) {
00078
00079
00080 repopulateList.push_back(entry.first);
00081
00082 cacheRepopulation++;
00083 }
00084 }
00085
00086 nodesAdded[estIdxAdded] = true;
00087
00088
00089 if (prefixListSize) {
00090
00091
00092 repopulateList[0] = repopulateList.size() - 1;
00093 }
00094 }
00095
00096 bool
00097 MSTMultiListCache::pruneCache(SMList& list, const int estIdx) {
00098 SMList::iterator curr = list.begin();
00099 while (curr != list.end()) {
00100 if ((*curr).estIdx == estIdx) {
00101
00102
00103 prunedEntries++;
00104
00105 curr = list.erase(curr);
00106 } else {
00107
00108 curr++;
00109 }
00110 }
00111
00112 return list.empty();
00113 }
00114
00115 void
00116 MSTMultiListCache::mergeList(const int estIdx, const SMList& list) {
00117
00118
00119 if (list.empty()) {
00120
00121 return;
00122 }
00123
00124 const int localIndex = estIdx - startOwnESTidx;
00125 MSTCacheEntry& cacheEntry = cache[localIndex];
00126 SMList& cacheList = cacheEntry.second;
00127
00128
00129
00130
00131 float worstMetric = analyzer->getInvalidMetric();
00132 if (cacheList.size() > 0) {
00133
00134
00135 worstMetric = cacheList.back().metric;
00136 } else {
00137
00138 cacheEntry.first = estIdx;
00139 }
00140
00141
00142
00143 SMList::const_iterator mergeStart = list.begin();
00144 if (analyzer->compareMetrics(worstMetric, (*mergeStart).metric) &&
00145 ((int) cacheList.size() >= maxCachePerEST)) {
00146
00147
00148
00149 return;
00150 }
00151
00152
00153 SMList mergedList(list.size() + cacheList.size());
00154 LessCachedESTInfo mergeComparator(analyzer);
00155 std::merge(list.begin(), list.end(),
00156 cacheList.begin(), cacheList.end(),
00157 mergedList.begin(), mergeComparator);
00158
00159
00160 cacheList.clear();
00161 if ((int) mergedList.size() > maxCachePerEST) {
00162
00163 MSTCache::copy_n(mergedList, maxCachePerEST, cacheList);
00164 } else {
00165
00166 cacheList = mergedList;
00167 }
00168
00169 ASSERT ( cacheList.size() >= list.size() );
00170 }
00171
00172 void
00173 MSTMultiListCache::getBestEntry(int& srcESTidx, int& destESTidx,
00174 float& metric, int &alignmentData,
00175 int& directionData) const {
00176
00177 srcESTidx= destESTidx = alignmentData = directionData = -1;
00178 metric = analyzer->getInvalidMetric();
00179
00180
00181 for(std::vector<MSTCacheEntry>::const_iterator curr = cache.begin();
00182 (curr != cache.end()); curr++) {
00183 const MSTCacheEntry& cacheEntry = *curr;
00184 if (cacheEntry.second.empty()) {
00185
00186 continue;
00187 }
00188
00189
00190 const CachedESTInfo& estInfo = cacheEntry.second.front();
00191
00192 if (analyzer->compareMetrics(estInfo.metric, metric)) {
00193
00194 srcESTidx = cacheEntry.first;
00195 destESTidx = estInfo.estIdx;
00196 metric = estInfo.metric;
00197 alignmentData = estInfo.alignmentData;
00198 directionData = estInfo.directionData;
00199 }
00200 }
00201 }
00202
00203 void
00204 MSTMultiListCache::preprocess(SMList& list) {
00205
00206
00207 std::sort(list.begin(), list.end(), LessCachedESTInfo(analyzer));
00208
00209
00210 analysisCount += list.size();
00211
00212
00213 while ((int) list.size() > maxCachePerEST) {
00214
00215
00216 list.pop_back();
00217
00218 prunedEntries++;
00219 }
00220 }
00221
00222 void
00223 MSTMultiListCache::displayStats(std::ostream &os, const int MyRank) const {
00224
00225 int total = 0;
00226 for(std::vector<MSTCacheEntry>::const_iterator curr = cache.begin();
00227 (curr != cache.end()); curr++) {
00228 total += (*curr).second.size();
00229 }
00230
00231
00232
00233
00234 int adjustedPrunedEntries = prunedEntries - cache.size();
00235 if (adjustedPrunedEntries < 0) {
00236 adjustedPrunedEntries = 0;
00237 }
00238
00239 os << "Statistics on process with Rank " << MyRank << "\n"
00240 << "-------------------------------------------\n"
00241 << " #ESTs managed by cache : " << cache.size() << "\n"
00242 << " Total remaining entries : " << total << "\n"
00243 << " #Pruned entries : " << adjustedPrunedEntries
00244 << std::endl;
00245
00246 const double mean = (double) total / cache.size();
00247
00248 double variance = 0;
00249 for(std::vector<MSTCacheEntry>::const_iterator curr = cache.begin();
00250 (curr != cache.end()); curr++) {
00251 const double deviation = mean - (*curr).second.size();
00252 variance += (deviation * deviation);
00253 }
00254
00255 const double deviation = sqrt(variance);
00256
00257 os << " Mean (Standard deviation): " << mean
00258 << " (" << deviation << ")\n";
00259
00260 os << " Cache Repopulation count : " << cacheRepopulation << "\n"
00261 << " #EST analyses performed : " << analysisCount
00262 << std::endl;
00263 }
00264
00265 #endif