]> git.saurik.com Git - apt.git/blobdiff - cmdline/apt-cache.cc
count strings more accurately for stats
[apt.git] / cmdline / apt-cache.cc
index 072cf4ef7798a098802ae5c3abca7815a57122b3..4030ce4e61ecb279d2c0d68d39332d1097ad6425 100644 (file)
@@ -264,6 +264,46 @@ static bool DumpPackage(CommandLine &CmdL)
    return true;
 }
                                                                        /*}}}*/
+// ShowHashTableStats - Show stats about a hashtable                   /*{{{*/
+// ---------------------------------------------------------------------
+/* */
+template<class T>
+static void ShowHashTableStats(std::string Type,
+                               T *StartP,
+                               map_pointer_t *Hashtable,
+                               unsigned long Size)
+{
+   // hashtable stats for the HashTable
+   unsigned long NumBuckets = Size;
+   unsigned long UsedBuckets = 0;
+   unsigned long UnusedBuckets = 0;
+   unsigned long LongestBucket = 0;
+   unsigned long ShortestBucket = NumBuckets;
+   unsigned long Entries = 0;
+   for (unsigned int i=0; i < NumBuckets; ++i)
+   {
+      T *P = StartP + Hashtable[i];
+      if(P == 0 || P == StartP)
+      {
+         ++UnusedBuckets;
+         continue;
+      }
+      ++UsedBuckets;
+      unsigned long ThisBucketSize = 0;
+      for (; P != StartP; P = StartP + P->Next)
+         ++ThisBucketSize;
+      Entries += ThisBucketSize;
+      LongestBucket = std::max(ThisBucketSize, LongestBucket);
+      ShortestBucket = std::min(ThisBucketSize, ShortestBucket);
+   }
+   cout << "Total buckets in " << Type << ": " << NumBuckets << std::endl;
+   cout << "  Unused: " << UnusedBuckets << std::endl;
+   cout << "  Used: " << UsedBuckets  << std::endl;
+   cout << "  Average entries: " << Entries/(double)NumBuckets << std::endl;
+   cout << "  Longest: " << LongestBucket << std::endl;
+   cout << "  Shortest: " << ShortestBucket << std::endl;
+}
+                                                                       /*}}}*/
 // Stats - Dump some nice statistics                                   /*{{{*/
 // ---------------------------------------------------------------------
 /* */
@@ -335,100 +375,81 @@ static bool Stats(CommandLine &)
       SizeToStr(Cache->Head().DescFileCount*Cache->Head().DescFileSz) << ')' << endl;
    cout << _("Total Provides mappings: ") << Cache->Head().ProvidesCount << " (" <<
       SizeToStr(Cache->Head().ProvidesCount*Cache->Head().ProvidesSz) << ')' << endl;
-   
-   // String list stats
-   unsigned long Size = 0;
-   unsigned long Count = 0;
-   for (pkgCache::StringItem *I = Cache->StringItemP + Cache->Head().StringList;
-        I!= Cache->StringItemP; I = Cache->StringItemP + I->NextItem)
-   {
-      Count++;
-      Size += strlen(Cache->StrP + I->String) + 1;
-   }
-   cout << _("Total globbed strings: ") << Count << " (" << SizeToStr(Size) << ')' << endl;
 
-   unsigned long DepVerSize = 0;
+   // String list stats
+   std::set<map_stringitem_t> stritems;
+   for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
+      stritems.insert(G->Name);
    for (pkgCache::PkgIterator P = Cache->PkgBegin(); P.end() == false; ++P)
    {
+      stritems.insert(P->Arch);
       for (pkgCache::VerIterator V = P.VersionList(); V.end() == false; ++V)
       {
+        if (V->VerStr != 0)
+           stritems.insert(V->VerStr);
+        if (V->Section != 0)
+           stritems.insert(V->Section);
         for (pkgCache::DepIterator D = V.DependsList(); D.end() == false; ++D)
         {
            if (D->Version != 0)
-              DepVerSize += strlen(D.TargetVer()) + 1;
+              stritems.insert(D->Version);
+        }
+        for (pkgCache::DescIterator D = V.DescriptionList(); D.end() == false; ++D)
+        {
+           stritems.insert(D->md5sum);
+           stritems.insert(D->language_code);
         }
       }
+      for (pkgCache::PrvIterator Prv = P.ProvidesList(); Prv.end() == false; ++Prv)
+      {
+        if (Prv->ProvideVersion != 0)
+           stritems.insert(Prv->ProvideVersion);
+      }
    }
-   cout << _("Total dependency version space: ") << SizeToStr(DepVerSize) << endl;
-   
+   for (pkgCache::PkgFileIterator F = Cache->FileBegin(); F != Cache->FileEnd(); ++F)
+   {
+      stritems.insert(F->FileName);
+      stritems.insert(F->Archive);
+      stritems.insert(F->Codename);
+      stritems.insert(F->Component);
+      stritems.insert(F->Version);
+      stritems.insert(F->Origin);
+      stritems.insert(F->Label);
+      stritems.insert(F->Architecture);
+      stritems.insert(F->Site);
+      stritems.insert(F->IndexType);
+   }
+   unsigned long Size = 0;
+   for (std::set<map_stringitem_t>::const_iterator i = stritems.begin(); i != stritems.end(); ++i)
+      Size += strlen(Cache->StrP + *i) + 1;
+
+   cout << _("Total globbed strings: ") << stritems.size() << " (" << SizeToStr(Size) << ')' << endl;
+   stritems.clear();
+
    unsigned long Slack = 0;
    for (int I = 0; I != 7; I++)
       Slack += Cache->Head().Pools[I].ItemSize*Cache->Head().Pools[I].Count;
    cout << _("Total slack space: ") << SizeToStr(Slack) << endl;
-   
+
    unsigned long Total = 0;
-   Total = Slack + Size + Cache->Head().DependsCount*Cache->Head().DependencySz + 
-           Cache->Head().VersionCount*Cache->Head().VersionSz +
-           Cache->Head().PackageCount*Cache->Head().PackageSz + 
-           Cache->Head().VerFileCount*Cache->Head().VerFileSz +
-           Cache->Head().ProvidesCount*Cache->Head().ProvidesSz;
+#define APT_CACHESIZE(X,Y) (Cache->Head().X * Cache->Head().Y)
+   Total = Slack + Size +
+      APT_CACHESIZE(GroupCount, GroupSz) +
+      APT_CACHESIZE(PackageCount, PackageSz) +
+      APT_CACHESIZE(VersionCount, VersionSz) +
+      APT_CACHESIZE(DescriptionCount, DescriptionSz) +
+      APT_CACHESIZE(DependsCount, DependencySz) +
+      APT_CACHESIZE(PackageFileCount, PackageFileSz) +
+      APT_CACHESIZE(VerFileCount, VerFileSz) +
+      APT_CACHESIZE(DescFileCount, DescFileSz) +
+      APT_CACHESIZE(ProvidesCount, ProvidesSz) +
+      (2 * Cache->Head().HashTableSize * sizeof(map_id_t));
    cout << _("Total space accounted for: ") << SizeToStr(Total) << endl;
+#undef APT_CACHESIZE
 
-   // hashtable stats for the PkgHashTable
-   long NumBuckets = sizeof(Cache->HeaderP->PkgHashTable)/sizeof(map_ptrloc);
-   long UsedBuckets = 0;
-   long UnusedBuckets = 0;
-   long LongestBucket = 0;
-   long ShortestBucket = NumBuckets;
-   for (unsigned int i=0; i < NumBuckets; ++i)
-   {
-      pkgCache::Package *Pkg = Cache->PkgP + Cache->HeaderP->PkgHashTable[i];
-      if(Pkg == 0 || Pkg == Cache->PkgP)
-      {
-         UnusedBuckets++;
-         continue;
-      }
-      long ThisBucketSize = 0;
-      for (; Pkg != Cache->PkgP; Pkg = Cache->PkgP + Pkg->NextPackage)
-         ThisBucketSize++;
-      LongestBucket = std::max(ThisBucketSize, LongestBucket);
-      ShortestBucket = std::min(ThisBucketSize, ShortestBucket);
-      UsedBuckets += ThisBucketSize;
-   }
-   cout << "Total PkgHashTable buckets: " << SizeToStr(NumBuckets) << std::endl;
-   cout << "  Unused: " << SizeToStr(UnusedBuckets) << std::endl;
-   cout << "  Used: " << UsedBuckets  << std::endl;
-   cout << "  Average entries: " << UsedBuckets/(double)NumBuckets << std::endl;
-   cout << "  Longest: " << LongestBucket << std::endl;
-   cout << "  Shortest: " << ShortestBucket << std::endl;
-
-   // hashtable stats for the GrpHashTable
-   NumBuckets = sizeof(Cache->HeaderP->GrpHashTable)/sizeof(map_ptrloc);
-   UsedBuckets = 0;
-   UnusedBuckets = 0;
-   LongestBucket = 0;
-   ShortestBucket = NumBuckets;
-   for (unsigned int i=0; i < NumBuckets; ++i)
-   {
-      pkgCache::Group *Grp = Cache->GrpP + Cache->HeaderP->GrpHashTable[i];
-      if(Grp == 0 || Grp == Cache->GrpP)
-      {
-         UnusedBuckets++;
-         continue;
-      }
-      long ThisBucketSize = 0;
-      for (; Grp != Cache->GrpP; Grp = Cache->GrpP + Grp->Next)
-         ThisBucketSize++;
-      LongestBucket = std::max(ThisBucketSize, LongestBucket);
-      ShortestBucket = std::min(ThisBucketSize, ShortestBucket);
-      UsedBuckets += ThisBucketSize;
-   }
-   cout << "Total GrpHashTable buckets: " << SizeToStr(NumBuckets) << std::endl;
-   cout << "  Unused: " << SizeToStr(UnusedBuckets) << std::endl;
-   cout << "  Used: " << UsedBuckets  << std::endl;
-   cout << "  Average entries: " << UsedBuckets/(double)NumBuckets << std::endl;
-   cout << "  Longest: " << LongestBucket << std::endl;
-   cout << "  Shortest: " << ShortestBucket << std::endl;
+   // hashtable stats
+   ShowHashTableStats<pkgCache::Package>("PkgHashTable", Cache->PkgP, Cache->Head().PkgHashTable(), Cache->Head().HashTableSize);
+   ShowHashTableStats<pkgCache::Group>("GrpHashTable", Cache->GrpP, Cache->Head().GrpHashTable(), Cache->Head().HashTableSize);
 
    return true;
 }
@@ -563,7 +584,7 @@ static bool DumpAvail(CommandLine &)
         break;
       }
 
-      FileFd PkgF(File.FileName(),FileFd::ReadOnly);
+      FileFd PkgF(File.FileName(),FileFd::ReadOnly, FileFd::Extension);
       if (_error->PendingError() == true)
         break;
       
@@ -1287,7 +1308,7 @@ static bool DisplayRecord(pkgCacheFile &CacheFile, pkgCache::VerIterator V)
 struct ExDescFile
 {
    pkgCache::DescFile *Df;
-   map_ptrloc ID;
+   map_id_t ID;
 };
 
 // Search - Perform a search                                           /*{{{*/
@@ -1334,8 +1355,8 @@ static bool Search(CommandLine &CmdL)
    ExDescFile *DFList = new ExDescFile[descCount];
    memset(DFList,0,sizeof(*DFList) * descCount);
 
-   bool PatternMatch[descCount * NumPatterns];
-   memset(PatternMatch,false,sizeof(PatternMatch));
+   bool *PatternMatch = new bool[descCount * NumPatterns];
+   memset(PatternMatch,false,sizeof(*PatternMatch) * descCount * NumPatterns);
 
    // Map versions that we want to write out onto the VerList array.
    for (pkgCache::GrpIterator G = Cache->GrpBegin(); G.end() == false; ++G)
@@ -1445,6 +1466,7 @@ static bool Search(CommandLine &CmdL)
    }
    
    delete [] DFList;
+   delete [] PatternMatch;
    for (unsigned I = 0; I != NumPatterns; I++)
       regfree(&Patterns[I]);
    if (ferror(stdout))