]> git.saurik.com Git - apt.git/blobdiff - apt-pkg/pkgcache.cc
* apt-pkg/policy.h:
[apt.git] / apt-pkg / pkgcache.cc
index 24d9e032994c3a40230ad6a5c8e84793cd4bf3e0..68aa83d0c8ebf4974180b61027006faaf9f6c1d9 100644 (file)
@@ -55,6 +55,7 @@ pkgCache::Header::Header()
    Dirty = false;
    
    HeaderSz = sizeof(pkgCache::Header);
+   GroupSz = sizeof(pkgCache::Group);
    PackageSz = sizeof(pkgCache::Package);
    PackageFileSz = sizeof(pkgCache::PackageFile);
    VersionSz = sizeof(pkgCache::Version);
@@ -64,6 +65,7 @@ pkgCache::Header::Header()
    VerFileSz = sizeof(pkgCache::VerFile);
    DescFileSz = sizeof(pkgCache::DescFile);
    
+   GroupCount = 0;
    PackageCount = 0;
    VersionCount = 0;
    DescriptionCount = 0;
@@ -90,6 +92,7 @@ pkgCache::Header::Header()
 bool pkgCache::Header::CheckSizes(Header &Against) const
 {
    if (HeaderSz == Against.HeaderSz &&
+       GroupSz == Against.GroupSz &&
        PackageSz == Against.PackageSz &&
        PackageFileSz == Against.PackageFileSz &&
        VersionSz == Against.VersionSz &&
@@ -108,6 +111,7 @@ bool pkgCache::Header::CheckSizes(Header &Against) const
 /* */
 pkgCache::pkgCache(MMap *Map, bool DoMap) : Map(*Map)
 {
+   MultiArchEnabled = APT::Configuration::getArchitectures().size() > 1;
    if (DoMap == true)
       ReMap();
 }
@@ -178,11 +182,31 @@ unsigned long pkgCache::sHash(const char *Str) const
    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");
@@ -195,7 +219,14 @@ pkgCache::PkgIterator pkgCache::FindPkg(const string &Name) {
 // 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) */
@@ -276,7 +307,7 @@ const char *pkgCache::Priority(unsigned char Prio)
 // 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);
 
@@ -309,30 +340,42 @@ pkgCache::PkgIterator pkgCache::GrpIterator::FindPkg(string Arch) {
                        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                             /*{{{*/
@@ -461,7 +504,7 @@ std::string pkgCache::PkgIterator::FullName(bool const &Pretty) const
 // ---------------------------------------------------------------------
 /* 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 ||
@@ -485,7 +528,7 @@ bool pkgCache::DepIterator::IsCritical()
    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();
    
@@ -534,7 +577,7 @@ bool pkgCache::DepIterator::SmartTargetPkg(PkgIterator &Result)
    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;
@@ -699,7 +742,7 @@ pkgCache::VerFileIterator pkgCache::VerIterator::NewestFile() const
 // ---------------------------------------------------------------------
 /* 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;