Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

StatCFP.C

Go to the documentation of this file.
00001 // Copyright (C) 2001, Compaq Computer Corporation
00002 // 
00003 // This file is part of Vesta.
00004 // 
00005 // Vesta is free software; you can redistribute it and/or
00006 // modify it under the terms of the GNU Lesser General Public
00007 // License as published by the Free Software Foundation; either
00008 // version 2.1 of the License, or (at your option) any later version.
00009 // 
00010 // Vesta is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013 // Lesser General Public License for more details.
00014 // 
00015 // You should have received a copy of the GNU Lesser General Public
00016 // License along with Vesta; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 
00019 // Last modified on Fri Apr 29 00:24:11 EDT 2005 by ken@xorian.net         
00020 //      modified on Mon Jul 15 17:03:49 EDT 2002 by kcschalk@shr.intel.com 
00021 //      modified on Sat Feb 12 13:10:05 PST 2000 by mann  
00022 //      modified on Mon May 26 18:09:08 PDT 1997 by heydon
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       // If we've already marked this name as redundant, we don't need
00041       // to check for whether it makes anything else redundant.
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               // Don't compare against ourselves
00054               if(nameIndex2 == nameIndex1)
00055                 continue;
00056 
00057               // If we've already marked this name as redundant, we
00058               // don't need to check for whether it's redundant.
00059               if(redundantNames.Read(nameIndex2))
00060                 continue;
00061 
00062               const Text *name2 = &(allNames->name[nameIndex2]);
00063 
00064               // Skip anything that doesn't match the path.
00065               if(name2->Sub(2, path.Length()) != path)
00066                 continue;
00067 
00068               if(name2->Length() > (path.Length()+2))
00069                 {
00070                   // If the next character after the path isn't a path
00071                   // separator, this isn't a sub-element of the first
00072                   // name.
00073                   if((*name2)[path.Length()+2] != '/')
00074                     continue;
00075 
00076                   // Otherwise, this is a sub-element of the first
00077                   // name, and therefore redundant.
00078                   redundantNames.Set(nameIndex2);
00079                 }
00080               else
00081                 {
00082                   // This is a dependency for the same path.  If it's
00083                   // a type (T), list length (L), binding names (B),
00084                   // or expression (E) dependency, then it's
00085                   // redundant.
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   // Return the total number of redundant names we found.
00097   return redundantNames.Cardinality();
00098 }
00099 
00100 int CFPObj::Search(int verbose,
00101                    /*INOUT*/ Stat::Collection &stats)
00102   const throw ()
00103 {
00104     // set "sc" to be StatCount for level 0
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     // iterate over children
00114     int cnt;
00115     {
00116       CE::T *ce = (CE::T *) 0;
00117       CFPIter it(this);
00118       for (cnt = 0; it.Next(/*OUT*/ ce); cnt++) {
00119         // Create a location for this entry
00120         Stat::Location *entry_loc = NEW_CONSTR(Stat::Location,
00121                                                (this->loc->add_ci(ce->CI())));
00122         // gather stats on "ce"
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           // Counting redundant dependencies is expensive, so we only
00134           // do it if it's been specifically requested.
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         // update "sc"
00168         sc->AddVal(1, 0);
00169       }
00170       ce = (CE::T *) 0; // drop on floor for GC;
00171     }
00172 
00173     // update fan-out for this level
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(/*OUT*/ 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 }

Generated on Mon May 8 00:48:36 2006 for Vesta by  doxygen 1.4.2