00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <Basics.H>
00025 #include <FP.H>
00026
00027 #include "CacheEntry.H"
00028 #include "StatNames.H"
00029 #include "StatCFP.H"
00030
00031 static unsigned int count_redundant_names(const FV::List *allNames,
00032 const BitVector *entryNames)
00033 {
00034 BitVector redundantNames;
00035
00036 BVIter nameIter1(*entryNames);
00037 int nameIndex1;
00038 while(nameIter1.Next(nameIndex1))
00039 {
00040
00041
00042 if(redundantNames.Read(nameIndex1))
00043 continue;
00044
00045 const Text *name1 = &(allNames->name[nameIndex1]);
00046 if((*name1)[0] == 'N')
00047 {
00048 Text path(name1->Sub(2));
00049 BVIter nameIter2(*entryNames);
00050 int nameIndex2;
00051 while(nameIter2.Next(nameIndex2))
00052 {
00053
00054 if(nameIndex2 == nameIndex1)
00055 continue;
00056
00057
00058
00059 if(redundantNames.Read(nameIndex2))
00060 continue;
00061
00062 const Text *name2 = &(allNames->name[nameIndex2]);
00063
00064
00065 if(name2->Sub(2, path.Length()) != path)
00066 continue;
00067
00068 if(name2->Length() > (path.Length()+2))
00069 {
00070
00071
00072
00073 if((*name2)[path.Length()+2] != '/')
00074 continue;
00075
00076
00077
00078 redundantNames.Set(nameIndex2);
00079 }
00080 else
00081 {
00082
00083
00084
00085
00086 char type = (*name2)[0];
00087 if((type == 'T') || (type == 'L') || (type == 'B') || (type == 'E'))
00088 {
00089 redundantNames.Set(nameIndex2);
00090 }
00091 }
00092 }
00093 }
00094 }
00095
00096
00097 return redundantNames.Cardinality();
00098 }
00099
00100 int CFPObj::Search(int verbose,
00101 Stat::Collection &stats)
00102 const throw ()
00103 {
00104
00105 StatCount *sc;
00106 if (stats.fanout.size() == 0) {
00107 sc = NEW(StatCount);
00108 stats.fanout.addhi(sc);
00109 } else {
00110 sc = stats.fanout.get(0);
00111 }
00112
00113
00114 int cnt;
00115 {
00116 CE::T *ce = (CE::T *) 0;
00117 CFPIter it(this);
00118 for (cnt = 0; it.Next( ce); cnt++) {
00119
00120 Stat::Location *entry_loc = NEW_CONSTR(Stat::Location,
00121 (this->loc->add_ci(ce->CI())));
00122
00123 int totalNames = ce->FPs()->len;
00124 stats.entryStats[Stat::NumEntryNames].AddVal(totalNames, entry_loc);
00125 if (totalNames > 0) {
00126 int numUncommonNames = ce->UncommonNames()->Cardinality();
00127 stats.entryStats[Stat::NumUncommonNames].AddVal(numUncommonNames, entry_loc);
00128 float totalF = (float)totalNames;
00129 float uncommonF = (float)numUncommonNames;
00130 int pcntUncommon = (int)(0.49 + (100.0 * uncommonF / totalF));
00131 stats.entryStats[Stat::PcntUncommonNames].AddVal(pcntUncommon, entry_loc);
00132
00133
00134
00135 if(stats.redundant)
00136 {
00137 BitVector entryNames(this->pkFile->CommonNames());
00138 entryNames |= *(ce->UncommonNames());
00139
00140 unsigned int redundantNames =
00141 count_redundant_names(this->pkFile->AllNames(), &entryNames);
00142
00143 stats.entryStats[Stat::NumRedundantNames].AddVal(redundantNames,
00144 entry_loc);
00145
00146 int pcntRedundant = (int)(0.49 +
00147 (100.0 * ((float)redundantNames) /
00148 totalF));
00149
00150 stats.entryStats[Stat::PcntRedundantNames].AddVal(pcntRedundant,
00151 entry_loc);
00152 }
00153 }
00154 const VestaVal::T *value = ce->Value();
00155 stats.entryStats[Stat::ValueSize].AddVal(value->len, entry_loc);
00156 stats.entryStats[Stat::NumDIs].AddVal(value->dis.len, entry_loc);
00157 stats.entryStats[Stat::NumKids].AddVal(ce->Kids()->len, entry_loc);
00158 const IntIntTblLR *imap = ce->IMap();
00159 int imapSz = (imap == NULL) ? 0 : imap->Size();
00160 stats.entryStats[Stat::NameMapSize].AddVal(imapSz, entry_loc);
00161 int imapNonEmpty = (imap == NULL) ? 0 : 1;
00162 stats.entryStats[Stat::NameMapNonEmpty].AddVal(imapNonEmpty, entry_loc);
00163 stats.entryStats[Stat::ValPfxTblSize].AddVal(value->prefixTbl.NumArcs(),
00164 entry_loc);
00165
00166
00167
00168 sc->AddVal(1, 0);
00169 }
00170 ce = (CE::T *) 0;
00171 }
00172
00173
00174 int thisLevel = 1;
00175 if (stats.fanout.size() <= thisLevel) {
00176 assert(stats.fanout.size() == thisLevel);
00177 sc = NEW(StatCount);
00178 stats.fanout.addhi(sc);
00179 } else {
00180 sc = stats.fanout.get(thisLevel);
00181 }
00182 sc->AddVal(cnt, this->loc);
00183 return thisLevel;
00184 }
00185
00186 bool CFPIter::Next( CE::T* &ce) throw ()
00187 {
00188 bool res = (this->next != (CE::List *)NULL);
00189 if (res) {
00190 ce = this->next->Head();
00191 this->next = this->next->Tail();
00192 }
00193 return res;
00194 }