X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/031aa37554d04be406588fb67807124b7f35d4c4..7974b907ac33f2a5d7c7ad75c0cb13166f642ec1:/apt-pkg/pkgcachegen.cc?ds=inline diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index 0bec88fc8..9806e5b91 100644 --- a/apt-pkg/pkgcachegen.cc +++ b/apt-pkg/pkgcachegen.cc @@ -1,6 +1,6 @@ // -*- mode: cpp; mode: fold -*- // Description /*{{{*/ -// $Id: pkgcachegen.cc,v 1.22 1998/11/12 03:28:31 jgg Exp $ +// $Id: pkgcachegen.cc,v 1.33 1999/03/08 07:18:11 jgg Exp $ /* ###################################################################### Package Cache Generator - Generator for the cache structure. @@ -21,8 +21,8 @@ #include #include #include - -#include +#include +#include #include #include @@ -45,6 +45,7 @@ pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map,OpProgress &Prog) : Cache.HeaderP->Dirty = true; Map.Sync(0,sizeof(pkgCache::Header)); Map.UsePools(*Cache.HeaderP->Pools,sizeof(Cache.HeaderP->Pools)/sizeof(Cache.HeaderP->Pools[0])); + memset(UniqHash,0,sizeof(UniqHash)); } /*}}}*/ // CacheGenerator::~pkgCacheGenerator - Destructor /*{{{*/ @@ -70,11 +71,14 @@ bool pkgCacheGenerator::MergeList(ListParser &List) { List.Owner = this; - int Counter = 0; + unsigned int Counter = 0; while (List.Step() == true) { // Get a pointer to the package structure string PackageName = List.Package(); + if (PackageName.empty() == true) + return false; + pkgCache::PkgIterator Pkg; if (NewPackage(Pkg,PackageName) == false) return _error->Error("Error occured while processing %s (NewPackage)",PackageName.c_str()); @@ -176,12 +180,20 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, pkgCache::VerFileIterator VF(Cache,Cache.VerFileP + VerFile); VF->File = CurrentFile - Cache.PkgFileP; - VF->NextFile = Ver->FileList; - Ver->FileList = VF.Index(); + + // Link it to the end of the list + __apt_ptrloc *Last = &Ver->FileList; + for (pkgCache::VerFileIterator V = Ver.FileList(); V.end() == false; V++) + Last = &V->NextFile; + VF->NextFile = *Last; + *Last = VF.Index(); + VF->Offset = List.Offset(); VF->Size = List.Size(); if (Cache.HeaderP->MaxVerFileSize < VF->Size) Cache.HeaderP->MaxVerFileSize = VF->Size; + Cache.HeaderP->VerFileCount++; + return true; } /*}}}*/ @@ -240,26 +252,33 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver, // Probe the reverse dependency list for a version string that matches if (Version.empty() == false) { - for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++) +/* for (pkgCache::DepIterator I = Pkg.RevDependsList(); I.end() == false; I++, Hit++) if (I->Version != 0 && I.TargetVer() == Version) - Dep->Version = I->Version; + Dep->Version = I->Version;*/ if (Dep->Version == 0) if ((Dep->Version = WriteString(Version)) == 0) return false; } - + // Link it to the package Dep->Package = Pkg.Index(); Dep->NextRevDepends = Pkg->RevDepends; Pkg->RevDepends = Dep.Index(); - // Link it to the version (at the end of the list) - __apt_ptrloc *Last = &Ver->DependsList; - for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) - Last = &D->NextDepends; - Dep->NextDepends = *Last; - *Last = Dep.Index(); + /* Link it to the version (at the end of the list) + Caching the old end point speeds up generation substantially */ + if (OldDepVer != Ver) + { + OldDepLast = &Ver->DependsList; + for (pkgCache::DepIterator D = Ver.DependsList(); D.end() == false; D++) + OldDepLast = &D->NextDepends; + OldDepVer = Ver; + } + Dep->NextDepends = *OldDepLast; + *OldDepLast = Dep.Index(); + OldDepLast = &Dep->NextDepends; + return true; } /*}}}*/ @@ -280,6 +299,7 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver, unsigned long Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides)); if (Provides == 0) return false; + Cache.HeaderP->ProvidesCount++; // Fill it in pkgCache::PrvIterator Prv(Cache,Cache.ProvideP + Provides,Cache.PkgP); @@ -342,6 +362,13 @@ bool pkgCacheGenerator::SelectFile(string File,unsigned long Flags) unsigned long pkgCacheGenerator::WriteUniqString(const char *S, unsigned int Size) { + /* We use a very small transient hash table here, this speeds up generation + by a fair amount on slower machines */ + pkgCache::StringItem *&Bucket = UniqHash[(S[0]*5 + S[1]) % _count(UniqHash)]; + if (Bucket != 0 && + stringcmp(S,S+Size,Cache.StrP + Bucket->String) == 0) + return Bucket->String; + // Search for an insertion point pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList; int Res = 1; @@ -356,7 +383,10 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, // Match if (Res == 0) + { + Bucket = I; return I->String; + } // Get a structure unsigned long Item = Map.Allocate(sizeof(pkgCache::StringItem)); @@ -371,6 +401,7 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, if (ItemP->String == 0) return 0; + Bucket = ItemP; return ItemP->String; } /*}}}*/ @@ -391,6 +422,13 @@ bool pkgSrcCacheCheck(pkgSourceList &List) int Missing = 0; for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) { + // Only cache deb source types. + if (I->Type != pkgSourceList::Item::Deb) + { + Missing++; + continue; + } + string File = ListDir + URItoFileName(I->PackagesURI()); struct stat Buf; if (stat(File.c_str(),&Buf) != 0) @@ -431,12 +469,16 @@ bool pkgSrcCacheCheck(pkgSourceList &List) return false; for (pkgCache::PkgFileIterator F(Cache); F.end() == false; F++) - { + { // Search for a match in the source list bool Bad = true; for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) { + // Only cache deb source types. + if (I->Type != pkgSourceList::Item::Deb) + continue; + string File = ListDir + URItoFileName(I->PackagesURI()); if (F.FileName() == File) { @@ -620,8 +662,8 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) { string File = ListDir + URItoFileName(I->PackagesURI()); - - if (stat(File.c_str(),&Buf) != 0) + + if (FileExists(File) == false) continue; FileFd Pkg(File,FileFd::ReadOnly); @@ -637,6 +679,16 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) if (Gen.MergeList(Parser) == false) return _error->Error("Problem with MergeList %s",File.c_str()); + + // Check the release file + string RFile = ListDir + URItoFileName(I->ReleaseURI()); + if (FileExists(RFile) == true) + { + FileFd Rel(RFile,FileFd::ReadOnly); + if (_error->PendingError() == true) + return false; + Parser.LoadReleaseInfo(Gen.GetCurFile(),Rel); + } } // Write the src cache