// -*- mode: cpp; mode: fold -*-
// Description /*{{{*/
-// $Id: pkgcachegen.cc,v 1.35 1999/04/18 06:36:36 jgg Exp $
+// $Id: pkgcachegen.cc,v 1.41 1999/07/26 17:46:07 jgg Exp $
/* ######################################################################
Package Cache Generator - Generator for the cache structure.
#include <sys/stat.h>
#include <unistd.h>
+#include <errno.h>
/*}}}*/
// CacheGenerator::pkgCacheGenerator - Constructor /*{{{*/
// ---------------------------------------------------------------------
/* We set the diry flag and make sure that is written to the disk */
pkgCacheGenerator::pkgCacheGenerator(DynamicMMap &Map,OpProgress &Prog) :
- Map(Map), Cache(Map), Progress(Prog)
+ Map(Map), Cache(Map), Progress(&Prog)
{
+ CurrentFile = 0;
+
if (_error->PendingError() == true)
return;
// ---------------------------------------------------------------------
/* This provides the generation of the entries in the cache. Each loop
goes through a single package record from the underlying parse engine. */
-bool pkgCacheGenerator::MergeList(ListParser &List)
+bool pkgCacheGenerator::MergeList(ListParser &List,
+ pkgCache::VerIterator *OutVer)
{
List.Owner = this;
if (NewPackage(Pkg,PackageName) == false)
return _error->Error("Error occured while processing %s (NewPackage)",PackageName.c_str());
Counter++;
- if (Counter % 100 == 0)
- Progress.Progress(List.Offset());
+ if (Counter % 100 == 0 && Progress != 0)
+ Progress->Progress(List.Offset());
/* Get a pointer to the version structure. We know the list is sorted
so we use that fact in the search. Insertion of new versions is
}
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++)
{
/* 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());
+ // Read only a single record and return
+ if (OutVer != 0)
+ {
+ *OutVer = Ver;
+ return true;
+ }
+
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());
if (NewFileVer(Ver,List) == false)
return _error->Error("Error occured while processing %s (NewVersion2)",PackageName.c_str());
+
+ // Read only a single record and return
+ if (OutVer != 0)
+ {
+ *OutVer = Ver;
+ return true;
+ }
}
return true;
bool pkgCacheGenerator::NewFileVer(pkgCache::VerIterator &Ver,
ListParser &List)
{
+ if (CurrentFile == 0)
+ return true;
+
// Get a structure
unsigned long VerFile = Map.Allocate(sizeof(pkgCache::VerFile));
if (VerFile == 0)
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;
if (CurrentFile->FileName == 0)
return false;
- Progress.SubProgress(Buf.st_size);
+ if (Progress != 0)
+ Progress->SubProgress(Buf.st_size);
return true;
}
/*}}}*/
// 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)
{
return true;
}
/*}}}*/
-// AddSourcesSize - Add the size of the status files /*{{{*/
+// AddStatusSize - Add the size of the status files /*{{{*/
// ---------------------------------------------------------------------
/* This adds the size of all the status files to the size counter */
-static bool pkgAddSourcesSize(unsigned long &TotalSize)
+bool pkgAddStatusSize(unsigned long &TotalSize)
{
// Grab the file names
string xstatus = _config->FindFile("Dir::State::xstatus");
// MergeStatus - Add the status files to the cache /*{{{*/
// ---------------------------------------------------------------------
/* This adds the status files to the map */
-static bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen,
- unsigned long &CurrentSize,unsigned long TotalSize)
+bool pkgMergeStatus(OpProgress &Progress,pkgCacheGenerator &Gen,
+ unsigned long &CurrentSize,unsigned long TotalSize)
{
// Grab the file names
string Status[3];
/* This puts the source package cache into the given generator. */
bool pkgGenerateSrcCache(pkgSourceList &List,OpProgress &Progress,
pkgCacheGenerator &Gen,
- unsigned long &CurrentSize,unsigned long TotalSize)
+ unsigned long &CurrentSize,unsigned long &TotalSize)
{
string ListDir = _config->FindDir("Dir::State::lists");
TotalSize += Buf.st_size;
}
- if (pkgAddSourcesSize(TotalSize) == false)
+ if (pkgAddStatusSize(TotalSize) == false)
return false;
// Generate the pkg source cache
// Compute the progress
unsigned long TotalSize = 0;
- if (pkgAddSourcesSize(TotalSize) == false)
+ if (pkgAddStatusSize(TotalSize) == false)
return false;
unsigned long CurrentSize = 0;
/* 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;
+ bool Writeable = (access(CacheFile.c_str(),W_OK) == 0) ||
+ (errno == ENOENT);
+
if (Writeable == true)
{
if (pkgMakeStatusCache(List,Progress) == false)
// Compute the progress
unsigned long TotalSize = 0;
- if (pkgAddSourcesSize(TotalSize) == false)
+ if (pkgAddStatusSize(TotalSize) == false)
{
delete Map;
return 0;