Dirty = false;
HeaderSz = sizeof(pkgCache::Header);
+ GroupSz = sizeof(pkgCache::Group);
PackageSz = sizeof(pkgCache::Package);
PackageFileSz = sizeof(pkgCache::PackageFile);
VersionSz = sizeof(pkgCache::Version);
VerFileSz = sizeof(pkgCache::VerFile);
DescFileSz = sizeof(pkgCache::DescFile);
+ GroupCount = 0;
PackageCount = 0;
VersionCount = 0;
DescriptionCount = 0;
bool pkgCache::Header::CheckSizes(Header &Against) const
{
if (HeaderSz == Against.HeaderSz &&
+ GroupSz == Against.GroupSz &&
PackageSz == Against.PackageSz &&
PackageFileSz == Against.PackageFileSz &&
VersionSz == Against.VersionSz &&
/* */
pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
{
+ MultiArchEnabled = APT::Configuration::getArchitectures().size() > 1;
if (DoMap == true)
ReMap();
}
// Cache::ReMap - Reopen the cache file /*{{{*/
// ---------------------------------------------------------------------
/* If the file is already closed then this will open it open it. */
-bool pkgCache::ReMap()
+bool pkgCache::ReMap(bool const &Errorchecks)
{
// Apply the typecasts.
HeaderP = (Header *)Map.Data();
StringItemP = (StringItem *)Map.Data();
StrP = (char *)Map.Data();
+ if (Errorchecks == false)
+ return true;
+
if (Map.Size() == 0 || HeaderP == 0)
return _error->Error(_("Empty package cache"));
return Hash % _count(HeaderP->PkgHashTable);
}
+ /*}}}*/
+// Cache::SingleArchFindPkg - Locate a package by name /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns 0 on error, pointer to the package otherwise
+ The multiArch enabled methods will fallback to this one as it is (a bit)
+ faster for single arch environments and realworld is mostly singlearch… */
+pkgCache::PkgIterator pkgCache::SingleArchFindPkg(const string &Name)
+{
+ // Look at the hash bucket
+ Package *Pkg = PkgP + HeaderP->PkgHashTable[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);
+}
/*}}}*/
// Cache::FindPkg - Locate a package by name /*{{{*/
// ---------------------------------------------------------------------
/* Returns 0 on error, pointer to the package otherwise */
pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
+ if (MultiArchCache() == false)
+ return SingleArchFindPkg(Name);
size_t const found = Name.find(':');
if (found == string::npos)
return FindPkg(Name, "native");
// Cache::FindPkg - Locate a package by name /*{{{*/
// ---------------------------------------------------------------------
/* Returns 0 on error, pointer to the package otherwise */
-pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string Arch) {
+pkgCache::PkgIterator pkgCache::FindPkg(const string &Name, string const &Arch) {
+ if (MultiArchCache() == false) {
+ if (Arch == "native" || Arch == "all" || Arch == "any" ||
+ Arch == _config->Find("APT::Architecture"))
+ return SingleArchFindPkg(Name);
+ else
+ return PkgIterator(*this,0);
+ }
/* 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) */
// 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) {
+pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) const {
if (unlikely(IsGood() == false || S->FirstPackage == 0))
return PkgIterator(*Owner, 0);
break;
}
+ return PkgIterator(*Owner, 0);
+}
+ /*}}}*/
+// GrpIterator::FindPreferredPkg - Locate the "best" package /*{{{*/
+// ---------------------------------------------------------------------
+/* Returns an End-Pointer on error, pointer to the package otherwise */
+pkgCache::PkgIterator pkgCache::GrpIterator::FindPreferredPkg() const {
+ pkgCache::PkgIterator Pkg = FindPkg("native");
+ if (Pkg.end() == false)
+ return Pkg;
+
+ std::vector<std::string> const archs = APT::Configuration::getArchitectures();
+ for (std::vector<std::string>::const_iterator a = archs.begin();
+ a != archs.end(); ++a) {
+ Pkg = FindPkg(*a);
+ if (Pkg.end() == false)
+ return Pkg;
+ }
+
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) {
+ We can't simply ++ to the next as the next package of the last will
+ be from a different group (with the same hash value) */
+pkgCache::PkgIterator pkgCache::GrpIterator::NextPkg(pkgCache::PkgIterator const &LastPkg) const {
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;
- }
+ if (S->LastPackage == LastPkg.Index())
+ return PkgIterator(*Owner, 0);
- return PkgIterator(*Owner, 0);
+ return PkgIterator(*Owner, Owner->PkgP + LastPkg->NextPackage);
}
/*}}}*/
// GrpIterator::operator ++ - Postfix incr /*{{{*/
// ---------------------------------------------------------------------
/* Currently critical deps are defined as depends, predepends and
conflicts (including dpkg's Breaks fields). */
-bool pkgCache::DepIterator::IsCritical()
+bool pkgCache::DepIterator::IsCritical() const
{
if (S->Type == pkgCache::Dep::Conflicts ||
S->Type == pkgCache::Dep::DpkgBreaks ||
In Conjunction with the DepCache the value of Result may not be
super-good since the policy may have made it uninstallable. Using
AllTargets is better in this case. */
-bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
+bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result) const
{
Result = TargetPkg();
provides. It includes every possible package-version that could satisfy
the dependency. The last item in the list has a 0. The resulting pointer
must be delete [] 'd */
-pkgCache::Version **pkgCache::DepIterator::AllTargets()
+pkgCache::Version **pkgCache::DepIterator::AllTargets() const
{
Version **Res = 0;
unsigned long Size =0;
// ---------------------------------------------------------------------
/* This describes the version from a release-centric manner. The output is a
list of Label:Version/Archive */
-string pkgCache::VerIterator::RelStr()
+string pkgCache::VerIterator::RelStr() const
{
bool First = true;
string Res;