]> git.saurik.com Git - apt.git/blob - apt-private/private-cachefile.cc
acquire: Use priority queues and a 3 stage pipeline design
[apt.git] / apt-private / private-cachefile.cc
1 // Include files /*{{{*/
2 #include<config.h>
3
4 #include <apt-pkg/algorithms.h>
5 #include <apt-pkg/upgrade.h>
6 #include <apt-pkg/error.h>
7 #include <apt-pkg/configuration.h>
8 #include <apt-pkg/depcache.h>
9 #include <apt-pkg/pkgcache.h>
10 #include <apt-pkg/cacheset.h>
11
12 #include <apt-private/private-output.h>
13 #include <apt-private/private-cachefile.h>
14
15 #include <string.h>
16 #include <ostream>
17 #include <cstdlib>
18
19 #include <apti18n.h>
20 /*}}}*/
21
22 using namespace std;
23
24 static bool SortPackagesByName(pkgCache * const Owner,
25 map_pointer_t const A, map_pointer_t const B)
26 {
27 if (A == 0)
28 return false;
29 if (B == 0 || A == B)
30 return true;
31 pkgCache::Group const * const GA = Owner->GrpP + A;
32 pkgCache::Group const * const GB = Owner->GrpP + B;
33 return strcmp(Owner->StrP + GA->Name, Owner->StrP + GB->Name) <= 0;
34 }
35 SortedPackageUniverse::SortedPackageUniverse(CacheFile &Cache) :
36 PackageUniverse{Cache}, List(Cache.UniverseList)
37 {
38 }
39 void SortedPackageUniverse::LazyInit() const
40 {
41 if (List.empty() == false)
42 return;
43 pkgCache * const Owner = data();
44 // In Multi-Arch systems Grps are easier to sort than Pkgs
45 std::vector<map_pointer_t> GrpList;
46 List.reserve(Owner->Head().GroupCount);
47 for (pkgCache::GrpIterator I{Owner->GrpBegin()}; I.end() != true; ++I)
48 GrpList.emplace_back(I - Owner->GrpP);
49 std::stable_sort(GrpList.begin(), GrpList.end(), std::bind( &SortPackagesByName, Owner, std::placeholders::_1, std::placeholders::_2 ));
50 List.reserve(Owner->Head().PackageCount);
51 for (auto G : GrpList)
52 {
53 pkgCache::GrpIterator const Grp(*Owner, Owner->GrpP + G);
54 for (pkgCache::PkgIterator P = Grp.PackageList(); P.end() != true; P = Grp.NextPkg(P))
55 List.emplace_back(P - Owner->PkgP);
56 }
57 }
58 // CacheFile::CheckDeps - Open the cache file /*{{{*/
59 // ---------------------------------------------------------------------
60 /* This routine generates the caches and then opens the dependency cache
61 and verifies that the system is OK. */
62 bool CacheFile::CheckDeps(bool AllowBroken)
63 {
64 bool FixBroken = _config->FindB("APT::Get::Fix-Broken",false);
65
66 if (_error->PendingError() == true)
67 return false;
68
69 // Check that the system is OK
70 if (DCache->DelCount() != 0 || DCache->InstCount() != 0)
71 return _error->Error("Internal error, non-zero counts");
72
73 // Apply corrections for half-installed packages
74 if (pkgApplyStatus(*DCache) == false)
75 return false;
76
77 if (_config->FindB("APT::Get::Fix-Policy-Broken",false) == true)
78 {
79 FixBroken = true;
80 if ((DCache->PolicyBrokenCount() > 0))
81 {
82 // upgrade all policy-broken packages with ForceImportantDeps=True
83 for (pkgCache::PkgIterator I = Cache->PkgBegin(); !I.end(); ++I)
84 if ((*DCache)[I].NowPolicyBroken() == true)
85 DCache->MarkInstall(I,true,0, false, true);
86 }
87 }
88
89 // Nothing is broken
90 if (DCache->BrokenCount() == 0 || AllowBroken == true)
91 return true;
92
93 // Attempt to fix broken things
94 if (FixBroken == true)
95 {
96 c1out << _("Correcting dependencies...") << flush;
97 if (pkgFixBroken(*DCache) == false || DCache->BrokenCount() != 0)
98 {
99 c1out << _(" failed.") << endl;
100 ShowBroken(c1out,*this,true);
101
102 return _error->Error(_("Unable to correct dependencies"));
103 }
104 if (pkgMinimizeUpgrade(*DCache) == false)
105 return _error->Error(_("Unable to minimize the upgrade set"));
106
107 c1out << _(" Done") << endl;
108 }
109 else
110 {
111 c1out << _("You might want to run 'apt-get -f install' to correct these.") << endl;
112 ShowBroken(c1out,*this,true);
113
114 return _error->Error(_("Unmet dependencies. Try using -f."));
115 }
116
117 return true;
118 }
119 /*}}}*/