X-Git-Url: https://git.saurik.com/apt.git/blobdiff_plain/eb6a718efeb2b7bea3b52890af7ecbcacfc0ed74..349cd3b8dbb1e218b31443be55933b01042c4acf:/apt-pkg/pkgcachegen.cc diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc index d7e830df5..478778946 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.34 1999/04/04 01:33:09 jgg Exp $ +// $Id: pkgcachegen.cc,v 1.40 1999/07/15 03:15:48 jgg Exp $ /* ###################################################################### Package Cache Generator - Generator for the cache structure. @@ -26,6 +26,7 @@ #include #include +#include /*}}}*/ // CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/ @@ -98,7 +99,7 @@ bool pkgCacheGenerator::MergeList(ListParser &List) } pkgCache::VerIterator Ver = Pkg.VersionList(); - __apt_ptrloc *Last = &Pkg->VersionList; + map_ptrloc *Last = &Pkg->VersionList; int Res = 1; for (; Ver.end() == false; Last = &Ver->NextVer, Ver++) { @@ -110,20 +111,34 @@ bool pkgCacheGenerator::MergeList(ListParser &List) /* We already have a version for this item, record that we saw it */ - if (Res == 0) + unsigned long Hash = List.VersionHash(); + if (Res == 0 && Ver->Hash == Hash) { if (List.UsePackage(Pkg,Ver) == false) return _error->Error("Error occured while processing %s (UsePackage2)",PackageName.c_str()); - + if (NewFileVer(Ver,List) == false) return _error->Error("Error occured while processing %s (NewFileVer1)",PackageName.c_str()); continue; } + // Skip to the end of the same version set. + if (Res == 0) + { + for (; Ver.end() == false; Last = &Ver->NextVer, Ver++) + { + Res = pkgVersionCompare(Version.begin(),Version.end(),Ver.VerStr(), + Ver.VerStr() + strlen(Ver.VerStr())); + if (Res != 0) + break; + } + } + // Add a new version *Last = NewVersion(Ver,Version,*Last); Ver->ParentPkg = Pkg.Index(); + Ver->Hash = Hash; if (List.NewVersion(Ver) == false) return _error->Error("Error occured while processing %s (NewVersion1)",PackageName.c_str()); @@ -182,7 +197,7 @@ bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver, VF->File = CurrentFile - Cache.PkgFileP; // Link it to the end of the list - __apt_ptrloc *Last = &Ver->FileList; + map_ptrloc *Last = &Ver->FileList; for (pkgCache::VerFileIterator V = Ver.FileList(); V.end() == false; V++) Last = &V->NextFile; VF->NextFile = *Last; @@ -372,7 +387,7 @@ unsigned long pkgCacheGenerator::WriteUniqString(const char *S, // Search for an insertion point pkgCache::StringItem *I = Cache.StringItemP + Cache.HeaderP->StringList; int Res = 1; - __apt_ptrloc *Last = &Cache.HeaderP->StringList; + map_ptrloc *Last = &Cache.HeaderP->StringList; for (; I != Cache.StringItemP; Last = &I->NextItem, I = Cache.StringItemP + I->NextItem) { @@ -615,6 +630,70 @@ static bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen, Progress.Progress(Pkg.Size()); } + return true; +} + /*}}}*/ +// GenerateSrcCache - Write the source package lists to the map /*{{{*/ +// --------------------------------------------------------------------- +/* This puts the source package cache into the given generator. */ +bool pkgGenerateSrcCache(pkgSourceList &List,OpProgress &Progress, + pkgCacheGenerator &Gen, + unsigned long &CurrentSize,unsigned long &TotalSize) +{ + string ListDir = _config->FindDir("Dir::State::lists"); + + // Prepare the progress indicator + TotalSize = 0; + struct stat Buf; + for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) + { + string File = ListDir + URItoFileName(I->PackagesURI()); + if (stat(File.c_str(),&Buf) != 0) + continue; + TotalSize += Buf.st_size; + } + + if (pkgAddSourcesSize(TotalSize) == false) + return false; + + // Generate the pkg source cache + CurrentSize = 0; + 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 (FileExists(File) == false) + continue; + + FileFd Pkg(File,FileFd::ReadOnly); + debListParser Parser(Pkg); + Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists"); + if (_error->PendingError() == true) + return _error->Error("Problem opening %s",File.c_str()); + CurrentSize += Pkg.Size(); + + Progress.SubProgress(0,I->PackagesInfo()); + if (Gen.SelectFile(File) == false) + return _error->Error("Problem with SelectFile %s",File.c_str()); + + 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); + } + } + return true; } /*}}}*/ @@ -634,67 +713,18 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) if (SrcOk == false) { string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); - string ListDir = _config->FindDir("Dir::State::lists"); FileFd SCacheF(SCacheFile,FileFd::WriteEmpty); FileFd CacheF(CacheFile,FileFd::WriteEmpty); DynamicMMap Map(CacheF,MMap::Public); if (_error->PendingError() == true) return false; - + pkgCacheGenerator Gen(Map,Progress); - - // Prepare the progress indicator + unsigned long CurrentSize = 0; unsigned long TotalSize = 0; - struct stat Buf; - for (pkgSourceList::const_iterator I = List.begin(); I != List.end(); I++) - { - string File = ListDir + URItoFileName(I->PackagesURI()); - if (stat(File.c_str(),&Buf) != 0) - continue; - TotalSize += Buf.st_size; - } - - if (pkgAddSourcesSize(TotalSize) == false) + if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) return false; - // Generate the pkg source cache - unsigned long CurrentSize = 0; - 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 (FileExists(File) == false) - continue; - - FileFd Pkg(File,FileFd::ReadOnly); - debListParser Parser(Pkg); - Progress.OverallProgress(CurrentSize,TotalSize,Pkg.Size(),"Reading Package Lists"); - if (_error->PendingError() == true) - return _error->Error("Problem opening %s",File.c_str()); - CurrentSize += Pkg.Size(); - - Progress.SubProgress(0,I->PackagesInfo()); - if (Gen.SelectFile(File) == false) - return _error->Error("Problem with SelectFile %s",File.c_str()); - - 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 Gen.GetCache().HeaderP->Dirty = false; if (SCacheF.Write(Map.Data(),Map.Size()) == false) @@ -736,3 +766,126 @@ bool pkgMakeStatusCache(pkgSourceList &List,OpProgress &Progress) return pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize); } /*}}}*/ +// MakeStatusCacheMem - Returns a map for the status cache /*{{{*/ +// --------------------------------------------------------------------- +/* This creates a map object for the status cache. If the process has write + access to the caches then it is the same as MakeStatusCache, otherwise it + creates a memory block and puts the cache in there. */ +MMap *pkgMakeStatusCacheMem(pkgSourceList &List,OpProgress &Progress) +{ + /* If the cache file is writeable this is just a wrapper for + MakeStatusCache */ + string CacheFile = _config->FindFile("Dir::Cache::pkgcache"); + bool Writeable = (access(CacheFile.c_str(),W_OK) == 0) || + (errno == ENOENT); + + if (Writeable == true) + { + if (pkgMakeStatusCache(List,Progress) == false) + return 0; + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // Mostly from MakeStatusCache.. + Progress.OverallProgress(0,1,1,"Reading Package Lists"); + + bool SrcOk = pkgSrcCacheCheck(List); + bool PkgOk = SrcOk && pkgPkgCacheCheck(CacheFile); + + // Rebuild the source and package caches + if (SrcOk == false) + { + DynamicMMap *Map = new DynamicMMap(MMap::Public); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + unsigned long CurrentSize = 0; + unsigned long TotalSize = 0; + if (pkgGenerateSrcCache(List,Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + // Merge in the source caches + if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; + } + + if (PkgOk == true) + { + Progress.OverallProgress(1,1,1,"Reading Package Lists"); + + // Open the cache file + FileFd File(_config->FindFile("Dir::Cache::pkgcache"),FileFd::ReadOnly); + if (_error->PendingError() == true) + return 0; + + MMap *Map = new MMap(File,MMap::Public | MMap::ReadOnly); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + return Map; + } + + // We use the source cache to generate the package cache + string SCacheFile = _config->FindFile("Dir::Cache::srcpkgcache"); + FileFd SCacheF(SCacheFile,FileFd::ReadOnly); + DynamicMMap *Map = new DynamicMMap(MMap::Public); + if (_error->PendingError() == true) + { + delete Map; + return 0; + } + + // Preload the map with the source cache + if (SCacheF.Read((unsigned char *)Map->Data() + Map->RawAllocate(SCacheF.Size()), + SCacheF.Size()) == false) + { + delete Map; + return 0; + } + + pkgCacheGenerator Gen(*Map,Progress); + + // Compute the progress + unsigned long TotalSize = 0; + if (pkgAddSourcesSize(TotalSize) == false) + { + delete Map; + return 0; + } + + unsigned long CurrentSize = 0; + if (pkgMergeStatus(Progress,Gen,CurrentSize,TotalSize) == false) + { + delete Map; + return 0; + } + + return Map; +} + /*}}}*/