summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apt-pkg/cacheiterators.h37
-rw-r--r--apt-pkg/deb/deblistparser.cc40
-rw-r--r--apt-pkg/deb/deblistparser.h1
-rw-r--r--apt-pkg/pkgcache.cc112
-rw-r--r--apt-pkg/pkgcache.h30
-rw-r--r--apt-pkg/pkgcachegen.cc111
-rw-r--r--apt-pkg/pkgcachegen.h6
7 files changed, 267 insertions, 70 deletions
diff --git a/apt-pkg/cacheiterators.h b/apt-pkg/cacheiterators.h
index 1da5c6f02..35d3aa228 100644
--- a/apt-pkg/cacheiterators.h
+++ b/apt-pkg/cacheiterators.h
@@ -31,10 +31,8 @@
#define PKGLIB_CACHEITERATORS_H
// abstract Iterator template /*{{{*/
/* This template provides the very basic iterator methods we
- need to have for doing some walk-over-the-cache magic, */
+ need to have for doing some walk-over-the-cache magic */
template<typename Str, typename Itr> class pkgCache::Iterator {
- __attribute__ ((deprecated)) void _dummy(); // FIXME: Who on earth uses this method ???
-
protected:
Str *S;
pkgCache *Owner;
@@ -77,6 +75,35 @@ template<typename Str, typename Itr> class pkgCache::Iterator {
inline Iterator(pkgCache &Owner,Str *T = 0) : S(T), Owner(&Owner) {};
};
/*}}}*/
+// Group Iterator /*{{{*/
+/* Packages with the same name are collected in a Group so someone only
+ interest in package names can iterate easily over the names, so the
+ different architectures can be treated as of the "same" package
+ (apt internally treat them as totally different packages) */
+class pkgCache::GrpIterator: public Iterator<Group, GrpIterator> {
+ protected:
+ inline Group* OwnerPointer() const {
+ return Owner->GrpP;
+ };
+
+ public:
+ void operator ++(int) {if (S != Owner->GrpP) S = Owner->GrpP + S->Next;};
+ virtual void operator ++() {operator ++(0);};
+
+ inline const char *Name() const {return S->Name == 0?0:Owner->StrP + S->Name;};
+ inline PkgIterator PackageList() const;
+ PkgIterator FindPkg(string Arch = "any");
+ PkgIterator NextPkg(PkgIterator const &Pkg);
+
+ // Constructors
+ inline GrpIterator(pkgCache &Owner, Group *Trg) : Iterator<Group, GrpIterator>(Owner, Trg) {
+ if (S == 0)
+ S = OwnerPointer();
+ };
+ inline GrpIterator() : Iterator<Group, GrpIterator>() {};
+
+};
+ /*}}}*/
// Package Iterator /*{{{*/
class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
long HashIndex;
@@ -103,6 +130,8 @@ class pkgCache::PkgIterator: public Iterator<Package, PkgIterator> {
inline const char *Section() const {return S->Section == 0?0:Owner->StrP + S->Section;};
inline bool Purge() const {return S->CurrentState == pkgCache::State::Purge ||
(S->CurrentVer == 0 && S->CurrentState == pkgCache::State::NotInstalled);};
+ inline const char *Arch() const {return S->Arch == 0?0:Owner->StrP + S->Arch;};
+ inline GrpIterator Group() const { return GrpIterator(*Owner, Owner->GrpP + S->Group);};
inline VerIterator VersionList() const;
inline VerIterator CurrentVer() const;
@@ -339,6 +368,8 @@ class pkgCache::DescFileIterator : public Iterator<DescFile, DescFileIterator> {
};
/*}}}*/
// Inlined Begin functions cant be in the class because of order problems /*{{{*/
+inline pkgCache::PkgIterator pkgCache::GrpIterator::PackageList() const
+ {return PkgIterator(*Owner,Owner->PkgP + S->FirstPackage);};
inline pkgCache::VerIterator pkgCache::PkgIterator::VersionList() const
{return VerIterator(*Owner,Owner->VerP + S->VersionList);};
inline pkgCache::VerIterator pkgCache::PkgIterator::CurrentVer() const
diff --git a/apt-pkg/deb/deblistparser.cc b/apt-pkg/deb/deblistparser.cc
index 25a1df3f9..fe68aec0b 100644
--- a/apt-pkg/deb/deblistparser.cc
+++ b/apt-pkg/deb/deblistparser.cc
@@ -53,12 +53,25 @@ unsigned long debListParser::UniqFindTagWrite(const char *Tag)
// ListParser::Package - Return the package name /*{{{*/
// ---------------------------------------------------------------------
/* This is to return the name of the package this section describes */
-string debListParser::Package()
-{
- string Result = Section.FindS("Package");
- if (Result.empty() == true)
- _error->Error("Encountered a section with no Package: header");
- return Result;
+string debListParser::Package() {
+ string const Result = Section.FindS("Package");
+ if(unlikely(Result.empty() == true))
+ _error->Error("Encountered a section with no Package: header");
+ return Result;
+}
+ /*}}}*/
+// ListParser::Architecture - Return the package arch /*{{{*/
+// ---------------------------------------------------------------------
+/* This will return the Architecture of the package this section describes
+ Note that architecture "all" packages will get the architecture of the
+ Packages file parsed here */
+string debListParser::Architecture() {
+ string const Result = Section.FindS("Architecture");
+ if (Result.empty() == true)
+ return Arch;
+ if (Result == "all")
+ return Arch;
+ return Result;
}
/*}}}*/
// ListParser::Version - Return the version string /*{{{*/
@@ -78,8 +91,10 @@ bool debListParser::NewVersion(pkgCache::VerIterator Ver)
{
// Parse the section
Ver->Section = UniqFindTagWrite("Section");
- Ver->Arch = UniqFindTagWrite("Architecture");
-
+
+ // Parse the architecture
+ Ver->Arch = WriteUniqString(Architecture());
+
// Archive Size
Ver->Size = (unsigned)Section.FindI("Size");
@@ -537,6 +552,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
return true;
string Package;
+ string const pkgArch = Ver.Arch();
string Version;
unsigned int Op;
@@ -546,7 +562,7 @@ bool debListParser::ParseDepends(pkgCache::VerIterator Ver,
if (Start == 0)
return _error->Error("Problem parsing dependency %s",Tag);
- if (NewDepends(Ver,Package,Version,Op,Type) == false)
+ if (NewDepends(Ver,Package,pkgArch,Version,Op,Type) == false)
return false;
if (Start == Stop)
break;
@@ -619,6 +635,7 @@ bool debListParser::Step()
if (Section.Find("Architecture",Start,Stop) == false)
return true;
+ //FIXME: Accept different Architectures here
if (stringcmp(Arch,Start,Stop) == 0)
return true;
@@ -641,8 +658,9 @@ bool debListParser::LoadReleaseInfo(pkgCache::PkgFileIterator FileI,
if (Tags.Step(Section) == false)
return false;
- //mvo: I don't think we need to fill that in (it's unused since apt-0.6)
- //FileI->Architecture = WriteUniqString(Arch);
+ // FIXME: Do we need it now for multi-arch?
+ // mvo: I don't think we need to fill that in (it's unused since apt-0.6)
+// FileI->Architecture = WriteUniqString(Arch);
// apt-secure does no longer download individual (per-section) Release
// file. to provide Component pinning we use the section name now
diff --git a/apt-pkg/deb/deblistparser.h b/apt-pkg/deb/deblistparser.h
index 1c709229f..5f91e073e 100644
--- a/apt-pkg/deb/deblistparser.h
+++ b/apt-pkg/deb/deblistparser.h
@@ -46,6 +46,7 @@ class debListParser : public pkgCacheGenerator::ListParser
// These all operate against the current section
virtual string Package();
+ virtual string Architecture();
virtual string Version();
virtual bool NewVersion(pkgCache::VerIterator Ver);
virtual string Description();
diff --git a/apt-pkg/pkgcache.cc b/apt-pkg/pkgcache.cc
index 2f8bde6f7..2b5f53f6f 100644
--- a/apt-pkg/pkgcache.cc
+++ b/apt-pkg/pkgcache.cc
@@ -79,7 +79,8 @@ pkgCache::Header::Header()
StringList = 0;
VerSysName = 0;
Architecture = 0;
- memset(HashTable,0,sizeof(HashTable));
+ memset(PkgHashTable,0,sizeof(PkgHashTable));
+ memset(GrpHashTable,0,sizeof(GrpHashTable));
memset(Pools,0,sizeof(Pools));
}
/*}}}*/
@@ -118,6 +119,7 @@ bool pkgCache::ReMap()
{
// Apply the typecasts.
HeaderP = (Header *)Map.Data();
+ GrpP = (Group *)Map.Data();
PkgP = (Package *)Map.Data();
VerFileP = (VerFile *)Map.Data();
DescFileP = (DescFile *)Map.Data();
@@ -165,7 +167,7 @@ unsigned long pkgCache::sHash(const string &Str) const
unsigned long Hash = 0;
for (string::const_iterator I = Str.begin(); I != Str.end(); I++)
Hash = 5*Hash + tolower_ascii(*I);
- return Hash % _count(HeaderP->HashTable);
+ return Hash % _count(HeaderP->PkgHashTable);
}
unsigned long pkgCache::sHash(const char *Str) const
@@ -173,24 +175,40 @@ unsigned long pkgCache::sHash(const char *Str) const
unsigned long Hash = 0;
for (const char *I = Str; *I != 0; I++)
Hash = 5*Hash + tolower_ascii(*I);
- return Hash % _count(HeaderP->HashTable);
+ return Hash % _count(HeaderP->PkgHashTable);
}
/*}}}*/
// Cache::FindPkg - Locate a package by name /*{{{*/
// ---------------------------------------------------------------------
/* Returns 0 on error, pointer to the package otherwise */
-pkgCache::PkgIterator pkgCache::FindPkg(const string &Name)
-{
- // Look at the hash bucket
- Package *Pkg = PkgP + HeaderP->HashTable[Hash(Name)];
- for (; Pkg != PkgP; Pkg = PkgP + Pkg->NextPackage)
- {
- if (Pkg->Name != 0 && StrP[Pkg->Name] == Name[0] &&
- stringcasecmp(Name,StrP + Pkg->Name) == 0)
- return PkgIterator(*this,Pkg);
- }
- return PkgIterator(*this,0);
+pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) {
+ /* We make a detour via the GrpIterator here as
+ on a multi-arch environment a group is easier to
+ find than a package (less entries in the buckets) */
+ pkgCache::GrpIterator Grp = FindGrp(Name);
+ if (Grp.end() == true)
+ return PkgIterator(*this,0);
+
+ return Grp.FindPkg(Arch);
+}
+ /*}}}*/
+// Cache::FindGrp - Locate a group by name /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns End-Pointer on error, pointer to the group otherwise */
+pkgCache::GrpIterator pkgCache::FindGrp(const string &Name) {
+ if (unlikely(Name.empty() == true))
+ return GrpIterator(*this,0);
+
+ // Look at the hash bucket for the group
+ Group *Grp = GrpP + HeaderP->GrpHashTable[sHash(Name)];
+ for (; Grp != GrpP; Grp = GrpP + Grp->Next) {
+ if (Grp->Name != 0 && StrP[Grp->Name] == Name[0] &&
+ stringcasecmp(Name, StrP + Grp->Name) == 0)
+ return GrpIterator(*this, Grp);
+ }
+
+ return GrpIterator(*this,0);
}
/*}}}*/
// Cache::CompTypeDeb - Return a string describing the compare type /*{{{*/
@@ -242,6 +260,68 @@ const char *pkgCache::Priority(unsigned char Prio)
return 0;
}
/*}}}*/
+// GrpIterator::FindPkg - Locate a package by arch /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns an End-Pointer on error, pointer to the package otherwise */
+pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) {
+ if (unlikely(IsGood() == false || S->FirstPackage == 0))
+ return PkgIterator(*Owner, 0);
+
+ static string const myArch = _config->Find("APT::Architecture");
+ /* Most of the time the package for our native architecture is
+ the one we add at first to the cache, but this would be the
+ last one we check, so we do it now. */
+ if (Arch == "native" || Arch == myArch) {
+ Arch = myArch;
+ pkgCache::Package *Pkg = Owner->PkgP + S->LastPackage;
+ if (stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0)
+ return PkgIterator(*Owner, Pkg);
+ }
+
+ /* If we accept any package we simply return the "first"
+ package in this group (the last one added). */
+ if (Arch == "any")
+ return PkgIterator(*Owner, Owner->PkgP + S->FirstPackage);
+
+ /* Iterate over the list to find the matching arch
+ unfortunately this list includes "package noise"
+ (= different packages with same calculated hash),
+ so we need to check the name also */
+ for (pkgCache::Package *Pkg = PackageList(); Pkg != Owner->PkgP;
+ Pkg = Owner->PkgP + Pkg->NextPackage) {
+ if (S->Name == Pkg->Name &&
+ stringcasecmp(Arch, Owner->StrP + Pkg->Arch) == 0)
+ return PkgIterator(*Owner, Pkg);
+ if ((Owner->PkgP + S->LastPackage) == Pkg)
+ break;
+ }
+
+ return PkgIterator(*Owner, 0);
+}
+ /*}}}*/
+// GrpIterator::NextPkg - Locate the next package in the group /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns an End-Pointer on error, pointer to the package otherwise.
+ We can't simply ++ to the next as the list of packages includes
+ "package noise" (= packages with the same hash value but different name) */
+pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) {
+ if (unlikely(IsGood() == false || S->FirstPackage == 0 ||
+ LastPkg.end() == true))
+ return PkgIterator(*Owner, 0);
+
+ // Iterate over the list to find the next package
+ pkgCache::Package *Pkg = Owner->PkgP + LastPkg.Index();
+ Pkg = Owner->PkgP + Pkg->NextPackage;
+ for (; Pkg != Owner->PkgP; Pkg = Owner->PkgP + Pkg->NextPackage) {
+ if (S->Name == Pkg->Name)
+ return PkgIterator(*Owner, Pkg);
+ if ((Owner->PkgP + S->LastPackage) == Pkg)
+ break;
+ }
+
+ return PkgIterator(*Owner, 0);
+}
+ /*}}}*/
// PkgIterator::operator ++ - Postfix incr /*{{{*/
// ---------------------------------------------------------------------
/* This will advance to the next logical package in the hash table. */
@@ -252,10 +332,10 @@ void pkgCache::PkgIterator::operator ++(int)
S = Owner->PkgP + S->NextPackage;
// Follow the hash table
- while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->HashTable))
+ while (S == Owner->PkgP && (HashIndex+1) < (signed)_count(Owner->HeaderP->PkgHashTable))
{
HashIndex++;
- S = Owner->PkgP + Owner->HeaderP->HashTable[HashIndex];
+ S = Owner->PkgP + Owner->HeaderP->PkgHashTable[HashIndex];
}
};
/*}}}*/
diff --git a/apt-pkg/pkgcache.h b/apt-pkg/pkgcache.h
index 359f8a590..b3d2752d2 100644
--- a/apt-pkg/pkgcache.h
+++ b/apt-pkg/pkgcache.h
@@ -32,6 +32,7 @@ class pkgCache /*{{{*/
public:
// Cache element predeclarations
struct Header;
+ struct Group;
struct Package;
struct PackageFile;
struct Version;
@@ -44,6 +45,7 @@ class pkgCache /*{{{*/
// Iterators
template<typename Str, typename Itr> class Iterator;
+ class GrpIterator;
class PkgIterator;
class VerIterator;
class DescIterator;
@@ -97,6 +99,7 @@ class pkgCache /*{{{*/
// Pointers to the arrays of items
Header *HeaderP;
+ Group *GrpP;
Package *PkgP;
VerFile *VerFileP;
DescFile *DescFileP;
@@ -121,7 +124,9 @@ class pkgCache /*{{{*/
const char *Priority(unsigned char Priority);
// Accessors
- PkgIterator FindPkg(const string &Name);
+ GrpIterator FindGrp(const string &Name);
+ PkgIterator FindPkg(const string &Name, string Arch = "native");
+
Header &Head() {return *HeaderP;};
inline PkgIterator PkgBegin();
inline PkgIterator PkgEnd();
@@ -161,6 +166,7 @@ struct pkgCache::Header
unsigned short DescFileSz;
// Structure counts
+ unsigned long GroupCount;
unsigned long PackageCount;
unsigned long VersionCount;
unsigned long DescriptionCount;
@@ -180,22 +186,36 @@ struct pkgCache::Header
/* Allocation pools, there should be one of these for each structure
excluding the header */
- DynamicMMap::Pool Pools[8];
+ DynamicMMap::Pool Pools[9];
- // Rapid package name lookup
- map_ptrloc HashTable[2*1048];
+ // Rapid package and group name lookup
+ // Notice: Increase only both table sizes as the
+ // hashmethod assume the size of the Pkg one
+ map_ptrloc PkgHashTable[2*1048];
+ map_ptrloc GrpHashTable[2*1048];
bool CheckSizes(Header &Against) const;
Header();
};
/*}}}*/
+struct pkgCache::Group { /*{{{*/
+ map_ptrloc Name; // Stringtable
+
+ // Linked List
+ map_ptrloc FirstPackage;// Package
+ map_ptrloc LastPackage; // Package
+ map_ptrloc Next; // Group
+};
+ /*}}}*/
struct pkgCache::Package /*{{{*/
{
// Pointers
map_ptrloc Name; // Stringtable
+ map_ptrloc Arch; // StringTable (StringItem)
map_ptrloc VersionList; // Version
map_ptrloc CurrentVer; // Version
map_ptrloc Section; // StringTable (StringItem)
+ map_ptrloc Group; // Group the Package belongs to
// Linked list
map_ptrloc NextPackage; // Package
@@ -254,7 +274,7 @@ struct pkgCache::Version /*{{{*/
map_ptrloc VerStr; // Stringtable
map_ptrloc Section; // StringTable (StringItem)
map_ptrloc Arch; // StringTable
-
+
// Lists
map_ptrloc FileList; // VerFile
map_ptrloc NextVer; // Version
diff --git a/apt-pkg/pkgcachegen.cc b/apt-pkg/pkgcachegen.cc
index 68180c702..c37f6f48e 100644
--- a/apt-pkg/pkgcachegen.cc
+++ b/apt-pkg/pkgcachegen.cc
@@ -108,12 +108,12 @@ bool pkgCacheGenerator::MergeList(ListParser &List,
while (List.Step() == true)
{
// Get a pointer to the package structure
- string PackageName = List.Package();
+ string const PackageName = List.Package();
if (PackageName.empty() == true)
return false;
-
+
pkgCache::PkgIterator Pkg;
- if (NewPackage(Pkg,PackageName) == false)
+ if (NewPackage(Pkg, PackageName, List.Architecture()) == false)
return _error->Error(_("Error occurred while processing %s (NewPackage)"),PackageName.c_str());
Counter++;
if (Counter % 100 == 0 && Progress != 0)
@@ -323,33 +323,71 @@ bool pkgCacheGenerator::MergeFileProvides(ListParser &List)
return true;
}
/*}}}*/
+// CacheGenerator::NewGroup - Add a new group /*{{{*/
+// ---------------------------------------------------------------------
+/* This creates a new group structure and adds it to the hash table */
+bool pkgCacheGenerator::NewGroup(pkgCache::GrpIterator &Grp, const string &Name) {
+ Grp = Cache.FindGrp(Name);
+ if (Grp.end() == false)
+ return true;
+
+ // Get a structure
+ unsigned long const Group = Map.Allocate(sizeof(pkgCache::Group));
+ if (unlikely(Group == 0))
+ return false;
+
+ Grp = pkgCache::GrpIterator(Cache, Cache.GrpP + Group);
+ Grp->Name = Map.WriteString(Name);
+ if (unlikely(Grp->Name == 0))
+ return false;
+
+ // Insert it into the hash table
+ unsigned long const Hash = Cache.Hash(Name);
+ Grp->Next = Cache.HeaderP->GrpHashTable[Hash];
+ Cache.HeaderP->GrpHashTable[Hash] = Group;
+
+ Cache.HeaderP->GroupCount++;
+
+ return true;
+}
+ /*}}}*/
// CacheGenerator::NewPackage - Add a new package /*{{{*/
// ---------------------------------------------------------------------
/* This creates a new package structure and adds it to the hash table */
-bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name)
-{
- Pkg = Cache.FindPkg(Name);
- if (Pkg.end() == false)
- return true;
+bool pkgCacheGenerator::NewPackage(pkgCache::PkgIterator &Pkg,const string &Name,
+ const string &Arch) {
+ pkgCache::GrpIterator Grp;
+ if (unlikely(NewGroup(Grp, Name) == false))
+ return false;
+
+ Pkg = Grp.FindPkg(Arch);
+ if (Pkg.end() == false)
+ return true;
// Get a structure
- unsigned long Package = Map.Allocate(sizeof(pkgCache::Package));
- if (Package == 0)
+ unsigned long const Package = Map.Allocate(sizeof(pkgCache::Package));
+ if (unlikely(Package == 0))
return false;
-
Pkg = pkgCache::PkgIterator(Cache,Cache.PkgP + Package);
-
+
// Insert it into the hash table
- unsigned long Hash = Cache.Hash(Name);
- Pkg->NextPackage = Cache.HeaderP->HashTable[Hash];
- Cache.HeaderP->HashTable[Hash] = Package;
-
- // Set the name and the ID
- Pkg->Name = Map.WriteString(Name);
- if (Pkg->Name == 0)
+ unsigned long const Hash = Cache.Hash(Name);
+ Pkg->NextPackage = Cache.HeaderP->PkgHashTable[Hash];
+ Cache.HeaderP->PkgHashTable[Hash] = Package;
+
+ // remember the packages in the group
+ Grp->FirstPackage = Package;
+ if (Grp->LastPackage == 0)
+ Grp->LastPackage = Package;
+
+ // Set the name, arch and the ID
+ Pkg->Name = Grp->Name;
+ Pkg->Group = Grp.Index();
+ Pkg->Arch = WriteUniqString(Arch.c_str());
+ if (unlikely(Pkg->Arch == 0))
return false;
Pkg->ID = Cache.HeaderP->PackageCount++;
-
+
return true;
}
/*}}}*/
@@ -474,6 +512,7 @@ map_ptrloc pkgCacheGenerator::NewDescription(pkgCache::DescIterator &Desc,
version and to the package that it is pointing to. */
bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
const string &PackageName,
+ const string &Arch,
const string &Version,
unsigned int Op,
unsigned int Type)
@@ -481,8 +520,8 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
pkgCache &Cache = Owner->Cache;
// Get a structure
- unsigned long Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency));
- if (Dependency == 0)
+ unsigned long const Dependency = Owner->Map.Allocate(sizeof(pkgCache::Dependency));
+ if (unlikely(Dependency == 0))
return false;
// Fill it in
@@ -492,11 +531,17 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
Dep->CompareOp = Op;
Dep->ID = Cache.HeaderP->DependsCount++;
- // Locate the target package
- pkgCache::PkgIterator Pkg;
- if (Owner->NewPackage(Pkg,PackageName) == false)
+ pkgCache::GrpIterator Grp;
+ if (unlikely(Owner->NewGroup(Grp, PackageName) == false))
return false;
-
+
+ // Locate the target package
+ pkgCache::PkgIterator Pkg = Grp.FindPkg(Arch);
+ if (Pkg.end() == true) {
+ if (unlikely(Owner->NewPackage(Pkg, PackageName, Arch) == false))
+ return false;
+ }
+
// Probe the reverse dependency list for a version string that matches
if (Version.empty() == false)
{
@@ -504,7 +549,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
if (I->Version != 0 && I.TargetVer() == Version)
Dep->Version = I->Version;*/
if (Dep->Version == 0)
- if ((Dep->Version = WriteString(Version)) == 0)
+ if (unlikely((Dep->Version = WriteString(Version)) == 0))
return false;
}
@@ -524,7 +569,7 @@ bool pkgCacheGenerator::ListParser::NewDepends(pkgCache::VerIterator Ver,
}
// Is it a file dependency?
- if (PackageName[0] == '/')
+ if (unlikely(PackageName[0] == '/'))
FoundFileDeps = true;
Dep->NextDepends = *OldDepLast;
@@ -544,12 +589,12 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
pkgCache &Cache = Owner->Cache;
// We do not add self referencing provides
- if (Ver.ParentPkg().Name() == PackageName)
+ if (unlikely(Ver.ParentPkg().Name() == PackageName))
return true;
// Get a structure
- unsigned long Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides));
- if (Provides == 0)
+ unsigned long const Provides = Owner->Map.Allocate(sizeof(pkgCache::Provides));
+ if (unlikely(Provides == 0))
return false;
Cache.HeaderP->ProvidesCount++;
@@ -558,12 +603,12 @@ bool pkgCacheGenerator::ListParser::NewProvides(pkgCache::VerIterator Ver,
Prv->Version = Ver.Index();
Prv->NextPkgProv = Ver->ProvidesList;
Ver->ProvidesList = Prv.Index();
- if (Version.empty() == false && (Prv->ProvideVersion = WriteString(Version)) == 0)
+ if (Version.empty() == false && unlikely((Prv->ProvideVersion = WriteString(Version)) == 0))
return false;
// Locate the target package
pkgCache::PkgIterator Pkg;
- if (Owner->NewPackage(Pkg,PackageName) == false)
+ if (unlikely(Owner->NewPackage(Pkg,PackageName,string(Ver.Arch())) == false))
return false;
// Link it to the package
diff --git a/apt-pkg/pkgcachegen.h b/apt-pkg/pkgcachegen.h
index 108b34207..4a2419b24 100644
--- a/apt-pkg/pkgcachegen.h
+++ b/apt-pkg/pkgcachegen.h
@@ -51,7 +51,8 @@ class pkgCacheGenerator /*{{{*/
// Flag file dependencies
bool FoundFileDeps;
- bool NewPackage(pkgCache::PkgIterator &Pkg,const string &PkgName);
+ bool NewGroup(pkgCache::GrpIterator &Grp,const string &Name);
+ bool NewPackage(pkgCache::PkgIterator &Pkg,const string &Name, const string &Arch);
bool NewFileVer(pkgCache::VerIterator &Ver,ListParser &List);
bool NewFileDesc(pkgCache::DescIterator &Desc,ListParser &List);
unsigned long NewVersion(pkgCache::VerIterator &Ver,const string &VerStr,unsigned long Next);
@@ -96,7 +97,7 @@ class pkgCacheGenerator::ListParser
inline unsigned long WriteUniqString(const char *S,unsigned int Size) {return Owner->WriteUniqString(S,Size);};
inline unsigned long WriteString(const string &S) {return Owner->Map.WriteString(S);};
inline unsigned long WriteString(const char *S,unsigned int Size) {return Owner->Map.WriteString(S,Size);};
- bool NewDepends(pkgCache::VerIterator Ver,const string &Package,
+ bool NewDepends(pkgCache::VerIterator Ver,const string &Package, const string &Arch,
const string &Version,unsigned int Op,
unsigned int Type);
bool NewProvides(pkgCache::VerIterator Ver,const string &Package,
@@ -106,6 +107,7 @@ class pkgCacheGenerator::ListParser
// These all operate against the current section
virtual string Package() = 0;
+ virtual string Architecture() = 0;
virtual string Version() = 0;
virtual bool NewVersion(pkgCache::VerIterator Ver) = 0;
virtual string Description() = 0;